Move ServiceMix Kernel trunk into Felix

git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@768912 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/karaf/gshell/gshell-core/pom.xml b/karaf/gshell/gshell-core/pom.xml
new file mode 100644
index 0000000..19e9a27
--- /dev/null
+++ b/karaf/gshell/gshell-core/pom.xml
@@ -0,0 +1,480 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <!--
+
+        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.servicemix.kernel.gshell</groupId>
+        <artifactId>gshell</artifactId>
+        <version>1.2.0-SNAPSHOT</version>
+    </parent>
+
+    <groupId>org.apache.servicemix.kernel.gshell</groupId>
+    <artifactId>org.apache.servicemix.kernel.gshell.core</artifactId>
+    <packaging>bundle</packaging>
+    <version>1.2.0-SNAPSHOT</version>
+    <name>Apache ServiceMix Kernel :: GShell Core</name>
+
+    <description>
+        Provides the OSGi GShell integration
+    </description>
+
+    <properties>
+        <gshell.osgi.import>
+            org.springframework.aop,
+            org.springframework.aop.framework,
+            org.springframework.beans.factory.annotation,
+            org.springframework.context.annotation,
+            org.springframework.osgi.service.importer,
+            org.aopalliance.aop,
+            org.apache.commons.vfs.provider.temp,
+            org.apache.commons.vfs.provider.ram,
+            jline*,
+            org.apache.servicemix.kernel.jaas.config;resolution:=optional,
+            org.apache.servicemix.kernel.version;resolution:=optional, 
+            org.apache.servicemix.kernel.main.spi;resolution:=optional;version="1.0.0",
+            org.codehaus.plexus*;resolution:=optional,
+            org.apache.sshd.server.keyprovider,
+            org.apache.sshd.server.jaas,
+            org.jsecurity*;resolution:=optional,
+            *
+        </gshell.osgi.import>
+        <!-- TODO: remove plexus util package -->
+        <gshell.osgi.export>
+            org.apache.geronimo.gshell*;version="1.0.0.alpha-2-SNAPSHOT";-split-package:=merge-first,
+            org.apache.servicemix.kernel.gshell.core*,
+            org.codehaus.plexus.interpolation*;-split-package:=merge-first,
+            org.codehaus.plexus.util;-split-package:=merge-first
+        </gshell.osgi.export>
+    </properties>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.servicemix.kernel</groupId>
+            <artifactId>org.apache.servicemix.kernel.main</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.servicemix.kernel.jaas</groupId>
+            <artifactId>org.apache.servicemix.kernel.jaas.config</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.servicemix.bundles</groupId>
+            <artifactId>org.apache.servicemix.bundles.cglib</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.osgi</groupId>
+            <artifactId>spring-osgi-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.gshell.commands</groupId>
+            <artifactId>gshell-builtin</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>oro</groupId>
+                    <artifactId>oro</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>commons-vfs</groupId>
+                    <artifactId>commons-vfs</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.gshell.commands</groupId>
+            <artifactId>gshell-file</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.gshell.commands</groupId>
+            <artifactId>gshell-network</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.gshell.commands</groupId>
+            <artifactId>gshell-shell</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.gshell.commands</groupId>
+            <artifactId>gshell-ssh</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.gshell.commands</groupId>
+            <artifactId>gshell-text</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.geronimo.gshell.wisdom</groupId>
+            <artifactId>gshell-wisdom-core</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.apache.geronimo.gshell.support</groupId>
+                    <artifactId>gshell-ivy</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>org.apache.geronimo.gshell.support</groupId>
+                    <artifactId>gshell-xstore</artifactId>
+                </exclusion>
+                <exclusion>
+                    <groupId>commons-jexl</groupId>
+                    <artifactId>commons-jexl</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.codehaus.plexus</groupId>
+            <artifactId>plexus-utils</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-aop</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-jdk14</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.servicemix.bundles</groupId>
+            <artifactId>org.apache.servicemix.bundles.commons-httpclient</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>commons-codec</groupId>
+                    <artifactId>commons-codec</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.servicemix.bundles</groupId>
+            <artifactId>org.apache.servicemix.bundles.commons-codec</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.servicemix.bundles</groupId>
+            <artifactId>org.apache.servicemix.bundles.commons-jexl</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>junit</groupId>
+                    <artifactId>junit</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.servicemix.bundles</groupId>
+            <artifactId>org.apache.servicemix.bundles.commons-vfs</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.servicemix.bundles</groupId>
+            <artifactId>org.apache.servicemix.bundles.oro</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.mina</groupId>
+            <artifactId>mina-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sshd</groupId>
+            <artifactId>sshd-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.servicemix.bundles</groupId>
+            <artifactId>org.apache.servicemix.bundles.junit</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.servicemix.bundles</groupId>
+            <artifactId>org.apache.servicemix.bundles.jline</artifactId>
+        </dependency>
+        
+        <!-- jsecurity is a dependency for the ssh commands -->
+        <dependency>
+            <groupId>org.jsecurity</groupId>
+            <artifactId>jsecurity</artifactId>
+            <version>0.9.0-RC2</version>
+            <exclusions>
+                <exclusion>
+                    <groupId>commons-logging</groupId>
+                    <artifactId>commons-logging</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+    </dependencies>
+
+    <build>
+        <resources>
+            <resource>
+                <directory>${pom.basedir}/src/main/resources</directory>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+            </resource>
+            <resource>
+                <directory>${pom.basedir}/src/main/filtered-resources</directory>
+                <filtering>true</filtering>
+                <includes>
+                    <include>**/*</include>
+                </includes>
+            </resource>
+        </resources>
+        <plugins>
+            <plugin>
+                <groupId>org.codehaus.mojo</groupId>
+                <artifactId>exec-maven-plugin</artifactId>
+                <configuration>
+                    <mainClass>Main</mainClass>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <configuration>
+                    <instructions>
+                        <Bundle-SymbolicName>${artifactId}</Bundle-SymbolicName>
+                        <Import-Package>${gshell.osgi.import}</Import-Package>
+                        <Export-Package>${gshell.osgi.export}</Export-Package>
+                        <Spring-Context>*;publish-context:=false;create-asynchronously:=false</Spring-Context>
+                    </instructions>
+                    <unpackBundle>true</unpackBundle>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-shade-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <phase>package</phase>
+                        <goals>
+                            <goal>shade</goal>
+                        </goals>
+                        <configuration>
+                            <artifactSet>
+                                <includes>
+                                    <include>org.apache.geronimo.gshell:gshell-api</include>
+                                    <include>org.apache.geronimo.gshell:gshell-application</include>
+                                    <include>org.apache.geronimo.gshell:gshell-parser</include>
+                                    <include>org.apache.geronimo.gshell.commands:gshell-builtin</include>
+                                    <include>org.apache.geronimo.gshell.commands:gshell-file</include>
+                                    <include>org.apache.geronimo.gshell.commands:gshell-network</include>
+                                    <include>org.apache.geronimo.gshell.commands:gshell-shell</include>
+                                    <include>org.apache.geronimo.gshell.commands:gshell-text</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-ansi</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-artifact</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-chronos</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-clp</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-console</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-event</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-i18n</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-interpolation</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-io</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-security</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-spring</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-terminal</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-vfs</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-vfs-meta</include>
+                                    <include>org.apache.geronimo.gshell.support:gshell-yarn</include>
+                                    <include>org.apache.geronimo.gshell.wisdom:gshell-wisdom-core</include>
+                                    <include>org.apache.geronimo.gshell.wisdom:gshell-wisdom-bootstrap</include>
+                                    <include>org.codehaus.plexus:plexus-utils</include>
+                                    <include>org.codehaus.plexus:plexus-interpolation</include>
+                                    <include>${project.groupId}:${project.artifactId}</include>
+                                </includes>
+                            </artifactSet>
+                            <filters>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell:gshell-api</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell:gshell-application</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell:gshell-parser</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.commands:gshell-builtin</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.commands:gshell-file</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.commands:gshell-network</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.commands:gshell-shell</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.commands:gshell-ssh</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.commands:gshell-text</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-ansi</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-artifact</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-chronos</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-clp</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-console</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-event</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-i18n</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-interpolation</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-io</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-security</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-spring</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-terminal</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-vfs</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-vfs-meta</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.support:gshell-yarn</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.wisdom:gshell-wisdom-core</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.apache.geronimo.gshell.wisdom:gshell-wisdom-bootstrap</artifact>
+                                    <excludes>
+                                        <exclude>org/apache/geronimo/gshell/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.codehaus.plexus:plexus-utils</artifact>
+                                    <excludes>
+                                        <exclude>org/codehaus/plexus/**</exclude>
+                                    </excludes>
+                                </filter>
+                                <filter>
+                                    <artifact>org.codehaus.plexus:plexus-interpolation</artifact>
+                                    <excludes>
+                                        <exclude>org/codehaus/plexus/**</exclude>
+                                    </excludes>
+                                </filter>
+                            </filters>
+                            <createSourcesJar>${createSourcesJar}</createSourcesJar>
+                            <promoteTransitiveDependencies>true</promoteTransitiveDependencies>
+                            <createDependencyReducedPom>true</createDependencyReducedPom>
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+</project>
diff --git a/karaf/gshell/gshell-core/src/main/filtered-resources/org/apache/servicemix/kernel/gshell/core/servicemix-version.properties b/karaf/gshell/gshell-core/src/main/filtered-resources/org/apache/servicemix/kernel/gshell/core/servicemix-version.properties
new file mode 100644
index 0000000..1fc0355
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/filtered-resources/org/apache/servicemix/kernel/gshell/core/servicemix-version.properties
@@ -0,0 +1,20 @@
+##
+## 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.
+##
+
+version=${pom.version}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/shell/FindAction.java b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/shell/FindAction.java
new file mode 100644
index 0000000..203e340
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/shell/FindAction.java
@@ -0,0 +1,208 @@
+/*
+ * 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.geronimo.gshell.commands.shell;
+
+import java.net.URI;
+
+import org.apache.commons.vfs.FileObject;
+import org.apache.commons.vfs.FileSelectInfo;
+import org.apache.commons.vfs.FileSelector;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileType;
+import org.apache.geronimo.gshell.clp.Argument;
+import org.apache.geronimo.gshell.clp.Option;
+import org.apache.geronimo.gshell.command.CommandAction;
+import org.apache.geronimo.gshell.command.CommandContext;
+import org.apache.geronimo.gshell.io.IO;
+import org.apache.geronimo.gshell.vfs.FileObjects;
+import org.apache.geronimo.gshell.vfs.selector.AggregateFileSelector;
+import org.apache.geronimo.gshell.vfs.support.VfsActionSupport;
+import org.apache.oro.text.GlobCompiler;
+import org.apache.oro.text.regex.MalformedPatternException;
+import org.apache.oro.text.regex.Pattern;
+import org.apache.oro.text.regex.PatternCompiler;
+import org.apache.oro.text.regex.PatternMatcher;
+import org.apache.oro.text.regex.Perl5Matcher;
+
+/**
+ * Find files in a hierarchy.
+ *
+ * TODO: remove this file when gshell is upgraded
+ *
+ * @version $Rev: 722797 $ $Date: 2008-12-03 08:18:16 +0100 (Wed, 03 Dec 2008) $
+ */
+public class FindAction
+    extends VfsActionSupport
+{
+    private final AggregateFileSelector selector = new AggregateFileSelector();
+
+    @Option(name="-name")
+    private void addNameFilter(final String name) throws MalformedPatternException {
+        log.debug("Adding -name selector for: {}", name);
+        selector.getSelectors().add(new NameSelector(name));
+    }
+
+    @Option(name="-iname")
+    private void addiNameFilter(final String name) throws MalformedPatternException {
+        log.debug("Adding -iname selector for: {}", name);
+        selector.getSelectors().add(new NameSelector(name, true));
+    }
+
+    @Option(name="-type")
+    private void addTypeFilter(final Type type) {
+        log.debug("Adding -type selector for: {}", type);
+        selector.getSelectors().add(new TypeSelector(type));
+    }
+
+    @Argument(required=true)
+    private String path;
+
+    public Object execute(final CommandContext context) throws Exception {
+        assert context != null;
+        IO io = context.getIo();
+
+        FileObject root = resolveFile(context, path);
+
+        ensureFileExists(root);
+
+        find(context, root, selector);
+
+        FileObjects.close(root);
+
+        return CommandAction.Result.SUCCESS;
+    }
+
+    private void find(final CommandContext context, final FileObject file, final FileSelector selector) throws FileSystemException {
+        assert context != null;
+        assert file != null;
+        assert selector != null;
+
+        FileObject[] files = file.findFiles(selector);
+
+        if (files != null && files.length != 0) {
+            for (FileObject child : files) {
+                display(context, child, file);
+            }
+        }
+    }
+
+    private void display(final CommandContext context, final FileObject file, final FileObject root) throws FileSystemException {
+        assert context != null;
+        assert file != null;
+
+        String path;
+        try {
+            path = new URI(this.path).resolve(root.getURL().toURI().relativize(file.getURL().toURI())).toString();
+        } catch (Exception e) {
+            path = file.getName().getPath();
+        }
+        IO io = context.getIo();
+        io.info(path);
+    }
+
+    //
+    // Type & TypeSelector
+    //
+
+    private enum Type
+    {
+        F, // normal file
+        D, // directory
+    }
+
+    private class TypeSelector
+        implements FileSelector
+    {
+        private final Type type;
+
+        public TypeSelector(final Type type) {
+            assert type != null;
+
+            this.type = type;
+
+            log.trace("Type: {}", type);
+        }
+
+        public boolean includeFile(final FileSelectInfo selection) throws Exception {
+            assert selection != null;
+
+            FileType ftype = selection.getFile().getType();
+
+            switch (type) {
+                case D:
+                    return ftype == FileType.FOLDER;
+
+                case F:
+                    return ftype == FileType.FILE;
+
+                // TODO: Handle FileType.FILE_OR_FOLDER
+
+                default:
+                    return false;
+            }
+        }
+
+        public boolean traverseDescendents(final FileSelectInfo selection) throws Exception {
+            return true;
+        }
+    }
+
+    //
+    // NameSelector
+    //
+
+    private class NameSelector
+        implements FileSelector
+    {
+        private final Pattern pattern;
+
+        private final PatternMatcher matcher;
+
+        public NameSelector(final String name, final boolean ignoreCase) throws MalformedPatternException {
+            assert name != null;
+
+            PatternCompiler compiler = new GlobCompiler();
+            int options;
+            if (ignoreCase) {
+                options = GlobCompiler.CASE_INSENSITIVE_MASK;
+            }
+            else {
+                options = GlobCompiler.DEFAULT_MASK;
+            }
+            this.pattern = compiler.compile(name, options);
+            this.matcher = new Perl5Matcher();
+
+            log.trace("Pattern: {}", pattern.getPattern());
+        }
+
+        public NameSelector(final String name) throws MalformedPatternException {
+            this(name, false);
+        }
+
+        public boolean includeFile(final FileSelectInfo selection) throws Exception {
+            assert selection != null;
+            return matcher.matches(selection.getFile().getName().getBaseName(), pattern);
+        }
+
+        public boolean traverseDescendents(final FileSelectInfo selection) throws Exception {
+            return true;
+        }
+    }
+}
\ No newline at end of file
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/JSecurityPasswordAuthenticator.java b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/JSecurityPasswordAuthenticator.java
new file mode 100644
index 0000000..d3bb6de
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/JSecurityPasswordAuthenticator.java
@@ -0,0 +1,84 @@
+/*
+ * 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.geronimo.gshell.commands.ssh;
+
+import org.apache.sshd.server.PasswordAuthenticator;
+import org.jsecurity.SecurityUtils;
+import org.jsecurity.authc.AuthenticationException;
+import org.jsecurity.authc.UsernamePasswordToken;
+import org.jsecurity.mgt.SecurityManager;
+import org.jsecurity.subject.Subject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * <a href="http://jsecurity.org">JSecurity</a> {@link PasswordAuthenticator}.
+ *
+ * @version $Rev: 722797 $ $Date: 2008-12-03 08:18:16 +0100 (Wed, 03 Dec 2008) $
+ */
+public class JSecurityPasswordAuthenticator
+    implements PasswordAuthenticator
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private final SecurityManager securityManager;
+
+    public JSecurityPasswordAuthenticator(final SecurityManager securityManager) {
+        // securityManager can be null
+        this.securityManager = securityManager;
+    }
+
+    public JSecurityPasswordAuthenticator() {
+        this(null);
+    }
+
+    public Object authenticate(final String username, final String password) {
+        assert username != null;
+        assert password != null;
+
+        log.debug("Authenticating: {}/{}", username, password);
+
+        Subject currentUser;
+
+        if (securityManager != null) {
+            currentUser = securityManager.getSubject();
+        }
+        else {
+            currentUser = SecurityUtils.getSubject();
+        }
+
+        if (currentUser.isAuthenticated()) {
+            log.debug("Logging out current user: {}", currentUser.getPrincipal());
+            currentUser.logout();
+        }
+
+        try {
+            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
+            currentUser.login(token);
+            Object principal = currentUser.getPrincipal();
+            log.info("User [{}] logged in successfully", principal);
+            return principal;
+        }
+        catch (AuthenticationException e) {
+            log.error("Authentication failed: " + e, e);
+            return null;
+        }
+    }
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/ShellFactoryImpl.java b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/ShellFactoryImpl.java
new file mode 100644
index 0000000..9795f01
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/ShellFactoryImpl.java
@@ -0,0 +1,267 @@
+/*
+ * 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.geronimo.gshell.commands.ssh;
+
+import org.apache.sshd.server.ShellFactory;
+import jline.Completor;
+import jline.History;
+import org.apache.geronimo.gshell.command.Variables;
+import org.apache.geronimo.gshell.commandline.CommandLineExecutor;
+import org.apache.geronimo.gshell.console.Console;
+import org.apache.geronimo.gshell.console.JLineConsole;
+import org.apache.geronimo.gshell.console.completer.AggregateCompleter;
+import org.apache.geronimo.gshell.io.Closer;
+import org.apache.geronimo.gshell.io.IO;
+import org.apache.geronimo.gshell.notification.ExitNotification;
+import org.apache.geronimo.gshell.shell.ShellContext;
+import org.apache.geronimo.gshell.shell.ShellContextHolder;
+import org.apache.geronimo.gshell.registry.CommandResolver;
+import org.apache.geronimo.gshell.application.Application;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * SSHD {@link ShellFactory} which provides access to GShell.
+ *
+ * @version $Rev: 731517 $ $Date: 2009-01-05 11:25:19 +0100 (Mon, 05 Jan 2009) $
+ */
+public class ShellFactoryImpl
+    implements ShellFactory
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private Application application;
+
+    private Console.Prompter prompter;
+
+    private CommandLineExecutor executor;
+
+    private History history;
+
+    private List<Completor> completers;
+
+    private Console.ErrorHandler errorHandler;
+
+    public Console.Prompter getPrompter() {
+        return prompter;
+    }
+
+    public void setPrompter(final Console.Prompter prompter) {
+        this.prompter = prompter;
+    }
+
+    public CommandLineExecutor getExecutor() {
+        return executor;
+    }
+
+    public void setExecutor(final CommandLineExecutor executor) {
+        this.executor = executor;
+    }
+
+    public History getHistory() {
+        return history;
+    }
+
+    public void setHistory(final History history) {
+        this.history = history;
+    }
+
+    public List<Completor> getCompleters() {
+        return completers;
+    }
+
+    public void setCompleters(final List<Completor> completers) {
+        this.completers = completers;
+    }
+
+    public Console.ErrorHandler getErrorHandler() {
+        return errorHandler;
+    }
+
+    public void setErrorHandler(final Console.ErrorHandler errorHandler) {
+        this.errorHandler = errorHandler;
+    }
+
+    public Application getApplication() {
+        return application;
+    }
+
+    public void setApplication(Application application) {
+        this.application = application;
+    }
+
+    public Shell createShell() {
+        return new ShellImpl();
+    }
+
+    public class ShellImpl
+        implements ShellFactory.Shell, org.apache.geronimo.gshell.shell.Shell, ShellContext, Runnable
+    {
+        private InputStream in;
+
+        private OutputStream out;
+
+        private OutputStream err;
+
+        private ExitCallback callback;
+
+        private IO io;
+
+        private Variables variables;
+
+        private boolean closed;
+
+        public void setInputStream(final InputStream in) {
+            this.in = in;
+        }
+
+        public void setOutputStream(final OutputStream out) {
+            this.out = out;
+        }
+
+        public void setErrorStream(final OutputStream err) {
+            this.err = err;
+        }
+
+        public void setExitCallback(ExitCallback callback) {
+            this.callback = callback;
+        }
+
+        public void start(final Map<String,String> env) throws IOException {
+            this.io = new IO(in, out, err, false);
+
+            // Create variables, inheriting the application ones
+            this.variables = new Variables(application.getVariables());
+            // Set up additional env
+            if (env != null) {
+                for (Map.Entry<String,String> entry : env.entrySet()) {
+                    this.variables.set(entry.getKey(), entry.getValue());
+                }
+            }
+            this.variables.set("gshell.prompt", application.getModel().getBranding().getPrompt());
+            this.variables.set(CommandResolver.GROUP, "/");
+            this.variables.set("gshell.username", env.get("USER"));
+            this.variables.set("gshell.hostname", application.getLocalHost());
+            // HACK: Add history for the 'history' command, since its not part of the Shell intf it can't really access it
+            this.variables.set("gshell.internal.history", getHistory(), true);
+            new Thread(this).start();
+        }
+
+        public void destroy() {
+            close();
+        }
+
+        public ShellContext getContext() {
+            return this;
+        }
+
+        public Object execute(final String line) throws Exception {
+
+            return executor.execute(getContext(), line);
+        }
+
+        public Object execute(final String command, final Object[] args) throws Exception {
+            return executor.execute(getContext(), args);
+        }
+
+        public Object execute(final Object... args) throws Exception {
+            return executor.execute(getContext(), args);
+        }
+
+        public boolean isOpened() {
+            return !closed;
+        }
+
+        public void close() {
+            closed = true;
+            Closer.close(in, out, err);
+            callback.onExit(0);
+        }
+
+        public boolean isInteractive() {
+            return false;
+        }
+
+        public void run(final Object... args) throws Exception {
+            Console.Executor executor = new Console.Executor()
+            {
+                public Result execute(final String line) throws Exception {
+                    assert line != null;
+                    try {
+                        ShellImpl.this.execute(line);
+                    }
+                    catch (ExitNotification n) {
+                        return Result.STOP;
+                    }
+                    return Result.CONTINUE;
+                }
+            };
+
+            IO io = getContext().getIo();
+
+            // Setup the console runner
+            JLineConsole console = new JLineConsole(executor, io);
+            console.setPrompter(getPrompter());
+            console.setErrorHandler(getErrorHandler());
+            console.setHistory(getHistory());
+
+            if (completers != null) {
+                // Have to use aggregate here to get the completion list to update properly
+                console.addCompleter(new AggregateCompleter(completers));
+            }
+            
+            console.run();
+        }
+
+        public org.apache.geronimo.gshell.shell.Shell getShell() {
+            return this;
+        }
+
+        public IO getIo() {
+            return io;
+        }
+
+        public Variables getVariables() {
+            return variables;
+        }
+
+        public void run() {
+            ShellContext ctx = ShellContextHolder.get(true);
+
+            try {
+                ShellContextHolder.set(getContext());
+                run(new Object[0]);
+            }
+            catch (Exception e) {
+                log.error("Unhandled failure: " + e, e);
+            }
+            finally {
+                ShellContextHolder.set(ctx);
+                close();
+            }
+        }
+    }
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/SshAction.java b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/SshAction.java
new file mode 100644
index 0000000..cafc437
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/SshAction.java
@@ -0,0 +1,169 @@
+/*
+ * 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.geronimo.gshell.commands.ssh;
+
+import org.apache.sshd.ClientChannel;
+import org.apache.sshd.ClientSession;
+import org.apache.sshd.SshClient;
+import org.apache.sshd.client.future.ConnectFuture;
+import org.apache.sshd.common.util.NoCloseInputStream;
+import org.apache.sshd.common.util.NoCloseOutputStream;
+import org.apache.geronimo.gshell.clp.Argument;
+import org.apache.geronimo.gshell.clp.Option;
+import org.apache.geronimo.gshell.command.CommandAction;
+import org.apache.geronimo.gshell.command.CommandContext;
+import org.apache.geronimo.gshell.i18n.MessageSource;
+import org.apache.geronimo.gshell.io.IO;
+import org.apache.geronimo.gshell.io.PromptReader;
+import org.apache.geronimo.gshell.spring.BeanContainer;
+import org.apache.geronimo.gshell.spring.BeanContainerAware;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Connect to a SSH server.
+ *
+ * @version $Rev: 721244 $ $Date: 2008-11-27 18:19:56 +0100 (Thu, 27 Nov 2008) $
+ */
+public class SshAction
+    implements CommandAction, BeanContainerAware
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Option(name="-l", aliases={"--username"})
+    private String username;
+
+    @Option(name="-P", aliases={"--password"})
+    private String password;
+
+    @Argument(required=true)
+    private String hostname;
+
+    @Option(name="-p", aliases={"--port"})
+    private int port = 22;
+
+    private BeanContainer container;
+
+	private ClientSession session;
+
+    public void setBeanContainer(final BeanContainer container) {
+        assert container != null;
+        this.container = container;
+    }
+
+    /**
+     * Helper to validate that prompted username or password is not null or empty.
+     */
+    private class UsernamePasswordValidator
+        implements PromptReader.Validator
+    {
+        private String type;
+
+        private int count = 0;
+
+        private int max = 3;
+
+        public UsernamePasswordValidator(final String type) {
+            assert type != null;
+
+            this.type = type;
+        }
+
+        public boolean isValid(final String value) {
+            count++;
+
+            if (value != null && value.trim().length() > 0) {
+                return true;
+            }
+
+            if (count >= max) {
+                throw new RuntimeException("Too many attempts; failed to prompt user for " + type + " after " + max + " tries");
+            }
+
+            return false;
+        }
+    }
+
+    public Object execute(final CommandContext context) throws Exception {
+        assert context != null;
+        IO io = context.getIo();
+        MessageSource messages = context.getCommand().getMessages();
+
+        //
+        // TODO: Parse hostname for <username>@<hostname>
+        //
+        
+        io.info(messages.format("info.connecting", hostname, port));
+
+        // If the username/password was not configured via cli, then prompt the user for the values
+        if (username == null || password == null) {
+            PromptReader prompter = new PromptReader(io);
+            String text;
+
+            log.debug("Prompting user for credentials");
+
+            if (username == null) {
+                text = messages.getMessage("prompt.username");
+                username = prompter.readLine(text + ": ", new UsernamePasswordValidator(text));
+            }
+
+            if (password == null) {
+                text = messages.getMessage("prompt.password");
+                password = prompter.readPassword(text + ": ", new UsernamePasswordValidator(text));
+            }
+        }
+
+        // Create the client from prototype
+        SshClient client = container.getBean(SshClient.class);
+        log.debug("Created client: {}", client);
+        client.start();;
+
+        try {
+            ConnectFuture future = client.connect(hostname, port);
+            future.await();
+            session = future.getSession();
+            try {
+                io.info(messages.getMessage("info.connected"));
+
+                session.authPassword(username, password);
+                int ret = session.waitFor(ClientSession.WAIT_AUTH | ClientSession.CLOSED | ClientSession.AUTHED, 0);
+                if ((ret & ClientSession.AUTHED) == 0) {
+                    io.err.println("Authentication failed");
+                    return Result.FAILURE;
+                }
+
+                ClientChannel channel = session.createChannel("shell");
+                channel.setIn(new NoCloseInputStream(io.inputStream));
+                channel.setOut(new NoCloseOutputStream(io.outputStream));
+                channel.setErr(new NoCloseOutputStream(io.errorStream));
+                channel.open();
+                channel.waitFor(ClientChannel.CLOSED, 0);
+            } finally {
+                session.close(false);
+            }
+        } finally {
+            client.stop();
+        }
+
+        io.verbose(messages.getMessage("verbose.disconnected"));
+
+        return Result.SUCCESS;
+    }
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/SshServerAction.java b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/SshServerAction.java
new file mode 100644
index 0000000..db1cfb0
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/ssh/SshServerAction.java
@@ -0,0 +1,84 @@
+/*
+ * 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.geronimo.gshell.commands.ssh;
+
+import org.apache.sshd.SshServer;
+import org.apache.geronimo.gshell.clp.Option;
+import org.apache.geronimo.gshell.command.CommandAction;
+import org.apache.geronimo.gshell.command.CommandContext;
+import org.apache.geronimo.gshell.i18n.MessageSource;
+import org.apache.geronimo.gshell.io.IO;
+import org.apache.geronimo.gshell.spring.BeanContainer;
+import org.apache.geronimo.gshell.spring.BeanContainerAware;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Start a SSH server.
+ *
+ * @version $Rev: 720411 $ $Date: 2008-11-25 05:32:43 +0100 (Tue, 25 Nov 2008) $
+ */
+public class SshServerAction
+    implements CommandAction, BeanContainerAware
+{
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    @Option(name="-p", aliases={ "--port" })
+    private int port=8101;
+
+    @Option(name="-b", aliases={ "--background"})
+    private boolean background = true;
+
+    private BeanContainer container;
+
+    public void setBeanContainer(final BeanContainer container) {
+        assert container != null;
+
+        this.container = container;
+    }
+
+    public Object execute(final CommandContext context) throws Exception {
+        assert context != null;
+        IO io = context.getIo();
+        MessageSource messages = context.getCommand().getMessages();
+
+        SshServer server = container.getBean("sshServer", SshServer.class);
+
+        log.debug("Created server: {}", server);
+
+        server.setPort(port);
+
+        server.start();
+
+        io.info(messages.format("info.listening", port));
+
+        if (!background) {
+            synchronized (this) {
+                log.debug("Waiting for server to shutdown");
+
+                wait();
+            }
+
+            server.stop();
+        }
+
+        return Result.SUCCESS;
+    }
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/text/SortAction.java b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/text/SortAction.java
new file mode 100644
index 0000000..e81b247
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/commands/text/SortAction.java
@@ -0,0 +1,391 @@
+/*
+ * 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.geronimo.gshell.commands.text;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.commons.vfs.FileObject;
+import org.apache.geronimo.gshell.clp.Argument;
+import org.apache.geronimo.gshell.clp.Option;
+import org.apache.geronimo.gshell.command.CommandContext;
+import org.apache.geronimo.gshell.io.Closer;
+import org.apache.geronimo.gshell.vfs.FileObjects;
+import org.apache.geronimo.gshell.vfs.support.VfsActionSupport;
+
+/**
+ * Sort lines of text
+ *
+ * TODO: remove this file when gshell is upgraded
+ *
+ */
+public class SortAction extends VfsActionSupport {
+
+    @Option(name = "-f")
+    private boolean caseInsensitive;
+
+    @Option(name = "-r")
+    private boolean reverse;
+
+    @Option(name = "-u")
+    private boolean unique;
+
+    @Option(name = "-t")
+    private String separator;
+
+    @Option(name = "-b")
+    private boolean ignoreBlanks;
+
+    @Option(name = "-k", argumentRequired = true, multiValued = true)
+    private List<String> sortFields;
+
+    @Option(name = "-n")
+    private boolean numeric;
+
+    @Argument(index = 0, required=false)
+    private String path;
+
+
+    public Object execute(CommandContext context) throws Exception {
+        assert context != null;
+
+        if (path != null) {
+            FileObject file = resolveFile(context, path);
+
+            try {
+                sort(context, file);
+            }
+            finally {
+                FileObjects.close(file);
+            }
+        }
+        else {
+            sort(context.getIo().inputStream, context.getIo().out);
+        }
+        return Result.SUCCESS;
+    }
+
+    protected void sort(final CommandContext context, final FileObject file) throws Exception {
+        assert context != null;
+        assert file != null;
+
+        ensureFileExists(file);
+        ensureFileHasContent(file);
+        ensureFileIsReadable(file);
+
+        BufferedInputStream input = new BufferedInputStream(file.getContent().getInputStream());
+        try {
+            sort(input, context.getIo().out);
+        }
+        finally {
+            Closer.close(input);
+        }
+    }
+
+    protected void sort(InputStream input, PrintWriter out) throws Exception {
+        BufferedReader r = new BufferedReader(new InputStreamReader(input));
+        List<String> strings = new ArrayList<String>();
+        for (String s = r.readLine(); s != null; s = r.readLine()) {
+            strings.add(s);
+        }
+        char sep = (separator == null || separator.length() == 0) ? '\0' : separator.charAt(0);
+        Collections.sort(strings, new SortComparator(caseInsensitive, reverse, ignoreBlanks, numeric, sep, sortFields));
+        String last = null;
+        for (String s : strings) {
+            if (last == null) {
+                last = s;
+            } else if (!unique || !s.equals(last)) {
+                out.println(s);
+            }
+        }
+    }
+
+    public static class SortComparator implements Comparator<String> {
+
+        private boolean caseInsensitive;
+        private boolean reverse;
+        private boolean ignoreBlanks;
+        private boolean numeric;
+        private char separator;
+        private List<Key> sortKeys;
+
+        private static Pattern fpPattern;
+        static {
+            final String Digits     = "(\\p{Digit}+)";
+            final String HexDigits  = "(\\p{XDigit}+)";
+            final String Exp        = "[eE][+-]?" + Digits;
+            final String fpRegex    = "([\\x00-\\x20]*[+-]?(NaN|Infinity|(((" + Digits + "(\\.)?(" + Digits + "?)(" + Exp + ")?)|(\\.(" + Digits + ")(" + Exp + ")?)|(((0[xX]" + HexDigits + "(\\.)?)|(0[xX]" + HexDigits + "?(\\.)" + HexDigits + "))[pP][+-]?" + Digits + "))" + "[fFdD]?))[\\x00-\\x20]*)(.*)";
+            fpPattern = Pattern.compile(fpRegex);
+        }
+
+        public SortComparator(boolean caseInsensitive,
+                              boolean reverse,
+                              boolean ignoreBlanks,
+                              boolean numeric,
+                              char separator,
+                              List<String> sortFields) {
+            this.caseInsensitive = caseInsensitive;
+            this.reverse = reverse;
+            this.separator = separator;
+            this.ignoreBlanks = ignoreBlanks;
+            this.numeric = numeric;
+            if (sortFields == null || sortFields.size() == 0) {
+                sortFields = new ArrayList<String>();
+                sortFields.add("1");
+            }
+            sortKeys = new ArrayList<Key>();
+            for (String f : sortFields) {
+                sortKeys.add(new Key(f));
+            }
+        }
+
+        public int compare(String o1, String o2) {
+            int res = 0;
+
+            List<Integer> fi1 = getFieldIndexes(o1);
+            List<Integer> fi2 = getFieldIndexes(o2);
+            for (Key key : sortKeys) {
+                int[] k1 = getSortKey(o1, fi1, key);
+                int[] k2 = getSortKey(o2, fi2, key);
+                if (key.numeric) {
+                    Double d1 = getDouble(o1, k1[0], k1[1]);
+                    Double d2 = getDouble(o2, k2[0], k2[1]);
+                    res = d1.compareTo(d2);
+                } else {
+                    res = compareRegion(o1, k1[0], k1[1], o2, k2[0], k2[1], key.caseInsensitive);
+                }
+                if (res != 0) {
+                    if (key.reverse) {
+                        res = - res;
+                    }
+                    break;
+                }
+            }
+            return res;
+        }
+
+        protected Double getDouble(String s, int start, int end) {
+            Matcher m = fpPattern.matcher(s.substring(start, end));
+            m.find();
+            return new Double(s.substring(0, m.end(1)));
+        }
+
+        protected int compareRegion(String s1, int start1, int end1, String s2, int start2, int end2, boolean caseInsensitive) {
+            int n1 = end1, n2 = end2;
+            for (int i1 = start1, i2 = start2; i1 < end1 && i2 < n2; i1++, i2++) {
+                char c1 = s1.charAt(i1);
+                char c2 = s2.charAt(i2);
+                if (c1 != c2) {
+                    if (caseInsensitive) {
+                        c1 = Character.toUpperCase(c1);
+                        c2 = Character.toUpperCase(c2);
+                        if (c1 != c2) {
+                            c1 = Character.toLowerCase(c1);
+                            c2 = Character.toLowerCase(c2);
+                            if (c1 != c2) {
+                                return c1 - c2;
+                            }
+                        }
+                    } else {
+                        return c1 - c2;
+                    }
+                }
+            }
+            return n1 - n2;
+        }
+
+        protected int[] getSortKey(String str, List<Integer> fields, Key key) {
+            int start;
+            int end;
+            if (key.startField * 2 < fields.size()) {
+                start = fields.get((key.startField - 1) * 2);
+                if (key.ignoreBlanksStart) {
+                    while (start < fields.get((key.startField - 1) * 2 + 1) && Character.isWhitespace(str.charAt(start))) {
+                        start++;
+                    }
+                }
+                if (key.startChar > 0) {
+                    start = Math.min(start + key.startChar - 1, fields.get((key.startField - 1) * 2 + 1));
+                }
+            } else {
+                start = 0;
+            }
+            if (key.endField > 0 && key.endField * 2 < fields.size()) {
+                end =  fields.get((key.endField - 1) * 2);
+                if (key.ignoreBlanksEnd) {
+                    while (end < fields.get((key.endField - 1) * 2 + 1) && Character.isWhitespace(str.charAt(end))) {
+                        end++;
+                    }
+                }
+                if (key.endChar > 0) {
+                    end = Math.min(end + key.endChar - 1, fields.get((key.endField - 1) * 2 + 1));
+                }
+            } else {
+                end = str.length();
+            }
+            return new int[] { start, end };
+        }
+
+        protected List<Integer> getFieldIndexes(String o) {
+            List<Integer> fields = new ArrayList<Integer>();
+            if (o.length() > 0) {
+                if (separator == '\0') {
+                    int i = 0;
+                    fields.add(0);
+                    for (int idx = 1; idx < o.length(); idx++) {
+                        if (Character.isWhitespace(o.charAt(idx)) && !Character.isWhitespace(o.charAt(idx - 1))) {
+                            fields.add(idx - 1);
+                            fields.add(idx);
+                        }
+                    }
+                    fields.add(o.length() - 1);
+                } else {
+                    int last = -1;
+                    for (int idx = o.indexOf(separator); idx >= 0; idx = o.indexOf(separator, idx + 1)) {
+                        if (last >= 0) {
+                            fields.add(last);
+                            fields.add(idx - 1);
+                        } else if (idx > 0) {
+                            fields.add(0);
+                            fields.add(idx - 1);
+                        }
+                        last = idx + 1;
+                    }
+                    if (last < o.length()) {
+                        fields.add(last < 0 ? 0 : last);
+                        fields.add(o.length() - 1);
+                    }
+                }
+            }
+            return fields;
+        }
+
+        public class Key {
+            int startField;
+            int startChar;
+            int endField;
+            int endChar;
+            boolean ignoreBlanksStart;
+            boolean ignoreBlanksEnd;
+            boolean caseInsensitive;
+            boolean reverse;
+            boolean numeric;
+
+            public Key(String str) {
+                boolean modifiers = false;
+                boolean startPart = true;
+                boolean inField = true;
+                boolean inChar = false;
+                for (char c : str.toCharArray()) {
+                    switch (c) {
+                        case '0':
+                        case '1':
+                        case '2':
+                        case '3':
+                        case '4':
+                        case '5':
+                        case '6':
+                        case '7':
+                        case '8':
+                        case '9':
+                            if (!inField && !inChar) {
+                                throw new IllegalArgumentException("Bad field syntax: " + str);
+                            }
+                            if (startPart) {
+                                if (inChar) {
+                                    startChar = startChar * 10 + (c - '0');
+                                } else {
+                                    startField = startField * 10 + (c - '0');
+                                }
+                            } else {
+                                if (inChar) {
+                                    endChar = endChar * 10 + (c - '0');
+                                } else {
+                                    endField = endField * 10 + (c - '0');
+                                }
+                            }
+                            break;
+                        case '.':
+                            if (!inField) {
+                                throw new IllegalArgumentException("Bad field syntax: " + str);
+                            }
+                            inField = false;
+                            inChar = true;
+                            break;
+                        case 'n':
+                            inField = false;
+                            inChar = false;
+                            modifiers = true;
+                            numeric = true;
+                            break;
+                        case 'f':
+                            inField = false;
+                            inChar = false;
+                            modifiers = true;
+                            caseInsensitive = true;
+                            break;
+                        case 'r':
+                            inField = false;
+                            inChar = false;
+                            modifiers = true;
+                            reverse = true;
+                            break;
+                        case 'b':
+                            inField = false;
+                            inChar = false;
+                            modifiers = true;
+                            if (startPart) {
+                                ignoreBlanksStart = true;
+                            } else {
+                                ignoreBlanksEnd = true;
+                            }
+                            break;
+                        case ',':
+                            inField = true;
+                            inChar = false;
+                            startPart = false;
+                            break;
+                        default:
+                            throw new IllegalArgumentException("Bad field syntax: " + str);
+                    }
+                }
+                if (!modifiers) {
+                    ignoreBlanksStart = ignoreBlanksEnd = SortComparator.this.ignoreBlanks;
+                    reverse = SortComparator.this.reverse;
+                    caseInsensitive = SortComparator.this.caseInsensitive;
+                    numeric = SortComparator.this.numeric;
+                }
+                if (startField < 1) {
+                    throw new IllegalArgumentException("Bad field syntax: " + str);
+                }
+            }
+        }
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/vfs/provider/meta/MetaFileObject.java b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/vfs/provider/meta/MetaFileObject.java
new file mode 100644
index 0000000..7e71328
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/geronimo/gshell/vfs/provider/meta/MetaFileObject.java
@@ -0,0 +1,144 @@
+/*
+ * 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.geronimo.gshell.vfs.provider.meta;
+
+import org.apache.commons.vfs.FileContentInfoFactory;
+import org.apache.commons.vfs.FileName;
+import org.apache.commons.vfs.FileType;
+import org.apache.commons.vfs.FileContent;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.provider.AbstractFileObject;
+import org.apache.commons.vfs.provider.DefaultFileContent;
+import org.apache.geronimo.gshell.vfs.provider.meta.data.MetaData;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * Meta file object.
+ *
+ * TODO: remove this file when gshell version is upgraded
+ *
+ * @version $Rev: 706033 $ $Date: 2008-10-19 17:36:15 +0200 (Sun, 19 Oct 2008) $
+ */
+public class MetaFileObject
+    extends AbstractFileObject
+{
+    private final MetaFileSystem fileSystem;
+
+    private MetaData data;
+    private FileContent content;
+
+    public MetaFileObject(final FileName fileName, final MetaFileSystem fileSystem) {
+        super(fileName, fileSystem);
+
+        // Save for uncasted typed access
+        this.fileSystem = fileSystem;
+    }
+
+    public MetaData getData() {
+        if (data == null) {
+            throw new IllegalStateException("Meta data has not been attached");
+        }
+
+        return data;
+    }
+
+    @Override
+    protected FileType doGetType() throws Exception {
+        return getData().getType();
+    }
+
+    @Override
+    protected long doGetLastModifiedTime() throws Exception {
+        return getData().getLastModified();
+    }
+
+    @Override
+    protected boolean doIsReadable() throws Exception {
+        return data.getBuffer() != null;
+    }
+
+    @Override
+    protected boolean doIsWriteable() throws Exception {
+        return false;
+    }
+
+    @Override
+    protected FileContentInfoFactory getFileContentInfoFactory() {
+        return fileSystem.getFileContentInfoFactory();
+    }
+
+    @Override
+    protected long doGetContentSize() throws Exception {
+        byte[] bytes = data.getBuffer();
+        return bytes != null ? bytes.length : 0;
+    }
+
+    @Override
+    protected InputStream doGetInputStream() throws Exception {
+        byte[] bytes = data.getBuffer();
+        if (bytes != null) {
+            return new ByteArrayInputStream(bytes);
+        }
+
+        return null;
+    }
+
+    @Override
+    protected Map<String,Object> doGetAttributes() {
+        return getData().getAttributes();
+    }
+
+    @Override
+    protected void doSetAttribute(final String name, final Object value) {
+        getData().getAttributes().put(name, value);
+    }
+
+    protected void doRemoveAttribute(final String name) {
+        getData().getAttributes().remove(name);
+    }
+
+    @Override
+    protected String[] doListChildren() throws Exception {
+        return fileSystem.listChildren(getName());
+    }
+
+    @Override
+    protected void doAttach() throws Exception {
+        if (data == null) {
+            data = fileSystem.lookupData(this);
+        }
+        content = new DefaultFileContent(this, getFileContentInfoFactory());
+    }
+
+    @Override
+    protected void doDetach() throws Exception {
+        data = null;
+        content = null;
+    }
+
+    @Override
+    public FileContent getContent() throws FileSystemException {
+        super.getContent();
+        return content;
+    }
+}
\ No newline at end of file
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/ApplicationImpl.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/ApplicationImpl.java
new file mode 100644
index 0000000..350fd63
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/ApplicationImpl.java
@@ -0,0 +1,143 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.servicemix.kernel.gshell.core;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.InetAddress;
+import java.net.URL;
+import java.util.Properties;
+
+import org.apache.geronimo.gshell.application.Application;
+import org.apache.geronimo.gshell.application.ClassPath;
+import org.apache.geronimo.gshell.application.model.ApplicationModel;
+import org.apache.geronimo.gshell.artifact.Artifact;
+import org.apache.geronimo.gshell.command.Variables;
+import org.apache.geronimo.gshell.io.IO;
+import org.springframework.beans.factory.InitializingBean; 
+
+public class ApplicationImpl implements Application, InitializingBean  {
+
+	private static final String EMBEDDED_PROPS = "org/apache/servicemix/kernel/version/embedded.properties";
+    private static final String SERVICEMIX_VERSION ="org/apache/servicemix/kernel/gshell/core/servicemix-version.properties";
+    private static final String VERSION_PROPERTY = "version";
+
+    private String id;
+    private IO io;
+    private ApplicationModel model;
+    private Variables variables;
+    private InetAddress localHost;
+    private File homeDir;         
+    private URL embeddedResource = null; 
+
+    public ApplicationImpl() throws Exception {
+        this.localHost = InetAddress.getLocalHost();
+        this.homeDir = detectHomeDir();    
+    }           
+     
+    public void afterPropertiesSet() throws Exception {      	         	    	
+        Properties props = new Properties();
+        props.load(getClass().getClassLoader().getResourceAsStream(SERVICEMIX_VERSION));
+        String kernelVersion = props.getProperty(VERSION_PROPERTY);
+        this.model.setVersion(kernelVersion);
+    	ServiceMixBranding smxBranding = (ServiceMixBranding) this.model.getBranding();
+        smxBranding.setVersion(kernelVersion);
+        
+     	if (this.getClass().getClassLoader().getResource(EMBEDDED_PROPS) != null) {                    
+            embeddedResource = this.getClass().getClassLoader().getResource(EMBEDDED_PROPS);
+            smxBranding.setEmbeddedResource(embeddedResource);
+        }
+    }
+    
+    public URL getEmbeddedResource() {
+    	return embeddedResource;
+    }        
+        
+    public String getId() {
+        return id;
+    }
+
+    public void setId(String id) {
+        this.id = id;
+    }
+
+    public IO getIo() {
+        return io;
+    }
+
+    public void setIo(IO io) {
+        this.io = io;
+    }
+
+    public Variables getVariables() {
+        return variables;
+    }
+
+    public void setVariables(Variables variables) {
+        this.variables = variables;
+    }
+
+    public ApplicationModel getModel() {
+        return model;
+    }
+
+    public void setModel(ApplicationModel model) {
+        this.model = model;
+    }
+
+    public ClassPath getClassPath() {
+        throw new UnsupportedOperationException();
+    }
+
+    public File getHomeDir() {
+        if (homeDir == null) {
+            throw new IllegalStateException();
+        }
+        return homeDir;
+    }
+
+    public InetAddress getLocalHost() {
+        return localHost;
+    }
+
+    public String getUserName() {
+        return System.getProperty("user.name");
+    }
+
+    public Artifact getArtifact() {
+        return null;
+    }
+
+    private File detectHomeDir() {
+        String homePath = System.getProperty("user.home");
+        // And now lets resolve this sucker
+        File dir;
+        try {
+            dir = new File(homePath).getCanonicalFile();
+        }
+        catch (IOException e) {
+            throw new RuntimeException("Failed to resolve home directory: " + homePath, e);
+        }
+        // And some basic sanity too
+        if (!dir.exists() || !dir.isDirectory()) {
+            throw new RuntimeException("Home directory configured but is not a valid directory: " + dir);
+        }
+
+        return dir;
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/ApplicationManagerImpl.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/ApplicationManagerImpl.java
new file mode 100644
index 0000000..7465900
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/ApplicationManagerImpl.java
@@ -0,0 +1,81 @@
+/*
+ * 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.servicemix.kernel.gshell.core;
+
+import org.apache.geronimo.gshell.application.Application;
+import org.apache.geronimo.gshell.application.ApplicationConfiguration;
+import org.apache.geronimo.gshell.application.ApplicationManager;
+import org.apache.geronimo.gshell.event.EventPublisher;
+import org.apache.geronimo.gshell.io.SystemOutputHijacker;
+import org.apache.geronimo.gshell.shell.Shell;
+import org.apache.geronimo.gshell.wisdom.application.ShellCreatedEvent;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+public class ApplicationManagerImpl implements ApplicationManager, ApplicationContextAware, InitializingBean, DisposableBean {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private EventPublisher eventPublisher;
+
+    private Application application;
+
+    private ApplicationContext applicationContext;
+
+    public ApplicationManagerImpl(EventPublisher eventPublisher, Application application) {
+        this.eventPublisher = eventPublisher;
+        this.application = application;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        if (!SystemOutputHijacker.isInstalled()) {
+            SystemOutputHijacker.install();
+        }
+        //SystemOutputHijacker.register(application.getIo().outputStream, application.getIo().errorStream);
+    }
+
+    public void destroy() {
+        SystemOutputHijacker.uninstall();
+    }
+
+    public void setApplicationContext(ApplicationContext applicationContext) {
+        this.applicationContext = applicationContext;
+    }
+
+    public void configure(ApplicationConfiguration applicationConfiguration) throws Exception {
+        throw new UnsupportedOperationException();
+    }
+
+    public Application getApplication() {
+        return application;
+    }
+
+    public Shell create() throws Exception {
+        final Shell shell = (Shell) applicationContext.getBean("shell");
+
+        log.debug("Created shell instance: {}", shell);
+
+        eventPublisher.publish(new ShellCreatedEvent(shell));
+
+        return shell;
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/BeanContainerAwareProcessor.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/BeanContainerAwareProcessor.java
new file mode 100644
index 0000000..7deacb1
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/BeanContainerAwareProcessor.java
@@ -0,0 +1,55 @@
+/*
+ * 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.servicemix.kernel.gshell.core;
+
+import org.apache.geronimo.gshell.spring.BeanContainer;
+import org.apache.geronimo.gshell.spring.BeanContainerAware;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.config.BeanPostProcessor;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+
+public class BeanContainerAwareProcessor implements InitializingBean, BeanPostProcessor, ApplicationContextAware {
+
+    private ApplicationContext applicationContext;
+    private BeanContainer container;
+
+    public void setApplicationContext(ApplicationContext applicationContext) {
+        this.applicationContext = applicationContext;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        this.container = new BeanContainerWrapper(applicationContext);
+    }
+
+    public Object postProcessBeforeInitialization(final Object bean, final String beanName) throws BeansException {
+        assert bean != null;
+
+        if (bean instanceof BeanContainerAware) {
+            ((BeanContainerAware)bean).setBeanContainer(container);
+        }
+
+        return bean;
+    }
+
+    public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException {
+        return bean;
+    }
+}
\ No newline at end of file
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/BeanContainerWrapper.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/BeanContainerWrapper.java
new file mode 100644
index 0000000..edc15d7
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/BeanContainerWrapper.java
@@ -0,0 +1,109 @@
+/*
+ * 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.servicemix.kernel.gshell.core;
+
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.geronimo.gshell.spring.BeanContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.context.ApplicationContext;
+
+public class BeanContainerWrapper implements BeanContainer {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private ApplicationContext context;
+
+    public BeanContainerWrapper(ApplicationContext context) {
+        this.context = context;
+    }
+
+    public BeanContainer getParent() {
+        return null;
+    }
+
+    public ClassLoader getClassLoader() {
+        return context.getClassLoader();
+    }
+
+    public void loadBeans(String[] strings) throws Exception {
+        throw new UnsupportedOperationException();
+    }
+
+    public <T> T getBean(Class<T> type) {
+        assert type != null;
+
+        log.trace("Getting bean of type: {}", type);
+
+        String[] names = context.getBeanNamesForType(type);
+
+        if (names.length == 0) {
+            throw new NoSuchBeanDefinitionException(type, "No bean defined for type: " + type);
+        }
+        if (names.length > 1) {
+            throw new NoSuchBeanDefinitionException(type, "No unique bean defined for type: " + type + ", found matches: " + Arrays.asList(names));
+        }
+
+        return getBean(names[0], type);
+    }
+
+    public <T> T getBean(String name, Class<T> requiredType) {
+        assert name != null;
+        assert requiredType != null;
+
+        log.trace("Getting bean named '{}' of type: {}", name, requiredType);
+
+        return (T) context.getBean(name, requiredType);
+    }
+
+    public <T> Map<String, T> getBeans(Class<T> type) {
+        assert type != null;
+
+        log.trace("Getting beans of type: {}", type);
+
+        return (Map<String,T>) context.getBeansOfType(type);
+    }
+
+    public String[] getBeanNames() {
+        log.trace("Getting bean names");
+
+        return context.getBeanDefinitionNames();
+    }
+
+    public String[] getBeanNames(Class type) {
+        assert type != null;
+
+        log.trace("Getting bean names of type: {}", type);
+
+        return context.getBeanNamesForType(type);
+    }
+
+    public BeanContainer createChild(Collection<URL> urls) {
+        throw new UnsupportedOperationException();
+    }
+
+    public BeanContainer createChild() {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/CommandBundle.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/CommandBundle.java
new file mode 100644
index 0000000..2111072
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/CommandBundle.java
@@ -0,0 +1,175 @@
+/*
+ * 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.servicemix.kernel.gshell.core;
+
+import java.util.ArrayList;
+import java.util.Dictionary;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.geronimo.gshell.command.Alias;
+import org.apache.geronimo.gshell.command.Command;
+import org.apache.geronimo.gshell.command.Link;
+import org.apache.geronimo.gshell.registry.AliasRegistry;
+import org.apache.geronimo.gshell.registry.CommandRegistry;
+import org.apache.geronimo.gshell.wisdom.command.LinkCommand;
+import org.apache.geronimo.gshell.wisdom.registry.CommandLocationImpl;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.osgi.context.BundleContextAware;
+
+public class CommandBundle implements BundleContextAware, InitializingBean, DisposableBean, ApplicationContextAware {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private CommandRegistry commandRegistry;
+
+    private AliasRegistry aliasRegistry;
+
+    private BundleContext bundleContext;
+
+    private List<Command> commands;
+
+    private List<Link> links;
+
+    private List<Alias> aliases;
+
+    private ApplicationContext applicationContext;
+
+    private List<ServiceRegistration> registrations = new ArrayList<ServiceRegistration>();
+
+    public CommandBundle() {
+    }
+
+    public void setApplicationContext(ApplicationContext applicationContext) {
+        this.applicationContext = applicationContext;
+    }
+
+    public List<Command> getCommands() {
+        return commands;
+    }
+
+    public void setCommands(final List<Command> commands) {
+        assert commands != null;
+
+        this.commands = commands;
+    }
+
+    public List<Link> getLinks() {
+        return links;
+    }
+
+    public void setLinks(List<Link> links) {
+        assert links != null;
+
+        this.links = links;
+    }
+
+    public List<Alias> getAliases() {
+        return aliases;
+    }
+
+    public void setAliases(List<Alias> aliases) {
+        assert aliases != null;
+
+        this.aliases = aliases;
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    public void afterPropertiesSet() throws Exception {
+        log.debug("Initializing command bundle");
+        if (commandRegistry == null) {
+            String[] names = applicationContext.getBeanNamesForType(CommandRegistry.class);
+            if (names.length == 1) {
+                commandRegistry = (CommandRegistry) applicationContext.getBean(names[0], CommandRegistry.class);
+            }
+        }
+        if (aliasRegistry == null) {
+            String[] names = applicationContext.getBeanNamesForType(AliasRegistry.class);
+            if (names.length == 1) {
+                aliasRegistry = (AliasRegistry) applicationContext.getBean(names[0], AliasRegistry.class);
+            }
+        }
+        if (commandRegistry != null && aliasRegistry != null) {
+            log.debug("Command bundle is using the auto wired command/alias registry");
+            if (commands != null) {
+                for (Command command : commands) {
+                    log.debug("Registering command: {}", command.getLocation());
+                    commandRegistry.registerCommand(command);
+                }
+            }
+            if (links != null) {
+                for (Link link : links) {
+                    log.debug("Registering link: {}", link.getName());
+                    LinkCommand cmd = new LinkCommand(commandRegistry, link.getTarget());
+                    cmd.setLocation(new CommandLocationImpl(link.getName()));
+                    commandRegistry.registerCommand(cmd);
+                }
+            }
+            if (aliases != null) {
+                for (Alias alias : aliases) {
+                    log.debug("Registering alias: {}", alias.getName());
+                    aliasRegistry.registerAlias(alias.getName(), alias.getAlias());
+                }
+            }
+        } else if (bundleContext != null) {
+            log.debug("Command bundle is using the OSGi registry");
+            if (commands != null) {
+                for (Command command : commands) {
+                    log.debug("Registering command: {}", command.getLocation());
+                    Dictionary props = new Properties();
+                    props.put(OsgiCommandRegistry.NAME, command.getLocation().getFullPath());
+                    registrations.add(bundleContext.registerService(Command.class.getName(), command, props));
+                }
+            }
+            if (links != null) {
+                for (Link link : links) {
+                    log.debug("Registering link: {}", link.getName());
+                    registrations.add(bundleContext.registerService(Link.class.getName(), link, new Properties()));
+                }
+            }
+            if (aliases != null) {
+                for (Alias alias : aliases) {
+                    log.debug("Registering alias: {}", alias.getName());
+                    Dictionary props = new Properties();
+                    registrations.add(bundleContext.registerService(Alias.class.getName(), alias, new Properties()));
+                }
+            }
+        } else {
+            throw new Exception("Command bundle should be wired to the command/alias registry or be used in an OSGi context");
+        }
+    }
+
+    public void destroy() {
+        log.debug("Destroying command bundle");
+        for (ServiceRegistration reg : registrations) {
+            reg.unregister();
+        }
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/LocalConsole.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/LocalConsole.java
new file mode 100644
index 0000000..98c7193
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/LocalConsole.java
@@ -0,0 +1,172 @@
+/*
+ * 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.servicemix.kernel.gshell.core;
+
+import java.util.Arrays;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.geronimo.gshell.notification.ExitNotification;
+import org.apache.geronimo.gshell.shell.Shell;
+import org.apache.servicemix.kernel.main.spi.MainService;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.framework.FrameworkEvent;
+import org.osgi.framework.FrameworkListener;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.osgi.context.BundleContextAware;
+
+public class LocalConsole implements Runnable, BundleContextAware {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private Shell shell;
+
+    private boolean createLocalShell;
+
+    private BundleContext bundleContext;
+
+    private MainService mainService;
+
+    private CountDownLatch frameworkStarted;
+    
+    public BundleContext getBundleContext() {
+        return bundleContext;
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    public MainService getMainService() {
+        return mainService;
+    }
+
+    public void setMainService(MainService mainService) {
+        this.mainService = mainService;
+    }
+
+    public Shell getShell() {
+        return shell;
+    }
+
+    public void setShell(Shell shell) {
+        this.shell = shell;
+    }
+
+    public boolean isCreateLocalShell() {
+        return createLocalShell;
+    }
+
+    public void setCreateLocalShell(boolean createLocalShell) {
+        this.createLocalShell = createLocalShell;
+    }
+
+    public void init() {
+        shell.getContext().getVariables().set("gshell.username", "smx");
+        frameworkStarted = new CountDownLatch(1);
+		getBundleContext().addFrameworkListener(new FrameworkListener(){
+			public void frameworkEvent(FrameworkEvent event) {
+				log.debug("Got event: " + event.getType());
+				if( event.getType() == FrameworkEvent.STARTED ) {
+					frameworkStarted.countDown();
+				}
+			}
+		});
+        if (createLocalShell) {
+            new Thread(this, "localShell").start();
+        }
+    }
+
+    public void destroy() {
+        if (createLocalShell) {
+            shell.close();
+        }
+    }
+
+    public void run() {
+        try {
+            String[] args = mainService.getArgs();
+            // If a command was specified on the command line, then just execute that command.
+            if (args != null && args.length > 0) {
+                waitForFrameworkToStart();
+                log.info("Executing Shell with arguments: " + Arrays.toString(args));
+                StringBuilder sb = new StringBuilder();
+                for (String arg : args) {
+                    sb.append(arg).append(" ");
+                }
+                Object value = shell.execute(sb.toString());
+                if (mainService != null) {
+                    if (value instanceof Number) {
+                        mainService.setExitCode(((Number) value).intValue());
+                    } else {
+                        mainService.setExitCode(value != null ? 1 : 0);
+                    }
+                    log.info("Exiting shell due to terminated command");
+                }
+            } else {
+                shell.run();
+            }
+        } catch (ExitNotification e) {
+            if (mainService != null) {
+                mainService.setExitCode(0);
+            }
+            log.info("Exiting shell due received exit notification");
+        } catch (Throwable e) {
+            if (mainService != null) {
+                mainService.setExitCode(-1);
+            }
+            log.error("Exiting shell due to caught exception " + e, e);
+        } finally {
+            try {
+                shell.close();
+            } catch (Throwable t) {}
+            asyncShutdown();
+        }
+    }
+
+    /**
+     * Blocks until the framework has finished starting.  We do this so that any installed
+     * bundles for commands get fully registered.
+     *
+     * @throws InterruptedException
+     */
+    private void waitForFrameworkToStart() throws InterruptedException {
+        log.info("Waiting from framework to start.");
+        if (frameworkStarted.await(60, TimeUnit.SECONDS)) {
+			log.info("System completed startup.");
+		} else {
+			log.warn("System took too long startup... continuing");
+		}
+    }
+
+    private void asyncShutdown() {
+        new Thread() {
+            public void run() {
+                try {
+                    getBundleContext().getBundle(0).stop();
+                } catch (BundleException e) {
+                    log.info("Caught exception while shutting down framework: " + e, e);
+                }
+            }
+        }.start();
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/OsgiAliasRegistry.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/OsgiAliasRegistry.java
new file mode 100644
index 0000000..a09ce0b
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/OsgiAliasRegistry.java
@@ -0,0 +1,45 @@
+/*
+ * 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.servicemix.kernel.gshell.core;
+
+import java.util.Map;
+
+import org.apache.geronimo.gshell.command.Alias;
+import org.apache.geronimo.gshell.registry.AliasRegistry;
+
+public class OsgiAliasRegistry {
+
+    public static final String NAME = "name";
+    public static final String ALIAS = "alias";
+
+    private AliasRegistry aliasRegistry;
+
+    public OsgiAliasRegistry(AliasRegistry aliasRegistry) {
+        this.aliasRegistry = aliasRegistry;
+    }
+
+    public void register(final Alias alias, Map<String, ?> properties) throws Exception {
+        aliasRegistry.registerAlias(alias.getName(), alias.getAlias());
+    }
+
+    public void unregister(final Alias alias, Map<String, ?> properties) throws Exception {
+        aliasRegistry.removeAlias(alias.getName());
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/OsgiCommandRegistry.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/OsgiCommandRegistry.java
new file mode 100644
index 0000000..c6817e8
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/OsgiCommandRegistry.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.servicemix.kernel.gshell.core;
+
+import java.util.Map;
+
+import org.apache.geronimo.gshell.command.Command;
+import org.apache.geronimo.gshell.command.Link;
+import org.apache.geronimo.gshell.registry.CommandRegistry;
+import org.apache.geronimo.gshell.wisdom.command.LinkCommand;
+import org.apache.geronimo.gshell.wisdom.registry.CommandLocationImpl;
+
+public class OsgiCommandRegistry {
+
+    public static final String NAME = "name";
+    public static final String TARGET = "target";
+
+    private CommandRegistry commandRegistry;
+
+    public OsgiCommandRegistry(CommandRegistry commandRegistry) {
+        this.commandRegistry = commandRegistry;
+    }
+
+    public void register(final Command command, Map<String, ?> properties) throws Exception {
+        commandRegistry.registerCommand(command);
+    }
+
+    public void unregister(final Command command, Map<String, ?> properties) throws Exception {
+        commandRegistry.removeCommand(command);
+    }
+
+    public void register(final Link link, Map<String, ?> properties) throws Exception {
+        LinkCommand cmd = new LinkCommand(commandRegistry, link.getTarget());
+        cmd.setLocation(new CommandLocationImpl(link.getName()));
+        commandRegistry.registerCommand(cmd);
+    }
+
+    public void unregister(final Link link, Map<String, ?> properties) throws Exception {
+        commandRegistry.removeCommand(commandRegistry.getCommand(link.getName()));
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/OsgiCommandSupport.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/OsgiCommandSupport.java
new file mode 100644
index 0000000..e13940a
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/OsgiCommandSupport.java
@@ -0,0 +1,96 @@
+/*
+ * 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.servicemix.kernel.gshell.core;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.geronimo.gshell.command.CommandAction;
+import org.apache.geronimo.gshell.command.CommandContext;
+import org.apache.geronimo.gshell.command.Variables;
+import org.apache.geronimo.gshell.io.IO;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.springframework.osgi.context.BundleContextAware;
+
+public abstract class OsgiCommandSupport implements CommandAction, BundleContextAware {
+
+    protected Log log = LogFactory.getLog(getClass());
+    protected BundleContext bundleContext;
+    protected CommandContext commandContext;
+    protected IO io;
+    protected Variables variables;
+    protected List<ServiceReference> usedReferences;
+    
+    public Object execute(CommandContext commandContext) throws Exception {
+        this.commandContext = commandContext;
+        this.io = commandContext.getIo();
+        this.variables = commandContext.getVariables();
+        try {
+            return doExecute();
+        } finally {
+            ungetServices();
+        }
+    }
+
+    protected abstract Object doExecute() throws Exception;
+
+    public BundleContext getBundleContext() {
+        return bundleContext;
+    }
+
+    public void setBundleContext(BundleContext bundleContext) {
+        this.bundleContext = bundleContext;
+    }
+
+    protected <T> List<T> getAllServices(Class<T> clazz, String filter) throws Exception {
+        ServiceReference[] references = getBundleContext().getAllServiceReferences(clazz.getName(), filter);
+        if (references == null) {
+            return null;
+        }
+        List<T> services = new ArrayList<T>();
+        for (ServiceReference ref : references) {
+            T t = getService(clazz, ref);
+            services.add(t);
+        }
+        return services;
+    }
+
+    protected <T> T getService(Class<T> clazz, ServiceReference reference) {
+        T t = (T) getBundleContext().getService(reference);
+        if (t != null) {
+            if (usedReferences == null) {
+                usedReferences = new ArrayList<ServiceReference>();
+            }
+            usedReferences.add(reference);
+        }
+        return t;
+    }
+
+    protected void ungetServices() {
+        if (usedReferences != null) {
+            for (ServiceReference ref : usedReferences) {
+                getBundleContext().ungetService(ref);
+            }
+        }
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/ServiceMixBranding.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/ServiceMixBranding.java
new file mode 100644
index 0000000..803b511
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/ServiceMixBranding.java
@@ -0,0 +1,188 @@
+/*
+ * 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.servicemix.kernel.gshell.core;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.net.URL;
+import java.util.Properties;
+import java.util.StringTokenizer;
+
+import org.apache.geronimo.gshell.ansi.AnsiBuffer;
+import org.apache.geronimo.gshell.ansi.AnsiCode;
+import org.apache.geronimo.gshell.ansi.AnsiRenderWriter;
+import org.apache.geronimo.gshell.application.model.Branding;
+
+public class ServiceMixBranding extends Branding {		
+   
+    private String prompt; 
+    private String[] banner;
+    private String displayName;
+    private String displayVersion;    
+    private String displayLocation;
+    private String applicationName;
+    private String applicationVersion;
+    private String applicationLocation;
+    
+    private String[] kernelBanner = {
+        " ____                  _          __  __ _      ",
+        "/ ___|  ___ _ ____   _(_) ___ ___|  \\/  (_)_  __",
+        "\\___ \\ / _ \\ '__\\ \\ / / |/ __/ _ \\ |\\/| | \\ \\/ /",
+        " ___) |  __/ |   \\ V /| | (_|  __/ |  | | |>  < ",
+        "|____/ \\___|_|    \\_/ |_|\\___\\___|_|  |_|_/_/\\_\\",
+    };
+
+    public ServiceMixBranding() {
+    	banner = kernelBanner;
+    	displayName = "ServiceMix Kernel";
+    	displayLocation = "http://servicemix.apache.org/kernel/";    	
+    }
+    
+    public void setEmbeddedResource(URL embeddedResource) {    	
+    	Properties brandProps = loadPropertiesFile(embeddedResource);        
+    	String brandBanner = brandProps.getProperty("banner");
+    	int i = 0;
+        char quot = '"';
+
+        StringTokenizer st = new StringTokenizer(brandBanner, ",");
+        banner = new String[st.countTokens()];
+
+        while (st.hasMoreTokens()) {        	
+            banner[i] = st.nextToken();
+            banner[i] = banner[i].substring(1, banner[i].lastIndexOf(quot));        
+            i++;
+        }
+
+    	applicationName = brandProps.getProperty("application.name");  
+    	applicationVersion = brandProps.getProperty("application.version");
+    	applicationLocation = brandProps.getProperty("application.location");
+    }    
+    
+    public String getName() {
+        return "servicemix";
+    }
+        
+    public String getDisplayName() {    	
+        return displayName;
+    }
+        
+    public void setVersion(String version) {
+    	displayVersion = version;
+    }
+    
+    public String getVersion() {
+    	return displayVersion;
+    }        
+    
+    public String getApplicationName() {
+    	return applicationName;
+    }
+
+    public String getApplicationVersion() {
+    	return applicationVersion;
+    }
+    
+    public String getProgramName() {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getPrompt() {
+        return prompt;
+    }
+
+    public void setPrompt(String prompt) {
+        this.prompt = prompt;
+    }
+
+    public String getAboutMessage() {
+        StringWriter writer = new StringWriter();
+        PrintWriter out = new AnsiRenderWriter(writer);
+
+        out.println("For information about @|cyan " + displayName + "|, visit:");
+        out.println("    @|bold " + displayLocation + "| ");
+        out.flush();
+
+        if (applicationName != null && applicationVersion != null) {
+        	out.println();
+        	out.println(applicationName + " " + applicationVersion);
+        	out.println();
+        	if (applicationLocation != null) {
+                out.println("For information about @|cyan " + applicationName + "|, visit:");
+                out.println("    @|bold " + applicationLocation + "| ");
+                out.flush();
+        	}
+        }
+
+        return writer.toString();
+    }      
+    
+    public String getWelcomeMessage() {    	        
+        StringWriter writer = new StringWriter();
+        PrintWriter out = new AnsiRenderWriter(writer);
+    	
+        AnsiBuffer buff = new AnsiBuffer();        
+                
+        for (String line : banner) {
+            buff.attrib(line, AnsiCode.CYAN);
+            out.println(buff);
+        }
+
+        out.println();
+        out.println(" @|bold " + displayName + "| (" + displayVersion + ")");
+        if (applicationName != null && applicationVersion != null) {
+            out.println(" @|bold " + applicationName + "| (" + applicationVersion + ")");
+        }
+        out.println();
+        out.println("Type '@|bold help|' for more information.");
+        out.flush();
+
+        return writer.toString();
+    }
+            
+    private static Properties loadPropertiesFile(URL brandPropURL) {
+        // Read the properties file.
+        Properties brandProps = new Properties();
+        InputStream is = null;
+        try {
+            is = brandPropURL.openConnection().getInputStream();
+            brandProps.load(is);
+            is.close();
+        }
+        catch (FileNotFoundException ex) {
+            // Ignore file not found.
+        }
+        catch (Exception ex) {
+            System.err.println(
+                    "Error loading embedded properties from " + brandPropURL);
+            System.err.println("ServicemixBranding: " + ex);
+            try {
+                if (is != null) is.close();
+            }
+            catch (IOException ex2) {
+                // Nothing we can do.
+            }
+            return null;
+        }
+       
+        return brandProps;
+    }
+    
+}
+
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/ShellWrapper.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/ShellWrapper.java
new file mode 100644
index 0000000..ae86534
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/ShellWrapper.java
@@ -0,0 +1,86 @@
+/*
+ * 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.servicemix.kernel.gshell.core;
+
+import org.apache.geronimo.gshell.shell.Shell;
+import org.apache.geronimo.gshell.shell.ShellContext;
+import org.apache.geronimo.gshell.shell.ShellContextHolder;
+
+public class ShellWrapper implements Shell {
+
+    private Shell delegate;
+
+    public ShellWrapper(Shell delegate) {
+        this.delegate = delegate;
+    }
+
+    public ShellContext getContext() {
+        return delegate.getContext();
+    }
+
+    public Object execute(String s) throws Exception {
+        ShellContext ctx = ShellContextHolder.get(true);
+        try {
+            ShellContextHolder.set(getContext());
+            return delegate.execute(s);
+        } finally {
+            ShellContextHolder.set(ctx);
+        }
+    }
+
+    public Object execute(String s, Object[] objects) throws Exception {
+        ShellContext ctx = ShellContextHolder.get(true);
+        try {
+            ShellContextHolder.set(getContext());
+            return delegate.execute(s, objects);
+        } finally {
+            ShellContextHolder.set(ctx);
+        }
+    }
+
+    public Object execute(Object... objects) throws Exception {
+        ShellContext ctx = ShellContextHolder.get(true);
+        try {
+            ShellContextHolder.set(getContext());
+            return delegate.execute(objects);
+        } finally {
+            ShellContextHolder.set(ctx);
+        }
+    }
+
+    public boolean isOpened() {
+        return delegate.isOpened();
+    }
+
+    public void close() {
+        delegate.close();
+    }
+
+    public boolean isInteractive() {
+        return delegate.isInteractive();
+    }
+
+    public void run(Object... objects) throws Exception {
+        ShellContext ctx = ShellContextHolder.get(true);
+        try {
+            ShellContextHolder.set(getContext());
+            delegate.run(objects);
+        } finally {
+            ShellContextHolder.set(ctx);
+        }
+    }
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/WorkAroundAliasCommand.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/WorkAroundAliasCommand.java
new file mode 100644
index 0000000..1e52177
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/WorkAroundAliasCommand.java
@@ -0,0 +1,118 @@
+/*
+ * 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.servicemix.kernel.gshell.core;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.geronimo.gshell.clp.Argument;
+import org.apache.geronimo.gshell.command.CommandAction;
+import org.apache.geronimo.gshell.command.CommandContext;
+import org.apache.geronimo.gshell.command.CommandResult;
+import org.apache.geronimo.gshell.command.Variables;
+import org.apache.geronimo.gshell.commandline.CommandLineExecutor;
+import org.apache.geronimo.gshell.io.IO;
+import org.apache.geronimo.gshell.shell.Shell;
+import org.apache.geronimo.gshell.shell.ShellContext;
+import org.apache.geronimo.gshell.shell.ShellContextHolder;
+import org.apache.geronimo.gshell.wisdom.command.AliasCommand;
+
+public class WorkAroundAliasCommand extends AliasCommand {
+
+    private final CommandLineExecutor executor;
+
+    public WorkAroundAliasCommand(CommandLineExecutor executor) {
+        super(executor);
+        this.executor = executor;
+        setAction(new AliasCommandAction());
+    }
+
+    @Override
+    protected void prepareAction(final ShellContext context, final Object[] args) {
+        // HACK: Reset state for proper appendArgs muck
+        assert context != null;
+        assert args != null;
+
+        setAction(new AliasCommandAction());
+        log.trace("Preparing action");
+
+        IO io = context.getIo();
+        CommandAction action = getAction();
+
+        // Setup the command action
+        try {
+            // Process command line options/arguments
+            processArguments(io, action, args);
+        }
+        catch (Exception e) {
+            // Abort if preparation caused a failure
+            throw new AbortExecutionNotification(new CommandResult.FailureResult(e));
+        }
+    }
+
+    private class AliasCommandAction
+        implements CommandAction
+    {
+        @Argument
+        private List<String> appendArgs = null;
+
+        public Object execute(final CommandContext context) throws Exception {
+            assert context != null;
+
+            StringBuilder buff = new StringBuilder();
+            buff.append(getAlias());
+
+            // If we have args to append, then do it
+            if (appendArgs != null && !appendArgs.isEmpty()) {
+                buff.append(" ");
+
+                // Append args quoted as they have already been processed by the parser
+                Iterator iter = appendArgs.iterator();
+                while (iter.hasNext()) {
+                    //
+                    // HACK: Using double quote instead of single quote for now as the parser's handling of single quote is broken
+                    //
+
+                    buff.append('"').append(iter.next()).append('"');
+                    if (iter.hasNext()) {
+                        buff.append(" ");
+                    }
+                }
+            }
+
+            log.debug("Executing alias: {}", buff);
+
+            final Shell shell = ShellContextHolder.get().getShell();
+            ShellContext shellContext = new ShellContext() {
+                public Shell getShell() {
+                    return shell;
+                }
+                public IO getIo() {
+                    return context.getIo();
+                }
+                public Variables getVariables() {
+                    return context.getVariables();
+                }
+            };
+            Object result = executor.execute(shellContext, buff.toString());
+
+            log.debug("Alias result: {}", result);
+
+            return result;
+        }
+    }
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/commands/InfoAction.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/commands/InfoAction.java
new file mode 100644
index 0000000..8f3b580
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/commands/InfoAction.java
@@ -0,0 +1,177 @@
+/*
+ * 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.servicemix.kernel.gshell.core.commands;
+
+import java.lang.management.ClassLoadingMXBean;
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.lang.management.OperatingSystemMXBean;
+import java.lang.management.RuntimeMXBean;
+import java.lang.management.ThreadMXBean;
+import java.lang.reflect.Method;
+import java.text.DecimalFormat;
+import java.text.DecimalFormatSymbols;
+import java.text.NumberFormat;
+import java.util.Locale;
+
+import org.apache.geronimo.gshell.ansi.AnsiCode;
+import org.apache.geronimo.gshell.ansi.AnsiRenderer;
+import org.apache.geronimo.gshell.command.CommandAction;
+import org.apache.geronimo.gshell.command.CommandContext;
+import org.apache.geronimo.gshell.io.IO;
+import org.apache.servicemix.kernel.gshell.core.ServiceMixBranding;
+import org.codehaus.plexus.util.StringUtils;
+
+public class InfoAction implements CommandAction {
+
+    private ServiceMixBranding branding;
+
+    private IO io;
+
+    private AnsiRenderer renderer = new AnsiRenderer();
+    private NumberFormat fmtI = new DecimalFormat("###,###", new DecimalFormatSymbols(Locale.ENGLISH));
+    private NumberFormat fmtD = new DecimalFormat("###,##0.000", new DecimalFormatSymbols(Locale.ENGLISH));
+
+    public InfoAction(ServiceMixBranding branding) {
+        this.branding = branding;
+    }
+
+    public Object execute(CommandContext context) throws Exception {
+        int maxNameLen;
+
+        RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
+        OperatingSystemMXBean os = ManagementFactory.getOperatingSystemMXBean();
+        ThreadMXBean threads = ManagementFactory.getThreadMXBean();
+        MemoryMXBean mem = ManagementFactory.getMemoryMXBean();
+        ClassLoadingMXBean cl = ManagementFactory.getClassLoadingMXBean();
+        io = context.getIo();
+
+        //
+        // print ServiceMix informations
+        //
+        maxNameLen = 25;
+        io.out.println("ServiceMix");
+        printValue("ServiceMix home", maxNameLen, System.getProperty("servicemix.home"));
+        printValue("ServiceMix base", maxNameLen, System.getProperty("servicemix.base"));
+        printValue("ServiceMix Kernel version", maxNameLen, branding.getParent().getVersion());
+
+        if (branding.getApplicationName() != null && branding.getApplicationVersion() != null) {
+            printValue(branding.getApplicationName() + " version", maxNameLen, branding.getApplicationVersion());
+        }
+        io.out.println();
+
+        io.out.println("JVM");
+        printValue("Java Virtual Machine", maxNameLen, runtime.getVmName() + " version " + runtime.getVmVersion());
+        printValue("Vendor", maxNameLen, runtime.getVmVendor());
+        printValue("Uptime", maxNameLen, printDuration(runtime.getUptime()));
+        try {
+            printValue("Process CPU time", maxNameLen, printDuration(getSunOsValueAsLong(os, "getProcessCpuTime") / 1000000));
+        } catch (Throwable t) {}
+        printValue("Total compile time", maxNameLen, printDuration(ManagementFactory.getCompilationMXBean().getTotalCompilationTime()));
+
+        io.out.println("Threads");
+        printValue("Live threads", maxNameLen, Integer.toString(threads.getThreadCount()));
+        printValue("Daemon threads", maxNameLen, Integer.toString(threads.getDaemonThreadCount()));
+        printValue("Peak", maxNameLen, Integer.toString(threads.getPeakThreadCount()));
+        printValue("Total started", maxNameLen, Long.toString(threads.getTotalStartedThreadCount()));
+
+        io.out.println("Memory");
+        printValue("Current heap size", maxNameLen, printSizeInKb(mem.getHeapMemoryUsage().getUsed()));
+        printValue("Maximum heap size", maxNameLen, printSizeInKb(mem.getHeapMemoryUsage().getMax()));
+        printValue("Committed heap size", maxNameLen, printSizeInKb(mem.getHeapMemoryUsage().getCommitted()));
+        printValue("Pending objects", maxNameLen, Integer.toString(mem.getObjectPendingFinalizationCount()));
+        for (GarbageCollectorMXBean gc : ManagementFactory.getGarbageCollectorMXBeans()) {
+            String val = "Name = '" + gc.getName() + "', Collections = " + gc.getCollectionCount() + ", Time = " + printDuration(gc.getCollectionTime());
+            printValue("Garbage collector", maxNameLen, val);
+        }
+
+        io.out.println("Classes");
+        printValue("Current classes loaded", maxNameLen, printLong(cl.getLoadedClassCount()));
+        printValue("Total classes loaded", maxNameLen, printLong(cl.getTotalLoadedClassCount()));
+        printValue("Total classes unloaded", maxNameLen, printLong(cl.getUnloadedClassCount()));
+
+        io.out.println("Operating system");
+        printValue("Name", maxNameLen, os.getName() + " version " + os.getVersion());
+        printValue("Architecture", maxNameLen, os.getArch());
+        printValue("Processors", maxNameLen, Integer.toString(os.getAvailableProcessors()));
+        try {
+            printValue("Total physical memory", maxNameLen, printSizeInKb(getSunOsValueAsLong(os, "getTotalPhysicalMemorySize")));
+            printValue("Free physical memory", maxNameLen, printSizeInKb(getSunOsValueAsLong(os, "getFreePhysicalMemorySize")));
+            printValue("Committed virtual memory", maxNameLen, printSizeInKb(getSunOsValueAsLong(os, "getCommittedVirtualMemorySize")));
+            printValue("Total swap space", maxNameLen, printSizeInKb(getSunOsValueAsLong(os, "getTotalSwapSpaceSize")));
+            printValue("Free swap space", maxNameLen, printSizeInKb(getSunOsValueAsLong(os, "getFreeSwapSpaceSize")));
+        } catch (Throwable t) {}
+
+        return null;
+    }
+
+    private long getSunOsValueAsLong(OperatingSystemMXBean os, String name) throws Exception {
+        Method mth = os.getClass().getMethod(name);
+        return (Long) mth.invoke(os);
+    }
+
+    private String printLong(long i) {
+        return fmtI.format(i);
+    }
+
+    private String printSizeInKb(double size) {
+        return fmtI.format((long) (size / 1024)) + " kbytes";
+    }
+
+    private String printDuration(double uptime) {
+        uptime /= 1000;
+        if (uptime < 60) {
+            return fmtD.format(uptime) + " seconds";
+        }
+        uptime /= 60;
+        if (uptime < 60) {
+            long minutes = (long) uptime;
+            String s = fmtI.format(minutes) + (minutes > 1 ? " minutes" : " minute");
+            return s;
+        }
+        uptime /= 60;
+        if (uptime < 24) {
+            long hours = (long) uptime;
+            long minutes = (long) ((uptime - hours) * 60);
+            String s = fmtI.format(hours) + (hours > 1 ? " hours" : " hour");
+            if (minutes != 0) {
+                s += " " + fmtI.format(minutes) + (minutes > 1 ? " minutes" : "minute");
+            }
+            return s;
+        }
+        uptime /= 24;
+        long days = (long) uptime;
+        long hours = (long) ((uptime - days) * 60);
+        String s = fmtI.format(days) + (days > 1 ? " days" : " day");
+        if (hours != 0) {
+            s += " " + fmtI.format(hours) + (hours > 1 ? " hours" : "hour");
+        }
+        return s;
+    }
+
+    void printSysValue(String prop, int pad) {
+        printValue(prop, pad, System.getProperty(prop));
+    }
+
+    void printValue(String name, int pad, String value) {
+        io.out.println("  " + renderer.render(AnsiRenderer.encode(StringUtils.rightPad(name, pad), AnsiCode.BOLD)) + "   " + value);
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/config/CommandParser.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/config/CommandParser.java
new file mode 100644
index 0000000..45d9d7d
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/config/CommandParser.java
@@ -0,0 +1,474 @@
+/*
+ * 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.servicemix.kernel.gshell.core.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.w3c.dom.Element;
+
+import org.apache.geronimo.gshell.command.Alias;
+import org.apache.geronimo.gshell.command.Link;
+import org.apache.geronimo.gshell.wisdom.command.AliasImpl;
+import org.apache.geronimo.gshell.wisdom.command.ConfigurableCommandCompleter;
+import org.apache.geronimo.gshell.wisdom.command.LinkImpl;
+import org.apache.geronimo.gshell.wisdom.registry.CommandLocationImpl;
+import org.apache.servicemix.kernel.gshell.core.CommandBundle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.BeanDefinitionStoreException;
+import org.springframework.beans.factory.config.BeanDefinition;
+import org.springframework.beans.factory.config.BeanDefinitionHolder;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
+import org.springframework.beans.factory.support.AbstractBeanDefinition;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
+import org.springframework.beans.factory.support.GenericBeanDefinition;
+import org.springframework.beans.factory.support.ManagedList;
+import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
+import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
+import org.springframework.beans.factory.xml.ParserContext;
+import org.springframework.util.StringUtils;
+import org.springframework.util.xml.DomUtils;
+
+public class CommandParser extends AbstractBeanDefinitionParser {
+
+    public static final String ID = ID_ATTRIBUTE;
+
+    public static final String DESCRIPTION = "description";
+
+    public static final String PLUGIN_TEMPLATE = "pluginTemplate";
+
+    public static final String ACTION = "action";
+
+    public static final String ACTION_ID = "actionId";
+
+    public static final String COMMAND_TEMPLATE_SUFFIX = "CommandTemplate";
+
+    public static final String COMMAND_BUNDLE = "command-bundle";
+
+    public static final String NAME = "name";
+
+    public static final String LOCATION = "location";
+
+    public static final String COMMANDS = "commands";
+
+    public static final String COMMAND = "command";
+
+    public static final String TYPE = "type";
+
+    public static final String DOCUMENTER = "documenter";
+
+    public static final String COMPLETER = "completer";
+
+    public static final String COMPLETERS = "completers";
+
+    public static final String BEAN = "bean";
+
+    public static final String REF = "ref";
+
+    public static final String NULL = "null";
+
+    public static final String MESSAGE_SOURCE = "message-source";
+
+    public static final String MESSAGES = "messages";
+
+    public static final String PROTOTYPE = "prototype";
+
+    public static final String ALIAS = "alias";
+
+    public static final String ALIASES = "aliases";
+
+    public static final String LINK = "link";
+
+    public static final String LINKS = "links";
+
+    public static final String TARGET = "target";
+
+    @Override
+    protected boolean shouldGenerateId() {
+        return true;
+    }
+
+    @Override
+    protected boolean shouldGenerateIdAsFallback() {
+        return true;
+    }
+
+    protected AbstractBeanDefinition parseInternal(final Element element, final ParserContext context) {
+        assert element != null;
+        assert context != null;
+
+        Builder builder = new Builder(context);
+        BeanDefinitionBuilder plugin = builder.parseCommandBundle(element);
+        return plugin.getBeanDefinition();
+    }
+
+    /**
+     * Helper to deal with command type.
+     */
+    private enum CommandType
+    {
+        STATELESS,
+        STATEFUL;
+
+        public static CommandType parse(final String text) {
+            assert text != null;
+
+            return valueOf(text.toUpperCase());
+        }
+
+        public String getTemplateName() {
+            return name().toLowerCase() + COMMAND_TEMPLATE_SUFFIX;
+        }
+
+        public void wire(final BeanDefinitionBuilder command, final BeanDefinitionHolder action) {
+            assert command != null;
+            assert action != null;
+
+            switch (this) {
+                case STATELESS:
+                    command.addPropertyReference(ACTION, action.getBeanName());
+                    break;
+
+                case STATEFUL:
+                    command.addPropertyValue(ACTION_ID, action.getBeanName());
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Helper to build plugin related bean definitions.
+     */
+    private class Builder
+    {
+        private final Logger log = LoggerFactory.getLogger(getClass());
+
+        private ParserContext context;
+
+        public Builder(final ParserContext context) {
+            assert context != null;
+
+            this.context = context;
+        }
+
+        private String resolveId(final Element element, final BeanDefinition def) throws BeanDefinitionStoreException {
+            assert element != null;
+            assert def != null;
+
+            if (shouldGenerateId()) {
+                return context.getReaderContext().generateBeanName(def);
+            }
+
+            String id = element.getAttribute(ID_ATTRIBUTE);
+
+            if (!StringUtils.hasText(id) && shouldGenerateIdAsFallback()) {
+                id = context.getReaderContext().generateBeanName(def);
+            }
+
+            return id;
+        }
+
+        @SuppressWarnings({"unchecked"})
+        private List<Element> getChildElements(final Element element, final String name) {
+            assert element != null;
+            assert name != null;
+
+            return DomUtils.getChildElementsByTagName(element, name);
+        }
+
+        @SuppressWarnings({"unchecked"})
+        private List<Element> getChildElements(final Element element, final String[] names) {
+            assert element != null;
+            assert names != null;
+
+            return DomUtils.getChildElementsByTagName(element, names);
+        }
+
+        @SuppressWarnings({"unchecked"})
+        private Element getChildElement(final Element element, final String name) {
+            assert element != null;
+            assert name != null;
+
+            List<Element> elements = DomUtils.getChildElementsByTagName(element, name);
+            if (elements != null && !elements.isEmpty()) {
+                return elements.get(0);
+            }
+            return null;
+        }
+
+        private BeanDefinitionParserDelegate createBeanDefinitionParserDelegate(final Element element) {
+            assert element != null;
+
+            BeanDefinitionParserDelegate parser = new BeanDefinitionParserDelegate(context.getReaderContext());
+            parser.initDefaults(element.getOwnerDocument().getDocumentElement());
+            return parser;
+        }
+
+        private BeanDefinitionHolder parseBeanDefinitionElement(final Element element) {
+            assert element != null;
+
+            BeanDefinitionParserDelegate parser = createBeanDefinitionParserDelegate(element);
+            return parser.parseBeanDefinitionElement(element);
+        }
+
+        private void parseAndApplyDescription(final Element element, final BeanDefinition def) {
+            assert element != null;
+            assert def != null;
+
+            Element desc = getChildElement(element, DESCRIPTION);
+            if (desc != null) {
+                if (def instanceof AbstractBeanDefinition) {
+                    ((AbstractBeanDefinition)def).setDescription(desc.getTextContent());
+                }
+            }
+        }
+
+        private void parseAndApplyDescription(final Element element, final BeanDefinitionBuilder builder) {
+            assert element != null;
+            assert builder != null;
+
+            parseAndApplyDescription(element, builder.getRawBeanDefinition());
+        }
+
+        private BeanDefinitionHolder register(final BeanDefinitionHolder holder) {
+            assert holder != null;
+
+            registerBeanDefinition(holder, context.getRegistry());
+            return holder;
+        }
+
+        private BeanDefinitionHolder register(final BeanDefinition def, final String id) {
+            assert def != null;
+            assert id != null;
+
+            BeanDefinitionHolder holder = new BeanDefinitionHolder(def, id);
+            return register(holder);
+        }
+
+        //
+        // <gshell:command-bundle>
+        //
+
+        private BeanDefinitionBuilder parseCommandBundle(final Element element) {
+            assert element != null;
+
+            log.trace("Parse command bundle; element; {}", element);
+
+            BeanDefinitionBuilder bundle = BeanDefinitionBuilder.rootBeanDefinition(CommandBundle.class);
+            parseAndApplyDescription(element, bundle);
+
+            //
+            // TODO: Figure out how we can save the order of <gshell:command> and <gshell:link> so that 'help' displays them in the order they are defined
+            //
+
+            ManagedList commands = new ManagedList();
+            commands.addAll(parseCommands(element));
+            bundle.addPropertyValue(COMMANDS, commands);
+
+            ManagedList links = new ManagedList();
+            links.addAll(parseLinks(element));
+            bundle.addPropertyValue(LINKS, links);
+
+            ManagedList aliases = new ManagedList();
+            aliases.addAll(parseAliases(element));
+            bundle.addPropertyValue(ALIASES, aliases);
+
+            return bundle;
+        }
+
+        //
+        // <gshell:command>
+        //
+
+        private List<BeanDefinition> parseCommands(final Element element) {
+            assert element != null;
+
+            log.trace("Parse commands; element; {}", element);
+
+            List<BeanDefinition> commands = new ArrayList<BeanDefinition>();
+
+            List<Element> children = getChildElements(element, COMMAND);
+
+            for (Element child : children) {
+                BeanDefinitionBuilder command = parseCommand(child);
+                commands.add(command.getBeanDefinition());
+            }
+
+            return commands;
+        }
+
+        private BeanDefinitionBuilder parseCommand(final Element element) {
+            assert element != null;
+
+            log.trace("Parse command; element; {}", element);
+
+            CommandType type = CommandType.parse(element.getAttribute(TYPE));
+            BeanDefinitionBuilder command = BeanDefinitionBuilder.childBeanDefinition(type.getTemplateName());
+            parseAndApplyDescription(element, command);
+
+            Element child;
+
+            // Required children elements
+
+            String name = element.getAttribute(NAME);
+            BeanDefinition def = new GenericBeanDefinition();
+            def.setBeanClassName(CommandLocationImpl.class.getName());
+            def.getConstructorArgumentValues().addGenericArgumentValue(name);
+            command.addPropertyValue(LOCATION, def);
+
+            child = getChildElement(element, ACTION);
+            BeanDefinitionHolder action = parseCommandAction(child);
+            type.wire(command, action);
+
+            // Optional children elements
+
+            child = getChildElement(element, DOCUMENTER);
+            if (child != null) {
+                BeanDefinitionHolder holder = parseBeanDefinitionElement(child);
+                command.addPropertyValue(DOCUMENTER, holder.getBeanDefinition());
+            }
+
+            child = getChildElement(element, COMPLETER);
+            if (child != null) {
+                BeanDefinitionHolder holder = parseBeanDefinitionElement(child);
+                command.addPropertyValue(COMPLETER, holder.getBeanDefinition());
+            }
+
+            child = getChildElement(element, COMPLETERS);
+            if (child != null) {
+                BeanDefinitionBuilder completer = parseCommandCompleters(child);
+                command.addPropertyValue(COMPLETER, completer.getBeanDefinition());
+            }
+
+            child = getChildElement(element, MESSAGE_SOURCE);
+            if (child != null) {
+                BeanDefinitionHolder holder = parseBeanDefinitionElement(child);
+                command.addPropertyValue(MESSAGES, holder.getBeanDefinition());
+            }
+
+            //String id = resolveId(element, command.getBeanDefinition());
+            //BeanDefinitionHolder holder = register(command.getBeanDefinition(), id);
+
+            return command;
+        }
+
+        //
+        // <gshell:completers>
+        //
+
+        private BeanDefinitionBuilder parseCommandCompleters(final Element element) {
+            assert element != null;
+
+            BeanDefinitionBuilder completer = BeanDefinitionBuilder.rootBeanDefinition(ConfigurableCommandCompleter.class);
+
+            ManagedList completers = new ManagedList();
+
+            List<Element> children = getChildElements(element, new String[] {BEAN, REF, NULL});
+
+            for (Element child : children) {
+                if (DomUtils.nodeNameEquals(child, BEAN)) {
+                    BeanDefinitionHolder holder = parseBeanDefinitionElement(child);
+                    // noinspection unchecked
+                    completers.add(holder.getBeanDefinition());
+                }
+                else if (DomUtils.nodeNameEquals(child, REF)) {
+                    BeanDefinitionParserDelegate parser = createBeanDefinitionParserDelegate(child);
+                    RuntimeBeanReference ref = (RuntimeBeanReference) parser.parsePropertySubElement(child, completer.getRawBeanDefinition());
+                    // noinspection unchecked
+                    completers.add(ref);
+                }
+                else if (DomUtils.nodeNameEquals(child, NULL)) {
+                    // noinspection unchecked
+                    completers.add(null);
+                }
+            }
+
+            completer.addConstructorArgValue(completers);
+
+            return completer;
+        }
+
+        //
+        // <gshell:action>
+        //
+
+        private BeanDefinitionHolder parseCommandAction(final Element element) {
+            assert element != null;
+
+            log.trace("Parse command action; element; {}", element);
+
+            // Construct the action
+            BeanDefinition action = parseBeanDefinitionElement(element).getBeanDefinition();
+
+            // All actions are configured as prototypes
+            action.setScope(PROTOTYPE);
+
+            // Generate id and register the bean
+            String id = resolveId(element, action);
+            return register(action, id);
+        }
+
+        //
+        // <gshell:link>
+        //
+
+        private List<Link> parseLinks(final Element element) {
+            assert element != null;
+
+            log.trace("Parse links; element; {}", element);
+
+            List<Link> links = new ArrayList<Link>();
+
+            List<Element> children = getChildElements(element, LINK);
+
+            for (Element child : children) {
+                String name = child.getAttribute(NAME);
+                String target = child.getAttribute(TARGET);
+
+                links.add(new LinkImpl(name, target));
+            }
+
+            return links;
+        }
+
+        //
+        // <gshell:alias>
+        //
+
+        private List<Alias> parseAliases(final Element element) {
+            assert element != null;
+
+            log.trace("Parse aliases; element; {}", element);
+
+            List<Alias> aliases = new ArrayList<Alias>();
+
+            List<Element> children = getChildElements(element, ALIAS);
+
+            for (Element child : children) {
+                String name = child.getAttribute(NAME);
+                String alias = child.getAttribute(ALIAS);
+
+                aliases.add(new AliasImpl(name, alias));
+            }
+
+            return aliases;
+        }
+    }
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/config/NamespaceHandler.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/config/NamespaceHandler.java
new file mode 100644
index 0000000..3e464d3
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/config/NamespaceHandler.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.servicemix.kernel.gshell.core.config;
+
+import org.springframework.beans.factory.xml.NamespaceHandlerSupport;
+
+public class NamespaceHandler extends NamespaceHandlerSupport {
+
+    public void init() {
+        registerBeanDefinitionParser(CommandParser.COMMAND_BUNDLE, new CommandParser());
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/sshd/BogusPasswordAuthenticator.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/sshd/BogusPasswordAuthenticator.java
new file mode 100644
index 0000000..34e2527
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/sshd/BogusPasswordAuthenticator.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.servicemix.kernel.gshell.core.sshd;
+
+import org.apache.sshd.server.PasswordAuthenticator;
+
+public class BogusPasswordAuthenticator implements PasswordAuthenticator {
+
+    public Object authenticate(String username, String password) {
+        return (username != null && username.equals(password)) ? username : null;
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/sshd/SshServerFactory.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/sshd/SshServerFactory.java
new file mode 100644
index 0000000..fbf9041
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/sshd/SshServerFactory.java
@@ -0,0 +1,58 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.servicemix.kernel.gshell.core.sshd;
+
+import org.apache.sshd.SshServer;
+
+public class SshServerFactory {
+
+    private SshServer server;
+
+    private boolean start;
+
+    public SshServerFactory(SshServer server) {
+        this.server = server;
+    }
+
+    public boolean isStart() {
+        return start;
+    }
+
+    public void setStart(boolean start) {
+        this.start = start;
+    }
+
+    public void start() throws Exception {
+        if (start) {
+            try {
+                server.start();
+            } catch (Exception e) {
+                e.printStackTrace();
+                throw e;
+            }
+        }
+    }
+
+    public void stop() throws Exception {
+        if (start) {
+            server.stop();
+        }
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/vfs/mvn/MvnFileObject.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/vfs/mvn/MvnFileObject.java
new file mode 100644
index 0000000..41a2bb8
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/vfs/mvn/MvnFileObject.java
@@ -0,0 +1,56 @@
+/*
+ * 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.servicemix.kernel.gshell.core.vfs.mvn;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.httpclient.URIException;
+import org.apache.commons.vfs.FileName;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.provider.URLFileName;
+import org.apache.commons.vfs.provider.url.UrlFileObject;
+
+public class MvnFileObject extends UrlFileObject {
+
+    public MvnFileObject(MvnFileSystem fs, FileName fileName) {
+        super(fs, fileName);
+    }
+
+    protected URL createURL(final FileName name) throws MalformedURLException, FileSystemException, URIException
+    {
+        String url;
+        if (name instanceof URLFileName)
+        {
+            URLFileName urlName = (URLFileName) getName();
+
+            // TODO: charset
+            url = urlName.getURIEncoded(null);
+        }
+        else
+        {
+            url = getName().getURI();
+        }
+        if (url.startsWith("mvn:///")) {
+            url = "mvn:" + url.substring("mvn:///".length());
+        }
+        return new URL(url);
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/vfs/mvn/MvnFileProvider.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/vfs/mvn/MvnFileProvider.java
new file mode 100644
index 0000000..7d88cd6
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/vfs/mvn/MvnFileProvider.java
@@ -0,0 +1,66 @@
+/*
+ * 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.servicemix.kernel.gshell.core.vfs.mvn;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.vfs.FileName;
+import org.apache.commons.vfs.FileObject;
+import org.apache.commons.vfs.FileSystem;
+import org.apache.commons.vfs.FileSystemException;
+import org.apache.commons.vfs.FileSystemOptions;
+import org.apache.commons.vfs.provider.url.UrlFileProvider;
+
+public class MvnFileProvider extends UrlFileProvider {
+
+    /**
+     * Locates a file object, by absolute URI.
+     */
+    public synchronized FileObject findFile(final FileObject baseFile,
+                                            final String uri,
+                                            final FileSystemOptions fileSystemOptions)
+        throws FileSystemException
+    {
+        try
+        {
+            final URL url = new URL(uri);
+
+            URL rootUrl = new URL(url, "/");
+            final String key = this.getClass().getName() + rootUrl.toString();
+            FileSystem fs = findFileSystem(key, fileSystemOptions);
+            if (fs == null)
+            {
+                String extForm = rootUrl.toExternalForm();
+                final FileName rootName = getContext().parseURI(extForm);
+                // final FileName rootName =
+                //    new BasicFileName(rootUrl, FileName.ROOT_PATH);
+                fs = new MvnFileSystem(rootName, fileSystemOptions);
+                addFileSystem(key, fs);
+            }
+            return fs.resolveFile(url.getPath());
+        }
+        catch (final MalformedURLException e)
+        {
+            throw new FileSystemException("vfs.provider.url/badly-formed-uri.error", uri, e);
+        }
+    }
+
+
+}
diff --git a/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/vfs/mvn/MvnFileSystem.java b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/vfs/mvn/MvnFileSystem.java
new file mode 100644
index 0000000..7583eb5
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/java/org/apache/servicemix/kernel/gshell/core/vfs/mvn/MvnFileSystem.java
@@ -0,0 +1,35 @@
+/*
+ * 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.servicemix.kernel.gshell.core.vfs.mvn;
+
+import org.apache.commons.vfs.FileName;
+import org.apache.commons.vfs.FileObject;
+import org.apache.commons.vfs.FileSystemOptions;
+import org.apache.commons.vfs.provider.url.UrlFileSystem;
+
+public class MvnFileSystem extends UrlFileSystem {
+
+    protected MvnFileSystem(FileName fileName, FileSystemOptions fileSystemOptions) {
+        super(fileName, fileSystemOptions);
+    }
+
+    protected FileObject createFile(FileName fileName) {
+        return new MvnFileObject(this, fileName);
+    }
+}
diff --git a/karaf/gshell/gshell-core/src/main/resources/META-INF/spring.handlers b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring.handlers
new file mode 100644
index 0000000..2315764
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring.handlers
@@ -0,0 +1,24 @@
+##
+## 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.
+##
+
+##
+## $Rev: 697807 $ $Date: 2008-09-22 20:12:04 +0700 (Mon, 22 Sep 2008) $
+##
+
+http\://servicemix.apache.org/schema/servicemix-gshell=org.apache.servicemix.kernel.gshell.core.config.NamespaceHandler
\ No newline at end of file
diff --git a/karaf/gshell/gshell-core/src/main/resources/META-INF/spring.schemas b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring.schemas
new file mode 100644
index 0000000..67eca68
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring.schemas
@@ -0,0 +1,24 @@
+##
+## 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.
+##
+
+##
+## $Rev: 697807 $ $Date: 2008-09-22 20:12:04 +0700 (Mon, 22 Sep 2008) $
+##
+
+http\://servicemix.apache.org/schema/servicemix-gshell/servicemix-gshell.xsd=org/apache/servicemix/kernel/gshell/core/servicemix-gshell.xsd
diff --git a/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-commands.xml b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-commands.xml
new file mode 100644
index 0000000..dbcafd3
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-commands.xml
@@ -0,0 +1,277 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xmlns:gshell="http://servicemix.apache.org/schema/servicemix-gshell"
+       xsi:schemaLocation="
+  http://www.springframework.org/schema/beans
+  http://www.springframework.org/schema/beans/spring-beans.xsd
+  http://www.springframework.org/schema/util
+  http://www.springframework.org/schema/util/spring-util.xsd
+  http://servicemix.apache.org/schema/servicemix-gshell
+  http://servicemix.apache.org/schema/servicemix-gshell/servicemix-gshell.xsd"
+       default-autowire="no"
+       default-dependency-check="none"
+       default-init-method="init"
+       default-destroy-method="destroy">
+
+    <import resource="classpath:org/apache/servicemix/kernel/gshell/core/commands.xml" />
+
+    <bean id="vfsCommandActionTemplate" abstract="true">
+        <property name="fileSystemAccess" ref="fileSystemAccess"/>
+    </bean>
+
+    <gshell:command-bundle>
+        <gshell:command name="about">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.AboutAction">
+                <constructor-arg ref="application"/>
+            </gshell:action>
+        </gshell:command>
+
+        <gshell:command name="help">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.HelpAction">
+                <constructor-arg ref="commandResolver"/>
+            </gshell:action>
+            <gshell:completers>
+                <bean class="org.apache.geronimo.gshell.console.completer.AggregateCompleter">
+                    <constructor-arg>
+                        <list>
+                            <ref bean="aliasNameCompleter"/>
+                            <ref bean="commandNameCompleter"/>
+                        </list>
+                    </constructor-arg>
+                </bean>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="exit">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.ExitAction"/>
+        </gshell:command>
+
+        <gshell:link name="quit" target="exit"/>
+
+        <gshell:command name="echo">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.EchoAction"/>
+        </gshell:command>
+
+        <gshell:command name="clear" type="stateless">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.ClearAction"/>
+        </gshell:command>
+
+        <gshell:command name="source">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.SourceAction">
+                <constructor-arg ref="commandLineExecutor"/>
+                <constructor-arg ref="fileSystemAccess"/>
+            </gshell:action>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="set">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.SetAction"/>
+        </gshell:command>
+
+        <gshell:command name="unset">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.UnsetAction"/>
+            <gshell:completers>
+                <ref bean="variableNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="alias">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.AliasAction">
+                <constructor-arg ref="aliasRegistry"/>
+            </gshell:action>
+        </gshell:command>
+
+        <gshell:command name="unalias">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.UnaliasAction">
+                <constructor-arg ref="aliasRegistry"/>
+            </gshell:action>
+            <gshell:completers>
+                <ref bean="aliasNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="history">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.HistoryAction"/>
+        </gshell:command>
+
+        <gshell:command name="info">
+            <gshell:action class="org.apache.servicemix.kernel.gshell.core.commands.InfoAction">
+                <constructor-arg ref="branding" />
+            </gshell:action>
+        </gshell:command>
+    </gshell:command-bundle>
+
+    <gshell:command-bundle>
+        <gshell:command name="ssh">
+            <gshell:action class="org.apache.geronimo.gshell.commands.ssh.SshAction"/>
+        </gshell:command>
+
+        <gshell:command name="sshd">
+            <gshell:action class="org.apache.geronimo.gshell.commands.ssh.SshServerAction"/>
+        </gshell:command>
+    </gshell:command-bundle>
+
+    <gshell:command-bundle>
+        <gshell:command name="exec">
+            <gshell:action class="org.apache.geronimo.gshell.commands.shell.ExecuteAction"/>
+        </gshell:command>
+
+        <gshell:command name="java">
+            <gshell:action class="org.apache.geronimo.gshell.commands.shell.JavaAction"/>
+        </gshell:command>
+
+        <gshell:command name="sleep">
+            <gshell:action class="org.apache.geronimo.gshell.commands.shell.SleepAction"/>
+        </gshell:command>
+
+        <gshell:command name="date">
+            <gshell:action class="org.apache.geronimo.gshell.commands.shell.DateAction"/>
+        </gshell:command>
+
+        <gshell:command name="edit">
+            <gshell:action class="org.apache.geronimo.gshell.commands.shell.EditAction">
+                <property name="fileSystemAccess" ref="fileSystemAccess"/>
+            </gshell:action>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="find">
+            <gshell:action class="org.apache.geronimo.gshell.commands.shell.FindAction">
+                <property name="fileSystemAccess" ref="fileSystemAccess"/>
+            </gshell:action>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="sort">
+            <gshell:action class="org.apache.geronimo.gshell.commands.text.SortAction">
+                <property name="fileSystemAccess" ref="fileSystemAccess"/>
+            </gshell:action>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+    </gshell:command-bundle>
+
+    <gshell:command-bundle>
+        <gshell:command name="hostname">
+            <gshell:action class="org.apache.geronimo.gshell.commands.network.HostnameAction"/>
+        </gshell:command>
+    </gshell:command-bundle>
+
+    <gshell:command-bundle>
+        <gshell:link name="print" target="echo"/>
+
+        <gshell:command name="printf">
+            <gshell:action class="org.apache.geronimo.gshell.commands.text.PrintfAction"/>
+        </gshell:command>
+
+        <gshell:command name="cat">
+            <gshell:action class="org.apache.geronimo.gshell.commands.text.CatAction">
+                <property name="fileSystemAccess" ref="fileSystemAccess"/>
+            </gshell:action>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="grep">
+            <gshell:action class="org.apache.geronimo.gshell.commands.text.GrepAction"/>
+        </gshell:command>
+    </gshell:command-bundle>
+
+    <gshell:command-bundle>
+        <gshell:command name="cd">
+            <gshell:action class="org.apache.geronimo.gshell.commands.file.ChangeDirectoryAction" parent="vfsCommandActionTemplate"/>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="pwd" type="stateless">
+            <gshell:action class="org.apache.geronimo.gshell.commands.file.CurrentDirectoryAction" parent="vfsCommandActionTemplate"/>
+        </gshell:command>
+
+        <gshell:command name="ls">
+            <gshell:action class="org.apache.geronimo.gshell.commands.file.ListDirectoryAction" parent="vfsCommandActionTemplate"/>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:link name="dir" target="ls"/>
+
+        <gshell:command name="cp">
+            <gshell:action class="org.apache.geronimo.gshell.commands.file.CopyAction" parent="vfsCommandActionTemplate"/>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:link name="copy" target="cp"/>
+
+        <gshell:command name="rm">
+            <gshell:action class="org.apache.geronimo.gshell.commands.file.RemoveAction" parent="vfsCommandActionTemplate"/>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:link name="del" target="rm"/>
+
+        <gshell:command name="fileinfo">
+            <gshell:action class="org.apache.geronimo.gshell.commands.file.FileInfoAction" parent="vfsCommandActionTemplate"/>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="touch">
+            <gshell:action class="org.apache.geronimo.gshell.commands.file.TouchAction" parent="vfsCommandActionTemplate"/>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+    </gshell:command-bundle>
+
+</beans>
diff --git a/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-local.xml b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-local.xml
new file mode 100644
index 0000000..a047339
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-local.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xmlns:osgi="http://www.springframework.org/schema/osgi"
+       xsi:schemaLocation="
+  http://www.springframework.org/schema/beans
+  http://www.springframework.org/schema/beans/spring-beans.xsd
+  http://www.springframework.org/schema/util
+  http://www.springframework.org/schema/util/spring-util.xsd
+  http://www.springframework.org/schema/osgi
+  http://www.springframework.org/schema/osgi/spring-osgi.xsd"
+       default-autowire="no"
+       default-dependency-check="none"
+       default-init-method="init"
+       default-destroy-method="destroy">
+
+    <bean id="localShellWrapped" parent="shell" init-method="init" destroy-method="close"/>
+
+    <bean id="localShell" class="org.apache.servicemix.kernel.gshell.core.ShellWrapper">
+        <constructor-arg ref="localShellWrapped" />
+    </bean>
+
+    <osgi:reference id="mainService" interface="org.apache.servicemix.kernel.main.spi.MainService"/>
+
+    <bean id="localConsole" class="org.apache.servicemix.kernel.gshell.core.LocalConsole">
+        <property name="createLocalShell" value="${servicemix.startLocalConsole}"/>
+        <property name="shell" ref="localShell"/>
+        <property name="mainService" ref="mainService" />
+    </bean>
+
+</beans>
\ No newline at end of file
diff --git a/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-osgi.xml b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-osgi.xml
new file mode 100644
index 0000000..b99626a
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-osgi.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:ctx="http://www.springframework.org/schema/context"
+       xmlns:osgi="http://www.springframework.org/schema/osgi"
+       xmlns:osgix="http://www.springframework.org/schema/osgi-compendium"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xsi:schemaLocation="
+  http://www.springframework.org/schema/beans
+  http://www.springframework.org/schema/beans/spring-beans.xsd
+  http://www.springframework.org/schema/context
+  http://www.springframework.org/schema/context/spring-context.xsd
+  http://www.springframework.org/schema/util
+  http://www.springframework.org/schema/util/spring-util.xsd
+  http://www.springframework.org/schema/osgi
+  http://www.springframework.org/schema/osgi/spring-osgi.xsd
+  http://www.springframework.org/schema/osgi-compendium
+  http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd"
+       default-autowire="no"
+       default-dependency-check="none"
+       default-init-method="init"
+       default-destroy-method="destroy">
+
+    <bean id="osgiCommandRegistry" class="org.apache.servicemix.kernel.gshell.core.OsgiCommandRegistry">
+        <constructor-arg ref="commandRegistry" />
+    </bean>
+
+    <bean id="osgiAliasRegistry" class="org.apache.servicemix.kernel.gshell.core.OsgiAliasRegistry">
+        <constructor-arg ref="aliasRegistry" />
+    </bean>
+
+    <osgi:list id="osgiCommands" interface="org.apache.geronimo.gshell.command.Command" cardinality="0..N">
+        <osgi:listener ref="osgiCommandRegistry" bind-method="register" unbind-method="unregister" />
+    </osgi:list>
+
+    <osgi:list id="osgiLinkCommands" interface="org.apache.geronimo.gshell.command.Link" cardinality="0..N">
+        <osgi:listener ref="osgiCommandRegistry" bind-method="register" unbind-method="unregister" />
+    </osgi:list>
+
+    <osgi:list id="osgiAliases" interface="org.apache.geronimo.gshell.command.Alias" cardinality="0..N">
+        <osgi:listener ref="osgiAliasRegistry" bind-method="register" unbind-method="unregister" />
+    </osgi:list>
+
+    <osgi:service ref="localShell" interface="org.apache.geronimo.gshell.shell.Shell">
+    </osgi:service>
+
+    <osgi:service ref="commandLineExecutor" interface="org.apache.geronimo.gshell.commandline.CommandLineExecutor">
+    </osgi:service>
+
+    <osgix:cm-properties id="cmProps" persistent-id="org.apache.servicemix.shell">
+        <prop key="sshPort">8101</prop>
+        <prop key="sshRealm">servicemix</prop>
+        <prop key="hostKey">${servicemix.base}/etc/host.key</prop>
+    </osgix:cm-properties>
+
+    <ctx:property-placeholder properties-ref="cmProps" />
+    
+</beans>
\ No newline at end of file
diff --git a/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-remote.xml b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-remote.xml
new file mode 100644
index 0000000..d68ee51
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-remote.xml
@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xmlns:osgi="http://www.springframework.org/schema/osgi"
+       xmlns:jaas="http://servicemix.apache.org/jaas"
+       xsi:schemaLocation="
+  http://www.springframework.org/schema/beans
+  http://www.springframework.org/schema/beans/spring-beans.xsd
+  http://www.springframework.org/schema/util
+  http://www.springframework.org/schema/util/spring-util.xsd
+  http://www.springframework.org/schema/osgi
+  http://www.springframework.org/schema/osgi/spring-osgi.xsd
+  http://servicemix.apache.org/jaas
+  http://servicemix.apache.org/schema/servicemix-jaas.xsd"
+       default-autowire="no"
+       default-dependency-check="none"
+       default-init-method="init"
+       default-destroy-method="destroy">
+
+    <bean name="sshClient" class="org.apache.sshd.SshClient" factory-method="setUpDefaultClient" init-method="start" destroy-method="stop">
+    </bean>
+
+    <bean name="sshServer" class="org.apache.sshd.SshServer" factory-method="setUpDefaultServer" scope="prototype">
+        <property name="port" value="${sshPort}" />
+        <property name="shellFactory">
+            <bean class="org.apache.geronimo.gshell.commands.ssh.ShellFactoryImpl">
+                <property name="application" ref="application" />
+                <property name="completers">
+                    <list>
+                        <ref bean="commandsCompleter"/>
+                        <ref bean="aliasNameCompleter"/>
+                    </list>
+                </property>
+                <property name="executor" ref="commandLineExecutor" />
+                <property name="prompter">
+                    <bean class="org.apache.geronimo.gshell.wisdom.shell.ConsolePrompterImpl">
+                        <constructor-arg ref="application"/>
+                    </bean>
+                </property>
+                <property name="errorHandler">
+                    <bean class="org.apache.geronimo.gshell.wisdom.shell.ConsoleErrorHandlerImpl" />
+                </property>
+                <property name="history">
+                    <bean class="org.apache.geronimo.gshell.wisdom.shell.HistoryImpl">
+                        <constructor-arg ref="application"/>
+                    </bean>
+                </property>
+            </bean>
+        </property>
+        <property name="keyPairProvider" ref="keyPairProvider" />
+        <property name="passwordAuthenticator" ref="passwordAuthenticator" />
+    </bean>
+
+    <bean name="keyPairProvider" class="org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider">
+        <property name="path" value="${hostKey}" />
+    </bean>
+    <bean name="passwordAuthenticator" class="org.apache.sshd.server.jaas.JaasPasswordAuthenticator">
+        <property name="domain" value="${sshRealm}" />
+    </bean>
+
+    <bean id="sshServerFactory" class="org.apache.servicemix.kernel.gshell.core.sshd.SshServerFactory" init-method="start" destroy-method="stop">
+        <constructor-arg ref="sshServer" />
+        <property name="start" value="${servicemix.startRemoteShell}" />
+    </bean>
+
+    <!--
+    <jaas:config id="SshServer" rank="-1">
+        <jaas:module className="org.apache.geronimo.gshell.remote.server.auth.BogusLoginModule" flags="required" />
+    </jaas:config>
+    -->
+
+</beans>
\ No newline at end of file
diff --git a/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-vfs.xml b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-vfs.xml
new file mode 100644
index 0000000..3992f54
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell-vfs.xml
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xsi:schemaLocation="
+  http://www.springframework.org/schema/beans
+  http://www.springframework.org/schema/beans/spring-beans.xsd
+  http://www.springframework.org/schema/util
+  http://www.springframework.org/schema/util/spring-util.xsd
+  http://servicemix.apache.org/schema/servicemix-gshell
+  http://servicemix.apache.org/schema/servicemix-gshell/servicemix-gshell.xsd"
+       default-autowire="no"
+       default-dependency-check="none"
+       default-init-method="init"
+       default-destroy-method="destroy">
+
+    <bean id="fileSystemAccess" class="org.apache.geronimo.gshell.vfs.FileSystemAccessImpl">
+        <constructor-arg ref="fileSystemManager"/>
+    </bean>
+
+    <bean id="fileObjectNameCompleter" class="org.apache.geronimo.gshell.vfs.FileObjectNameCompleter">
+        <constructor-arg ref="fileSystemAccess"/>
+    </bean>
+
+    <bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
+        <property name="customEditors">
+            <map>
+                <entry key="org.apache.commons.vfs.CacheStrategy">
+                    <bean class="org.apache.geronimo.gshell.vfs.config.CacheStrategyEditor"/>
+                </entry>
+            </map>
+        </property>
+    </bean>
+
+    <!--
+    TODO: Set tempDir File arg in constructor to set the temporary location, may need 2 replicators?
+    -->
+    <bean id="defaultFileReplicator" class="org.apache.commons.vfs.impl.DefaultFileReplicator"/>
+
+    <bean id="fileSystemManager" class="org.apache.geronimo.gshell.vfs.config.FileSystemManagerFactoryBean">
+        <property name="filesCache">
+            <bean class="org.apache.commons.vfs.cache.SoftRefFilesCache"/>
+        </property>
+
+        <property name="cacheStrategy" value="ON_RESOLVE"/>
+
+        <property name="fileReplicator">
+            <bean class="org.apache.commons.vfs.impl.PrivilegedFileReplicator">
+                <constructor-arg ref="defaultFileReplicator"/>
+            </bean>
+        </property>
+
+        <!--
+        TODO: Try and root the temporary store under ${gshell.home}/tmp or something
+        -->
+        <property name="temporaryFileStore">
+            <ref bean="defaultFileReplicator"/>
+        </property>
+
+        <property name="fileContentInfoFactory">
+            <bean class="org.apache.commons.vfs.impl.FileContentInfoFilenameFactory"/>
+        </property>
+
+        <property name="defaultProvider">
+            <bean class="org.apache.commons.vfs.provider.url.UrlFileProvider"/>
+        </property>
+    </bean>
+
+    <bean class="org.apache.geronimo.gshell.vfs.config.FileProviderConfigurer">
+        <property name="fileSystemManager" ref="fileSystemManager"/>
+        <property name="scheme" value="tmp"/>
+        <property name="provider">
+            <bean class="org.apache.commons.vfs.provider.temp.TemporaryFileProvider"/>
+        </property>
+    </bean>
+
+    <bean class="org.apache.geronimo.gshell.vfs.config.FileProviderConfigurer">
+        <property name="fileSystemManager" ref="fileSystemManager"/>
+        <property name="scheme" value="ram"/>
+        <property name="provider">
+            <bean class="org.apache.commons.vfs.provider.ram.RamFileProvider"/>
+        </property>
+    </bean>
+
+    <bean class="org.apache.geronimo.gshell.vfs.config.FileProviderConfigurer">
+        <property name="fileSystemManager" ref="fileSystemManager"/>
+        <property name="scheme" value="file"/>
+        <property name="provider">
+            <bean class="org.apache.commons.vfs.provider.local.DefaultLocalFileProvider"/>
+        </property>
+    </bean>
+
+    <bean class="org.apache.geronimo.gshell.vfs.config.FileProviderConfigurer">
+        <property name="fileSystemManager" ref="fileSystemManager"/>
+        <property name="scheme" value="mvn"/>
+        <property name="provider">
+            <bean class="org.apache.servicemix.kernel.gshell.core.vfs.mvn.MvnFileProvider"/>
+        </property>
+    </bean>
+
+    <bean id="metaDataRegistry" class="org.apache.geronimo.gshell.vfs.provider.meta.data.MetaDataRegistryImpl">
+        <constructor-arg ref="eventManager" />
+    </bean>
+
+    <bean id="metaFileProviderConfigurer" class="org.apache.geronimo.gshell.vfs.config.FileProviderConfigurer">
+        <property name="fileSystemManager" ref="fileSystemManager"/>
+        <property name="scheme" value="meta"/>
+        <property name="provider">
+            <bean class="org.apache.geronimo.gshell.vfs.provider.meta.MetaFileProvider">
+                <constructor-arg ref="metaDataRegistry"/>
+            </bean>
+        </property>
+    </bean>
+
+</beans>
\ No newline at end of file
diff --git a/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell.xml b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell.xml
new file mode 100644
index 0000000..8bc494e
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/resources/META-INF/spring/gshell.xml
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:util="http://www.springframework.org/schema/util" xmlns:osgi="http://www.springframework.org/schema/osgi"
+       xsi:schemaLocation="http://www.springframework.org/schema/beans
+  http://www.springframework.org/schema/beans/spring-beans.xsd
+  http://www.springframework.org/schema/util
+  http://www.springframework.org/schema/util/spring-util.xsd
+  http://servicemix.apache.org/schema/servicemix-gshell
+  http://servicemix.apache.org/schema/servicemix-gshell/servicemix-gshell.xsd
+  http://www.springframework.org/schema/osgi
+  http://www.springframework.org/schema/osgi/spring-osgi-1.0.xsd"
+       default-autowire="no"
+       default-dependency-check="none"
+       default-init-method="init"
+       default-destroy-method="destroy">
+
+    <bean id="io" class="org.apache.geronimo.gshell.io.IO">
+        <property name="verbosity" value="DEBUG"/>
+    </bean>
+
+    <bean id="branding" class="org.apache.servicemix.kernel.gshell.core.ServiceMixBranding">
+        <property name="prompt" value="@|bold %{gshell.username}|@%{application.id}:@|bold %{gshell.group}|> " />
+    </bean>
+
+    <bean id="application" class="org.apache.servicemix.kernel.gshell.core.ApplicationImpl">
+        <property name="id" value="${servicemix.name}"/>
+        <property name="io" ref="io"/>
+        <property name="model">
+            <bean class="org.apache.geronimo.gshell.application.model.ApplicationModel">
+                <property name="branding" ref="branding"/>
+            </bean>
+        </property>
+        <property name="variables">
+            <bean class="org.apache.geronimo.gshell.command.Variables"/>
+        </property>
+    </bean>
+
+    <bean id="eventManager" class="org.apache.geronimo.gshell.event.EventManagerImpl"/>
+
+    <bean id="applicationManager" class="org.apache.servicemix.kernel.gshell.core.ApplicationManagerImpl">
+        <constructor-arg ref="eventManager" />
+        <constructor-arg ref="application" />
+    </bean>
+
+    <bean id="commandLineParser" class="org.apache.geronimo.gshell.parser.CommandLineParser"/>
+
+    <bean id="aliasRegistry" class="org.apache.geronimo.gshell.wisdom.registry.AliasRegistryImpl">
+        <constructor-arg ref="eventManager"/>
+    </bean>
+
+    <bean id="aliasMetaMapper" class="org.apache.geronimo.gshell.wisdom.registry.AliasMetaMapper">
+        <constructor-arg ref="eventManager"/>
+        <constructor-arg ref="metaDataRegistry"/>
+        <constructor-arg ref="aliasRegistry"/>
+    </bean>
+
+    <bean id="commandRegistry" class="org.apache.geronimo.gshell.wisdom.registry.CommandRegistryImpl">
+        <constructor-arg ref="eventManager"/>
+    </bean>
+
+    <bean id="commandMetaMapper" class="org.apache.geronimo.gshell.wisdom.registry.CommandMetaMapper">
+        <constructor-arg ref="eventManager"/>
+        <constructor-arg ref="metaDataRegistry"/>
+        <constructor-arg ref="commandRegistry"/>
+    </bean>
+
+    <bean id="groupDirResolver" class="org.apache.geronimo.gshell.wisdom.registry.GroupDirectoryResolver">
+        <constructor-arg ref="fileSystemAccess"/>
+    </bean>
+
+    <bean id="commandResolver" class="org.apache.geronimo.gshell.wisdom.registry.CommandResolverImpl">
+        <constructor-arg ref="fileSystemAccess"/>
+        <constructor-arg ref="groupDirResolver"/>
+    </bean>
+
+    <bean class="org.apache.servicemix.kernel.gshell.core.WorkAroundAliasCommand" scope="prototype">
+        <constructor-arg ref="commandLineExecutor"/>
+    </bean>
+
+    <bean class="org.apache.geronimo.gshell.wisdom.command.GroupCommand" scope="prototype"/>
+
+    <bean id="commandLineBuilder" class="org.apache.geronimo.gshell.wisdom.shell.CommandLineBuilderImpl">
+        <constructor-arg ref="commandLineParser"/>
+    </bean>
+
+    <bean id="commandLineExecutor" class="org.apache.geronimo.gshell.wisdom.shell.CommandLineExecutorImpl">
+        <constructor-arg ref="commandResolver"/>
+        <constructor-arg ref="commandLineBuilder"/>
+    </bean>
+
+    <bean id="shell" class="org.apache.geronimo.gshell.wisdom.shell.ShellImpl" scope="prototype" init-method="init" destroy-method="close">
+        <constructor-arg ref="application"/>
+        <constructor-arg ref="commandLineExecutor"/>
+
+        <property name="completers">
+            <list>
+                <ref bean="commandsCompleter"/>
+                <ref bean="aliasNameCompleter"/>
+            </list>
+        </property>
+        <property name="prompter">
+            <bean class="org.apache.geronimo.gshell.wisdom.shell.ConsolePrompterImpl">
+                <constructor-arg ref="application"/>
+            </bean>
+        </property>
+        <property name="errorHandler">
+            <bean class="org.apache.geronimo.gshell.wisdom.shell.ConsoleErrorHandlerImpl" />
+        </property>
+        <property name="history">
+            <bean class="org.apache.geronimo.gshell.wisdom.shell.HistoryImpl">
+                <constructor-arg ref="application"/>
+            </bean>
+        </property>
+    </bean>
+
+    <bean id="commandNameCompleter" class="org.apache.geronimo.gshell.wisdom.completer.CommandNameCompleter"
+          lazy-init="true">
+        <constructor-arg ref="eventManager"/>
+        <constructor-arg ref="commandRegistry"/>
+    </bean>
+
+    <bean id="aliasNameCompleter" class="org.apache.geronimo.gshell.wisdom.completer.AliasNameCompleter"
+          lazy-init="true">
+        <constructor-arg ref="eventManager"/>
+        <constructor-arg ref="aliasRegistry"/>
+    </bean>
+
+    <bean id="commandsCompleter" class="org.apache.geronimo.gshell.wisdom.completer.CommandsCompleter" lazy-init="true">
+        <constructor-arg ref="eventManager"/>
+        <constructor-arg ref="commandRegistry"/>
+    </bean>
+
+    <bean id="variableNameCompleter" class="org.apache.geronimo.gshell.wisdom.completer.VariableNameCompleter" lazy-init="true">
+    </bean>
+
+</beans>
\ No newline at end of file
diff --git a/karaf/gshell/gshell-core/src/main/resources/org/apache/geronimo/gshell/commands/text/SortAction.properties b/karaf/gshell/gshell-core/src/main/resources/org/apache/geronimo/gshell/commands/text/SortAction.properties
new file mode 100644
index 0000000..e4e787d
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/resources/org/apache/geronimo/gshell/commands/text/SortAction.properties
@@ -0,0 +1,27 @@
+##
+## 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.
+##
+
+##
+## $Rev: 703511 $ $Date: 2008-10-10 18:07:36 +0200 (Fri, 10 Oct 2008) $
+##
+
+command.description=Sort lines of text.
+
+command.manual=\
+  TODO: about manual
\ No newline at end of file
diff --git a/karaf/gshell/gshell-core/src/main/resources/org/apache/servicemix/kernel/gshell/core/commands.xml b/karaf/gshell/gshell-core/src/main/resources/org/apache/servicemix/kernel/gshell/core/commands.xml
new file mode 100644
index 0000000..8b91ee1
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/resources/org/apache/servicemix/kernel/gshell/core/commands.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xsi:schemaLocation="
+  http://www.springframework.org/schema/beans
+  http://www.springframework.org/schema/beans/spring-beans.xsd
+  http://www.springframework.org/schema/util
+  http://www.springframework.org/schema/util/spring-util.xsd">
+
+    <bean class="org.apache.servicemix.kernel.gshell.core.BeanContainerAwareProcessor" />
+
+    <bean id="statelessCommandTemplate" class="org.apache.geronimo.gshell.wisdom.command.StatelessCommand" abstract="true">
+        <property name="documenter">
+            <bean class="org.apache.geronimo.gshell.wisdom.command.MessageSourceCommandDocumenter"/>
+        </property>
+
+        <property name="messages">
+            <bean class="org.apache.geronimo.gshell.wisdom.command.CommandMessageSource"/>
+        </property>
+    </bean>
+
+    <bean id="statefulCommandTemplate" class="org.apache.geronimo.gshell.wisdom.command.StatefulCommand" abstract="true">
+        <property name="documenter">
+            <bean class="org.apache.geronimo.gshell.wisdom.command.MessageSourceCommandDocumenter"/>
+        </property>
+
+        <property name="messages">
+            <bean class="org.apache.geronimo.gshell.wisdom.command.CommandMessageSource"/>
+        </property>
+    </bean>
+
+</beans>
\ No newline at end of file
diff --git a/karaf/gshell/gshell-core/src/main/resources/org/apache/servicemix/kernel/gshell/core/commands/InfoAction.properties b/karaf/gshell/gshell-core/src/main/resources/org/apache/servicemix/kernel/gshell/core/commands/InfoAction.properties
new file mode 100644
index 0000000..755f0c8
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/resources/org/apache/servicemix/kernel/gshell/core/commands/InfoAction.properties
@@ -0,0 +1,27 @@
+##
+## 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.
+##
+
+##
+## $Rev: 703511 $ $Date: 2008-10-10 18:07:36 +0200 (Fri, 10 Oct 2008) $
+##
+
+command.description=Display JVM informations about the current application.
+
+command.manual=\
+  TODO: about manual
\ No newline at end of file
diff --git a/karaf/gshell/gshell-core/src/main/resources/org/apache/servicemix/kernel/gshell/core/servicemix-gshell.xsd b/karaf/gshell/gshell-core/src/main/resources/org/apache/servicemix/kernel/gshell/core/servicemix-gshell.xsd
new file mode 100644
index 0000000..36a1e1d
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/main/resources/org/apache/servicemix/kernel/gshell/core/servicemix-gshell.xsd
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+
+<!-- $Rev: 699828 $ $Date: 2008-09-28 16:35:27 +0200 (Sun, 28 Sep 2008) $ -->
+
+<xsd:schema xmlns="http://servicemix.apache.org/schema/servicemix-gshell"
+        xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+        xmlns:beans="http://www.springframework.org/schema/beans"
+        targetNamespace="http://servicemix.apache.org/schema/servicemix-gshell"
+        elementFormDefault="qualified"
+        attributeFormDefault="unqualified">
+
+    <xsd:import namespace="http://www.springframework.org/schema/beans"/>
+
+    <xsd:annotation>
+        <xsd:documentation>
+            Defines the configuration elements for Apache ServiceMix Kernel commands support.
+        </xsd:documentation>
+    </xsd:annotation>
+
+    <xsd:element name="command-bundle">
+        <xsd:complexType>
+            <xsd:annotation>
+                <xsd:documentation>
+                    Defines a command bundle.
+                </xsd:documentation>
+            </xsd:annotation>
+            <xsd:sequence>
+                <xsd:element ref="beans:description" minOccurs="0" maxOccurs="1"/>
+                <xsd:choice minOccurs="0" maxOccurs="unbounded">
+					<xsd:element ref="command"/>
+					<xsd:element ref="alias"/>
+                    <xsd:element ref="link"/>
+				</xsd:choice>
+            </xsd:sequence>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:element name="command">
+        <xsd:complexType>
+            <xsd:annotation>
+                <xsd:documentation>
+                    Defines a command.
+                </xsd:documentation>
+            </xsd:annotation>
+            <xsd:sequence>
+                <xsd:element ref="beans:description" minOccurs="0" maxOccurs="1"/>
+                <!--
+                NOTE: Not using an xsd:choice here, as I can't seem to figure out how to get it to properly
+                      validate the min/max of the containted elements.  W/o the xsd:choice the validation
+                      works, though have to define elements in order :-(
+                -->
+                <xsd:element ref="action" minOccurs="1" maxOccurs="1"/>
+                <xsd:element ref="documenter" minOccurs="0" maxOccurs="1"/>
+                <xsd:choice minOccurs="0" maxOccurs="1">
+                    <xsd:element ref="completer"/>
+                    <xsd:element ref="completers"/>
+                </xsd:choice>
+                <xsd:element ref="message-source" minOccurs="0" maxOccurs="1"/>
+            </xsd:sequence>
+            <xsd:attribute name="name" type="xsd:string" use="required"/>
+            <xsd:attribute name="type" use="optional" default="stateful">
+                <xsd:annotation>
+                    <xsd:documentation>
+                        The command type.
+                    </xsd:documentation>
+                </xsd:annotation>
+                <xsd:simpleType>
+                    <xsd:restriction base="xsd:string">
+                        <xsd:enumeration value="stateless"/>
+                        <xsd:enumeration value="stateful"/>
+                    </xsd:restriction>
+                </xsd:simpleType>
+            </xsd:attribute>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:element name="link">
+        <xsd:complexType>
+            <xsd:annotation>
+                <xsd:documentation>
+                    Defines a link command.
+                </xsd:documentation>
+            </xsd:annotation>
+            <xsd:sequence>
+                <xsd:element ref="beans:description" minOccurs="0" maxOccurs="1"/>
+            </xsd:sequence>
+            <xsd:attribute name="name" type="xsd:string" use="required"/>
+            <xsd:attribute name="target" type="xsd:string" use="required"/>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:group name="commandComponentElements">
+        <xsd:annotation>
+            <xsd:documentation>
+                Defines the valid elements for command components.  This is based on beans:beanElements,
+                stripping off the bits which are not valid in the command component context.
+            </xsd:documentation>
+        </xsd:annotation>
+		<xsd:sequence>
+			<xsd:element ref="beans:description" minOccurs="0"/>
+			<xsd:choice minOccurs="0" maxOccurs="unbounded">
+				<xsd:element ref="beans:meta"/>
+				<xsd:element ref="beans:constructor-arg"/>
+				<xsd:element ref="beans:property"/>
+				<xsd:element ref="beans:qualifier"/>
+				<xsd:element ref="beans:lookup-method"/>
+				<xsd:element ref="beans:replaced-method"/>
+				<!--
+				NOTE: This seems to cause schema validation problems... not really sure why
+				<xsd:any namespace="##other" processContents="strict" minOccurs="0" maxOccurs="unbounded"/>
+				-->
+			</xsd:choice>
+		</xsd:sequence>
+	</xsd:group>
+
+    <xsd:attributeGroup name="commandComponentAttributes">
+        <xsd:annotation>
+            <xsd:documentation>
+                Defines the valid attributes for command components.  This is based on beans:beanAttributes,
+                stripping off the bits which are not valid in the command component context.
+            </xsd:documentation>
+        </xsd:annotation>
+		<xsd:attribute name="class" type="xsd:string"/>
+		<xsd:attribute name="parent" type="xsd:string"/>
+		<xsd:attribute name="autowire" default="default">
+			<xsd:simpleType>
+				<xsd:restriction base="xsd:NMTOKEN">
+					<xsd:enumeration value="default"/>
+					<xsd:enumeration value="no"/>
+					<xsd:enumeration value="byName"/>
+					<xsd:enumeration value="byType"/>
+					<xsd:enumeration value="constructor"/>
+					<xsd:enumeration value="autodetect"/>
+				</xsd:restriction>
+			</xsd:simpleType>
+		</xsd:attribute>
+		<xsd:attribute name="dependency-check" default="default">
+			<xsd:simpleType>
+				<xsd:restriction base="xsd:NMTOKEN">
+					<xsd:enumeration value="default"/>
+					<xsd:enumeration value="none"/>
+					<xsd:enumeration value="simple"/>
+					<xsd:enumeration value="objects"/>
+					<xsd:enumeration value="all"/>
+				</xsd:restriction>
+			</xsd:simpleType>
+		</xsd:attribute>
+		<xsd:attribute name="depends-on" type="xsd:string"/>
+		<xsd:attribute name="autowire-candidate" default="default" type="beans:defaultable-boolean"/>
+		<xsd:attribute name="primary" type="xsd:boolean"/>
+		<xsd:attribute name="init-method" type="xsd:string"/>
+		<xsd:attribute name="destroy-method" type="xsd:string"/>
+		<xsd:attribute name="factory-method" type="xsd:string"/>
+		<xsd:attribute name="factory-bean" type="xsd:string"/>
+		<xsd:anyAttribute namespace="##other" processContents="lax"/>
+	</xsd:attributeGroup>
+
+    <xsd:complexType name="commandComponent" abstract="true">
+        <xsd:annotation>
+            <xsd:documentation>
+                Support for command component elements, which are all basically just beans.
+            </xsd:documentation>
+        </xsd:annotation>
+        <xsd:group ref="commandComponentElements"/>
+        <xsd:attributeGroup ref="commandComponentAttributes"/>
+    </xsd:complexType>
+
+    <xsd:element name="action">
+        <xsd:complexType>
+            <xsd:annotation>
+                <xsd:documentation>
+                    Defines a command action.
+                </xsd:documentation>
+            </xsd:annotation>
+            <xsd:complexContent>
+                <xsd:extension base="commandComponent"/>
+            </xsd:complexContent>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:element name="documenter">
+        <xsd:complexType>
+            <xsd:annotation>
+                <xsd:documentation>
+                    Defines a command documenter.
+                </xsd:documentation>
+            </xsd:annotation>
+            <xsd:complexContent>
+                <xsd:extension base="commandComponent"/>
+            </xsd:complexContent>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:element name="completer">
+        <xsd:complexType>
+            <xsd:annotation>
+                <xsd:documentation>
+                    Defines a command completer.
+                </xsd:documentation>
+            </xsd:annotation>
+            <xsd:complexContent>
+                <xsd:extension base="commandComponent"/>
+            </xsd:complexContent>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:element name="completers">
+        <xsd:complexType>
+            <xsd:annotation>
+                <xsd:documentation>
+                    Defines a configurable command completer with a set of completers.
+                </xsd:documentation>
+            </xsd:annotation>
+            <xsd:sequence>
+                <xsd:choice minOccurs="1" maxOccurs="unbounded">
+                    <xsd:element ref="beans:bean"/>
+                    <xsd:element ref="beans:ref"/>
+                    <xsd:element ref="beans:null"/>
+                </xsd:choice>
+            </xsd:sequence>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:element name="message-source">
+        <xsd:complexType>
+            <xsd:annotation>
+                <xsd:documentation>
+                    Defines a command message source.
+                </xsd:documentation>
+            </xsd:annotation>
+            <xsd:complexContent>
+                <xsd:extension base="commandComponent"/>
+            </xsd:complexContent>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:element name="alias">
+        <xsd:complexType>
+            <xsd:annotation>
+                <xsd:documentation>
+                    Defines a command alias.
+                </xsd:documentation>
+            </xsd:annotation>
+            <xsd:sequence>
+                <xsd:element ref="beans:description" minOccurs="0" maxOccurs="1"/>
+            </xsd:sequence>
+            <xsd:attribute name="name" type="xsd:string" use="required"/>
+            <xsd:attribute name="alias" type="xsd:string" use="required"/>
+        </xsd:complexType>
+    </xsd:element>
+
+</xsd:schema>
\ No newline at end of file
diff --git a/karaf/gshell/gshell-core/src/test/java/org/apache/geronimo/gshell/commands/text/SortTest.java b/karaf/gshell/gshell-core/src/test/java/org/apache/geronimo/gshell/commands/text/SortTest.java
new file mode 100644
index 0000000..90e405e
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/test/java/org/apache/geronimo/gshell/commands/text/SortTest.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.geronimo.gshell.commands.text;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Collections;
+
+import junit.framework.TestCase;
+
+/**
+ * TODO: remove this file when gshell is upgraded
+ */
+public class SortTest extends TestCase {
+
+    public void testFieldIndexesDefaultSep() {
+        SortAction.SortComparator comparator = new SortAction.SortComparator(false, false, false, false, '\0', null);
+        List<Integer> indexes = comparator.getFieldIndexes(" ad  re  t ");
+        assertTrue(Arrays.asList(0, 2, 3, 6, 7, 9, 10, 10).equals(indexes));
+    }
+
+    public void testFieldIndexesWithSep() {
+        SortAction.SortComparator comparator = new SortAction.SortComparator(false, false, false, false, '[', null);
+        List<Integer> indexes = comparator.getFieldIndexes("[  10] [Active     ] [       ] [    8] OPS4J Pax Logging - Service (1.3.0)");
+        assertTrue(Arrays.asList(1, 6, 8, 20, 22, 30, 32, 73 ).equals(indexes));
+
+        indexes = comparator.getFieldIndexes(" ad  re  t ");
+        assertTrue(Arrays.asList(0, 10).equals(indexes));
+    }
+
+    public void testSort() {
+        String s0 = "0321   abcd  ddcba   a";
+        String s1 = " 57t   bcad  ddacb   b";
+        String s2 = "  128  cab   ddbac   c";
+        List<String> strings = Arrays.asList(s0, s1, s2);
+
+        Collections.sort(strings, new SortAction.SortComparator(false, false, false, false, '\0', Arrays.asList("2")));
+        assertTrue(Arrays.asList(s0, s1, s2).equals(strings));
+
+        Collections.sort(strings, new SortAction.SortComparator(false, false, false, false, '\0', Arrays.asList("2.2b")));
+        assertTrue(Arrays.asList(s2, s0, s1).equals(strings));
+
+        Collections.sort(strings, new SortAction.SortComparator(false, false, false, true, '\0', null));
+        assertTrue(Arrays.asList(s1, s2, s0).equals(strings));
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/test/java/org/apache/servicemix/kernel/gshell/core/Test.java b/karaf/gshell/gshell-core/src/test/java/org/apache/servicemix/kernel/gshell/core/Test.java
new file mode 100644
index 0000000..0983b12
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/test/java/org/apache/servicemix/kernel/gshell/core/Test.java
@@ -0,0 +1,154 @@
+/*
+ * 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.servicemix.kernel.gshell.core;
+
+import junit.framework.TestCase;
+import org.apache.geronimo.gshell.application.ApplicationManager;
+import org.apache.geronimo.gshell.shell.Shell;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
+public class Test extends TestCase {
+
+    public void test() throws Exception {
+        System.setProperty("startLocalConsole", "true");
+        System.setProperty("servicemix.name", "root");
+
+        ClassPathXmlApplicationContext context = null;
+        try {
+            context = new ClassPathXmlApplicationContext(
+                    new String[] { "META-INF/spring/gshell.xml",
+                                   "META-INF/spring/gshell-vfs.xml",
+                                   "META-INF/spring/gshell-commands.xml",
+                                   "org/apache/servicemix/kernel/gshell/core/gshell-test.xml" });
+            ApplicationManager appMgr = (ApplicationManager) context.getBean("applicationManager");
+            assertNotNull(appMgr);
+            Shell shell = appMgr.create();
+            assertNotNull(shell);
+            shell.execute("help");
+        } finally {
+            if (context != null) {
+                context.destroy();
+            }
+        }
+    }
+
+    public void testBanner() throws Exception {
+        System.setProperty("startLocalConsole", "true");
+        System.setProperty("servicemix.name", "root");
+
+        ClassPathXmlApplicationContext context = null;
+        try {
+            context = new ClassPathXmlApplicationContext(
+                    new String[] { "META-INF/spring/gshell.xml",
+                                   "META-INF/spring/gshell-vfs.xml",
+                                   "META-INF/spring/gshell-commands.xml",
+                                   "org/apache/servicemix/kernel/gshell/core/gshell-test.xml"});
+            ApplicationManager appMgr = (ApplicationManager) context.getBean("applicationManager");
+            assertNotNull(appMgr);
+            Shell shell = appMgr.create();
+            ServiceMixBranding smxBrandng = (ServiceMixBranding)appMgr.getApplication().getModel().getBranding();
+            assertNotNull(smxBrandng.getWelcomeMessage());
+            System.out.println(smxBrandng.getWelcomeMessage());
+            assertNotNull(shell);
+            shell.execute("about");
+        } finally {
+            if (context != null) {
+                context.destroy();
+            }
+        }
+    }
+
+    public void testLs() throws Exception {
+        System.setProperty("startLocalConsole", "true");
+        System.setProperty("servicemix.name", "root");
+
+        ClassPathXmlApplicationContext context = null;
+        try {
+            context = new ClassPathXmlApplicationContext(
+                    new String[] { "META-INF/spring/gshell.xml",
+                                   "META-INF/spring/gshell-vfs.xml",
+                                   "org/apache/servicemix/kernel/gshell/core/gshell-test-commands.xml",
+                                   "org/apache/servicemix/kernel/gshell/core/gshell-test.xml"});
+            ApplicationManager appMgr = (ApplicationManager) context.getBean("applicationManager");
+            assertNotNull(appMgr);
+            Shell shell = appMgr.create();
+            ServiceMixBranding smxBrandng = (ServiceMixBranding)appMgr.getApplication().getModel().getBranding();
+            assertNotNull(smxBrandng.getWelcomeMessage());
+            System.out.println(smxBrandng.getWelcomeMessage());
+            assertNotNull(shell);
+            shell.execute("vfs/ls meta:/commands/");
+        } finally {
+            if (context != null) {
+                context.destroy();
+            }
+        }
+    }
+
+    public void testCommandGroups() throws Exception {
+        System.setProperty("startLocalConsole", "true");
+        System.setProperty("servicemix.name", "root");
+
+        ClassPathXmlApplicationContext context = null;
+        try {
+            context = new ClassPathXmlApplicationContext(
+                    new String[] { "META-INF/spring/gshell.xml",
+                                   "META-INF/spring/gshell-vfs.xml",
+                                   "org/apache/servicemix/kernel/gshell/core/gshell-test-commands.xml",
+                                   "org/apache/servicemix/kernel/gshell/core/gshell-test.xml"});
+            ApplicationManager appMgr = (ApplicationManager) context.getBean("applicationManager");
+            assertNotNull(appMgr);
+            Shell shell = appMgr.create();
+            ServiceMixBranding smxBrandng = (ServiceMixBranding)appMgr.getApplication().getModel().getBranding();
+            assertNotNull(smxBrandng.getWelcomeMessage());
+            System.out.println(smxBrandng.getWelcomeMessage());
+            assertNotNull(shell);
+
+            shell.execute("vfs");
+            shell.execute("help");
+            shell.execute("..");
+        } finally {
+            if (context != null) {
+                context.destroy();
+            }
+        }
+    }
+
+    public void testFileAccessCommands() throws Exception {
+        System.setProperty("startLocalConsole", "true");
+        System.setProperty("servicemix.name", "root");
+
+        ClassPathXmlApplicationContext context = null;
+        try {
+            context = new ClassPathXmlApplicationContext(
+                    new String[] { "META-INF/spring/gshell.xml",
+                                   "META-INF/spring/gshell-vfs.xml",
+                                   "org/apache/servicemix/kernel/gshell/core/gshell-test-commands.xml",
+                                   "org/apache/servicemix/kernel/gshell/core/gshell-test.xml"});
+            ApplicationManager appMgr = (ApplicationManager) context.getBean("applicationManager");
+            assertNotNull(appMgr);
+            Shell shell = appMgr.create();            
+            assertNotNull(shell);
+            shell.execute("optional/cat src/test/resources/org/apache/servicemix/kernel/gshell/core/gshell-test.xml");
+            shell.execute("optional/find src/test/resources/org/apache/servicemix/kernel/gshell/core/gshell-test.xml");
+        } finally {
+            if (context != null) {
+                context.destroy();
+            }
+        }
+    }
+
+}
diff --git a/karaf/gshell/gshell-core/src/test/resources/log4j.properties b/karaf/gshell/gshell-core/src/test/resources/log4j.properties
new file mode 100644
index 0000000..8cc85f8
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/test/resources/log4j.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.
+#
+################################################################################
+
+# Root logger
+log4j.rootLogger=INFO, stdout
+
+# CONSOLE appender not used by default
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} | %-5.5p | %-16.16t | %-32.32c{1} | %-32.32C %4L | %m%n
+
+# File appender
+log4j.appender.out=org.apache.log4j.FileAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+log4j.appender.out.layout.ConversionPattern=%d{ABSOLUTE} | %-5.5p | %-16.16t | %-32.32c{1} | %-32.32C %4L | %m%n
+log4j.appender.out.file=${servicemix.base}/data/log/servicemix.log
+log4j.appender.out.append=true
diff --git a/karaf/gshell/gshell-core/src/test/resources/org/apache/servicemix/kernel/gshell/core/gshell-test-commands.xml b/karaf/gshell/gshell-core/src/test/resources/org/apache/servicemix/kernel/gshell/core/gshell-test-commands.xml
new file mode 100644
index 0000000..25e4de1
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/test/resources/org/apache/servicemix/kernel/gshell/core/gshell-test-commands.xml
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xmlns:gshell="http://servicemix.apache.org/schema/servicemix-gshell"
+       xsi:schemaLocation="
+  http://www.springframework.org/schema/beans
+  http://www.springframework.org/schema/beans/spring-beans.xsd
+  http://www.springframework.org/schema/util
+  http://www.springframework.org/schema/util/spring-util.xsd
+  http://servicemix.apache.org/schema/servicemix-gshell
+  http://servicemix.apache.org/schema/servicemix-gshell/servicemix-gshell.xsd"
+       default-autowire="no"
+       default-dependency-check="none"
+       default-init-method="init"
+       default-destroy-method="destroy">
+
+    <import resource="classpath:org/apache/servicemix/kernel/gshell/core/commands.xml" />
+
+    <bean id="vfsCommandActionTemplate" abstract="true">
+        <property name="fileSystemAccess" ref="fileSystemAccess"/>
+    </bean>
+
+    <gshell:command-bundle>
+        <gshell:command name="about">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.AboutAction">
+                <constructor-arg ref="application"/>
+            </gshell:action>
+        </gshell:command>
+
+        <gshell:command name="help">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.HelpAction">
+                <constructor-arg ref="commandResolver"/>
+            </gshell:action>
+            <gshell:completers>
+                <bean class="org.apache.geronimo.gshell.console.completer.AggregateCompleter">
+                    <constructor-arg>
+                        <list>
+                            <ref bean="aliasNameCompleter"/>
+                            <ref bean="commandNameCompleter"/>
+                        </list>
+                    </constructor-arg>
+                </bean>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="exit">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.ExitAction"/>
+        </gshell:command>
+
+        <gshell:link name="quit" target="exit"/>
+
+        <gshell:command name="echo">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.EchoAction"/>
+        </gshell:command>
+
+        <gshell:command name="clear" type="stateless">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.ClearAction"/>
+        </gshell:command>
+
+        <gshell:command name="source">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.SourceAction">
+                <constructor-arg ref="commandLineExecutor"/>
+                <constructor-arg ref="fileSystemAccess"/>
+            </gshell:action>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="set">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.SetAction"/>
+        </gshell:command>
+
+        <gshell:command name="unset">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.UnsetAction"/>
+            <gshell:completers>
+                <ref bean="variableNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="alias">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.AliasAction">
+                <constructor-arg ref="aliasRegistry"/>
+            </gshell:action>
+        </gshell:command>
+
+        <gshell:command name="unalias">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.UnaliasAction">
+                <constructor-arg ref="aliasRegistry"/>
+            </gshell:action>
+            <gshell:completers>
+                <ref bean="aliasNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="history">
+            <gshell:action class="org.apache.geronimo.gshell.commands.builtin.HistoryAction"/>
+        </gshell:command>
+
+        <gshell:command name="info">
+            <gshell:action class="org.apache.servicemix.kernel.gshell.core.commands.InfoAction">
+                <constructor-arg ref="branding" />
+            </gshell:action>
+        </gshell:command>
+    </gshell:command-bundle>
+
+    <gshell:command-bundle>
+        <gshell:command name="vfs/ls">
+            <gshell:action class="org.apache.geronimo.gshell.commands.file.ListDirectoryAction" parent="vfsCommandActionTemplate"/>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+   </gshell:command-bundle>
+
+    <gshell:command-bundle>
+        <gshell:command name="optional/cat">
+            <gshell:action class="org.apache.geronimo.gshell.commands.text.CatAction">
+                <property name="fileSystemAccess" ref="fileSystemAccess"/>
+            </gshell:action>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+
+        <gshell:command name="optional/find">
+            <gshell:action class="org.apache.geronimo.gshell.commands.shell.FindAction">
+                <property name="fileSystemAccess" ref="fileSystemAccess"/>
+            </gshell:action>
+            <gshell:completers>
+                <ref bean="fileObjectNameCompleter"/>
+                <null/>
+            </gshell:completers>
+        </gshell:command>
+    </gshell:command-bundle>
+
+</beans>
diff --git a/karaf/gshell/gshell-core/src/test/resources/org/apache/servicemix/kernel/gshell/core/gshell-test.xml b/karaf/gshell/gshell-core/src/test/resources/org/apache/servicemix/kernel/gshell/core/gshell-test.xml
new file mode 100644
index 0000000..127543f
--- /dev/null
+++ b/karaf/gshell/gshell-core/src/test/resources/org/apache/servicemix/kernel/gshell/core/gshell-test.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    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.
+
+-->
+<beans xmlns="http://www.springframework.org/schema/beans"
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+       xmlns:util="http://www.springframework.org/schema/util"
+       xmlns:gshell="http://servicemix.apache.org/schema/servicemix-gshell"
+       xsi:schemaLocation="
+  http://www.springframework.org/schema/beans
+  http://www.springframework.org/schema/beans/spring-beans.xsd
+  http://www.springframework.org/schema/util
+  http://www.springframework.org/schema/util/spring-util.xsd
+  http://servicemix.apache.org/schema/servicemix-gshell
+  http://servicemix.apache.org/schema/servicemix-gshell/servicemix-gshell.xsd">
+
+    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />
+
+</beans>
\ No newline at end of file