You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@karaf.apache.org by cs...@apache.org on 2014/02/24 11:28:09 UTC

[11/11] git commit: KARAF-2772 Extracting command-api

KARAF-2772 Extracting command-api


Project: http://git-wip-us.apache.org/repos/asf/karaf/repo
Commit: http://git-wip-us.apache.org/repos/asf/karaf/commit/1ee78df9
Tree: http://git-wip-us.apache.org/repos/asf/karaf/tree/1ee78df9
Diff: http://git-wip-us.apache.org/repos/asf/karaf/diff/1ee78df9

Branch: refs/heads/command-api
Commit: 1ee78df92a1345d2236c0000d22962d69324b787
Parents: 6fdb03b
Author: Christian Schneider <ch...@die-schneider.net>
Authored: Mon Feb 24 11:27:32 2014 +0100
Committer: Christian Schneider <ch...@die-schneider.net>
Committed: Mon Feb 24 11:27:32 2014 +0100

----------------------------------------------------------------------
 jaas/modules/pom.xml                            |   1 +
 pom.xml                                         |   5 +
 shell/command-api/NOTICE                        |  71 +++
 shell/command-api/pom.xml                       | 131 +++++
 .../karaf/shell/console/branding-ssh.properties |  34 ++
 .../karaf/shell/console/branding.properties     |  33 ++
 .../org/apache/felix/gogo/commands/Action.java  |  29 +
 .../apache/felix/gogo/commands/Argument.java    |  49 ++
 .../org/apache/felix/gogo/commands/Command.java |  53 ++
 .../felix/gogo/commands/CommandException.java   |  63 +++
 .../felix/gogo/commands/CommandWithAction.java  |  32 ++
 .../felix/gogo/commands/CompleterValues.java    |  37 ++
 .../org/apache/felix/gogo/commands/Option.java  |  48 ++
 .../apache/felix/gogo/commands/SubShell.java    |  46 ++
 .../gogo/commands/basic/AbstractCommand.java    |  64 +++
 .../gogo/commands/basic/ActionPreparator.java   |  31 +
 .../commands/basic/DefaultActionPreparator.java | 566 ++++++++++++++++++
 .../commands/converter/DefaultConverter.java    | 402 +++++++++++++
 .../gogo/commands/converter/GenericType.java    | 196 +++++++
 .../gogo/commands/converter/ReifiedType.java    | 118 ++++
 .../org/apache/karaf/shell/commands/Action.java |  40 ++
 .../apache/karaf/shell/commands/Argument.java   |  48 ++
 .../apache/karaf/shell/commands/Command.java    |  53 ++
 .../karaf/shell/commands/CommandException.java  |  64 +++
 .../karaf/shell/commands/CommandWithAction.java |  31 +
 .../apache/karaf/shell/commands/Completer.java  |  34 ++
 .../karaf/shell/commands/CompleterValues.java   |  37 ++
 .../apache/karaf/shell/commands/HelpOption.java |  54 ++
 .../karaf/shell/commands/InfoProvider.java      |  30 +
 .../org/apache/karaf/shell/commands/Option.java |  46 ++
 .../karaf/shell/commands/ansi/SimpleAnsi.java   |  28 +
 .../shell/commands/basic/AbstractCommand.java   |  62 ++
 .../shell/commands/basic/ActionPreparator.java  |  42 ++
 .../commands/basic/DefaultActionPreparator.java | 223 ++++++++
 .../shell/commands/basic/SimpleCommand.java     |  82 +++
 .../commands/converter/DefaultConverter.java    | 401 +++++++++++++
 .../shell/commands/converter/GenericType.java   | 195 +++++++
 .../shell/commands/converter/ReifiedType.java   | 116 ++++
 .../shell/commands/meta/ActionMetaData.java     | 296 ++++++++++
 .../commands/meta/ActionMetaDataFactory.java    | 251 ++++++++
 .../karaf/shell/console/AbstractAction.java     |  50 ++
 .../shell/console/BlueprintContainerAware.java  |  27 +
 .../karaf/shell/console/BundleContextAware.java |  27 +
 .../shell/console/CloseShellException.java      |  27 +
 .../shell/console/CommandSessionHolder.java     |  38 ++
 .../shell/console/CompletableFunction.java      |  31 +
 .../apache/karaf/shell/console/Completer.java   |  27 +
 .../org/apache/karaf/shell/console/Console.java |  29 +
 .../apache/karaf/shell/console/ExitAction.java  |  46 ++
 .../karaf/shell/console/HelpProvider.java       |  26 +
 .../karaf/shell/console/MultiException.java     |  95 ++++
 .../apache/karaf/shell/console/NameScoping.java |  79 +++
 .../karaf/shell/console/OsgiCommandSupport.java | 103 ++++
 .../karaf/shell/console/SessionProperties.java  |  28 +
 .../apache/karaf/shell/console/SubShell.java    |  38 ++
 .../karaf/shell/console/SubShellAction.java     |  39 ++
 .../console/commands/AnnotatedSubShell.java     |  43 ++
 .../shell/console/commands/BasicSubShell.java   |  51 ++
 .../console/commands/BlueprintCommand.java      | 110 ++++
 .../shell/console/commands/GenericType.java     | 195 +++++++
 .../console/commands/NamespaceHandler.java      | 523 +++++++++++++++++
 .../commands/NumberToStringConverter.java       |  36 ++
 .../console/completer/AggregateCompleter.java   |  91 +++
 .../console/completer/ArgumentCompleter.java    | 567 +++++++++++++++++++
 .../completer/CommandNamesCompleter.java        | 103 ++++
 .../console/completer/CommandsCompleter.java    | 321 +++++++++++
 .../shell/console/completer/FileCompleter.java  | 147 +++++
 .../shell/console/completer/NullCompleter.java  |  32 ++
 .../console/completer/OldArgumentCompleter.java | 448 +++++++++++++++
 .../karaf/shell/console/completer/Parser.java   | 396 +++++++++++++
 .../console/completer/StringsCompleter.java     | 103 ++++
 .../org/apache/karaf/shell/inject/Destroy.java  |  29 +
 .../org/apache/karaf/shell/inject/Init.java     |  29 +
 .../apache/karaf/shell/inject/Reference.java    |  29 +
 .../org/apache/karaf/shell/inject/Service.java  |  29 +
 .../blueprint/shell-namespacehandler.xml        |  42 ++
 .../src/main/resources/OSGI-INF/bundle.info     |  14 +
 .../console/commands/karaf-shell-1.0.0.xsd      | 217 +++++++
 .../console/commands/karaf-shell-1.1.0.xsd      | 209 +++++++
 .../console/commands/karaf-shell-1.2.0.xsd      | 225 ++++++++
 .../karaf/shell/commands/basic/Context.java     |  67 +++
 .../shell/commands/basic/SimpleSubShell.java    |  39 ++
 .../shell/commands/basic/TestCommands.java      | 184 ++++++
 .../shell/commands/meta/TestFormatting.java     |  35 ++
 .../completer/ArgumentCompleterTest.java        | 145 +++++
 .../console/completer/BooleanCompleterTest.java |  62 ++
 .../console/completer/CompleterTestSupport.java |  34 ++
 .../console/completer/CompleterValuesTest.java  |  74 +++
 .../shell/console/completer/CompletionTest.java | 172 ++++++
 .../console/completer/DummyCommandSession.java  |  48 ++
 .../console/completer/FileCompleterTest.java    |  56 ++
 shell/commands/pom.xml                          |   2 +-
 shell/console/pom.xml                           |  15 +-
 .../org/apache/felix/gogo/commands/Action.java  |  29 -
 .../apache/felix/gogo/commands/Argument.java    |  49 --
 .../org/apache/felix/gogo/commands/Command.java |  53 --
 .../felix/gogo/commands/CommandException.java   |  63 ---
 .../felix/gogo/commands/CommandWithAction.java  |  32 --
 .../felix/gogo/commands/CompleterValues.java    |  37 --
 .../org/apache/felix/gogo/commands/Option.java  |  48 --
 .../apache/felix/gogo/commands/SubShell.java    |  46 --
 .../gogo/commands/basic/AbstractCommand.java    |  64 ---
 .../gogo/commands/basic/ActionPreparator.java   |  31 -
 .../commands/basic/DefaultActionPreparator.java | 566 ------------------
 .../commands/converter/DefaultConverter.java    | 402 -------------
 .../gogo/commands/converter/GenericType.java    | 196 -------
 .../gogo/commands/converter/ReifiedType.java    | 118 ----
 .../org/apache/karaf/shell/commands/Action.java |  40 --
 .../apache/karaf/shell/commands/Argument.java   |  48 --
 .../apache/karaf/shell/commands/Command.java    |  53 --
 .../karaf/shell/commands/CommandException.java  |  64 ---
 .../karaf/shell/commands/CommandWithAction.java |  31 -
 .../apache/karaf/shell/commands/Completer.java  |  34 --
 .../karaf/shell/commands/CompleterValues.java   |  37 --
 .../apache/karaf/shell/commands/HelpOption.java |  54 --
 .../karaf/shell/commands/InfoProvider.java      |  30 -
 .../org/apache/karaf/shell/commands/Option.java |  46 --
 .../karaf/shell/commands/ansi/SimpleAnsi.java   |  30 -
 .../shell/commands/basic/AbstractCommand.java   |  62 --
 .../shell/commands/basic/ActionPreparator.java  |  42 --
 .../commands/basic/DefaultActionPreparator.java | 223 --------
 .../shell/commands/basic/SimpleCommand.java     |  82 ---
 .../commands/converter/DefaultConverter.java    | 401 -------------
 .../shell/commands/converter/GenericType.java   | 195 -------
 .../shell/commands/converter/ReifiedType.java   | 116 ----
 .../shell/commands/meta/ActionMetaData.java     | 296 ----------
 .../commands/meta/ActionMetaDataFactory.java    | 251 --------
 .../karaf/shell/console/AbstractAction.java     |  50 --
 .../shell/console/BlueprintContainerAware.java  |  27 -
 .../karaf/shell/console/BundleContextAware.java |  27 -
 .../shell/console/CloseShellException.java      |  27 -
 .../shell/console/CommandSessionHolder.java     |  38 --
 .../shell/console/CompletableFunction.java      |  31 -
 .../apache/karaf/shell/console/Completer.java   |  27 -
 .../org/apache/karaf/shell/console/Console.java |  29 -
 .../apache/karaf/shell/console/ExitAction.java  |  46 --
 .../karaf/shell/console/HelpProvider.java       |  26 -
 .../karaf/shell/console/MultiException.java     |  95 ----
 .../apache/karaf/shell/console/NameScoping.java |  79 ---
 .../karaf/shell/console/OsgiCommandSupport.java | 103 ----
 .../karaf/shell/console/SessionProperties.java  |  28 -
 .../apache/karaf/shell/console/SubShell.java    |  38 --
 .../karaf/shell/console/SubShellAction.java     |  39 --
 .../console/commands/AnnotatedSubShell.java     |  43 --
 .../shell/console/commands/BasicSubShell.java   |  51 --
 .../console/commands/BlueprintCommand.java      | 110 ----
 .../shell/console/commands/GenericType.java     | 195 -------
 .../console/commands/NamespaceHandler.java      | 523 -----------------
 .../commands/NumberToStringConverter.java       |  36 --
 .../console/completer/AggregateCompleter.java   |  91 ---
 .../console/completer/ArgumentCompleter.java    | 567 -------------------
 .../completer/CommandNamesCompleter.java        | 103 ----
 .../console/completer/CommandsCompleter.java    | 321 -----------
 .../shell/console/completer/FileCompleter.java  | 147 -----
 .../shell/console/completer/NullCompleter.java  |  32 --
 .../console/completer/OldArgumentCompleter.java | 448 ---------------
 .../karaf/shell/console/completer/Parser.java   | 396 -------------
 .../console/completer/StringsCompleter.java     | 103 ----
 .../org/apache/karaf/shell/inject/Destroy.java  |  29 -
 .../org/apache/karaf/shell/inject/Init.java     |  29 -
 .../apache/karaf/shell/inject/Reference.java    |  29 -
 .../org/apache/karaf/shell/inject/Service.java  |  29 -
 .../karaf/shell/commands/basic/Context.java     |  67 ---
 .../shell/commands/basic/SimpleSubShell.java    |  39 --
 .../shell/commands/basic/TestCommands.java      | 184 ------
 .../shell/commands/meta/TestFormatting.java     |  35 --
 .../completer/ArgumentCompleterTest.java        | 145 -----
 .../console/completer/BooleanCompleterTest.java |  62 --
 .../console/completer/CompleterTestSupport.java |  34 --
 .../console/completer/CompleterValuesTest.java  |  74 ---
 .../shell/console/completer/CompletionTest.java | 172 ------
 .../console/completer/DummyCommandSession.java  |  48 --
 .../console/completer/FileCompleterTest.java    |  56 --
 shell/help/pom.xml                              |   7 +-
 .../help/impl/CommandListHelpProvider.java      |  15 +-
 shell/pom.xml                                   |   1 +
 176 files changed, 9772 insertions(+), 8802 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/jaas/modules/pom.xml
----------------------------------------------------------------------
diff --git a/jaas/modules/pom.xml b/jaas/modules/pom.xml
index a74adc2..908674e 100644
--- a/jaas/modules/pom.xml
+++ b/jaas/modules/pom.xml
@@ -57,6 +57,7 @@
         <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.fileinstall</artifactId>
+            <scope>provided</scope>
         </dependency>
 
         <dependency>

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 1b5d4e9..d80d27c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -636,6 +636,11 @@
 
             <dependency>
                 <groupId>org.apache.karaf.shell</groupId>
+                <artifactId>org.apache.karaf.shell.command.api</artifactId>
+                <version>${project.version}</version>
+            </dependency>
+            <dependency>
+                <groupId>org.apache.karaf.shell</groupId>
                 <artifactId>org.apache.karaf.shell.console</artifactId>
                 <version>${project.version}</version>
             </dependency>

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/NOTICE
----------------------------------------------------------------------
diff --git a/shell/command-api/NOTICE b/shell/command-api/NOTICE
new file mode 100644
index 0000000..de8d101
--- /dev/null
+++ b/shell/command-api/NOTICE
@@ -0,0 +1,71 @@
+Apache Karaf
+Copyright 2010-2013 The Apache Software Foundation
+
+
+I. Included Software
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+The OSGi Alliance (http://www.osgi.org/).
+Copyright (c) OSGi Alliance (2000, 2010).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+OW2 (http://www.ow2.org/).
+Licensed under the BSD License.
+
+This product includes software developed at
+OPS4J (http://www.ops4j.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software developed at
+Eclipse Foundation (http://www.eclipse.org/).
+Licensed under the EPL.
+
+This product includes software written by
+Antony Lesuisse.
+Licensed under Public Domain.
+
+
+II. Used Software
+
+This product uses software developed at
+FUSE Source (http://www.fusesource.org/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+AOP Alliance (http://aopalliance.sourceforge.net/).
+Licensed under the Public Domain.
+
+This product uses software developed at
+Tanuki Software (http://www.tanukisoftware.com/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+Jasypt (http://jasypt.sourceforge.net/).
+Licensed under the Apache License 2.0.
+
+This product uses software developed at
+JLine (http://jline.sourceforge.net).
+Licensed under the BSD License.
+
+This product uses software developed at
+SLF4J (http://www.slf4j.org/).
+Licensed under the MIT License.
+
+This product uses software developed at
+SpringSource (http://www.springsource.org/).
+Licensed under the Apache License 2.0.
+
+This product includes software from http://www.json.org.
+Copyright (c) 2002 JSON.org
+
+
+III. License Summary
+- Apache License 2.0
+- BSD License
+- EPL License
+- MIT License

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/pom.xml
----------------------------------------------------------------------
diff --git a/shell/command-api/pom.xml b/shell/command-api/pom.xml
new file mode 100644
index 0000000..7e453f8
--- /dev/null
+++ b/shell/command-api/pom.xml
@@ -0,0 +1,131 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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/xsd/maven-4.0.0.xsd">
+
+    <!--
+
+        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.
+    -->
+
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>org.apache.karaf.shell</groupId>
+        <artifactId>shell</artifactId>
+        <version>3.1.0-SNAPSHOT</version>
+        <relativePath>../pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.karaf.shell.command.api</artifactId>
+    <packaging>bundle</packaging>
+    <name>Apache Karaf :: Shell :: Command :: API</name>
+    <description>Action and Command API, support classes for implementing commands</description>
+
+    <properties>
+        <appendedResourcesDirectory>${basedir}/../../etc/appended-resources</appendedResourcesDirectory>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.aries.blueprint</groupId>
+            <artifactId>org.apache.aries.blueprint.api</artifactId>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.aries.blueprint</groupId>
+            <artifactId>org.apache.aries.blueprint.core</artifactId>
+            <scope>provided</scope>
+            <optional>true</optional>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.gogo.runtime</artifactId>
+            <scope>provided</scope>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>${project.basedir}/src/main/resources</directory>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+            </resource>
+            <resource>
+                <directory>${project.basedir}/src/main/resources</directory>
+                <filtering>true</filtering>
+                <includes>
+                    <include>**/*.info</include>
+                </includes>
+            </resource>
+            <resource>
+                <directory>${project.basedir}/src/main/filtered-resources</directory>
+                <filtering>true</filtering>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Import-Package>
+                            *
+                        </Import-Package>
+                        <Export-Package>
+                     	    org.apache.karaf.shell.commands;version=${project.version},
+                            org.apache.karaf.shell.commands;version=2.3.0,
+                            org.apache.karaf.shell.commands.basic;version=${project.version},
+                            org.apache.karaf.shell.commands.basic;version=2.3.0,
+                            org.apache.karaf.shell.commands.converter;version=${project.version},
+                            org.apache.karaf.shell.commands.converter;version=2.3.0,
+                            org.apache.karaf.shell.commands.meta;version=${project.version},
+                            org.apache.karaf.shell.commands.meta;version=2.3.0,
+                            org.apache.karaf.shell.console;version=${project.version},
+                            org.apache.karaf.shell.console;version=2.3.0,
+                            org.apache.karaf.shell.console.commands;version=${project.version},
+                            org.apache.karaf.shell.console.commands;version=2.3.0,
+                            org.apache.karaf.shell.console.completer;version=${project.version},
+                            org.apache.karaf.shell.console.completer;version=2.3.0,
+                            org.apache.karaf.shell.inject;version=${project.version},
+                        </Export-Package>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/src/main/filtered-resources/org/apache/karaf/shell/console/branding-ssh.properties
----------------------------------------------------------------------
diff --git a/shell/command-api/src/main/filtered-resources/org/apache/karaf/shell/console/branding-ssh.properties b/shell/command-api/src/main/filtered-resources/org/apache/karaf/shell/console/branding-ssh.properties
new file mode 100644
index 0000000..978484b
--- /dev/null
+++ b/shell/command-api/src/main/filtered-resources/org/apache/karaf/shell/console/branding-ssh.properties
@@ -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.
+##
+
+welcome = \
+\u001B[36m        __ __                  ____      \u001B[0m\r\n\
+\u001B[36m       / //_/____ __________ _/ __/      \u001B[0m\r\n\
+\u001B[36m      / ,<  / __ `/ ___/ __ `/ /_        \u001B[0m\r\n\
+\u001B[36m     / /| |/ /_/ / /  / /_/ / __/        \u001B[0m\r\n\
+\u001B[36m    /_/ |_|\\__,_/_/   \\__,_/_/         \u001B[0m\r\n\
+\r\n\
+\u001B[1m  Apache Karaf\u001B[0m (${project.version})\r\n\
+\r\n\
+Hit '\u001B[1m<tab>\u001B[0m' for a list of available commands\r\n\
+   and '\u001B[1m[cmd] --help\u001B[0m' for help on a specific command.\r\n\
+Hit '\u001B[1msystem:shutdown\u001B[0m' to shutdown Karaf.\r\n\
+Hit '\u001B[1m<ctrl-d>\u001B[0m' or type '\u001B[1mlogout\u001B[0m' to disconnect shell from current session.\r\n
+
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/src/main/filtered-resources/org/apache/karaf/shell/console/branding.properties
----------------------------------------------------------------------
diff --git a/shell/command-api/src/main/filtered-resources/org/apache/karaf/shell/console/branding.properties b/shell/command-api/src/main/filtered-resources/org/apache/karaf/shell/console/branding.properties
new file mode 100644
index 0000000..3fbcb0a
--- /dev/null
+++ b/shell/command-api/src/main/filtered-resources/org/apache/karaf/shell/console/branding.properties
@@ -0,0 +1,33 @@
+##
+## 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.
+##
+
+welcome = \
+\u001B[36m        __ __                  ____      \u001B[0m\r\n\
+\u001B[36m       / //_/____ __________ _/ __/      \u001B[0m\r\n\
+\u001B[36m      / ,<  / __ `/ ___/ __ `/ /_        \u001B[0m\r\n\
+\u001B[36m     / /| |/ /_/ / /  / /_/ / __/        \u001B[0m\r\n\
+\u001B[36m    /_/ |_|\\__,_/_/   \\__,_/_/         \u001B[0m\r\n\
+\r\n\
+\u001B[1m  Apache Karaf\u001B[0m (${project.version})\r\n\
+\r\n\
+Hit '\u001B[1m<tab>\u001B[0m' for a list of available commands\r\n\
+   and '\u001B[1m[cmd] --help\u001B[0m' for help on a specific command.\r\n\
+Hit '\u001B[1m<ctrl-d>\u001B[0m' or type '\u001B[1msystem:shutdown\u001B[0m' or '\u001B[1mlogout\u001B[0m' to shutdown Karaf.\r\n
+
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Action.java
----------------------------------------------------------------------
diff --git a/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Action.java b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Action.java
new file mode 100644
index 0000000..0727f24
--- /dev/null
+++ b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Action.java
@@ -0,0 +1,29 @@
+/*
+ * 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.commands;
+
+import org.apache.felix.service.command.CommandSession;
+
+@Deprecated
+public interface Action {
+
+    Object execute(CommandSession session) throws Exception;
+
+}
+

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Argument.java
----------------------------------------------------------------------
diff --git a/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Argument.java b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Argument.java
new file mode 100644
index 0000000..33c15bf
--- /dev/null
+++ b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Argument.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.gogo.commands;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Represents a positional argument on a command line (as opposed to an optional named {@link Option}
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+@Deprecated
+public @interface Argument {
+
+    public static final String DEFAULT_STRING = "DEFAULT";
+
+    String DEFAULT = "##default";
+
+    String name() default DEFAULT;
+
+    String description() default "";
+
+    boolean required() default false;
+
+    int index() default 0;
+
+    boolean multiValued() default false;
+
+    String valueToShowInHelp() default DEFAULT_STRING;
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Command.java
----------------------------------------------------------------------
diff --git a/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Command.java b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Command.java
new file mode 100644
index 0000000..10c494a
--- /dev/null
+++ b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Command.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.commands;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Used to denote a class represents a command which is executable within a shell/scope or as a
+ * command line process.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@Deprecated
+public @interface Command {
+    /**
+     * Returns the scope or sub shell of the command
+     */
+    String scope();
+
+    /**
+     * REturns the name of the command if used inside a shell
+     */
+    String name();
+
+    /**
+     * Returns the description of the command which is used to generate command line help
+     */
+    String description() default "";
+
+    /**
+     * Returns a detailed description of the command
+     */
+    String detailedDescription() default "";
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/src/main/java/org/apache/felix/gogo/commands/CommandException.java
----------------------------------------------------------------------
diff --git a/shell/command-api/src/main/java/org/apache/felix/gogo/commands/CommandException.java b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/CommandException.java
new file mode 100644
index 0000000..3c02d63
--- /dev/null
+++ b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/CommandException.java
@@ -0,0 +1,63 @@
+/*
+ * 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.commands;
+
+import org.apache.karaf.shell.commands.ansi.SimpleAnsi;
+
+/**
+ * Base class for exceptions thrown when executing commands.
+ */
+@Deprecated
+public class CommandException extends Exception {
+
+    private String help;
+
+    public CommandException() {
+    }
+
+    public CommandException(String message) {
+        super(message);
+    }
+
+    public CommandException(String message, Throwable cause) {
+        super(message, cause);
+    }
+
+    public CommandException(Throwable cause) {
+        super(cause);
+    }
+
+    public CommandException(String help, String message) {
+        super(message);
+        this.help = help;
+    }
+
+    public CommandException(String help, String message, Throwable cause) {
+        super(message, cause);
+        this.help = help;
+    }
+
+    public String getNiceHelp() {
+        return help != null ? help
+                : SimpleAnsi.COLOR_RED + "Error executing command: " 
+                 + getMessage() != null ? getMessage() : getClass().getName()
+                 + SimpleAnsi.COLOR_DEFAULT;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/src/main/java/org/apache/felix/gogo/commands/CommandWithAction.java
----------------------------------------------------------------------
diff --git a/shell/command-api/src/main/java/org/apache/felix/gogo/commands/CommandWithAction.java b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/CommandWithAction.java
new file mode 100644
index 0000000..e09cf64
--- /dev/null
+++ b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/CommandWithAction.java
@@ -0,0 +1,32 @@
+/*
+ * 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.commands;
+
+import org.apache.felix.service.command.Function;
+
+@Deprecated
+public interface CommandWithAction extends Function {
+
+    Class<? extends Action> getActionClass();
+
+    Action createNewAction();
+
+    void releaseAction(Action action) throws Exception;
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/src/main/java/org/apache/felix/gogo/commands/CompleterValues.java
----------------------------------------------------------------------
diff --git a/shell/command-api/src/main/java/org/apache/felix/gogo/commands/CompleterValues.java b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/CompleterValues.java
new file mode 100644
index 0000000..99129e5
--- /dev/null
+++ b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/CompleterValues.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.commands;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Represents a method which can return a List or Array of values used for a
+ * {@link org.apache.karaf.shell.console.Completer}
+ * which is associated with the index of an
+ * {@link org.apache.karaf.shell.commands.Argument}
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.METHOD, ElementType.FIELD})
+@Deprecated
+public @interface CompleterValues {
+    int index() default 0;
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Option.java
----------------------------------------------------------------------
diff --git a/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Option.java b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Option.java
new file mode 100644
index 0000000..1ce6f75
--- /dev/null
+++ b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/Option.java
@@ -0,0 +1,48 @@
+/*
+ * 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.commands;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.lang.annotation.ElementType;
+
+/**
+ * Used to mark an optional named command line option who's name typically starts with "--"
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD})
+@Deprecated
+public @interface Option {
+
+    public static final String DEFAULT_STRING = "DEFAULT";
+
+    String name();
+
+    String[] aliases() default {};
+
+    String description() default "";
+
+    boolean required() default false;
+
+    boolean multiValued() default false;
+
+    String valueToShowInHelp() default DEFAULT_STRING;
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/src/main/java/org/apache/felix/gogo/commands/SubShell.java
----------------------------------------------------------------------
diff --git a/shell/command-api/src/main/java/org/apache/felix/gogo/commands/SubShell.java b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/SubShell.java
new file mode 100644
index 0000000..0206964
--- /dev/null
+++ b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/SubShell.java
@@ -0,0 +1,46 @@
+/*
+ * 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.commands;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.TYPE})
+@Deprecated
+public @interface SubShell {
+
+    /**
+     * Returns the name of the command if used inside a shell
+     */
+    String name();
+
+    /**
+     * Returns the description of the command which is used to generate command line help
+     */
+    String description() default "";
+
+    /**
+     * Returns a detailed description of the command
+     */
+    String detailedDescription() default "";
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/src/main/java/org/apache/felix/gogo/commands/basic/AbstractCommand.java
----------------------------------------------------------------------
diff --git a/shell/command-api/src/main/java/org/apache/felix/gogo/commands/basic/AbstractCommand.java b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/basic/AbstractCommand.java
new file mode 100644
index 0000000..809ed67
--- /dev/null
+++ b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/basic/AbstractCommand.java
@@ -0,0 +1,64 @@
+/*
+ * 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.commands.basic;
+
+import java.util.List;
+
+import org.apache.felix.gogo.commands.Action;
+import org.apache.felix.gogo.commands.CommandWithAction;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.felix.service.command.Function;
+
+@Deprecated
+public abstract class AbstractCommand implements Function, CommandWithAction {
+
+    public Object execute(CommandSession session, List<Object> arguments) throws Exception {
+        Action action = createNewAction();
+        try {
+            if (getPreparator().prepare(action, session, arguments)) {
+                return action.execute(session);
+            } else {
+                return null;
+            }
+        } finally {
+            releaseAction(action);
+        }
+    }
+
+    public Class<? extends Action> getActionClass() {
+        return createNewAction().getClass();
+    }
+
+    public abstract Action createNewAction();
+
+    /**
+     * Release the used Action.
+     * This method has to be overridden for pool based Actions.
+     * @param action Action that was executed
+     * @throws Exception if something went wrong during the Action release
+     */
+    public void releaseAction(Action action) throws Exception {
+        // Do nothing by default (stateful)
+    }
+
+    protected ActionPreparator getPreparator() throws Exception {
+        return new DefaultActionPreparator();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/src/main/java/org/apache/felix/gogo/commands/basic/ActionPreparator.java
----------------------------------------------------------------------
diff --git a/shell/command-api/src/main/java/org/apache/felix/gogo/commands/basic/ActionPreparator.java b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/basic/ActionPreparator.java
new file mode 100644
index 0000000..65fe24e
--- /dev/null
+++ b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/basic/ActionPreparator.java
@@ -0,0 +1,31 @@
+/*
+ * 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.commands.basic;
+
+import java.util.List;
+
+import org.apache.felix.gogo.commands.Action;
+import org.apache.felix.service.command.CommandSession;
+
+@Deprecated
+public interface ActionPreparator {
+
+    boolean prepare(Action action, CommandSession session, List<Object> arguments) throws Exception;
+
+}

http://git-wip-us.apache.org/repos/asf/karaf/blob/1ee78df9/shell/command-api/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java
----------------------------------------------------------------------
diff --git a/shell/command-api/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java
new file mode 100644
index 0000000..6b7865e
--- /dev/null
+++ b/shell/command-api/src/main/java/org/apache/felix/gogo/commands/basic/DefaultActionPreparator.java
@@ -0,0 +1,566 @@
+/*
+ * 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.commands.basic;
+
+import static org.apache.karaf.shell.commands.ansi.SimpleAnsi.COLOR_DEFAULT;
+import static org.apache.karaf.shell.commands.ansi.SimpleAnsi.COLOR_RED;
+import static org.apache.karaf.shell.commands.ansi.SimpleAnsi.INTENSITY_BOLD;
+import static org.apache.karaf.shell.commands.ansi.SimpleAnsi.INTENSITY_NORMAL;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Field;
+import java.lang.reflect.Type;
+import java.util.*;
+import java.io.PrintStream;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.felix.gogo.commands.CommandException;
+import org.apache.felix.gogo.commands.Option;
+import org.apache.felix.gogo.commands.Action;
+import org.apache.felix.gogo.commands.Argument;
+import org.apache.felix.gogo.commands.Command;
+import org.apache.felix.gogo.commands.converter.DefaultConverter;
+import org.apache.felix.gogo.commands.converter.GenericType;
+import org.apache.felix.service.command.CommandSession;
+import org.apache.karaf.shell.console.NameScoping;
+
+@Deprecated
+public class DefaultActionPreparator implements ActionPreparator {
+
+    public static final Option HELP = new Option() {
+        public String name() {
+            return "--help";
+        }
+
+        public String[] aliases() {
+            return new String[]{};
+        }
+
+        public String description() {
+            return "Display this help message";
+        }
+
+        public boolean required() {
+            return false;
+        }
+
+        public boolean multiValued() {
+            return false;
+        }
+
+        public String valueToShowInHelp() {
+            return Option.DEFAULT_STRING;
+        }
+
+        public Class<? extends Annotation> annotationType() {
+            return Option.class;
+        }
+    };
+
+    public boolean prepare(Action action, CommandSession session, List<Object> params) throws Exception {
+        Map<Option, Field> options = new HashMap<Option, Field>();
+        Map<Argument, Field> arguments = new HashMap<Argument, Field>();
+        List<Argument> orderedArguments = new ArrayList<Argument>();
+        // Introspect
+        for (Class type = action.getClass(); type != null; type = type.getSuperclass()) {
+            for (Field field : type.getDeclaredFields()) {
+                Option option = field.getAnnotation(Option.class);
+                if (option != null) {
+                    options.put(option, field);
+                }
+                Argument argument = field.getAnnotation(Argument.class);
+                if (argument != null) {
+                    if (Argument.DEFAULT.equals(argument.name())) {
+                        final Argument delegate = argument;
+                        final String name = field.getName();
+                        argument = new Argument() {
+                            public String name() {
+                                return name;
+                            }
+
+                            public String description() {
+                                return delegate.description();
+                            }
+
+                            public boolean required() {
+                                return delegate.required();
+                            }
+
+                            public int index() {
+                                return delegate.index();
+                            }
+
+                            public boolean multiValued() {
+                                return delegate.multiValued();
+                            }
+
+                            public String valueToShowInHelp() {
+                                return delegate.valueToShowInHelp();
+                            }
+
+                            public Class<? extends Annotation> annotationType() {
+                                return delegate.annotationType();
+                            }
+                        };
+                    }
+                    arguments.put(argument, field);
+                    int index = argument.index();
+                    while (orderedArguments.size() <= index) {
+                        orderedArguments.add(null);
+                    }
+                    if (orderedArguments.get(index) != null) {
+                        throw new IllegalArgumentException("Duplicate argument index: " + index);
+                    }
+                    orderedArguments.set(index, argument);
+                }
+            }
+        }
+        // Check indexes are correct
+        for (int i = 0; i < orderedArguments.size(); i++) {
+            if (orderedArguments.get(i) == null) {
+                throw new IllegalArgumentException("Missing argument for index: " + i);
+            }
+        }
+        // Populate
+        Map<Option, Object> optionValues = new HashMap<Option, Object>();
+        Map<Argument, Object> argumentValues = new HashMap<Argument, Object>();
+        boolean processOptions = true;
+        int argIndex = 0;
+        for (Iterator<Object> it = params.iterator(); it.hasNext(); ) {
+            Object param = it.next();
+            // Check for help
+            if (HELP.name().equals(param) || Arrays.asList(HELP.aliases()).contains(param)) {
+                printUsage(session, action, options, arguments, System.out);
+                return false;
+            }
+            if (processOptions && param instanceof String && ((String) param).startsWith("-")) {
+                boolean isKeyValuePair = ((String) param).indexOf('=') != -1;
+                String name;
+                Object value = null;
+                if (isKeyValuePair) {
+                    name = ((String) param).substring(0, ((String) param).indexOf('='));
+                    value = ((String) param).substring(((String) param).indexOf('=') + 1);
+                } else {
+                    name = (String) param;
+                }
+                Option option = null;
+                for (Option opt : options.keySet()) {
+                    if (name.equals(opt.name()) || Arrays.asList(opt.aliases()).contains(name)) {
+                        option = opt;
+                        break;
+                    }
+                }
+                if (option == null) {
+                    Command command = action.getClass().getAnnotation(Command.class);
+                    if (command != null) {
+                        throw new CommandException(COLOR_RED
+                                                   + "Error executing command "
+                                                   + command.scope() + ":" 
+                                                   + INTENSITY_BOLD + command.name() + INTENSITY_NORMAL
+                                                   + " undefined option "
+                                                   + INTENSITY_BOLD + param + INTENSITY_NORMAL
+                                                   + COLOR_DEFAULT,
+                                                   "Undefined option: " + param
+                        );
+                    } else {
+                        throw new CommandException("Undefined option: " + param);
+                    }
+                }
+                Field field = options.get(option);
+                if (value == null && (field.getType() == boolean.class || field.getType() == Boolean.class)) {
+                    value = Boolean.TRUE;
+                }
+                if (value == null && it.hasNext()) {
+                    value = it.next();
+                }
+                if (value == null) {
+                    Command command = action.getClass().getAnnotation(Command.class);
+                    if (command != null) {
+                        throw new CommandException(COLOR_RED
+                                                   + "Error executing command "
+                                                   + command.scope() + ":" 
+                                                   + INTENSITY_BOLD + command.name() + INTENSITY_NORMAL
+                                                   + " missing value for option "
+                                                   + INTENSITY_BOLD + param + INTENSITY_NORMAL
+                                                   + COLOR_DEFAULT,
+                                                   "Missing value for option: " + param
+                        );
+                    } else {
+                        throw new CommandException("Missing value for option: " + param);
+                    }
+                }
+                if (option.multiValued()) {
+                    List<Object> l = (List<Object>) optionValues.get(option);
+                    if (l == null) {
+                        l = new ArrayList<Object>();
+                        optionValues.put(option, l);
+                    }
+                    l.add(value);
+                } else {
+                    optionValues.put(option, value);
+                }
+            } else {
+                processOptions = false;
+                if (argIndex >= orderedArguments.size()) {
+                    Command command = action.getClass().getAnnotation(Command.class);
+                    if (command != null) {
+                        throw new CommandException(COLOR_RED
+                                                   + "Error executing command "
+                                                   + command.scope() + ":" 
+                                                   + INTENSITY_BOLD + command.name() + INTENSITY_NORMAL
+                                                   + ": too many arguments specified"
+                                                   + INTENSITY_BOLD + param + INTENSITY_NORMAL
+                                                   + COLOR_DEFAULT,
+                                                   "Too many arguments specified"
+                        );
+                    } else {
+                        throw new CommandException("Too many arguments specified");
+                    }
+                }
+                Argument argument = orderedArguments.get(argIndex);
+                if (!argument.multiValued()) {
+                    argIndex++;
+                }
+                if (argument.multiValued()) {
+                    List<Object> l = (List<Object>) argumentValues.get(argument);
+                    if (l == null) {
+                        l = new ArrayList<Object>();
+                        argumentValues.put(argument, l);
+                    }
+                    l.add(param);
+                } else {
+                    argumentValues.put(argument, param);
+                }
+            }
+        }
+        // Check required arguments / options
+        for (Option option : options.keySet()) {
+            if (option.required() && optionValues.get(option) == null) {
+                Command command = action.getClass().getAnnotation(Command.class);
+                if (command != null) {
+                    throw new CommandException(COLOR_RED
+                                               + "Error executing command "
+                                               + command.scope() + ":" 
+                                               + INTENSITY_BOLD + command.name() + INTENSITY_NORMAL
+                                               + ": option "
+                                               + INTENSITY_BOLD + option.name() + INTENSITY_NORMAL
+                                               + " is required"
+                                               + COLOR_DEFAULT,
+                            "Option " + option.name() + " is required"
+                    );
+                } else {
+                    throw new CommandException("Option " + option.name() + " is required");
+                }
+            }
+        }
+        for (Argument argument : orderedArguments) {
+            if (argument.required() && argumentValues.get(argument) == null) {
+                Command command = action.getClass().getAnnotation(Command.class);
+                if (command != null) {
+                    throw new CommandException(COLOR_RED
+                                               + "Error executing command "
+                                               + command.scope() + ":" 
+                                               + INTENSITY_BOLD + command.name() + INTENSITY_NORMAL
+                                               + ": argument "
+                                               + INTENSITY_BOLD + argument.name() + INTENSITY_NORMAL
+                                               + " is required"
+                                               + COLOR_DEFAULT,
+                                               "Argument " + argument.name() + " is required"
+                    );
+                } else {
+                    throw new CommandException("Argument " + argument.name() + " is required");
+                }
+            }
+        }
+        // Convert and inject values
+        for (Map.Entry<Option, Object> entry : optionValues.entrySet()) {
+            Field field = options.get(entry.getKey());
+            Object value;
+            try {
+                value = convert(action, session, entry.getValue(), field.getGenericType());
+            } catch (Exception e) {
+                Command command = action.getClass().getAnnotation(Command.class);
+                if (command != null) {
+                    throw new CommandException(COLOR_RED
+                                               + "Error executing command "
+                                               + command.scope() + ":" 
+                                               + INTENSITY_BOLD + command.name() + INTENSITY_NORMAL
+                                               + ": unable to convert option "
+                                               + INTENSITY_BOLD + entry.getKey().name() + INTENSITY_NORMAL
+                                               + " with value '" + entry.getValue() + "' to type "
+                                               + new GenericType(field.getGenericType()).toString()
+                                               + COLOR_DEFAULT,
+                            "Unable to convert option " + entry.getKey().name() + " with value '"
+                                    + entry.getValue() + "' to type " + new GenericType(field.getGenericType()).toString(),
+                            e
+                    );
+                } else {
+                    throw new CommandException("Unable to convert option " + entry.getKey().name() + " with value '"
+                            + entry.getValue() + "' to type " + new GenericType(field.getGenericType()).toString(),
+                            e);
+                }
+            }
+            field.setAccessible(true);
+            field.set(action, value);
+        }
+        for (Map.Entry<Argument, Object> entry : argumentValues.entrySet()) {
+            Field field = arguments.get(entry.getKey());
+            Object value;
+            try {
+                value = convert(action, session, entry.getValue(), field.getGenericType());
+            } catch (Exception e) {
+                Command command = action.getClass().getAnnotation(Command.class);
+                if (command != null) {
+                    throw new CommandException(COLOR_RED
+                                               + "Error executing command "
+                                               + command.scope() + ":" 
+                                               + INTENSITY_BOLD + command.name() + INTENSITY_NORMAL
+                                               + ": unable to convert argument "
+                                               + INTENSITY_BOLD + entry.getKey().name() + INTENSITY_NORMAL
+                                               + " with value '" + entry.getValue() + "' to type "
+                                               + new GenericType(field.getGenericType()).toString()
+                                               + COLOR_DEFAULT,
+                            "Unable to convert argument " + entry.getKey().name() + " with value '"
+                                    + entry.getValue() + "' to type " + new GenericType(field.getGenericType()).toString(),
+                            e
+                    );
+                } else {
+                    throw new CommandException("Unable to convert argument " + entry.getKey().name() + " with value '"
+                            + entry.getValue() + "' to type " + new GenericType(field.getGenericType()).toString(),
+                            e);
+                }
+            }
+            field.setAccessible(true);
+            field.set(action, value);
+        }
+        return true;
+    }
+
+    protected void printUsage(CommandSession session, Action action, Map<Option, Field> optionsMap, Map<Argument, Field> argsMap, PrintStream out) {
+        Command command = action.getClass().getAnnotation(Command.class);
+        if (command != null) {
+            
+            List<Argument> arguments = new ArrayList<Argument>(argsMap.keySet());
+            Collections.sort(arguments, new Comparator<Argument>() {
+                public int compare(Argument o1, Argument o2) {
+                    return Integer.valueOf(o1.index()).compareTo(Integer.valueOf(o2.index()));
+                }
+            });
+            Set<Option> options = new HashSet<Option>(optionsMap.keySet());
+            options.add(HELP);
+            boolean globalScope = NameScoping.isGlobalScope(session, command.scope());
+            if (command != null && (command.description() != null || command.name() != null)) {
+                out.println(INTENSITY_BOLD + "DESCRIPTION" + INTENSITY_NORMAL);
+                out.print("        ");
+                if (command.name() != null) {
+                    if (globalScope) {
+                        out.println(INTENSITY_BOLD + command.name() + INTENSITY_NORMAL);
+                    } else {
+                        out.println(command.scope() + ":" + INTENSITY_BOLD + command.name() + INTENSITY_NORMAL);
+                    }
+                    out.println();
+                }
+                out.print("\t");
+                out.println(command.description());
+                out.println();
+            }
+            StringBuffer syntax = new StringBuffer();
+            if (command != null) {
+                if (globalScope) {
+                    syntax.append(command.name());
+                } else {
+                    syntax.append(String.format("%s:%s", command.scope(), command.name()));
+                }
+            }
+            if (options.size() > 0) {
+                syntax.append(" [options]");
+            }
+            if (arguments.size() > 0) {
+                syntax.append(' ');
+                for (Argument argument : arguments) {
+                    if (!argument.required()) {
+                        syntax.append(String.format("[%s] ", argument.name()));
+                    } else {
+                        syntax.append(String.format("%s ", argument.name()));
+                    }
+                }
+            }
+            int width = getWidth(session);
+            out.println(INTENSITY_BOLD + "SYNTAX" + INTENSITY_NORMAL);
+            out.print("        ");
+            out.println(syntax.toString());
+            out.println();
+            if (arguments.size() > 0) {
+                out.println(INTENSITY_BOLD + "ARGUMENTS" + INTENSITY_NORMAL);
+                for (Argument argument : arguments) {
+                    out.print("        ");
+                    out.println(INTENSITY_BOLD + argument.name() + INTENSITY_NORMAL);
+                    
+                    printFormatted("                ", argument.description(), width, out);
+                    if (!argument.required()) {
+                        if (argument.valueToShowInHelp() != null && argument.valueToShowInHelp().length() != 0) {
+                            try {
+                                if (Argument.DEFAULT_STRING.equals(argument.valueToShowInHelp())) {
+                                    argsMap.get(argument).setAccessible(true);
+                                    Object o = argsMap.get(argument).get(action);
+                                    printObjectDefaultsTo(out, o);
+                                } else {
+                                    printDefaultsTo(out, argument.valueToShowInHelp());
+                                }
+                            } catch (Throwable t) {
+                                // Ignore
+                            }
+                        }
+                    }
+                }
+                out.println();
+            }
+            if (options.size() > 0) {
+                out.println(INTENSITY_BOLD + "OPTIONS" + INTENSITY_NORMAL);
+                for (Option option : options) {
+                    String opt = option.name();
+                    for (String alias : option.aliases()) {
+                        opt += ", " + alias;
+                    }
+                    out.print("        ");
+                    out.println(INTENSITY_BOLD + opt + INTENSITY_NORMAL);
+                    printFormatted("                ", option.description(), width, out);
+                    if (option.valueToShowInHelp() != null && option.valueToShowInHelp().length() != 0) {
+                        try {
+                            if (Option.DEFAULT_STRING.equals(option.valueToShowInHelp())) {
+                                optionsMap.get(option).setAccessible(true);
+                                Object o = optionsMap.get(option).get(action);
+                                printObjectDefaultsTo(out, o);
+                            } else {
+                                printDefaultsTo(out, option.valueToShowInHelp());
+                            }
+                        } catch (Throwable t) {
+                            // Ignore
+                        }
+                    }
+                }
+                out.println();
+            }
+            if (command.detailedDescription().length() > 0) {
+                out.println(INTENSITY_BOLD + "DETAILS" + INTENSITY_NORMAL);
+                String desc = loadDescription(action.getClass(), command.detailedDescription());
+                printFormatted("        ", desc, width, out);
+            }
+        }
+    }
+
+    private void printObjectDefaultsTo(PrintStream out, Object o) {
+        if (o != null
+                && (!(o instanceof Boolean) || ((Boolean) o))
+                && (!(o instanceof Number) || ((Number) o).doubleValue() != 0.0)) {
+            printDefaultsTo(out, o.toString());
+        }
+    }
+
+    private void printDefaultsTo(PrintStream out, String value) {
+        out.print("                (defaults to ");
+        out.print(value);
+        out.println(")");
+    }
+
+    protected String loadDescription(Class clazz, String desc) {
+        if (desc.startsWith("classpath:")) {
+            InputStream is = clazz.getResourceAsStream(desc.substring("classpath:".length()));
+            if (is == null) {
+                is = clazz.getClassLoader().getResourceAsStream(desc.substring("classpath:".length()));
+            }
+            if (is == null) {
+                desc = "Unable to load description from " + desc;
+            } else {
+                try {
+                    Reader r = new InputStreamReader(is);
+                    StringWriter sw = new StringWriter();
+                    int c;
+                    while ((c = r.read()) != -1) {
+                        sw.append((char) c);
+                    }
+                    desc = sw.toString();
+                } catch (IOException e) {
+                    desc = "Unable to load description from " + desc;
+                } finally {
+                    try {
+                        is.close();
+                    } catch (IOException e) {
+                        // Ignore
+                    }
+                }
+            }
+        }
+        return desc;
+    }
+
+    // TODO move this to a helper class?
+    public static void printFormatted(String prefix, String str, int termWidth, PrintStream out) {
+        printFormatted(prefix, str, termWidth, out, true);
+    }
+
+    public static void printFormatted(String prefix, String str, int termWidth, PrintStream out, boolean prefixFirstLine) {
+        int pfxLen = length(prefix);
+        int maxwidth = termWidth - pfxLen;
+        Pattern wrap = Pattern.compile("(\\S\\S{" + maxwidth + ",}|.{1," + maxwidth + "})(\\s+|$)");
+        int cur = 0;
+        while (cur >= 0) {
+            int lst = str.indexOf('\n', cur);
+            String s = (lst >= 0) ? str.substring(cur, lst) : str.substring(cur);
+            if (s.length() == 0) {
+                out.println();
+            } else {
+                Matcher m = wrap.matcher(s);
+                while (m.find()) {
+                    if (cur > 0 || prefixFirstLine) {
+                        out.print(prefix);
+                    }
+                    out.println(m.group());
+                }
+            }
+            if (lst >= 0) {
+                cur = lst + 1;
+            } else {
+                break;
+            }
+        }
+    }
+
+    public static int length(String str) {
+        return str.length();
+    }
+
+    protected Object convert(Action action, CommandSession session, Object value, Type toType) throws Exception {
+        if (toType == String.class) {
+            return value != null ? value.toString() : null;
+        }
+        return new DefaultConverter(action.getClass().getClassLoader()).convert(value, toType);
+    }
+
+    private int getWidth(CommandSession session) {
+        Object cols = session.get("COLUMNS");
+        return  (cols != null && cols instanceof Integer) ? (Integer)cols : 80;
+    }
+}