karaf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gno...@apache.org
Subject [3/6] karaf git commit: [KARAF-4570] Upgrade to JLine 3
Date Tue, 14 Jun 2016 13:23:18 GMT
http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/console/src/test/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImplTest.java
----------------------------------------------------------------------
diff --git a/shell/console/src/test/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImplTest.java b/shell/console/src/test/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImplTest.java
deleted file mode 100644
index 351a89f..0000000
--- a/shell/console/src/test/java/org/apache/karaf/shell/security/impl/SecuredCommandProcessorImplTest.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.karaf.shell.security.impl;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.security.PrivilegedAction;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.security.auth.Subject;
-
-import org.apache.felix.gogo.api.CommandSessionListener;
-import org.apache.felix.service.command.CommandProcessor;
-import org.apache.felix.service.command.Converter;
-import org.apache.felix.service.threadio.ThreadIO;
-import org.apache.karaf.jaas.boot.principal.RolePrincipal;
-import org.easymock.EasyMock;
-import org.easymock.IAnswer;
-import org.junit.Test;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Filter;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-
-public class SecuredCommandProcessorImplTest {
-    @Test
-    public void testCommandProcessor() throws Exception {
-        ThreadIO tio = EasyMock.createMock(ThreadIO.class);
-        EasyMock.replay(tio);
-
-        @SuppressWarnings("unchecked")
-        ServiceReference<ThreadIO> tioRef = EasyMock.createMock(ServiceReference.class);
-        EasyMock.replay(tioRef);
-
-        final BundleContext bc = EasyMock.createMock(BundleContext.class);
-        EasyMock.expect(bc.getServiceReference(ThreadIO.class)).andReturn(tioRef).anyTimes();
-        EasyMock.expect(bc.getService(tioRef)).andReturn(tio).anyTimes();
-        EasyMock.expect(bc.createFilter(EasyMock.isA(String.class))).andAnswer(new IAnswer<Filter>() {
-            @Override
-            public Filter answer() throws Throwable {
-                return FrameworkUtil.createFilter((String) EasyMock.getCurrentArguments()[0]);
-            }
-        }).anyTimes();
-        EasyMock.expect(bc.getServiceReferences((String) EasyMock.anyObject(), (String) EasyMock.anyObject())).andReturn(null).anyTimes();
-
-        // Capture the listeners
-        final Map<String, ServiceListener> listeners = new HashMap<String, ServiceListener>();
-
-        // Here are the expected calls
-        final String commandFilter = "(&(osgi.command.scope=*)(osgi.command.function=*)" +
-                "(|(org.apache.karaf.service.guard.roles=aaabbbccc)(!(org.apache.karaf.service.guard.roles=*))))";
-        expectServiceTracker(bc, commandFilter, listeners);
-        expectServiceTracker(bc, "(objectClass=" + Converter.class.getName() + ")", listeners);
-        expectServiceTracker(bc, "(objectClass=" + CommandSessionListener.class.getName() + ")", listeners);
-        EasyMock.replay(bc);
-
-        Subject subject = new Subject();
-        subject.getPrincipals().add(new RolePrincipal("aaabbbccc"));
-
-        Subject.doAs(subject, new PrivilegedAction<Object>() {
-            @Override
-            public Object run() {
-                MySecuredCommandProcessorImpl scp = new MySecuredCommandProcessorImpl(bc) {};
-
-                assertEquals(3, scp.getCommands().size());
-                assertTrue(scp.getCommands().contains("osgi:addcommand"));
-                assertTrue(scp.getCommands().contains("osgi:removecommand"));
-                assertTrue(scp.getCommands().contains("osgi:eval"));
-                assertEquals(1, scp.getConstants().size());
-                assertEquals(bc, scp.getConstants().get(".context"));
-
-                // Now let's make a command appear...
-                ServiceListener commandListener = listeners.get(commandFilter);
-
-                ServiceReference<?> cdRef = EasyMock.createMock(ServiceReference.class);
-                EasyMock.expect(cdRef.getProperty(CommandProcessor.COMMAND_SCOPE)).andReturn("foo");
-                EasyMock.expect(cdRef.getProperty(CommandProcessor.COMMAND_FUNCTION)).andReturn("bar");
-                EasyMock.replay(cdRef);
-
-                ServiceEvent event = new ServiceEvent(ServiceEvent.REGISTERED, cdRef);
-                commandListener.serviceChanged(event);
-                assertEquals(4, scp.getCommands().size());
-                assertTrue(scp.getCommands().contains("foo:bar"));
-
-                ServiceReference<?> cd2Ref = EasyMock.createMock(ServiceReference.class);
-                EasyMock.expect(cd2Ref.getProperty(CommandProcessor.COMMAND_SCOPE)).andReturn("xxx");
-                EasyMock.expect(cd2Ref.getProperty(CommandProcessor.COMMAND_FUNCTION)).andReturn(
-                        new String[] {"aaa", "bbb"});
-                EasyMock.replay(cd2Ref);
-
-                ServiceEvent event2 = new ServiceEvent(ServiceEvent.REGISTERED, cd2Ref);
-                commandListener.serviceChanged(event2);
-                assertEquals(6, scp.getCommands().size());
-                assertTrue(scp.getCommands().contains("xxx:aaa"));
-                assertTrue(scp.getCommands().contains("xxx:bbb"));
-
-                return null;
-            }
-        });
-    }
-
-    void expectServiceTracker(final BundleContext bc, final String expectedFilter, final Map<String, ServiceListener> listeners) throws InvalidSyntaxException {
-        bc.addServiceListener(EasyMock.isA(ServiceListener.class), EasyMock.eq(expectedFilter));
-        EasyMock.expectLastCall().andAnswer(new IAnswer<Object>() {
-            @Override
-            public Object answer() throws Throwable {
-                listeners.put(expectedFilter, (ServiceListener) EasyMock.getCurrentArguments()[0]);
-                return null;
-            }
-        }).once();
-    }
-
-    // Subclass to provide access to some protected members
-    static class MySecuredCommandProcessorImpl extends SecuredCommandProcessorImpl {
-        public MySecuredCommandProcessorImpl(BundleContext bc) {
-            super(bc);
-        }
-
-        Map<String, Object> getConstants() {
-            return constants;
-        }
-    };
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/pom.xml
----------------------------------------------------------------------
diff --git a/shell/core/pom.xml b/shell/core/pom.xml
index 9ac3f14..f113baa 100644
--- a/shell/core/pom.xml
+++ b/shell/core/pom.xml
@@ -69,6 +69,11 @@
         </dependency>
         <dependency>
             <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.gogo.jline</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.utils</artifactId>
             <scope>provided</scope>
         </dependency>
@@ -131,6 +136,8 @@
                         <Import-Package>
                             org.osgi.service.event;resolution:=optional,
                             org.apache.karaf.branding;resolution:=optional,
+                            !org.apache.felix.gogo.jline*,
+                            !org.apache.sshd.*,
                             *
                         </Import-Package>
                         <Export-Package>
@@ -147,6 +154,7 @@
                             org.apache.felix.utils.extender,
                             org.apache.felix.utils.manifest,
                             org.apache.felix.gogo.api,
+                            org.apache.felix.gogo.jline,
                             org.apache.felix.gogo.runtime,
                             org.apache.felix.gogo.runtime.threadio,
                             org.apache.felix.service.command,

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/api/console/Candidate.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/api/console/Candidate.java b/shell/core/src/main/java/org/apache/karaf/shell/api/console/Candidate.java
new file mode 100644
index 0000000..c882566
--- /dev/null
+++ b/shell/core/src/main/java/org/apache/karaf/shell/api/console/Candidate.java
@@ -0,0 +1,78 @@
+/*
+ * 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.karaf.shell.api.console;
+
+import java.util.Objects;
+
+public class Candidate implements Comparable<Candidate> {
+
+    private final String value;
+    private final String displ;
+    private final String group;
+    private final String descr;
+    private final String suffix;
+    private final String key;
+    private final boolean complete;
+
+    public Candidate(String value) {
+        this(value, value, null, null, null, null, true);
+    }
+
+    public Candidate(String value, String displ, String group, String descr, String suffix, String key, boolean complete) {
+        Objects.requireNonNull(value);
+        this.value = value;
+        this.displ = displ;
+        this.group = group;
+        this.descr = descr;
+        this.suffix = suffix;
+        this.key = key;
+        this.complete = complete;
+    }
+
+    public String value() {
+        return value;
+    }
+
+    public String displ() {
+        return displ;
+    }
+
+    public String group() {
+        return group;
+    }
+
+    public String descr() {
+        return descr;
+    }
+
+    public String suffix() {
+        return suffix;
+    }
+
+    public String key() {
+        return key;
+    }
+
+    public boolean complete() {
+        return complete;
+    }
+
+    @Override
+    public int compareTo(Candidate o) {
+        return value.compareTo(o.value);
+    }
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/api/console/Completer.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/api/console/Completer.java b/shell/core/src/main/java/org/apache/karaf/shell/api/console/Completer.java
index 4f9f3d1..527f0db 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/api/console/Completer.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/api/console/Completer.java
@@ -18,6 +18,7 @@
  */
 package org.apache.karaf.shell.api.console;
 
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -35,4 +36,11 @@ public interface Completer {
      */
     int complete(Session session, CommandLine commandLine, List<String> candidates);
 
+    default void completeCandidates(Session session, CommandLine commandLine, List<Candidate> candidates) {
+        List<String> strings = new ArrayList<>();
+        complete(session, commandLine, strings);
+        for (String string : strings) {
+            candidates.add(new Candidate(string));
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/api/console/Session.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/api/console/Session.java b/shell/core/src/main/java/org/apache/karaf/shell/api/console/Session.java
index 4150ead..b9b549f 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/api/console/Session.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/api/console/Session.java
@@ -18,6 +18,7 @@
  */
 package org.apache.karaf.shell.api.console;
 
+import java.io.Closeable;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintStream;
@@ -35,7 +36,7 @@ import java.io.PrintStream;
  *     <li>{@link Terminal}</li>
  * </ul>
  */
-public interface Session extends Runnable {
+public interface Session extends Runnable, Closeable {
 
     //
     // Session properties

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ActionCommand.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ActionCommand.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ActionCommand.java
index ac4be9f..0b815f6 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ActionCommand.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ActionCommand.java
@@ -23,6 +23,7 @@ import java.util.List;
 import org.apache.karaf.shell.api.action.Action;
 import org.apache.karaf.shell.api.action.Command;
 import org.apache.karaf.shell.api.action.Parsing;
+import org.apache.karaf.shell.api.console.Candidate;
 import org.apache.karaf.shell.api.console.CommandLine;
 import org.apache.karaf.shell.api.console.Completer;
 import org.apache.karaf.shell.api.console.Parser;
@@ -115,6 +116,14 @@ public class ActionCommand implements org.apache.karaf.shell.api.console.Command
             }
             return -1;
         }
+
+        @Override
+        public void completeCandidates(Session session, CommandLine commandLine, List<Candidate> candidates) {
+            Object service = session.getRegistry().getService(clazz);
+            if (service instanceof Completer) {
+                ((Completer) service).completeCandidates(session, commandLine, candidates);
+            }
+        }
     }
 
     public static class DelayedParser implements Parser {

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ArgumentCompleter.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ArgumentCompleter.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ArgumentCompleter.java
index c766c24..201212a 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ArgumentCompleter.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/action/command/ArgumentCompleter.java
@@ -34,6 +34,7 @@ import org.apache.karaf.shell.api.action.Argument;
 import org.apache.karaf.shell.api.action.Command;
 import org.apache.karaf.shell.api.action.Completion;
 import org.apache.karaf.shell.api.action.Option;
+import org.apache.karaf.shell.api.console.Candidate;
 import org.apache.karaf.shell.api.console.CommandLine;
 import org.apache.karaf.shell.api.console.Completer;
 import org.apache.karaf.shell.api.console.Session;
@@ -51,8 +52,8 @@ public class ArgumentCompleter implements Completer {
     private static final Logger LOGGER = LoggerFactory.getLogger(ArgumentCompleter.class);
 
     final ActionCommand command;
-    final Completer commandCompleter;
-    final Completer optionsCompleter;
+    final CandidateCompleter commandCompleter;
+    final CandidateCompleter optionsCompleter;
     final List<Completer> argsCompleters;
     final Map<String, Completer> optionalCompleters;
     final Map<Option, Field> fields = new HashMap<>();
@@ -66,7 +67,10 @@ public class ArgumentCompleter implements Completer {
         // Command name completer
         Command cmd = actionClass.getAnnotation(Command.class);
         String[] names = scoped || Session.SCOPE_GLOBAL.equals(cmd.scope()) ? new String[] { cmd.name() } : new String[] { cmd.name(), cmd.scope() + ":" + cmd.name() };
-        commandCompleter = new StringsCompleter(names);
+        commandCompleter = new CandidateCompleter();
+        for (String name : names) {
+            commandCompleter.addCandidate(name, cmd.description(), actionClass.getName());
+        }
         // Build options completer
         for (Class<?> type = actionClass; type != null; type = type.getSuperclass()) {
             for (Field field : type.getDeclaredFields()) {
@@ -94,8 +98,15 @@ public class ArgumentCompleter implements Completer {
         }
         options.put(HelpOption.HELP.name(), HelpOption.HELP);
 
+        optionsCompleter = new CandidateCompleter();
+        for (Map.Entry<String, Option> entry : options.entrySet()) {
+            optionsCompleter.addCandidate(
+                    entry.getKey(),
+                    entry.getValue().description(),
+                    actionClass.getName() + "/" + entry.getValue().name());
+        }
+
         argsCompleters = new ArrayList<>();
-        optionsCompleter = new StringsCompleter(options.keySet());
 
         boolean multi = false;
         for (int key = 0; key < arguments.size(); key++) {
@@ -187,7 +198,17 @@ public class ArgumentCompleter implements Completer {
         return completer;
     }
 
-    public int complete(Session session, final CommandLine list, final List<String> candidates) {
+    public int complete(Session session, final CommandLine commandLine, final List<String> candidates) {
+        List<Candidate> cands = new ArrayList<>();
+        completeCandidates(session, commandLine, cands);
+        for (Candidate cand : cands) {
+            candidates.add(cand.value());
+        }
+        return 0;
+    }
+
+    @Override
+    public void completeCandidates(Session session, final CommandLine list, List<Candidate> candidates) {
         int argIndex = list.getCursorArgumentIndex();
 
         Completer comp = null;
@@ -197,11 +218,11 @@ public class ArgumentCompleter implements Completer {
         if (index < argIndex) {
             // Verify scope
             if (!Session.SCOPE_GLOBAL.equals(command.getScope()) && !session.resolveCommand(args[index]).equals(command.getScope() + ":" + command.getName())) {
-                return -1;
+                return;
             }
             // Verify command name
             if (!verifyCompleter(session, commandCompleter, args[index])) {
-                return -1;
+                return;
             }
             index++;
         } else {
@@ -211,11 +232,11 @@ public class ArgumentCompleter implements Completer {
         if (comp == null) {
             while (index < argIndex && args[index].startsWith("-")) {
                 if (!verifyCompleter(session, optionsCompleter, args[index])) {
-                    return -1;
+                    return;
                 }
                 Option option = options.get(args[index]);
                 if (option == null) {
-                    return -1;
+                    return;
                 }
                 Field field = fields.get(option);
                 if (field != null && field.getType() != boolean.class && field.getType() != Boolean.class) {
@@ -229,7 +250,7 @@ public class ArgumentCompleter implements Completer {
                 comp = optionsCompleter;
             }
         }
-        //Now check for if last Option has a completer
+        // Now check for if last Option has a completer
         int lastAgurmentIndex = argIndex - 1;
         if (lastAgurmentIndex >= 1) {
             Option lastOption = options.get(args[lastAgurmentIndex]);
@@ -265,7 +286,7 @@ public class ArgumentCompleter implements Completer {
             while (index < argIndex) {
                 Completer sub = argsCompleters.get(indexArg >= argsCompleters.size() ? argsCompleters.size() - 1 : indexArg);
                 if (!verifyCompleter(session, sub, args[index])) {
-                    return -1;
+                    return;
                 }
                 index++;
                 indexArg++;
@@ -273,11 +294,13 @@ public class ArgumentCompleter implements Completer {
             comp = argsCompleters.get(indexArg >= argsCompleters.size() ? argsCompleters.size() - 1 : indexArg);
         }
 
-        int pos = comp.complete(session, list, candidates);
+        comp.completeCandidates(session, list, candidates);
 
+        /* TODO:JLINE
         if (pos == -1) {
             return -1;
         }
+        */
 
         /**
          *  Special case: when completing in the middle of a line, and the
@@ -290,6 +313,7 @@ public class ArgumentCompleter implements Completer {
          *  and hit TAB, we want "foo bar" instead of "foo  bar".
          */
 
+        /* TODO:JLINE
         String buffer = list.getBuffer();
         int cursor = list.getBufferPosition();
         if ((buffer != null) && (cursor != buffer.length()) && isDelimiter(buffer, cursor)) {
@@ -306,11 +330,13 @@ public class ArgumentCompleter implements Completer {
         }
 
         return pos;
+        */
     }
 
     protected boolean verifyCompleter(Session session, Completer completer, String argument) {
-        List<String> candidates = new ArrayList<>();
-        return completer.complete(session, new ArgumentCommandLine(argument, argument.length()), candidates) != -1 && !candidates.isEmpty();
+        List<Candidate> candidates = new ArrayList<>();
+        completer.completeCandidates(session, new ArgumentCommandLine(argument, argument.length()), candidates);
+        return !candidates.isEmpty();
     }
 
     /**
@@ -343,4 +369,35 @@ public class ArgumentCompleter implements Completer {
         return Character.isWhitespace(buffer.charAt(pos));
     }
 
+    static class CandidateCompleter implements Completer {
+
+        private final List<Candidate> candidates = new ArrayList<>();
+
+        public void addCandidate(String value, String desc) {
+            addCandidate(value, desc, null);
+        }
+
+        public void addCandidate(String value, String desc, String key) {
+            if (desc.endsWith(".")) {
+                desc = desc.substring(0, desc.length() - 1);
+            }
+            candidates.add(new Candidate(value, value, null, desc, null, key, true));
+        }
+
+        @Override
+        public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+            List<Candidate> cands = new ArrayList<>();
+            completeCandidates(session, commandLine, cands);
+            for (Candidate cand : cands) {
+                candidates.add(cand.value());
+            }
+            return 0;
+        }
+
+        @Override
+        public void completeCandidates(Session session, CommandLine commandLine, List<Candidate> candidates) {
+            candidates.addAll(this.candidates);
+        }
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CommandsCompleter.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CommandsCompleter.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CommandsCompleter.java
index 66d8f6a4..8a878d3 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CommandsCompleter.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CommandsCompleter.java
@@ -30,36 +30,53 @@ import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
 
+import org.apache.karaf.shell.api.console.Candidate;
 import org.apache.karaf.shell.api.console.Command;
 import org.apache.karaf.shell.api.console.CommandLine;
 import org.apache.karaf.shell.api.console.Completer;
 import org.apache.karaf.shell.api.console.Session;
 import org.apache.karaf.shell.api.console.SessionFactory;
-import org.apache.karaf.shell.support.completers.AggregateCompleter;
 import org.apache.karaf.shell.support.completers.ArgumentCommandLine;
 import org.apache.karaf.shell.support.completers.StringsCompleter;
+import org.jline.reader.LineReader;
+import org.jline.reader.ParsedLine;
 
 /**
  * Overall command line completer.
  */
-public class CommandsCompleter extends org.apache.karaf.shell.support.completers.CommandsCompleter {
+public class CommandsCompleter implements org.jline.reader.Completer {
 
     private final SessionFactory factory;
-    private final Map<String, Completer> globalCompleters = new HashMap<String, Completer>();
-    private final Map<String, Completer> localCompleters = new HashMap<String, Completer>();
+    private final Session session;
+    private final Map<String, Completer> globalCompleters = new HashMap<>();
+    private final Map<String, Completer> localCompleters = new HashMap<>();
     private final Completer aliasesCompleter = new SimpleCommandCompleter() {
         @Override
         protected Collection<String> getNames(Session session) {
             return getAliases(session);
         }
     };
-    private final List<Command> commands = new ArrayList<Command>();
+    private final List<Command> commands = new ArrayList<>();
 
-    public CommandsCompleter(SessionFactory factory) {
+    public CommandsCompleter(SessionFactory factory, Session session) {
         this.factory = factory;
+        this.session = session;
     }
 
-    public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+    @Override
+    public void complete(LineReader reader, ParsedLine line, List<org.jline.reader.Candidate> candidates) {
+        CommandLine commandLine = new CommandLineImpl(line);
+        List<Candidate> cands = new ArrayList<>();
+        completeCandidates(session, commandLine, cands);
+        for (Candidate cand : cands) {
+            candidates.add(new org.jline.reader.Candidate(
+                    cand.value(), cand.displ(), cand.group(),
+                    cand.descr(), cand.suffix(), cand.key(),
+                    cand.complete()));
+        }
+    }
+
+    public void completeCandidates(Session session, CommandLine commandLine, List<Candidate> candidates) {
         Map<String, Completer>[] allCompleters = checkData();
 
         List<String> scopes = getCurrentScopes(session);
@@ -73,7 +90,7 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers
             if (subShell.isEmpty()) {
                 subShell = Session.SCOPE_GLOBAL;
             }
-            List<Completer> completers = new ArrayList<Completer>();
+            List<Completer> completers = new ArrayList<>();
             for (String name : allCompleters[1].keySet()) {
                 if (name.startsWith(subShell + ":")) {
                     completers.add(allCompleters[1].get(name));
@@ -82,46 +99,50 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers
             if (!subShell.equals(Session.SCOPE_GLOBAL)) {
                 completers.add(new StringsCompleter(new String[] { "exit" }));
             }
-            int res = new AggregateCompleter(completers).complete(session, commandLine, candidates);
-            Collections.sort(candidates);
-            return res;
+            completers.forEach(c -> c.completeCandidates(session, commandLine, candidates));
+            return;
         }
 
         // FIRST mode
         if (Session.COMPLETION_MODE_FIRST.equalsIgnoreCase(completion)) {
             if (!subShell.isEmpty()) {
-                List<Completer> completers = new ArrayList<Completer>();
+                List<Completer> completers = new ArrayList<>();
                 for (String name : allCompleters[1].keySet()) {
                     if (name.startsWith(subShell + ":")) {
                         completers.add(allCompleters[1].get(name));
                     }
                 }
-                int res = new AggregateCompleter(completers).complete(session, commandLine, candidates);
+                completers.forEach(c -> c.completeCandidates(session, commandLine, candidates));
                 if (!candidates.isEmpty()) {
-                    Collections.sort(candidates);
-                    return res;
+                    return;
                 }
             }
-            List<Completer> compl = new ArrayList<Completer>();
+            List<Completer> compl = new ArrayList<>();
             compl.add(aliasesCompleter);
             compl.addAll(allCompleters[0].values());
-            int res = new AggregateCompleter(compl).complete(session, commandLine, candidates);
-            Collections.sort(candidates);
-            return res;
+            compl.forEach(c -> c.completeCandidates(session, commandLine, candidates));
+            return;
         }
 
-        List<Completer> compl = new ArrayList<Completer>();
+        List<Completer> compl = new ArrayList<>();
         compl.add(aliasesCompleter);
         compl.addAll(allCompleters[0].values());
-        int res = new AggregateCompleter(compl).complete(session, commandLine, candidates);
-        Collections.sort(candidates);
-        return res;
+        compl.forEach(c -> c.completeCandidates(session, commandLine, candidates));
+    }
+
+    public int complete(Session session, CommandLine commandLine, List<String> candidates) {
+        List<Candidate> cands = new ArrayList<>();
+        completeCandidates(session, commandLine, cands);
+        for (Candidate cand : cands) {
+            candidates.add(cand.value());
+        }
+        return 0;
     }
 
     protected void sort(Map<String, Completer>[] completers, List<String> scopes) {
         ScopeComparator comparator = new ScopeComparator(scopes);
         for (int i = 0; i < completers.length; i++) {
-            Map<String, Completer> map = new TreeMap<String, Completer>(comparator);
+            Map<String, Completer> map = new TreeMap<>(comparator);
             map.putAll(completers[i]);
             completers[i] = map;
         }
@@ -186,11 +207,6 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers
         return completion;
     }
 
-    protected String stripScope(String name) {
-        int index = name.indexOf(":");
-        return index > 0 ? name.substring(index + 1) : name;
-    }
-
     @SuppressWarnings("unchecked")
     protected Map<String, Completer>[] checkData() {
         // Copy the set to avoid concurrent modification exceptions
@@ -203,8 +219,8 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers
         }
         if (update) {
             // get command aliases
-            Map<String, Completer> global = new HashMap<String, Completer>();
-            Map<String, Completer> local = new HashMap<String, Completer>();
+            Map<String, Completer> global = new HashMap<>();
+            Map<String, Completer> local = new HashMap<>();
 
             // add argument completers for each command
             for (Command command : commands) {
@@ -213,13 +229,13 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers
                 Completer cl = command.getCompleter(true);
                 if (cg == null) {
                     if (Session.SCOPE_GLOBAL.equals(command.getScope())) {
-                        cg = new FixedSimpleCommandCompleter(Arrays.asList(command.getName()));
+                        cg = new FixedSimpleCommandCompleter(Collections.singletonList(command.getName()));
                     } else {
                         cg = new FixedSimpleCommandCompleter(Arrays.asList(key, command.getName()));
                     }
                 }
                 if (cl == null) {
-                    cl = new FixedSimpleCommandCompleter(Arrays.asList(command.getName()));
+                    cl = new FixedSimpleCommandCompleter(Collections.singletonList(command.getName()));
                 }
                 global.put(key, cg);
                 local.put(key, cl);
@@ -236,8 +252,8 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers
         }
         synchronized (this) {
             return new Map[] {
-                    new HashMap<String, Completer>(this.globalCompleters),
-                    new HashMap<String, Completer>(this.localCompleters)
+                    new HashMap<>(this.globalCompleters),
+                    new HashMap<>(this.localCompleters)
             };
         }
     }
@@ -250,7 +266,7 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers
     @SuppressWarnings("unchecked")
     private Set<String> getAliases(Session session) {
         Set<String> vars = ((Set<String>) session.get(null));
-        Set<String> aliases = new HashSet<String>();
+        Set<String> aliases = new HashSet<>();
         for (String var : vars) {
             Object content = session.get(var);
             if (content != null && "org.apache.felix.gogo.runtime.Closure".equals(content.getClass().getName())) {
@@ -282,7 +298,7 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers
         protected abstract Collection<String> getNames(Session session);
 
         private boolean verifyCompleter(Session session, Completer completer, String argument) {
-            List<String> candidates = new ArrayList<String>();
+            List<String> candidates = new ArrayList<>();
             return completer.complete(session, new ArgumentCommandLine(argument, argument.length()), candidates) != -1 && !candidates.isEmpty();
         }
 
@@ -302,5 +318,43 @@ public class CommandsCompleter extends org.apache.karaf.shell.support.completers
         }
     }
 
+    private static class CommandLineImpl implements CommandLine {
+        private final ParsedLine line;
+
+        public CommandLineImpl(ParsedLine line) {
+            this.line = line;
+        }
+
+        @Override
+        public int getCursorArgumentIndex() {
+            return line.wordIndex();
+        }
+
+        @Override
+        public String getCursorArgument() {
+            return line.word();
+        }
+
+        @Override
+        public int getArgumentPosition() {
+            return line.wordCursor();
+        }
+
+        @Override
+        public String[] getArguments() {
+            return line.words().toArray(new String[line.words().size()]);
+        }
+
+        @Override
+        public int getBufferPosition() {
+            return line.cursor();
+        }
+
+        @Override
+        public String getBuffer() {
+            return line.line();
+        }
+    }
+
 }
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CompleterAsCompletor.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CompleterAsCompletor.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CompleterAsCompletor.java
deleted file mode 100644
index f1e87c8..0000000
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/CompleterAsCompletor.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.karaf.shell.impl.console;
-
-import java.util.List;
-import java.util.concurrent.atomic.AtomicInteger;
-
-import org.apache.karaf.shell.api.console.CommandLine;
-import org.apache.karaf.shell.api.console.Completer;
-import org.apache.karaf.shell.api.console.Session;
-import org.apache.karaf.shell.impl.console.parsing.CommandLineParser;
-
-public class CompleterAsCompletor implements jline.console.completer.Completer {
-
-    private final Session session;
-    private final Completer completer;
-
-    public CompleterAsCompletor(Session session, Completer completer) {
-        this.session = session;
-        this.completer = completer;
-    }
-
-    @SuppressWarnings("unchecked")
-	public int complete(String buffer, int cursor, @SuppressWarnings("rawtypes") List candidates) {
-        AtomicInteger begOfLine = new AtomicInteger();
-        CommandLine cmdLine = CommandLineParser.buildCommandLine(session, buffer, cursor, begOfLine);
-        int res = completer.complete(session, cmdLine, candidates);
-        if (res >= 0) {
-            return res + begOfLine.get();
-        } else {
-            return res;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/console/ConsoleSessionImpl.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/ConsoleSessionImpl.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/ConsoleSessionImpl.java
index 2925346..413f2af 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/ConsoleSessionImpl.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/ConsoleSessionImpl.java
@@ -18,36 +18,26 @@
  */
 package org.apache.karaf.shell.impl.console;
 
-import java.io.CharArrayWriter;
-import java.io.Closeable;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.InterruptedIOException;
 import java.io.PrintStream;
-import java.io.Reader;
 import java.lang.management.ManagementFactory;
+import java.nio.file.Files;
+import java.nio.file.Paths;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import jline.UnsupportedTerminal;
-import jline.console.ConsoleReader;
-import jline.console.history.MemoryHistory;
-import jline.console.history.PersistentHistory;
 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.Function;
 import org.apache.felix.service.threadio.ThreadIO;
 import org.apache.karaf.shell.api.console.Command;
-import org.apache.karaf.shell.api.console.Completer;
 import org.apache.karaf.shell.api.console.History;
 import org.apache.karaf.shell.api.console.Registry;
 import org.apache.karaf.shell.api.console.Session;
@@ -58,6 +48,12 @@ import org.apache.karaf.shell.support.ShellUtil;
 import org.apache.karaf.shell.support.completers.FileCompleter;
 import org.apache.karaf.shell.support.completers.FileOrUriCompleter;
 import org.apache.karaf.shell.support.completers.UriCompleter;
+import org.jline.reader.EndOfFileException;
+import org.jline.reader.UserInterruptException;
+import org.jline.reader.impl.LineReaderImpl;
+import org.jline.reader.impl.history.history.FileHistory;
+import org.jline.reader.impl.history.history.MemoryHistory;
+import org.jline.terminal.impl.DumbTerminal;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -71,11 +67,7 @@ public class ConsoleSessionImpl implements Session {
     private static final Logger LOGGER = LoggerFactory.getLogger(ConsoleSessionImpl.class);
 
     // Input stream
-    final BlockingQueue<Integer> queue = new ArrayBlockingQueue<Integer>(1024);
-    final ConsoleInputStream console = new ConsoleInputStream();
-    final Pipe pipe = new Pipe();
     volatile boolean running;
-    volatile boolean eof;
 
     final SessionFactory factory;
     final ThreadIO threadIO;
@@ -87,10 +79,10 @@ public class ConsoleSessionImpl implements Session {
     final CommandSession session;
     final Registry registry;
     final Terminal terminal;
+    final org.jline.terminal.Terminal jlineTerminal;
     final History history;
-    final ConsoleReader reader;
+    final LineReaderImpl reader;
 
-    private boolean interrupt;
     private Thread thread;
 
     public ConsoleSessionImpl(SessionFactory factory,
@@ -111,16 +103,28 @@ public class ConsoleSessionImpl implements Session {
         this.closeCallback = closeCallback;
 
         // Terminal
-        terminal = term == null ? new JLineTerminal(new UnsupportedTerminal(), "dumb") : term;
+        if (term instanceof org.jline.terminal.Terminal) {
+            terminal = term;
+            jlineTerminal = (org.jline.terminal.Terminal) term;
+        } else if (term != null) {
+            terminal = term;
+//            jlineTerminal = new KarafTerminal(term);
+            // TODO:JLINE
+            throw new UnsupportedOperationException();
+        } else {
+            try {
+                jlineTerminal = new DumbTerminal(in, out);
+                terminal = new JLineTerminal(jlineTerminal);
+            } catch (IOException e) {
+                throw new RuntimeException("Unable to create terminal", e);
+            }
+        }
 
         // Console reader
         try {
-            System.setProperty("jline.sigcont", "true");
-            reader = new ConsoleReader(null,
-                    in != null ? console : null,
-                    out,
-                    terminal instanceof JLineTerminal ? ((JLineTerminal) terminal).getTerminal() : new KarafTerminal(terminal),
-                    encoding);
+            reader = new LineReaderImpl(
+                    jlineTerminal,
+                    "karaf");
         } catch (IOException e) {
             throw new RuntimeException("Error opening console reader", e);
         }
@@ -129,7 +133,7 @@ public class ConsoleSessionImpl implements Session {
         final File file = getHistoryFile();
         try {
             file.getParentFile().mkdirs();
-            reader.setHistory(new KarafFileHistory(file));
+            reader.setHistory(new FileHistory(file));
         } catch (Exception e) {
             LOGGER.error("Can not read history from file " + file + ". Using in memory history", e);
         }
@@ -150,8 +154,8 @@ public class ConsoleSessionImpl implements Session {
         registry.register(history);
 
         // Completers
-        Completer completer = new CommandsCompleter(factory);
-        reader.addCompleter(new CompleterAsCompletor(this, completer));
+        CommandsCompleter completer = new CommandsCompleter(factory, this);
+        reader.setCompleter(completer);
         registry.register(completer);
         registry.register(new CommandNamesCompleter());
         registry.register(new FileCompleter());
@@ -159,7 +163,9 @@ public class ConsoleSessionImpl implements Session {
         registry.register(new FileOrUriCompleter());
 
         // Session
-        session = processor.createSession(in != null ? console : null, out, err);
+        session = processor.createSession(jlineTerminal.input(),
+                                          jlineTerminal.output(),
+                                          jlineTerminal.output());
         Properties sysProps = System.getProperties();
         for (Object key : sysProps.keySet()) {
             session.put(key.toString(), sysProps.get(key));
@@ -175,17 +181,14 @@ public class ConsoleSessionImpl implements Session {
         session.put("USER", ShellUtil.getCurrentUserName());
         session.put("TERM", terminal.getType());
         session.put("APPLICATION", System.getProperty("karaf.name", "root"));
-        session.put("#LINES", new Function() {
-            public Object execute(CommandSession session, List<Object> arguments) throws Exception {
-                return Integer.toString(terminal.getHeight());
-            }
-        });
-        session.put("#COLUMNS", new Function() {
-            public Object execute(CommandSession session, List<Object> arguments) throws Exception {
-                return Integer.toString(terminal.getWidth());
-            }
-        });
+        session.put("#LINES", (Function) (session, arguments) -> Integer.toString(terminal.getHeight()));
+        session.put("#COLUMNS", (Function) (session, arguments) -> Integer.toString(terminal.getWidth()));
         session.put("pid", getPid());
+        session.currentDir(null);
+
+        reader.setHighlighter(new org.apache.felix.gogo.jline.Highlighter(session));
+        reader.setParser(new org.apache.felix.gogo.jline.Parser());
+
     }
 
     /**
@@ -221,27 +224,24 @@ public class ConsoleSessionImpl implements Session {
         if (!running) {
             return;
         }
-        out.println();
-        if (reader.getHistory() instanceof PersistentHistory) {
-            try {
-                ((PersistentHistory) reader.getHistory()).flush();
-            } catch (IOException e) {
-                // ignore
-            }
+//        out.println();
+        try {
+            reader.getHistory().flush();
+        } catch (IOException e) {
+            // ignore
         }
+
         running = false;
-        pipe.interrupt();
         if (thread != Thread.currentThread()) {
             thread.interrupt();
         }
-        reader.shutdown();
         if (closeCallback != null) {
             closeCallback.run();
         }
-        if (terminal instanceof Closeable) {
+        if (terminal instanceof AutoCloseable) {
             try {
-                ((Closeable) terminal).close();
-            } catch (IOException e) {
+                ((AutoCloseable) terminal).close();
+            } catch (Exception e) {
                 // Ignore
             }
         }
@@ -254,7 +254,6 @@ public class ConsoleSessionImpl implements Session {
             threadIO.setStreams(session.getKeyboard(), out, err);
             thread = Thread.currentThread();
             running = true;
-            pipe.start();
             Properties brandingProps = Branding.loadBrandingProperties(terminal);
             welcome(brandingProps);
             setSessionProperties(brandingProps);
@@ -262,20 +261,15 @@ public class ConsoleSessionImpl implements Session {
             executeScript(scriptFileName);
             while (running) {
                 try {
-                    String command = readAndParseCommand();
-                    if (command == null) {
-                        break;
-                    }
-                    //session.getConsole().println("Executing: " + line);
+                    String command = reader.readLine(getPrompt());
                     Object result = session.execute(command);
                     if (result != null) {
                         session.getConsole().println(session.format(result, Converter.INSPECT));
                     }
-                } catch (InterruptedIOException e) {
-                    //System.err.println("^C");
-                    // TODO: interrupt current thread
-                } catch (InterruptedException e) {
-                    //interrupt current thread
+                } catch (UserInterruptException e) {
+                    // Ignore, loop again
+                } catch (EndOfFileException e) {
+                    break;
                 } catch (Throwable t) {
                     ShellUtil.logException(this, t);
                 }
@@ -335,12 +329,7 @@ public class ConsoleSessionImpl implements Session {
 
     @Override
     public String readLine(String prompt, Character mask) throws IOException {
-        reader.setHistoryEnabled(false);
-        try {
-            return reader.readLine(prompt, mask);
-        } finally {
-            reader.setHistoryEnabled(true);
-        }
+        return reader.readLine(prompt, mask);
     }
 
     private String loadCompletionMode() {
@@ -361,70 +350,15 @@ public class ConsoleSessionImpl implements Session {
         return mode;
     }
 
-    private String readAndParseCommand() throws IOException {
-        String command = null;
-        boolean first = true;
-        while (true) {
-            checkInterrupt();
-            String line = reader.readLine(first ? getPrompt() : "> ");
-            if (line == null) {
-                return null;
-            }
-            if (command == null) {
-                command = line;
-            } else {
-                if (command.charAt(command.length() - 1) == '\\') {
-                    command = command.substring(0, command.length() - 1) + line;
-                } else {
-                    command += "\n" + line;
-                }
-            }
-            if (reader.getHistory().size() == 0) {
-                reader.getHistory().add(command);
-            } else {
-                // jline doesn't add blank lines to the history so we don't
-                // need to replace the command in jline's console history with
-                // an indented one
-                if (command.length() > 0 && !" ".equals(command)) {
-                    reader.getHistory().replace(command);
-                }
-            }
-            if (command.length() > 0 && command.charAt(command.length() - 1) == '\\') {
-                first = false;
-            } else {
-                try {
-                    return CommandLineParser.parse(this, command);
-                } catch (Exception e) {
-                    first = false;
-                }
-            }
-        }
-    }
-
     private void executeScript(String scriptFileName) {
         if (scriptFileName != null) {
-            Reader r = null;
             try {
-                File scriptFile = new File(scriptFileName);
-                r = new InputStreamReader(new FileInputStream(scriptFile));
-                CharArrayWriter w = new CharArrayWriter();
-                int n;
-                char[] buf = new char[8192];
-                while ((n = r.read(buf)) > 0) {
-                    w.write(buf, 0, n);
-                }
-                session.execute(new String(w.toCharArray()));
+                String script = String.join("\n",
+                        Files.readAllLines(Paths.get(scriptFileName)));
+                session.execute(script);
             } catch (Exception e) {
                 LOGGER.debug("Error in initialization script", e);
                 System.err.println("Error in initialization script: " + e.getMessage());
-            } finally {
-                if (r != null) {
-                    try {
-                        r.close();
-                    } catch (IOException e) {
-                        // Ignore
-                    }
-                }
             }
         }
     }
@@ -480,131 +414,10 @@ public class ConsoleSessionImpl implements Session {
         }
     }
 
-    private void checkInterrupt() throws IOException {
-        if (Thread.interrupted() || interrupt) {
-            interrupt = false;
-            throw new InterruptedIOException("Keyboard interruption");
-        }
-    }
-
-    private void interrupt() {
-        interrupt = true;
-        thread.interrupt();
-    }
-
     private String getPid() {
         String name = ManagementFactory.getRuntimeMXBean().getName();
         String[] parts = name.split("@");
         return parts[0];
     }
 
-    private class ConsoleInputStream extends InputStream {
-        private int read(boolean wait) throws IOException {
-            if (!running) {
-                return -1;
-            }
-            checkInterrupt();
-            if (eof && queue.isEmpty()) {
-                return -1;
-            }
-            Integer i;
-            if (wait) {
-                try {
-                    i = queue.take();
-                } catch (InterruptedException e) {
-                    throw new InterruptedIOException();
-                }
-                checkInterrupt();
-            } else {
-                i = queue.poll();
-            }
-            if (i == null) {
-                return -1;
-            }
-            return i;
-        }
-
-        @Override
-        public int read() throws IOException {
-            return read(true);
-        }
-
-        @Override
-        public int read(byte b[], int off, int len) throws IOException {
-            if (b == null) {
-                throw new NullPointerException();
-            } else if (off < 0 || len < 0 || len > b.length - off) {
-                throw new IndexOutOfBoundsException();
-            } else if (len == 0) {
-                return 0;
-            }
-
-            int nb = 1;
-            int i = read(true);
-            if (i < 0) {
-                return -1;
-            }
-            b[off++] = (byte) i;
-            while (nb < len) {
-                i = read(false);
-                if (i < 0) {
-                    return nb;
-                }
-                b[off++] = (byte) i;
-                nb++;
-            }
-            return nb;
-        }
-
-        @Override
-        public int available() throws IOException {
-            return queue.size();
-        }
-    }
-
-    private class Pipe extends Thread {
-        public Pipe() {
-            super("Karaf shell pipe thread");
-            setDaemon(true);
-        }
-
-        public void run() {
-            boolean useAvailable = !System.getProperty("os.name").toLowerCase().contains("windows");
-            try {
-                while (running) {
-                    try {
-                        while (useAvailable && in.available() == 0) {
-                            if (!running) {
-                                return;
-                            }
-                            Thread.sleep(50);
-                        }
-                        int c = in.read();
-                        if (c == -1) {
-                            return;
-                        } else if (c == 4 && !ShellUtil.getBoolean(ConsoleSessionImpl.this, Session.IGNORE_INTERRUPTS)) {
-                            err.print("^D");
-                            err.flush();
-                            ConsoleSessionImpl.this.interrupt();
-                            return;
-                        } else if (c == 3 && !ShellUtil.getBoolean(ConsoleSessionImpl.this, Session.IGNORE_INTERRUPTS)) {
-                            err.println("^C");
-                            reader.getCursorBuffer().clear();
-                            ConsoleSessionImpl.this.interrupt();
-                        }
-                        queue.put(c);
-                    } catch (Throwable t) {
-                        return;
-                    }
-                }
-            } finally {
-                eof = true;
-                try {
-                    queue.put(-1);
-                } catch (InterruptedException e) {
-                }
-            }
-        }
-    }
-
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/console/HeadlessSessionImpl.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/HeadlessSessionImpl.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/HeadlessSessionImpl.java
index e59eb82..7f951d3 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/HeadlessSessionImpl.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/HeadlessSessionImpl.java
@@ -78,6 +78,7 @@ public class HeadlessSessionImpl implements Session {
             session.put("USER", ShellUtil.getCurrentUserName());
             session.put("APPLICATION", System.getProperty("karaf.name", "root"));
         }
+        session.currentDir(null);
     }
 
     public CommandSession getSession() {

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/console/HistoryWrapper.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/HistoryWrapper.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/HistoryWrapper.java
index 6f69991..ef21593 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/HistoryWrapper.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/HistoryWrapper.java
@@ -22,9 +22,9 @@ import org.apache.karaf.shell.api.console.History;
 
 public class HistoryWrapper implements History {
 
-    private final jline.console.history.History history;
+    private final org.jline.reader.History history;
 
-    public HistoryWrapper(jline.console.history.History history) {
+    public HistoryWrapper(org.jline.reader.History history) {
         this.history = history;
     }
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/console/JLineTerminal.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/JLineTerminal.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/JLineTerminal.java
index c662aed..c45ba34 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/JLineTerminal.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/JLineTerminal.java
@@ -18,37 +18,59 @@
  */
 package org.apache.karaf.shell.impl.console;
 
-import java.io.Closeable;
 import java.io.IOException;
-import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Method;
-import java.lang.reflect.Proxy;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.util.EnumSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArraySet;
 
-import org.apache.karaf.shell.api.console.Signal;
+import org.apache.karaf.shell.api.console.SignalListener;
 import org.apache.karaf.shell.api.console.Terminal;
-import org.apache.karaf.shell.support.terminal.SignalSupport;
+import org.jline.terminal.Attributes;
+import org.jline.terminal.Size;
+import org.jline.utils.InfoCmp.Capability;
+import org.jline.utils.NonBlockingReader;
 
-/**
- * Created by gnodet on 27/02/14.
- */
-public class JLineTerminal extends SignalSupport implements Terminal, Closeable {
+public class JLineTerminal implements Terminal, org.jline.terminal.Terminal {
 
-    private final jline.Terminal terminal;
-    private final String type;
+    private final org.jline.terminal.Terminal terminal;
+    private final ConcurrentMap<Signal, Set<SignalListener>> listeners = new ConcurrentHashMap<>();
+    private final ConcurrentMap<Signal, SignalHandler> handlers = new ConcurrentHashMap<>();
 
-    public JLineTerminal(jline.Terminal terminal, String type) {
+    public JLineTerminal(org.jline.terminal.Terminal terminal) {
         this.terminal = terminal;
-        this.type = type;
-        registerSignalHandler();
+        for (Signal signal : Signal.values()) {
+            terminal.handle(signal, this::handle);
+        }
     }
 
-    public jline.Terminal getTerminal() {
-        return terminal;
+    @Override
+    public String getType() {
+        return terminal.getType();
     }
 
     @Override
-    public String getType() {
-        return type;
+    public boolean puts(Capability capability, Object... params) {
+        return terminal.puts(capability, params);
+    }
+
+    @Override
+    public boolean getBooleanCapability(Capability capability) {
+        return terminal.getBooleanCapability(capability);
+    }
+
+    @Override
+    public Integer getNumericCapability(Capability capability) {
+        return terminal.getNumericCapability(capability);
+    }
+
+    @Override
+    public String getStringCapability(Capability capability) {
+        return terminal.getStringCapability(capability);
     }
 
     @Override
@@ -62,59 +84,177 @@ public class JLineTerminal extends SignalSupport implements Terminal, Closeable
     }
 
     @Override
+    public void flush() {
+        terminal.flush();
+    }
+
+    @Override
     public boolean isAnsiSupported() {
-        return terminal.isAnsiSupported();
+        return true;
     }
 
     @Override
     public boolean isEchoEnabled() {
-        return terminal.isEchoEnabled();
+        return terminal.echo();
     }
 
     @Override
     public void setEchoEnabled(boolean enabled) {
-        terminal.setEchoEnabled(enabled);
+        terminal.echo(enabled);
     }
 
     @Override
     public void close() throws IOException {
-        unregisterSignalHandler();
-    }
-
-    private void registerSignalHandler() {
-        try {
-            Class<?> signalClass = Class.forName("sun.misc.Signal");
-            Class<?> signalHandlerClass = Class.forName("sun.misc.SignalHandler");
-            // Implement signal handler
-            Object signalHandler = Proxy.newProxyInstance(getClass().getClassLoader(),
-                    new Class<?>[]{signalHandlerClass}, new InvocationHandler() {
-                        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
-                            JLineTerminal.this.signal(Signal.WINCH);
-                            return null;
-                        }
-                    }
-            );
-            // Register the signal handler, this code is equivalent to:
-            // Signal.handle(new Signal("CONT"), signalHandler);
-            signalClass.getMethod("handle", signalClass, signalHandlerClass).invoke(null, signalClass.getConstructor(String.class).newInstance("WINCH"), signalHandler);
-        } catch (Exception e) {
-            // Ignore this exception, if the above failed, the signal API is incompatible with what we're expecting
+        terminal.close();
+    }
+
+    @Override
+    public String getName() {
+        return terminal.getName();
+    }
+
+    @Override
+    public NonBlockingReader reader() {
+        return terminal.reader();
+    }
+
+    @Override
+    public PrintWriter writer() {
+        return terminal.writer();
+    }
+
+    @Override
+    public InputStream input() {
+        return terminal.input();
+    }
+
+    @Override
+    public OutputStream output() {
+        return terminal.output();
+    }
+
+    @Override
+    public Attributes enterRawMode() {
+        return terminal.enterRawMode();
+    }
+
+    @Override
+    public boolean echo() {
+        return terminal.echo();
+    }
+
+    @Override
+    public boolean echo(boolean echo) {
+        return terminal.echo(echo);
+    }
+
+    @Override
+    public Attributes getAttributes() {
+        return terminal.getAttributes();
+    }
+
+    @Override
+    public void setAttributes(Attributes attr) {
+        terminal.setAttributes(attr);
+    }
+
+    @Override
+    public Size getSize() {
+        return terminal.getSize();
+    }
+
+    @Override
+    public void setSize(Size size) {
+        terminal.setSize(size);
+    }
+
+    @Override
+    public void raise(Signal signal) {
+        terminal.raise(signal);
+    }
+
+    @Override
+    public SignalHandler handle(Signal signal, SignalHandler handler) {
+        return handlers.put(signal, handler);
+    }
 
+    @Override
+    public void addSignalListener(SignalListener listener) {
+        addSignalListener(listener, EnumSet.allOf(org.apache.karaf.shell.api.console.Signal.class));
+    }
+
+    @Override
+    public void addSignalListener(SignalListener listener, org.apache.karaf.shell.api.console.Signal... signals) {
+        for (org.apache.karaf.shell.api.console.Signal sig : signals) {
+            addSignalListener(listener, sig);
+        }
+    }
+
+    @Override
+    public void addSignalListener(SignalListener listener, EnumSet<org.apache.karaf.shell.api.console.Signal> signals) {
+        for (org.apache.karaf.shell.api.console.Signal sig : signals) {
+            addSignalListener(listener, sig);
+        }
+    }
+
+    private void addSignalListener(SignalListener listener, org.apache.karaf.shell.api.console.Signal signal) {
+        Set<SignalListener> ls = listeners.compute(signal(signal), (s, l) -> l != null ? l : new CopyOnWriteArraySet<>());
+        ls.add(listener);
+    }
+
+    @Override
+    public void removeSignalListener(SignalListener listener) {
+        for (Signal signal : Signal.values()) {
+            Set<SignalListener> ls = listeners.get(signal);
+            if (ls != null) {
+                ls.remove(listener);
+            }
         }
     }
 
-    private void unregisterSignalHandler() {
-        try {
-            Class<?> signalClass = Class.forName("sun.misc.Signal");
-            Class<?> signalHandlerClass = Class.forName("sun.misc.SignalHandler");
+    private Signal signal(org.apache.karaf.shell.api.console.Signal sig) {
+        switch (sig) {
+            case INT:
+                return Signal.INT;
+            case QUIT:
+                return Signal.QUIT;
+            case TSTP:
+                return Signal.TSTP;
+            case CONT:
+                return Signal.CONT;
+            case WINCH:
+                return Signal.WINCH;
+        }
+        throw new UnsupportedOperationException();
+    }
 
-            Object signalHandler = signalHandlerClass.getField("SIG_DFL").get(null);
-            // Register the signal handler, this code is equivalent to:
-            // Signal.handle(new Signal("CONT"), signalHandler);
-            signalClass.getMethod("handle", signalClass, signalHandlerClass).invoke(null, signalClass.getConstructor(String.class).newInstance("WINCH"), signalHandler);
-        } catch (Exception e) {
-            // Ignore this exception, if the above failed, the signal API is incompatible with what we're expecting
+    private org.apache.karaf.shell.api.console.Signal signal(Signal sig) {
+        switch (sig) {
+            case INT:
+                return org.apache.karaf.shell.api.console.Signal.INT;
+            case QUIT:
+                return org.apache.karaf.shell.api.console.Signal.QUIT;
+            case TSTP:
+                return org.apache.karaf.shell.api.console.Signal.TSTP;
+            case CONT:
+                return org.apache.karaf.shell.api.console.Signal.CONT;
+            case WINCH:
+                return org.apache.karaf.shell.api.console.Signal.WINCH;
+        }
+        throw new UnsupportedOperationException();
+    }
 
+    protected void handle(Signal signal) {
+        SignalHandler handler = handlers.get(signal);
+        if (handler != null) {
+            handler.handle(signal);
+        }
+        Set<SignalListener> sl = listeners.get(signal);
+        if (sl != null) {
+            for (SignalListener l : sl) {
+                l.signal(signal(signal));
+            }
         }
     }
+
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/console/KarafFileHistory.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/KarafFileHistory.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/KarafFileHistory.java
deleted file mode 100644
index aa4d2e4..0000000
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/KarafFileHistory.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.karaf.shell.impl.console;
-
-import java.io.File;
-import java.io.IOException;
-
-import jline.console.history.FileHistory;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Override the FileHistory impl to trap failures due to the
- * user does not having write access to the history file.
- */
-public final class KarafFileHistory extends FileHistory {
-
-	static final Logger LOGGER = LoggerFactory.getLogger(KarafFileHistory.class);
-	boolean failed = false;
-
-	public KarafFileHistory(File file) throws IOException {
-		super(file);
-	}
-
-	@Override
-	public void flush() throws IOException {
-	    if( !failed ) {
-	        try {
-	            super.flush();
-	        } catch (IOException e) {
-	            failed = true;
-	            LOGGER.debug("Could not write history file: "+ getFile(), e);
-	        }
-	    }
-	}
-
-	@Override
-	public void purge() throws IOException {
-	    if( !failed ) {
-	        try {
-	            super.purge();
-	        } catch (IOException e) {
-	            failed = true;
-	            LOGGER.debug("Could not delete history file: "+ getFile(), e);
-	        }
-	    }
-	}
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/console/KarafTerminal.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/KarafTerminal.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/KarafTerminal.java
index 643408a..169db55 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/KarafTerminal.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/KarafTerminal.java
@@ -18,25 +18,29 @@
  */
 package org.apache.karaf.shell.impl.console;
 
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Set;
 
-import jline.Terminal2;
-import jline.TerminalSupport;
-import jline.internal.InfoCmp;
 import org.apache.karaf.shell.api.console.Terminal;
+import org.jline.terminal.Attributes;
+import org.jline.terminal.Size;
+import org.jline.terminal.impl.AbstractTerminal;
+import org.jline.utils.InfoCmp;
+import org.jline.utils.InfoCmp.Capability;
+import org.jline.utils.NonBlockingReader;
 
-public class KarafTerminal extends TerminalSupport implements Terminal2 {
+public class KarafTerminal extends AbstractTerminal implements org.jline.terminal.Terminal {
 
     private final Terminal terminal;
-    private Set<String> bools = new HashSet<>();
-    private Map<String, Integer> ints = new HashMap<>();
-    private Map<String, String> strings = new HashMap<>();
 
-    public KarafTerminal(Terminal terminal) {
-        super(true);
+    public KarafTerminal(Terminal terminal) throws IOException {
+        super("Karaf", terminal.getType());
         this.terminal = terminal;
 
         String type = terminal.getType();
@@ -47,7 +51,7 @@ public class KarafTerminal extends TerminalSupport implements Terminal2 {
         try {
             caps = InfoCmp.getInfoCmp(type);
         } catch (Exception e) {
-            caps = InfoCmp.getAnsiCaps();
+            caps = InfoCmp.ANSI_CAPS;
         }
         try {
             InfoCmp.parseInfoCmp(caps, bools, ints, strings);
@@ -57,41 +61,49 @@ public class KarafTerminal extends TerminalSupport implements Terminal2 {
     }
 
     @Override
-    public synchronized boolean isAnsiSupported() {
-        return terminal.isAnsiSupported();
+    public NonBlockingReader reader() {
+        return null;
     }
 
     @Override
-    public int getWidth() {
-        return terminal.getWidth();
+    public PrintWriter writer() {
+        return null;
     }
 
     @Override
-    public int getHeight() {
-        return terminal.getHeight();
+    public InputStream input() {
+        return null;
     }
 
     @Override
-    public synchronized boolean isEchoEnabled() {
-        return false;
+    public OutputStream output() {
+        return null;
     }
 
     @Override
-    public synchronized void setEchoEnabled(boolean enabled) {
+    public Attributes getAttributes() {
+        return null;
     }
 
     @Override
-    public boolean getBooleanCapability(String capability) {
-        return bools.contains(capability);
+    public void setAttributes(Attributes attr) {
+
     }
 
     @Override
-    public Integer getNumericCapability(String capability) {
-        return ints.get(capability);
+    public Size getSize() {
+        int h = terminal.getHeight();
+        int w = terminal.getWidth();
+        return new Size(w, h);
     }
 
     @Override
-    public String getStringCapability(String capability) {
-        return strings.get(capability);
+    public void setSize(Size size) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void close() throws IOException {
     }
 }
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/console/TerminalFactory.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/TerminalFactory.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/TerminalFactory.java
deleted file mode 100644
index bae3a25..0000000
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/TerminalFactory.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *  http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.karaf.shell.impl.console;
-
-import jline.NoInterruptUnixTerminal;
-import jline.Terminal;
-
-public class TerminalFactory {
-
-    private Terminal term;
-
-    public synchronized Terminal getTerminal() throws Exception {
-        if (term == null) {
-            init();
-        }
-        return term;
-    }
-
-    public void init() throws Exception {
-        jline.TerminalFactory.registerFlavor(jline.TerminalFactory.Flavor.UNIX, NoInterruptUnixTerminal.class);
-        term = jline.TerminalFactory.create();
-    }
-
-    public synchronized void destroy() throws Exception {
-        if (term != null) {
-            term.restore();
-            term = null;
-        }
-    }
-
-}

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/AnsiPrintingWikiVisitor.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/AnsiPrintingWikiVisitor.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/AnsiPrintingWikiVisitor.java
index bd5acd9..79f0fbe 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/AnsiPrintingWikiVisitor.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/commands/help/wikidoc/AnsiPrintingWikiVisitor.java
@@ -18,10 +18,8 @@ package org.apache.karaf.shell.impl.console.commands.help.wikidoc;
 
 import java.io.PrintStream;
 
+import org.apache.karaf.shell.support.ansi.SimpleAnsi;
 import org.apache.karaf.shell.support.table.ShellTable;
-import org.fusesource.jansi.Ansi;
-import org.fusesource.jansi.Ansi.Attribute;
-import org.fusesource.jansi.Ansi.Color;
 
 /**
  * Translates the Wiki tags to Ansi escape sequences to display them on the console
@@ -62,19 +60,25 @@ public class AnsiPrintingWikiVisitor implements WikiVisitor {
 
 	@Override
 	public void heading(int level, String header) {
-		sb.append(Ansi.ansi().a(Attribute.INTENSITY_BOLD).a(header)
-				.a(Attribute.INTENSITY_BOLD_OFF).toString());
+		sb.append(SimpleAnsi.INTENSITY_BOLD)
+				.append(header)
+				.append(SimpleAnsi.INTENSITY_NORMAL);
 	}
 	
 	@Override
 	public void link(String target, String title) {
-		sb.append(Ansi.ansi().fg(Color.YELLOW)
-				.a(target).fg(Color.DEFAULT));
+		sb.append(SimpleAnsi.COLOR_YELLOW)
+				.append(target)
+				.append(SimpleAnsi.COLOR_DEFAULT);
 	}
 
 	@Override
 	public void enumeration(String text) {
-		sb.append(Ansi.ansi().a(" * ").fg(Color.CYAN).a(text).fg(Color.DEFAULT).a(" "));
+		sb.append(" * ")
+				.append(SimpleAnsi.COLOR_CYAN)
+				.append(text)
+				.append(SimpleAnsi.COLOR_DEFAULT)
+				.append(" ");
 	}
 
 	@Override
@@ -85,9 +89,9 @@ public class AnsiPrintingWikiVisitor implements WikiVisitor {
 	@Override
 	public void bold(boolean on) {
 		if (on) {
-			sb.append(Ansi.ansi().bold().toString());
+			sb.append(SimpleAnsi.INTENSITY_BOLD);
 		} else {
-			sb.append(Ansi.ansi().boldOff().toString());
+			sb.append(SimpleAnsi.INTENSITY_NORMAL);
 		}
 	}
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/Activator.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/Activator.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/Activator.java
index 3bd1b8f..57c0f95 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/Activator.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/Activator.java
@@ -27,7 +27,6 @@ import org.apache.karaf.shell.api.console.SessionFactory;
 import org.apache.karaf.shell.impl.action.command.ManagerImpl;
 import org.apache.karaf.shell.impl.action.osgi.CommandExtender;
 import org.apache.karaf.shell.impl.console.SessionFactoryImpl;
-import org.apache.karaf.shell.impl.console.TerminalFactory;
 import org.apache.karaf.shell.impl.console.osgi.secured.SecuredSessionFactoryImpl;
 import org.osgi.framework.BundleActivator;
 import org.osgi.framework.BundleContext;
@@ -49,7 +48,6 @@ public class Activator implements BundleActivator {
 
     private Closeable eventAdminListener;
 
-    private TerminalFactory terminalFactory;
     private LocalConsoleManager localConsoleManager;
 
     ServiceTracker<CommandLoggingFilter, CommandLoggingFilter> filterTracker;
@@ -64,7 +62,7 @@ public class Activator implements BundleActivator {
         sessionFactory.getCommandProcessor().addConstant(".context", context.getBundle(0).getBundleContext());
 
         final CopyOnWriteArraySet<CommandLoggingFilter> listeners = new CopyOnWriteArraySet<>();
-        filterTracker = new ServiceTracker<CommandLoggingFilter, CommandLoggingFilter>(
+        filterTracker = new ServiceTracker<>(
                 context, CommandLoggingFilter.class, new ServiceTrackerCustomizer<CommandLoggingFilter, CommandLoggingFilter>() {
             @Override
             public CommandLoggingFilter addingService(ServiceReference<CommandLoggingFilter> reference) {
@@ -104,8 +102,7 @@ public class Activator implements BundleActivator {
         actionExtender.start(context);
 
         if (Boolean.parseBoolean(context.getProperty(START_CONSOLE))) {
-            terminalFactory = new TerminalFactory();
-            localConsoleManager = new LocalConsoleManager(context, terminalFactory, sessionFactory);
+            localConsoleManager = new LocalConsoleManager(context, sessionFactory);
             localConsoleManager.start();
         }
     }
@@ -116,7 +113,6 @@ public class Activator implements BundleActivator {
         sessionFactoryRegistration.unregister();
         if (localConsoleManager != null) {
             localConsoleManager.stop();
-            terminalFactory.destroy();
         }
         sessionFactory.stop();
         actionExtender.stop(context);

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/LocalConsoleManager.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/LocalConsoleManager.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/LocalConsoleManager.java
index 804f9c2..494fb65 100644
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/LocalConsoleManager.java
+++ b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/LocalConsoleManager.java
@@ -18,6 +18,7 @@
  */
 package org.apache.karaf.shell.impl.console.osgi;
 
+import java.io.PrintStream;
 import java.nio.charset.Charset;
 import java.security.PrivilegedAction;
 
@@ -28,9 +29,9 @@ import org.apache.karaf.jaas.boot.principal.UserPrincipal;
 import org.apache.karaf.shell.api.console.Session;
 import org.apache.karaf.shell.api.console.SessionFactory;
 import org.apache.karaf.shell.impl.console.JLineTerminal;
-import org.apache.karaf.shell.impl.console.TerminalFactory;
 import org.apache.karaf.shell.support.ShellUtil;
 import org.apache.karaf.util.jaas.JaasHelper;
+import org.jline.terminal.TerminalBuilder;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceRegistration;
 
@@ -38,21 +39,18 @@ public class LocalConsoleManager {
 
     private SessionFactory sessionFactory;
     private BundleContext bundleContext;
-    private TerminalFactory terminalFactory;
     private Session session;
     private ServiceRegistration<?> registration;
     private boolean closing;
 
     public LocalConsoleManager(BundleContext bundleContext,
-                               TerminalFactory terminalFactory,
                                SessionFactory sessionFactory) throws Exception {
         this.bundleContext = bundleContext;
-        this.terminalFactory = terminalFactory;
         this.sessionFactory = sessionFactory;
     }
 
     public void start() throws Exception {
-        final jline.Terminal terminal = terminalFactory.getTerminal();
+        final org.jline.terminal.Terminal terminal = TerminalBuilder.terminal();
         final Runnable callback = new Runnable() {
             public void run() {
                 try {
@@ -71,10 +69,10 @@ public class LocalConsoleManager {
             public Session run() {
                 String encoding = getEncoding();
                 session = sessionFactory.create(
-                                      StreamWrapUtil.reWrapIn(terminal, System.in),
-                                      StreamWrapUtil.reWrap(System.out), 
-                                      StreamWrapUtil.reWrap(System.err),
-                                      new JLineTerminal(terminal, System.getenv("TERM")),
+                                      terminal.input(),
+                                      new PrintStream(terminal.output()),
+                                      new PrintStream(terminal.output()),
+                                      new JLineTerminal(terminal),
                                       encoding, 
                                       callback);
                 registration = bundleContext.registerService(Session.class, session, null);

http://git-wip-us.apache.org/repos/asf/karaf/blob/b4ae5245/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/StreamWrapUtil.java
----------------------------------------------------------------------
diff --git a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/StreamWrapUtil.java b/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/StreamWrapUtil.java
deleted file mode 100644
index 2b3afcd..0000000
--- a/shell/core/src/main/java/org/apache/karaf/shell/impl/console/osgi/StreamWrapUtil.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.karaf.shell.impl.console.osgi;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.lang.reflect.Method;
-
-import jline.Terminal;
-import org.fusesource.jansi.AnsiConsole;
-
-final class StreamWrapUtil {
-    private StreamWrapUtil() {
-    }
-
-    private static Object invokePrivateMethod(Object o, String methodName, Object[] params) throws Exception {
-        final Method methods[] = o.getClass().getDeclaredMethods();
-        for (int i = 0; i < methods.length; ++i) {
-            if (methodName.equals(methods[i].getName())) {
-                methods[i].setAccessible(true);
-                return methods[i].invoke(o, params);
-            }
-        }
-        return o;
-    }
-
-    /**
-     * unwrap stream so it can be recognized by the terminal and wrapped to get
-     * special keys in windows
-     * 
-     * @param stream
-     * @return
-     */
-    @SuppressWarnings("unchecked")
-    private static <T> T unwrapBIS(T stream) {
-        try {
-            return (T) invokePrivateMethod(stream, "getInIfOpen", null);
-        } catch (Throwable t) {
-            return stream;
-        }
-    }
-
-    private static PrintStream wrap(PrintStream stream) {
-        OutputStream o = AnsiConsole.wrapOutputStream(stream);
-        if (o instanceof PrintStream) {
-            return ((PrintStream) o);
-        } else {
-            return new PrintStream(o);
-        }
-    }
-
-    @SuppressWarnings("unchecked")
-    private static <T> T unwrap(T stream) {
-        try {
-            Method mth = stream.getClass().getMethod("getRoot");
-            return (T) mth.invoke(stream);
-        } catch (Throwable t) {
-            return stream;
-        }
-    }
-
-    static InputStream reWrapIn(Terminal terminal, InputStream stream) {
-        try {
-            return terminal.wrapInIfNeeded(unwrapBIS(unwrap(stream)));
-        } catch (IOException e) {
-            throw new RuntimeException(e);
-        }
-    }
-
-    static PrintStream reWrap(PrintStream stream) {
-        return wrap(unwrap(stream));
-    }
-}


Mime
View raw message