diff --git a/jline/DEPENDENCIES b/jline/DEPENDENCIES
new file mode 100644
index 0000000..664b8ac
--- /dev/null
+++ b/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/jline/LICENSE b/jline/LICENSE
new file mode 100644
index 0000000..d645695
--- /dev/null
+++ b/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/jline/NOTICE b/jline/NOTICE
new file mode 100644
index 0000000..4007bd3
--- /dev/null
+++ b/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/jline/doc/changelog.txt b/jline/doc/changelog.txt
new file mode 100644
index 0000000..7aa4756
--- /dev/null
+++ b/jline/doc/changelog.txt
@@ -0,0 +1,154 @@
+Changes from 1.1.0 to 1.1.2
+----------------------------
+Improvement
+    [FELIX-5970] - Add requirement & capabilities model so gogo can be resolved
+    [FELIX-5999] - cleanup compiler warnings
+    [FELIX-6003] - Add some resolver checks to make sure @RequireGogo annotation works for both jline and shell
+    [FELIX-6007] - create a gogo bom
+
+Changes from 1.0.12 to 1.1.0
+----------------------------
+New Feature
+    [FELIX-5833] - Support for completion of quoted arguments
+    [FELIX-5834] - Upgrade to JLine 3.7.0
+    [FELIX-5835] - Upgrade to JDK 8
+    [FELIX-5836] - Upgrade to OSGi r6
+    [FELIX-5837] - [gogo][jline] Improve styling support
+
+Improvement
+    [FELIX-5857] - Provide a context classloader on the session to help with class loading
+    [FELIX-5869] - [goto][jline] Weird error if the script contains unicode characters
+
+Changes from 1.0.10 to 1.0.12
+-----------------------------
+Improvement
+    [FELIX-5822] - [gogo][jline] Improve syntax of procedural functions
+
+Changes from 1.0.8 to 1.0.10
+----------------------------
+Bug
+    [FELIX-5635] - [gogo][jline] The "cd" command should not attempt to complete multiple directories
+    [FELIX-5714] - ArrayIndexOutOfBoundsException running history | grep
+
+Improvement
+    [FELIX-5651] - Disable Log history in Gogo console
+    [FELIX-5705] - Provide completion for SCR commands
+
+Changes from 1.0.6 to 1.0.8
+---------------------------
+Bug
+    [FELIX-5687] - Do not use the threaded streams when passing the input stream to a command
+
+Changes from 1.0.4 to 1.0.6
+---------------------------
+Bug
+    [FELIX-5600] - System streams are not correctly set when running a new shell
+    [FELIX-5629] - [gogo][jline] When a job is in the foreground, the shell should wait for its completion
+    [FELIX-5631] - [gogo][runtime] The parser indicates wrong repair string when parsing heredocs
+
+Improvement
+    [FELIX-5594] - [gogo][jline] Improve color support for ls/grep and syntax highlighting
+    [FELIX-5596] - Allow to configure the colors for the gogo grep command
+    [FELIX-5598] - [gogo][jline] Support the JLine ttop function if available
+
+Changes from 1.0.2 to 1.0.4
+---------------------------
+Bug
+    [FELIX-5463] - [gogo][jline] The Main class should add a default Function->FunctionInterface converter
+    [FELIX-5498] - [gogo][jline] The shell should display exception thrown from commands
+    [FELIX-5584] - [gogo][jline] Remove dependency on LineReaderImpl
+
+Changes from 1.0.0 to 1.0.2
+---------------------------
+Bug
+    [FELIX-5077] - Gogo shell prints out nasty error on shutdown
+    [FELIX-5388] - Strange Prompt characters in the eclipse console
+    [FELIX-5442] - [gogo][jline] The gosh_script can not resolve the motd file inside the jar
+    [FELIX-5447] - [gogo][jline] Command results should be printed by default
+
+Changes from 0.10.0 to 1.0.0
+----------------------------
+** Bug
+    * [FELIX-5342] - Division by zero in new gogo for jline3
+
+** New Feature
+    * [FELIX-5272] - New gogo features
+
+** Task
+    * [FELIX-5378] - [gogo] Upgrade packages and bundle to 1.0.0
+
+Changes from 0.8.0 to 0.10.0
+----------------------------
+
+** Improvement
+    * Added gosh_profile work around for issue wit.3 API to 1.0.0
+      ambiguity.
+      ** Bug
+    * [FELIX-5342] - Division by zero in new gogo for jline3
+
+** New Feature
+    * [FELIX-5272] - New gogo features
+
+** Task
+    * [FELIX-5378] - [gogo] Upgrade packages and bundle to 1.
+
+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/jline/pom.xml b/jline/pom.xml
new file mode 100644
index 0000000..5093d6a
--- /dev/null
+++ b/jline/pom.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied.  See the License for the
+ specific language governing permissions and limitations
+ under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+    <parent>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>gogo-parent</artifactId>
+        <version>5</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>1.1.2</version>
+    <url>http://felix.apache.org/</url>
+    <scm>
+        <connection>scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.gogo.jline-1.1.2</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.gogo.jline-1.1.2</developerConnection>
+        <url>https://svn.apache.org/repos/asf/felix/releases/org.apache.felix.gogo.jline-1.1.2</url>
+    </scm>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.annotation</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.gogo.runtime</artifactId>
+            <version>1.1.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.jline</groupId>
+            <artifactId>jline</artifactId>
+            <version>3.7.0</version>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sshd</groupId>
+            <artifactId>sshd-core</artifactId>
+            <version>1.2.0</version>
+            <optional>true</optional>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+        </dependency>
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Export-Package>
+                            org.apache.felix.gogo.jline
+                        </Export-Package>
+                        <Import-Package>
+                            !org.apache.felix.gogo.runtime.threadio,
+                            org.jline*;version="[3.0,4)",
+                            *
+                        </Import-Package>
+                    </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>
+        </plugins>
+    </build>
+</project>
diff --git a/jline/src/main/java/org/apache/felix/gogo/jline/Activator.java b/jline/src/main/java/org/apache/felix/gogo/jline/Activator.java
new file mode 100644
index 0000000..62f86d9
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/Activator.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.gogo.jline;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.apache.felix.gogo.jline.Shell.Context;
+import org.apache.felix.gogo.jline.SingleServiceTracker.SingleServiceListener;
+import org.apache.felix.gogo.runtime.Token;
+import org.apache.felix.gogo.runtime.Tokenizer;
+import org.apache.felix.service.command.CommandProcessor;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.command.Converter;
+import org.jline.terminal.Terminal;
+import org.jline.terminal.TerminalBuilder;
+import org.osgi.annotation.bundle.Header;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
+
+@Header(name = Constants.BUNDLE_ACTIVATOR, value = "${@class}")
+public class Activator implements BundleActivator, SingleServiceListener {
+    private final Set<ServiceRegistration<?>> regs = new HashSet<>();
+    private BundleContext context;
+    private SingleServiceTracker<CommandProcessor> commandProcessorTracker;
+
+    private Runnable closer;
+
+    public Activator() {
+    }
+
+    public void start(BundleContext context) throws Exception {
+        this.context = context;
+        this.commandProcessorTracker = new SingleServiceTracker<>(context, CommandProcessor.class, this);
+        this.commandProcessorTracker.open();
+    }
+
+    public void stop(BundleContext context) {
+        Iterator<ServiceRegistration<?>> iterator = regs.iterator();
+        while (iterator.hasNext()) {
+            ServiceRegistration<?> reg = iterator.next();
+            reg.unregister();
+            iterator.remove();
+        }
+        this.commandProcessorTracker.close();
+    }
+
+    @Override
+    public void serviceFound() {
+        try {
+            closer = startShell(context, commandProcessorTracker.getService());
+        } catch (Exception e) {
+            // Ignore
+        }
+    }
+
+    @Override
+    public void serviceLost() {
+        stopShell();
+    }
+
+    @Override
+    public void serviceReplaced() {
+        serviceLost();
+        serviceFound();
+    }
+
+    private Runnable startShell(BundleContext context, CommandProcessor processor) throws Exception {
+        Dictionary<String, Object> dict = new Hashtable<>();
+        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(processor), dict));
+
+        Shell shell = new Shell(new ShellContext(), processor);
+        dict.put(CommandProcessor.COMMAND_FUNCTION, Shell.functions);
+        regs.add(context.registerService(Shell.class.getName(), shell, dict));
+
+        Terminal terminal = TerminalBuilder.builder()
+                .name("gogo")
+                .system(true)
+                .nativeSignals(true)
+                .signalHandler(Terminal.SignalHandler.SIG_IGN)
+                .build();
+        CommandSession session = processor.createSession(terminal.input(), terminal.output(), terminal.output());
+        AtomicBoolean closing = new AtomicBoolean();
+
+        Thread thread = new Thread(() -> {
+            String errorMessage = "gogo: unable to create console";
+            try {
+                session.put(Shell.VAR_TERMINAL, terminal);
+                try {
+                    List<String> args = new ArrayList<>();
+                    args.add("--login");
+                    String argstr = shell.getContext().getProperty("gosh.args");
+                    if (argstr != null) {
+                        Tokenizer tokenizer = new Tokenizer(argstr);
+                        Token token;
+                        while ((token = tokenizer.next()) != null) {
+                            args.add(token.toString());
+                        }
+                    }
+                    shell.gosh(session, args.toArray(new String[args.size()]));
+                } catch (Throwable e) {
+                    Object loc = session.get(".location");
+                    if (null == loc || !loc.toString().contains(":")) {
+                        loc = "gogo";
+                    }
+                    errorMessage = loc.toString();
+                    throw e;
+                }
+            } catch (Throwable e) {
+                if (!closing.get()) {
+                    System.err.println(errorMessage + e.getClass().getSimpleName() + ": " + e.getMessage());
+                    e.printStackTrace();
+                }
+            }
+        }, "Gogo shell");
+        // start shell on a separate thread...
+        thread.start();
+
+        return () -> {
+            closing.set(true);
+            shell.stop();
+            try {
+                terminal.close();
+            } catch (IOException e) {
+                // Ignore
+            }
+            try {
+                long t0 = System.currentTimeMillis();
+                while (thread.isAlive()) {
+                    thread.interrupt();
+                    thread.join(10);
+                    if (System.currentTimeMillis() - t0 > 5000) {
+                        System.err.println("!!! FAILED TO STOP EXECUTOR !!!");
+                        break;
+                    }
+                }
+            } catch (InterruptedException e) {
+                // Restore administration...
+                Thread.currentThread().interrupt();
+            }
+        };
+    }
+
+    private void stopShell() {
+        if (closer != null) {
+            closer.run();
+        }
+        while (!regs.isEmpty()) {
+            ServiceRegistration<?> reg = regs.iterator().next();
+            regs.remove(reg);
+            reg.unregister();
+        }
+    }
+
+    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/jline/src/main/java/org/apache/felix/gogo/jline/BaseConverters.java b/jline/src/main/java/org/apache/felix/gogo/jline/BaseConverters.java
new file mode 100644
index 0000000..4eb1149
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/BaseConverters.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;
+
+import org.apache.felix.service.command.Converter;
+import org.apache.felix.service.command.Function;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.invoke.MethodHandles;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Proxy;
+import java.util.Arrays;
+import java.util.Collections;
+
+public class BaseConverters implements Converter {
+
+    public Object convert(Class<?> desiredType, final Object in) throws Exception {
+        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 && isFunctional(desiredType)) {
+            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 {
+                            if (isObjectMethod(method)) {
+                                return method.invoke(command, args);
+                            } else if (method.isDefault()) {
+                                final Field field = MethodHandles.Lookup.class.getDeclaredField("IMPL_LOOKUP");
+                                field.setAccessible(true);
+                                final MethodHandles.Lookup lookup = (MethodHandles.Lookup) field.get(null);
+                                return lookup
+                                        .unreflectSpecial(method, method.getDeclaringClass())
+                                        .bindTo(proxy)
+                                        .invokeWithArguments(args);
+                            } else {
+                                return command.execute(null,
+                                        args != null ? Arrays.asList(args) : Collections.emptyList());
+                            }
+                        }
+                    });
+        }
+
+        return null;
+    }
+
+    public CharSequence format(Object target, int level, Converter converter)
+            throws IOException {
+        if (level == INSPECT && target instanceof InputStream) {
+            return read(((InputStream) target));
+        }
+        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;
+    }
+
+    public static boolean isFunctional(Class<?> clazz) {
+        if (!clazz.isInterface()) {
+            return false;
+        }
+        int nb = 0;
+        for (Method method : clazz.getMethods()) {
+            if (method.isDefault() || isObjectMethod(method) || isStatic(method)) {
+                continue;
+            }
+            nb++;
+        }
+        return nb == 1;
+    }
+
+    public static boolean isStatic(Method method) {
+        return (method.getModifiers() & Modifier.STATIC) == Modifier.STATIC;
+    }
+
+    public static boolean isObjectMethod(Method method) {
+        switch (method.getName()) {
+            case "toString":
+                if (method.getParameterCount() == 0 && method.getReturnType() == String.class) {
+                    return true;
+                }
+                break;
+            case "equals":
+                if (method.getParameterCount() == 1
+                        && method.getParameterTypes()[0] == Object.class
+                        && method.getReturnType() == boolean.class) {
+                    return true;
+                }
+                break;
+            case "hashCode":
+                if (method.getParameterCount() == 0 && method.getReturnType() == int.class) {
+                    return true;
+                }
+                break;
+        }
+        return false;
+    }
+
+}
diff --git a/jline/src/main/java/org/apache/felix/gogo/jline/Builtin.java b/jline/src/main/java/org/apache/felix/gogo/jline/Builtin.java
new file mode 100644
index 0000000..0e4190d
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/Builtin.java
@@ -0,0 +1,771 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+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.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.OpenOption;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+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 java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.felix.service.command.Job;
+import org.apache.felix.service.command.Process;
+import org.apache.felix.gogo.runtime.CommandSessionImpl;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.command.Converter;
+import org.apache.felix.service.command.Function;
+import org.jline.builtins.Commands;
+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.Terminal;
+
+import static org.apache.felix.gogo.jline.Shell.getCommands;
+
+/**
+ * gosh built-in commands.
+ */
+public class Builtin {
+
+    static final String[] functions = {
+            "format", "getopt", "new", "set", "tac", "type",
+            "jobs", "fg", "bg",
+            "keymap", "setopt", "unsetopt", "complete", "history", "widget",
+            "__files", "__directories", "__usage_completion"
+    };
+
+    private static final String[] packages = {"java.lang", "java.io", "java.net", "java.util"};
+
+    private final static Set<String> KEYWORDS = new HashSet<>(
+            Arrays.asList("abstract", "continue", "for", "new", "switch",
+                    "assert", "default", "goto", "package", "synchronized", "boolean", "do",
+                    "if", "private", "this", "break", "double", "implements", "protected",
+                    "throw", "byte", "else", "import", "public", "throws", "case", "enum",
+                    "instanceof", "return", "transient", "catch", "extends", "int", "short",
+                    "try", "char", "final", "interface", "static", "void", "class",
+                    "finally", "long", "strictfp", "volatile", "const", "float", "native",
+                    "super", "while"));
+
+    public CharSequence format(CommandSession session) {
+        return format(session, session.get("_"));    // last result
+    }
+
+    public CharSequence format(CommandSession session, Object arg) {
+        Process process = Process.Utils.current();
+        CharSequence result = session.format(arg, Converter.INSPECT);
+        process.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(session, 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(CommandSession session, String name) throws ClassNotFoundException {
+        if (!name.contains(".")) {
+            for (String p : packages) {
+                String pkg = p + "." + name;
+                try {
+                    return Class.forName(pkg, true, session.classLoader());
+                } catch (ClassNotFoundException e) {
+                }
+            }
+        }
+        return Class.forName(name, true, session.classLoader());
+    }
+
+    public void set(CommandSession session, String[] argv) {
+        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"};
+
+        Process process = Process.Utils.current();
+        Options opt = Options.compile(usage).parse(argv);
+
+        if (opt.isSet("help")) {
+            opt.usage(process.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<>(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<?> clazz = target.getClass();
+                    type = clazz.getSimpleName();
+                    value = target.toString();
+                }
+
+                String trunc = value == null || value.length() < 55 ? "" : "...";
+                process.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"};
+
+        Process process = Process.Utils.current();
+        Options opt = Options.compile(usage).parse(argv);
+
+        if (opt.isSet("help")) {
+            opt.usage(process.err());
+            return null;
+        }
+
+        List<String> args = opt.args();
+        BufferedWriter fw = null;
+
+        if (args.size() == 1) {
+            Path path = session.currentDir().resolve(args.get(0));
+            Set<OpenOption> options = new HashSet<>();
+            options.add(StandardOpenOption.WRITE);
+            options.add(StandardOpenOption.CREATE);
+            if (opt.isSet("append")) {
+                options.add(StandardOpenOption.APPEND);
+            } else {
+                options.add(StandardOpenOption.TRUNCATE_EXISTING);
+            }
+            fw = Files.newBufferedWriter(path, StandardCharsets.UTF_8, options.toArray(new OpenOption[options.size()]));
+        }
+
+        StringWriter sw = new StringWriter();
+        BufferedReader rdr = new BufferedReader(new InputStreamReader(process.in()));
+
+        ArrayList<String> list = null;
+
+        if (opt.isSet("list")) {
+            list = new ArrayList<>();
+        }
+
+        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"};
+
+        Process process = Process.Utils.current();
+        Options opt = Options.compile(usage).parse(argv);
+        List<String> args = opt.args();
+
+        if (opt.isSet("help")) {
+            opt.usage(process.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<>();
+
+            for (String sname : (getCommands(session))) {
+                if ((optScope == null) || sname.startsWith(optScope)) {
+                    snames.add(sname);
+                }
+            }
+
+            for (String sname : snames) {
+                process.out().println(sname);
+            }
+
+            return true;
+        }
+
+        if (args.size() == 0) {
+            Map<String, Integer> scopes = new TreeMap<>();
+
+            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()) {
+                process.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<>();
+
+        // 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")) {
+                process.out().println(buf);
+            }
+            return true;
+        }
+
+        if (!opt.isSet("quiet")) {
+            process.err().println("type: " + name + " not found.");
+        }
+
+        return false;
+    }
+
+    public void jobs(CommandSession session, String[] argv) {
+        final String[] usage = {
+                "jobs - list jobs",
+                "Usage: jobs [OPTIONS]",
+                "  -? --help                show help",
+        };
+        Process process = Process.Utils.current();
+        Options opt = Options.compile(usage).parse(argv);
+        if (opt.isSet("help")) {
+            opt.usage(process.err());
+            return;
+        }
+        if (!opt.args().isEmpty()) {
+            process.err().println("usage: jobs");
+            process.error(2);
+            return;
+        }
+        List<Job> jobs = session.jobs();
+        Job current = Job.Utils.current();
+        for (Job job : jobs) {
+            if (job != current) {
+                process.out().println("[" + job.id() + "] " + job.status().toString().toLowerCase()
+                        + " " + job.command());
+            }
+        }
+    }
+
+    public void fg(CommandSession session, String[] argv) {
+        final String[] usage = {
+                "fg - put job in foreground",
+                "Usage: fg [OPTIONS] [jobid]",
+                "  -? --help                show help",
+        };
+        Process process = Process.Utils.current();
+        Options opt = Options.compile(usage).parse(argv);
+        if (opt.isSet("help")) {
+            opt.usage(process.err());
+            return;
+        }
+        if (opt.args().size() > 1) {
+            process.err().println("usage: fg [jobid]");
+            process.error(2);
+            return;
+        }
+        List<Job> jobs = new ArrayList<>(session.jobs());
+        Collections.reverse(jobs);
+        Job current = Job.Utils.current();
+        if (argv.length == 0) {
+            Job job = jobs.stream().filter(j -> j != current)
+                    .findFirst().orElse(null);
+            if (job != null) {
+                job.foreground();
+            } else {
+                process.err().println("fg: no current job");
+                process.error(1);
+            }
+        } else {
+            Job job = jobs.stream().filter(j -> j != current && argv[0].equals(Integer.toString(j.id())))
+                    .findFirst().orElse(null);
+            if (job != null) {
+                job.foreground();
+            } else {
+                process.err().println("fg: job not found: " + argv[0]);
+                process.error(1);
+            }
+        }
+    }
+
+    public void bg(CommandSession session, String[] argv) {
+        final String[] usage = {
+                "bg - put job in background",
+                "Usage: bg [OPTIONS] [jobid]",
+                "  -? --help                show help",
+        };
+        Process process = Process.Utils.current();
+        Options opt = Options.compile(usage).parse(argv);
+        if (opt.isSet("help")) {
+            opt.usage(process.err());
+            return;
+        }
+        if (opt.args().size() > 1) {
+            process.err().println("usage: bg [jobid]");
+            process.error(2);
+            return;
+        }
+        List<Job> jobs = new ArrayList<>(session.jobs());
+        Collections.reverse(jobs);
+        Job current = Job.Utils.current();
+        if (argv.length == 0) {
+            Job job = jobs.stream().filter(j -> j != current)
+                    .findFirst().orElse(null);
+            if (job != null) {
+                job.background();
+            } else {
+                process.err().println("bg: no current job");
+                process.error(1);
+            }
+        } else {
+            Job job = jobs.stream().filter(j -> j != current && argv[0].equals(Integer.toString(j.id())))
+                    .findFirst().orElse(null);
+            if (job != null) {
+                job.background();
+            } else {
+                process.err().println("bg: job not found: " + argv[0]);
+                process.error(1);
+            }
+        }
+    }
+
+    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<>();
+        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;
+    }
+
+    public void history(CommandSession session, String[] argv) throws IOException {
+        Process process = Process.Utils.current();
+        Commands.history(Shell.getReader(session), process.out(), process.err(), argv);
+    }
+
+    public void complete(CommandSession session, String[] argv) {
+        Process process = Process.Utils.current();
+        Commands.complete(Shell.getReader(session), process.out(), process.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;
+        };
+        Process process = Process.Utils.current();
+        Commands.widget(Shell.getReader(session), process.out(), process.err(), creator, argv);
+    }
+
+    public void keymap(CommandSession session, String[] argv) {
+        Process process = Process.Utils.current();
+        Commands.keymap(Shell.getReader(session), process.out(), process.err(), argv);
+    }
+
+    public void setopt(CommandSession session, String[] argv) {
+        Process process = Process.Utils.current();
+        Commands.setopt(Shell.getReader(session), process.out(), process.err(), argv);
+    }
+
+    public void unsetopt(CommandSession session, String[] argv) {
+        Process process = Process.Utils.current();
+        Commands.unsetopt(Shell.getReader(session), process.out(), process.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(session.currentDir()) {
+            @Override
+            protected String getDisplay(Terminal terminal, Path p) {
+                return getFileDisplay(session, p);
+            }
+        }.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(session.currentDir()) {
+            @Override
+            protected String getDisplay(Terminal terminal, Path p) {
+                return getFileDisplay(session, p);
+            }
+        }.complete(reader, line, candidates);
+        return candidates;
+    }
+
+    private String getFileDisplay(CommandSession session, Path path) {
+        String type;
+        String suffix;
+        if (Files.isSymbolicLink(path)) {
+            type = "sl";
+            suffix = "@";
+        } else if (Files.isDirectory(path)) {
+            type = "dr";
+            suffix = "/";
+        } else if (Files.isExecutable(path)) {
+            type = "ex";
+            suffix = "*";
+        } else if (!Files.isRegularFile(path)) {
+            type = "ot";
+            suffix = "";
+        } else {
+            type = "";
+            suffix = "";
+        }
+        return Posix.applyStyle(path.getFileName().toString(), Posix.getLsColorMap(session), type) + suffix;
+
+    }
+
+    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/jline/src/main/java/org/apache/felix/gogo/jline/Converters.java b/jline/src/main/java/org/apache/felix/gogo/jline/Converters.java
new file mode 100644
index 0000000..0ed4d89
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/Converters.java
@@ -0,0 +1,180 @@
+/*
+ * 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.util.Formatter;
+
+import org.apache.felix.service.command.Converter;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.startlevel.BundleStartLevel;
+
+public class Converters extends BaseConverters {
+    private final BundleContext context;
+
+    public Converters(BundleContext context) {
+        this.context = context;
+    }
+
+    private CharSequence print(Bundle bundle) {
+        // [ ID ] [STATE      ] [ SL ] symname
+        int level = bundle.adapt(BundleStartLevel.class).getStartLevel();
+
+        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();
+        try (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).append(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);
+        }
+
+        return super.convert(desiredType, in);
+    }
+
+    private Object convertServiceReference(Object in) throws InvalidSyntaxException {
+        String s = in.toString();
+        if (s.startsWith("(") && s.endsWith(")")) {
+            ServiceReference<?> refs[] = context.getServiceReferences((String) null, String.format(
+                    "(|(service.id=%s)(service.pid=%s))", in, in));
+            if (refs != null && refs.length > 0) {
+                return refs[0];
+            }
+        }
+
+        ServiceReference<?> refs[] = context.getServiceReferences((String) 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 == 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 super.format(target, level, converter);
+    }
+
+}
diff --git a/jline/src/main/java/org/apache/felix/gogo/jline/Expander.java b/jline/src/main/java/org/apache/felix/gogo/jline/Expander.java
new file mode 100644
index 0000000..e9a8d2d
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/Expander.java
@@ -0,0 +1,58 @@
+/*
+ * 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.Collection;
+import java.util.stream.Collectors;
+
+import org.apache.felix.gogo.runtime.Closure;
+import org.apache.felix.gogo.runtime.CommandSessionImpl;
+import org.apache.felix.service.command.CommandSession;
+import org.jline.reader.impl.DefaultExpander;
+
+public class Expander extends DefaultExpander {
+
+    private final CommandSession session;
+
+    public Expander(CommandSession session) {
+        this.session = session;
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public String expandVar(String word) {
+        try {
+            Object o = org.apache.felix.gogo.runtime.Expander.expand(
+                    word,
+                    new Closure((CommandSessionImpl) session, null, null));
+            if (o instanceof Collection) {
+                return ((Collection<Object>) o).stream()
+                        .map(String::valueOf)
+                        .collect(Collectors.joining(" "));
+            }
+            else if (o != null) {
+                return o.toString();
+            }
+        } catch (Exception e) {
+            // ignore
+        }
+        return word;
+    }
+
+}
diff --git a/jline/src/main/java/org/apache/felix/gogo/jline/Highlighter.java b/jline/src/main/java/org/apache/felix/gogo/jline/Highlighter.java
new file mode 100644
index 0000000..d0156ed
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/Highlighter.java
@@ -0,0 +1,226 @@
+/*
+ * 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.Map;
+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 {
+
+    public static final String DEFAULT_HIGHLIGHTER_COLORS = "rs=35:st=32:nu=32:co=32:va=36:vn=36:fu=94:bf=91:re=90";
+
+    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();
+                    // Make sure we don't loop forever
+                    if (repaired.length() > buffer.length() + 1024) {
+                        return new AttributedStringBuilder().append(buffer).toAttributedString();
+                    }
+                }
+            }
+
+            Map<String, String> colors = Posix.getColorMap(session, "HIGHLIGHTER", DEFAULT_HIGHLIGHTER_COLORS);
+
+            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) {
+                    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);
+                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();
+            for (int i = 0; i < repaired.length(); i++) {
+                sb.style(AttributedStyle.DEFAULT);
+                applyStyle(sb, colors, types[i]);
+                if (i >= underlineStart && i <= underlineEnd) {
+                    sb.style(sb.style().underline());
+                }
+                if (i >= negativeStart && i <= negativeEnd) {
+                    sb.style(sb.style().inverse());
+                }
+                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);
+                    }
+                }
+            }
+
+            return sb.toAttributedString();
+        } catch (SyntaxError e) {
+            return super.highlight(reader, buffer);
+        }
+    }
+
+    private void applyStyle(AttributedStringBuilder sb, Map<String, String> colors, Type type) {
+        Posix.applyStyle(sb, colors, type.color);
+    }
+
+    enum Type {
+        Reserved("rs"),
+        String("st"),
+        Number("nu"),
+        Variable("va"),
+        VariableName("vn"),
+        Function("fu"),
+        BadFunction("bf"),
+        Constant("co"),
+        Unknown("un"),
+        Repair("re");
+
+        private final String color;
+
+        Type(String color) {
+            this.color = color;
+        }
+    }
+
+}
diff --git a/jline/src/main/java/org/apache/felix/gogo/jline/Main.java b/jline/src/main/java/org/apache/felix/gogo/jline/Main.java
new file mode 100644
index 0000000..4fcaecc
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/Main.java
@@ -0,0 +1,108 @@
+/*
+ * 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.FilterInputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import org.apache.felix.gogo.jline.Shell.Context;
+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 {
+        try (Terminal terminal = TerminalBuilder.builder()
+                .name("gogo")
+                .system(true)
+                .nativeSignals(true)
+                .signalHandler(Terminal.SignalHandler.SIG_IGN)
+                .build()) {
+            ThreadIOImpl tio = new ThreadIOImpl();
+            tio.start();
+            try {
+                CommandProcessorImpl processor = new CommandProcessorImpl(tio);
+                Context context = new MyContext();
+                Shell shell = new Shell(context, processor, tio, null);
+                processor.addCommand("gogo", processor, "addCommand");
+                processor.addCommand("gogo", processor, "removeCommand");
+                processor.addCommand("gogo", processor, "eval");
+                processor.addConverter(new BaseConverters());
+                register(processor, new Builtin(), Builtin.functions);
+                register(processor, new Procedural(), Procedural.functions);
+                register(processor, new Posix(processor), Posix.functions);
+                register(processor, shell, Shell.functions);
+                InputStream in = new FilterInputStream(terminal.input()) {
+                    @Override
+                    public void close() {
+                    }
+                };
+                OutputStream out = new FilterOutputStream(terminal.output()) {
+                    @Override
+                    public void close() {
+                    }
+                };
+                CommandSession session = processor.createSession(in, out, out);
+                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() {
+            System.exit(0);
+        }
+    }
+}
diff --git a/jline/src/main/java/org/apache/felix/gogo/jline/ParsedLineImpl.java b/jline/src/main/java/org/apache/felix/gogo/jline/ParsedLineImpl.java
new file mode 100644
index 0000000..25b5270
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/ParsedLineImpl.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;
+
+import org.apache.felix.gogo.runtime.Parser.Program;
+import org.apache.felix.gogo.runtime.Token;
+import org.jline.reader.CompletingParsedLine;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Predicate;
+
+public class ParsedLineImpl implements CompletingParsedLine {
+
+    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;
+    private final CharSequence rawWord;
+    private final int rawWordCursor;
+
+    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<>();
+        for (Token token : tokens) {
+            this.tokens.add(unquote(token, null).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("");
+            rawWord = "";
+            wordCursor = 0;
+        } else {
+            rawWord = tokens.get(wi);
+            int[] c = new int[] { wc };
+            unquote(rawWord, c);
+            wordCursor = c[0];
+        }
+        wordIndex = wi;
+        rawWordCursor = 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;
+    }
+
+    public int rawWordCursor() {
+        return rawWordCursor;
+    }
+
+    public int rawWordLength() {
+        return rawWord.length();
+    }
+
+    public CharSequence escape(CharSequence str, boolean complete) {
+        StringBuilder sb = new StringBuilder(str);
+        Predicate<Character> needToBeEscaped;
+        char quote = 0;
+        char first = rawWord.length() > 0 ? rawWord.charAt(0) : 0;
+        if (first == '\'') {
+            quote = '\'';
+            needToBeEscaped = i -> i == '\'';
+        } else if (first == '"') {
+            quote = '"';
+            needToBeEscaped = i -> i == '"';
+        } else {
+            needToBeEscaped = i -> i == ' ' || i == '\t';
+        }
+        for (int i = 0; i < sb.length(); i++) {
+            if (needToBeEscaped.test(str.charAt(i))) {
+                sb.insert(i++, '\\');
+            }
+        }
+        if (quote != 0) {
+            sb.insert(0, quote);
+            if (complete) {
+                sb.append(quote);
+            }
+        }
+        return sb;
+    }
+
+    private CharSequence unquote(CharSequence arg, int[] cursor) {
+        boolean hasEscape = false;
+        for (int i = 0; i < arg.length(); i++) {
+            int c = arg.charAt(i);
+            if (c == '\\' || c == '"' || c == '\'') {
+                hasEscape = true;
+                break;
+            }
+        }
+        if (!hasEscape) {
+            return arg;
+        }
+        boolean singleQuoted = false;
+        boolean doubleQuoted = false;
+        boolean escaped = false;
+        StringBuilder buf = new StringBuilder(arg.length());
+        for (int i = 0; i < arg.length(); i++) {
+            if (cursor != null && cursor[0] == i) {
+                cursor[0] = buf.length();
+                cursor = null;
+            }
+            char c = arg.charAt(i);
+            if (doubleQuoted && escaped) {
+                if (c != '"' && c != '\\' && c != '$' && c != '%') {
+                    buf.append('\\');
+                }
+                buf.append(c);
+                escaped = false;
+            } else if (escaped) {
+                buf.append(c);
+                escaped = false;
+            } else if (singleQuoted) {
+                if (c == '\'') {
+                    singleQuoted = false;
+                } else {
+                    buf.append(c);
+                }
+            } else if (doubleQuoted) {
+                if (c == '\\') {
+                    escaped = true;
+                } else if (c == '\"') {
+                    doubleQuoted = false;
+                } else {
+                    buf.append(c);
+                }
+            } else if (c == '\\') {
+                escaped = true;
+            } else if (c == '\'') {
+                singleQuoted = true;
+            } else if (c == '"') {
+                doubleQuoted = true;
+            } else {
+                buf.append(c);
+            }
+        }
+        return buf.toString();
+    }
+
+}
diff --git a/jline/src/main/java/org/apache/felix/gogo/jline/Parser.java b/jline/src/main/java/org/apache/felix/gogo/jline/Parser.java
new file mode 100644
index 0000000..d307b5a
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/Parser.java
@@ -0,0 +1,93 @@
+/*
+ * 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.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, ParseContext context) throws org.jline.reader.SyntaxError {
+        try {
+            return doParse(line, cursor, context);
+        } 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(String line, int cursor, ParseContext parseContext) throws SyntaxError {
+        Program program = null;
+        List<Statement> statements = null;
+        String repaired = line;
+        while (program == null) {
+            try {
+                org.apache.felix.gogo.runtime.Parser parser = new org.apache.felix.gogo.runtime.Parser(repaired);
+                program = parser.program();
+                statements = parser.statements();
+            } catch (EOFError e) {
+                // Make sure we don't loop forever
+                if (parseContext == ParseContext.COMPLETE && repaired.length() < line.length() + 1024) {
+                    repaired = repaired + " " + e.repair();
+                } else {
+                    throw e;
+                }
+            }
+        }
+        // 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 && statement.tokens() != null && !statement.tokens().isEmpty()) {
+            if (repaired != line) {
+                Token stmt = statement.subSequence(0, line.length() - statement.start());
+                List<Token> tokens = new ArrayList<>(statement.tokens());
+                Token last = tokens.get(tokens.size() - 1);
+                tokens.set(tokens.size() - 1, last.subSequence(0, line.length() - last.start()));
+                return new ParsedLineImpl(program, stmt, cursor, tokens);
+            }
+            return new ParsedLineImpl(program, statement, cursor, statement.tokens());
+        } else {
+            // TODO:
+            return new ParsedLineImpl(program, program, cursor, Collections.singletonList(program));
+        }
+    }
+
+}
diff --git a/jline/src/main/java/org/apache/felix/gogo/jline/Posix.java b/jline/src/main/java/org/apache/felix/gogo/jline/Posix.java
new file mode 100644
index 0000000..43723fc
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/Posix.java
@@ -0,0 +1,2110 @@
+/*
+ * 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.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FilterInputStream;
+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.nio.file.Files;
+import java.nio.file.LinkOption;
+import java.nio.file.Path;
+import java.nio.file.StandardWatchEventKinds;
+import java.nio.file.WatchKey;
+import java.nio.file.WatchService;
+import java.nio.file.attribute.FileTime;
+import java.nio.file.attribute.PosixFilePermission;
+import java.nio.file.attribute.PosixFilePermissions;
+import java.text.SimpleDateFormat;
+import java.time.Instant;
+import java.time.ZoneId;
+import java.time.ZonedDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.EnumSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+import java.util.function.IntBinaryOperator;
+import java.util.function.IntConsumer;
+import java.util.function.Predicate;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.apache.felix.service.command.Process;
+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.Commands;
+import org.jline.builtins.Less;
+import org.jline.builtins.Nano;
+import org.jline.builtins.Options;
+import org.jline.builtins.Source;
+import org.jline.builtins.Source.PathSource;
+import org.jline.builtins.TTop;
+import org.jline.terminal.Attributes;
+import org.jline.terminal.Terminal;
+import org.jline.utils.AttributedString;
+import org.jline.utils.AttributedStringBuilder;
+import org.jline.utils.InfoCmp.Capability;
+import org.jline.utils.OSUtils;
+import org.jline.utils.StyleResolver;
+
+/**
+ * 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;
+
+    static {
+        // TTop function is new in JLine 3.2
+        String[] func;
+        try {
+            @SuppressWarnings("unused")
+            Class<?> cl = TTop.class;
+            func = new String[] {
+                    "cat", "echo", "grep", "sort", "sleep", "cd", "pwd", "ls",
+                    "less", "watch", "nano", "tmux",
+                    "head", "tail", "clear", "wc",
+                    "date", "ttop",
+            };
+        } catch (Throwable t) {
+            func = new String[] {
+                    "cat", "echo", "grep", "sort", "sleep", "cd", "pwd", "ls",
+                    "less", "watch", "nano", "tmux",
+                    "head", "tail", "clear", "wc",
+                    "date"
+            };
+        }
+        functions = func;
+    }
+
+    public static final String DEFAULT_LS_COLORS = "dr=1;91:ex=1;92:sl=1;96:ot=34;43";
+    public static final String DEFAULT_GREP_COLORS = "mt=1;31:fn=35:ln=32:se=36";
+
+    private static final LinkOption[] NO_FOLLOW_OPTIONS = new LinkOption[]{LinkOption.NOFOLLOW_LINKS};
+    private static final List<String> WINDOWS_EXECUTABLE_EXTENSIONS = Collections.unmodifiableList(Arrays.asList(".bat", ".exe", ".cmd"));
+    private static final LinkOption[] EMPTY_LINK_OPTIONS = new LinkOption[0];
+
+    private final CommandProcessor processor;
+
+    public Posix(CommandProcessor processor) {
+        this.processor = processor;
+    }
+
+    public void _main(CommandSession session, String[] argv) {
+        if (argv == null || argv.length < 1) {
+            throw new IllegalArgumentException();
+        }
+        Process process = Process.Utils.current();
+        try {
+            run(session, process, argv);
+        } catch (IllegalArgumentException e) {
+            process.err().println(e.getMessage());
+            process.error(2);
+        } catch (HelpException e) {
+            process.err().println(e.getMessage());
+            process.error(0);
+        } catch (Exception e) {
+            process.err().println(argv[0] + ": " + e.toString());
+            process.error(1);
+        }
+    }
+
+    @SuppressWarnings("serial")
+    protected static class HelpException extends Exception {
+        public HelpException(String message) {
+            super(message);
+        }
+    }
+
+    protected Options parseOptions(CommandSession session, String[] usage, Object[] argv) throws Exception {
+        Options opt = Options.compile(usage, s -> get(session, s)).parse(argv, true);
+        if (opt.isSet("help")) {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            opt.usage(new PrintStream(baos));
+            throw new HelpException(baos.toString());
+        }
+        return opt;
+    }
+
+    protected String get(CommandSession session, String name) {
+        Object o = session.get(name);
+        return o != null ? o.toString() : null;
+    }
+
+    protected Object run(CommandSession session, Process process, String[] argv) throws Exception {
+        switch (argv[0]) {
+            case "cat":
+                cat(session, process, argv);
+                break;
+            case "echo":
+                echo(session, process, argv);
+                break;
+            case "grep":
+                grep(session, process, argv);
+                break;
+            case "sort":
+                sort(session, process, argv);
+                break;
+            case "sleep":
+                sleep(session, process, argv);
+                break;
+            case "cd":
+                cd(session, process, argv);
+                break;
+            case "pwd":
+                pwd(session, process, argv);
+                break;
+            case "ls":
+                ls(session, process, argv);
+                break;
+            case "less":
+                less(session, process, argv);
+                break;
+            case "watch":
+                watch(session, process, argv);
+                break;
+            case "nano":
+                nano(session, process, argv);
+                break;
+            case "tmux":
+                tmux(session, process, argv);
+                break;
+            case "ttop":
+                ttop(session, process, argv);
+                break;
+            case "clear":
+                clear(session, process, argv);
+                break;
+            case "head":
+                head(session, process, argv);
+                break;
+            case "tail":
+                tail(session, process, argv);
+                break;
+            case "wc":
+                wc(session, process, argv);
+                break;
+            case "date":
+                date(session, process, argv);
+                break;
+        }
+        return null;
+    }
+
+    protected void date(CommandSession session, Process process, String[] argv) throws Exception {
+        String[] usage = {
+                "date -  display date",
+                "Usage: date [-r seconds] [-v[+|-]val[mwdHMS] ...] [-f input_fmt new_date] [+output_fmt]",
+                "  -? --help                    Show help",
+                "  -u                           Use UTC",
+                "  -r                           Print the date represented by 'seconds' since January 1, 1970",
+                "  -f                           Use 'input_fmt' to parse 'new_date'"
+        };
+        Date input = new Date();
+        String output = null;
+        for (int i = 1; i < argv.length; i++) {
+            if ("-?".equals(argv[i]) || "--help".equals(argv[i])) {
+                throw new HelpException(String.join("\n", usage));
+            }
+            else if ("-r".equals(argv[i])) {
+                if (i + 1 < argv.length) {
+                    input = new Date(Long.parseLong(argv[++i]) * 1000L);
+                } else {
+                    throw new IllegalArgumentException("usage: date [-u] [-r seconds] [-v[+|-]val[mwdHMS] ...] [-f input_fmt new_date] [+output_fmt]");
+                }
+            }
+            else if ("-f".equals(argv[i])) {
+                if (i + 2 < argv.length) {
+                    String fmt = argv[++i];
+                    String inp = argv[++i];
+                    String jfmt = toJavaDateFormat(fmt);
+                    input = new SimpleDateFormat(jfmt).parse(inp);
+                } else {
+                    throw new IllegalArgumentException("usage: date [-u] [-r seconds] [-v[+|-]val[mwdHMS] ...] [-f input_fmt new_date] [+output_fmt]");
+                }
+            }
+            else if (argv[i].startsWith("+")) {
+                if (output == null) {
+                    output = argv[i].substring(1);
+                } else {
+                    throw new IllegalArgumentException("usage: date [-u] [-r seconds] [-v[+|-]val[mwdHMS] ...] [-f input_fmt new_date] [+output_fmt]");
+                }
+            }
+            else {
+                throw new IllegalArgumentException("usage: date [-u] [-r seconds] [-v[+|-]val[mwdHMS] ...] [-f input_fmt new_date] [+output_fmt]");
+            }
+        }
+        if (output == null) {
+            output = "%c";
+        }
+        // Print output
+        process.out().println(new SimpleDateFormat(toJavaDateFormat(output)).format(input));
+    }
+
+    private String toJavaDateFormat(String format) {
+        // transform Unix format to Java SimpleDateFormat (if required)
+        StringBuilder sb = new StringBuilder();
+        boolean quote = false;
+        for (int i = 0; i < format.length(); i++) {
+            char c = format.charAt(i);
+            if (c == '%') {
+                if (i + 1 < format.length()) {
+                    if (quote) {
+                        sb.append('\'');
+                        quote = false;
+                    }
+                    c = format.charAt(++i);
+                    switch (c) {
+                        case '+':
+                        case 'A': sb.append("MMM EEE d HH:mm:ss yyyy"); break;
+                        case 'a': sb.append("EEE"); break;
+                        case 'B': sb.append("MMMMMMM"); break;
+                        case 'b': sb.append("MMM"); break;
+                        case 'C': sb.append("yy"); break;
+                        case 'c': sb.append("MMM EEE d HH:mm:ss yyyy"); break;
+                        case 'D': sb.append("MM/dd/yy"); break;
+                        case 'd': sb.append("dd"); break;
+                        case 'e': sb.append("dd"); break;
+                        case 'F': sb.append("yyyy-MM-dd"); break;
+                        case 'G': sb.append("YYYY"); break;
+                        case 'g': sb.append("YY"); break;
+                        case 'H': sb.append("HH"); break;
+                        case 'h': sb.append("MMM"); break;
+                        case 'I': sb.append("hh"); break;
+                        case 'j': sb.append("DDD"); break;
+                        case 'k': sb.append("HH"); break;
+                        case 'l': sb.append("hh"); break;
+                        case 'M': sb.append("mm"); break;
+                        case 'm': sb.append("MM"); break;
+                        case 'N': sb.append("S"); break;
+                        case 'n': sb.append("\n"); break;
+                        case 'P': sb.append("aa"); break;
+                        case 'p': sb.append("aa"); break;
+                        case 'r': sb.append("hh:mm:ss aa"); break;
+                        case 'R': sb.append("HH:mm"); break;
+                        case 'S': sb.append("ss"); break;
+                        case 's': sb.append("S"); break;
+                        case 'T': sb.append("HH:mm:ss"); break;
+                        case 't': sb.append("\t"); break;
+                        case 'U': sb.append("w"); break;
+                        case 'u': sb.append("u"); break;
+                        case 'V': sb.append("W"); break;
+                        case 'v': sb.append("dd-MMM-yyyy"); break;
+                        case 'W': sb.append("w"); break;
+                        case 'w': sb.append("u"); break;
+                        case 'X': sb.append("HH:mm:ss"); break;
+                        case 'x': sb.append("MM/dd/yy"); break;
+                        case 'Y': sb.append("yyyy"); break;
+                        case 'y': sb.append("yy"); break;
+                        case 'Z': sb.append("z"); break;
+                        case 'z': sb.append("X"); break;
+                        case '%': sb.append("%"); break;
+                    }
+                } else {
+                    if (!quote) {
+                        sb.append('\'');
+                    }
+                    sb.append(c);
+                    sb.append('\'');
+                }
+            } else {
+                if ((c >= 'A' && c <= 'Z' || c >= 'a' && c <= 'z') && !quote) {
+                    sb.append('\'');
+                    quote = true;
+                }
+                sb.append(c);
+            }
+        }
+        return sb.toString();
+    }
+
+    protected void wc(CommandSession session, Process process, String[] argv) throws Exception {
+        String[] usage = {
+                "wc -  word, line, character, and byte count",
+                "Usage: wc [OPTIONS] [FILES]",
+                "  -? --help                    Show help",
+                "  -l --lines                   Print line counts",
+                "  -c --bytes                   Print byte counts",
+                "  -m --chars                   Print character counts",
+                "  -w --words                   Print word counts",
+        };
+        Options opt = parseOptions(session, usage, argv);
+        List<Source> sources = new ArrayList<>();
+        if (opt.args().isEmpty()) {
+            opt.args().add("-");
+        }
+        for (String arg : opt.args()) {
+            if ("-".equals(arg)) {
+                sources.add(new StdInSource(process));
+            } else {
+                sources.add(new PathSource(session.currentDir().resolve(arg), arg));
+            }
+        }
+        boolean displayLines = opt.isSet("lines");
+        boolean displayWords = opt.isSet("words");
+        boolean displayChars = opt.isSet("chars");
+        boolean displayBytes = opt.isSet("bytes");
+        if (displayChars) {
+            displayBytes = false;
+        }
+        if (!displayLines && !displayWords && !displayChars && !displayBytes) {
+            displayLines = true;
+            displayWords = true;
+            displayBytes = true;
+        }
+        String format = "";
+        if (displayLines) {
+            format += "%1$8d";
+        }
+        if (displayWords) {
+            format += "%2$8d";
+        }
+        if (displayChars) {
+            format += "%3$8d";
+        }
+        if (displayBytes) {
+            format += "%4$8d";
+        }
+        format += "  %5s";
+        int totalLines = 0;
+        int totalBytes = 0;
+        int totalChars = 0;
+        int totalWords = 0;
+        for (Source src : sources) {
+            try (InputStream is = src.read()) {
+                AtomicInteger lines = new AtomicInteger();
+                AtomicInteger bytes = new AtomicInteger();
+                AtomicInteger chars = new AtomicInteger();
+                AtomicInteger words = new AtomicInteger();
+                AtomicBoolean inWord = new AtomicBoolean();
+                AtomicBoolean lastNl = new AtomicBoolean(true);
+                InputStream isc = new FilterInputStream(is) {
+                    @Override
+                    public int read() throws IOException {
+                        int b = super.read();
+                        if (b >= 0) {
+                            bytes.incrementAndGet();
+                        }
+                        return b;
+                    }
+
+                    @Override
+                    public int read(byte[] b, int off, int len) throws IOException {
+                        int nb = super.read(b, off, len);
+                        if (nb > 0) {
+                            bytes.addAndGet(nb);
+                        }
+                        return nb;
+                    }
+                };
+                IntConsumer consumer = cp -> {
+                    chars.incrementAndGet();
+                    boolean ws = Character.isWhitespace(cp);
+                    if (inWord.getAndSet(!ws) && ws) {
+                        words.incrementAndGet();
+                    }
+                    if (cp == '\n') {
+                        lines.incrementAndGet();
+                        lastNl.set(true);
+                    } else {
+                        lastNl.set(false);
+                    }
+                };
+                Reader reader = new InputStreamReader(isc);
+                while (true) {
+                    int h = reader.read();
+                    if (Character.isHighSurrogate((char) h)) {
+                        int l = reader.read();
+                        if (Character.isLowSurrogate((char) l)) {
+                            int cp = Character.toCodePoint((char) h, (char) l);
+                            consumer.accept(cp);
+                        } else {
+                            consumer.accept(h);
+                            if (l >= 0) {
+                                consumer.accept(l);
+                            } else {
+                                break;
+                            }
+                        }
+                    } else if (h >= 0) {
+                        consumer.accept(h);
+                    } else {
+                        break;
+                    }
+                }
+                if (inWord.get()) {
+                    words.incrementAndGet();
+                }
+                if (!lastNl.get()) {
+                    lines.incrementAndGet();
+                }
+                process.out().println(String.format(format, lines.get(), words.get(), chars.get(), bytes.get(), src.getName()));
+                totalBytes += bytes.get();
+                totalChars += chars.get();
+                totalWords += words.get();
+                totalLines += lines.get();
+            }
+        }
+        if (sources.size() > 1) {
+            process.out().println(String.format(format, totalLines, totalWords, totalChars, totalBytes, "total"));
+        }
+    }
+
+    protected void head(CommandSession session, Process process, String[] argv) throws Exception {
+        String[] usage = {
+                "head -  displays first lines of file",
+                "Usage: head [-n lines | -c bytes] [file ...]",
+                "  -? --help                    Show help",
+                "  -n --lines=LINES             Print line counts",
+                "  -c --bytes=BYTES             Print byte counts",
+        };
+        Options opt = parseOptions(session, usage, argv);
+        if (opt.isSet("lines") && opt.isSet("bytes")) {
+            throw new IllegalArgumentException("usage: head [-n # | -c #] [file ...]");
+        }
+        int nbLines = Integer.MAX_VALUE;
+        int nbBytes = Integer.MAX_VALUE;
+        if (opt.isSet("lines")) {
+            nbLines = opt.getNumber("lines");
+        } else if (opt.isSet("bytes")) {
+            nbBytes = opt.getNumber("bytes");
+        } else {
+            nbLines = 10;
+        }
+        List<Source> sources = new ArrayList<>();
+        if (opt.args().isEmpty()) {
+            opt.args().add("-");
+        }
+        for (String arg : opt.args()) {
+            if ("-".equals(arg)) {
+                sources.add(new StdInSource(process));
+            } else {
+                sources.add(new PathSource(session.currentDir().resolve(arg), arg));
+            }
+        }
+        for (Source src : sources) {
+            int bytes = nbBytes;
+            int lines = nbLines;
+            if (sources.size() > 1) {
+                if (src != sources.get(0)) {
+                    process.out().println();
+                }
+                process.out().println("==> " + src.getName() + " <==");
+            }
+            try (InputStream is = src.read()) {
+                byte[] buf = new byte[1024];
+                int nb;
+                do {
+                    nb = is.read(buf);
+                    if (nb > 0 && lines > 0 && bytes > 0) {
+                        nb = Math.min(nb, bytes);
+                        for (int i = 0; i < nb; i++) {
+                            if (buf[i] == '\n' && --lines <= 0) {
+                                nb = i + 1;
+                                break;
+                            }
+                        }
+                        bytes -= nb;
+                        process.out().write(buf, 0, nb);
+                    }
+                } while (nb > 0 && lines > 0 && bytes > 0);
+            }
+        }
+    }
+
+    protected void tail(CommandSession session, Process process, String[] argv) throws Exception {
+        String[] usage = {
+                "tail -  displays last lines of file",
+                "Usage: tail [-f] [-q] [-c # | -n #] [file ...]",
+                "  -? --help                    Show help",
+                "  -q --quiet                   Suppress headers when printing multiple sources",
+                "  -f --follow                  Do not stop at end of file",
+                "  -F --FOLLOW                  Follow and check for file renaming or rotation",
+                "  -n --lines=LINES             Number of lines to print",
+                "  -c --bytes=BYTES             Number of bytes to print",
+        };
+        Options opt = parseOptions(session, usage, argv);
+        if (opt.isSet("lines") && opt.isSet("bytes")) {
+            throw new IllegalArgumentException("usage: tail [-f] [-q] [-c # | -n #] [file ...]");
+        }
+        int lines;
+        int bytes;
+        if (opt.isSet("lines")) {
+            lines = opt.getNumber("lines");
+            bytes = Integer.MAX_VALUE;
+        } else if (opt.isSet("bytes")) {
+            lines = Integer.MAX_VALUE;
+            bytes = opt.getNumber("bytes");
+        } else {
+            lines = 10;
+            bytes = Integer.MAX_VALUE;
+        }
+        boolean follow = opt.isSet("follow") || opt.isSet("FOLLOW");
+
+        AtomicReference<Object> lastPrinted = new AtomicReference<>();
+        WatchService watchService = follow ? session.currentDir().getFileSystem().newWatchService() : null;
+        Set<Path> watched = new HashSet<>();
+
+        class Input implements Closeable {
+            String name;
+            Path path;
+            Reader reader;
+            StringBuilder buffer;
+            long ino;
+            long size;
+
+            public Input(String name) {
+                this.name = name;
+                this.buffer = new StringBuilder();
+            }
+
+            public void open() {
+                if (reader == null) {
+                    try {
+                        InputStream is;
+                        if ("-".equals(name)) {
+                            is = new StdInSource(process).read();
+                        } else {
+                            path = session.currentDir().resolve(name);
+                            is = Files.newInputStream(path);
+                            if (opt.isSet("FOLLOW")) {
+                                try {
+                                    ino = (Long) Files.getAttribute(path, "unix:ino");
+                                } catch (Exception e) {
+                                    // Ignore
+                                }
+                            }
+                            size = Files.size(path);
+                        }
+                        reader = new InputStreamReader(is);
+                    } catch (IOException e) {
+                        // Ignore
+                    }
+                }
+            }
+
+            @Override
+            public void close() throws IOException {
+                if (reader != null) {
+                    try {
+                        reader.close();
+                    } finally {
+                        reader = null;
+                    }
+                }
+            }
+
+            public boolean tail() throws IOException {
+                open();
+                if (reader != null) {
+                    if (buffer != null) {
+                        char[] buf = new char[1024];
+                        int nb;
+                        while ((nb = reader.read(buf)) > 0) {
+                            buffer.append(buf, 0, nb);
+                            if (bytes > 0 && buffer.length() > bytes) {
+                                buffer.delete(0, buffer.length() - bytes);
+                            } else {
+                                int l = 0;
+                                int i = -1;
+                                while ((i = buffer.indexOf("\n", i + 1)) >= 0) {
+                                    l++;
+                                }
+                                if (l > lines) {
+                                    i = -1;
+                                    l = l - lines;
+                                    while (--l >= 0) {
+                                        i = buffer.indexOf("\n", i + 1);
+                                    }
+                                    buffer.delete(0, i + 1);
+                                }
+                            }
+                        }
+                        String toPrint = buffer.toString();
+                        print(toPrint);
+                        buffer = null;
+                        if (follow && path != null) {
+                            Path parent = path.getParent();
+                            if (!watched.contains(parent)) {
+                                parent.register(watchService,
+                                        StandardWatchEventKinds.ENTRY_CREATE,
+                                        StandardWatchEventKinds.ENTRY_DELETE,
+                                        StandardWatchEventKinds.ENTRY_MODIFY);
+                                watched.add(parent);
+                            }
+                        }
+                        return follow;
+                    }
+                    else if (follow && path != null) {
+                        while (true) {
+                            long newSize = Files.size(path);
+                            if (size != newSize) {
+                                char[] buf = new char[1024];
+                                int nb;
+                                while ((nb = reader.read(buf)) > 0) {
+                                    print(new String(buf, 0, nb));
+                                }
+                                size = newSize;
+                            }
+                            if (opt.isSet("FOLLOW")) {
+                                long newIno = 0;
+                                try {
+                                    newIno = (Long) Files.getAttribute(path, "unix:ino");
+                                } catch (Exception e) {
+                                    // Ignore
+                                }
+                                if (ino != newIno) {
+                                    close();
+                                    open();
+                                    ino = newIno;
+                                    size = -1;
+                                    continue;
+                                }
+                            }
+                            break;
+                        }
+                        return true;
+                    } else {
+                        return false;
+                    }
+                } else {
+                    Path parent = path.getParent();
+                    if (!watched.contains(parent)) {
+                        parent.register(watchService,
+                                StandardWatchEventKinds.ENTRY_CREATE,
+                                StandardWatchEventKinds.ENTRY_DELETE,
+                                StandardWatchEventKinds.ENTRY_MODIFY);
+                        watched.add(parent);
+                    }
+                    return true;
+                }
+            }
+
+            private void print(String toPrint) {
+                if (lastPrinted.get() != this && opt.args().size() > 1 && !opt.isSet("quiet")) {
+                    process.out().println();
+                    process.out().println("==> " + name + " <==");
+                }
+                process.out().print(toPrint);
+                lastPrinted.set(this);
+            }
+        }
+
+        if (opt.args().isEmpty()) {
+            opt.args().add("-");
+        }
+        List<Input> inputs = new ArrayList<>();
+        for (String name : opt.args()) {
+            Input input = new Input(name);
+            inputs.add(input);
+        }
+        try {
+            boolean cont = true;
+            while (cont) {
+                cont = false;
+                for (Input input : inputs) {
+                    cont |= input.tail();
+                }
+                if (cont) {
+                    WatchKey key = watchService.take();
+                    key.pollEvents();
+                    key.reset();
+                }
+            }
+        } catch (InterruptedException e) {
+            // Ignore, this is the only way to quit
+        } finally {
+            for (Input input : inputs) {
+                input.close();
+            }
+        }
+    }
+
+    protected void clear(CommandSession session, Process process, String[] argv) throws Exception {
+        final String[] usage = {
+                "clear -  clear screen",
+                "Usage: clear [OPTIONS]",
+                "  -? --help                    Show help",
+        };
+        @SuppressWarnings("unused")
+        Options opt = parseOptions(session, usage, argv);
+        if (process.isTty(1)) {
+            Shell.getTerminal(session).puts(Capability.clear_screen);
+            Shell.getTerminal(session).flush();
+        }
+    }
+
+    protected void tmux(final CommandSession session, Process process, String[] argv) throws Exception {
+        Commands.tmux(Shell.getTerminal(session),
+                process.out(), System.err,
+                () -> session.get(".tmux"),
+                t -> session.put(".tmux", t),
+                c -> startShell(session, c),
+                Arrays.copyOfRange(argv, 1, argv.length));
+    }
+
+    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();
+        OutputStream out = 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).gosh(newSession, new String[]{"--login"});
+        } catch (Exception e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                terminal.close();
+            } catch (IOException e) {
+                e.printStackTrace();
+            }
+        }
+    }
+
+    protected void ttop(final CommandSession session, Process process, String[] argv) throws Exception {
+        TTop.ttop(Shell.getTerminal(session), process.out(), process.err(), argv);
+    }
+
+    protected void nano(final CommandSession session, Process process, String[] argv) throws Exception {
+        final String[] usage = {
+                "nano -  edit files",
+                "Usage: nano [FILES]",
+                "  -? --help                    Show help",
+        };
+        Options opt = parseOptions(session, usage, argv);
+        Nano edit = new Nano(Shell.getTerminal(session), session.currentDir());
+        edit.open(opt.args());
+        edit.run();
+    }
+
+    protected void watch(final CommandSession session, Process process, String[] argv) throws Exception {
+        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"
+        };
+
+        Options opt = parseOptions(session, usage, argv);
+
+        List<String> args = opt.args();
+        if (args.isEmpty()) {
+            throw new IllegalArgumentException("usage: watch COMMAND");
+        }
+        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();
+                PrintStream os = new PrintStream(baos);
+                InputStream is = new ByteArrayInputStream(new byte[0]);
+                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();
+        }
+    }
+
+    protected void less(CommandSession session, Process process, String[] argv) throws Exception {
+        String[] usage = {
+                "less -  file pager",
+                "Usage: less [OPTIONS] [FILES]",
+                "  -? --help                    Show help",
+                "  -e --quit-at-eof             Exit on second EOF",
+                "  -E --QUIT-AT-EOF             Exit on EOF",
+                "  -F --quit-if-one-screen      Exit if entire file fits on first screen",
+                "  -q --quiet --silent          Silent mode",
+                "  -Q --QUIET --SILENT          Completely  silent",
+                "  -S --chop-long-lines         Do not fold long lines",
+                "  -i --ignore-case             Search ignores lowercase case",
+                "  -I --IGNORE-CASE             Search ignores all case",
+                "  -x --tabs                    Set tab stops",
+                "  -N --LINE-NUMBERS            Display line number for each line",
+                "     --no-init                 Disable terminal initialization",
+                "     --no-keypad               Disable keypad handling"
+        };
+        boolean hasExtendedOptions = false;
+        try {
+            Less.class.getField("quitIfOneScreen");
+            hasExtendedOptions = true;
+        } catch (NoSuchFieldException e) {
+            List<String> ustrs = new ArrayList<>(Arrays.asList(usage));
+            ustrs.removeIf(s -> s.contains("--quit-if-one-screen") || s.contains("--no-init") || s.contains("--no-keypad"));
+            usage = ustrs.toArray(new String[ustrs.size()]);
+        }
+        Options opt = parseOptions(session, usage, argv);
+        List<Source> sources = new ArrayList<>();
+        if (opt.args().isEmpty()) {
+            opt.args().add("-");
+        }
+        for (String arg : opt.args()) {
+            if ("-".equals(arg)) {
+                sources.add(new StdInSource(process));
+            } else {
+                sources.add(new PathSource(session.currentDir().resolve(arg), arg));
+            }
+        }
+
+        if (!process.isTty(1)) {
+            for (Source source : sources) {
+                try (BufferedReader reader = new BufferedReader(new InputStreamReader(source.read()))) {
+                    cat(process, reader, opt.isSet("LINE-NUMBERS"));
+                }
+            }
+            return;
+        }
+
+        Less less = new Less(Shell.getTerminal(session));
+        less.quitAtFirstEof = opt.isSet("QUIT-AT-EOF");
+        less.quitAtSecondEof = opt.isSet("quit-at-eof");
+        less.quiet = opt.isSet("quiet");
+        less.veryQuiet = opt.isSet("QUIET");
+        less.chopLongLines = opt.isSet("chop-long-lines");
+        less.ignoreCaseAlways = opt.isSet("IGNORE-CASE");
+        less.ignoreCaseCond = opt.isSet("ignore-case");
+        if (opt.isSet("tabs")) {
+            less.tabs = opt.getNumber("tabs");
+        }
+        less.printLineNumbers = opt.isSet("LINE-NUMBERS");
+        if (hasExtendedOptions) {
+            Less.class.getField("quitIfOneScreen").set(less, opt.isSet("quit-if-one-screen"));
+            Less.class.getField("noInit").set(less, opt.isSet("no-init"));
+            Less.class.getField("noKeypad").set(less, opt.isSet("no-keypad"));
+        }
+        less.run(sources);
+    }
+
+    protected void sort(CommandSession session, Process process, String[] argv) throws Exception {
+        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 = parseOptions(session, usage, argv);
+
+        List<String> args = opt.args();
+
+        List<String> lines = new ArrayList<>();
+        if (!args.isEmpty()) {
+            for (String filename : args) {
+                try (BufferedReader reader = new BufferedReader(new InputStreamReader(
+                        session.currentDir().toUri().resolve(filename).toURL().openStream()))) {
+                    read(reader, lines);
+                }
+            }
+        } else {
+            BufferedReader r = new BufferedReader(new InputStreamReader(process.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);
+        lines.sort(new SortComparator(caseInsensitive, reverse, ignoreBlanks, numeric, sep, sortFields));
+        String last = null;
+        for (String s : lines) {
+            if (!unique || last == null || !s.equals(last)) {
+                process.out().println(s);
+            }
+            last = s;
+        }
+    }
+
+    protected void pwd(CommandSession session, Process process, String[] argv) throws Exception {
+        final String[] usage = {
+                "pwd - get current directory",
+                "Usage: pwd [OPTIONS]",
+                "  -? --help                show help"
+        };
+        Options opt = parseOptions(session, usage, argv);
+        if (!opt.args().isEmpty()) {
+            throw new IllegalArgumentException("usage: pwd");
+        }
+        process.out().println(session.currentDir());
+    }
+
+    protected void cd(CommandSession session, Process process, String[] argv) throws Exception {
+        final String[] usage = {
+                "cd - get current directory",
+                "Usage: cd [OPTIONS] DIRECTORY",
+                "  -? --help                show help"
+        };
+        Options opt = parseOptions(session, usage, argv);
+        if (opt.args().size() != 1) {
+            throw new IllegalArgumentException("usage: cd DIRECTORY");
+        }
+        Path cwd = session.currentDir();
+        cwd = cwd.resolve(opt.args().get(0)).toAbsolutePath();
+        if (!Files.exists(cwd)) {
+            throw new IOException("no such file or directory: " + opt.args().get(0));
+        } else if (!Files.isDirectory(cwd)) {
+            throw new IOException("not a directory: " + opt.args().get(0));
+        }
+        session.currentDir(cwd);
+    }
+
+    protected void ls(CommandSession session, Process process, String[] argv) throws Exception {
+        final String[] usage = {
+                "ls - list files",
+                "Usage: ls [OPTIONS] [PATTERNS...]",
+                "  -? --help                show help",
+                "  -1                       list one entry per line",
+                "  -C                       multi-column output",
+                "     --color=WHEN          colorize the output, may be `always', `never' or `auto'",
+                "  -a                       list entries starting with .",
+                "  -F                       append file type indicators",
+                "  -m                       comma separated",
+                "  -l                       long listing",
+                "  -S                       sort by size",
+                "  -f                       output is not sorted",
+                "  -r                       reverse sort order",
+                "  -t                       sort by modification time",
+                "  -x                       sort horizontally",
+                "  -L                       list referenced file for links",
+                "  -h                       print sizes in human readable form"
+        };
+        Options opt = parseOptions(session, usage, argv);
+        String color = opt.isSet("color") ? opt.get("color") : "auto";
+        boolean colored;
+        switch (color) {
+            case "always":
+            case "yes":
+            case "force":
+                colored = true;
+                break;
+            case "never":
+            case "no":
+            case "none":
+                colored = false;
+                break;
+            case "auto":
+            case "tty":
+            case "if-tty":
+                colored = process.isTty(1);
+                break;
+            default:
+                throw new IllegalArgumentException("invalid argument ‘" + color + "’ for ‘--color’");
+        }
+        Map<String, String> colors = colored ? getLsColorMap(session) : Collections.emptyMap();
+
+        class PathEntry implements Comparable<PathEntry> {
+            final Path abs;
+            final Path path;
+            final Map<String, Object> attributes;
+
+            public PathEntry(Path abs, Path root) {
+                this.abs = abs;
+                this.path = abs.startsWith(root) ? root.relativize(abs) : abs;
+                this.attributes = readAttributes(abs);
+            }
+
+            @Override
+            public int compareTo(PathEntry o) {
+                int c = doCompare(o);
+                return opt.isSet("r") ? -c : c;
+            }
+
+            private int doCompare(PathEntry o) {
+                if (opt.isSet("f")) {
+                    return -1;
+                }
+                if (opt.isSet("S")) {
+                    long s0 = attributes.get("size") != null ? ((Number) attributes.get("size")).longValue() : 0L;
+                    long s1 = o.attributes.get("size") != null ? ((Number) o.attributes.get("size")).longValue() : 0L;
+                    return s0 > s1 ? -1 : s0 < s1 ? 1 : path.toString().compareTo(o.path.toString());
+                }
+                if (opt.isSet("t")) {
+                    long t0 = attributes.get("lastModifiedTime") != null ? ((FileTime) attributes.get("lastModifiedTime")).toMillis() : 0L;
+                    long t1 = o.attributes.get("lastModifiedTime") != null ? ((FileTime) o.attributes.get("lastModifiedTime")).toMillis() : 0L;
+                    return t0 > t1 ? -1 : t0 < t1 ? 1 : path.toString().compareTo(o.path.toString());
+                }
+                return path.toString().compareTo(o.path.toString());
+            }
+
+            boolean isNotDirectory() {
+                return is("isRegularFile") || is("isSymbolicLink") || is("isOther");
+            }
+
+            boolean isDirectory() {
+                return is("isDirectory");
+            }
+
+            private boolean is(String attr) {
+                Object d = attributes.get(attr);
+                return d instanceof Boolean && (Boolean) d;
+            }
+
+            String display() {
+                String type;
+                String suffix;
+                String link = "";
+                if (is("isSymbolicLink")) {
+                    type = "sl";
+                    suffix = "@";
+                    try {
+                        Path l = Files.readSymbolicLink(abs);
+                        link = " -> " + l.toString();
+                    } catch (IOException e) {
+                        // ignore
+                    }
+                } else if (is("isDirectory")) {
+                    type = "dr";
+                    suffix = "/";
+                } else if (is("isExecutable")) {
+                    type = "ex";
+                    suffix = "*";
+                } else if (is("isOther")) {
+                    type = "ot";
+                    suffix = "";
+                } else {
+                    type = "";
+                    suffix = "";
+                }
+                boolean addSuffix = opt.isSet("F");
+                return applyStyle(path.toString(), colors, type)
+                        + (addSuffix ? suffix : "") + link;
+            }
+
+            String longDisplay() {
+                String username;
+                if (attributes.containsKey("owner")) {
+                    username = Objects.toString(attributes.get("owner"), null);
+                } else {
+                    username = "owner";
+                }
+                if (username.length() > 8) {
+                    username = username.substring(0, 8);
+                } else {
+                    for (int i = username.length(); i < 8; i++) {
+                        username = username + " ";
+                    }
+                }
+                String group;
+                if (attributes.containsKey("group")) {
+                    group = Objects.toString(attributes.get("group"), null);
+                } else {
+                    group = "group";
+                }
+                if (group.length() > 8) {
+                    group = group.substring(0, 8);
+                } else {
+                    for (int i = group.length(); i < 8; i++) {
+                        group = group + " ";
+                    }
+                }
+                Number length = (Number) attributes.get("size");
+                if (length == null) {
+                    length = 0L;
+                }
+                String lengthString;
+                if (opt.isSet("h")) {
+                    double l = length.longValue();
+                    String unit = "B";
+                    if (l >= 1000) {
+                         l /= 1024;
+                        unit = "K";
+                        if (l >= 1000) {
+                            l /= 1024;
+                            unit = "M";
+                            if (l >= 1000) {
+                                l /= 1024;
+                                unit = "T";
+                            }
+                        }
+                    }
+                    if (l < 10 && length.longValue() > 1000) {
+                        lengthString = String.format("%.1f", l) + unit;
+                    } else {
+                        lengthString = String.format("%3.0f", l) + unit;
+                    }
+                } else {
+                    lengthString = String.format("%1$8s", length);
+                }
+                @SuppressWarnings("unchecked")
+                Set<PosixFilePermission> perms = (Set<PosixFilePermission>) attributes.get("permissions");
+                if (perms == null) {
+                    perms = EnumSet.noneOf(PosixFilePermission.class);
+                }
+                // TODO: all fields should be padded to align
+                return (is("isDirectory") ? "d" : (is("isSymbolicLink") ? "l" : (is("isOther") ? "o" : "-")))
+                        + PosixFilePermissions.toString(perms) + " "
+                        + String.format("%3s", (attributes.containsKey("nlink") ? attributes.get("nlink").toString() : "1"))
+                        + " " + username + " " + group + " " + lengthString + " "
+                        + toString((FileTime) attributes.get("lastModifiedTime"))
+                        + " " + display();
+            }
+
+            protected String toString(FileTime time) {
+                long millis = (time != null) ? time.toMillis() : -1L;
+                if (millis < 0L) {
+                    return "------------";
+                }
+                ZonedDateTime dt = Instant.ofEpochMilli(millis).atZone(ZoneId.systemDefault());
+                // Less than six months
+                if (System.currentTimeMillis() - millis < 183L * 24L * 60L * 60L * 1000L) {
+                    return DateTimeFormatter.ofPattern("MMM ppd HH:mm").format(dt);
+                }
+                // Older than six months
+                else {
+                    return DateTimeFormatter.ofPattern("MMM ppd  yyyy").format(dt);
+                }
+            }
+
+            protected Map<String, Object> readAttributes(Path path) {
+                Map<String, Object>  attrs = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+                for (String view : path.getFileSystem().supportedFileAttributeViews()) {
+                    try {
+                        Map<String, Object> ta = Files.readAttributes(path, view + ":*",
+                                getLinkOptions(opt.isSet("L")));
+                        ta.forEach(attrs::putIfAbsent);
+                    } catch (IOException e) {
+                        // Ignore
+                    }
+                }
+                attrs.computeIfAbsent("isExecutable", s -> Files.isExecutable(path));
+                attrs.computeIfAbsent("permissions", s -> getPermissionsFromFile(path.toFile()));
+                return attrs;
+            }
+        }
+
+        Path currentDir = session.currentDir();
+        // Listing
+        List<Path> expanded = new ArrayList<>();
+        if (opt.args().isEmpty()) {
+            expanded.add(currentDir);
+        } else {
+            opt.args().forEach(s -> expanded.add(currentDir.resolve(s)));
+        }
+        boolean listAll = opt.isSet("a");
+        Predicate<Path> filter = p -> listAll || !p.getFileName().toString().startsWith(".");
+        List<PathEntry> all = expanded.stream()
+                .filter(filter)
+                .map(p -> new PathEntry(p, currentDir))
+                .sorted()
+                .collect(Collectors.toList());
+        // Print files first
+        List<PathEntry> files = all.stream()
+                .filter(PathEntry::isNotDirectory)
+                .collect(Collectors.toList());
+        PrintStream out = process.out();
+        Consumer<Stream<PathEntry>> display = s -> {
+            boolean optLine  = opt.isSet("1");
+            boolean optComma = opt.isSet("m");
+            boolean optLong  = opt.isSet("l");
+            boolean optCol   = opt.isSet("C");
+            if (!optLine && !optComma && !optLong && !optCol) {
+                if (process.isTty(1)) {
+                    optCol = true;
+                }
+                else {
+                    optLine = true;
+                }
+            }
+            // One entry per line
+            if (optLine) {
+                s.map(PathEntry::display).forEach(out::println);
+            }
+            // Comma separated list
+            else if (optComma) {
+                out.println(s.map(PathEntry::display).collect(Collectors.joining(", ")));
+            }
+            // Long listing
+            else if (optLong) {
+                s.map(PathEntry::longDisplay).forEach(out::println);
+            }
+            // Column listing
+            else if (optCol) {
+                toColumn(session, process, out, s.map(PathEntry::display), opt.isSet("x"));
+            }
+        };
+        boolean space = false;
+        if (!files.isEmpty()) {
+            display.accept(files.stream());
+            space = true;
+        }
+        // Print directories
+        List<PathEntry> directories = all.stream()
+                .filter(PathEntry::isDirectory)
+                .collect(Collectors.toList());
+        for (PathEntry entry : directories) {
+            if (space) {
+                out.println();
+            }
+            space = true;
+            Path path = currentDir.resolve(entry.path);
+            if (expanded.size() > 1) {
+                out.println(currentDir.relativize(path).toString() + ":");
+            }
+            display.accept(Stream.concat(Stream.of(".", "..").map(path::resolve), Files.list(path))
+                            .filter(filter)
+                            .map(p -> new PathEntry(p, path))
+                            .sorted()
+            );
+        }
+    }
+
+    private void toColumn(CommandSession session, Process process, PrintStream out, Stream<String> ansi, boolean horizontal) {
+        Terminal terminal = Shell.getTerminal(session);
+        int width = process.isTty(1) ? terminal.getWidth() : 80;
+        List<AttributedString> strings = ansi.map(AttributedString::fromAnsi).collect(Collectors.toList());
+        if (!strings.isEmpty()) {
+            int max = strings.stream().mapToInt(AttributedString::columnLength).max().getAsInt();
+            int c = Math.max(1, width / max);
+            while (c > 1 && c * max + (c - 1) >= width) {
+                c--;
+            }
+            int columns = c;
+            int lines = (strings.size() + columns - 1) / columns;
+            IntBinaryOperator index;
+            if (horizontal) {
+                index = (i, j) -> i * columns + j;
+            } else {
+                index = (i, j) -> j * lines + i;
+            }
+            AttributedStringBuilder sb = new AttributedStringBuilder();
+            for (int i = 0; i < lines; i++) {
+                for (int j = 0; j < columns; j++) {
+                    int idx = index.applyAsInt(i, j);
+                    if (idx < strings.size()) {
+                        AttributedString str = strings.get(idx);
+                        boolean hasRightItem = j < columns - 1 && index.applyAsInt(i, j + 1) < strings.size();
+                        sb.append(str);
+                        if (hasRightItem) {
+                            for (int k = 0; k <= max - str.length(); k++) {
+                                sb.append(' ');
+                            }
+                        }
+                    }
+                }
+                sb.append('\n');
+            }
+            out.print(sb.toAnsi(terminal));
+        }
+    }
+
+    protected void cat(CommandSession session, Process process, 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 = parseOptions(session, usage, argv);
+        List<String> args = opt.args();
+        if (args.isEmpty()) {
+            args = Collections.singletonList("-");
+        }
+        Path cwd = session.currentDir();
+        for (String arg : args) {
+            InputStream is;
+            if ("-".equals(arg)) {
+                is = process.in();
+            } else {
+                is = cwd.toUri().resolve(arg).toURL().openStream();
+            }
+            cat(process, new BufferedReader(new InputStreamReader(is)), opt.isSet("n"));
+        }
+    }
+
+    protected void echo(CommandSession session, Process process, Object[] argv) throws Exception {
+        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 = parseOptions(session, usage, argv);
+        List<String> args = opt.args();
+        StringBuilder buf = new StringBuilder();
+        if (args != null) {
+            for (String arg : args) {
+                if (buf.length() > 0)
+                    buf.append(' ');
+                for (int i = 0; i < arg.length(); i++) {
+                    int c = arg.charAt(i);
+                    int ch;
+                    if (c == '\\') {
+                        c = i < arg.length() - 1 ? arg.charAt(++i) : '\\';
+                        switch (c) {
+                            case 'a':
+                                buf.append('\u0007');
+                                break;
+                            case 'n':
+                                buf.append('\n');
+                                break;
+                            case 't':
+                                buf.append('\t');
+                                break;
+                            case 'r':
+                                buf.append('\r');
+                                break;
+                            case '\\':
+                                buf.append('\\');
+                                break;
+                            case '0':
+                            case '1':
+                            case '2':
+                            case '3':
+                            case '4':
+                            case '5':
+                            case '6':
+                            case '7':
+                            case '8':
+                            case '9':
+                                ch = 0;
+                                for (int j = 0; j < 3; j++) {
+                                    c = i < arg.length() - 1 ? arg.charAt(++i) : -1;
+                                    if (c >= 0) {
+                                        ch = ch * 8 + (c - '0');
+                                    }
+                                }
+                                buf.append((char) ch);
+                                break;
+                            case 'u':
+                                ch = 0;
+                                for (int j = 0; j < 4; j++) {
+                                    c = i < arg.length() - 1 ? arg.charAt(++i) : -1;
+                                    if (c >= 0) {
+                                        if (c >= 'A' && c <= 'Z') {
+                                            ch = ch * 16 + (c - 'A' + 10);
+                                        } else if (c >= 'a' && c <= 'z') {
+                                            ch = ch * 16 + (c - 'a' + 10);
+                                        } else if (c >= '0' && c <= '9') {
+                                            ch = ch * 16 + (c - '0');
+                                        } else {
+                                            break;
+                                        }
+                                    }
+                                }
+                                buf.append((char) ch);
+                                break;
+                            default:
+                                buf.append((char) c);
+                                break;
+                        }
+                    } else {
+                        buf.append((char) c);
+                    }
+                }
+            }
+        }
+        if (opt.isSet("n")) {
+            process.out().print(buf);
+        } else {
+            process.out().println(buf);
+        }
+    }
+
+    protected void grep(CommandSession session, Process process, String[] argv) throws Exception {
+        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",
+                "  -w --word-regexp         Select only whole words",
+                "  -x --line-regexp         Select only whole lines",
+                "  -c --count               Only print a count of matching lines per file",
+                "     --color=WHEN          Use markers to distinguish the matching string, may be `always', `never' or `auto'",
+                "  -B --before-context=NUM  Print NUM lines of leading context before matching lines",
+                "  -A --after-context=NUM   Print NUM lines of trailing context after matching lines",
+                "  -C --context=NUM         Print NUM lines of output context",
+                "     --pad-lines           Pad line numbers"
+        };
+        Options opt = parseOptions(session, usage, argv);
+        List<String> args = opt.args();
+        if (args.isEmpty()) {
+            throw new IllegalArgumentException("no pattern supplied");
+        }
+
+        String regex = args.remove(0);
+        String regexp = regex;
+        if (opt.isSet("word-regexp")) {
+            regexp = "\\b" + regexp + "\\b";
+        }
+        if (opt.isSet("line-regexp")) {
+            regexp = "^" + regexp + "$";
+        } else {
+            regexp = ".*" + regexp + ".*";
+        }
+        Pattern p;
+        Pattern p2;
+        if (opt.isSet("ignore-case")) {
+            p = Pattern.compile(regexp, Pattern.CASE_INSENSITIVE);
+            p2 = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
+        } else {
+            p = Pattern.compile(regexp);
+            p2 = Pattern.compile(regex);
+        }
+        int after = opt.isSet("after-context") ? opt.getNumber("after-context") : -1;
+        int before = opt.isSet("before-context") ? opt.getNumber("before-context") : -1;
+        int context = opt.isSet("context") ? opt.getNumber("context") : 0;
+        String lineFmt = opt.isSet("pad-lines") ? "%6d" : "%d";
+        if (after < 0) {
+            after = context;
+        }
+        if (before < 0) {
+            before = context;
+        }
+        List<String> lines = new ArrayList<>();
+        boolean invertMatch = opt.isSet("invert-match");
+        boolean lineNumber = opt.isSet("line-number");
+        boolean count = opt.isSet("count");
+        String color = opt.isSet("color") ? opt.get("color") : "auto";
+        boolean colored;
+        switch (color) {
+            case "always":
+            case "yes":
+            case "force":
+                colored = true;
+                break;
+            case "never":
+            case "no":
+            case "none":
+                colored = false;
+                break;
+            case "auto":
+            case "tty":
+            case "if-tty":
+                colored = process.isTty(1);
+                break;
+            default:
+                throw new IllegalArgumentException("invalid argument ‘" + color + "’ for ‘--color’");
+        }
+        Map<String, String> colors = colored ? getColorMap(session, "GREP", DEFAULT_GREP_COLORS) : Collections.emptyMap();
+
+        List<Source> sources = new ArrayList<>();
+        if (opt.args().isEmpty()) {
+            opt.args().add("-");
+        }
+        for (String arg : opt.args()) {
+            if ("-".equals(arg)) {
+                sources.add(new StdInSource(process));
+            } else {
+                sources.add(new PathSource(session.currentDir().resolve(arg), arg));
+            }
+        }
+        boolean match = false;
+        for (Source source : sources) {
+            boolean firstPrint = true;
+            int nb = 0;
+            int lineno = 1;
+            String line;
+            int lineMatch = 0;
+            try (BufferedReader r = new BufferedReader(new InputStreamReader(source.read()))) {
+                while ((line = r.readLine()) != null) {
+                    if (line.length() == 1 && line.charAt(0) == '\n') {
+                        break;
+                    }
+                    boolean matches = p.matcher(line).matches();
+                    AttributedStringBuilder sbl = new AttributedStringBuilder();
+                    if (!count) {
+                        if (sources.size() > 1) {
+                            if (colored) {
+                                applyStyle(sbl, colors, "fn");
+                            }
+                            sbl.append(source.getName());
+                            if (colored) {
+                                applyStyle(sbl, colors, "se");
+                            }
+                            sbl.append(":");
+                        }
+                        if (lineNumber) {
+                            if (colored) {
+                                applyStyle(sbl, colors, "ln");
+                            }
+                            sbl.append(String.format(lineFmt, lineno));
+                            if (colored) {
+                                applyStyle(sbl, colors, "se");
+                            }
+                            sbl.append((matches ^ invertMatch) ? ":" : "-");
+                        }
+                        String style = matches ^ invertMatch ^ (invertMatch && colors.containsKey("rv"))
+                                ? "sl" : "cx";
+                        if (colored) {
+                            applyStyle(sbl, colors, style);
+                        }
+                        AttributedString aLine = AttributedString.fromAnsi(line);
+                        Matcher matcher2 = p2.matcher(aLine.toString());
+                        int cur = 0;
+                        while (matcher2.find()) {
+                            int index = matcher2.start(0);
+                            AttributedString prefix = aLine.subSequence(cur, index);
+                            sbl.append(prefix);
+                            cur = matcher2.end();
+                            if (colored) {
+                                applyStyle(sbl, colors, invertMatch ? "mc" : "ms", "mt");
+                            }
+                            sbl.append(aLine.subSequence(index, cur));
+                            if (colored) {
+                                applyStyle(sbl, colors, style);
+                            }
+                            nb++;
+                        }
+                        sbl.append(aLine.subSequence(cur, aLine.length()));
+                    }
+                    if (matches ^ invertMatch) {
+                        lines.add(sbl.toAnsi(Shell.getTerminal(session)));
+                        lineMatch = lines.size();
+                    } else {
+                        if (lineMatch != 0 & lineMatch + after + before <= lines.size()) {
+                            if (!count) {
+                                if (!firstPrint && before + after > 0) {
+                                    AttributedStringBuilder sbl2 = new AttributedStringBuilder();
+                                    if (colored) {
+                                        applyStyle(sbl2, colors, "se");
+                                    }
+                                    sbl2.append("--");
+                                    process.out().println(sbl2.toAnsi(Shell.getTerminal(session)));
+                                } else {
+                                    firstPrint = false;
+                                }
+                                for (int i = 0; i < lineMatch + after; i++) {
+                                    process.out().println(lines.get(i));
+                                }
+                            }
+                            while (lines.size() > before) {
+                                lines.remove(0);
+                            }
+                            lineMatch = 0;
+                        }
+                        lines.add(sbl.toAnsi(Shell.getTerminal(session)));
+                        while (lineMatch == 0 && lines.size() > before) {
+                            lines.remove(0);
+                        }
+                    }
+                    lineno++;
+                }
+                if (!count && lineMatch > 0) {
+                    if (!firstPrint && before + after > 0) {
+                        AttributedStringBuilder sbl2 = new AttributedStringBuilder();
+                        if (colored) {
+                            applyStyle(sbl2, colors, "se");
+                        }
+                        sbl2.append("--");
+                        process.out().println(sbl2.toAnsi(Shell.getTerminal(session)));
+                    } else {
+                        firstPrint = false;
+                    }
+                    for (int i = 0; i < lineMatch + after && i < lines.size(); i++) {
+                        process.out().println(lines.get(i));
+                    }
+                }
+                if (count) {
+                    process.out().println(nb);
+                }
+                match |= nb > 0;
+            }
+        }
+        Process.Utils.current().error(match ? 0 : 1);
+    }
+
+    protected void sleep(CommandSession session, Process process, String[] argv) throws Exception {
+        final String[] usage = {
+                "sleep -  suspend execution for an interval of time",
+                "Usage: sleep seconds",
+                "  -? --help                    show help"};
+
+        Options opt = parseOptions(session, usage, argv);
+        List<String> args = opt.args();
+        if (args.size() != 1) {
+            throw new IllegalArgumentException("usage: sleep seconds");
+        } else {
+            int s = Integer.parseInt(args.get(0));
+            Thread.sleep(s * 1000);
+        }
+    }
+
+    protected static void read(BufferedReader r, List<String> lines) throws IOException {
+        for (String s = r.readLine(); s != null; s = r.readLine()) {
+            lines.add(s);
+        }
+    }
+
+    private static void cat(Process process, final BufferedReader reader, boolean displayLineNumbers) throws IOException {
+        String line;
+        int lineno = 1;
+        try {
+            while ((line = reader.readLine()) != null) {
+                if (displayLineNumbers) {
+                    process.out().print(String.format("%6d  ", lineno++));
+                }
+                process.out().println(line);
+            }
+        } finally {
+            reader.close();
+        }
+    }
+
+    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<>();
+                sortFields.add("1");
+            }
+            sortKeys = sortFields.stream().map(Key::new).collect(Collectors.toList());
+        }
+
+        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) {
+            for (int i1 = start1, i2 = start2; i1 < end1 && i2 < end2; 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 end1 - end2;
+        }
+
+        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<>();
+            if (o.length() > 0) {
+                if (separator == '\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);
+                }
+            }
+        }
+    }
+
+    private static LinkOption[] getLinkOptions(boolean followLinks) {
+        if (followLinks) {
+            return EMPTY_LINK_OPTIONS;
+        } else {    // return a clone that modifications to the array will not affect others
+            return NO_FOLLOW_OPTIONS.clone();
+        }
+    }
+
+    /**
+     * @param fileName The file name to be evaluated - ignored if {@code null}/empty
+     * @return {@code true} if the file ends in one of the {@link #WINDOWS_EXECUTABLE_EXTENSIONS}
+     */
+    private static boolean isWindowsExecutable(String fileName) {
+        if ((fileName == null) || (fileName.length() <= 0)) {
+            return false;
+        }
+        for (String suffix : WINDOWS_EXECUTABLE_EXTENSIONS) {
+            if (fileName.endsWith(suffix)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @param f The {@link File} to be checked
+     * @return A {@link Set} of {@link PosixFilePermission}s based on whether
+     * the file is readable/writable/executable. If so, then <U>all</U> the
+     * relevant permissions are set (i.e., owner, group and others)
+     */
+    private static Set<PosixFilePermission> getPermissionsFromFile(File f) {
+        Set<PosixFilePermission> perms = EnumSet.noneOf(PosixFilePermission.class);
+        if (f.canRead()) {
+            perms.add(PosixFilePermission.OWNER_READ);
+            perms.add(PosixFilePermission.GROUP_READ);
+            perms.add(PosixFilePermission.OTHERS_READ);
+        }
+
+        if (f.canWrite()) {
+            perms.add(PosixFilePermission.OWNER_WRITE);
+            perms.add(PosixFilePermission.GROUP_WRITE);
+            perms.add(PosixFilePermission.OTHERS_WRITE);
+        }
+
+        if (f.canExecute() || (OSUtils.IS_WINDOWS && isWindowsExecutable(f.getName()))) {
+            perms.add(PosixFilePermission.OWNER_EXECUTE);
+            perms.add(PosixFilePermission.GROUP_EXECUTE);
+            perms.add(PosixFilePermission.OTHERS_EXECUTE);
+        }
+
+        return perms;
+    }
+
+    public static Map<String, String> getLsColorMap(CommandSession session) {
+        return getColorMap(session, "LS", DEFAULT_LS_COLORS);
+    }
+
+    public static Map<String, String> getColorMap(CommandSession session, String name, String def) {
+        Object obj = session.get(name + "_COLORS");
+        String str = obj != null ? obj.toString() : null;
+        if (str == null) {
+            str = def;
+        }
+        String sep = str.matches("[a-z]{2}=[0-9]*(;[0-9]+)*(:[a-z]{2}=[0-9]*(;[0-9]+)*)*") ? ":" : " ";
+        return Arrays.stream(str.split(sep))
+                .collect(Collectors.toMap(s -> s.substring(0, s.indexOf('=')),
+                                          s -> s.substring(s.indexOf('=') + 1)));
+    }
+
+    static String applyStyle(String text, Map<String, String> colors, String... types) {
+        String t = null;
+        for (String type : types) {
+            if (colors.get(type) != null) {
+                t = type;
+                break;
+            }
+        }
+        return new AttributedString(text, new StyleResolver(colors::get).resolve("." + t))
+                .toAnsi();
+    }
+
+    static void applyStyle(AttributedStringBuilder sb, Map<String, String> colors, String... types) {
+        String t = null;
+        for (String type : types) {
+            if (colors.get(type) != null) {
+                t = type;
+                break;
+            }
+        }
+        sb.style(new StyleResolver(colors::get).resolve("." + t));
+    }
+
+    private static class StdInSource implements Source {
+
+        private final Process process;
+
+        StdInSource(Process process) {
+            this.process = process;
+        }
+
+        @Override
+        public String getName() {
+            return null;
+        }
+
+        @Override
+        public InputStream read() {
+            return process.in();
+        }
+    }
+}
diff --git a/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java b/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java
new file mode 100644
index 0000000..eece61a
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/Procedural.java
@@ -0,0 +1,604 @@
+/*
+ * 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.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.command.Function;
+import org.apache.felix.service.command.Process;
+import org.jline.builtins.Options;
+
+public class Procedural {
+
+    static final String[] functions = {"each", "if", "not", "throw", "try", "until", "while", "break", "continue"};
+
+    public Object _main(CommandSession session, Object[] argv) throws Throwable {
+        if (argv == null || argv.length < 1) {
+            throw new IllegalArgumentException();
+        }
+        Process process = Process.Utils.current();
+        try {
+            return run(session, process, argv);
+        } catch (OptionException e) {
+            process.err().println(e.getMessage());
+            process.error(2);
+        } catch (HelpException e) {
+            process.err().println(e.getMessage());
+            process.error(0);
+        } catch (ThrownException e) {
+            process.error(1);
+            throw e.getCause();
+        }
+        return null;
+    }
+
+    @SuppressWarnings("serial")
+    protected static class OptionException extends Exception {
+        public OptionException(String message, Throwable cause) {
+            super(message, cause);
+        }
+    }
+
+    @SuppressWarnings("serial")
+    protected static class HelpException extends Exception {
+        public HelpException(String message) {
+            super(message);
+        }
+    }
+
+    @SuppressWarnings("serial")
+    protected static class ThrownException extends Exception {
+        public ThrownException(Throwable cause) {
+            super(cause);
+        }
+    }
+
+    @SuppressWarnings("serial")
+    protected static class BreakException extends Exception {
+    }
+
+    @SuppressWarnings("serial")
+    protected static class ContinueException extends Exception {
+    }
+
+    protected Options parseOptions(CommandSession session, String[] usage, Object[] argv) throws HelpException, OptionException {
+        try {
+            Options opt = Options.compile(usage, s -> get(session, s)).parse(argv, true);
+            if (opt.isSet("help")) {
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                opt.usage(new PrintStream(baos));
+                throw new HelpException(baos.toString());
+            }
+            return opt;
+        } catch (IllegalArgumentException e) {
+            throw new OptionException(e.getMessage(), e);
+        }
+    }
+
+    protected String get(CommandSession session, String name) {
+        Object o = session.get(name);
+        return o != null ? o.toString() : null;
+    }
+
+    protected Object run(CommandSession session, Process process, Object[] argv) throws Throwable {
+        switch (argv[0].toString()) {
+            case "each":
+                return doEach(session, process, argv);
+            case "if":
+                return doIf(session, process, argv);
+            case "not":
+                return doNot(session, process, argv);
+            case "throw":
+                return doThrow(session, process, argv);
+            case "try":
+                return doTry(session, process, argv);
+            case "until":
+                return doUntil(session, process, argv);
+            case "while":
+                return doWhile(session, process, argv);
+            case "break":
+                return doBreak(session, process, argv);
+            case "continue":
+                return doContinue(session, process, argv);
+            default:
+                throw new UnsupportedOperationException();
+        }
+    }
+
+    protected List<Object> doEach(CommandSession session,
+                                  Process process,
+                                  Object[] argv) throws Exception {
+        String[] usage = {
+                "each -  loop over the elements",
+                "Usage: each [-r] elements [do] { closure }",
+                "         elements              an array to iterate on",
+                "         closure               a closure to call",
+                "  -? --help                    Show help",
+                "  -r --result                  Return a list containing each iteration result",
+        };
+        Options opt = parseOptions(session, usage, argv);
+
+        Collection<Object> elements = getElements(opt);
+        if (opt.argObjects().size() > 0 && "do".equals(opt.argObjects().get(0))) {
+            opt.argObjects().remove(0);
+        }
+        List<Function> functions = getFunctions(opt);
+
+
+        if (elements == null || functions == null || functions.size() != 1) {
+            process.err().println("usage: each elements [do] { closure }");
+            process.err().println("       elements: an array to iterate on");
+            process.err().println("       closure: a function or closure to call");
+            process.error(2);
+            return null;
+        }
+
+        List<Object> args = new ArrayList<>();
+        List<Object> results = new ArrayList<>();
+        args.add(null);
+
+        for (Object x : elements) {
+            checkInterrupt();
+            args.set(0, x);
+            try {
+                results.add(functions.get(0).execute(session, args));
+            } catch (BreakException b) {
+                break;
+            } catch (ContinueException c) {
+                // Ignore
+            }
+        }
+
+        return opt.isSet("result") ? results : null;
+    }
+
+    protected Object doIf(CommandSession session, Process process, Object[] argv) throws Exception {
+        String[] usage = {
+                "if -  if / then / else construct",
+                "Usage: if {condition} [then] {if-action} [elif {cond} [then] {elif-action}]... [else] {else-action}",
+                "  -? --help                    Show help",
+        };
+        Options opt = parseOptions(session, usage, argv);
+
+        List<Function> conditions = new ArrayList<>();
+        List<Function> actions = new ArrayList<>();
+        Function elseFunction = null;
+        int step = 0;
+        boolean error = false;
+        for (Object obj : opt.argObjects()) {
+            switch (step) {
+                case 0:
+                    if (obj instanceof Function) {
+                        conditions.add((Function) obj);
+                    } else {
+                        error = true;
+                    }
+                    step = 1;
+                    break;
+                case 1:
+                    if ("then".equals(obj)) {
+                        step = 2;
+                        break;
+                    }
+                case 2:
+                    if (obj instanceof Function) {
+                        actions.add((Function) obj);
+                        step = 3;
+                    } else {
+                        error = true;
+                    }
+                    break;
+                case 3:
+                    if ("elif".equals(obj)) {
+                        step = 4;
+                    } else if ("else".equals(obj)) {
+                        step = 7;
+                    } else if (obj instanceof Function) {
+                        elseFunction = (Function) obj;
+                        step = 8;
+                    } else {
+                        error = true;
+                    }
+                    break;
+                case 4:
+                    if (obj instanceof Function) {
+                        conditions.add((Function) obj);
+                    } else {
+                        error = true;
+                    }
+                    step = 5;
+                    break;
+                case 5:
+                    if ("then".equals(obj)) {
+                        step = 6;
+                        break;
+                    }
+                case 6:
+                    if (obj instanceof Function) {
+                        actions.add((Function) obj);
+                        step = 3;
+                    } else {
+                        error = true;
+                    }
+                    break;
+                case 7:
+                    if (obj instanceof Function) {
+                        elseFunction = (Function) obj;
+                        step = 8;
+                    } else {
+                        error = true;
+                    }
+                    break;
+                case 8:
+                    error = true;
+                    break;
+            }
+            if (error) {
+                break;
+            }
+        }
+        error |= conditions.isEmpty();
+        error |= conditions.size() != actions.size();
+
+        if (error) {
+            process.err().println("usage: if {condition} [then] {if-action} [elif {elif-action}]... [else] {else-action}");
+            process.error(2);
+            return null;
+        }
+        for (int i = 0, length = conditions.size(); i < length; ++i) {
+            if (isTrue(session, conditions.get(i))) {
+                return actions.get(i).execute(session, null);
+            }
+        }
+        if (elseFunction != null) {
+            return elseFunction.execute(session, null);
+        }
+        return null;
+    }
+
+    protected Boolean doNot(CommandSession session, Process process, Object[] argv) throws Exception {
+        String[] usage = {
+                "not -  return the opposite condition",
+                "Usage: not { condition }",
+                "  -? --help                    Show help",
+        };
+        Options opt = parseOptions(session, usage, argv);
+        List<Function> functions = getFunctions(opt);
+        if (functions == null || functions.size() != 1) {
+            process.err().println("usage: not { condition }");
+            process.error(2);
+            return null;
+        }
+        return !isTrue(session, functions.get(0));
+
+    }
+
+    protected Object doThrow(CommandSession session, Process process, Object[] argv) throws ThrownException, HelpException, OptionException {
+        String[] usage = {
+                "throw -  throw an exception",
+                "Usage: throw [ message [ cause ] ]",
+                "       throw exception",
+                "       throw",
+                "  -? --help                    Show help",
+        };
+        Options opt = parseOptions(session, usage, argv);
+        if (opt.argObjects().size() == 0) {
+            Object exception = session.get("exception");
+            if (exception instanceof Throwable)
+                throw new ThrownException((Throwable) exception);
+            else
+                throw new ThrownException(new Exception());
+        }
+        else if (opt.argObjects().size() == 1 && opt.argObjects().get(0) instanceof Throwable) {
+            throw new ThrownException((Throwable) opt.argObjects().get(0));
+        }
+        else {
+            String message = opt.argObjects().get(0).toString();
+            Throwable cause = null;
+            if (opt.argObjects().size() > 1) {
+                if (opt.argObjects().get(1) instanceof Throwable) {
+                    cause = (Throwable) opt.argObjects().get(1);
+                }
+            }
+            throw new ThrownException(new Exception(message, cause));
+        }
+    }
+
+    protected Object doTry(CommandSession session, Process process, Object[] argv) throws Exception {
+        String[] usage = {
+                "try -  try / catch / finally construct",
+                "Usage: try { try-action } [ [catch] { catch-action } [ [finally] { finally-action } ]  ]",
+                "  -? --help                    Show help",
+        };
+        Options opt = parseOptions(session, usage, argv);
+        Function tryAction = null;
+        Function catchFunction = null;
+        Function finallyFunction = null;
+        int step = 0;
+        boolean error = false;
+        for (Object obj : opt.argObjects()) {
+            if (tryAction == null) {
+                if (obj instanceof Function) {
+                    tryAction = (Function) obj;
+                } else {
+                    error = true;
+                    break;
+                }
+                step = 1;
+            } else if ("catch".equals(obj)) {
+                if (step != 1) {
+                    error = true;
+                    break;
+                }
+                step = 2;
+            } else if ("finally".equals(obj)) {
+                if (step != 1 && step != 3) {
+                    error = true;
+                    break;
+                }
+                step = 4;
+            } else if (step == 1 || step == 2) {
+                if (obj instanceof Function) {
+                    catchFunction = (Function) obj;
+                } else {
+                    error = true;
+                    break;
+                }
+                step = 3;
+            } else if (step == 3 || step == 4) {
+                if (obj instanceof Function) {
+                    finallyFunction = (Function) obj;
+                } else {
+                    error = true;
+                    break;
+                }
+                step = 5;
+            } else {
+                error = true;
+                break;
+            }
+        }
+        error |= tryAction == null;
+        error |= catchFunction == null && finallyFunction == null;
+
+        if (error) {
+            process.err().println("usage: try { try-action } [ [catch] { catch-action } [ [finally] { finally-action } ] ]");
+            process.error(2);
+            return null;
+        }
+        try {
+            return tryAction.execute(session, null);
+        } catch (BreakException b) {
+            throw b;
+        } catch (Exception e) {
+            session.put("exception", e);
+            if (catchFunction != null) {
+                catchFunction.execute(session, null);
+            }
+            return null;
+        } finally {
+            if (finallyFunction != null) {
+                finallyFunction.execute(session, null);
+            }
+        }
+    }
+
+    protected Object doWhile(CommandSession session, Process process, Object[] argv) throws Exception {
+        String[] usage = {
+                "while -  while loop",
+                "Usage: while { condition } [do] { action }",
+                "  -? --help                    Show help",
+        };
+        Options opt = parseOptions(session, usage, argv);
+        Function condition = null;
+        Function action = null;
+        int step = 0;
+        boolean error = false;
+        for (Object obj : opt.argObjects()) {
+            if (condition == null) {
+                if (obj instanceof Function) {
+                    condition = (Function) obj;
+                } else {
+                    error = true;
+                    break;
+                }
+                step = 1;
+            } else if ("do".equals(obj)) {
+                if (step != 1) {
+                    error = true;
+                    break;
+                }
+                step = 2;
+            } else if (step == 1 || step == 2) {
+                if (obj instanceof Function) {
+                    action = (Function) obj;
+                } else {
+                    error = true;
+                    break;
+                }
+                step = 3;
+            } else {
+                error = true;
+                break;
+            }
+        }
+        error |= condition == null;
+        error |= action == null;
+
+        if (error) {
+            process.err().println("usage: while { condition } [do] { action }");
+            process.error(2);
+            return null;
+        }
+        while (isTrue(session, condition)) {
+            try {
+                action.execute(session, null);
+            } catch (BreakException b) {
+                break;
+            } catch (ContinueException c) {
+                // Ignore
+            }
+        }
+        return null;
+    }
+
+    protected Object doUntil(CommandSession session, Process process, Object[] argv) throws Exception {
+        String[] usage = {
+                "until -  until loop",
+                "Usage: until { condition } [do] { action }",
+                "  -? --help                    Show help",
+        };
+        Options opt = parseOptions(session, usage, argv);
+        Function condition = null;
+        Function action = null;
+        int step = 0;
+        boolean error = false;
+        for (Object obj : opt.argObjects()) {
+            if (condition == null) {
+                if (obj instanceof Function) {
+                    condition = (Function) obj;
+                } else {
+                    error = true;
+                    break;
+                }
+                step = 1;
+            } else if ("do".equals(obj)) {
+                if (step != 1) {
+                    error = true;
+                    break;
+                }
+                step = 2;
+            } else if (step == 1 || step == 2) {
+                if (obj instanceof Function) {
+                    action = (Function) obj;
+                } else {
+                    error = true;
+                    break;
+                }
+                step = 3;
+            } else {
+                error = true;
+                break;
+            }
+        }
+        error |= condition == null;
+        error |= action == null;
+
+        if (error) {
+            process.err().println("usage: until { condition } [do] { action }");
+            process.error(2);
+            return null;
+        }
+        while (!isTrue(session, condition)) {
+            try {
+                action.execute(session, null);
+            } catch (BreakException e) {
+                break;
+            } catch (ContinueException c) {
+                // Ignore
+            }
+        }
+        return null;
+    }
+
+    protected Object doBreak(CommandSession session, Process process, Object[] argv) throws Exception {
+        String[] usage = {
+                "break -  break from loop",
+                "Usage: break",
+                "  -? --help                    Show help",
+        };
+        parseOptions(session, usage, argv);
+        throw new BreakException();
+    }
+
+    protected Object doContinue(CommandSession session, Process process, Object[] argv) throws Exception {
+        String[] usage = {
+                "continue -  continue loop",
+                "Usage: continue",
+                "  -? --help                    Show help",
+        };
+        parseOptions(session, usage, argv);
+        throw new ContinueException();
+    }
+
+    private boolean isTrue(CommandSession session, Function function) throws Exception {
+        checkInterrupt();
+        return isTrue(function.execute(session, null));
+    }
+
+    private boolean isTrue(Object result) throws InterruptedException {
+        checkInterrupt();
+
+        if (result == null)
+            return false;
+
+        if (result instanceof Boolean)
+            return (Boolean) result;
+
+        if (result instanceof Number) {
+            if (0 == ((Number) result).intValue())
+                return false;
+        }
+
+        if ("".equals(result))
+            return false;
+
+        return !"0".equals(result);
+    }
+
+    private void checkInterrupt() throws InterruptedException {
+        if (Thread.currentThread().isInterrupted())
+            throw new InterruptedException("interrupted");
+    }
+
+    @SuppressWarnings("unchecked")
+    private Collection<Object> getElements(Options opt) {
+        Collection<Object> elements = null;
+        if (opt.argObjects().size() > 0) {
+            Object o = opt.argObjects().remove(0);
+            if (o instanceof Collection) {
+                elements = (Collection<Object>) o;
+            } else if (o != null && o.getClass().isArray()) {
+                elements = Arrays.asList((Object[]) o);
+            }
+        }
+        return elements;
+    }
+
+    private List<Function> getFunctions(Options opt) {
+        List<Function> functions = new ArrayList<>();
+        for (Object o : opt.argObjects()) {
+            if (o instanceof Function) {
+                functions.add((Function) o);
+            }
+            else {
+                functions = null;
+                break;
+            }
+        }
+        return functions;
+    }
+
+}
diff --git a/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java b/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java
new file mode 100644
index 0000000..eaf0901
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/Shell.java
@@ -0,0 +1,728 @@
+/*
+ * 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.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.HttpURLConnection;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLConnection;
+import java.nio.CharBuffer;
+import java.nio.file.Paths;
+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 java.util.concurrent.atomic.AtomicBoolean;
+
+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.service.command.Job;
+import org.apache.felix.service.command.Job.Status;
+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.apache.felix.service.threadio.ThreadIO;
+import org.jline.builtins.Completers.CompletionData;
+import org.jline.builtins.Completers.CompletionEnvironment;
+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.terminal.Terminal;
+import org.jline.terminal.Terminal.Signal;
+import org.jline.terminal.Terminal.SignalHandler;
+import org.jline.utils.AttributedStringBuilder;
+import org.jline.utils.AttributedStyle;
+
+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_RESULT = "_";
+    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;
+    private final ThreadIO tio;
+
+    private AtomicBoolean stopping = new AtomicBoolean();
+
+    public Shell(Context context, CommandProcessor processor) {
+        this(context, processor, null);
+    }
+
+    public Shell(Context context, CommandProcessor processor, String profile) {
+        this(context, processor, null, profile);
+    }
+
+    public Shell(Context context, CommandProcessor processor, ThreadIO tio, String profile) {
+        this.context = context;
+        this.processor = processor;
+        this.tio = tio != null ? tio : getThreadIO(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";
+    }
+
+    private ThreadIO getThreadIO(CommandProcessor processor) {
+        try {
+            Field field = processor.getClass().getDeclaredField("threadIO");
+            field.setAccessible(true);
+            return (ThreadIO) field.get(processor);
+        } catch (Throwable t) {
+            return null;
+        }
+    }
+
+    public Context getContext() {
+        return context;
+    }
+
+    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<String, List<CompletionData>>) 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 = org.apache.felix.gogo.runtime.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 {
+        CharBuffer buf = CharBuffer.allocate(4096);
+        StringBuilder sb = new StringBuilder();
+
+        URLConnection conn = script.toURL().openConnection();
+
+        try (InputStreamReader in = new InputStreamReader(conn.getInputStream()))
+        {
+            while (in.read(buf) > 0)
+            {
+                buf.flip();
+                sb.append(buf);
+                buf.clear();
+            }
+        }
+        finally
+        {
+            if (conn instanceof HttpURLConnection)
+            {
+                ((HttpURLConnection) conn).disconnect();
+            }
+        }
+
+        return sb;
+    }
+
+    @SuppressWarnings("unchecked")
+    static Set<String> getVariables(CommandSession session) {
+        return (Set<String>) session.get(".variables");
+    }
+
+    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 void stop() {
+        stopping.set(true);
+    }
+
+    public Object gosh(CommandSession currentSession, 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",
+                "     --nohistory           don't save the command history",
+                "     --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 session;
+        if (login) {
+            session = currentSession;
+        } else {
+            session = createChildSession(currentSession);
+        }
+
+        if (opt.isSet("xtrace")) {
+            session.put("echo", true);
+        }
+
+        Terminal terminal = getTerminal(session);
+        session.put(Shell.VAR_CONTEXT, context);
+        session.put(Shell.VAR_PROCESSOR, processor);
+        session.put(Shell.VAR_SESSION, session);
+        session.put("#TERM", (Function) (s, arguments) -> terminal.getType());
+        session.put("#COLUMNS", (Function) (s, arguments) -> terminal.getWidth());
+        session.put("#LINES", (Function) (s, arguments) -> terminal.getHeight());
+        session.put("#PWD", (Function) (s, arguments) -> s.currentDir().toString());
+        if (!opt.isSet("nohistory")) {
+            session.put(LineReader.HISTORY_FILE, Paths.get(System.getProperty("user.home"), ".gogo.history"));
+        }
+
+        if (tio != null) {
+            PrintWriter writer = terminal.writer();
+            PrintStream out = new PrintStream(new OutputStream() {
+                @Override
+                public void write(int b) throws IOException {
+                    write(new byte[]{(byte) b}, 0, 1);
+                }
+                public void write(byte b[], int off, int len) {
+                    writer.write(new String(b, off, len));
+                }
+                public void flush() {
+                    writer.flush();
+                }
+                public void close() {
+                    writer.close();
+                }
+            });
+            tio.setStreams(terminal.input(), out, out);
+        }
+
+        try {
+            LineReader reader;
+            if (args.isEmpty() && interactive) {
+                CompletionEnvironment completionEnvironment = new CompletionEnvironment() {
+                    @Override
+                    public Map<String, List<CompletionData>> getCompletions() {
+                        return Shell.getCompletions(session);
+                    }
+
+                    @Override
+                    public Set<String> getCommands() {
+                        return Shell.getCommands(session);
+                    }
+
+                    @Override
+                    public String resolveCommand(String command) {
+                        return Shell.resolve(session, command);
+                    }
+
+                    @Override
+                    public String commandName(String command) {
+                        int idx = command.indexOf(':');
+                        return idx >= 0 ? command.substring(idx + 1) : command;
+                    }
+
+                    @Override
+                    public Object evaluate(LineReader reader, ParsedLine line, String func) throws Exception {
+                        session.put(Shell.VAR_COMMAND_LINE, line);
+                        return session.execute(func);
+                    }
+                };
+                reader = LineReaderBuilder.builder()
+                        .terminal(terminal)
+                        .variables(((CommandSessionImpl) session).getVariables())
+                        .completer(new org.jline.builtins.Completers.Completer(completionEnvironment))
+                        .highlighter(new Highlighter(session))
+                        .parser(new Parser())
+                        .expander(new Expander(session))
+                        .build();
+                reader.setOpt(LineReader.Option.AUTO_FRESH_LINE);
+                session.put(Shell.VAR_READER, reader);
+                session.put(Shell.VAR_COMPLETIONS, new HashMap<>());
+            } else {
+                reader = null;
+            }
+
+            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(session, uri.toString());
+                }
+            }
+
+            Object result = null;
+
+            if (args.isEmpty()) {
+                if (interactive) {
+                    result = runShell(session, terminal, reader);
+                }
+            } 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 = session.currentDir().toUri().resolve(args.remove(0));
+
+                    // set script arguments
+                    session.put("0", script);
+                    session.put("args", args);
+
+                    for (int i = 0; i < args.size(); ++i) {
+                        session.put(String.valueOf(i + 1), args.get(i));
+                    }
+
+                    program = readScript(script);
+                }
+
+                result = session.execute(program);
+            }
+
+            if (login && interactive && !opt.isSet("noshutdown")) {
+                if (terminal != null) {
+                    terminal.writer().println("gosh: stopping framework");
+                    terminal.flush();
+                }
+                shutdown();
+            }
+
+            return result;
+        } finally {
+            if (tio != null) {
+                tio.close();
+            }
+        }
+    }
+
+    private CommandSession createChildSession(CommandSession parent) {
+        CommandSession session = processor.createSession(parent);
+        getVariables(parent).stream()
+                .filter(key -> key.matches("[.]?[A-Z].*"))
+                .forEach(key -> session.put(key, parent.get(key)));
+        session.put(Shell.VAR_TERMINAL, getTerminal(parent));
+        return session;
+    }
+
+    private Object runShell(final CommandSession session, Terminal terminal,
+                            LineReader reader) throws InterruptedException {
+        AtomicBoolean reading = new AtomicBoolean();
+        session.setJobListener((job, previous, current) -> {
+            if (previous == Status.Background || current == Status.Background
+                    || previous == Status.Suspended || current == Status.Suspended) {
+                int width = terminal.getWidth();
+                String status = current.name().toLowerCase();
+                terminal.writer().write(getStatusLine(job, width, status));
+                terminal.flush();
+                if (reading.get() && !stopping.get()) {
+                    reader.callWidget(LineReader.REDRAW_LINE);
+                    reader.callWidget(LineReader.REDISPLAY);
+                }
+            }
+        });
+        SignalHandler intHandler = terminal.handle(Signal.INT, s -> {
+            Job current = session.foregroundJob();
+            if (current != null) {
+                current.interrupt();
+            }
+        });
+        SignalHandler suspHandler = terminal.handle(Signal.TSTP, s -> {
+            Job current = session.foregroundJob();
+            if (current != null) {
+                current.suspend();
+            }
+        });
+        Object result = null;
+        try {
+            while (!stopping.get()) {
+                try {
+                    reading.set(true);
+                    try {
+                        String prompt = Shell.getPrompt(session);
+                        String rprompt = Shell.getRPrompt(session);
+                        if (stopping.get()) {
+                            break;
+                        }
+                        reader.readLine(prompt, rprompt, (Character) null, null);
+                    } finally {
+                        reading.set(false);
+                    }
+                    ParsedLine parsedLine = reader.getParsedLine();
+                    if (parsedLine == null) {
+                        throw new EndOfFileException();
+                    }
+                    try {
+                        result = session.execute(((ParsedLineImpl) parsedLine).program());
+                        session.put(Shell.VAR_RESULT, 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) {
+                        AttributedStringBuilder sb = new AttributedStringBuilder();
+                        sb.style(sb.style().foreground(AttributedStyle.RED));
+                        sb.append(e.toString());
+                        sb.style(sb.style().foregroundDefault());
+                        terminal.writer().println(sb.toAnsi(terminal));
+                        terminal.flush();
+                        session.put(Shell.VAR_EXCEPTION, e);
+                    }
+
+                    waitJobCompletion(session);
+
+                } catch (UserInterruptException e) {
+                    // continue;
+                } catch (EndOfFileException e) {
+                    try {
+                        reader.getHistory().save();
+                    } catch (IOException e1) {
+                        // ignore
+                    }
+                    break;
+                }
+            }
+        } finally {
+            terminal.handle(Signal.INT, intHandler);
+            terminal.handle(Signal.TSTP, suspHandler);
+        }
+        return result;
+    }
+
+    private void waitJobCompletion(final CommandSession session) throws InterruptedException {
+        while (true) {
+            Job job = session.foregroundJob();
+            if (job != null) {
+                //noinspection SynchronizationOnLocalVariableOrMethodParameter
+                synchronized (job) {
+                    if (job.status() == Status.Foreground) {
+                        job.wait();
+                    }
+                }
+            } else {
+                break;
+            }
+        }
+    }
+
+    private String getStatusLine(Job job, int width, String status) {
+        StringBuilder sb = new StringBuilder();
+        for (int i = 0; i < width - 1; i++) {
+            sb.append(' ');
+        }
+        sb.append('\r');
+        sb.append("[").append(job.id()).append("]  ");
+        sb.append(status);
+        for (int i = status.length(); i < "background".length(); i++) {
+            sb.append(' ');
+        }
+        sb.append("  ").append(job.command()).append("\n");
+        return sb.toString();
+    }
+
+    @Descriptor("start a new shell")
+    public Object sh(final CommandSession session, String[] argv) throws Exception {
+        return gosh(session, argv);
+    }
+
+    private void shutdown() throws Exception {
+        context.exit();
+    }
+
+    @Descriptor("Evaluates contents of file")
+    public Object source(CommandSession session, String script) throws Exception {
+        URI uri = session.currentDir().toUri().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<>();
+        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);
+        commands.keySet().forEach(System.out::println);
+    }
+
+    @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<>();
+                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/jline/src/main/java/org/apache/felix/gogo/jline/SingleServiceTracker.java b/jline/src/main/java/org/apache/felix/gogo/jline/SingleServiceTracker.java
new file mode 100644
index 0000000..c9e4be8
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/SingleServiceTracker.java
@@ -0,0 +1,191 @@
+/*
+ * 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.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.Filter;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+//This is from aries util
+public final class SingleServiceTracker<T> implements ServiceListener {
+
+    public interface SingleServiceListener {
+        void serviceFound();
+
+        void serviceLost();
+
+        void serviceReplaced();
+    }
+
+    private final BundleContext ctx;
+    private final String className;
+    private final AtomicReference<T> service = new AtomicReference<>();
+    private final AtomicReference<ServiceReference<?>> ref = new AtomicReference<>();
+    private final AtomicBoolean open = new AtomicBoolean(false);
+    private final SingleServiceListener serviceListener;
+    private final String filterString;
+    private final Filter filter;
+
+    public SingleServiceTracker(BundleContext context, Class<T> clazz, SingleServiceListener sl) throws InvalidSyntaxException {
+        this(context, clazz, null, sl);
+    }
+
+    public SingleServiceTracker(BundleContext context, Class<T> clazz, String filterString, SingleServiceListener sl) throws InvalidSyntaxException {
+        this(context, clazz.getName(), filterString, sl);
+    }
+
+    public SingleServiceTracker(BundleContext context, String className, String filterString, SingleServiceListener sl) throws InvalidSyntaxException {
+        this.ctx = context;
+        this.className = className;
+        this.serviceListener = sl;
+        if (filterString == null || filterString.isEmpty()) {
+            this.filterString = null;
+            this.filter = null;
+        } else {
+            this.filterString = filterString;
+            this.filter = context.createFilter(filterString);
+        }
+    }
+
+    public T getService() {
+        return service.get();
+    }
+
+    public ServiceReference<?> getServiceReference() {
+        return ref.get();
+    }
+
+    public void open() {
+        if (open.compareAndSet(false, true)) {
+            try {
+                String filterString = '(' + Constants.OBJECTCLASS + '=' + className + ')';
+                if (filter != null) filterString = "(&" + filterString + filter + ')';
+                ctx.addServiceListener(this, filterString);
+                findMatchingReference(null);
+            } catch (InvalidSyntaxException e) {
+                // this can never happen. (famous last words :)
+            }
+        }
+    }
+
+    public void serviceChanged(ServiceEvent event) {
+        if (open.get()) {
+            if (event.getType() == ServiceEvent.UNREGISTERING) {
+                ServiceReference<?> deadRef = event.getServiceReference();
+                if (deadRef.equals(ref.get())) {
+                    findMatchingReference(deadRef);
+                }
+            } else if (event.getType() == ServiceEvent.REGISTERED && ref.get() == null) {
+                findMatchingReference(null);
+            }
+        }
+    }
+
+    private void findMatchingReference(ServiceReference<?> original) {
+        try {
+            boolean clear = true;
+            ServiceReference<?>[] refs = ctx.getServiceReferences(className, filterString);
+            if (refs != null && refs.length > 0) {
+                if (refs.length > 1) {
+                    Arrays.sort(refs);
+                }
+                @SuppressWarnings("unchecked")
+                T service = (T) ctx.getService(refs[0]);
+                if (service != null) {
+                    clear = false;
+
+                    // We do the unget out of the lock so we don't exit this class while holding a lock.
+                    if (!update(original, refs[0], service)) {
+                        ctx.ungetService(refs[0]);
+                    }
+                }
+            } else if (original == null) {
+                clear = false;
+            }
+
+            if (clear) {
+                update(original, null, null);
+            }
+        } catch (InvalidSyntaxException e) {
+            // this can never happen. (famous last words :)
+        }
+    }
+
+    private boolean update(ServiceReference<?> deadRef, ServiceReference<?> newRef, T service) {
+        boolean result = false;
+        int foundLostReplaced = -1;
+
+        // Make sure we don't try to get a lock on null
+        Object lock;
+
+        // we have to choose our lock.
+        if (newRef != null) lock = newRef;
+        else if (deadRef != null) lock = deadRef;
+        else lock = this;
+
+        // This lock is here to ensure that no two threads can set the ref and service
+        // at the same time.
+        synchronized (lock) {
+            if (open.get()) {
+                result = this.ref.compareAndSet(deadRef, newRef);
+                if (result) {
+                    this.service.set(service);
+
+                    if (deadRef == null && newRef != null) foundLostReplaced = 0;
+                    if (deadRef != null && newRef == null) foundLostReplaced = 1;
+                    if (deadRef != null && newRef != null) foundLostReplaced = 2;
+                }
+            }
+        }
+
+        if (serviceListener != null) {
+            if (foundLostReplaced == 0) serviceListener.serviceFound();
+            else if (foundLostReplaced == 1) serviceListener.serviceLost();
+            else if (foundLostReplaced == 2) serviceListener.serviceReplaced();
+        }
+
+        return result;
+    }
+
+    public void close() {
+        if (open.compareAndSet(true, false)) {
+            ctx.removeServiceListener(this);
+
+            ServiceReference<?> deadRef;
+            synchronized (this) {
+                deadRef = ref.getAndSet(null);
+                service.set(null);
+            }
+            if (deadRef != null) {
+                serviceListener.serviceLost();
+                ctx.ungetService(deadRef);
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/jline/src/main/java/org/apache/felix/gogo/jline/package-info.java b/jline/src/main/java/org/apache/felix/gogo/jline/package-info.java
new file mode 100644
index 0000000..7a33720
--- /dev/null
+++ b/jline/src/main/java/org/apache/felix/gogo/jline/package-info.java
@@ -0,0 +1,34 @@
+/*
+ * 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.
+ */
+
+@org.osgi.annotation.bundle.Capability(
+    attribute = "implementation.name=gogo.jline",
+    namespace = "org.apache.felix.gogo",
+    name = "shell.implementation",
+    version = "1.0.0"
+)
+@Requirement(
+    effective = "active",
+    namespace = "org.apache.felix.gogo",
+    name = "command.implementation",
+    version = "1.0.0"
+)
+package org.apache.felix.gogo.jline;
+
+import org.osgi.annotation.bundle.Requirement;
diff --git a/jline/src/main/resources/gosh_profile b/jline/src/main/resources/gosh_profile
new file mode 100644
index 0000000..64061d8
--- /dev/null
+++ b/jline/src/main/resources/gosh_profile
@@ -0,0 +1,344 @@
+#
+# 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 \'$'\u001B\\[90m'\'HH:mm:ss) format (new Date) }
+  secondary-prompt-pattern = '%M%P > '
+  # could also be written
+  #  \#rprompt = { ${(qq)$(date +$'\u001B\[90m%T')} }
+
+
+  __option_not_present = {
+      res = true
+      opts = $argv
+      each $opts {
+          arg = $it
+          each ($.commandLine words) {
+              if { ($it toString) equals ($arg toString) } {
+                  res = false
+              }
+          }
+      }
+      $res
+  }
+
+  __load_class = {
+      (($.reader class) classLoader) loadClass $1
+  }
+
+  __set_unset_arguments = {
+      is_setopt = (($.commandLine words) get 0) equals "setopt"
+      enums = ((__load_class 'org.jline.reader.LineReader$Option') enumConstants)
+      candidates = new ArrayList
+      each $enums {
+          name = ${(GL)it/_/-}
+          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.reader.Candidate $name $name (if { $neg } { "unset" } { "set" }) null null null true)
+          }
+      }
+      $candidates
+  }
+
+  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 'wi = ($.commandLine wordIndex); if { %(wi==1) } { __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"
+
+  complete -c gogo:bg -e
+  complete -c gogo:bg -d "Put job in background"
+
+  complete -c gogo:fg -e
+  complete -c gogo:fg -d "Put job in foreground"
+
+  complete -c gogo:jobs -e
+  complete -c gogo:jobs -d "List jobs"
+
+  complete -c gogo:clear -e
+  complete -c gogo:clear -d "Clear screen"
+
+  complete -c gogo:head -e
+  complete -c gogo:head -d "Displays first lines of file"
+  complete -c gogo:head -s n -l lines --description "Print line counts"
+  complete -c gogo:head -s c -l bytes --description "Print byte counts"
+  complete -c gogo:head -a '__files'
+
+  complete -c gogo:tail -e
+  complete -c gogo:tail -d "Displays last lines of file"
+  complete -c gogo:tail -s q -l quiet --description "Suppress headers when printing multiple sources"
+  complete -c gogo:tail -s f -l follow --description "Do not stop at end of file"
+  complete -c gogo:tail -s F -l FOLLOW --description "Follow and check for file renaming or rotation"
+  complete -c gogo:tail -s n -l lines --description "Number of lines to print"
+  complete -c gogo:tail -s c -l bytes --description "Number of bytes to print"
+  complete -c gogo:tail -a '__files'
+
+  complete -c gogo:date -e
+  complete -c gogo:date -d "Display date and time"
+  complete -c gogo:date -s u --description "Use UTC"
+  complete -c gogo:date -s r --description "Print the date represented by 'seconds' since January 1, 1970"
+  complete -c gogo:date -s v --description "Adjust date"
+  complete -c gogo:date -s f --description "Use 'input_fmt' to parse 'new_date'"
+
+  complete -c gogo:wc -e
+  complete -c gogo:wc -d "Word, line, character, and byte count"
+  complete -c gogo:wc -s n -l lines --description "Print line count"
+  complete -c gogo:wc -s c -l bytes --description "Print byte count"
+  complete -c gogo:wc -s m -l chars --description "Print character count"
+  complete -c gogo:wc -s w -l words --description "Print word count"
+  complete -c gogo:wc -a '__files'
+
+  __get_scr_components = {
+    list = [ ]
+    scrref = ($.context getServiceReference org.osgi.service.component.runtime.ServiceComponentRuntime)
+    scr = ($.context getService $scrref)
+    each ($scr getComponentDescriptionDTOs ($.context bundles)) {
+      $list add ((($it getClass) getField "name") get $it)
+    }
+    $.context ungetService $scrref
+    $list
+  }
+  __get_bundles_with_scr_components = {
+    list = [ ]
+    scrref = ($.context getServiceReference org.osgi.service.component.runtime.ServiceComponentRuntime)
+    scr = ($.context getService $scrref)
+    each ($.context bundles) {
+      if { ($scr getComponentDescriptionDTOs $it) isEmpty } { } {
+        $list add ($it symbolicName)
+      }
+    }
+    $.context ungetService $scrref
+    $list
+  }
+
+  complete -c scr:config -e
+  complete -c scr:config -d "Show the current SCR configuration"
+
+  complete -c scr:disable -e
+  complete -c scr:disable -d "Disable an enabled component"
+  complete -c scr:disable -a '__get_scr_components'
+
+  complete -c scr:enable -e
+  complete -c scr:enable -d "Enable an disabled component"
+  complete -c scr:enable -a '__get_scr_components'
+
+  complete -c scr:info -e
+  complete -c scr:info -d "Dump information of a component or component configuration"
+  complete -c scr:info -a '__get_scr_components'
+
+  complete -c scr:list -e
+  complete -c scr:list -d "List component configurations of a specific bundle"
+  complete -c scr:list -a '__get_bundles_with_scr_components'
+
+  # print welcome message
+  __resolve_uri = {
+    uri = $1
+    path = $2
+    if { "$uri" startsWith "jar:" } /* then */ {
+      idx = ("$uri" indexOf "!")
+      p1 = ("$uri" substring 0 $idx)
+      p2 = "!"
+      p3 = (new java.net.URI ("$uri" substring %(idx+1))) resolve $path
+      "$p1$p2$p3"
+    } /* else */ {
+      $uri resolve $path
+    }
+  }
+
+  # print welcome message, unless we're explicitly told not to...
+  if { $.gosh_quiet } { } { cat (new java.net.URL ($0 toURL) motd) }
+} {
+    echo "$0: ERROR: $exception"
+}
+
+# end
diff --git a/jline/src/main/resources/motd b/jline/src/main/resources/motd
new file mode 100644
index 0000000..01954f9
--- /dev/null
+++ b/jline/src/main/resources/motd
@@ -0,0 +1,3 @@
+____________________________
+Welcome to Apache Felix Gogo
+
diff --git a/jline/src/test/java/org/apache/felix/gogo/jline/AbstractParserTest.java b/jline/src/test/java/org/apache/felix/gogo/jline/AbstractParserTest.java
new file mode 100644
index 0000000..a785c2e
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/AbstractParserTest.java
@@ -0,0 +1,75 @@
+/*
+ * 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.FilterInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+import org.apache.felix.gogo.runtime.threadio.ThreadIOImpl;
+import org.junit.After;
+import org.junit.Before;
+
+public abstract class AbstractParserTest {
+
+    private ThreadIOImpl threadIO;
+    private InputStream sin;
+    private PrintStream sout;
+    private PrintStream serr;
+
+    @Before
+    public void setUp() {
+        sin = new NoCloseInputStream(System.in);
+        sout = new NoClosePrintStream(System.out);
+        serr = new NoClosePrintStream(System.err);
+        threadIO = new ThreadIOImpl();
+        threadIO.start();
+    }
+
+    @After
+    public void tearDown() {
+        threadIO.stop();
+    }
+
+    public class Context extends org.apache.felix.gogo.jline.Context {
+        public Context() {
+            super(AbstractParserTest.this.threadIO, sin, sout, serr);
+        }
+    }
+
+    private static class NoCloseInputStream extends FilterInputStream {
+        public NoCloseInputStream(InputStream in) {
+            super(in);
+        }
+        @Override
+        public void close() {
+        }
+    }
+
+    private static class NoClosePrintStream extends PrintStream {
+        public NoClosePrintStream(OutputStream out) {
+            super(out);
+        }
+        @Override
+        public void close() {
+        }
+    }
+
+}
diff --git a/jline/src/test/java/org/apache/felix/gogo/jline/BaseConvertersTest.java b/jline/src/test/java/org/apache/felix/gogo/jline/BaseConvertersTest.java
new file mode 100644
index 0000000..cae7a44
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/BaseConvertersTest.java
@@ -0,0 +1,61 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.gogo.jline;
+
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.command.Function;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+
+public class BaseConvertersTest {
+
+    @Test
+    public void testFunctionProxy() throws Exception {
+        Function function = new Function() {
+            @Override
+            public Object execute(CommandSession session, List<Object> arguments) {
+                return "Hello ";
+            }
+            public String toString() {
+                return "MyFunction";
+            }
+        };
+        MyType myType = (MyType) new BaseConverters().convert(MyType.class, function);
+        assertEquals("MyFunction", myType.toString());
+        assertEquals("Hello ", myType.run(null));
+        assertEquals("World !", myType.hello());
+    }
+
+    @FunctionalInterface
+    public interface MyType {
+
+        String toString();
+
+        Object run(List<Object> args);
+
+        default String hello() {
+            return "World !";
+        }
+
+    }
+
+}
diff --git a/jline/src/test/java/org/apache/felix/gogo/jline/Context.java b/jline/src/test/java/org/apache/felix/gogo/jline/Context.java
new file mode 100644
index 0000000..45040dc
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/Context.java
@@ -0,0 +1,103 @@
+/*
+ * 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.InputStream;
+import java.io.PrintStream;
+import java.nio.file.Path;
+
+import org.apache.felix.gogo.runtime.CommandProcessorImpl;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.threadio.ThreadIO;
+
+public class Context extends CommandProcessorImpl
+{
+    public static final String EMPTY = "";
+    
+    private final CommandSession session;
+
+    public Context(ThreadIO threadio, InputStream in, PrintStream out, PrintStream err)
+    {
+        super(threadio);
+        Shell shell = new Shell(new MyContext(), this);
+        addCommand("gogo", this, "addCommand");
+        addCommand("gogo", this, "removeCommand");
+        addCommand("gogo", this, "eval");
+        register(this, new Builtin(), Builtin.functions);
+        register(this, new Procedural(), Procedural.functions);
+        register(this, new Posix(this), Posix.functions);
+        register(this, shell, Shell.functions);
+        session = createSession(in, out, err);
+    }
+
+    static void register(CommandProcessorImpl processor, Object target, String[] functions) {
+        for (String function : functions) {
+            processor.addCommand("gogo", target, function);
+        }
+    }
+
+    private static class MyContext implements Shell.Context {
+
+        public String getProperty(String name) {
+            return System.getProperty(name);
+        }
+
+        public void exit() {
+            System.exit(0);
+        }
+    }
+
+    public Object execute(CharSequence source) throws Exception
+    {
+        Object result = new Exception();
+        try
+        {
+            return result = session.execute(source);
+        }
+        finally
+        {
+            System.err.println("execute<" + source + "> = ("
+                + (null == result ? "Null" : result.getClass().getSimpleName()) + ")("
+                + result + ")\n");
+        }
+    }
+
+    public void addCommand(String function, Object target)
+    {
+        addCommand("test", target, function);
+    }
+
+    public Object set(String name, Object value)
+    {
+        return session.put(name, value);
+    }
+
+    public Object get(String name)
+    {
+        return session.get(name);
+    }
+
+    public void currentDir(Path path) {
+        session.currentDir(path);
+    }
+
+    public Path currentDir() {
+        return session.currentDir();
+    }
+}
diff --git a/jline/src/test/java/org/apache/felix/gogo/jline/ParserTest.java b/jline/src/test/java/org/apache/felix/gogo/jline/ParserTest.java
new file mode 100644
index 0000000..5d19905
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/ParserTest.java
@@ -0,0 +1,59 @@
+/*
+ * 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 org.jline.reader.CompletingParsedLine;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class ParserTest {
+
+    @Test
+    public void testEscapedWord() {
+        Parser parser = new Parser();
+        CompletingParsedLine line = (CompletingParsedLine) parser.parse("foo second\\ param \"quoted param\"", 15);
+        assertNotNull(line);
+        assertNotNull(line.words());
+        assertEquals("foo second\\ param \"quoted param\"", line.line());
+        assertEquals(15, line.cursor());
+        assertEquals(3, line.words().size());
+        assertEquals("second param", line.word());
+        assertEquals(10, line.wordCursor());
+        assertEquals(11, line.rawWordCursor());
+        assertEquals(13, line.rawWordLength());
+    }
+
+    @Test
+    public void testQuotedWord() {
+        Parser parser = new Parser();
+        CompletingParsedLine line = (CompletingParsedLine) parser.parse("foo second\\ param \"quoted param\"", 20);
+        assertNotNull(line);
+        assertNotNull(line.words());
+        assertEquals("foo second\\ param \"quoted param\"", line.line());
+        assertEquals(20, line.cursor());
+        assertEquals(3, line.words().size());
+        assertEquals("quoted param", line.word());
+        assertEquals(1, line.wordCursor());
+        assertEquals(2, line.rawWordCursor());
+        assertEquals(14, line.rawWordLength());
+    }
+
+}
diff --git a/jline/src/test/java/org/apache/felix/gogo/jline/PosixTest.java b/jline/src/test/java/org/apache/felix/gogo/jline/PosixTest.java
new file mode 100644
index 0000000..6e3034f
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/PosixTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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 org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+
+import static org.junit.Assert.assertEquals;
+
+public class PosixTest extends AbstractParserTest {
+
+    @Test
+    public void testGrepWithColoredInput() throws Exception {
+        Context context = new Context();
+        context.addCommand("echo", new Posix(context));
+        context.addCommand("grep", new Posix(context));
+        context.addCommand("tac", this);
+
+        Object res = context.execute("echo \"  \\u001b[1mbold\\u001b[0m  la\" | grep la | tac");
+        assertEquals("  \u001b[1mbold\u001b[0m  la", res);
+    }
+
+    public String tac() throws IOException {
+        StringWriter sw = new StringWriter();
+        Reader rdr = new InputStreamReader(System.in);
+        char[] buf = new char[1024];
+        int len;
+        while ((len = rdr.read(buf)) >= 0) {
+            sw.write(buf, 0, len);
+        }
+        return sw.toString();
+    }
+}
diff --git a/jline/src/test/java/org/apache/felix/gogo/jline/ShellTest.java b/jline/src/test/java/org/apache/felix/gogo/jline/ShellTest.java
new file mode 100644
index 0000000..74a3127
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/ShellTest.java
@@ -0,0 +1,54 @@
+/*
+ * 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 org.junit.Assert;
+import org.junit.Test;
+
+public class ShellTest extends AbstractParserTest {
+
+    @Test
+    public void testAssignmentWithEcho() throws Exception {
+        Context context = new Context();
+        context.execute("a = \"foo\"");
+        Assert.assertEquals("foo", context.get("a"));
+        context.execute("a = $(echo bar)");
+        Assert.assertEquals("bar", context.get("a"));
+    }
+
+    @Test
+    public void testLoopBreak() throws Exception {
+        Context context = new Context();
+        Object result = context.execute("$(each {1..10} { i = $it; if { %(i >= 5) } { break } ; echo $i })");
+        Assert.assertEquals("1\n2\n3\n4", result);
+    }
+
+    @Test
+    public void testJobIds() throws Exception {
+        Context context = new Context();
+        // TODO: not than in zsh, the same thing is achieved using
+        // TODO:     ${${${(@f)"$(jobs)"}%]*}#*\[}
+//        Object result = context.execute("sleep 1 & sleep 1 & ${${${(f)\"$(jobs)\"}%']*'}#'*\\['}");
+        Object result = context.execute("sleep 1 & sleep 1 & ${${${(f)$(jobs)}%\\]*}#*\\[}");
+        Assert.assertEquals(Arrays.asList("1", "2"), result);
+    }
+
+}
diff --git a/jline/src/test/java/org/apache/felix/gogo/jline/ssh/ShellCommand.java b/jline/src/test/java/org/apache/felix/gogo/jline/ssh/ShellCommand.java
new file mode 100644
index 0000000..736cb4b
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/ssh/ShellCommand.java
@@ -0,0 +1,136 @@
+/*
+ * 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.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;
+    @SuppressWarnings("unused")
+    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) {
+        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) {
+            File scriptFile = new File(scriptFileName);
+            try (Reader 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);
+            }
+            // Ignore
+        }
+    }
+
+}
diff --git a/jline/src/test/java/org/apache/felix/gogo/jline/ssh/ShellCommandFactory.java b/jline/src/test/java/org/apache/felix/gogo/jline/ssh/ShellCommandFactory.java
new file mode 100644
index 0000000..d0a0a45
--- /dev/null
+++ b/jline/src/test/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/jline/src/test/java/org/apache/felix/gogo/jline/ssh/ShellFactoryImpl.java b/jline/src/test/java/org/apache/felix/gogo/jline/ssh/ShellFactoryImpl.java
new file mode 100644
index 0000000..91c40e7
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/ssh/ShellFactoryImpl.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.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.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;
+
+        @SuppressWarnings("unused")
+        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(() -> {
+                    try {
+                        ShellImpl.this.run(env);
+                    } catch (Throwable t) {
+                        t.printStackTrace();
+                    }
+                }).start();
+            } catch (Exception e) {
+                throw (IOException) new IOException("Unable to start shell", e);
+            }
+        }
+
+        public void run(Environment env) {
+            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;
+                        default:
+                    }
+                }
+                terminal.setAttributes(attr);
+                PrintStream pout = new PrintStream(terminal.output());
+                final CommandSession session = processor.createSession(terminal.input(), pout, pout);
+                session.put(Shell.VAR_TERMINAL, terminal);
+                for (Map.Entry<String, String> e : env.getEnv().entrySet()) {
+                    session.put(e.getKey(), e.getValue());
+                }
+                env.addSignalListener(signals -> {
+                    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() {
+                        destroy();
+                    }
+                };
+                new Shell(context, processor).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/jline/src/test/java/org/apache/felix/gogo/jline/ssh/Ssh.java b/jline/src/test/java/org/apache/felix/gogo/jline/ssh/Ssh.java
new file mode 100644
index 0000000..9fa10ae
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/ssh/Ssh.java
@@ -0,0 +1,114 @@
+/*
+ * 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.server.ServerBuilder;
+import org.apache.sshd.server.SshServer;
+import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider;
+import org.apache.sshd.server.scp.ScpCommandFactory;
+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;
+    @SuppressWarnings("unused")
+    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.singletonList(
+                new SftpSubsystemFactory.Builder().build()
+        ));
+        server.setKeyPairProvider(new SimpleGeneratorHostKeyProvider());
+        server.start();
+    }
+
+    private void stop() throws IOException {
+        server.stop();
+    }
+}
diff --git a/jline/src/test/java/org/apache/felix/gogo/jline/telnet/BootException.java b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/BootException.java
new file mode 100644
index 0000000..ee1f053
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/BootException.java
@@ -0,0 +1,74 @@
+/*
+ * 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)
+ */
+@SuppressWarnings("serial")
+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/jline/src/test/java/org/apache/felix/gogo/jline/telnet/Connection.java b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/Connection.java
new file mode 100644
index 0000000..a6c87d7
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/Connection.java
@@ -0,0 +1,255 @@
+/*
+ * 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<>();
+        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) {
+            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/jline/src/test/java/org/apache/felix/gogo/jline/telnet/ConnectionData.java b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/ConnectionData.java
new file mode 100644
index 0000000..48ee8e4
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/ConnectionData.java
@@ -0,0 +1,464 @@
+/*
+ * 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<>(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);
+            switch (country) {
+                case "at":
+                    locale = new Locale("de", "AT");
+                    break;
+                case "de":
+                    locale = new Locale("de", "DE");
+                    break;
+                case "mx":
+                    locale = new Locale("es", "MX");
+                    break;
+                case "es":
+                    locale = new Locale("es", "ES");
+                    break;
+                case "it":
+                    locale = Locale.ITALY;
+                    break;
+                case "fr":
+                    locale = Locale.FRANCE;
+                    break;
+                case "uk":
+                    locale = new Locale("en", "GB");
+                    break;
+                case "arpa":
+                    locale = Locale.US;
+                    break;
+                case "com":
+                    locale = Locale.US;
+                    break;
+                case "edu":
+                    locale = Locale.US;
+                    break;
+                case "gov":
+                    locale = Locale.US;
+                    break;
+                case "org":
+                    locale = Locale.US;
+                    break;
+                case "mil":
+                    locale = Locale.US;
+                    break;
+                default:
+                    //default to english
+                    locale = Locale.ENGLISH;
+                    break;
+            }
+        } catch (Exception ex) {
+            //default to english
+            locale = Locale.ENGLISH;
+        }
+    }//setLocale
+
+}//class ConnectionData
diff --git a/jline/src/test/java/org/apache/felix/gogo/jline/telnet/ConnectionEvent.java b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/ConnectionEvent.java
new file mode 100644
index 0000000..8348f58
--- /dev/null
+++ b/jline/src/test/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/jline/src/test/java/org/apache/felix/gogo/jline/telnet/ConnectionFilter.java b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/ConnectionFilter.java
new file mode 100644
index 0000000..e948166
--- /dev/null
+++ b/jline/src/test/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/jline/src/test/java/org/apache/felix/gogo/jline/telnet/ConnectionListener.java b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/ConnectionListener.java
new file mode 100644
index 0000000..38ed90b
--- /dev/null
+++ b/jline/src/test/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/jline/src/test/java/org/apache/felix/gogo/jline/telnet/ConnectionManager.java b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/ConnectionManager.java
new file mode 100644
index 0000000..d46b0e5
--- /dev/null
+++ b/jline/src/test/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<>();
+        openConnections = Collections.synchronizedList(new ArrayList<>(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<>();
+        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/jline/src/test/java/org/apache/felix/gogo/jline/telnet/PortListener.java b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/PortListener.java
new file mode 100644
index 0000000..1682db0
--- /dev/null
+++ b/jline/src/test/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/jline/src/test/java/org/apache/felix/gogo/jline/telnet/Telnet.java b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/Telnet.java
new file mode 100644
index 0000000..1f3259b
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/Telnet.java
@@ -0,0 +1,203 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.gogo.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) {
+        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);
+                        session.put(Shell.VAR_TERMINAL, terminal);
+                        Context context = new Context() {
+                            @Override
+                            public String getProperty(String name) {
+                                return System.getProperty(name);
+                            }
+                            @Override
+                            public void exit() {
+                                close();
+                            }
+                        };
+                        new Shell(context, processor).gosh(session, new String[]{"--login"});
+                    }
+
+                    @Override
+                    protected void doClose() {
+                        telnetIO.closeOutput();
+                        telnetIO.closeInput();
+                    }
+                };
+            }
+        };
+        portListener = new PortListener("gogo", port, 10);
+        portListener.setConnectionManager(connectionManager);
+        portListener.start();
+    }
+
+    private void stop() {
+        portListener.stop();
+        portListener = null;
+    }
+
+}
diff --git a/jline/src/test/java/org/apache/felix/gogo/jline/telnet/TelnetIO.java b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/TelnetIO.java
new file mode 100644
index 0000000..7015319
--- /dev/null
+++ b/jline/src/test/java/org/apache/felix/gogo/jline/telnet/TelnetIO.java
@@ -0,0 +1,1532 @@
+/*
+ * 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
+    @SuppressWarnings("unused")
+    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);
+
+        crFlag = b == 13;
+    }//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;
+        @SuppressWarnings("unused")
+        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 "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:
+                    DO_SUPGA = !DO_SUPGA;
+                    break;
+                case ECHO:
+                    DO_ECHO = !DO_ECHO;
+                    break;
+                case NAWS:
+                    DO_NAWS = !DO_NAWS;
+                    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
