diff --git a/gogo/jline/DEPENDENCIES b/gogo/jline/DEPENDENCIES
new file mode 100644
index 0000000..664b8ac
--- /dev/null
+++ b/gogo/jline/DEPENDENCIES
@@ -0,0 +1,20 @@
+Apache Felix Gogo Shell
+Copyright 2011 The Apache Software Foundation
+
+This software was developed at the Apache Software Foundation
+(http://www.apache.org) and may have dependencies on other
+Apache software licensed under Apache License 2.0.
+
+I. Included Third-Party Software
+
+None.
+
+II. Used Third-Party Software
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2009).
+Licensed under the Apache License 2.0.
+
+III. License Summary
+- Apache License 2.0
diff --git a/gogo/jline/LICENSE b/gogo/jline/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/gogo/jline/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed 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.
diff --git a/gogo/jline/NOTICE b/gogo/jline/NOTICE
new file mode 100644
index 0000000..4007bd3
--- /dev/null
+++ b/gogo/jline/NOTICE
@@ -0,0 +1,6 @@
+Apache Felix Gogo Shell
+Copyright 2011 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
diff --git a/gogo/jline/doc/changelog.txt b/gogo/jline/doc/changelog.txt
new file mode 100644
index 0000000..0f7c8dc
--- /dev/null
+++ b/gogo/jline/doc/changelog.txt
@@ -0,0 +1,67 @@
+Changes from 0.8.0 to 0.10.0
+----------------------------
+
+** Improvement
+    * Added gosh_profile work around for issue with OSGi R4.3 API
+      ambiguity.
+
+Changes from 0.6.1 to 0.8.0
+---------------------------
+
+** Bug
+    * [FELIX-2651] - [Gogo] MOTD formatting is broken under Windows
+
+** Improvement
+    * [FELIX-2661] - [Gogo] It should be easier to start Gogo shell
+      non-interactively
+
+** New Feature
+    * [FELIX-2767] - gogo telnet IP address
+
+Changes from 0.6.0 to 0.6.1
+---------------------------
+
+** Bug
+    * [FELIX-2446] - [Gogo] The bundle context command is not used with a
+      scope in gosh_profile
+    * [FELIX-2477] - [gogo] shell procedural commands don't inherit closure
+      arguments
+
+** Improvement
+    * [FELIX-2445] - [Gogo] Default gosh_profile should be updated to use
+      system bundle to load java.lang.System
+    * [FELIX-2543] - [Gogo] Should avoid using System.getProperty() to get
+      configuration properties
+
+Gogo Shell 0.6.0
+----------------
+
+** Bug
+    * [FELIX-1473] - [gogo] The syntax does not provide a way to call methods
+      on a string
+    * [FELIX-1474] - [gogo] result of commands is implicitly written to pipe
+    * [FELIX-1493] - [gogo] automatic expansion of $args in Closure stops
+      direct access to $args list
+    * [FELIX-2337] - [gogo] no way to access array[] elements produced by
+      assignment
+    * [FELIX-2375] - [gogo] when supplied args can't be coerced, the error
+      message prints the arg values, rather than their types
+    * [FELIX-2380] - [gogo] lock contention in piped writer when reader
+      doesn't read all input
+
+** Improvement
+    * [FELIX-1487] - Support for commands on multiple lines
+    * [FELIX-2328] - [gogo] tidy-up runtime to remove optional code etc
+    * [FELIX-2339] - [gogo] add support for running scripts
+    * [FELIX-2342] - [gogo] remove old felix command adaptor
+
+** New Feature
+    * [FELIX-2363] - [Gogo] Add annotations for creating commands with
+      optional and out-of-order arguments
+
+** Task
+    * [FELIX-1670] - [gogo] launcher bundle not required
+    * [FELIX-1889] - Gogo should depend on the official OSGi jars
+    * [FELIX-2334] - [Gogo] Use org.apache.felix as Maven groupId
+    * [FELIX-2367] - [Gogo] Use org.apache.felix namespace to avoid any
+      perceived legal issues
diff --git a/gogo/jline/pom.xml b/gogo/jline/pom.xml
new file mode 100644
index 0000000..ecb67b1
--- /dev/null
+++ b/gogo/jline/pom.xml
@@ -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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <parent>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>gogo-parent</artifactId>
+        <version>0.6.0</version>
+        <relativePath>../gogo-parent/pom.xml</relativePath>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <packaging>bundle</packaging>
+    <name>Apache Felix Gogo JLine Shell</name>
+    <artifactId>org.apache.felix.gogo.jline</artifactId>
+    <version>0.11.0-SNAPSHOT</version>
+    <properties>
+        <!-- Skip because of NPE -->
+        <animal.sniffer.skip>true</animal.sniffer.skip>
+    </properties>
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <version>4.2.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <version>4.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.gogo.runtime</artifactId>
+            <version>0.16.3-SNAPSHOT</version>
+        </dependency>
+        <dependency>
+            <groupId>jline</groupId>
+            <artifactId>jline</artifactId>
+            <version>3.0.0-SNAPSHOT</version>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sshd</groupId>
+            <artifactId>sshd-core</artifactId>
+            <version>1.0.0</version>
+            <optional>true</optional>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Export-Package>
+                        </Export-Package>
+                        <Import-Package>
+                            org.apache.felix.service.command; status="provisional",
+                            *
+                        </Import-Package>
+                        <Private-Package>
+			                org.apache.felix.gogo.shell,
+			                org.apache.felix.gogo.options
+			            </Private-Package>
+                        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
+                        <Bundle-Vendor>The Apache Software Foundation</Bundle-Vendor>
+                        <Bundle-Activator>org.apache.felix.gogo.jline.Activator</Bundle-Activator>
+                        <Include-Resource>{maven-resources},META-INF/LICENSE=LICENSE,META-INF/NOTICE=NOTICE,META-INF/DEPENDENCIES=DEPENDENCIES</Include-Resource>
+                        <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy>
+                        <_removeheaders>Private-Package,Ignore-Package,Include-Resource</_removeheaders>
+                    </instructions>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.rat</groupId>
+                <artifactId>apache-rat-plugin</artifactId>
+                <configuration>
+                    <excludes>
+                        <param>src/main/resources/motd</param>
+                    </excludes>
+                </configuration>
+            </plugin>
+            <plugin>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>1.8</source>
+                    <target>1.8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Activator.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Activator.java
new file mode 100644
index 0000000..ca19dd2
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Activator.java
@@ -0,0 +1,182 @@
+/*
+ * 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.jline;
+
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.felix.gogo.jline.Shell.Context;
+import org.apache.felix.gogo.jline.telnet.Telnet;
+import org.apache.felix.service.command.CommandProcessor;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.command.Converter;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+
+public class Activator implements BundleActivator {
+    private BundleContext context;
+    private ServiceTracker commandProcessorTracker;
+    private Set<ServiceRegistration> regs;
+
+    private ExecutorService executor;
+
+    public Activator() {
+        regs = new HashSet<ServiceRegistration>();
+    }
+
+    public void start(BundleContext context) throws Exception {
+        this.context = context;
+        this.commandProcessorTracker = createCommandProcessorTracker();
+        this.commandProcessorTracker.open();
+    }
+
+    public void stop(BundleContext context) throws Exception {
+        Iterator<ServiceRegistration> iterator = regs.iterator();
+        while (iterator.hasNext()) {
+            ServiceRegistration reg = iterator.next();
+            reg.unregister();
+            iterator.remove();
+        }
+
+        stopShell();
+
+        this.commandProcessorTracker.close();
+    }
+
+    private ServiceTracker createCommandProcessorTracker() {
+        return new ServiceTracker(context, CommandProcessor.class.getName(), null) {
+            @Override
+            public Object addingService(ServiceReference reference) {
+                CommandProcessor processor = (CommandProcessor) super.addingService(reference);
+                startShell(context, processor);
+                return processor;
+            }
+
+            @Override
+            public void removedService(ServiceReference reference, Object service) {
+                stopShell();
+                super.removedService(reference, service);
+            }
+        };
+    }
+
+    private void startShell(final BundleContext context, CommandProcessor processor) {
+        Dictionary<String, Object> dict = new Hashtable<String, Object>();
+        dict.put(CommandProcessor.COMMAND_SCOPE, "gogo");
+
+        // register converters
+        regs.add(context.registerService(Converter.class.getName(), new Converters(context.getBundle(0).getBundleContext()), null));
+
+        // register commands
+
+        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));
+
+        dict.put(CommandProcessor.COMMAND_FUNCTION, Telnet.functions);
+        regs.add(context.registerService(Telnet.class.getName(), new Telnet(processor), dict));
+
+        Shell shell = new Shell(new ShellContext(), processor, null);
+        dict.put(CommandProcessor.COMMAND_FUNCTION, Shell.functions);
+        regs.add(context.registerService(Shell.class.getName(), shell, dict));
+
+        // start shell on a separate thread...
+        executor = Executors.newSingleThreadExecutor(new ThreadFactory() {
+            public Thread newThread(Runnable runnable) {
+                return new Thread(runnable, "Gogo shell");
+            }
+        });
+        executor.submit(new StartShellJob(context, processor));
+    }
+
+    private void stopShell() {
+        if (executor != null && !(executor.isShutdown() || executor.isTerminated())) {
+            executor.shutdownNow();
+
+            try {
+                if (!executor.awaitTermination(5, TimeUnit.SECONDS)) {
+                    System.err.println("!!! FAILED TO STOP EXECUTOR !!!");
+                }
+            } catch (InterruptedException e) {
+                // Restore administration...
+                Thread.currentThread().interrupt();
+            }
+            executor = null;
+        }
+    }
+
+    private static class StartShellJob implements Runnable {
+        private final BundleContext context;
+        private final CommandProcessor processor;
+
+        public StartShellJob(BundleContext context, CommandProcessor processor) {
+            this.context = context;
+            this.processor = processor;
+        }
+
+        public void run() {
+            CommandSession session = processor.createSession(System.in, System.out, System.err);
+            try {
+                // wait for gosh command to be registered
+                for (int i = 0; (i < 100) && session.get("gogo:gosh") == null; ++i) {
+                    TimeUnit.MILLISECONDS.sleep(10);
+                }
+
+                String args = context.getProperty("gosh.args");
+                args = (args == null) ? "" : 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 class ShellContext implements Context {
+        public String getProperty(String name) {
+            return context.getProperty(name);
+        }
+
+        public void exit() throws Exception {
+            context.getBundle(0).stop();
+        }
+    }
+}
\ No newline at end of file
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Builtin.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Builtin.java
new file mode 100644
index 0000000..a4fc3ef
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Builtin.java
@@ -0,0 +1,498 @@
+/*
+ * 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.jline;
+
+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.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.command.Converter;
+import org.jline.builtins.Options;
+
+/**
+ * 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"};
+    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"}));
+
+    @SuppressWarnings("unchecked")
+    static Set<String> getCommands(CommandSession session) {
+        return (Set<String>) session.get(".commands");
+    }
+
+    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 Options 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(CommandSession session, Object name, Object[] argv) throws Exception {
+        Class<?> clazz;
+
+        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;
+
+            Object[] transformed = argv.clone();
+            for (int i = 0; i < transformed.length; ++i) {
+                try {
+                    transformed[i] = session.convert(types[i], transformed[i]);
+                } catch (IllegalArgumentException e) {
+                    match = false;
+                    break;
+                }
+            }
+
+            if (!match) {
+                continue;
+            }
+
+            try {
+                return c.newInstance(transformed);
+            } 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"};
+
+        Options opt = Options.compile(usage).parse(argv);
+
+        if (opt.isSet("help")) {
+            opt.usage(System.err);
+            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));
+            }
+        }
+    }
+
+    /*
+     * the following methods depend on the internals of the runtime implementation.
+     * ideally, they should be available via some API.
+     */
+
+    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"};
+
+        Options opt = Options.compile(usage).parse(argv);
+
+        if (opt.isSet("help")) {
+            opt.usage(System.err);
+            return null;
+        }
+
+        List<String> args = opt.args();
+        BufferedWriter fw = null;
+
+        if (args.size() == 1) {
+            String path = args.get(0);
+            File file = new File(Posix._pwd(session), 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"};
+
+        Options opt = Options.compile(usage).parse(argv);
+        List<String> args = opt.args();
+
+        if (opt.isSet("help")) {
+            opt.usage(System.err);
+            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;
+    }
+
+    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;
+    }
+
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Converters.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Converters.java
new file mode 100644
index 0000000..7d67d45
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Converters.java
@@ -0,0 +1,243 @@
+/*
+ * 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.jline;
+
+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.apache.felix.service.command.Converter;
+import org.apache.felix.service.command.Function;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+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/jline/src/main/java/org/apache/felix/gogo/jline/Highlighter.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Highlighter.java
new file mode 100644
index 0000000..1d91d46
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Highlighter.java
@@ -0,0 +1,274 @@
+/*
+ * 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.jline;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.felix.gogo.runtime.CommandSessionImpl;
+import org.apache.felix.gogo.runtime.EOFError;
+import org.apache.felix.gogo.runtime.Parser.Program;
+import org.apache.felix.gogo.runtime.Parser.Statement;
+import org.apache.felix.gogo.runtime.SyntaxError;
+import org.apache.felix.gogo.runtime.Token;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.command.Function;
+import org.jline.reader.LineReader;
+import org.jline.reader.LineReader.RegionType;
+import org.jline.reader.impl.DefaultHighlighter;
+import org.jline.utils.AttributedString;
+import org.jline.utils.AttributedStringBuilder;
+import org.jline.utils.AttributedStyle;
+import org.jline.utils.WCWidth;
+
+public class Highlighter extends DefaultHighlighter {
+
+    private final CommandSession session;
+
+    public Highlighter(CommandSession session) {
+        this.session = session;
+    }
+
+    public AttributedString highlight(LineReader reader, String buffer) {
+        try {
+            Program program = null;
+            List<Token> tokens = null;
+            List<Statement> statements = null;
+            String repaired = buffer + " ";
+            while (program == null) {
+                try {
+                    org.apache.felix.gogo.runtime.Parser parser = new org.apache.felix.gogo.runtime.Parser(repaired);
+                    program = parser.program();
+                    tokens = parser.tokens();
+                    statements = parser.statements();
+                } catch (EOFError e) {
+                    repaired = repaired + e.repair();
+                }
+            }
+
+            int underlineStart = -1;
+            int underlineEnd = -1;
+            int negativeStart = -1;
+            int negativeEnd = -1;
+            String search = reader.getSearchTerm();
+            if (search != null && search.length() > 0) {
+                underlineStart = buffer.indexOf(search);
+                if (underlineStart >= 0) {
+                    underlineEnd = underlineStart + search.length() - 1;
+                }
+            }
+            if (reader.getRegionActive() != RegionType.NONE) {
+                negativeStart = reader.getRegionMark();
+                negativeEnd = reader.getBuffer().cursor();
+                if (negativeStart > negativeEnd) {
+                    int x = negativeEnd;
+                    negativeEnd = negativeStart;
+                    negativeStart = x;
+                }
+                if (reader.getRegionActive() == RegionType.LINE) {
+                    while (negativeStart > 0 && reader.getBuffer().atChar(negativeStart - 1) != '\n') {
+                        negativeStart--;
+                    }
+                    while (negativeEnd < reader.getBuffer().length() - 1 && reader.getBuffer().atChar(negativeEnd + 1) != '\n') {
+                        negativeEnd++;
+                    }
+                }
+            }
+
+            Type[] types = new Type[repaired.length()];
+
+            Arrays.fill(types, Type.Unknown);
+
+            int cur = 0;
+            for (Token token : tokens) {
+                // We're on the repair side, so exit now
+                if (token.start() >= buffer.length()) {
+                    break;
+                }
+                if (token.start() > cur) {
+//                    ansi.a(buffer.substring(cur, token.start()));
+                    cur = token.start();
+                }
+                // Find corresponding statement
+                Statement statement = null;
+                for (int i = statements.size() - 1; i >= 0; i--) {
+                    Statement s = statements.get(i);
+                    if (s.start() <= cur && cur < s.start() + s.length()) {
+                        statement = s;
+                        break;
+                    }
+                }
+
+                // Reserved tokens
+                Type type = Type.Unknown;
+                if (Token.eq(token, "{")
+                        || Token.eq(token, "}")
+                        || Token.eq(token, "(")
+                        || Token.eq(token, ")")
+                        || Token.eq(token, "[")
+                        || Token.eq(token, "]")
+                        || Token.eq(token, "|")
+                        || Token.eq(token, ";")
+                        || Token.eq(token, "=")) {
+                    type = Type.Reserved;
+                } else if (token.charAt(0) == '\'' || token.charAt(0) == '"') {
+                    type = Type.String;
+                } else if (token.toString().matches("^[-+]?[0-9]*\\.?[0-9]+([eE][-+]?[0-9]+)?$")) {
+                    type = Type.Number;
+                } else if (token.charAt(0) == '$') {
+                    type = Type.Variable;
+                } else if (((Set) session.get(CommandSessionImpl.CONSTANTS)).contains(token.toString())
+                        || Token.eq(token, "null") || Token.eq(token, "false") || Token.eq(token, "true")) {
+                    type = Type.Constant;
+                } else {
+                    boolean isFirst = statement != null && statement.tokens().size() > 0
+                            && token == statement.tokens().get(0);
+                    boolean isThirdWithNext = statement != null && statement.tokens().size() > 3
+                            && token == statement.tokens().get(2);
+                    boolean isAssign = statement != null && statement.tokens().size() > 1
+                            && Token.eq(statement.tokens().get(1), "=");
+                    if (isFirst && isAssign) {
+                        type = Type.VariableName;
+                    }
+                    if (isFirst && !isAssign || isAssign && isThirdWithNext) {
+                        Object v = session.get(Shell.resolve(session, token.toString()));
+                        type = (v instanceof Function) ? Type.Function : Type.BadFunction;
+                    }
+                }
+                Arrays.fill(types, token.start(), Math.min(token.start() + token.length(), types.length), type);
+                /*
+                String valid;
+                if (token.start() + token.length() <= buffer.length()) {
+                    valid = token.toString();
+                } else {
+                    valid = token.subSequence(0, buffer.length() - token.start()).toString();
+                }
+                switch (type) {
+                    case Reserved:
+                        ansi.fg(Color.MAGENTA).a(valid).fg(Color.DEFAULT);
+                        break;
+                    case String:
+                    case Number:
+                    case Constant:
+                        ansi.fg(Color.GREEN).a(valid).fg(Color.DEFAULT);
+                        break;
+                    case Variable:
+                    case VariableName:
+                        ansi.fg(Color.CYAN).a(valid).fg(Color.DEFAULT);
+                        break;
+                    case Function:
+                        ansi.fg(Color.BLUE).a(valid).fg(Color.DEFAULT);
+                        break;
+                    case BadFunction:
+                        ansi.fg(Color.RED).a(valid).fg(Color.DEFAULT);
+                        break;
+                    default:
+                        ansi.a(valid);
+                        break;
+                }
+                */
+                cur = Math.min(token.start() + token.length(), buffer.length());
+            }
+
+            if (buffer.length() < repaired.length()) {
+                Arrays.fill(types, buffer.length(), repaired.length(), Type.Repair);
+            }
+
+            AttributedStringBuilder sb = new AttributedStringBuilder();
+            Type prevType = Type.Unknown;
+            for (int i = 0; i < repaired.length(); i++) {
+                if (i == underlineStart) {
+                    sb.style(sb.style().underline());
+                }
+                if (i == negativeStart) {
+                    sb.style(sb.style().inverse());
+                }
+                if (types[i] != prevType) {
+                    prevType = types[i];
+                    switch (prevType) {
+                        case Reserved:
+                            sb.style(sb.style().foreground(AttributedStyle.MAGENTA));
+                            break;
+                        case String:
+                        case Number:
+                        case Constant:
+                            sb.style(sb.style().foreground(AttributedStyle.GREEN));
+                            break;
+                        case Variable:
+                        case VariableName:
+                            sb.style(sb.style().foreground(AttributedStyle.CYAN));
+                            break;
+                        case Function:
+                            sb.style(sb.style().foreground(AttributedStyle.BLUE));
+                            break;
+                        case BadFunction:
+                            sb.style(sb.style().foreground(AttributedStyle.RED));
+                            break;
+                        case Repair:
+                            sb.style(sb.style().foreground(AttributedStyle.BLACK + AttributedStyle.BRIGHT));
+                            break;
+                        default:
+                            sb.style(sb.style().foregroundDefault());
+                            break;
+                    }
+                }
+                char c = repaired.charAt(i);
+                if (c == '\t' || c == '\n') {
+                    sb.append(c);
+                } else if (c < 32) {
+                    sb.style(sb.style().inverseNeg())
+                            .append('^')
+                            .append((char) (c + '@'))
+                            .style(sb.style().inverseNeg());
+                } else {
+                    int w = WCWidth.wcwidth(c);
+                    if (w > 0) {
+                        sb.append(c);
+                    }
+                }
+                if (i == underlineEnd) {
+                    sb.style(sb.style().underlineOff());
+                }
+                if (i == negativeEnd) {
+                    sb.style(sb.style().inverseOff());
+                }
+            }
+
+            return sb.toAttributedString();
+        } catch (SyntaxError e) {
+            return super.highlight(reader, buffer);
+        }
+    }
+
+    enum Type {
+        Reserved,
+        String,
+        Number,
+        Variable,
+        VariableName,
+        Function,
+        BadFunction,
+        Value,
+        Constant,
+        Unknown,
+        Repair
+    }
+
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/JLineCommands.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/JLineCommands.java
new file mode 100644
index 0000000..498e12e
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/JLineCommands.java
@@ -0,0 +1,266 @@
+/*
+ * 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.jline;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.felix.gogo.jline.Shell.Context;
+import org.apache.felix.gogo.runtime.CommandSessionImpl;
+import org.apache.felix.service.command.CommandProcessor;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.command.Function;
+import org.jline.builtins.Completers.DirectoriesCompleter;
+import org.jline.builtins.Completers.FilesCompleter;
+import org.jline.builtins.Options;
+import org.jline.reader.Candidate;
+import org.jline.reader.LineReader;
+import org.jline.reader.ParsedLine;
+import org.jline.reader.Widget;
+import org.jline.terminal.Attributes;
+import org.jline.terminal.Terminal;
+import org.jline.utils.InfoCmp.Capability;
+
+public class JLineCommands {
+
+    public static final String[] functions = {
+            "keymap", "setopt", "unsetopt", "complete", "history",
+            "less", "watch", "nano", "widget", "tmux",
+            "__files", "__directories", "__usage_completion"
+    };
+
+    private final CommandProcessor processor;
+
+    private final org.jline.builtins.Commands commands = new org.jline.builtins.Commands();
+
+    public JLineCommands(CommandProcessor processor) {
+        this.processor = processor;
+    }
+
+    public void tmux(final CommandSession session, String[] argv) throws Exception {
+        commands.tmux(Shell.getTerminal(session),
+                System.out, System.err,
+                () -> session.get(".tmux"),
+                t -> session.put(".tmux", t),
+                c -> startShell(session, c), argv);
+    }
+
+    private void startShell(CommandSession session, Terminal terminal) {
+        new Thread(() -> runShell(session, terminal), terminal.getName() + " shell").start();
+    }
+
+    private void runShell(CommandSession session, Terminal terminal) {
+        InputStream in = terminal.input();
+        PrintStream out = new PrintStream(terminal.output());
+        CommandSession newSession = processor.createSession(in, out, out);
+        newSession.put(Shell.VAR_TERMINAL, terminal);
+        newSession.put(".tmux", session.get(".tmux"));
+        Context context = new Context() {
+            public String getProperty(String name) {
+                return System.getProperty(name);
+            }
+            public void exit() throws Exception {
+                terminal.close();
+            }
+        };
+        try {
+            new Shell(context, processor, terminal).gosh(newSession, new String[]{"--login"});
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                terminal.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    public void nano(final CommandSession session, String[] argv) throws Exception {
+        commands.nano(Shell.getTerminal(session), System.out, System.err, Shell.cwd(session), argv);
+    }
+
+    public void watch(final CommandSession session, String[] argv) throws IOException, InterruptedException {
+        final String[] usage = {
+                "watch - watches & refreshes the output of a command",
+                "Usage: watch [OPTIONS] COMMAND",
+                "  -? --help                    Show help",
+                "  -n --interval                Interval between executions of the command in seconds",
+                "  -a --append                  The output should be appended but not clear the console"
+        };
+        final Options opt = Options.compile(usage).parse(argv);
+        if (opt.isSet("help")) {
+            opt.usage(System.err);
+            return;
+        }
+        List<String> args = opt.args();
+        if (args.isEmpty()) {
+            System.err.println("Argument expected");
+            return;
+        }
+        ScheduledExecutorService executorService = Executors.newSingleThreadScheduledExecutor();
+        final Terminal terminal = Shell.getTerminal(session);
+        final CommandProcessor processor = Shell.getProcessor(session);
+        try {
+            int interval = 1;
+            if (opt.isSet("interval")) {
+                interval = opt.getNumber("interval");
+                if (interval < 1) {
+                    interval = 1;
+                }
+            }
+            final String cmd = String.join(" ", args);
+            Runnable task = () -> {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                InputStream is = new ByteArrayInputStream(new byte[0]);
+                PrintStream os = new PrintStream(baos);
+                if (opt.isSet("append") || !terminal.puts(Capability.clear_screen)) {
+                    terminal.writer().println();
+                }
+                try {
+                    CommandSession ns = processor.createSession(is, os, os);
+                    Set<String> vars = Shell.getCommands(session);
+                    for (String n : vars) {
+                        ns.put(n, session.get(n));
+                    }
+                    ns.execute(cmd);
+                } catch (Throwable t) {
+                    t.printStackTrace(os);
+                }
+                os.flush();
+                terminal.writer().print(baos.toString());
+                terminal.writer().flush();
+            };
+            executorService.scheduleAtFixedRate(task, 0, interval, TimeUnit.SECONDS);
+            Attributes attr = terminal.enterRawMode();
+            terminal.reader().read();
+            terminal.setAttributes(attr);
+        } finally {
+            executorService.shutdownNow();
+        }
+    }
+
+    public void less(CommandSession session, String[] argv) throws IOException, InterruptedException {
+        commands.less(Shell.getTerminal(session), System.out, System.err, Shell.cwd(session), argv);
+    }
+
+    public void history(CommandSession session, String[] argv) throws IOException {
+        commands.history(Shell.getReader(session), System.out, System.err, argv);
+    }
+
+    public void complete(CommandSession session, String[] argv) {
+        commands.complete(Shell.getReader(session), System.out, System.err, Shell.getCompletions(session), argv);
+    }
+
+    public void widget(final CommandSession session, String[] argv) throws Exception {
+        java.util.function.Function<String, Widget> creator = func -> () -> {
+            try {
+                session.execute(func);
+            } catch (Exception e) {
+                // TODO: log exception ?
+                return false;
+            }
+            return true;
+        };
+        commands.widget(Shell.getReader(session), System.out, System.err, creator, argv);
+    }
+
+    public void keymap(CommandSession session, String[] argv) {
+        commands.keymap(Shell.getReader(session), System.out, System.err, argv);
+    }
+
+    public void setopt(CommandSession session, String[] argv) {
+        commands.setopt(Shell.getReader(session), System.out, System.err, argv);
+    }
+
+    public void unsetopt(CommandSession session, String[] argv) {
+        commands.unsetopt(Shell.getReader(session), System.out, System.err, argv);
+    }
+
+    public List<Candidate> __files(CommandSession session) {
+        ParsedLine line = Shell.getParsedLine(session);
+        LineReader reader = Shell.getReader(session);
+        List<Candidate> candidates = new ArrayList<>();
+        new FilesCompleter(new File(Shell.cwd(session))).complete(reader, line, candidates);
+        return candidates;
+    }
+
+    public List<Candidate> __directories(CommandSession session) {
+        ParsedLine line = Shell.getParsedLine(session);
+        LineReader reader = Shell.getReader(session);
+        List<Candidate> candidates = new ArrayList<>();
+        new DirectoriesCompleter(new File(Shell.cwd(session))).complete(reader, line, candidates);
+        return candidates;
+    }
+
+    public void __usage_completion(CommandSession session, String command) throws Exception {
+        Object func = session.get(command.contains(":") ? command : "*:" + command);
+        if (func instanceof Function) {
+            ByteArrayInputStream bais = new ByteArrayInputStream(new byte[0]);
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ByteArrayOutputStream baes = new ByteArrayOutputStream();
+            CommandSession ts = ((CommandSessionImpl) session).processor().createSession(bais, new PrintStream(baos), new PrintStream(baes));
+            ts.execute(command + " --help");
+
+            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
+                    "(.*)";                               // 7: description
+            Pattern pattern = Pattern.compile(regex);
+            for (String l : baes.toString().split("\n")) {
+                Matcher matcher = pattern.matcher(l);
+                if (matcher.matches()) {
+                    List<String> args = new ArrayList<>();
+                    if (matcher.group(1) != null) {
+                        args.add("--short-option");
+                        args.add(matcher.group(1));
+                    }
+                    if (matcher.group(3) != null) {
+                        args.add("--long-option");
+                        args.add(matcher.group(1));
+                    }
+                    if (matcher.group(4) != null) {
+                        args.add("--argument");
+                        args.add("");
+                    }
+                    if (matcher.group(7) != null) {
+                        args.add("--description");
+                        args.add(matcher.group(7));
+                    }
+                    complete(session, args.toArray(new String[args.size()]));
+                }
+            }
+        }
+    }
+
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/JLineCompletionEnvironment.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/JLineCompletionEnvironment.java
new file mode 100644
index 0000000..93b31ef
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/JLineCompletionEnvironment.java
@@ -0,0 +1,60 @@
+/*
+ * 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.jline;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.felix.service.command.CommandSession;
+import org.jline.builtins.Completers.CompletionData;
+import org.jline.builtins.Completers.CompletionEnvironment;
+import org.jline.reader.LineReader;
+import org.jline.reader.ParsedLine;
+
+public class JLineCompletionEnvironment implements CompletionEnvironment {
+
+    private final CommandSession session;
+
+    public JLineCompletionEnvironment(CommandSession session) {
+        this.session = session;
+    }
+
+    public Map<String, List<CompletionData>> getCompletions() {
+        return Shell.getCompletions(session);
+    }
+
+    public Set<String> getCommands() {
+        return Shell.getCommands(session);
+    }
+
+    public String resolveCommand(String command) {
+        return Shell.resolve(session, command);
+    }
+
+    public String commandName(String command) {
+        int idx = command.indexOf(':');
+        return idx >= 0 ? command.substring(idx + 1) : command;
+    }
+
+    public Object evaluate(LineReader reader, ParsedLine line, String func) throws Exception {
+        session.put(Shell.VAR_COMMAND_LINE, line);
+        return session.execute(func);
+    }
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Main.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Main.java
new file mode 100644
index 0000000..8d78f6a
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Main.java
@@ -0,0 +1,113 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.gogo.jline;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintStream;
+
+import org.apache.felix.gogo.jline.Shell.Context;
+import org.apache.felix.gogo.jline.ssh.Ssh;
+import org.apache.felix.gogo.jline.telnet.Telnet;
+import org.apache.felix.gogo.runtime.CommandProcessorImpl;
+import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl;
+import org.apache.felix.service.command.CommandSession;
+import org.jline.terminal.Terminal;
+import org.jline.terminal.TerminalBuilder;
+
+public class Main {
+
+    public static void main(String[] args) throws IOException {
+        InputStream sin = System.in;
+        PrintStream sout = System.out;
+        PrintStream serr = System.err;
+
+        try (Terminal terminal = TerminalBuilder.builder()
+                .name("gogo")
+                .type(System.getenv("TERM"))
+                .system(true)
+                .streams(sin, sout)
+                .build()) {
+            ThreadIOImpl tio = new ThreadIOImpl();
+            tio.start();
+            try {
+                CommandProcessorImpl processor = new CommandProcessorImpl(tio);
+                Context context = new MyContext();
+                Shell shell = new Shell(context, processor, terminal);
+                processor.addCommand("gogo", processor, "addCommand");
+                processor.addCommand("gogo", processor, "removeCommand");
+                processor.addCommand("gogo", processor, "eval");
+                register(processor, new Builtin(), Builtin.functions);
+                register(processor, new Procedural(), Procedural.functions);
+                register(processor, new Posix(), Posix.functions);
+                register(processor, shell, Shell.functions);
+                register(processor, new JLineCommands(processor), JLineCommands.functions);
+                try {
+                    register(processor, new Telnet(processor), Telnet.functions);
+                } catch (Throwable t) {
+                    // ignore
+                }
+                try {
+                    register(processor, new Ssh(processor), Ssh.functions);
+                } catch (Throwable t) {
+                    // ignore
+                }
+                PrintStream pout = new PrintStream(terminal.output());
+                CommandSession session = processor.createSession(terminal.input(), pout, pout);
+                session.put(Shell.VAR_CONTEXT, context);
+                session.put(Shell.VAR_TERMINAL, terminal);
+                try {
+                    String[] argv = new String[args.length + 1];
+                    argv[0] = "--login";
+                    System.arraycopy(args, 0, argv, 1, args.length);
+                    shell.gosh(session, argv);
+                } 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();
+                }
+            } finally {
+                tio.stop();
+            }
+        }
+    }
+
+    static void register(CommandProcessorImpl processor, Object target, String[] functions) {
+        for (String function : functions) {
+            processor.addCommand("gogo", target, function);
+        }
+    }
+
+    private static class MyContext implements Context {
+
+        public String getProperty(String name) {
+            return System.getProperty(name);
+        }
+
+        public void exit() throws Exception {
+            System.exit(0);
+        }
+    }
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ParsedLineImpl.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ParsedLineImpl.java
new file mode 100644
index 0000000..22f0cdc
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ParsedLineImpl.java
@@ -0,0 +1,97 @@
+/*
+ * 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.jline;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.felix.gogo.runtime.Parser.Program;
+import org.apache.felix.gogo.runtime.Token;
+import org.jline.reader.ParsedLine;
+
+public class ParsedLineImpl implements ParsedLine {
+
+    private final Program program;
+    private final String source;
+    private final int cursor;
+    private final List<String> tokens;
+    private final int wordIndex;
+    private final int wordCursor;
+
+    public ParsedLineImpl(Program program, Token line, int cursor, List<Token> tokens) {
+        this.program = program;
+        this.source = line.toString();
+        this.cursor = cursor - line.start();
+        this.tokens = new ArrayList<String>();
+        for (Token token : tokens) {
+            this.tokens.add(token.toString());
+        }
+        int wi = tokens.size();
+        int wc = 0;
+        if (cursor >= 0) {
+            for (int i = 0; i < tokens.size(); i++) {
+                Token t = tokens.get(i);
+                if (t.start() > cursor) {
+                    wi = i;
+                    wc = 0;
+                    this.tokens.add(i, "");
+                    break;
+                }
+                if (t.start() + t.length() >= cursor) {
+                    wi = i;
+                    wc = cursor - t.start();
+                    break;
+                }
+            }
+        }
+        if (wi == tokens.size()) {
+            this.tokens.add("");
+        }
+        wordIndex = wi;
+        wordCursor = wc;
+    }
+
+    public String word() {
+        return tokens.get(wordIndex());
+    }
+
+    public int wordCursor() {
+        return wordCursor;
+    }
+
+    public int wordIndex() {
+        return wordIndex;
+    }
+
+    public List<String> words() {
+        return tokens;
+    }
+
+    public String line() {
+        return source;
+    }
+
+    public int cursor() {
+        return cursor;
+    }
+
+    public Program program() {
+        return program;
+    }
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Parser.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Parser.java
new file mode 100644
index 0000000..4864252
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Parser.java
@@ -0,0 +1,71 @@
+/*
+ * 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.jline;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.felix.gogo.runtime.EOFError;
+import org.apache.felix.gogo.runtime.Parser.Program;
+import org.apache.felix.gogo.runtime.Parser.Statement;
+import org.apache.felix.gogo.runtime.SyntaxError;
+import org.apache.felix.gogo.runtime.Token;
+import org.jline.reader.ParsedLine;
+
+public class Parser implements org.jline.reader.Parser {
+
+    public ParsedLine parse(String line, int cursor) throws org.jline.reader.SyntaxError {
+        try {
+            return doParse(line, cursor);
+        } catch (EOFError e) {
+            throw new org.jline.reader.EOFError(e.line(), e.column(), e.getMessage(), e.missing());
+        } catch (SyntaxError e) {
+            throw new org.jline.reader.SyntaxError(e.line(), e.column(), e.getMessage());
+        }
+    }
+
+    private ParsedLine doParse(CharSequence line, int cursor) throws SyntaxError {
+        org.apache.felix.gogo.runtime.Parser parser = new org.apache.felix.gogo.runtime.Parser(line);
+        Program program = parser.program();
+        List<Statement> statements = parser.statements();
+        // Find corresponding statement
+        Statement statement = null;
+        for (int i = statements.size() - 1; i >= 0; i--) {
+            Statement s = statements.get(i);
+            if (s.start() <= cursor) {
+                boolean isOk = true;
+                // check if there are only spaces after the previous statement
+                if (s.start() + s.length() < cursor) {
+                    for (int j = s.start() + s.length(); isOk && j < cursor; j++) {
+                        isOk = Character.isWhitespace(line.charAt(j));
+                    }
+                }
+                statement = s;
+                break;
+            }
+        }
+        if (statement != null) {
+            return new ParsedLineImpl(program, statement, cursor, statement.tokens());
+        } else {
+            // TODO:
+            return new ParsedLineImpl(program, program, cursor, Collections.<Token>singletonList(program));
+        }
+    }
+
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Posix.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Posix.java
new file mode 100644
index 0000000..05c4908
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Posix.java
@@ -0,0 +1,816 @@
+/*
+ * 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.jline;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.felix.service.command.CommandSession;
+import org.jline.builtins.Options;
+
+/**
+ * Posix-like utilities.
+ *
+ * @see <a href="http://www.opengroup.org/onlinepubs/009695399/utilities/contents.html">
+ * http://www.opengroup.org/onlinepubs/009695399/utilities/contents.html</a>
+ */
+public class Posix {
+    static final String[] functions = {"cat", "echo", "grep", "sort", "sleep", "cd", "pwd", "ls"};
+
+    static final String CWD = "_cwd";
+
+    public static File _pwd(CommandSession session) {
+        try {
+            File cwd = (File) session.get(CWD);
+            if (cwd == null) {
+                cwd = new File(".").getCanonicalFile();
+                session.put(CWD, cwd);
+            }
+            return cwd;
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public static void sort(CommandSession session, String[] argv) throws IOException {
+        final String[] usage = {
+                "sort -  writes sorted standard input to standard output.",
+                "Usage: sort [OPTIONS] [FILES]",
+                "  -? --help                    show help",
+                "  -f --ignore-case             fold lower case to upper case characters",
+                "  -r --reverse                 reverse the result of comparisons",
+                "  -u --unique                  output only the first of an equal run",
+                "  -t --field-separator=SEP     use SEP instead of non-blank to blank transition",
+                "  -b --ignore-leading-blanks   ignore leading blancks",
+                "     --numeric-sort            compare according to string numerical value",
+                "  -k --key=KEY                 fields to use for sorting separated by whitespaces"};
+
+        Options opt = Options.compile(usage).parse(argv);
+
+        if (opt.isSet("help")) {
+            opt.usage(System.err);
+            return;
+        }
+
+        List<String> args = opt.args();
+
+        List<String> lines = new ArrayList<String>();
+        if (!args.isEmpty()) {
+            for (String filename : args) {
+                BufferedReader reader = new BufferedReader(new InputStreamReader(
+                        Shell.cwd(session).resolve(filename).toURL().openStream()));
+                try {
+                    read(reader, lines);
+                } finally {
+                    reader.close();
+                }
+            }
+        } else {
+            BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
+            read(r, lines);
+        }
+
+        String separator = opt.get("field-separator");
+        boolean caseInsensitive = opt.isSet("ignore-case");
+        boolean reverse = opt.isSet("reverse");
+        boolean ignoreBlanks = opt.isSet("ignore-leading-blanks");
+        boolean numeric = opt.isSet("numeric-sort");
+        boolean unique = opt.isSet("unique");
+        List<String> sortFields = opt.getList("key");
+
+        char sep = (separator == null || separator.length() == 0) ? '\0' : separator.charAt(0);
+        Collections.sort(lines, new SortComparator(caseInsensitive, reverse, ignoreBlanks, numeric, sep, sortFields));
+        String last = null;
+        for (String s : lines) {
+            if (!unique || last == null || !s.equals(last)) {
+                System.out.println(s);
+            }
+            last = s;
+        }
+    }
+
+    protected static void read(BufferedReader r, List<String> lines) throws IOException {
+        for (String s = r.readLine(); s != null; s = r.readLine()) {
+            lines.add(s);
+        }
+    }
+
+    public static List<String> parseSubstring(String value) {
+        List<String> pieces = new ArrayList<String>();
+        StringBuilder ss = new StringBuilder();
+        // int kind = SIMPLE; // assume until proven otherwise
+        boolean wasStar = false; // indicates last piece was a star
+        boolean leftstar = false; // track if the initial piece is a star
+        boolean rightstar = false; // track if the final piece is a star
+
+        int idx = 0;
+
+        // We assume (sub)strings can contain leading and trailing blanks
+        boolean escaped = false;
+        loop:
+        for (; ; ) {
+            if (idx >= value.length()) {
+                if (wasStar) {
+                    // insert last piece as "" to handle trailing star
+                    rightstar = true;
+                } else {
+                    pieces.add(ss.toString());
+                    // accumulate the last piece
+                    // note that in the case of
+                    // (cn=); this might be
+                    // the string "" (!=null)
+                }
+                ss.setLength(0);
+                break loop;
+            }
+
+            // Read the next character and account for escapes.
+            char c = value.charAt(idx++);
+            if (!escaped && ((c == '(') || (c == ')'))) {
+                throw new IllegalArgumentException(
+                        "Illegal value: " + value);
+            } else if (!escaped && (c == '*')) {
+                if (wasStar) {
+                    // encountered two successive stars;
+                    // I assume this is illegal
+                    throw new IllegalArgumentException("Invalid filter string: " + value);
+                }
+                if (ss.length() > 0) {
+                    pieces.add(ss.toString()); // accumulate the pieces
+                    // between '*' occurrences
+                }
+                ss.setLength(0);
+                // if this is a leading star, then track it
+                if (pieces.size() == 0) {
+                    leftstar = true;
+                }
+                wasStar = true;
+            } else if (!escaped && (c == '\\')) {
+                escaped = true;
+            } else {
+                escaped = false;
+                wasStar = false;
+                ss.append(c);
+            }
+        }
+        if (leftstar || rightstar || pieces.size() > 1) {
+            // insert leading and/or trailing "" to anchor ends
+            if (rightstar) {
+                pieces.add("");
+            }
+            if (leftstar) {
+                pieces.add(0, "");
+            }
+        }
+        return pieces;
+    }
+
+    public static boolean compareSubstring(List<String> pieces, String s) {
+        // Walk the pieces to match the string
+        // There are implicit stars between each piece,
+        // and the first and last pieces might be "" to anchor the match.
+        // assert (pieces.length > 1)
+        // minimal case is <string>*<string>
+
+        boolean result = true;
+        int len = pieces.size();
+
+        int index = 0;
+
+        loop:
+        for (int i = 0; i < len; i++) {
+            String piece = pieces.get(i);
+
+            // If this is the first piece, then make sure the
+            // string starts with it.
+            if (i == 0) {
+                if (!s.startsWith(piece)) {
+                    result = false;
+                    break loop;
+                }
+            }
+
+            // If this is the last piece, then make sure the
+            // string ends with it.
+            if (i == len - 1) {
+                if (s.endsWith(piece)) {
+                    result = true;
+                } else {
+                    result = false;
+                }
+                break loop;
+            }
+
+            // If this is neither the first or last piece, then
+            // make sure the string contains it.
+            if ((i > 0) && (i < (len - 1))) {
+                index = s.indexOf(piece, index);
+                if (index < 0) {
+                    result = false;
+                    break loop;
+                }
+            }
+
+            // Move string index beyond the matching piece.
+            index += piece.length();
+        }
+
+        return result;
+    }
+
+    private static void cat(final BufferedReader reader, boolean displayLineNumbers) throws IOException {
+        String line;
+        int lineno = 1;
+        try {
+            while ((line = reader.readLine()) != null) {
+                if (displayLineNumbers) {
+                    System.out.print(String.format("%6d  ", lineno++));
+                }
+                System.out.println(line);
+            }
+        } finally {
+            reader.close();
+        }
+    }
+
+    private static <T> void addAll(List<? super T> list, T[] array) {
+        if (array != null) {
+            Collections.addAll(list, array);
+        }
+    }
+
+    public File pwd(CommandSession session, String[] argv) throws IOException {
+        final String[] usage = {
+                "pwd - get current directory",
+                "Usage: pwd [OPTIONS]",
+                "  -? --help                show help"
+        };
+        Options opt = Options.compile(usage).parse(argv);
+        if (opt.isSet("help")) {
+            opt.usage(System.err);
+            return null;
+        }
+        if (!opt.args().isEmpty()) {
+            System.err.println("usage: pwd");
+            return null;
+        }
+        File cwd = (File) session.get(CWD);
+        if (cwd == null) {
+            cwd = new File(".").getCanonicalFile();
+            session.put(CWD, cwd);
+        }
+        return cwd;
+    }
+
+    public File cd(CommandSession session, String[] argv)
+            throws IOException {
+        final String[] usage = {
+                "cd - get current directory",
+                "Usage: cd [OPTIONS] DIRECTORY",
+                "  -? --help                show help"
+        };
+        Options opt = Options.compile(usage).parse(argv);
+        if (opt.isSet("help")) {
+            opt.usage(System.err);
+            return null;
+        }
+        if (opt.args().size() != 1) {
+            System.err.println("usage: cd DIRECTORY");
+            return null;
+        }
+        File cwd = pwd(session, new String[0]);
+        String dir = opt.args().get(0);
+
+        URI curUri = cwd.toURI();
+        URI newUri = curUri.resolve(dir);
+
+        cwd = new File(newUri);
+        if (!cwd.exists()) {
+            throw new IOException("Directory does not exist");
+        } else if (!cwd.isDirectory()) {
+            throw new IOException("Target is not a directory");
+        }
+        session.put(CWD, cwd.getCanonicalFile());
+        return cwd;
+    }
+
+    public Collection<File> ls(CommandSession session, String[] argv) throws IOException {
+        final String[] usage = {
+                "ls - list files",
+                "Usage: ls [OPTIONS] PATTERNS...",
+                "  -? --help                show help"
+        };
+        Options opt = Options.compile(usage).parse(argv);
+        if (opt.isSet("help")) {
+            opt.usage(System.err);
+            return null;
+        }
+        if (opt.args().isEmpty()) {
+            opt.args().add("*");
+        }
+        opt.args().remove(0);
+        List<File> files = new ArrayList<File>();
+        for (String pattern : opt.args()) {
+            pattern = ((pattern == null) || (pattern.length() == 0)) ? "." : pattern;
+            pattern = ((pattern.charAt(0) != File.separatorChar) && (pattern.charAt(0) != '.'))
+                    ? "./" + pattern : pattern;
+            int idx = pattern.lastIndexOf(File.separatorChar);
+            String parent = (idx < 0) ? "." : pattern.substring(0, idx + 1);
+            String target = (idx < 0) ? pattern : pattern.substring(idx + 1);
+
+            File actualParent = ((parent.charAt(0) == File.separatorChar)
+                    ? new File(parent)
+                    : new File(pwd(session, new String[0]), parent)).getCanonicalFile();
+
+            idx = target.indexOf(File.separatorChar, idx);
+            boolean isWildcarded = (target.indexOf('*', idx) >= 0);
+            if (isWildcarded) {
+                if (!actualParent.exists()) {
+                    throw new IOException("File does not exist");
+                }
+                final List<String> pieces = parseSubstring(target);
+                addAll(files, actualParent.listFiles(new FileFilter() {
+                    public boolean accept(File pathname) {
+                        return compareSubstring(pieces, pathname.getName());
+                    }
+                }));
+            } else {
+                File actualTarget = new File(actualParent, target).getCanonicalFile();
+                if (!actualTarget.exists()) {
+                    throw new IOException("File does not exist");
+                }
+                if (actualTarget.isDirectory()) {
+                    addAll(files, actualTarget.listFiles());
+                } else {
+                    files.add(actualTarget);
+                }
+            }
+        }
+        return files;
+    }
+
+    public void cat(CommandSession session, String[] argv) throws Exception {
+        final String[] usage = {
+                "cat - concatenate and print FILES",
+                "Usage: cat [OPTIONS] [FILES]",
+                "  -? --help                show help",
+                "  -n                       number the output lines, starting at 1"
+        };
+
+        Options opt = Options.compile(usage).parse(argv);
+
+        if (opt.isSet("help")) {
+            opt.usage(System.err);
+            return;
+        }
+
+        List<String> args = opt.args();
+        if (args.isEmpty()) {
+            args = Collections.singletonList("-");
+        }
+
+        URI cwd = Shell.cwd(session);
+        for (String arg : args) {
+            InputStream is;
+            if ("-".equals(arg)) {
+                is = System.in;
+
+            } else {
+                is = cwd.resolve(arg).toURL().openStream();
+            }
+            cat(new BufferedReader(new InputStreamReader(is)), opt.isSet("n"));
+        }
+    }
+
+    public void echo(Object[] argv) {
+        final String[] usage = {
+                "echo - echoes or prints ARGUMENT to standard output",
+                "Usage: echo [OPTIONS] [ARGUMENTS]",
+                "  -? --help                show help",
+                "  -n                       no trailing new line"
+        };
+
+        Options opt = Options.compile(usage).parse(argv);
+
+        if (opt.isSet("help")) {
+            opt.usage(System.err);
+            return;
+        }
+
+        List<String> args = opt.args();
+        StringBuilder buf = new StringBuilder();
+        if (args != null) {
+            for (String arg : args) {
+                if (buf.length() > 0)
+                    buf.append(' ');
+                buf.append(arg);
+            }
+        }
+        if (opt.isSet("n")) {
+            System.out.print(buf);
+        } else {
+            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"};
+
+        Options opt = Options.compile(usage).parse(argv);
+
+        if (opt.isSet("help")) {
+            opt.usage(System.err);
+            return true;
+        }
+
+        List<String> args = opt.args();
+
+        if (args.isEmpty()) {
+            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 void sleep(String[] argv) throws InterruptedException {
+        final String[] usage = {
+                "sleep -  suspend execution for an interval of time",
+                "Usage: sleep seconds",
+                "  -? --help                    show help"};
+
+        Options opt = Options.compile(usage).parse(argv);
+
+        if (opt.isSet("help")) {
+            opt.usage(System.err);
+            return;
+        }
+
+        List<String> args = opt.args();
+        if (args.size() != 1) {
+            System.err.println("usage: sleep seconds");
+        } else {
+            int s = Integer.parseInt(args.get(0));
+            Thread.sleep(s * 1000);
+        }
+    }
+
+    public static class SortComparator implements Comparator<String> {
+
+        private static Pattern fpPattern;
+
+        static {
+            final String Digits = "(\\p{Digit}+)";
+            final String HexDigits = "(\\p{XDigit}+)";
+            final String Exp = "[eE][+-]?" + Digits;
+            final String fpRegex = "([\\x00-\\x20]*[+-]?(NaN|Infinity|(((" + Digits + "(\\.)?(" + Digits + "?)(" + Exp + ")?)|(\\.(" + Digits + ")(" + Exp + ")?)|(((0[xX]" + HexDigits + "(\\.)?)|(0[xX]" + HexDigits + "?(\\.)" + HexDigits + "))[pP][+-]?" + Digits + "))" + "[fFdD]?))[\\x00-\\x20]*)(.*)";
+            fpPattern = Pattern.compile(fpRegex);
+        }
+
+        private boolean caseInsensitive;
+        private boolean reverse;
+        private boolean ignoreBlanks;
+        private boolean numeric;
+        private char separator;
+        private List<Key> sortKeys;
+
+        public SortComparator(boolean caseInsensitive,
+                              boolean reverse,
+                              boolean ignoreBlanks,
+                              boolean numeric,
+                              char separator,
+                              List<String> sortFields) {
+            this.caseInsensitive = caseInsensitive;
+            this.reverse = reverse;
+            this.separator = separator;
+            this.ignoreBlanks = ignoreBlanks;
+            this.numeric = numeric;
+            if (sortFields == null || sortFields.size() == 0) {
+                sortFields = new ArrayList<String>();
+                sortFields.add("1");
+            }
+            sortKeys = new ArrayList<Key>();
+            for (String f : sortFields) {
+                sortKeys.add(new Key(f));
+            }
+        }
+
+        public int compare(String o1, String o2) {
+            int res = 0;
+
+            List<Integer> fi1 = getFieldIndexes(o1);
+            List<Integer> fi2 = getFieldIndexes(o2);
+            for (Key key : sortKeys) {
+                int[] k1 = getSortKey(o1, fi1, key);
+                int[] k2 = getSortKey(o2, fi2, key);
+                if (key.numeric) {
+                    Double d1 = getDouble(o1, k1[0], k1[1]);
+                    Double d2 = getDouble(o2, k2[0], k2[1]);
+                    res = d1.compareTo(d2);
+                } else {
+                    res = compareRegion(o1, k1[0], k1[1], o2, k2[0], k2[1], key.caseInsensitive);
+                }
+                if (res != 0) {
+                    if (key.reverse) {
+                        res = -res;
+                    }
+                    break;
+                }
+            }
+            return res;
+        }
+
+        protected Double getDouble(String s, int start, int end) {
+            Matcher m = fpPattern.matcher(s.substring(start, end));
+            m.find();
+            return new Double(s.substring(0, m.end(1)));
+        }
+
+        protected int compareRegion(String s1, int start1, int end1, String s2, int start2, int end2, boolean caseInsensitive) {
+            int n1 = end1, n2 = end2;
+            for (int i1 = start1, i2 = start2; i1 < end1 && i2 < n2; i1++, i2++) {
+                char c1 = s1.charAt(i1);
+                char c2 = s2.charAt(i2);
+                if (c1 != c2) {
+                    if (caseInsensitive) {
+                        c1 = Character.toUpperCase(c1);
+                        c2 = Character.toUpperCase(c2);
+                        if (c1 != c2) {
+                            c1 = Character.toLowerCase(c1);
+                            c2 = Character.toLowerCase(c2);
+                            if (c1 != c2) {
+                                return c1 - c2;
+                            }
+                        }
+                    } else {
+                        return c1 - c2;
+                    }
+                }
+            }
+            return n1 - n2;
+        }
+
+        protected int[] getSortKey(String str, List<Integer> fields, Key key) {
+            int start;
+            int end;
+            if (key.startField * 2 <= fields.size()) {
+                start = fields.get((key.startField - 1) * 2);
+                if (key.ignoreBlanksStart) {
+                    while (start < fields.get((key.startField - 1) * 2 + 1) && Character.isWhitespace(str.charAt(start))) {
+                        start++;
+                    }
+                }
+                if (key.startChar > 0) {
+                    start = Math.min(start + key.startChar - 1, fields.get((key.startField - 1) * 2 + 1));
+                }
+            } else {
+                start = 0;
+            }
+            if (key.endField > 0 && key.endField * 2 <= fields.size()) {
+                end = fields.get((key.endField - 1) * 2);
+                if (key.ignoreBlanksEnd) {
+                    while (end < fields.get((key.endField - 1) * 2 + 1) && Character.isWhitespace(str.charAt(end))) {
+                        end++;
+                    }
+                }
+                if (key.endChar > 0) {
+                    end = Math.min(end + key.endChar - 1, fields.get((key.endField - 1) * 2 + 1));
+                }
+            } else {
+                end = str.length();
+            }
+            return new int[]{start, end};
+        }
+
+        protected List<Integer> getFieldIndexes(String o) {
+            List<Integer> fields = new ArrayList<Integer>();
+            if (o.length() > 0) {
+                if (separator == '\0') {
+                    int i = 0;
+                    fields.add(0);
+                    for (int idx = 1; idx < o.length(); idx++) {
+                        if (Character.isWhitespace(o.charAt(idx)) && !Character.isWhitespace(o.charAt(idx - 1))) {
+                            fields.add(idx - 1);
+                            fields.add(idx);
+                        }
+                    }
+                    fields.add(o.length() - 1);
+                } else {
+                    int last = -1;
+                    for (int idx = o.indexOf(separator); idx >= 0; idx = o.indexOf(separator, idx + 1)) {
+                        if (last >= 0) {
+                            fields.add(last);
+                            fields.add(idx - 1);
+                        } else if (idx > 0) {
+                            fields.add(0);
+                            fields.add(idx - 1);
+                        }
+                        last = idx + 1;
+                    }
+                    if (last < o.length()) {
+                        fields.add(last < 0 ? 0 : last);
+                        fields.add(o.length() - 1);
+                    }
+                }
+            }
+            return fields;
+        }
+
+        public class Key {
+            int startField;
+            int startChar;
+            int endField;
+            int endChar;
+            boolean ignoreBlanksStart;
+            boolean ignoreBlanksEnd;
+            boolean caseInsensitive;
+            boolean reverse;
+            boolean numeric;
+
+            public Key(String str) {
+                boolean modifiers = false;
+                boolean startPart = true;
+                boolean inField = true;
+                boolean inChar = false;
+                for (char c : str.toCharArray()) {
+                    switch (c) {
+                        case '0':
+                        case '1':
+                        case '2':
+                        case '3':
+                        case '4':
+                        case '5':
+                        case '6':
+                        case '7':
+                        case '8':
+                        case '9':
+                            if (!inField && !inChar) {
+                                throw new IllegalArgumentException("Bad field syntax: " + str);
+                            }
+                            if (startPart) {
+                                if (inChar) {
+                                    startChar = startChar * 10 + (c - '0');
+                                } else {
+                                    startField = startField * 10 + (c - '0');
+                                }
+                            } else {
+                                if (inChar) {
+                                    endChar = endChar * 10 + (c - '0');
+                                } else {
+                                    endField = endField * 10 + (c - '0');
+                                }
+                            }
+                            break;
+                        case '.':
+                            if (!inField) {
+                                throw new IllegalArgumentException("Bad field syntax: " + str);
+                            }
+                            inField = false;
+                            inChar = true;
+                            break;
+                        case 'n':
+                            inField = false;
+                            inChar = false;
+                            modifiers = true;
+                            numeric = true;
+                            break;
+                        case 'f':
+                            inField = false;
+                            inChar = false;
+                            modifiers = true;
+                            caseInsensitive = true;
+                            break;
+                        case 'r':
+                            inField = false;
+                            inChar = false;
+                            modifiers = true;
+                            reverse = true;
+                            break;
+                        case 'b':
+                            inField = false;
+                            inChar = false;
+                            modifiers = true;
+                            if (startPart) {
+                                ignoreBlanksStart = true;
+                            } else {
+                                ignoreBlanksEnd = true;
+                            }
+                            break;
+                        case ',':
+                            inField = true;
+                            inChar = false;
+                            startPart = false;
+                            break;
+                        default:
+                            throw new IllegalArgumentException("Bad field syntax: " + str);
+                    }
+                }
+                if (!modifiers) {
+                    ignoreBlanksStart = ignoreBlanksEnd = SortComparator.this.ignoreBlanks;
+                    reverse = SortComparator.this.reverse;
+                    caseInsensitive = SortComparator.this.caseInsensitive;
+                    numeric = SortComparator.this.numeric;
+                }
+                if (startField < 1) {
+                    throw new IllegalArgumentException("Bad field syntax: " + str);
+                }
+            }
+        }
+    }
+
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java
new file mode 100644
index 0000000..0311f1b
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java
@@ -0,0 +1,149 @@
+/*
+ * 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.jline;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.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;
+    }
+
+    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}");
+        }
+
+        for (int i = 0; i < length; ++i) {
+            if (i == length - 1 || isTrue(fns[i++].execute(session, null))) {
+                return fns[i].execute(session, null);
+            }
+        }
+
+        return null;
+    }
+
+    public boolean not(CommandSession session, Function condition) throws Exception {
+        if (null == condition) {
+            return true;
+        }
+
+        return !isTrue(condition.execute(session, null));
+    }
+
+    // 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.");
+    }
+
+    public Object _try(CommandSession session, Function func) throws Exception {
+        try {
+            return func.execute(session, null);
+        } catch (Exception e) {
+            session.put("exception", e);
+            return null;
+        }
+    }
+
+    public Object _try(CommandSession session, Function func, Function error)
+            throws Exception {
+        try {
+            return func.execute(session, null);
+        } catch (Exception e) {
+            session.put("exception", e);
+            return error.execute(session, null);
+        }
+    }
+
+    public void _while(CommandSession session, Function condition, Function ifTrue)
+            throws Exception {
+        while (isTrue(condition.execute(session, null))) {
+            ifTrue.execute(session, null);
+        }
+    }
+
+    public void until(CommandSession session, Function condition, Function ifTrue)
+            throws Exception {
+        while (!isTrue(condition.execute(session, null))) {
+            ifTrue.execute(session, null);
+        }
+    }
+
+    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/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java
new file mode 100644
index 0000000..d92fed6
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java
@@ -0,0 +1,537 @@
+/*
+ * 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.jline;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.CharBuffer;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.apache.felix.gogo.runtime.Closure;
+import org.apache.felix.gogo.runtime.CommandProxy;
+import org.apache.felix.gogo.runtime.CommandSessionImpl;
+import org.apache.felix.gogo.runtime.Expander;
+import org.apache.felix.gogo.runtime.Reflective;
+import org.apache.felix.service.command.CommandProcessor;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.command.Converter;
+import org.apache.felix.service.command.Descriptor;
+import org.apache.felix.service.command.Function;
+import org.apache.felix.service.command.Parameter;
+import org.jline.builtins.Completers.CompletionData;
+import org.jline.builtins.Options;
+import org.jline.reader.EndOfFileException;
+import org.jline.reader.LineReader;
+import org.jline.reader.LineReaderBuilder;
+import org.jline.reader.ParsedLine;
+import org.jline.reader.UserInterruptException;
+import org.jline.reader.impl.history.history.FileHistory;
+import org.jline.terminal.Terminal;
+
+public class Shell {
+
+    public static final String VAR_COMPLETIONS = ".completions";
+    public static final String VAR_COMMAND_LINE = ".commandLine";
+    public static final String VAR_READER = ".reader";
+    public static final String VAR_SESSION = ".session";
+    public static final String VAR_PROCESSOR = ".processor";
+    public static final String VAR_TERMINAL = ".terminal";
+    public static final String VAR_EXCEPTION = "exception";
+    public static final String VAR_LOCATION = ".location";
+    public static final String VAR_PROMPT = "prompt";
+    public static final String VAR_RPROMPT = "rprompt";
+    public static final String VAR_SCOPE = "SCOPE";
+    public static final String VAR_CONTEXT = org.apache.felix.gogo.runtime.activator.Activator.CONTEXT;
+
+    static final String[] functions = {"gosh", "sh", "source", "help"};
+
+    private final URI baseURI;
+    private final String profile;
+    private final Context context;
+    private final CommandProcessor processor;
+
+    public Shell(Context context, CommandProcessor processor, Terminal terminal) {
+        this(context, processor, terminal, null);
+    }
+
+    public Shell(Context context, CommandProcessor processor, Terminal terminal, String profile) {
+        this.context = context;
+        this.processor = processor;
+        String baseDir = context.getProperty("gosh.home");
+        baseDir = (baseDir == null) ? context.getProperty("user.dir") : baseDir;
+        this.baseURI = new File(baseDir).toURI();
+        this.profile = profile != null ? profile : "gosh_profile";
+    }
+
+    public static Terminal getTerminal(CommandSession session) {
+        return (Terminal) session.get(VAR_TERMINAL);
+    }
+
+    public static LineReader getReader(CommandSession session) {
+        return (LineReader) session.get(VAR_READER);
+    }
+
+    public static CommandProcessor getProcessor(CommandSession session) {
+        return (CommandProcessor) session.get(VAR_PROCESSOR);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static Map<String, List<CompletionData>> getCompletions(CommandSession session) {
+        return (Map) session.get(VAR_COMPLETIONS);
+    }
+
+    @SuppressWarnings("unchecked")
+    public static Set<String> getCommands(CommandSession session) {
+        return (Set<String>) session.get(CommandSessionImpl.COMMANDS);
+    }
+
+    public static ParsedLine getParsedLine(CommandSession session) {
+        return (ParsedLine) session.get(VAR_COMMAND_LINE);
+    }
+
+    public static String getPrompt(CommandSession session) {
+        return expand(session, VAR_PROMPT, "gl! ");
+    }
+
+    public static String getRPrompt(CommandSession session) {
+        return expand(session, VAR_RPROMPT, null);
+    }
+
+    public static String expand(CommandSession session, String name, String def) {
+        Object prompt = session.get(name);
+        if (prompt != null) {
+            try {
+                Object o = Expander.expand(
+                        prompt.toString(),
+                        new Closure((CommandSessionImpl) session, null, null));
+                if (o != null) {
+                    return o.toString();
+                }
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+        return def;
+    }
+
+    public static String resolve(CommandSession session, String command) {
+        String resolved = command;
+        if (command.indexOf(':') < 0) {
+            Set<String> commands = getCommands(session);
+            Object path = session.get(VAR_SCOPE);
+            String scopePath = (null == path ? "*" : path.toString());
+            for (String scope : scopePath.split(":")) {
+                for (String entry : commands) {
+                    if ("*".equals(scope) && entry.endsWith(":" + command)
+                            || entry.equals(scope + ":" + command)) {
+                        resolved = entry;
+                        break;
+                    }
+                }
+            }
+        }
+        return resolved;
+    }
+
+    public static 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) {
+        return Posix._pwd(session).toURI(); // _cwd is set by felixcommands:cd
+    }
+
+    private static <T extends Annotation> T findAnnotation(Annotation[] anns,
+                                                           Class<T> clazz) {
+        for (int i = 0; (anns != null) && (i < anns.length); i++) {
+            if (clazz.isInstance(anns[i])) {
+                return clazz.cast(anns[i]);
+            }
+        }
+        return null;
+    }
+
+    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",
+                "     --nointeractive       don't start interactive session",
+                "     --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."};
+
+        Options opt = Options.compile(usage).setOptionsFirst(true).parse(argv);
+        List<String> args = opt.args();
+
+        boolean login = opt.isSet("login");
+        boolean interactive = !opt.isSet("nointeractive");
+
+        if (opt.isSet("help")) {
+            opt.usage(System.err);
+            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);
+        }
+
+        // export variables starting with upper-case to newSession
+        for (String key : getVariables(session)) {
+            if (key.matches("[.]?[A-Z].*")) {
+                newSession.put(key, session.get(key));
+            }
+        }
+
+        Terminal terminal = getTerminal(session);
+        newSession.put(Shell.VAR_CONTEXT, context);
+        newSession.put(Shell.VAR_TERMINAL, terminal);
+        newSession.put(Shell.VAR_PROCESSOR, processor);
+        newSession.put(Shell.VAR_SESSION, session);
+        newSession.put("#TERM", (Function) (s, arguments) -> terminal.getType());
+        newSession.put("#COLUMNS", (Function) (s, arguments) -> terminal.getWidth());
+        newSession.put("#LINES", (Function) (s, arguments) -> terminal.getHeight());
+
+        LineReader reader = null;
+        if (args.isEmpty() && interactive) {
+            reader = LineReaderBuilder.builder()
+                    .terminal(terminal)
+                    .variables(((CommandSessionImpl) newSession).getVariables())
+                    .completer(new org.jline.builtins.Completers.Completer(new JLineCompletionEnvironment(newSession)))
+                    .highlighter(new Highlighter(session))
+                    .history(new FileHistory(new File(System.getProperty("user.home"), ".gogo.history")))
+                    .parser(new Parser())
+                    .build();
+            newSession.put(Shell.VAR_READER, reader);
+            newSession.put(Shell.VAR_COMPLETIONS, new HashMap());
+        }
+
+        if (login || interactive) {
+            URI uri = baseURI.resolve("etc/" + profile);
+            if (!new File(uri).exists()) {
+                URL url = getClass().getResource("/ext/" + profile);
+                if (url == null) {
+                    url = getClass().getResource("/" + profile);
+                }
+                uri = (url == null) ? null : url.toURI();
+            }
+            if (uri != null) {
+                source(newSession, uri.toString());
+            }
+        }
+
+        Object result = null;
+
+        if (args.isEmpty()) {
+            if (interactive) {
+                while (true) {
+                    try {
+                        reader.readLine(Shell.getPrompt(session), Shell.getRPrompt(session), null, null);
+                        ParsedLine parsedLine = reader.getParsedLine();
+                        if (parsedLine == null) {
+                            throw new EndOfFileException();
+                        }
+                        try {
+                            result = session.execute(((ParsedLineImpl) parsedLine).program());
+                            session.put("_", result); // set $_ to last result
+
+                            if (result != null && !Boolean.FALSE.equals(session.get(".Gogo.format"))) {
+                                System.out.println(session.format(result, Converter.INSPECT));
+                            }
+                        } catch (Exception e) {
+                            session.put(Shell.VAR_EXCEPTION, e);
+                            Object loc = session.get(Shell.VAR_LOCATION);
+
+                            if (null == loc || !loc.toString().contains(":")) {
+                                loc = "gogo";
+                            }
+                            System.out.println(loc + ": " + e.getClass().getSimpleName() + ": "
+                                    + e.getMessage());
+                        }
+
+                    } catch (UserInterruptException e) {
+                        // continue;
+                    } catch (EndOfFileException e) {
+                        try {
+                            reader.getHistory().flush();
+                        } catch (IOException e1) {
+                            e.addSuppressed(e1);
+                        }
+                        break;
+                    }
+                }
+            }
+        } 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 && interactive && !opt.isSet("noshutdown")) {
+            System.out.println("gosh: stopping framework");
+            shutdown();
+        }
+
+        return result;
+    }
+
+    public Object sh(final CommandSession session, String[] argv) throws Exception {
+        return gosh(session, argv);
+    }
+
+    private void shutdown() throws Exception {
+        context.exit();
+    }
+
+    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
+        }
+    }
+
+    private Map<String, List<Method>> getReflectionCommands(CommandSession session) {
+        Map<String, List<Method>> commands = new TreeMap<String, List<Method>>();
+        Set<String> names = getCommands(session);
+        for (String name : names) {
+            Function function = (Function) session.get(name);
+            if (function instanceof CommandProxy) {
+                Object target = ((CommandProxy) function).getTarget();
+                List<Method> methods = new ArrayList<>();
+                String func = name.substring(name.indexOf(':') + 1).toLowerCase();
+                List<String> funcs = new ArrayList<>();
+                funcs.add("is" + func);
+                funcs.add("get" + func);
+                funcs.add("set" + func);
+                if (Reflective.KEYWORDS.contains(func)) {
+                    funcs.add("_" + func);
+                } else {
+                    funcs.add(func);
+                }
+                for (Method method : target.getClass().getMethods()) {
+                    if (funcs.contains(method.getName().toLowerCase())) {
+                        methods.add(method);
+                    }
+                }
+                commands.put(name, methods);
+                ((CommandProxy) function).ungetTarget();
+            }
+        }
+        return commands;
+    }
+
+    @Descriptor("displays available commands")
+    public void help(CommandSession session) {
+        Map<String, List<Method>> commands = getReflectionCommands(session);
+        for (String name : commands.keySet()) {
+            System.out.println(name);
+        }
+    }
+
+    @Descriptor("displays information about a specific command")
+    public void help(CommandSession session, @Descriptor("target command") String name) {
+        Map<String, List<Method>> commands = getReflectionCommands(session);
+
+        List<Method> methods = null;
+
+        // If the specified command doesn't have a scope, then
+        // search for matching methods by ignoring the scope.
+        int scopeIdx = name.indexOf(':');
+        if (scopeIdx < 0) {
+            for (Entry<String, List<Method>> entry : commands.entrySet()) {
+                String k = entry.getKey().substring(entry.getKey().indexOf(':') + 1);
+                if (name.equals(k)) {
+                    name = entry.getKey();
+                    methods = entry.getValue();
+                    break;
+                }
+            }
+        }
+        // Otherwise directly look up matching methods.
+        else {
+            methods = commands.get(name);
+        }
+
+        if ((methods != null) && (methods.size() > 0)) {
+            for (Method m : methods) {
+                Descriptor d = m.getAnnotation(Descriptor.class);
+                if (d == null) {
+                    System.out.println("\n" + m.getName());
+                } else {
+                    System.out.println("\n" + m.getName() + " - " + d.value());
+                }
+
+                System.out.println("   scope: " + name.substring(0, name.indexOf(':')));
+
+                // Get flags and options.
+                Class<?>[] paramTypes = m.getParameterTypes();
+                Map<String, Parameter> flags = new TreeMap<>();
+                Map<String, String> flagDescs = new TreeMap<>();
+                Map<String, Parameter> options = new TreeMap<>();
+                Map<String, String> optionDescs = new TreeMap<>();
+                List<String> params = new ArrayList<String>();
+                Annotation[][] anns = m.getParameterAnnotations();
+                for (int paramIdx = 0; paramIdx < anns.length; paramIdx++) {
+                    Class<?> paramType = m.getParameterTypes()[paramIdx];
+                    if (paramType == CommandSession.class) {
+                        /* Do not bother the user with a CommandSession. */
+                        continue;
+                    }
+                    Parameter p = findAnnotation(anns[paramIdx], Parameter.class);
+                    d = findAnnotation(anns[paramIdx], Descriptor.class);
+                    if (p != null) {
+                        if (p.presentValue().equals(Parameter.UNSPECIFIED)) {
+                            options.put(p.names()[0], p);
+                            if (d != null) {
+                                optionDescs.put(p.names()[0], d.value());
+                            }
+                        } else {
+                            flags.put(p.names()[0], p);
+                            if (d != null) {
+                                flagDescs.put(p.names()[0], d.value());
+                            }
+                        }
+                    } else if (d != null) {
+                        params.add(paramTypes[paramIdx].getSimpleName());
+                        params.add(d.value());
+                    } else {
+                        params.add(paramTypes[paramIdx].getSimpleName());
+                        params.add("");
+                    }
+                }
+
+                // Print flags and options.
+                if (flags.size() > 0) {
+                    System.out.println("   flags:");
+                    for (Entry<String, Parameter> entry : flags.entrySet()) {
+                        // Print all aliases.
+                        String[] names = entry.getValue().names();
+                        System.out.print("      " + names[0]);
+                        for (int aliasIdx = 1; aliasIdx < names.length; aliasIdx++) {
+                            System.out.print(", " + names[aliasIdx]);
+                        }
+                        System.out.println("   " + flagDescs.get(entry.getKey()));
+                    }
+                }
+                if (options.size() > 0) {
+                    System.out.println("   options:");
+                    for (Entry<String, Parameter> entry : options.entrySet()) {
+                        // Print all aliases.
+                        String[] names = entry.getValue().names();
+                        System.out.print("      " + names[0]);
+                        for (int aliasIdx = 1; aliasIdx < names.length; aliasIdx++) {
+                            System.out.print(", " + names[aliasIdx]);
+                        }
+                        System.out.println("   "
+                                + optionDescs.get(entry.getKey())
+                                + ((entry.getValue().absentValue() == null) ? ""
+                                : " [optional]"));
+                    }
+                }
+                if (params.size() > 0) {
+                    System.out.println("   parameters:");
+                    for (Iterator<String> it = params.iterator(); it.hasNext(); ) {
+                        System.out.println("      " + it.next() + "   " + it.next());
+                    }
+                }
+            }
+        }
+    }
+
+    public interface Context {
+        String getProperty(String name);
+
+        void exit() throws Exception;
+    }
+
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ssh/ShellCommand.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ssh/ShellCommand.java
new file mode 100644
index 0000000..a679a60
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ssh/ShellCommand.java
@@ -0,0 +1,145 @@
+/*
+ * 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.jline.ssh;
+
+import java.io.CharArrayWriter;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.felix.service.command.CommandProcessor;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.sshd.server.Command;
+import org.apache.sshd.server.Environment;
+import org.apache.sshd.server.ExitCallback;
+import org.apache.sshd.server.SessionAware;
+import org.apache.sshd.server.session.ServerSession;
+
+public class ShellCommand implements Command, Runnable, SessionAware {
+
+    public static final String SHELL_INIT_SCRIPT = "karaf.shell.init.script";
+    public static final String EXEC_INIT_SCRIPT = "karaf.exec.init.script";
+
+    private static final Logger LOGGER = Logger.getLogger(ShellCommand.class.getName());
+
+    private String command;
+    private InputStream in;
+    private OutputStream out;
+    private OutputStream err;
+    private ExitCallback callback;
+    private ServerSession session;
+    private CommandProcessor processor;
+    private Environment env;
+
+    public ShellCommand(CommandProcessor processor, String command) {
+        this.processor = processor;
+        this.command = command;
+    }
+
+    public void setInputStream(InputStream in) {
+        this.in = in;
+    }
+
+    public void setOutputStream(OutputStream out) {
+        this.out = out;
+    }
+
+    public void setErrorStream(OutputStream err) {
+        this.err = err;
+    }
+
+    public void setExitCallback(ExitCallback callback) {
+        this.callback = callback;
+    }
+
+    public void setSession(ServerSession session) {
+        this.session = session;
+    }
+
+    public void start(final Environment env) throws IOException {
+        this.env = env;
+        new Thread(this).start();
+    }
+
+    public void run() {
+        int exitStatus = 0;
+        try {
+            final CommandSession session = processor.createSession(in, new PrintStream(out), new PrintStream(err));
+            for (Map.Entry<String, String> e : env.getEnv().entrySet()) {
+                session.put(e.getKey(), e.getValue());
+            }
+            try {
+                String scriptFileName = System.getProperty(EXEC_INIT_SCRIPT);
+                if (scriptFileName == null) {
+                    scriptFileName = System.getProperty(SHELL_INIT_SCRIPT);
+                }
+                executeScript(scriptFileName, session);
+                session.execute(command);
+            } catch (Throwable t) {
+                exitStatus = 1;
+                t.printStackTrace();
+            }
+        } catch (Exception e) {
+            exitStatus = 1;
+            LOGGER.log(Level.SEVERE, "Unable to start shell", e);
+        } finally {
+            ShellFactoryImpl.close(in, out, err);
+            callback.onExit(exitStatus);
+        }
+    }
+
+    public void destroy() {
+    }
+
+    private void executeScript(String scriptFileName, CommandSession session) {
+        if (scriptFileName != null) {
+            Reader r = null;
+            try {
+                File scriptFile = new File(scriptFileName);
+                r = new InputStreamReader(new FileInputStream(scriptFile));
+                CharArrayWriter w = new CharArrayWriter();
+                int n;
+                char[] buf = new char[8192];
+                while ((n = r.read(buf)) > 0) {
+                    w.write(buf, 0, n);
+                }
+                session.execute(new String(w.toCharArray()));
+            } catch (Exception e) {
+                LOGGER.log(Level.FINE, "Error in initialization script", e);
+            } finally {
+                if (r != null) {
+                    try {
+                        r.close();
+                    } catch (IOException e) {
+                        // Ignore
+                    }
+                }
+            }
+        }
+    }
+
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ssh/ShellCommandFactory.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ssh/ShellCommandFactory.java
new file mode 100644
index 0000000..d0a0a45
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ssh/ShellCommandFactory.java
@@ -0,0 +1,37 @@
+/*
+ * 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.jline.ssh;
+
+import org.apache.felix.service.command.CommandProcessor;
+import org.apache.sshd.server.Command;
+import org.apache.sshd.server.CommandFactory;
+
+public class ShellCommandFactory implements CommandFactory {
+
+    private CommandProcessor processor;
+
+    public ShellCommandFactory(CommandProcessor processor) {
+        this.processor = processor;
+    }
+
+    public Command createCommand(String command) {
+        return new ShellCommand(processor, command);
+    }
+
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ssh/ShellFactoryImpl.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ssh/ShellFactoryImpl.java
new file mode 100644
index 0000000..ad0cc8d
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ssh/ShellFactoryImpl.java
@@ -0,0 +1,277 @@
+/*
+ * 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.jline.ssh;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Map;
+
+import org.apache.felix.gogo.jline.Shell;
+import org.apache.felix.gogo.jline.Shell.Context;
+import org.apache.felix.service.command.CommandProcessor;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.sshd.common.Factory;
+import org.apache.sshd.common.channel.PtyMode;
+import org.apache.sshd.server.Command;
+import org.apache.sshd.server.Environment;
+import org.apache.sshd.server.ExitCallback;
+import org.apache.sshd.server.SessionAware;
+import org.apache.sshd.server.Signal;
+import org.apache.sshd.server.SignalListener;
+import org.apache.sshd.server.session.ServerSession;
+import org.jline.terminal.Attributes;
+import org.jline.terminal.Attributes.ControlChar;
+import org.jline.terminal.Attributes.InputFlag;
+import org.jline.terminal.Attributes.LocalFlag;
+import org.jline.terminal.Attributes.OutputFlag;
+import org.jline.terminal.Size;
+import org.jline.terminal.Terminal;
+import org.jline.terminal.TerminalBuilder;
+
+/**
+ * SSHD {@link org.apache.sshd.server.Command} factory which provides access to
+ * Shell.
+ */
+public class ShellFactoryImpl implements Factory<Command> {
+    private final CommandProcessor processor;
+
+    public ShellFactoryImpl(CommandProcessor processor) {
+        this.processor = processor;
+    }
+
+    private static void flush(OutputStream... streams) {
+        for (OutputStream s : streams) {
+            try {
+                s.flush();
+            } catch (IOException e) {
+                // Ignore
+            }
+        }
+    }
+
+    static void close(Closeable... closeables) {
+        for (Closeable c : closeables) {
+            try {
+                c.close();
+            } catch (IOException e) {
+                // Ignore
+            }
+        }
+    }
+
+    public Command create() {
+        return new ShellImpl();
+    }
+
+    public class ShellImpl implements Command, SessionAware {
+        private InputStream in;
+
+        private OutputStream out;
+
+        private OutputStream err;
+
+        private ExitCallback callback;
+
+        private ServerSession session;
+
+        private boolean closed;
+
+        public void setInputStream(final InputStream in) {
+            this.in = in;
+        }
+
+        public void setOutputStream(final OutputStream out) {
+            this.out = out;
+        }
+
+        public void setErrorStream(final OutputStream err) {
+            this.err = err;
+        }
+
+        public void setExitCallback(ExitCallback callback) {
+            this.callback = callback;
+        }
+
+        public void setSession(ServerSession session) {
+            this.session = session;
+        }
+
+        public void start(final Environment env) throws IOException {
+            try {
+                new Thread() {
+                    public void run() {
+                        try {
+                            ShellImpl.this.run(env);
+                        } catch (Throwable t) {
+                            t.printStackTrace();
+                        }
+                    }
+                }.start();
+            } catch (Exception e) {
+                throw (IOException) new IOException("Unable to start shell").initCause(e);
+            }
+        }
+
+        public void run(Environment env) throws Exception {
+            try {
+                Terminal terminal = TerminalBuilder.builder()
+                        .name("gogo")
+                        .type(env.getEnv().get("TERM"))
+                        .system(false)
+                        .streams(in, out)
+                        .build();
+                terminal.setSize(new Size(Integer.parseInt(env.getEnv().get("COLUMNS")),
+                        Integer.parseInt(env.getEnv().get("LINES"))));
+                Attributes attr = terminal.getAttributes();
+                for (Map.Entry<PtyMode, Integer> e : env.getPtyModes().entrySet()) {
+                    switch (e.getKey()) {
+                        case VINTR:
+                            attr.setControlChar(ControlChar.VINTR, e.getValue());
+                            break;
+                        case VQUIT:
+                            attr.setControlChar(ControlChar.VQUIT, e.getValue());
+                            break;
+                        case VERASE:
+                            attr.setControlChar(ControlChar.VERASE, e.getValue());
+                            break;
+                        case VKILL:
+                            attr.setControlChar(ControlChar.VKILL, e.getValue());
+                            break;
+                        case VEOF:
+                            attr.setControlChar(ControlChar.VEOF, e.getValue());
+                            break;
+                        case VEOL:
+                            attr.setControlChar(ControlChar.VEOL, e.getValue());
+                            break;
+                        case VEOL2:
+                            attr.setControlChar(ControlChar.VEOL2, e.getValue());
+                            break;
+                        case VSTART:
+                            attr.setControlChar(ControlChar.VSTART, e.getValue());
+                            break;
+                        case VSTOP:
+                            attr.setControlChar(ControlChar.VSTOP, e.getValue());
+                            break;
+                        case VSUSP:
+                            attr.setControlChar(ControlChar.VSUSP, e.getValue());
+                            break;
+                        case VDSUSP:
+                            attr.setControlChar(ControlChar.VDSUSP, e.getValue());
+                            break;
+                        case VREPRINT:
+                            attr.setControlChar(ControlChar.VREPRINT, e.getValue());
+                            break;
+                        case VWERASE:
+                            attr.setControlChar(ControlChar.VWERASE, e.getValue());
+                            break;
+                        case VLNEXT:
+                            attr.setControlChar(ControlChar.VLNEXT, e.getValue());
+                            break;
+                        /*
+                        case VFLUSH:
+                            attr.setControlChar(ControlChar.VMIN, e.getValue());
+                            break;
+                        case VSWTCH:
+                            attr.setControlChar(ControlChar.VTIME, e.getValue());
+                            break;
+                        */
+                        case VSTATUS:
+                            attr.setControlChar(ControlChar.VSTATUS, e.getValue());
+                            break;
+                        case VDISCARD:
+                            attr.setControlChar(ControlChar.VDISCARD, e.getValue());
+                            break;
+                        case ECHO:
+                            attr.setLocalFlag(LocalFlag.ECHO, e.getValue() != 0);
+                            break;
+                        case ICANON:
+                            attr.setLocalFlag(LocalFlag.ICANON, e.getValue() != 0);
+                            break;
+                        case ISIG:
+                            attr.setLocalFlag(LocalFlag.ISIG, e.getValue() != 0);
+                            break;
+                        case ICRNL:
+                            attr.setInputFlag(InputFlag.ICRNL, e.getValue() != 0);
+                            break;
+                        case INLCR:
+                            attr.setInputFlag(InputFlag.INLCR, e.getValue() != 0);
+                            break;
+                        case IGNCR:
+                            attr.setInputFlag(InputFlag.IGNCR, e.getValue() != 0);
+                            break;
+                        case OCRNL:
+                            attr.setOutputFlag(OutputFlag.OCRNL, e.getValue() != 0);
+                            break;
+                        case ONLCR:
+                            attr.setOutputFlag(OutputFlag.ONLCR, e.getValue() != 0);
+                            break;
+                        case ONLRET:
+                            attr.setOutputFlag(OutputFlag.ONLRET, e.getValue() != 0);
+                            break;
+                        case OPOST:
+                            attr.setOutputFlag(OutputFlag.OPOST, e.getValue() != 0);
+                            break;
+                    }
+                }
+                terminal.setAttributes(attr);
+                PrintStream pout = new PrintStream(terminal.output());
+                final CommandSession session = processor.createSession(terminal.input(), pout, pout);
+                for (Map.Entry<String, String> e : env.getEnv().entrySet()) {
+                    session.put(e.getKey(), e.getValue());
+                }
+                env.addSignalListener(new SignalListener() {
+                    @Override
+                    public void signal(Signal signal) {
+                        terminal.setSize(new Size(Integer.parseInt(env.getEnv().get("COLUMNS")),
+                                Integer.parseInt(env.getEnv().get("LINES"))));
+                        terminal.raise(Terminal.Signal.WINCH);
+                    }
+                }, Signal.WINCH);
+                Context context = new Context() {
+                    @Override
+                    public String getProperty(String name) {
+                        return System.getProperty(name);
+                    }
+
+                    @Override
+                    public void exit() throws Exception {
+                        destroy();
+                    }
+                };
+                new Shell(context, processor, terminal).gosh(session, new String[]{"--login"});
+            } catch (Throwable t) {
+                t.printStackTrace();
+            }
+        }
+
+        public void destroy() {
+            if (!closed) {
+                closed = true;
+                ShellFactoryImpl.flush(out, err);
+                ShellFactoryImpl.close(in, out, err);
+                callback.onExit(0);
+            }
+        }
+
+    }
+
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ssh/Ssh.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ssh/Ssh.java
new file mode 100644
index 0000000..72e7ac1
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/ssh/Ssh.java
@@ -0,0 +1,115 @@
+/*
+ * 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.jline.ssh;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.felix.service.command.CommandProcessor;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.server.Command;
+import org.apache.sshd.server.ServerBuilder;
+import org.apache.sshd.server.SshServer;
+import org.apache.sshd.server.command.ScpCommandFactory;
+import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
+import org.apache.sshd.server.subsystem.sftp.SftpSubsystemFactory;
+import org.jline.builtins.Options;
+
+public class Ssh {
+
+    public static final String[] functions = {"sshd"};
+
+    private static final int defaultPort = 2022;
+
+    private final CommandProcessor processor;
+    private SshServer server;
+    private Object context;
+    private int port;
+    private String ip;
+
+    public Ssh(CommandProcessor processor) {
+        this.processor = processor;
+    }
+
+    public void sshd(CommandSession session, String[] argv) throws IOException {
+        final String[] usage = {"sshd - start an ssh server",
+                "Usage: sshd [-i ip] [-p port] start | stop | status",
+                "  -i --ip=INTERFACE        listen interface (default=127.0.0.1)",
+                "  -p --port=PORT           listen port (default=" + defaultPort + ")",
+                "  -? --help                show help"};
+
+        Options opt = Options.compile(usage).parse(argv);
+        List<String> args = opt.args();
+
+        if (opt.isSet("help") || args.isEmpty()) {
+            opt.usage(System.err);
+            return;
+        }
+
+        String command = args.get(0);
+
+        if ("start".equals(command)) {
+            if (server != null) {
+                throw new IllegalStateException("sshd is already running on port " + port);
+            }
+            ip = opt.get("ip");
+            port = opt.getNumber("port");
+            context = session.get(org.apache.felix.gogo.runtime.activator.Activator.CONTEXT);
+            start();
+            status();
+        } else if ("stop".equals(command)) {
+            if (server == null) {
+                throw new IllegalStateException("sshd 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("sshd is running on " + ip + ":" + port);
+        } else {
+            System.out.println("sshd is not running.");
+        }
+    }
+
+    private void start() throws IOException {
+        server = ServerBuilder.builder().build();
+        server.setPort(port);
+        server.setHost(ip);
+        server.setShellFactory(new ShellFactoryImpl(processor));
+        server.setCommandFactory(new ScpCommandFactory.Builder().withDelegate(new ShellCommandFactory(processor)).build());
+        server.setSubsystemFactories(Collections.<NamedFactory<Command>>singletonList(
+                new SftpSubsystemFactory.Builder().build()
+        ));
+        server.setKeyPairProvider(new SimpleGeneratorHostKeyProvider());
+        server.start();
+    }
+
+    private void stop() throws IOException {
+        server.stop();
+    }
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/BootException.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/BootException.java
new file mode 100644
index 0000000..a29a824
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/BootException.java
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+/***
+ * Java TelnetD library (embeddable telnet daemon)
+ * Copyright (c) 2000-2005 Dieter Wimberger
+ * All rights reserved.
+ * <p/>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * <p/>
+ * Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * <p/>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS
+ * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ ***/
+
+package org.apache.felix.gogo.jline.telnet;
+
+/**
+ * Class that implements a BootException.<br>
+ * This exception will flag a broken boot process,
+ * which expresses startup failure and unavailabilty
+ * of telnet service for the container application.
+ *
+ * @author Dieter Wimberger
+ * @version 2.0 (16/07/2006)
+ */
+public class BootException extends Exception {
+
+    /**
+     * Constructor method for a BootException.<br>
+     *
+     * @param msg String that contains an understandable failure message.
+     */
+    public BootException(String msg) {
+        super(msg);
+    }//constructor
+
+}//class BootException
\ No newline at end of file
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/Connection.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/Connection.java
new file mode 100644
index 0000000..b5f90d3
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/Connection.java
@@ -0,0 +1,257 @@
+/*
+ * 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.
+ */
+
+/***
+ * Java TelnetD library (embeddable telnet daemon)
+ * Copyright (c) 2000-2005 Dieter Wimberger
+ * All rights reserved.
+ * <p/>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * <p/>
+ * Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * <p/>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS
+ * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ ***/
+
+package org.apache.felix.gogo.jline.telnet;
+
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Class that implements a connection with this telnet daemon.<br>
+ * It is derived from java.lang.Thread, which reflects the architecture
+ * constraint of one thread per connection. This might seem a waste of
+ * resources, but as a matter of fact sharing threads would require a
+ * far more complex imlementation, due to the fact that telnet is not a
+ * stateless protocol (i.e. alive throughout a session of multiple requests
+ * and responses).<br>
+ * Each Connection instance is created by the listeners ConnectionManager
+ * instance, making it part of a threadgroup and passing in an associated
+ * ConnectionData instance, that holds vital information about the connection.
+ * Be sure to take a look at their documention.<br>
+ * <p/>
+ * Once the thread has started and is running, it will get a login
+ * shell instance from the ShellManager and run passing its own reference.
+ *
+ * @author Dieter Wimberger
+ * @version 2.0 (16/07/2006)
+ * @see ConnectionManager
+ * @see ConnectionData
+ */
+public abstract class Connection
+        extends Thread {
+
+    private static final Logger LOG = Logger.getLogger(Connection.class.getName());
+    private static int number;            //unique number for a thread in the thread group
+    private boolean dead;
+    private List<ConnectionListener> listeners;
+
+    //Associations
+    private ConnectionData connectionData;    //associated information
+
+    /**
+     * Constructs a TelnetConnection by invoking its parent constructor
+     * and setting of various members.<br>
+     * Subsequently instantiates the whole i/o subsystem, negotiating
+     * telnet protocol level options etc.<br>
+     *
+     * @param tcg ThreadGroup that this instance is running in.
+     * @param cd  ConnectionData instance containing all vital information
+     *            of this connection.
+     * @see ConnectionData
+     */
+    public Connection(ThreadGroup tcg, ConnectionData cd) {
+        super(tcg, ("Connection" + (++number)));
+
+        connectionData = cd;
+        //init the connection listeners for events
+        //(there should actually be only one or two)
+        listeners = new CopyOnWriteArrayList<ConnectionListener>();
+        dead = false;
+    }//constructor
+
+    /**
+     * Method overloaded to implement following behaviour:
+     * <ol>
+     * <li> On first entry, retrieve an instance of the configured
+     * login shell from the ShellManager and run it.
+     * <li> Handle a shell switch or close down disgracefully when
+     * problems (i.e. unhandled unchecked exceptions) occur in the
+     * running shell.
+     * </ol>
+     */
+    public void run() {
+        try {
+            doRun();
+
+        } catch (Exception ex) {
+            LOG.log(Level.SEVERE, "run()", ex); //Handle properly
+        } finally {
+            //call close if not dead already
+            if (!dead) {
+                close();
+            }
+        }
+        LOG.log(Level.FINE, "run():: Returning from " + this.toString());
+    }//run
+
+    protected abstract void doRun() throws Exception;
+
+    protected abstract void doClose() throws Exception;
+
+    /**
+     * Method to access the associated connection data.
+     *
+     * @return ConnectionData associated with the Connection instance.
+     * @see ConnectionData
+     */
+    public ConnectionData getConnectionData() {
+        return connectionData;
+    }//getConnectionData
+
+    /**
+     * Closes the connection and its underlying i/o and network
+     * resources.<br>
+     */
+    public synchronized void close() {
+        if (dead) {
+            return;
+        } else {
+            try {
+                //connection dead
+                dead = true;
+                //close i/o
+                doClose();
+            } catch (Exception ex) {
+                LOG.log(Level.SEVERE, "close()", ex);
+                //handle
+            }
+            try {
+                //close socket
+                connectionData.getSocket().close();
+            } catch (Exception ex) {
+                LOG.log(Level.SEVERE, "close()", ex);
+                //handle
+            }
+            try {
+                //register closed connection in ConnectionManager
+                connectionData.getManager().registerClosedConnection(this);
+            } catch (Exception ex) {
+                LOG.log(Level.SEVERE, "close()", ex);
+                //handle
+            }
+            try {
+                //try to interrupt it
+                interrupt();
+            } catch (Exception ex) {
+                LOG.log(Level.SEVERE, "close()", ex);
+                //handle
+            }
+
+
+            LOG.log(Level.FINE, "Closed " + this.toString() + " and inactive.");
+        }
+    }//close
+
+    /**
+     * Returns if a connection has been closed.<br>
+     *
+     * @return the state of the connection.
+     */
+    public boolean isActive() {
+        return !dead;
+    }//isClosed
+
+    /****** Event handling ****************/
+
+    /**
+     * Method that registers a ConnectionListener with the
+     * Connection instance.
+     *
+     * @param cl ConnectionListener to be registered.
+     * @see ConnectionListener
+     */
+    public void addConnectionListener(ConnectionListener cl) {
+        listeners.add(cl);
+    }//addConnectionListener
+
+    /**
+     * Method that removes a ConnectionListener from the
+     * Connection instance.
+     *
+     * @param cl ConnectionListener to be removed.
+     * @see ConnectionListener
+     */
+    public void removeConnectionListener(ConnectionListener cl) {
+        listeners.remove(cl);
+    }//removeConnectionListener
+
+
+    /**
+     * Method called by the io subsystem to pass on a
+     * "low-level" event. It will be properly delegated to
+     * all registered listeners.
+     *
+     * @param ce ConnectionEvent to be processed.
+     * @see ConnectionEvent
+     */
+    public void processConnectionEvent(ConnectionEvent ce) {
+        for (ConnectionListener cl : listeners) {
+            switch (ce.getType()) {
+                case CONNECTION_IDLE:
+                    cl.connectionIdle(ce);
+                    break;
+                case CONNECTION_TIMEDOUT:
+                    cl.connectionTimedOut(ce);
+                    break;
+                case CONNECTION_LOGOUTREQUEST:
+                    cl.connectionLogoutRequest(ce);
+                    break;
+                case CONNECTION_BREAK:
+                    cl.connectionSentBreak(ce);
+                    break;
+                case CONNECTION_TERMINAL_GEOMETRY_CHANGED:
+                    cl.connectionTerminalGeometryChanged(ce);
+            }
+        }
+    }//processConnectionEvent
+
+}//class Connection
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionData.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionData.java
new file mode 100644
index 0000000..ca7288b
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionData.java
@@ -0,0 +1,449 @@
+/*
+ * 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.
+ */
+
+/***
+ * Java TelnetD library (embeddable telnet daemon)
+ * Copyright (c) 2000-2005 Dieter Wimberger
+ * All rights reserved.
+ * <p/>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * <p/>
+ * Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * <p/>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS
+ * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ ***/
+
+package org.apache.felix.gogo.jline.telnet;
+
+import java.net.InetAddress;
+import java.net.Socket;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * An utility class that is used to store and allow retrieval
+ * of all data associated with a connection.
+ *
+ * @author Dieter Wimberger
+ * @version 2.0 (16/07/2006)
+ * @see Connection
+ */
+public class ConnectionData {
+
+    //Associations
+    private ConnectionManager connectionManager;    //the connection's ConnectionManager
+    private Socket socket;                            //the connection's socket
+    private InetAddress address;                    //the connection's IP Address Object
+    private Map<String, String> environment;        //the environment
+
+    //Members
+    private String hostName;                        //cache for the hostname
+    private String hostAddress;                        //cache for the host ip
+    private int port;                                //port of the connection
+    private Locale locale;                            //locale of the connection
+    private long lastActivity;                        //timestamp for the last activity
+    private boolean warned;                            //warned flag
+    private String negotiatedTerminalType;            //negotiated TerminalType as String
+    private int[] terminalGeometry;                    //negotiated terminal geometry
+    private boolean terminalGeometryChanged = true;    //flag for changes in the terminal geometry
+    private String loginShell;                      //the login shell
+    private boolean lineMode = false;
+
+    /**
+     * Constructs a ConnectionData instance storing vital
+     * information about a connection.
+     *
+     * @param sock Socket of the inbound connection.
+     */
+    public ConnectionData(Socket sock, ConnectionManager cm) {
+        socket = sock;
+        connectionManager = cm;
+        address = sock.getInetAddress();
+        setHostName();
+        setHostAddress();
+        setLocale();
+        port = sock.getPort();
+        //this will set a default geometry and terminal type for the terminal
+        terminalGeometry = new int[2];
+        terminalGeometry[0] = 80;    //width
+        terminalGeometry[1] = 25;    //height
+        negotiatedTerminalType = "default";
+        environment = new HashMap<String, String>(20);
+        //this will stamp the first activity for validity :)
+        activity();
+    }//ConnectionData
+
+
+    /**
+     * Returns a reference to the ConnectionManager the
+     * connection is associated with.
+     *
+     * @return Reference to the associated ConnectionManager.
+     * @see ConnectionManager
+     */
+    public ConnectionManager getManager() {
+        return connectionManager;
+    }//getManager
+
+    /**
+     * Returns a reference to the socket the Connection
+     * is associated with.
+     *
+     * @return Reference to the associated Socket.
+     * @see java.net.Socket
+     */
+    public Socket getSocket() {
+        return socket;
+    }//getSocket
+
+    /**
+     * Returns the remote port to which the socket is connected.
+     *
+     * @return String that contains the remote port number to which the socket is connected.
+     */
+    public int getPort() {
+        return port;
+    }//getPort
+
+    /**
+     * Returns the fully qualified host name for the connection's IP address.<br>
+     * The name is cached on creation for performance reasons. Subsequent calls
+     * will not result in resolve queries.
+     *
+     * @return String that contains the fully qualified host name for this address.
+     */
+    public String getHostName() {
+        return hostName;
+    }//getHostName
+
+    /**
+     * Returns the IP address of the connection.
+     *
+     * @return String that contains the connection's IP address.<br>
+     *         The format "%d.%d.%d.%d" is well known, where %d goes from zero to 255.
+     */
+    public String getHostAddress() {
+        return hostAddress;
+    }//getHostAddress
+
+    /**
+     * Returns the InetAddress object associated with the connection.
+     *
+     * @return InetAddress associated with the connection.
+     */
+    public InetAddress getInetAddress() {
+        return address;
+    }//getInetAddress
+
+    /**
+     * Returns the Locale object associated with the connection
+     * by carrying out a simple domain match. <br>
+     * This can either be effective, if your users are really
+     * home in the country they are connecting from,
+     * or ineffective if they are on the move getting connected
+     * from anywhere in the world.<br>
+     * <br>
+     * Yet this gives the chance of capturing a default locale
+     * and starting from some point. On application context
+     * this can be by far better handled, so be aware that
+     * it makes sense to spend some thoughts on that thing when you
+     * build your application.
+     *
+     * @return the Locale object "guessed" for the connection based
+     *         on its host name.
+     */
+    public Locale getLocale() {
+        return locale;
+    }//getLocale
+
+
+    /**
+     * Returns a timestamp of the last activity that happened on
+     * the associated connection.
+     *
+     * @return the timestamp as a long representing the difference,
+     *         measured in milliseconds, between the current time and
+     *         midnight, January 1, 1970 UTC.
+     */
+    public long getLastActivity() {
+        return lastActivity;
+    }//getLastActivity
+
+
+    /**
+     * Sets a new timestamp to the actual time in millis
+     * retrieved from the System. This will remove an idle warning
+     * flag if it has been set. Note that you can use this behaviour
+     * to implement your own complex idle timespan policies within
+     * the context of your application.<br>
+     * The check frequency of the ConnectionManager should just be set
+     * according to the lowest time to warning and time to disconnect
+     * requirements.
+     */
+    public void activity() {
+        warned = false;
+        lastActivity = System.currentTimeMillis();
+    }//setLastActivity
+
+    /**
+     * Returns the state of the idle warning flag, which
+     * will be true if a warning has been issued, and false
+     * if not.
+     *
+     * @return the state of the idle warning flag.
+     */
+    public boolean isWarned() {
+        return warned;
+    }//isWarned
+
+    /**
+     * Sets the state of the idle warning flag.<br>
+     * Note that this method will also update the
+     * the timestamp if the idle warning flag is removed,
+     * which means its kind of a second way to achieve the
+     * same thing as with the activity method.
+     *
+     * @param bool true if a warning is to be issued,
+     *             false if to be removed.
+     * @see #activity()
+     */
+    public void setWarned(boolean bool) {
+        warned = bool;
+        if (!bool) {
+            lastActivity = System.currentTimeMillis();
+        }
+    }//setWarned
+
+    /**
+     * Sets the terminal geometry data.<br>
+     * <em>This method should not be called explicitly
+     * by the application (i.e. the its here for the io subsystem).</em><br>
+     * A call will set the terminal geometry changed flag.
+     *
+     * @param width  of the terminal in columns.
+     * @param height of the terminal in rows.
+     */
+    public void setTerminalGeometry(int width, int height) {
+        terminalGeometry[0] = width;
+        terminalGeometry[1] = height;
+        terminalGeometryChanged = true;
+    }//setTerminalGeometry
+
+    /**
+     * Returns the terminal geometry in an array of two integers.
+     * <ul>
+     * <li>index 0: Width in columns.
+     * <li>index 1: Height in rows.
+     * </ul>
+     * A call will reset the terminal geometry changed flag.
+     *
+     * @return integer array containing width and height.
+     */
+    public int[] getTerminalGeometry() {
+        //we toggle the flag because the change should now be known
+        if (terminalGeometryChanged) terminalGeometryChanged = false;
+        return terminalGeometry;
+    }//getTerminalGeometry
+
+    /**
+     * Returns the width of the terminal in columns for convenience.
+     *
+     * @return the number of columns.
+     */
+    public int getTerminalColumns() {
+        return terminalGeometry[0];
+    }//getTerminalColumns
+
+    /**
+     * Returns the height of the terminal in rows for convenience.
+     *
+     * @return the number of rows.
+     */
+    public int getTerminalRows() {
+        return terminalGeometry[1];
+    }//getTerminalRows
+
+    /**
+     * Returns the state of the terminal geometry changed flag,
+     * which will be true if it has been set, and false
+     * if not.
+     *
+     * @return the state of the terminal geometry changed flag.
+     */
+    public boolean isTerminalGeometryChanged() {
+        return terminalGeometryChanged;
+    }//isTerminalGeometryChanged
+
+    /**
+     * Returns the terminal type that has been negotiated
+     * between the telnet client and the telnet server, in
+     * of a String.<br>
+     *
+     * @return the negotiated terminal type as String.
+     */
+    public String getNegotiatedTerminalType() {
+        return negotiatedTerminalType;
+    }//getNegotiatedTerminalType
+
+    /**
+     * Sets the terminal type that has been negotiated
+     * between telnet client and telnet server, in form of
+     * a String.<br>
+     * <p/>
+     * <em>This method should not be called explicitly
+     * by the application (i.e. the its here for the io subsystem).</em><br>
+     *
+     * @param termtype the negotiated terminal type as String.
+     */
+    public void setNegotiatedTerminalType(String termtype) {
+        negotiatedTerminalType = termtype;
+    }//setNegotiatedTerminalType
+
+    /**
+     * Returns the hashmap for storing and
+     * retrieving environment variables to be passed
+     * between shells.
+     *
+     * @return a <tt>HashMap</tt> instance.
+     */
+    public Map<String, String> getEnvironment() {
+        return environment;
+    }//getEnvironment
+
+    /**
+     * Returns the login shell name.
+     *
+     * @return the shell name as string.
+     */
+    public String getLoginShell() {
+        return loginShell;
+    }//getLoginShell
+
+    /**
+     * Sets the login shell name.
+     *
+     * @param s the shell name as string.
+     */
+    public void setLoginShell(String s) {
+        loginShell = s;
+    }//setLoginShell
+
+    /**
+     * Tests if in line mode.
+     *
+     * @return true if in line mode, false otherwise
+     */
+    public boolean isLineMode() {
+        return lineMode;
+    }//isLineMode
+
+    /**
+     * Sets the line mode flag for the connection.
+     * Note that the setting will only be used at
+     * startup at the moment.
+     *
+     * @param b true if to be initialized in linemode,
+     *          false otherwise.
+     */
+    public void setLineMode(boolean b) {
+        lineMode = b;
+    }//setLineMode
+
+    /**
+     * Mutator for HostName cache
+     */
+    private void setHostName() {
+        hostName = address.getHostName();
+    }//setHostName
+
+    /**
+     * Mutator for HostAddress cache
+     */
+    private void setHostAddress() {
+        hostAddress = address.getHostAddress();
+    }//setHostAddress
+
+    /**
+     * Mutator for Locale
+     * Sets a Locale derived from the hostname,
+     * or the default which is Locale.ENGLISH if something
+     * goes wrong.
+     * The localhost represents a problem for example :)
+     */
+    private void setLocale() {
+        String country = getHostName();
+        try {
+            country = country.substring(country.lastIndexOf(".") + 1);
+            if (country.equals("at")) {
+                locale = new Locale("de", "AT");
+            } else if (country.equals("de")) {
+                locale = new Locale("de", "DE");
+            } else if (country.equals("mx")) {
+                locale = new Locale("es", "MX");
+            } else if (country.equals("es")) {
+                locale = new Locale("es", "ES");
+            } else if (country.equals("it")) {
+                locale = Locale.ITALY;
+            } else if (country.equals("fr")) {
+                locale = Locale.FRANCE;
+            } else if (country.equals("uk")) {
+                locale = new Locale("en", "GB");
+            } else if (country.equals("arpa")) {
+                locale = Locale.US;
+            } else if (country.equals("com")) {
+                locale = Locale.US;
+            } else if (country.equals("edu")) {
+                locale = Locale.US;
+            } else if (country.equals("gov")) {
+                locale = Locale.US;
+            } else if (country.equals("org")) {
+                locale = Locale.US;
+            } else if (country.equals("mil")) {
+                locale = Locale.US;
+            } else {
+                //default to english
+                locale = Locale.ENGLISH;
+            }
+        } catch (Exception ex) {
+            //default to english
+            locale = Locale.ENGLISH;
+        }
+    }//setLocale
+
+}//class ConnectionData
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionEvent.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionEvent.java
new file mode 100644
index 0000000..3a75a4d
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionEvent.java
@@ -0,0 +1,137 @@
+/*
+ * 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.
+ */
+
+/***
+ * Java TelnetD library (embeddable telnet daemon)
+ * Copyright (c) 2000-2005 Dieter Wimberger
+ * All rights reserved.
+ * <p/>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * <p/>
+ * Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * <p/>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS
+ * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ ***/
+
+package org.apache.felix.gogo.jline.telnet;
+
+/**
+ * Class implmenting a ConnectionEvent.<br>
+ * These events are used to communicate things that are
+ * supposed to be handled within the application context.
+ * These events are processed by the Connection instance
+ * calling upon its registered listeners.
+ *
+ * @author Dieter Wimberger
+ * @version 2.0 (16/07/2006)
+ * @see Connection
+ * @see ConnectionListener
+ */
+public class ConnectionEvent {
+
+    private final Connection source;
+    private final Type type;
+    /**
+     * Constructs a new instance of a ConnectionEvent
+     * with a given source (Connection) and a given type.
+     *
+     * @param source Connection that represents the source of this event.
+     * @param type int that contains one of the defined event types.
+     */
+    public ConnectionEvent(Connection source, Type type) {
+        this.type = type;
+        this.source = source;
+    }//constructor
+
+    /**
+     * Accessor method returning the source of the
+     * ConnectionEvent instance.
+     *
+     * @return Connection representing the source.
+     */
+    public Connection getSource() {
+        return source;
+    }//getSource
+
+    /**
+     * Method that helps identifying the type.
+     *
+     * @return Event type.
+     */
+    public Type getType() {
+        return type;
+    }//getType
+
+    public enum Type {
+        /**
+         * Defines the connection idle event type.<br>
+         * It occurs if a connection has been idle exceeding
+         * the configured time to warning.
+         */
+        CONNECTION_IDLE,
+
+        /**
+         * Defines the connection timed out event type.<br>
+         * It occurs if a connection has been idle exceeding
+         * the configured time to warning and the configured time
+         * to timedout.
+         */
+        CONNECTION_TIMEDOUT,
+
+        /**
+         * Defines the connection requested logout event type.<br>
+         * It occurs if a connection requested disgraceful logout by
+         * sending a <Ctrl>-<D> key combination.
+         */
+        CONNECTION_LOGOUTREQUEST,
+
+        /**
+         * Defines the connection sent break event type.<br>
+         * It occurs when the connection sent a NVT BREAK.
+         */
+        CONNECTION_BREAK,
+
+        /**
+         * Defines the connection geometry event type.
+         * It occurs when the connection sent a NAWS.
+         */
+        CONNECTION_TERMINAL_GEOMETRY_CHANGED;
+    }
+
+
+}//class ConnectionEvent
\ No newline at end of file
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionFilter.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionFilter.java
new file mode 100644
index 0000000..e948166
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionFilter.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.
+ */
+
+/***
+ * Java TelnetD library (embeddable telnet daemon)
+ * Copyright (c) 2000-2005 Dieter Wimberger
+ * All rights reserved.
+ * <p/>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * <p/>
+ * Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * <p/>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS
+ * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ ***/
+
+package org.apache.felix.gogo.jline.telnet;
+
+import java.net.InetAddress;
+
+/**
+ * Interface defining a generic IP level connection
+ * filter.<br>
+ * Due to the fact that this task depends heavily on
+ * application context, I chose a very generic way
+ * of applying IP level connection filtering.
+ * <br><br>
+ * Implementations should consider following issues:
+ * <ul>
+ * <li>performance
+ * <li>administration (maybe via an admin shell)
+ * <li>logging denials
+ * </ul>
+ *
+ * @author Dieter Wimberger
+ * @version 2.0 (16/07/2006)
+ */
+public interface ConnectionFilter {
+
+    /**
+     * Tests if a given ip address is allowed to connect.
+     *
+     * @param ip the address to be tested.
+     * @return true if allowed to connect, false otherwise.
+     */
+    boolean isAllowed(InetAddress ip);
+
+}//interface ConnectionFilter
\ No newline at end of file
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionListener.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionListener.java
new file mode 100644
index 0000000..38ed90b
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionListener.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/***
+ * Java TelnetD library (embeddable telnet daemon)
+ * Copyright (c) 2000-2005 Dieter Wimberger
+ * All rights reserved.
+ * <p/>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * <p/>
+ * Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * <p/>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS
+ * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ ***/
+
+package org.apache.felix.gogo.jline.telnet;
+
+
+/**
+ * Interface to be implemented if a class wants to
+ * qualify as a ConnectionListener.<br>
+ * Note that a Shell is per contract also forced to
+ * implement this interface.
+ *
+ * @author Dieter Wimberger
+ * @version 2.0 (16/07/2006)
+ * @see ConnectionEvent
+ */
+public interface ConnectionListener {
+
+    /**
+     * Called when a CONNECTION_IDLE event occured.
+     *
+     * @param ce ConnectionEvent instance.
+     * @see ConnectionEvent.Type#CONNECTION_IDLE
+     */
+    void connectionIdle(ConnectionEvent ce);
+
+    /**
+     * Called when a CONNECTION_TIMEDOUT event occured.
+     *
+     * @param ce ConnectionEvent instance.
+     * @see ConnectionEvent.Type#CONNECTION_TIMEDOUT
+     */
+    void connectionTimedOut(ConnectionEvent ce);
+
+    /**
+     * Called when a CONNECTION_LOGOUTREQUEST occured.
+     *
+     * @param ce ConnectionEvent instance.
+     * @see ConnectionEvent.Type#CONNECTION_LOGOUTREQUEST
+     */
+    void connectionLogoutRequest(ConnectionEvent ce);
+
+    /**
+     * Called when a CONNECTION_BREAK event occured.
+     *
+     * @param ce ConnectionEvent instance.
+     * @see ConnectionEvent.Type#CONNECTION_BREAK
+     */
+    void connectionSentBreak(ConnectionEvent ce);
+
+    /**
+     * Called when a CONNECTION_TERMINAL_GEOMETRY_CHANGED event occured.
+     *
+     * @param ce ConnectionEvent instance.
+     * @see ConnectionEvent.Type#CONNECTION_TERMINAL_GEOMETRY_CHANGED
+     */
+    void connectionTerminalGeometryChanged(ConnectionEvent ce);
+
+}//interface ConnectionListener
\ No newline at end of file
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionManager.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionManager.java
new file mode 100644
index 0000000..d169a49
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/ConnectionManager.java
@@ -0,0 +1,393 @@
+/*
+ * 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.
+ */
+
+/***
+ * Java TelnetD library (embeddable telnet daemon)
+ * Copyright (c) 2000-2005 Dieter Wimberger
+ * All rights reserved.
+ * <p/>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * <p/>
+ * Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * <p/>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS
+ * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ ***/
+
+package org.apache.felix.gogo.jline.telnet;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Stack;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Class that takes care for active and queued connection.
+ * Housekeeping is done also for connections that were just broken
+ * off, or exceeded their timeout. 
+ *
+ * @author Dieter Wimberger
+ * @version 2.0 (16/07/2006)
+ */
+public abstract class ConnectionManager implements Runnable {
+
+    private static Logger LOG = Logger.getLogger(ConnectionManager.class.getName());
+    private final List<Connection> openConnections;
+    private Thread thread;
+    private ThreadGroup threadGroup; //ThreadGroup all connections run in
+    private Stack<Connection> closedConnections;
+    private ConnectionFilter connectionFilter; //reference to the connection filter
+    private int maxConnections; //maximum allowed connections stored from the properties
+    private int warningTimeout; //time to idle warning
+    private int disconnectTimeout; //time to idle diconnection
+    private int housekeepingInterval; //interval for managing cleanups
+    private String loginShell;
+    private boolean lineMode = false;
+    private boolean stopping = false;
+
+    public ConnectionManager() {
+        threadGroup = new ThreadGroup(toString() + "Connections");
+        closedConnections = new Stack<Connection>();
+        openConnections = Collections.synchronizedList(new ArrayList<Connection>(100));
+    }
+
+    public ConnectionManager(int con, int timew, int timedis, int hoke, ConnectionFilter filter, String lsh, boolean lm) {
+        this();
+        connectionFilter = filter;
+        loginShell = lsh;
+        lineMode = lm;
+        maxConnections = con;
+        warningTimeout = timew;
+        disconnectTimeout = timedis;
+        housekeepingInterval = hoke;
+    }//constructor
+
+    /**
+     * Gets the active ConnectionFilter instance or
+     * returns null if no filter is set.
+     *
+     * @return the managers ConnectionFilter.
+     */
+    public ConnectionFilter getConnectionFilter() {
+        return connectionFilter;
+    }//getConnectionFilter
+
+    /**
+     * Set a connection filter for this
+     * ConnectionManager instance. The filter is used to handle
+     * IP level allow/deny of incoming connections.
+     *
+     * @param filter ConnectionFilter instance.
+     */
+    public void setConnectionFilter(ConnectionFilter filter) {
+        connectionFilter = filter;
+    }//setConnectionFilter
+
+    /**
+     * Returns the number of open connections.
+     * @return the number of open connections as <tt>int</tt>.
+     */
+    public int openConnectionCount() {
+        return openConnections.size();
+    }//openConnectionCount
+
+    /**
+     * Returns the {@link Connection} at the given index.
+     * @param idx
+     * @return
+     */
+    public Connection getConnection(int idx) {
+        synchronized (openConnections) {
+            return openConnections.get(idx);
+        }
+    }//getConnection
+
+    /**
+     * Get all {@link Connection} instances with the given
+     * <tt>InetAddress</tt>.
+     *
+     * @return all {@link Connection} instances with the given
+     *         <tt>InetAddress</tt>.
+     */
+    public Connection[] getConnectionsByAdddress(InetAddress addr) {
+        ArrayList<Connection> l = new ArrayList<Connection>();
+        synchronized (openConnections) {
+            for (Connection connection : openConnections) {
+                if (connection.getConnectionData().getInetAddress().equals(addr)) {
+                    l.add(connection);
+                }
+            }
+        }
+        Connection[] conns = new Connection[l.size()];
+        return l.toArray(conns);
+    }//getConnectionsByAddress
+
+    /**
+     * Starts this <tt>ConnectionManager</tt>.
+     */
+    public void start() {
+        thread = new Thread(this);
+        thread.start();
+    }//start
+
+    /**
+     * Stops this <tt>ConnectionManager</tt>.
+     */
+    public void stop() {
+        LOG.log(Level.FINE, "stop()::" + this.toString());
+        stopping = true;
+        //wait for thread to die
+        try {
+            if (thread != null) {
+                thread.join();
+            }
+        } catch (InterruptedException iex) {
+            LOG.log(Level.SEVERE, "stop()", iex);
+        }
+        synchronized (openConnections) {
+            for (Connection tc : openConnections) {
+                try {
+                    //maybe write a disgrace to the socket?
+                    tc.close();
+                } catch (Exception exc) {
+                    LOG.log(Level.SEVERE, "stop()", exc);
+                }
+            }
+            openConnections.clear();
+        }
+        LOG.log(Level.FINE, "stop():: Stopped " + this.toString());
+    }//stop
+
+    /**
+     * Method that that tries to connect an incoming request.
+     * Properly  queueing.
+     *
+     * @param insock Socket thats representing the incoming connection.
+     */
+    public void makeConnection(Socket insock) {
+        LOG.log(Level.FINE, "makeConnection()::" + insock.toString());
+        if (connectionFilter == null || connectionFilter.isAllowed(insock.getInetAddress())) {
+            //we create the connection data object at this point to
+            //store certain information there.
+            ConnectionData newCD = new ConnectionData(insock, this);
+            newCD.setLoginShell(loginShell);
+            newCD.setLineMode(lineMode);
+            if (openConnections.size() < maxConnections) {
+                //create a new Connection instance
+                Connection con = createConnection(threadGroup, newCD);
+                //log the newly created connection
+                Object[] args = {openConnections.size() + 1};
+                LOG.info(MessageFormat.format("connection #{0,number,integer} made.", args));
+                //register it for being managed
+                synchronized (openConnections) {
+                    openConnections.add(con);
+                }
+                //start it
+                con.start();
+            }
+        } else {
+            LOG.info("makeConnection():: Active Filter blocked incoming connection.");
+            try {
+                insock.close();
+            } catch (IOException ex) {
+                //do nothing or log.
+            }
+        }
+    }//makeConnection
+
+    protected abstract Connection createConnection(ThreadGroup threadGroup, ConnectionData newCD);
+
+    /**
+     * Periodically does following work:
+     * <ul>
+     * <li> cleaning up died connections.
+     * <li> checking managed connections if they are working properly.
+     * <li> checking the open connections.
+     * </ul>
+     */
+    public void run() {
+        //housekeep connections
+        try {
+            do {
+                //clean up and close all broken connections
+                //cleanupBroken();
+                //clean up closed connections
+                cleanupClosed();
+                //check all active connections
+                checkOpenConnections();
+                //sleep interval
+                Thread.sleep(housekeepingInterval);
+            } while (!stopping);
+
+        } catch (Exception e) {
+            LOG.log(Level.SEVERE, "run()", e);
+        }
+        LOG.log(Level.FINE, "run():: Ran out " + this.toString());
+    }//run
+
+    /*
+    private void cleanupBroken() {
+      //cleanup loop
+      while (!m_BrokenConnections.isEmpty()) {
+        Connection nextOne = (Connection) m_BrokenConnections.pop();
+        log.info("cleanupBroken():: Closing broken connection " + nextOne.toString());
+        //fire logoff event for shell site cleanup , beware could hog the daemon thread
+        nextOne.processConnectionEvent(new ConnectionEvent(nextOne, ConnectionEvent.CONNECTION_BROKEN));
+        //close the connection, will be automatically registered as closed
+        nextOne.close();
+      }
+    }//cleanupBroken
+    */
+    private void cleanupClosed() {
+        if (stopping) {
+            return;
+        }
+        //cleanup loop
+        while (!closedConnections.isEmpty()) {
+            Connection nextOne = closedConnections.pop();
+            LOG.info("cleanupClosed():: Removing closed connection " + nextOne.toString());
+            synchronized (openConnections) {
+                openConnections.remove(nextOne);
+            }
+        }
+    }//cleanupBroken
+
+    private void checkOpenConnections() {
+        if (stopping) {
+            return;
+        }
+        //do routine checks on active connections
+        synchronized (openConnections) {
+            for (Connection conn : openConnections) {
+                ConnectionData cd = conn.getConnectionData();
+                //check if it is dead and remove it.
+                if (!conn.isActive()) {
+                    registerClosedConnection(conn);
+                    continue;
+                }
+                /* Timeouts check */
+                //first we caculate the inactivity time
+                long inactivity = System.currentTimeMillis() - cd.getLastActivity();
+                //now we check for warning and disconnection
+                if (inactivity > warningTimeout) {
+                    //..and for disconnect
+                    if (inactivity > (disconnectTimeout + warningTimeout)) {
+                        //this connection needs to be disconnected :)
+                        LOG.log(Level.FINE, "checkOpenConnections():" + conn.toString() + " exceeded total timeout.");
+                        //fire logoff event for shell site cleanup , beware could hog the daemon thread
+                        conn.processConnectionEvent(new ConnectionEvent(conn, ConnectionEvent.Type.CONNECTION_TIMEDOUT));
+                        //conn.close();
+                    } else {
+                        //this connection needs to be warned :)
+                        if (!cd.isWarned()) {
+                            LOG.log(Level.FINE, "checkOpenConnections():" + conn.toString() + " exceeded warning timeout.");
+                            cd.setWarned(true);
+                            //warning event is fired but beware this could hog the daemon thread!!
+                            conn.processConnectionEvent(new ConnectionEvent(conn, ConnectionEvent.Type.CONNECTION_IDLE));
+                        }
+                    }
+                }
+            }
+            /* end Timeouts check */
+        }
+    }//checkConnections
+
+    public void registerClosedConnection(Connection con) {
+        if (stopping) {
+            return;
+        }
+        if (!closedConnections.contains(con)) {
+            LOG.log(Level.FINE, "registerClosedConnection()::" + con.toString());
+            closedConnections.push(con);
+        }
+    }//unregister
+
+    public int getDisconnectTimeout() {
+        return disconnectTimeout;
+    }
+
+    public void setDisconnectTimeout(int disconnectTimeout) {
+        this.disconnectTimeout = disconnectTimeout;
+    }
+
+    public int getHousekeepingInterval() {
+        return housekeepingInterval;
+    }
+
+    public void setHousekeepingInterval(int housekeepingInterval) {
+        this.housekeepingInterval = housekeepingInterval;
+    }
+
+    public boolean isLineMode() {
+        return lineMode;
+    }
+
+    public void setLineMode(boolean lineMode) {
+        this.lineMode = lineMode;
+    }
+
+    public String getLoginShell() {
+        return loginShell;
+    }
+
+    public void setLoginShell(String loginShell) {
+        this.loginShell = loginShell;
+    }
+
+    public int getMaxConnections() {
+        return maxConnections;
+    }
+
+    public void setMaxConnections(int maxConnections) {
+        this.maxConnections = maxConnections;
+    }
+
+    public int getWarningTimeout() {
+        return warningTimeout;
+    }
+
+    public void setWarningTimeout(int warningTimeout) {
+        this.warningTimeout = warningTimeout;
+    }
+
+}//class ConnectionManager
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/PortListener.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/PortListener.java
new file mode 100644
index 0000000..1682db0
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/PortListener.java
@@ -0,0 +1,222 @@
+/*
+ * 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.
+ */
+
+/***
+ * Java TelnetD library (embeddable telnet daemon)
+ * Copyright (c) 2000-2005 Dieter Wimberger
+ * All rights reserved.
+ * <p/>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * <p/>
+ * Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * <p/>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS
+ * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ ***/
+
+package org.apache.felix.gogo.jline.telnet;
+
+import java.io.IOException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.text.MessageFormat;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Class that implements a <tt>PortListener</tt>.<br>
+ * If available, it accepts incoming connections and passes them
+ * to an associated <tt>ConnectionManager</tt>.
+ *
+ * @author Dieter Wimberger
+ * @version 2.0 (16/07/2006)
+ * @see ConnectionManager
+ */
+public class PortListener
+        implements Runnable {
+
+    private static final Logger LOG = Logger.getLogger(PortListener.class.getName());
+    private static final String logmsg =
+            "Listening to Port {0,number,integer} with a connectivity queue size of {1,number,integer}.";
+    private String name;
+    private int port;                                        //port number running on
+    private int floodProtection;                        //flooding protection
+    private ServerSocket serverSocket = null; //server socket
+    private Thread thread;
+    private ConnectionManager connectionManager;    //connection management thread
+    private boolean stopping = false;
+    private boolean available;                    //Flag for availability
+
+    /**
+     * Constructs a PortListener instance.<br>
+     *
+     * @param port      int that specifies the port number of the server socket.
+     * @param floodprot that specifies the server socket queue size.
+     */
+    public PortListener(String name, int port, int floodprot) {
+        this.name = name;
+        available = false;
+        this.port = port;
+        floodProtection = floodprot;
+    }//constructor
+
+    /**
+     * Returns the name of this <tt>PortListener</tt>.
+     *
+     * @return the name as <tt>String</tt>.
+     */
+    public String getName() {
+        return name;
+    }//getName
+
+    /**
+     * Tests if this <tt>PortListener</tt> is available.
+     *
+     * @return true if available, false otherwise.
+     */
+    public boolean isAvailable() {
+        return available;
+    }//isAvailable
+
+    /**
+     * Sets the availability flag of this <tt>PortListener</tt>.
+     *
+     * @param b true if to be available, false otherwise.
+     */
+    public void setAvailable(boolean b) {
+        available = b;
+    }//setAvailable
+
+    /**
+     * Starts this <tt>PortListener</tt>.
+     */
+    public void start() {
+        LOG.log(Level.FINE, "start()");
+        thread = new Thread(this);
+        thread.start();
+        available = true;
+    }//start
+
+    /**
+     * Stops this <tt>PortListener</tt>, and returns
+     * when everything was stopped successfully.
+     */
+    public void stop() {
+        LOG.log(Level.FINE, "stop()::" + this.toString());
+        //flag stop
+        stopping = true;
+        available = false;
+        //take down all connections
+        connectionManager.stop();
+
+        //close server socket
+        try {
+            serverSocket.close();
+        } catch (IOException ex) {
+            LOG.log(Level.SEVERE, "stop()", ex);
+        }
+
+        //wait for thread to die
+        try {
+            thread.join();
+        } catch (InterruptedException iex) {
+            LOG.log(Level.SEVERE, "stop()", iex);
+        }
+
+        LOG.info("stop()::Stopped " + this.toString());
+    }//stop
+
+    /**
+     * Listen constantly to a server socket and handles incoming connections
+     * through the associated {a:link ConnectionManager}.
+     *
+     * @see ConnectionManager
+     */
+    public void run() {
+        try {
+            /*
+                A server socket is opened with a connectivity queue of a size specified
+                in int floodProtection.  Concurrent login handling under normal circumstances
+                should be handled properly, but denial of service attacks via massive parallel
+                program logins should be prevented with this.
+            */
+            serverSocket = new ServerSocket(port, floodProtection);
+
+            //log entry
+            LOG.info(MessageFormat.format(logmsg, port, floodProtection));
+
+            do {
+                try {
+                    Socket s = serverSocket.accept();
+                    if (available) {
+                        connectionManager.makeConnection(s);
+                    } else {
+                        //just shut down the socket
+                        s.close();
+                    }
+                } catch (SocketException ex) {
+                    if (stopping) {
+                        //server socket was closed blocked in accept
+                        LOG.log(Level.FINE, "run(): ServerSocket closed by stop()");
+                    } else {
+                        LOG.log(Level.SEVERE, "run()", ex);
+                    }
+                }
+            } while (!stopping);
+
+        } catch (IOException e) {
+            LOG.log(Level.SEVERE, "run()", e);
+        }
+        LOG.log(Level.FINE, "run(): returning.");
+    }//run
+
+    /**
+     * Returns reference to ConnectionManager instance associated
+     * with the PortListener.
+     *
+     * @return the associated ConnectionManager.
+     */
+    public ConnectionManager getConnectionManager() {
+        return connectionManager;
+    }//getConnectionManager
+
+    public void setConnectionManager(ConnectionManager connectionManager) {
+        this.connectionManager = connectionManager;
+    }
+
+}//class PortListener
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/Telnet.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/Telnet.java
new file mode 100644
index 0000000..7bba28b
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/Telnet.java
@@ -0,0 +1,202 @@
+/*
+ * 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.jline.telnet;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.List;
+
+import org.apache.felix.gogo.jline.Shell;
+import org.apache.felix.gogo.jline.Shell.Context;
+import org.apache.felix.service.command.CommandProcessor;
+import org.apache.felix.service.command.CommandSession;
+import org.jline.builtins.Options;
+import org.jline.terminal.Size;
+import org.jline.terminal.Terminal;
+import org.jline.terminal.Terminal.Signal;
+import org.jline.terminal.TerminalBuilder;
+
+/*
+ * a very simple Telnet server.
+ * real remote access should be via ssh.
+ */
+public class Telnet {
+    public static final String[] functions = {"telnetd"};
+
+    private static final int defaultPort = 2019;
+    private final CommandProcessor processor;
+    private PortListener portListener;
+    private int port;
+    private String ip;
+
+    public Telnet(CommandProcessor procesor) {
+        this.processor = procesor;
+    }
+
+    public void telnetd(CommandSession session, String[] argv) throws IOException {
+        final String[] usage = {"telnetd - start simple telnet server",
+                "Usage: telnetd [-i ip] [-p port] start | stop | status",
+                "  -i --ip=INTERFACE        listen interface (default=127.0.0.1)",
+                "  -p --port=PORT           listen port (default=" + defaultPort + ")",
+                "  -? --help                show help"};
+
+        Options opt = Options.compile(usage).parse(argv);
+        List<String> args = opt.args();
+
+        if (opt.isSet("help") || args.isEmpty()) {
+            opt.usage(System.err);
+            return;
+        }
+
+        String command = args.get(0);
+
+        if ("start".equals(command)) {
+            if (portListener != null) {
+                throw new IllegalStateException("telnetd is already running on port " + port);
+            }
+            ip = opt.get("ip");
+            port = opt.getNumber("port");
+            start(session);
+            status();
+        } else if ("stop".equals(command)) {
+            if (portListener == 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 (portListener != null) {
+            System.out.println("telnetd is running on " + ip + ":" + port);
+        } else {
+            System.out.println("telnetd is not running.");
+        }
+    }
+
+    private void start(CommandSession session) throws IOException {
+        ConnectionManager connectionManager = new ConnectionManager(1000, 5 * 60 * 1000, 5 * 60 * 1000, 60 * 1000, null, null, false) {
+            @Override
+            protected Connection createConnection(ThreadGroup threadGroup, ConnectionData newCD) {
+                return new Connection(threadGroup, newCD) {
+                    TelnetIO telnetIO;
+
+                    @Override
+                    protected void doRun() throws Exception {
+                        telnetIO = new TelnetIO();
+                        telnetIO.setConnection(this);
+                        telnetIO.initIO();
+
+                        InputStream in = new InputStream() {
+                            @Override
+                            public int read() throws IOException {
+                                return telnetIO.read();
+                            }
+                            @Override
+                            public int read(byte[] b, int off, int len) throws IOException {
+                                int r = read();
+                                if (r >= 0) {
+                                    b[off] = (byte) r;
+                                    return 1;
+                                } else {
+                                    return -1;
+                                }
+                            }
+                        };
+                        PrintStream out = new PrintStream(new OutputStream() {
+                            @Override
+                            public void write(int b) throws IOException {
+                                telnetIO.write(b);
+                            }
+                            @Override
+                            public void flush() throws IOException {
+                                telnetIO.flush();
+                            }
+                        });
+                        Terminal terminal = TerminalBuilder.builder()
+                                .type(getConnectionData().getNegotiatedTerminalType().toLowerCase())
+                                .streams(in, out)
+                                .system(false)
+                                .name("telnet")
+                                .build();
+                        terminal.setSize(new Size(getConnectionData().getTerminalColumns(), getConnectionData().getTerminalRows()));
+                        terminal.setAttributes(Shell.getTerminal(session).getAttributes());
+                        addConnectionListener(new ConnectionListener() {
+                            @Override
+                            public void connectionIdle(ConnectionEvent ce) {
+                            }
+
+                            @Override
+                            public void connectionTimedOut(ConnectionEvent ce) {
+                            }
+
+                            @Override
+                            public void connectionLogoutRequest(ConnectionEvent ce) {
+                            }
+
+                            @Override
+                            public void connectionSentBreak(ConnectionEvent ce) {
+                            }
+
+                            @Override
+                            public void connectionTerminalGeometryChanged(ConnectionEvent ce) {
+                                terminal.setSize(new Size(getConnectionData().getTerminalColumns(), getConnectionData().getTerminalRows()));
+                                terminal.raise(Signal.WINCH);
+                            }
+                        });
+                        PrintStream pout = new PrintStream(terminal.output());
+                        CommandSession session = processor.createSession(terminal.input(), pout, pout);
+                        Context context = new Context() {
+                            @Override
+                            public String getProperty(String name) {
+                                return System.getProperty(name);
+                            }
+                            @Override
+                            public void exit() throws Exception {
+                                close();
+                            }
+                        };
+                        new Shell(context, processor, terminal).gosh(session, new String[]{"--login"});
+                    }
+
+                    @Override
+                    protected void doClose() throws Exception {
+                        telnetIO.closeOutput();
+                        telnetIO.closeInput();
+                    }
+                };
+            }
+        };
+        portListener = new PortListener("gogo", port, 10);
+        portListener.setConnectionManager(connectionManager);
+        portListener.start();
+    }
+
+    private void stop() throws IOException {
+        portListener.stop();
+        portListener = null;
+    }
+
+}
diff --git a/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/TelnetIO.java b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/TelnetIO.java
new file mode 100644
index 0000000..540db98
--- /dev/null
+++ b/gogo/jline/src/main/java/org/apache/felix/gogo/jline/telnet/TelnetIO.java
@@ -0,0 +1,1548 @@
+/*
+ * 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.
+ */
+
+/***
+ * Java TelnetD library (embeddable telnet daemon)
+ * Copyright (c) 2000-2005 Dieter Wimberger
+ * All rights reserved.
+ * <p/>
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * <p/>
+ * Neither the name of the author nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ * <p/>
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS
+ * IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ ***/
+
+package org.apache.felix.gogo.jline.telnet;
+
+import java.io.BufferedOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.apache.felix.gogo.jline.telnet.ConnectionEvent.Type;
+
+/**
+ * Class that represents the TelnetIO implementation. It contains
+ * an inner IACHandler class to handle the telnet protocol level
+ * communication.
+ * <p/>
+ * Although supposed to work full-duplex, we only process the telnet protocol
+ * layer communication in case of reading requests from the higher levels.
+ * This is the only way to meet the one thread per connection requirement.
+ * </p>
+ * <p/>
+ * The output is done via byte-oriented streams, definately suitable for the
+ * telnet protocol. The format of the  output is UTF-8 (Unicode), which is a
+ * standard and supported by any telnet client, including the ones included
+ * in Microsoft OS's.
+ * </p>
+ * <em>Notes:</em>
+ * <ul>
+ * <li>The underlying output is buffered, to ensure that all bytes written
+ * are send, the flush() method has to be called.
+ * <li>This low-level routines ensure nice multithreading behaviour on I/O.
+ * Neither large outputs, nor input sequences excuted by the connection thread
+ * can hog the system.
+ * </ul>
+ *
+ * @author Dieter Wimberger
+ * @version 2.0 (16/07/2006)
+ */
+public class TelnetIO {
+
+    /**
+     * Interpret As Command
+     */
+    protected static final int IAC = 255;
+    /**
+     * Go Ahead <BR> Newer Telnets do not make use of this option
+     * that allows a specific communication mode.
+     */
+    protected static final int GA = 249;
+    /**
+     * Negotiation: Will do option
+     */
+    protected static final int WILL = 251;
+    /**
+     * Negotiation: Wont do option
+     */
+    protected static final int WONT = 252;
+    /**
+     * Negotiation: Do option
+     */
+    protected static final int DO = 253;
+    /**
+     * Negotiation:  Dont do option
+     */
+    protected static final int DONT = 254;
+    /**
+     * Marks start of a subnegotiation.
+     */
+    protected static final int SB = 250;
+    /**
+     * Marks end of subnegotiation.
+     */
+    protected static final int SE = 240;
+    /**
+     * No operation
+     */
+    protected static final int NOP = 241;
+    /**
+     * Data mark its the data part of a SYNCH which helps to clean up the buffers between
+     * Telnet Server &lt;-&gt; Telnet Client. <BR>
+     * It should work like this we send a TCP urgent package and &lt;IAC&gt; &lt;DM&gt; the receiver
+     * should get the urgent package (SYNCH) and just discard everything until he receives
+     * our &lt;IAC&gt; &lt;DM&gt;.<BR>
+     * <EM>Remark</EM>:
+     * <OL>
+     * <LI>can we send a TCP urgent package?
+     * <LI>can we make use of the thing at all?
+     * </OL>
+     */
+    protected static final int DM = 242;
+    /**
+     * Break
+     */
+    protected static final int BRK = 243;
+    /**
+     * Interrupt Process
+     */
+    protected static final int IP = 244;
+    /**
+     * Abort Output
+     */
+    protected static final int AO = 245;
+
+    /**** Implementation of OutputStream ****************************************************/
+    /**
+     * Are You There
+     */
+    protected static final int AYT = 246;
+    /**
+     * Erase Char
+     */
+    protected static final int EC = 247;
+    /**
+     * Erase Line
+     */
+    protected static final int EL = 248;
+    /**
+     * Telnet Option: ECHO
+     */
+    protected static final int ECHO = 1;
+    /**
+     * Telnet Option: SUPress Go Ahead<br>
+     * This will be negotiated, all new telnet protocol implementations are
+     * recommended to do this.
+     */
+    protected static final int SUPGA = 3;
+    /**
+     * Telnet Option: Negotiate About Window Size<br>
+     * <ul>
+     * <li>Server request is IAC DO NAWS
+     * <li>Client response contains subnegotiation with data (columns, rows).
+     * </ul>
+     */
+    protected static final int NAWS = 31;
+    /**
+     * Telnet Option: Terminal TYPE <br>
+     * <ul>
+     * <li>Server request contains subnegotiation SEND
+     * <li>Client response contains subnegotiation with data IS,terminal type string
+     * </ul>
+     */
+    protected static final int TTYPE = 24;
+    /**
+     * TTYPE subnegotiation: IS
+     */
+    protected static final int IS = 0;
+    /**
+     * TTYPE subnegotiation: SEND
+     */
+    protected static final int SEND = 1;
+
+    /**** End implementation of OutputStream ***********************************************/
+
+
+    /**** Implementation of InputStream ****************************************************/
+    /**
+     * Telnet Option: Logout<br>
+     * This allows nice goodbye to time-outed or unwanted clients.
+     */
+    protected static final int LOGOUT = 18;
+    /**
+     * Telnet Option: Linemode
+     * <p/>
+     * The infamous line mode option.
+     */
+    protected static final int LINEMODE = 34;
+    protected static final int LM_MODE = 1;
+    protected static final int LM_EDIT = 1;
+    protected static final int LM_TRAPSIG = 2;
+
+    /**** Implementation of InputStream ****************************************************/
+
+
+    /****
+     * Following methods implement init/request/answer procedures for telnet
+     * protocol level communication.
+     */
+    protected static final int LM_MODEACK = 4;
+    protected static final int LM_FORWARDMASK = 2;
+    protected static final int LM_SLC = 3;
+    protected static final int LM_SLC_NOSUPPORT = 0;
+    protected static final int LM_SLC_DEFAULT = 3;
+
+
+    /**** End telnet protocol level communication methods *******************************/
+    protected static final int LM_SLC_VALUE = 2;
+
+
+    /** Constants declaration ***********************************************/
+
+//Telnet Protocoll Constants
+    protected static final int LM_SLC_CANTCHANGE = 1;
+    protected static final int LM_SLC_LEVELBITS = 3;
+    protected static final int LM_SLC_ACK = 128;
+    protected static final int LM_SLC_FLUSHIN = 64;
+    protected static final int LM_SLC_FLUSHOUT = 32;
+    protected static final int LM_SLC_SYNCH = 1;
+    protected static final int LM_SLC_BRK = 2;
+    protected static final int LM_SLC_IP = 3;
+    protected static final int LM_SLC_AO = 4;
+    protected static final int LM_SLC_AYT = 5;
+    protected static final int LM_SLC_EOR = 6;
+
+    /**
+     * The following implement the NVT (network virtual terminal) which offers the concept
+     * of a simple "printer". They are the basical meanings of control possibilities
+     * on a standard telnet implementation.
+     */
+    protected static final int LM_SLC_ABORT = 7;
+    protected static final int LM_SLC_EOF = 8;
+    protected static final int LM_SLC_SUSP = 9;
+    /**
+     * Telnet Option: Environment
+     */
+    protected static final int NEWENV = 39;
+    protected static final int NE_INFO = 2;
+
+    /**
+     * The following are constants for supported options,
+     * which can be negotiated based upon the telnet protocol
+     * specification.
+     */
+    protected static final int NE_VAR = 0;
+    protected static final int NE_VALUE = 1;
+
+    /**
+     * The following options are options for which we also support subnegotiation
+     * based upon the telnet protocol specification.
+     */
+    protected static final int NE_ESC = 2;
+    protected static final int NE_USERVAR = 3;
+    protected static final int NE_VAR_OK = 2;
+    protected static final int NE_VAR_DEFINED = 1;
+    protected static final int NE_VAR_DEFINED_EMPTY = 0;
+    protected static final int NE_VAR_UNDEFINED = -1;
+    protected static final int NE_IN_ERROR = -2;
+    protected static final int NE_IN_END = -3;
+    protected static final int NE_VAR_NAME_MAXLENGTH = 50;
+    protected static final int NE_VAR_VALUE_MAXLENGTH = 1000;
+    /**
+     * Unused
+     */
+    protected static final int EXT_ASCII = 17;        //Defines Extended ASCII
+    protected static final int SEND_LOC = 23;        //Defines Send Location
+    protected static final int AUTHENTICATION = 37;    //Defines Authentication
+    protected static final int ENCRYPT = 38;            //Defines Encryption
+    private static final Logger LOG = Logger.getLogger(TelnetIO.class.getName());
+    /**
+     * Window Size Constants
+     */
+    private static final int SMALLEST_BELIEVABLE_WIDTH = 20;
+    private static final int SMALLEST_BELIEVABLE_HEIGHT = 6;
+    private static final int DEFAULT_WIDTH = 80;
+    private static final int DEFAULT_HEIGHT = 25;
+    private Connection connection;                    //a reference to the connection this instance works for
+    private ConnectionData connectionData;            //holds all important information of the connection
+    private DataOutputStream out;                    //the byte oriented outputstream
+    private DataInputStream in;                        //the byte oriented input stream
+    //Aggregations
+    private IACHandler iacHandler;                    //holds a reference to the aggregated IACHandler
+    //Members
+    private InetAddress localAddress;                //address of the host the telnetd is running on
+    private boolean noIac = false;                    //describes if IAC was found and if its just processed
+    private boolean initializing;
+    private boolean crFlag;
+    /**
+     * Creates a TelnetIO object for the given connection.<br>
+     * Input- and OutputStreams are properly set and the primary telnet
+     * protocol initialization is carried out by the inner IACHandler class.<BR>
+     */
+    public TelnetIO() {
+    }//constructor
+
+    public void initIO() throws IOException {
+        //we make an instance of our inner class
+        iacHandler = new IACHandler();
+        //we setup underlying byte oriented streams
+        in = new DataInputStream(connectionData.getSocket().getInputStream());
+        out = new DataOutputStream(new BufferedOutputStream(connectionData.getSocket().getOutputStream()));
+
+        //we save the local address (necessary?)
+        localAddress = connectionData.getSocket().getLocalAddress();
+        crFlag = false;
+        //bootstrap telnet communication
+        initTelnetCommunication();
+    }//initIO
+
+    public void setConnection(Connection con) {
+        connection = con;
+        connectionData = connection.getConnectionData();
+    }//setConnection
+
+    /**
+     * Method to output a byte. Ensures that CR(\r) is never send
+     * alone,but CRLF(\r\n), which is a rule of the telnet protocol.
+     *
+     * @param b Byte to be written.
+     */
+    public void write(byte b) throws IOException {
+        //ensure CRLF(\r\n) is written for LF(\n) to adhere
+        //to the telnet protocol.
+        if (!crFlag && b == 10) {
+            out.write(13);
+        }
+
+        out.write(b);
+
+        if (b == 13) {
+            crFlag = true;
+        } else {
+            crFlag = false;
+        }
+    }//write(byte)
+
+    /**
+     * Method to output an int.
+     *
+     * @param i Integer to be written.
+     */
+    public void write(int i)
+            throws IOException {
+        write((byte) i);
+    }//write(int)
+
+    /**
+     * Method to write an array of bytes.
+     *
+     * @param sequence byte[] to be written.
+     */
+    public void write(byte[] sequence) throws IOException {
+        for (byte b : sequence) {
+            write(b);
+        }
+    }//write(byte[])
+
+    /**
+     * Method to output an array of int' s.
+     *
+     * @param sequence int [] to write
+     */
+    public void write(int[] sequence) throws IOException {
+        for (int i : sequence) {
+            write((byte) i);
+        }
+    }//write(int[])
+
+    /**
+     * Method to write a char.
+     *
+     * @param ch char to be written.
+     */
+    public void write(char ch) throws IOException {
+        write((byte) ch);
+    }//write(char)
+
+    /**
+     * Method to output a string.
+     *
+     * @param str String to be written.
+     */
+    public void write(String str) throws IOException {
+        write(str.getBytes());
+    }//write(String)
+
+    /**
+     * Method to flush all buffered output.
+     */
+    public void flush() throws IOException {
+        out.flush();
+    }//flush
+
+    /**
+     * Method to close the underlying output stream to free system resources.<br>
+     * Most likely only to be called by the ConnectionManager upon clean up of
+     * connections that ended or died.
+     */
+    public void closeOutput() {
+
+        try {
+            //sends telnetprotocol logout acknowledgement
+            write(IAC);
+            write(DO);
+            write(LOGOUT);
+            //and now close underlying outputstream
+
+            out.close();
+        } catch (IOException ex) {
+            LOG.log(Level.SEVERE, "closeOutput()", ex);
+            //handle?
+        }
+    }//close
+
+    private void rawWrite(int i) throws IOException {
+        out.write(i);
+    }//rawWrite
+
+    /**
+     * Method to read a byte from the InputStream.
+     * Invokes the IACHandler upon IAC (Byte=255).
+     *
+     * @return int read from stream.
+     */
+    public int read() throws IOException {
+        int c = rawread();
+        //if (c == 255) {
+        noIac = false;
+        while ((c == 255) && (!noIac)) {
+            /**
+             * Read next, and invoke
+             * the IACHandler he is taking care of the rest. Or at least he should :)
+             */
+            c = rawread();
+            if (c != 255) {
+                iacHandler.handleC(c);
+                c = rawread();
+            } else {
+                noIac = true;
+            }
+        }
+        return stripCRSeq(c);
+    }//read
+
+    /**
+     * Method to close the underlying inputstream to free system resources.<br>
+     * Most likely only to be called by the ConnectionManager upon clean up of
+     * connections that ended or died.
+     */
+    public void closeInput() {
+        try {
+            in.close();
+        } catch (IOException e) {
+            //handle?
+        }
+    }//closeInput
+
+    /**
+     * This method reads an unsigned 16bit Integer from the stream,
+     * its here for getting the NAWS Data Values for height and width.
+     */
+    private int read16int() throws IOException {
+        int c = in.readUnsignedShort();
+        return c;
+    }//read16int
+
+    /**
+     * The following options are options which might be of interest, but are not
+     * yet implemented or in use.
+     */
+
+    /**
+     * Method to read a raw byte from the InputStream.<br>
+     * Telnet protocol layer communication is filtered and processed here.
+     *
+     * @return int read from stream.
+     */
+    private int rawread() throws IOException {
+        int b = 0;
+
+        //try {
+        b = in.readUnsignedByte();
+        connectionData.activity();
+        return b;
+    }//rawread
+
+    /**
+     * Checks for the telnet protocol specified  CR followed by NULL or LF<BR>
+     * Subsequently reads for the next byte and forwards
+     * only a ENTER represented by LF internally.
+     */
+    private int stripCRSeq(int input) throws IOException {
+        if (input == 13) {
+            rawread();
+            return 10;
+        }
+        return input;
+    }//stripCRSeq
+
+    /**
+     * Method that initializes the telnet communication layer.
+     */
+    private void initTelnetCommunication() {
+
+        initializing = true;
+        try {
+            //start out, some clients just wait
+            if (connectionData.isLineMode()) {
+                iacHandler.doLineModeInit();
+                LOG.log(Level.FINE, "Line mode initialized.");
+            } else {
+                iacHandler.doCharacterModeInit();
+                LOG.log(Level.FINE, "Character mode initialized.");
+            }
+            //open for a defined timeout so we read incoming negotiation
+            connectionData.getSocket().setSoTimeout(1000);
+            read();
+
+        } catch (Exception e) {
+            //handle properly
+            //log.error("initTelnetCommunication()",e);
+        } finally {
+            //this is important, dont ask me why :)
+            try {
+                connectionData.getSocket().setSoTimeout(0);
+            } catch (Exception ex) {
+                LOG.log(Level.SEVERE, "initTelnetCommunication()", ex);
+            }
+        }
+        initializing = false;
+    }//initTelnetCommunication
+
+    /**
+     * Method that represents the answer to the
+     * AreYouThere question of the telnet protocol specification
+     * <p/>
+     * Output of the String [HostAdress:Yes]
+     */
+    private void IamHere() {
+        try {
+            write("[" + localAddress.toString() + ":Yes]");
+            flush();
+        } catch (Exception ex) {
+            LOG.log(Level.SEVERE, "IamHere()", ex);
+        }
+    }//IamHere
+
+    /**
+     * Network virtual terminal break.
+     */
+    private void nvtBreak() {
+        connection.processConnectionEvent(new ConnectionEvent(connection, ConnectionEvent.Type.CONNECTION_BREAK));
+    }//nvtBreak
+
+    /**
+     * Method that checks reported terminal sizes and sets the
+     * asserted values in the ConnectionData instance associated with
+     * the connection.
+     *
+     * @param width  Integer that represents the Window width in chars
+     * @param height Integer that represents the Window height in chars
+     */
+    private void setTerminalGeometry(int width, int height) {
+        if (width < SMALLEST_BELIEVABLE_WIDTH) {
+            width = DEFAULT_WIDTH;
+        }
+        if (height < SMALLEST_BELIEVABLE_HEIGHT) {
+            height = DEFAULT_HEIGHT;
+        }
+        //DEBUG: write("[New Window Size " + window_width + "x" + window_height + "]");
+        connectionData.setTerminalGeometry(width, height);
+        connection.processConnectionEvent(new ConnectionEvent(connection,
+                Type.CONNECTION_TERMINAL_GEOMETRY_CHANGED));
+    }//setTerminalGeometry
+
+    public void setEcho(boolean b) {
+    }//setEcho
+
+    /**
+     * An inner class for handling incoming option negotiations implementing the <B>telnet protocol</B>
+     * specification based upon following Standards and RFCs:
+     * <OL>
+     * <LI><A HREF="ftp://ds.internic.net/rfc/rfc854.txt">854 Telnet Protocol Specification</A>
+     * <LI><A HREF="ftp://ds.internic.net/rfc/rfc855.txt">855 Telnet Option Specifications</A>
+     * <LI><A HREF="ftp://ds.internic.net/rfc/rfc857.txt">857 Telnet Echo Option</A>
+     * <LI><A HREF="ftp://ds.internic.net/rfc/rfc858.txt">858 Telnet Supress Go Ahead Option</A>
+     * <LI><A HREF="ftp://ds.internic.net/rfc/rfc727.txt">727 Telnet Logout Option</A>
+     * <LI><A HREF="ftp://ds.internic.net/rfc/rfc1073.txt">1073 Telnet Window Size Option</A>
+     * <LI><A HREF="ftp://ds.internic.net/rfc/rfc1091.txt">1091 Telnet Terminal-Type Option</A>
+     * </OL>
+     * <p/>
+     * Furthermore there are some more, which helped to solve problems, or might be important
+     * for future enhancements:<BR>
+     * <A HREF="ftp://ds.internic.net/rfc/rfc1143.txt">1143 The Q Method of Implementing Option Negotiation</A><BR>
+     * <A HREF="ftp://ds.internic.net/rfc/rfc1416.txt">1416 Telnet Authentication Option</A><BR>
+     * <p/>
+     * After an intense study of the available material (mainly cryptical written RFCs,
+     * a telnet client implementation for the macintosh based upon NCSA telnet, and a server side
+     * implementation called key, a mud-like system completely written in Java) I realized
+     * the problems we are facing regarding to the telnet protocol:
+     * <OL>
+     * <LI> a minimal spread of invented options, which means there are a lot of invented options,
+     * but rarely they made it through to become a standard.
+     * <LI> Dependency on a special type of implementation is dangerous in our case.
+     * We are no kind of host that offers the user to run several processes at once,
+     * a BBS is intended to be a single process the user is interacting with.
+     * <LI> The <B>LAMER</B> has to be expected to log in with the standard Microsoft telnet
+     * implementation. This means forget every nice feature and most of the almost-standards.
+     * <p/>
+     * </OL>
+     * <BR>
+     *
+     * @author Dieter Wimberger
+     * @version 1.1 16/06/1998
+     * <p/>
+     * <p/>
+     * <B>To-Do</B>:<UL>
+     * <LI>UNIX conform new style TTYPE negotiation. Setting a list and selecting from it...
+     * </UL>
+     */
+    class IACHandler {
+
+        /**
+         * Telnet readin buffer
+         * Here its implemented guys. Open your eyes upon this solution.
+         * The others take a one byte solution :)
+         */
+        private int[] buffer = new int[2];
+
+        /**
+         * DO_ECHO or not
+         */
+        private boolean DO_ECHO = false;
+
+        /**
+         * DO_SUPGA or not
+         */
+        private boolean DO_SUPGA = false;
+
+        /**
+         * DO_NAWS or not
+         */
+        private boolean DO_NAWS = false;
+
+        /**
+         * DO_TTYPE or not
+         */
+        private boolean DO_TTYPE = false;
+
+        /**
+         * DO_LINEMODE or not
+         */
+        private boolean DO_LINEMODE = false;
+
+        /**
+         * DO_NEWENV or not
+         */
+        private boolean DO_NEWENV = false;
+
+        /**
+         * Are we waiting for a DO reply?
+         */
+        private boolean WAIT_DO_REPLY_SUPGA = false;
+        private boolean WAIT_DO_REPLY_ECHO = false;
+        private boolean WAIT_DO_REPLY_NAWS = false;
+        private boolean WAIT_DO_REPLY_TTYPE = false;
+        private boolean WAIT_DO_REPLY_LINEMODE = false;
+        private boolean WAIT_LM_MODE_ACK = false;
+        private boolean WAIT_LM_DO_REPLY_FORWARDMASK = false;
+        private boolean WAIT_DO_REPLY_NEWENV = false;
+        private boolean WAIT_NE_SEND_REPLY = false;
+
+        /**
+         * Are we waiting for a WILL reply?
+         */
+        private boolean WAIT_WILL_REPLY_SUPGA = false;
+        private boolean WAIT_WILL_REPLY_ECHO = false;
+        private boolean WAIT_WILL_REPLY_NAWS = false;
+        private boolean WAIT_WILL_REPLY_TTYPE = false;
+
+
+        public void doCharacterModeInit() throws IOException {
+            sendCommand(WILL, ECHO, true);
+            sendCommand(DONT, ECHO, true); //necessary for some clients
+            sendCommand(DO, NAWS, true);
+            sendCommand(WILL, SUPGA, true);
+            sendCommand(DO, SUPGA, true);
+            sendCommand(DO, TTYPE, true);
+            sendCommand(DO, NEWENV, true); //environment variables
+        }//doCharacterModeInit
+
+        public void doLineModeInit() throws IOException {
+            sendCommand(DO, NAWS, true);
+            sendCommand(WILL, SUPGA, true);
+            sendCommand(DO, SUPGA, true);
+            sendCommand(DO, TTYPE, true);
+            sendCommand(DO, LINEMODE, true);
+            sendCommand(DO, NEWENV, true);
+        }//doLineModeInit
+
+
+        /**
+         * Method to handle a IAC that came in over the line.
+         *
+         * @param i (int)ed byte that followed the IAC
+         */
+        public void handleC(int i) throws IOException {
+            buffer[0] = i;
+            if (!parseTWO(buffer)) {
+                buffer[1] = rawread();
+                parse(buffer);
+            }
+            buffer[0] = 0;
+            buffer[1] = 0;
+        }//handleC
+
+        /**
+         * Method that parses for options with two characters.
+         *
+         * @param buf int [] that represents the first byte that followed the IAC first.
+         * @return true when it was a two byte command (IAC OPTIONBYTE)
+         */
+        private boolean parseTWO(int[] buf) {
+            switch (buf[0]) {
+                case IAC:
+                    //doubled IAC to escape 255 is handled within the
+                    //read method.
+                    break;
+                case AYT:
+                    IamHere();
+                    break;
+                case AO:
+                case IP:
+                case EL:
+                case EC:
+                case NOP:
+                    break;
+                case BRK:
+                    nvtBreak();
+                    break;
+                default:
+                    return false;
+            }
+            return true;
+        }//parseTWO
+
+        /**
+         * Method that parses further on for options.
+         *
+         * @param buf that represents the first two bytes that followed the IAC.
+         */
+        private void parse(int[] buf) throws IOException {
+            switch (buf[0]) {
+        /* First switch on the Negotiation Option */
+                case WILL:
+                    if (supported(buf[1]) && isEnabled(buf[1])) {
+                        ;// do nothing
+                    } else {
+                        if (waitDOreply(buf[1]) && supported(buf[1])) {
+                            enable(buf[1]);
+                            setWait(DO, buf[1], false);
+                        } else {
+                            if (supported(buf[1])) {
+                                sendCommand(DO, buf[1], false);
+                                enable(buf[1]);
+                            } else {
+                                sendCommand(DONT, buf[1], false);
+                            }
+                        }
+                    }
+                    break;
+                case WONT:
+                    if (waitDOreply(buf[1]) && supported(buf[1])) {
+                        setWait(DO, buf[1], false);
+                    } else {
+                        if (supported(buf[1]) && isEnabled(buf[1])) {
+                            // eanable() Method disables an Option that is already enabled
+                            enable(buf[1]);
+                        }
+                    }
+                    break;
+                case DO:
+                    if (supported(buf[1]) && isEnabled(buf[1])) {
+                        ; // do nothing
+                    } else {
+                        if (waitWILLreply(buf[1]) && supported(buf[1])) {
+                            enable(buf[1]);
+                            setWait(WILL, buf[1], false);
+                        } else {
+                            if (supported(buf[1])) {
+                                sendCommand(WILL, buf[1], false);
+                                enable(buf[1]);
+                            } else {
+                                sendCommand(WONT, buf[1], false);
+                            }
+                        }
+                    }
+                    break;
+                case DONT:
+                    if (waitWILLreply(buf[1]) && supported(buf[1])) {
+                        setWait(WILL, buf[1], false);
+                    } else {
+                        if (supported(buf[1]) && isEnabled(buf[1])) {
+                            // enable() Method disables an Option that is already enabled
+                            enable(buf[1]);
+                        }
+                    }
+                    break;
+
+          /* Now about other two byte IACs */
+                case DM:    //How do I implement a SYNCH signal?
+                    break;
+                case SB: //handle subnegotiations
+                    if ((supported(buf[1])) && (isEnabled(buf[1]))) {
+                        switch (buf[1]) {
+                            case NAWS:
+                                handleNAWS();
+                                break;
+                            case TTYPE:
+                                handleTTYPE();
+                                break;
+                            case LINEMODE:
+                                handleLINEMODE();
+                                break;
+                            case NEWENV:
+                                handleNEWENV();
+                                break;
+                            default:
+                                ;
+                        }
+                    } else {
+                        //do nothing
+                    }
+                    break;
+                default:
+                    ;
+            }//switch
+        }//parse
+
+        /**
+         * Method that reads a NawsSubnegotiation that ends up with a IAC SE
+         * If the measurements are unbelieveable it switches to the defaults.
+         */
+        private void handleNAWS() throws IOException {
+            int width = read16int();
+            if (width == 255) {
+                width = read16int(); //handle doubled 255 value;
+            }
+            int height = read16int();
+            if (height == 255) {
+                height = read16int(); //handle doubled 255 value;
+            }
+            skipToSE();
+            setTerminalGeometry(width, height);
+        }//handleNAWS
+
+        /**
+         * Method that reads a TTYPE Subnegotiation String that ends up with a IAC SE
+         * If no Terminal is valid, we switch to the dumb "none" terminal.
+         */
+        private void handleTTYPE() throws IOException {
+            String tmpstr = "";
+            // The next read should be 0 which is IS by the protocol
+            // specs. hmmm?
+            rawread(); //that should be the is :)
+            tmpstr = readIACSETerminatedString(40);
+            LOG.log(Level.FINE, "Reported terminal name " + tmpstr);
+            connectionData.setNegotiatedTerminalType(tmpstr);
+        }//handleTTYPE
+
+        /**
+         * Method that handles LINEMODE subnegotiation.
+         */
+        public void handleLINEMODE() throws IOException {
+            int c = rawread();
+            switch (c) {
+                case LM_MODE:
+                    handleLMMode();
+                    break;
+                case LM_SLC:
+                    handleLMSLC();
+                    break;
+                case WONT:
+                case WILL:
+                    handleLMForwardMask(c);
+                    break;
+                default:
+                    //skip to (including) SE
+                    skipToSE();
+            }
+        }//handleLINEMODE
+
+        public void handleLMMode() throws IOException {
+            //we sent the default which no client might deny
+            //so we only wait the ACK
+            if (WAIT_LM_MODE_ACK) {
+                int mask = rawread();
+                if (mask != (LM_EDIT | LM_TRAPSIG | LM_MODEACK)) {
+                    LOG.log(Level.FINE, "Client violates linemodeack sent: " + mask);
+                }
+                WAIT_LM_MODE_ACK = false;
+            }
+            skipToSE();
+        }//handleLMMode
+
+        public void handleLMSLC() throws IOException {
+            int[] triple = new int[3];
+            if (!readTriple(triple)) return;
+
+            //SLC will be initiated by the client
+            //case 1. client requests set
+            //LINEMODE SLC 0 SLC_DEFAULT 0
+            if ((triple[0] == 0) && (triple[1] == LM_SLC_DEFAULT) && (triple[2] == 0)) {
+                skipToSE();
+                //reply with SLC xxx SLC_DEFAULT 0
+                rawWrite(IAC);
+                rawWrite(SB);
+                rawWrite(LINEMODE);
+                rawWrite(LM_SLC);
+                //triples defaults for all
+                for (int i = 1; i < 12; i++) {
+                    rawWrite(i);
+                    rawWrite(LM_SLC_DEFAULT);
+                    rawWrite(0);
+                }
+                rawWrite(IAC);
+                rawWrite(SE);
+                flush();
+            } else {
+
+                //case 2: just acknowledge anything we get from the client
+                rawWrite(IAC);
+                rawWrite(SB);
+                rawWrite(LINEMODE);
+                rawWrite(LM_SLC);
+                rawWrite(triple[0]);
+                rawWrite(triple[1] | LM_SLC_ACK);
+                rawWrite(triple[2]);
+                while (readTriple(triple)) {
+                    rawWrite(triple[0]);
+                    rawWrite(triple[1] | LM_SLC_ACK);
+                    rawWrite(triple[2]);
+                }
+                rawWrite(IAC);
+                rawWrite(SE);
+                flush();
+            }
+        }//handleLMSLC
+
+        public void handleLMForwardMask(int WHAT) throws IOException {
+            switch (WHAT) {
+                case WONT:
+                    if (WAIT_LM_DO_REPLY_FORWARDMASK) {
+                        WAIT_LM_DO_REPLY_FORWARDMASK = false;
+                    }
+                    break;
+            }
+            skipToSE();
+        }//handleLMForward
+
+        public void handleNEWENV() throws IOException {
+            LOG.log(Level.FINE, "handleNEWENV()");
+            int c = rawread();
+            switch (c) {
+                case IS:
+                    handleNEIs();
+                    break;
+                case NE_INFO:
+                    handleNEInfo();
+                    break;
+                default:
+                    //skip to (including) SE
+                    skipToSE();
+            }
+        }//handleNEWENV
+
+        /*
+          The characters following a "type" up to the next "type" or VALUE specify the
+          variable name.
+
+          If a "type" is not followed by a VALUE
+          (e.g., by another VAR, USERVAR, or IAC SE) then that variable is
+          undefined.
+         */
+        private int readNEVariableName(StringBuffer sbuf) throws IOException {
+            LOG.log(Level.FINE, "readNEVariableName()");
+            int i = -1;
+            do {
+                i = rawread();
+                if (i == -1) {
+                    return NE_IN_ERROR;
+                } else if (i == IAC) {
+                    i = rawread();
+                    if (i == IAC) {
+                        //duplicated IAC
+                        sbuf.append((char) i);
+                    } else if (i == SE) {
+                        return NE_IN_END;
+                    } else {
+                        //Error should have been duplicated
+                        return NE_IN_ERROR;
+                    }
+                } else if (i == NE_ESC) {
+                    i = rawread();
+                    if (i == NE_ESC || i == NE_VAR || i == NE_USERVAR || i == NE_VALUE) {
+                        sbuf.append((char) i);
+                    } else {
+                        return NE_IN_ERROR;
+                    }
+                } else if (i == NE_VAR || i == NE_USERVAR) {
+                    return NE_VAR_UNDEFINED;
+                } else if (i == NE_VALUE) {
+                    return NE_VAR_DEFINED;
+                } else {
+                    //check maximum length to prevent overflow
+                    if (sbuf.length() >= NE_VAR_NAME_MAXLENGTH) {
+                        //TODO: Log Overflow
+                        return NE_IN_ERROR;
+                    } else {
+                        sbuf.append((char) i);
+                    }
+                }
+            } while (true);
+        }//readNEVariableName
+
+
+        /*
+          The characters following a VALUE up to the next
+          "type" specify the value of the variable.
+          If a VALUE is immediately
+          followed by a "type" or IAC, then the variable is defined, but has
+          no value.
+          If an IAC is contained between the IS and the IAC SE,
+          it must be sent as IAC IAC.
+        */
+        private int readNEVariableValue(StringBuffer sbuf) throws IOException {
+            LOG.log(Level.FINE, "readNEVariableValue()");
+            //check conditions for first character after VALUE
+            int i = rawread();
+            if (i == -1) {
+                return NE_IN_ERROR;
+            } else if (i == IAC) {
+                i = rawread();
+                if (i == IAC) {
+                    //Double IAC
+                    return NE_VAR_DEFINED_EMPTY;
+                } else if (i == SE) {
+                    return NE_IN_END;
+                } else {
+                    //according to rule IAC has to be duplicated
+                    return NE_IN_ERROR;
+                }
+            } else if (i == NE_VAR || i == NE_USERVAR) {
+                return NE_VAR_DEFINED_EMPTY;
+            } else if (i == NE_ESC) {
+                //escaped value
+                i = rawread();
+                if (i == NE_ESC || i == NE_VAR || i == NE_USERVAR || i == NE_VALUE) {
+                    sbuf.append((char) i);
+                } else {
+                    return NE_IN_ERROR;
+                }
+            } else {
+                //character
+                sbuf.append((char) i);
+            }
+            //loop until end of value (IAC SE or TYPE)
+            do {
+                i = rawread();
+                if (i == -1) {
+                    return NE_IN_ERROR;
+                } else if (i == IAC) {
+                    i = rawread();
+                    if (i == IAC) {
+                        //duplicated IAC
+                        sbuf.append((char) i);
+                    } else if (i == SE) {
+                        return NE_IN_END;
+                    } else {
+                        //Error should have been duplicated
+                        return NE_IN_ERROR;
+                    }
+                } else if (i == NE_ESC) {
+                    i = rawread();
+                    if (i == NE_ESC || i == NE_VAR || i == NE_USERVAR || i == NE_VALUE) {
+                        sbuf.append((char) i);
+                    } else {
+                        return NE_IN_ERROR;
+                    }
+                } else if (i == NE_VAR || i == NE_USERVAR) {
+                    return NE_VAR_OK;
+                } else {
+                    //check maximum length to prevent overflow
+                    if (sbuf.length() > NE_VAR_VALUE_MAXLENGTH) {
+                        //TODO: LOG Overflow
+                        return NE_IN_ERROR;
+                    } else {
+                        sbuf.append((char) i);
+                    }
+                }
+            } while (true);
+        }//readNEVariableValue
+
+
+        public void readNEVariables() throws IOException {
+            LOG.log(Level.FINE, "readNEVariables()");
+            StringBuffer sbuf = new StringBuffer(50);
+            int i = rawread();
+            if (i == IAC) {
+                //invalid or empty response
+                skipToSE();
+                LOG.log(Level.FINE, "readNEVariables()::INVALID VARIABLE");
+                return;
+            }
+            boolean cont = true;
+            if (i == NE_VAR || i == NE_USERVAR) {
+                do {
+                    switch (readNEVariableName(sbuf)) {
+                        case NE_IN_ERROR:
+                            LOG.log(Level.FINE, "readNEVariables()::NE_IN_ERROR");
+                            return;
+                        case NE_IN_END:
+                            LOG.log(Level.FINE, "readNEVariables()::NE_IN_END");
+                            return;
+                        case NE_VAR_DEFINED:
+                            LOG.log(Level.FINE, "readNEVariables()::NE_VAR_DEFINED");
+                            String str = sbuf.toString();
+                            sbuf.delete(0, sbuf.length());
+                            switch (readNEVariableValue(sbuf)) {
+                                case NE_IN_ERROR:
+                                    LOG.log(Level.FINE, "readNEVariables()::NE_IN_ERROR");
+                                    return;
+                                case NE_IN_END:
+                                    LOG.log(Level.FINE, "readNEVariables()::NE_IN_END");
+                                    return;
+                                case NE_VAR_DEFINED_EMPTY:
+                                    LOG.log(Level.FINE, "readNEVariables()::NE_VAR_DEFINED_EMPTY");
+                                    break;
+                                case NE_VAR_OK:
+                                    //add variable
+                                    LOG.log(Level.FINE, "readNEVariables()::NE_VAR_OK:VAR=" + str + " VAL=" + sbuf.toString());
+                                    TelnetIO.this.connectionData.getEnvironment().put(str, sbuf.toString());
+                                    sbuf.delete(0, sbuf.length());
+                                    break;
+                            }
+                            break;
+                        case NE_VAR_UNDEFINED:
+                            LOG.log(Level.FINE, "readNEVariables()::NE_VAR_UNDEFINED");
+                            break;
+                    }
+                } while (cont);
+            }
+        }//readVariables
+
+        public void handleNEIs() throws IOException {
+            LOG.log(Level.FINE, "handleNEIs()");
+            if (isEnabled(NEWENV)) {
+                readNEVariables();
+            }
+        }//handleNEIs
+
+        public void handleNEInfo() throws IOException {
+            LOG.log(Level.FINE, "handleNEInfo()");
+            if (isEnabled(NEWENV)) {
+                readNEVariables();
+            }
+        }//handleNEInfo
+
+        /**
+         * Method that sends a TTYPE Subnegotiation Request.
+         * IAC SB TERMINAL-TYPE SEND
+         */
+        public void getTTYPE() throws IOException {
+            if (isEnabled(TTYPE)) {
+                rawWrite(IAC);
+                rawWrite(SB);
+                rawWrite(TTYPE);
+                rawWrite(SEND);
+                rawWrite(IAC);
+                rawWrite(SE);
+                flush();
+            }
+        }//getTTYPE
+
+        /**
+         * Method that sends a LINEMODE MODE Subnegotiation request.
+         * IAC LINEMODE MODE MASK SE
+         */
+        public void negotiateLineMode() throws IOException {
+            if (isEnabled(LINEMODE)) {
+                rawWrite(IAC);
+                rawWrite(SB);
+                rawWrite(LINEMODE);
+                rawWrite(LM_MODE);
+                rawWrite(LM_EDIT | LM_TRAPSIG);
+                rawWrite(IAC);
+                rawWrite(SE);
+                WAIT_LM_MODE_ACK = true;
+
+                //dont forwardmask
+                rawWrite(IAC);
+                rawWrite(SB);
+                rawWrite(LINEMODE);
+                rawWrite(DONT);
+                rawWrite(LM_FORWARDMASK);
+                rawWrite(IAC);
+                rawWrite(SE);
+                WAIT_LM_DO_REPLY_FORWARDMASK = true;
+                flush();
+            }
+        }//negotiateLineMode
+
+        /**
+         * Method that sends a NEW-ENVIRON SEND subnegotiation request
+         * for default variables and user variables.
+         * IAC SB NEW-ENVIRON SEND VAR USERVAR IAC SE
+         */
+        private void negotiateEnvironment() throws IOException {
+            //log.debug("negotiateEnvironment()");
+            if (isEnabled(NEWENV)) {
+                rawWrite(IAC);
+                rawWrite(SB);
+                rawWrite(NEWENV);
+                rawWrite(SEND);
+                rawWrite(NE_VAR);
+                rawWrite(NE_USERVAR);
+                rawWrite(IAC);
+                rawWrite(SE);
+                WAIT_NE_SEND_REPLY = true;
+                flush();
+            }
+        }//negotiateEnvironment
+
+        /**
+         * Method that skips a subnegotiation response.
+         */
+        private void skipToSE() throws IOException {
+            while (rawread() != SE) ;
+        }//skipSubnegotiation
+
+        private boolean readTriple(int[] triple) throws IOException {
+            triple[0] = rawread();
+            triple[1] = rawread();
+            if ((triple[0] == IAC) && (triple[1] == SE)) {
+                return false;
+            } else {
+                triple[2] = rawread();
+                return true;
+            }
+        }//readTriple
+
+        /**
+         * Method that reads a subnegotiation String,
+         * one of those that end with a IAC SE combination.
+         * A maximum length is observed to prevent overflow.
+         *
+         * @return IAC SE terminated String
+         */
+        private String readIACSETerminatedString(int maxlength) throws IOException {
+            int where = 0;
+            char[] cbuf = new char[maxlength];
+            char b = ' ';
+            boolean cont = true;
+
+            do {
+                int i;
+                i = rawread();
+                switch (i) {
+                    case IAC:
+                        i = rawread();
+                        if (i == SE) {
+                            cont = false;
+                        }
+                        break;
+                    case -1:
+                        return (new String("default"));
+                    default:
+                }
+                if (cont) {
+                    b = (char) i;
+                    //Fix for overflow wimpi (10/06/2004)
+                    if (b == '\n' || b == '\r' || where == maxlength) {
+                        cont = false;
+                    } else {
+                        cbuf[where++] = b;
+                    }
+                }
+            } while (cont);
+
+            return (new String(cbuf, 0, where));
+        }//readIACSETerminatedString
+
+        /**
+         * Method that informs internally about the supported Negotiation Options
+         *
+         * @param i int that represents requested the Option
+         * @return Boolean that represents support status
+         */
+        private boolean supported(int i) {
+            switch (i) {
+                case SUPGA:
+                case ECHO:
+                case NAWS:
+                case TTYPE:
+                case NEWENV:
+                    return true;
+                case LINEMODE:
+                    return connectionData.isLineMode();
+                default:
+                    return false;
+            }
+        }//supported
+
+        /**
+         * Method that sends a Telnet IAC String with TelnetIO.write(byte b) method.
+         *
+         * @param i int that represents requested Command Type (DO,DONT,WILL,WONT)
+         * @param j int that represents the Option itself (e.g. ECHO, NAWS)
+         */
+        private void sendCommand(int i, int j, boolean westarted) throws IOException {
+            rawWrite(IAC);
+            rawWrite(i);
+            rawWrite(j);
+            // we started with DO OPTION and now wait for reply
+            if ((i == DO) && westarted) setWait(DO, j, true);
+            // we started with WILL OPTION and now wait for reply
+            if ((i == WILL) && westarted) setWait(WILL, j, true);
+            flush();
+        }//sendCommand
+
+        /**
+         * Method enables or disables a supported Option
+         *
+         * @param i int that represents the Option
+         */
+        private void enable(int i) throws IOException {
+            switch (i) {
+                case SUPGA:
+                    if (DO_SUPGA) {
+                        DO_SUPGA = false;
+                    } else {
+                        DO_SUPGA = true;
+                    }
+                    break;
+                case ECHO:
+                    if (DO_ECHO) {
+                        DO_ECHO = false;
+                    } else {
+                        DO_ECHO = true;
+                    }
+                    break;
+                case NAWS:
+                    if (DO_NAWS) {
+                        DO_NAWS = false;
+                    } else {
+                        DO_NAWS = true;
+                    }
+                    break;
+                case TTYPE:
+                    if (DO_TTYPE) {
+                        DO_TTYPE = false;
+                    } else {
+                        DO_TTYPE = true;
+                        getTTYPE();
+                    }
+                    break;
+                case LINEMODE:
+                    if (DO_LINEMODE) {
+                        DO_LINEMODE = false;
+                        //set false in connection data, so the application knows.
+                        connectionData.setLineMode(false);
+                    } else {
+                        DO_LINEMODE = true;
+                        negotiateLineMode();
+                    }
+                    break;
+                case NEWENV:
+                    if (DO_NEWENV) {
+                        DO_NEWENV = false;
+                    } else {
+                        DO_NEWENV = true;
+                        negotiateEnvironment();
+                    }
+                    break;
+            }
+        }//enable
+
+        /**
+         * Method that informs internally about the status of the supported
+         * Negotiation Options.
+         *
+         * @param i int that represents requested the Option
+         * @return Boolean that represents the enabled status
+         */
+        private boolean isEnabled(int i) {
+            switch (i) {
+                case SUPGA:
+                    return DO_SUPGA;
+                case ECHO:
+                    return DO_ECHO;
+                case NAWS:
+                    return DO_NAWS;
+                case TTYPE:
+                    return DO_TTYPE;
+                case LINEMODE:
+                    return DO_LINEMODE;
+                case NEWENV:
+                    return DO_NEWENV;
+                default:
+                    return false;
+            }
+        }//isEnabled
+
+        /**
+         * Method that informs internally about the WILL wait status
+         * of an option.
+         *
+         * @param i that represents requested the Option
+         * @return Boolean that represents WILL wait status of the Option
+         */
+        private boolean waitWILLreply(int i) {
+            switch (i) {
+                case SUPGA:
+                    return WAIT_WILL_REPLY_SUPGA;
+                case ECHO:
+                    return WAIT_WILL_REPLY_ECHO;
+                case NAWS:
+                    return WAIT_WILL_REPLY_NAWS;
+                case TTYPE:
+                    return WAIT_WILL_REPLY_TTYPE;
+                default:
+                    return false;
+            }
+        }//waitWILLreply
+
+        /**
+         * Method that informs internally about the DO wait status
+         * of an option.
+         *
+         * @param i Integer that represents requested the Option
+         * @return Boolean that represents DO wait status of the Option
+         */
+        private boolean waitDOreply(int i) {
+            switch (i) {
+                case SUPGA:
+                    return WAIT_DO_REPLY_SUPGA;
+                case ECHO:
+                    return WAIT_DO_REPLY_ECHO;
+                case NAWS:
+                    return WAIT_DO_REPLY_NAWS;
+                case TTYPE:
+                    return WAIT_DO_REPLY_TTYPE;
+                case LINEMODE:
+                    return WAIT_DO_REPLY_LINEMODE;
+                case NEWENV:
+                    return WAIT_DO_REPLY_NEWENV;
+                default:
+                    return false;
+            }
+        }//waitDOreply
+
+        /**
+         * Method that mutates the wait status of an option in
+         * negotiation. We need the wait status to keep track of
+         * negotiation in process. So we cant miss if we started out
+         * or the other and so on.
+         *
+         * @param WHAT   Integer values of  DO or WILL
+         * @param OPTION Integer that represents the Option
+         * @param WAIT   Boolean that represents the status of wait that should be set
+         */
+        private void setWait(int WHAT, int OPTION, boolean WAIT) {
+            switch (WHAT) {
+                case DO:
+                    switch (OPTION) {
+                        case SUPGA:
+                            WAIT_DO_REPLY_SUPGA = WAIT;
+                            break;
+                        case ECHO:
+                            WAIT_DO_REPLY_ECHO = WAIT;
+                            break;
+                        case NAWS:
+                            WAIT_DO_REPLY_NAWS = WAIT;
+                            break;
+                        case TTYPE:
+                            WAIT_DO_REPLY_TTYPE = WAIT;
+                            break;
+                        case LINEMODE:
+                            WAIT_DO_REPLY_LINEMODE = WAIT;
+                            break;
+                        case NEWENV:
+                            WAIT_DO_REPLY_NEWENV = WAIT;
+                            break;
+                    }
+                    break;
+                case WILL:
+                    switch (OPTION) {
+                        case SUPGA:
+                            WAIT_WILL_REPLY_SUPGA = WAIT;
+                            break;
+                        case ECHO:
+                            WAIT_WILL_REPLY_ECHO = WAIT;
+                            break;
+                        case NAWS:
+                            WAIT_WILL_REPLY_NAWS = WAIT;
+                            break;
+                        case TTYPE:
+                            WAIT_WILL_REPLY_TTYPE = WAIT;
+                            break;
+                    }
+                    break;
+            }
+        }//setWait
+
+    }//inner class IACHandler
+
+    /** end Constants declaration **************************************************/
+
+}//class TelnetIO
diff --git a/gogo/jline/src/main/resources/gosh_profile b/gogo/jline/src/main/resources/gosh_profile
new file mode 100644
index 0000000..1a5822c
--- /dev/null
+++ b/gogo/jline/src/main/resources/gosh_profile
@@ -0,0 +1,247 @@
+#
+# 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.
+#
+# 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.
+
+# catch all exceptions from this script to avoid it aborting startup
+try {
+
+  # ensure gogo commands are found first
+  SCOPE = gogo:*
+
+  # add methods on BundleContext object as commands
+  addcommand context ${.context}
+
+  # add methods on System object as commands
+  #addcommand system (((${.context} getClass) getClassLoader) 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! '
+  \#rprompt = { (new java.text.SimpleDateFormat "HH:mm:ss") format (new Date) }
+
+
+  __option_not_present = {
+      res = true
+      opts = ([ $args ] get 0)
+      each $opts {
+          arg = $it
+          each ($.commandLine words) {
+              if { ($it toString) contentEquals ($arg toString) } {
+                  res = false
+              }
+          }
+      }
+      $res
+  }
+
+  __load_class = {
+      (($.reader class) classLoader) loadClass $1
+  }
+
+  __as_list = {
+      (__load_class java.util.Arrays) asList $1
+  }
+
+  __set_unset_arguments = {
+      is_setopt = (($.commandLine words) get 0) equals "setopt"
+      enums = ((__load_class 'org.jline.ConsoleReader$Option') enumConstants)
+      candidates = new ArrayList
+      each (__as_list $enums) {
+          name = ((($it name) toLowerCase) replace '_' '-')
+          is_set = ($.reader isSet $it)
+          neg = %(( if(is_setopt, is_set, not(is_set)) ))
+          if { $neg } {
+              name = "no-${name}"
+          }
+          if { not  { (($.commandLine words) subList 1 ($.commandLine wordIndex)) contains $name } } {
+              $candidates add (new org.jline.Candidate $name $name (if { $neg } { "unset" } { "set" }) null null null true)
+          }
+      }
+      $candidates
+  }
+
+  setopt pad-prompts
+  setopt group
+
+  complete -c gogo:complete -e
+  complete -c gogo:complete -d "Edit command specific completions"
+  complete -c gogo:complete -s c -l command --description "Command to add completion to" -n '__option_not_present -c --command' -a '$.commands'
+  complete -c gogo:complete -s s -l short-option --description "Posix-style option to complete" -n '__option_not_present -s --short-option'
+  complete -c gogo:complete -s l -l long-option --description "GNU-style option to complete" -n '__option_not_present -l --long-option'
+  complete -c gogo:complete -s a -l arguments --description "A list of possible arguments" -n '__option_not_present -a --argument'
+  complete -c gogo:complete -s d -l description --description "Description of this completions" -n '__option_not_present -d --description'
+  complete -c gogo:complete -s h -l help --description "Display help and exit" -n '__option_not_present -h --help'
+  complete -c gogo:complete -s n -l condition --description "The completion should only be used if the specified command has a zero exit status"  -n '__option_not_present -n --condition'
+  complete -c gogo:complete -s e -l erase --description "Remove completion"  -n '__option_not_present -e --erase'
+
+  complete -c gogo:history -e
+  complete -c gogo:history -d "Show and manipulate command history"
+  complete -c gogo:history -l clear --description "Clear history" -n '__option_not_present --clear'
+  complete -c gogo:history -l save --description "Save history" -n '__option_not_present --save'
+
+  complete -c gogo:setopt -e
+  complete -c gogo:setopt -d "Set or view set shell options"
+  complete -c gogo:setopt -a '__set_unset_arguments'
+
+  complete -c gogo:unsetopt -e
+  complete -c gogo:unsetopt -d "Unset or view unset shell options"
+  complete -c gogo:unsetopt -a '__set_unset_arguments'
+
+  complete -c gogo:cat -e
+  complete -c gogo:cat -d "Concatenate and print files"
+  complete -c gogo:cat -s n "Number the output lines, starting at 1"
+  complete -c gogo:cat -a '__files'
+
+  complete -c gogo:pwd -e
+  complete -c gogo:pwd -d "Get current directory"
+
+  complete -c gogo:ls -e
+  complete -c gogo:ls -d "List files"
+
+  complete -c gogo:cd -e
+  complete -c gogo:cd -d "Change current directory"
+  complete -c gogo:cd -a '__directories'
+
+  complete -c gogo:sleep -e
+  complete -c gogo:sleep -d "Pause execution for the specified amount of time"
+
+  complete -c gogo:echo -e
+  complete -c gogo:echo -d "Write arguments to the standard output"
+  complete -c gogo:echo -s n -d "No trailing new line"
+
+  complete -c gogo:grep -e
+  complete -c gogo:grep -d "File pattern searcher"
+  # TODO
+
+  complete -c gogo:sort -e
+  complete -c gogo:sort -d "Sort lines of text files"
+  # TODO
+
+  complete -c gogo:gosh -e
+  complete -c gogo:gosh -d "Execute script with arguments in a new session"
+  # TODO
+
+  complete -c gogo:sh -e
+  complete -c gogo:sh -d "Execute script with arguments in a new session"
+  # TODO
+
+  complete -c gogo:source -e
+  complete -c gogo:source -d "Execute script with arguments"
+  # TODO
+
+  # TODO: format getopt new set tac type addcommand removeCommand eval
+
+  complete -c gogo:each -e
+  complete -c gogo:each -d "Loop and execute script on the specified elements"
+
+  complete -c gogo:if -e
+  complete -c gogo:if -d "Conditionaly execute a script"
+
+  complete -c gogo:not -e
+  complete -c gogo:not -d "Negates the result of a script"
+
+  complete -c gogo:throw -e
+  complete -c gogo:throw -d "Throws an exception"
+
+  complete -c gogo:try -e
+  complete -c gogo:try -d "Try executing a script and catch any exception"
+
+  complete -c gogo:until -e
+  complete -c gogo:until -d "Loop and execute script until a condition is satisfied"
+
+  complete -c gogo:while -e
+  complete -c gogo:while -d "Loop and execute script while a condition is satisfied"
+
+  complete -c gogo:less -e
+  complete -c gogo:less -d "File pager"
+  complete -c gogo:less -s e -l quit-at-eof --description "Exit on second EOF"
+  complete -c gogo:less -s E -l QUIT-AT-EOF --description "Exit on EOF"
+  complete -c gogo:less -s q -l quiet -l silent --description "Silent mode"
+  complete -c gogo:less -s Q -l QUIET -l SILENT --description "Completely  silent"
+  complete -c gogo:less -s S -l chop-long-lines --description "Do not fold long lines"
+  complete -c gogo:less -s i -l ignore-case --description "Search ignores lowercase case"
+  complete -c gogo:less -s I -l IGNORE-CASE --description "Search ignores all case"
+  complete -c gogo:less -s x -l tabs --description "Set tab stops"
+  complete -c gogo:less -s N -l LINE-NUMBERS --description "Display line number for each line"
+  complete -c gogo:less -a '__files'
+
+  complete -c gogo:nano -e
+  complete -c gogo:nano -d "File editor"
+  complete -c gogo:nano -a '__files'
+
+  complete -c gogo:keymap -e
+  complete -c gogo:keymap -d "Manipulate keymaps"
+  complete -c gogo:keymap -s N --description "Create a new keymap" -n '__option_not_present -N -d -D -l -r -s -A'
+  complete -c gogo:keymap -s d --description "Delete existing keymaps and reset to default state" -n '__option_not_present -N -d -D -l -r -s -A'
+  complete -c gogo:keymap -s D --description "Delete named keymaps" -n '__option_not_present -N -d -D -l -r -s -A'
+  complete -c gogo:keymap -s l --description "List existing keymap names" -n '__option_not_present -N -d -D -l -r -s -A'
+  complete -c gogo:keymap -s r --description "Unbind specified in-strings" -n '__option_not_present -N -d -D -l -r -s -A'
+  complete -c gogo:keymap -s s --description "Bind each in-string to each out-string" -n '__option_not_present -N -d -D -l -r -s -A'
+  complete -c gogo:keymap -s A --description "Create alias to keymap" -n '__option_not_present -N -d -D -l -r -s -A'
+  complete -c gogo:keymap -s e --description "Select emacs keymap and bind it to main" -n '__option_not_present -e -a -v -M'
+  complete -c gogo:keymap -s v --description "Select viins keymap and bind it to main" -n '__option_not_present -e -a -v -M'
+  complete -c gogo:keymap -s a --description "Select vicmd keymap" -n '__option_not_present -e -a -v -M'
+  complete -c gogo:keymap -s M --description "Specify keymap to select" -n '__option_not_present -e -a -v -M' -a '(keymap -l | tac) split " "'
+  complete -c gogo:keymap -s R --description "Interpret in-strings as ranges"
+  complete -c gogo:keymap -s p --description "List bindings which have given key sequence as a a prefix"
+  complete -c gogo:keymap -s L --description "Output in form of keymap commands"
+
+  complete -c gogo:widget -e
+  complete -c gogo:widget -d "Manipulate widgets"
+  complete -c gogo:widget -s N --description "Create a new widget" -n '__option_not_present -N -A -D -U -l'
+  complete -c gogo:widget -s A --description "Create alias to widget" -n '__option_not_present -N -A -D -U -l'
+  complete -c gogo:widget -s D --description "Delete widgets" -n '__option_not_present -N -A -D -U -l'
+  complete -c gogo:widget -s U --description "Push characters to the stack" -n '__option_not_present -N -A -D -U -l'
+  complete -c gogo:widget -s l --description "List user-defined widgets" -n '__option_not_present -N -A -D -U -l'
+  complete -c gogo:widget -s a --description "With -l, list all widgets" -n '__option_not_present -l'
+
+  complete -c gogo:telnetd -e
+  complete -c gogo:telnetd -d "Telnet daemon"
+  complete -c gogo:telnetd -s i -l ip --description "Listening IP interface" -n '__option_not_present -i --ip'
+  complete -c gogo:telnetd -s p -l port --description "Listening IP port" -n '__option_not_present -p --port'
+  complete -c gogo:telnetd -a '[start stop status]'
+
+  complete -c gogo:sshd -e
+  complete -c gogo:sshd -d "SSH daemon"
+  complete -c gogo:sshd -s i -l ip --description "Listening IP interface" -n '__option_not_present -i --ip'
+  complete -c gogo:sshd -s p -l port --description "Listening IP port" -n '__option_not_present -p --port'
+  complete -c gogo:sshd -a '[start stop status]'
+
+  complete -c gogo:tmux -e
+  complete -c gogo:tmux -d "Terminal multiplexer"
+
+  # print welcome message
+  cat ($0 resolve motd)
+} {
+    echo "$0: ERROR: $exception"
+}
+
+# end
diff --git a/gogo/jline/src/main/resources/motd b/gogo/jline/src/main/resources/motd
new file mode 100644
index 0000000..01954f9
--- /dev/null
+++ b/gogo/jline/src/main/resources/motd
@@ -0,0 +1,3 @@
+____________________________
+Welcome to Apache Felix Gogo
+
diff --git a/gogo/pom.xml b/gogo/pom.xml
index d814dbe..39a32d0 100644
--- a/gogo/pom.xml
+++ b/gogo/pom.xml
@@ -40,6 +40,7 @@
     <modules>
     	<module>gogo-parent</module>
         <module>runtime</module>
+        <module>jline</module>
         <module>shell</module>
         <module>command</module>
     </modules>
