diff --git a/shell/src/main/java/org/apache/felix/shell/impl/Activator.java b/shell/src/main/java/org/apache/felix/shell/impl/Activator.java
index 92ff81a..286d995 100644
--- a/shell/src/main/java/org/apache/felix/shell/impl/Activator.java
+++ b/shell/src/main/java/org/apache/felix/shell/impl/Activator.java
@@ -92,11 +92,6 @@
         context.registerService(
             classes, new CdCommandImpl(m_context), null);
 
-        // Register "exports" command service.
-        context.registerService(
-            org.apache.felix.shell.Command.class.getName(),
-            new ExportsCommandImpl(m_context), null);
-
         // Register "find" command service.
         context.registerService(
             org.apache.felix.shell.Command.class.getName(),
@@ -112,10 +107,10 @@
             org.apache.felix.shell.Command.class.getName(),
             new HelpCommandImpl(m_context), null);
 
-        // Register "imports" command service.
+        // Register "inspect" command service.
         context.registerService(
             org.apache.felix.shell.Command.class.getName(),
-            new ImportsCommandImpl(m_context), null);
+            new InspectCommandImpl(m_context), null);
 
         // Register "install" command service.
         context.registerService(
@@ -137,26 +132,11 @@
             org.apache.felix.shell.Command.class.getName(),
             new RefreshCommandImpl(m_context), null);
 
-        // Register "requires" command service.
-        context.registerService(
-            org.apache.felix.shell.Command.class.getName(),
-            new RequiresCommandImpl(m_context), null);
-
-        // Register "requirers" command service.
-        context.registerService(
-            org.apache.felix.shell.Command.class.getName(),
-            new RequirersCommandImpl(m_context), null);
-
         // Register "resolve" command service.
         context.registerService(
             org.apache.felix.shell.Command.class.getName(),
             new ResolveCommandImpl(m_context), null);
 
-        // Register "services" command service.
-        context.registerService(
-            org.apache.felix.shell.Command.class.getName(),
-            new ServicesCommandImpl(m_context), null);
-
         // Register "startlevel" command service.
         context.registerService(
             org.apache.felix.shell.Command.class.getName(),
diff --git a/shell/src/main/java/org/apache/felix/shell/impl/ExportsCommandImpl.java b/shell/src/main/java/org/apache/felix/shell/impl/ExportsCommandImpl.java
deleted file mode 100644
index 9637c6e..0000000
--- a/shell/src/main/java/org/apache/felix/shell/impl/ExportsCommandImpl.java
+++ /dev/null
@@ -1,125 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.shell.impl;
-
-import java.io.PrintStream;
-import java.util.StringTokenizer;
-
-import org.apache.felix.shell.Command;
-import org.osgi.framework.*;
-import org.osgi.service.packageadmin.ExportedPackage;
-import org.osgi.service.packageadmin.PackageAdmin;
-
-public class ExportsCommandImpl implements Command
-{
-    private BundleContext m_context = null;
-
-    public ExportsCommandImpl(BundleContext context)
-    {
-        m_context = context;
-    }
-
-    public String getName()
-    {
-        return "exports";
-    }
-
-    public String getUsage()
-    {
-        return "exports <id> ...";
-    }
-
-    public String getShortDescription()
-    {
-        return "list exported packages.";
-    }
-
-    public void execute(String s, PrintStream out, PrintStream err)
-    {
-        // Get package admin service.
-        ServiceReference ref = m_context.getServiceReference(
-            org.osgi.service.packageadmin.PackageAdmin.class.getName());
-        PackageAdmin pa = (ref == null) ? null : (PackageAdmin) m_context.getService(ref);
-        if (pa == null)
-        {
-            out.println("PackageAdmin service is unavailable.");
-            return;
-        }
-
-        // Parse command line.
-        StringTokenizer st = new StringTokenizer(s, " ");
-
-        // Ignore the command name.
-        st.nextToken();
-
-        if (st.hasMoreTokens())
-        {
-            boolean separatorNeeded = false;
-            while (st.hasMoreTokens())
-            {
-                String id = st.nextToken();
-                try
-                {
-                    long l = Long.parseLong(id);
-                    Bundle bundle = m_context.getBundle(l);
-                    if (bundle != null)
-                    {
-                        ExportedPackage[] exports = pa.getExportedPackages(bundle);
-                        if (separatorNeeded)
-                        {
-                            out.println("");
-                        }
-                        printExports(out, bundle, exports);
-                        separatorNeeded = true;
-                    }
-                    else
-                    {
-                        err.println("Bundle ID " + id + " is invalid.");
-                    }
-                }
-                catch (NumberFormatException ex)
-                {
-                    err.println("Unable to parse id '" + id + "'.");
-                }
-                catch (Exception ex)
-                {
-                    err.println(ex.toString());
-                }
-            }
-        }
-    }
-
-    private void printExports(PrintStream out, Bundle target, ExportedPackage[] exports)
-    {
-        String title = target + " exports:";
-        out.println(title);
-        out.println(Util.getUnderlineString(title));
-        if ((exports != null) && (exports.length > 0))
-        {
-            for (int i = 0; i < exports.length; i++)
-            {
-                out.println(exports[i]);
-            }
-        }
-        else
-        {
-            out.println("Nothing");
-        }
-    }
-}
\ No newline at end of file
diff --git a/shell/src/main/java/org/apache/felix/shell/impl/ImportsCommandImpl.java b/shell/src/main/java/org/apache/felix/shell/impl/ImportsCommandImpl.java
deleted file mode 100644
index 47e4b38..0000000
--- a/shell/src/main/java/org/apache/felix/shell/impl/ImportsCommandImpl.java
+++ /dev/null
@@ -1,152 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.shell.impl;
-
-import java.io.PrintStream;
-import java.util.StringTokenizer;
-
-import org.apache.felix.shell.Command;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.packageadmin.ExportedPackage;
-import org.osgi.service.packageadmin.PackageAdmin;
-
-public class ImportsCommandImpl implements Command
-{
-    private final BundleContext m_context;
-    private ServiceReference m_ref = null;
-
-    public ImportsCommandImpl(BundleContext context)
-    {
-        m_context = context;
-    }
-
-    public String getName()
-    {
-        return "imports";
-    }
-
-    public String getUsage()
-    {
-        return "imports <id> ...";
-    }
-
-    public String getShortDescription()
-    {
-        return "list imported packages.";
-    }
-
-    public void execute(String s, PrintStream out, PrintStream err)
-    {
-        StringTokenizer st = new StringTokenizer(s, " ");
-
-        // Ignore the command name.
-        st.nextToken();
-
-        if (st.hasMoreTokens())
-        {
-            boolean separatorNeeded = false;
-            while (st.hasMoreTokens())
-            {
-                String id = st.nextToken().trim();
-
-                try
-                {
-                    long l = Long.parseLong(id);
-                    Bundle bundle = m_context.getBundle(l);
-                    if (bundle != null)
-                    {
-                        if (separatorNeeded)
-                        {
-                            out.println("");
-                        }
-                        getImportedPackages(bundle, out, err);
-                        separatorNeeded = true;
-                    }
-                    else
-                    {
-                        err.println("Bundle ID " + id + " is invalid.");
-                    }
-                }
-                catch (NumberFormatException ex)
-                {
-                    err.println("Unable to parse id '" + id + "'.");
-                }
-                catch (Exception ex)
-                {
-                    err.println(ex.toString());
-                }
-            }
-        }
-    }
-
-    private void getImportedPackages(Bundle bundle, PrintStream out, PrintStream err)
-    {
-        // Get package admin service.
-        PackageAdmin pa = getPackageAdmin();
-        if (pa == null)
-        {
-            out.println("PackageAdmin service is unavailable.");
-        }
-        else
-        {
-            ExportedPackage[] exports = pa.getExportedPackages((Bundle) null);
-            String title = bundle + " imports:";
-            out.println(title);
-            out.println(Util.getUnderlineString(title));
-            boolean found = false;
-            for (int expIdx = 0; expIdx < exports.length; expIdx++)
-            {
-                Bundle[] importers = exports[expIdx].getImportingBundles();
-                for (int impIdx = 0; (importers != null) && (impIdx < importers.length); impIdx++)
-                {
-                    if (importers[impIdx] == bundle)
-                    {
-                        out.println(exports[expIdx]
-                            + " -> " + exports[expIdx].getExportingBundle());
-                        found = true;
-                    }
-                }
-            }
-            if (!found)
-            {
-                out.println("Nothing");
-            }
-            ungetPackageAdmin();
-        }
-    }
-
-    private PackageAdmin getPackageAdmin()
-    {
-        PackageAdmin pa = null;
-        m_ref = m_context.getServiceReference(
-            org.osgi.service.packageadmin.PackageAdmin.class.getName());
-        if (m_ref != null)
-        {
-            pa = (PackageAdmin) m_context.getService(m_ref);
-        }
-        return pa;
-    }
-
-    private void ungetPackageAdmin()
-    {
-        m_context.ungetService(m_ref);
-    }
-}
\ No newline at end of file
diff --git a/shell/src/main/java/org/apache/felix/shell/impl/InspectCommandImpl.java b/shell/src/main/java/org/apache/felix/shell/impl/InspectCommandImpl.java
new file mode 100644
index 0000000..43d1c0b
--- /dev/null
+++ b/shell/src/main/java/org/apache/felix/shell/impl/InspectCommandImpl.java
@@ -0,0 +1,553 @@
+/* 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.felix.shell.impl;
+
+import java.io.PrintStream;
+import java.util.StringTokenizer;
+
+import org.apache.felix.shell.Command;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.service.packageadmin.ExportedPackage;
+import org.osgi.service.packageadmin.PackageAdmin;
+import org.osgi.service.packageadmin.RequiredBundle;
+
+public class InspectCommandImpl implements Command
+{
+    public static final String PACKAGE_TYPE = "package";
+    public static final String BUNDLE_TYPE = "bundle";
+    public static final String FRAGMENT_TYPE = "fragment";
+    public static final String SERVICE_TYPE = "service";
+
+    public static final String PROVIDE_DIRECTION = "provide";
+    public static final String REQUIRE_DIRECTION = "require";
+
+    private final BundleContext m_context;
+    private ServiceReference m_ref = null;
+
+    public InspectCommandImpl(BundleContext context)
+    {
+        m_context = context;
+    }
+
+    public String getName()
+    {
+        return "inspect";
+    }
+
+    public String getUsage()
+    {
+        return "inspect (package|bundle|fragment|service) (require|provide) <id> ...";
+    }
+
+    public String getShortDescription()
+    {
+        return "inspects dependency information.";
+    }
+
+    public void execute(String s, PrintStream out, PrintStream err)
+    {
+        StringTokenizer st = new StringTokenizer(s, " ");
+
+        // Ignore the command name.
+        st.nextToken();
+
+        if (st.countTokens() < 3)
+        {
+            out.println("Too few arguments.");
+            out.println(getUsage());
+        }
+        else
+        {
+            // Get dependency type.
+            String type = st.nextToken();
+            // Get dependency direction.
+            String direction = st.nextToken();
+            // Get target bundle identifiers.
+            String[] ids = new String[st.countTokens()];
+            for (int i = 0; st.hasMoreTokens(); i++)
+            {
+                ids[i] = st.nextToken().trim();
+            }
+            // Verify arguments.
+            if (validTypeAndDirection(type, direction))
+            {
+                // Now determine what needs to be printed.
+                if (PACKAGE_TYPE.startsWith(type))
+                {
+                    if (PROVIDE_DIRECTION.startsWith(direction))
+                    {
+                        printExportedPackages(ids, out, err);
+                    }
+                    else
+                    {
+                        printImportedPackages(ids, out, err);
+                    }
+                }
+                else if (BUNDLE_TYPE.startsWith(type))
+                {
+                    if (PROVIDE_DIRECTION.startsWith(direction))
+                    {
+                        printRequiringBundles(ids, out, err);
+                    }
+                    else
+                    {
+                        printRequiredBundles(ids, out, err);
+                    }
+                }
+                else if (FRAGMENT_TYPE.startsWith(type))
+                {
+                    if (PROVIDE_DIRECTION.startsWith(direction))
+                    {
+                        out.println("Not yet implemented.");
+                    }
+                    else
+                    {
+                        out.println("Not yet implemented.");
+                    }
+                }
+                else
+                {
+                    if (PROVIDE_DIRECTION.startsWith(direction))
+                    {
+                        printExportedServices(ids, out, err);
+                    }
+                    else
+                    {
+                        printImportedServices(ids, out, err);
+                    }
+                }
+            }
+            else
+            {
+                out.println("Invalid arguments.");
+            }
+        }
+    }
+
+    private void printExportedPackages(String[] ids, PrintStream out, PrintStream err)
+    {
+        PackageAdmin pa = getPackageAdmin();
+        if (pa == null)
+        {
+            out.println("PackageAdmin service is unavailable.");
+        }
+        else
+        {
+            boolean separatorNeeded = false;
+            for (int idIdx = 0; idIdx < ids.length; idIdx++)
+            {
+                try
+                {
+                    long l = Long.parseLong(ids[idIdx]);
+                    Bundle bundle = m_context.getBundle(l);
+                    if (bundle != null)
+                    {
+                        ExportedPackage[] exports = pa.getExportedPackages(bundle);
+                        if (separatorNeeded)
+                        {
+                            out.println("");
+                        }
+                        String title = bundle + " provides packages:";
+                        out.println(title);
+                        out.println(Util.getUnderlineString(title));
+                        if ((exports != null) && (exports.length > 0))
+                        {
+                            for (int expIdx = 0; expIdx < exports.length; expIdx++)
+                            {
+                                out.println(exports[expIdx]);
+                            }
+                        }
+                        else
+                        {
+                            out.println("Nothing");
+                        }
+                        separatorNeeded = true;
+                    }
+                    else
+                    {
+                        err.println("Bundle ID " + ids[idIdx] + " is invalid.");
+                    }
+                }
+                catch (NumberFormatException ex)
+                {
+                    err.println("Unable to parse id '" + ids[idIdx] + "'.");
+                }
+                catch (Exception ex)
+                {
+                    err.println(ex.toString());
+                }
+            }
+        }
+        ungetPackageAdmin();
+    }
+
+    private void printImportedPackages(String[] ids, PrintStream out, PrintStream err)
+    {
+        boolean separatorNeeded = false;
+        for (int idIdx = 0; idIdx < ids.length; idIdx++)
+        {
+            try
+            {
+                long l = Long.parseLong(ids[idIdx]);
+                Bundle bundle = m_context.getBundle(l);
+                if (bundle != null)
+                {
+                    if (separatorNeeded)
+                    {
+                        out.println("");
+                    }
+                    _printImportedPackages(bundle, out, err);
+                    separatorNeeded = true;
+                }
+                else
+                {
+                    err.println("Bundle ID " + ids[idIdx] + " is invalid.");
+                }
+            }
+            catch (NumberFormatException ex)
+            {
+                err.println("Unable to parse id '" + ids[idIdx] + "'.");
+            }
+            catch (Exception ex)
+            {
+                err.println(ex.toString());
+            }
+        }
+    }
+
+    private void _printImportedPackages(Bundle bundle, PrintStream out, PrintStream err)
+    {
+        // Get package admin service.
+        PackageAdmin pa = getPackageAdmin();
+        if (pa == null)
+        {
+            out.println("PackageAdmin service is unavailable.");
+        }
+        else
+        {
+            ExportedPackage[] exports = pa.getExportedPackages((Bundle) null);
+            String title = bundle + " requires packages:";
+            out.println(title);
+            out.println(Util.getUnderlineString(title));
+            boolean found = false;
+            for (int expIdx = 0; expIdx < exports.length; expIdx++)
+            {
+                Bundle[] importers = exports[expIdx].getImportingBundles();
+                for (int impIdx = 0; (importers != null) && (impIdx < importers.length); impIdx++)
+                {
+                    if (importers[impIdx] == bundle)
+                    {
+                        out.println(exports[expIdx]
+                            + " -> " + exports[expIdx].getExportingBundle());
+                        found = true;
+                    }
+                }
+            }
+            if (!found)
+            {
+                out.println("Nothing");
+            }
+            ungetPackageAdmin();
+        }
+    }
+
+    private void printRequiringBundles(String[] ids, PrintStream out, PrintStream err)
+    {
+        PackageAdmin pa = getPackageAdmin();
+        if (pa == null)
+        {
+            out.println("PackageAdmin service is unavailable.");
+        }
+        else
+        {
+            boolean separatorNeeded = false;
+            for (int idIdx = 0; idIdx < ids.length; idIdx++)
+            {
+                try
+                {
+                    long l = Long.parseLong(ids[idIdx]);
+                    Bundle bundle = m_context.getBundle(l);
+                    if (bundle != null)
+                    {
+                        RequiredBundle[] rbs = pa.getRequiredBundles(bundle.getSymbolicName());
+                        for (int rbIdx = 0; (rbs != null) && (rbIdx < rbs.length); rbIdx++)
+                        {
+                            if (rbs[rbIdx].getBundle() == bundle)
+                            {
+                                if (separatorNeeded)
+                                {
+                                    out.println("");
+                                }
+                                String title = bundle + " required by bundles:";
+                                out.println(title);
+                                out.println(Util.getUnderlineString(title));
+                                if ((rbs[rbIdx].getRequiringBundles() != null)
+                                    && (rbs[rbIdx].getRequiringBundles().length > 0))
+                                {
+                                    for (int reqIdx = 0;
+                                        reqIdx < rbs[rbIdx].getRequiringBundles().length;
+                                        reqIdx++)
+                                    {
+                                        out.println(rbs[rbIdx].getRequiringBundles()[reqIdx]);
+                                    }
+                                }
+                                else
+                                {
+                                    out.println("Nothing");
+                                }
+                                separatorNeeded = true;
+                            }
+                        }
+                    }
+                    else
+                    {
+                        err.println("Bundle ID " + ids[idIdx] + " is invalid.");
+                    }
+                }
+                catch (NumberFormatException ex)
+                {
+                    err.println("Unable to parse id '" + ids[idIdx] + "'.");
+                }
+                catch (Exception ex)
+                {
+                    err.println(ex.toString());
+                }
+            }
+        }
+    }
+
+    private void printRequiredBundles(String[] ids, PrintStream out, PrintStream err)
+    {
+        boolean separatorNeeded = false;
+        for (int idIdx = 0; idIdx < ids.length; idIdx++)
+        {
+            try
+            {
+                long l = Long.parseLong(ids[idIdx]);
+                Bundle bundle = m_context.getBundle(l);
+                if (bundle != null)
+                {
+                    if (separatorNeeded)
+                    {
+                        out.println("");
+                    }
+                    _printRequiredBundles(bundle, out, err);
+                    separatorNeeded = true;
+                }
+                else
+                {
+                    err.println("Bundle ID " + ids[idIdx] + " is invalid.");
+                }
+            }
+            catch (NumberFormatException ex)
+            {
+                err.println("Unable to parse id '" + ids[idIdx] + "'.");
+            }
+            catch (Exception ex)
+            {
+                err.println(ex.toString());
+            }
+        }
+    }
+
+    private void _printRequiredBundles(Bundle bundle, PrintStream out, PrintStream err)
+    {
+        // Get package admin service.
+        PackageAdmin pa = getPackageAdmin();
+        if (pa == null)
+        {
+            out.println("PackageAdmin service is unavailable.");
+        }
+        else
+        {
+            RequiredBundle[] rbs = pa.getRequiredBundles(null);
+            String title = bundle + " requires bundles:";
+            out.println(title);
+            out.println(Util.getUnderlineString(title));
+            boolean found = false;
+            for (int rbIdx = 0; rbIdx < rbs.length; rbIdx++)
+            {
+                Bundle[] requirers = rbs[rbIdx].getRequiringBundles();
+                for (int reqIdx = 0; (requirers != null) && (reqIdx < requirers.length); reqIdx++)
+                {
+                    if (requirers[reqIdx] == bundle)
+                    {
+                        out.println(rbs[reqIdx]);
+                        found = true;
+                    }
+                }
+            }
+            if (!found)
+            {
+                out.println("Nothing");
+            }
+            ungetPackageAdmin();
+        }
+    }
+
+    public void printExportedServices(String[] ids, PrintStream out, PrintStream err)
+    {
+        for (int i = 0; i < ids.length; i++)
+        {
+            try
+            {
+                long l = Long.parseLong(ids[i]);
+                Bundle bundle = m_context.getBundle(l);
+                if (bundle != null)
+                {
+                    ServiceReference[] refs = bundle.getRegisteredServices();
+
+                    // Print header if we have not already done so.
+                    String title = Util.getBundleName(bundle) + " provides services:";
+                    out.println(title);
+                    out.println(Util.getUnderlineString(title));
+
+                    if ((refs == null) || (refs.length == 0))
+                    {
+                        out.println("Nothing");
+                    }
+
+                    // Print properties for each service.
+                    for (int refIdx = 0;
+                        (refs != null) && (refIdx < refs.length);
+                        refIdx++)
+                    {
+                        // Print service properties.
+                        String[] keys = refs[refIdx].getPropertyKeys();
+                        for (int keyIdx = 0;
+                            (keys != null) && (keyIdx < keys.length);
+                            keyIdx++)
+                        {
+                            Object v = refs[refIdx].getProperty(keys[keyIdx]);
+                            out.println(
+                                keys[keyIdx] + " = " + Util.getValueString(v));
+                        }
+
+                        // Print service separator if necessary.
+                        if ((refIdx + 1) < refs.length)
+                        {
+                            out.println("----");
+                        }
+                    }
+                }
+                else
+                {
+                    err.println("Bundle ID " + ids[i] + " is invalid.");
+                }
+            }
+            catch (NumberFormatException ex)
+            {
+                err.println("Unable to parse id '" + ids[i] + "'.");
+            }
+            catch (Exception ex)
+            {
+                err.println(ex.toString());
+            }
+        }
+    }
+
+    public void printImportedServices(String[] ids, PrintStream out, PrintStream err)
+    {
+        for (int i = 0; i < ids.length; i++)
+        {
+            try
+            {
+                long l = Long.parseLong(ids[i]);
+                Bundle bundle = m_context.getBundle(l);
+                if (bundle != null)
+                {
+                    ServiceReference[] refs = bundle.getServicesInUse();
+
+                    // Print header if we have not already done so.
+                    String title = Util.getBundleName(bundle) + " requires services:";
+                    out.println(title);
+                    out.println(Util.getUnderlineString(title));
+
+                    if ((refs == null) || (refs.length == 0))
+                    {
+                        out.println("Nothing");
+                    }
+
+                    // Print properties for each service.
+                    for (int refIdx = 0;
+                        (refs != null) && (refIdx < refs.length);
+                        refIdx++)
+                    {
+                        // Print service properties.
+                        String[] keys = refs[refIdx].getPropertyKeys();
+                        for (int keyIdx = 0;
+                            (keys != null) && (keyIdx < keys.length);
+                            keyIdx++)
+                        {
+                            Object v = refs[refIdx].getProperty(keys[keyIdx]);
+                            out.println(
+                                keys[keyIdx] + " = " + Util.getValueString(v));
+                        }
+
+                        // Print service separator if necessary.
+                        if ((refIdx + 1) < refs.length)
+                        {
+                            out.println("----");
+                        }
+                    }
+                }
+                else
+                {
+                    err.println("Bundle ID " + ids[i] + " is invalid.");
+                }
+            }
+            catch (NumberFormatException ex)
+            {
+                err.println("Unable to parse id '" + ids[i] + "'.");
+            }
+            catch (Exception ex)
+            {
+                err.println(ex.toString());
+            }
+        }
+    }
+
+    private PackageAdmin getPackageAdmin()
+    {
+        PackageAdmin pa = null;
+        m_ref = m_context.getServiceReference(
+            org.osgi.service.packageadmin.PackageAdmin.class.getName());
+        if (m_ref != null)
+        {
+            pa = (PackageAdmin) m_context.getService(m_ref);
+        }
+        return pa;
+    }
+
+    private void ungetPackageAdmin()
+    {
+        m_context.ungetService(m_ref);
+    }
+
+    private boolean validTypeAndDirection(String type, String direction)
+    {
+        return
+            (((PACKAGE_TYPE.startsWith(type) || BUNDLE_TYPE.startsWith(type)
+                || FRAGMENT_TYPE.startsWith(type) || SERVICE_TYPE.startsWith(type)))
+            && (PROVIDE_DIRECTION.startsWith(direction)
+                || REQUIRE_DIRECTION.startsWith(direction)));
+    }
+}
\ No newline at end of file
diff --git a/shell/src/main/java/org/apache/felix/shell/impl/RequirersCommandImpl.java b/shell/src/main/java/org/apache/felix/shell/impl/RequirersCommandImpl.java
deleted file mode 100644
index d21a404..0000000
--- a/shell/src/main/java/org/apache/felix/shell/impl/RequirersCommandImpl.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.shell.impl;
-
-import java.io.PrintStream;
-import java.util.StringTokenizer;
-
-import org.apache.felix.shell.Command;
-import org.osgi.framework.*;
-import org.osgi.service.packageadmin.PackageAdmin;
-import org.osgi.service.packageadmin.RequiredBundle;
-
-public class RequirersCommandImpl implements Command
-{
-    private BundleContext m_context = null;
-
-    public RequirersCommandImpl(BundleContext context)
-    {
-        m_context = context;
-    }
-
-    public String getName()
-    {
-        return "requirers";
-    }
-
-    public String getUsage()
-    {
-        return "requirers <id> ...";
-    }
-
-    public String getShortDescription()
-    {
-        return "list requiring bundles.";
-    }
-
-    public void execute(String s, PrintStream out, PrintStream err)
-    {
-        // Get package admin service.
-        ServiceReference ref = m_context.getServiceReference(
-            org.osgi.service.packageadmin.PackageAdmin.class.getName());
-        PackageAdmin pa = (ref == null) ? null : (PackageAdmin) m_context.getService(ref);
-        if (pa == null)
-        {
-            out.println("PackageAdmin service is unavailable.");
-            return;
-        }
-
-        // Parse command line.
-        StringTokenizer st = new StringTokenizer(s, " ");
-
-        // Ignore the command name.
-        st.nextToken();
-
-        if (st.hasMoreTokens())
-        {
-            boolean separatorNeeded = false;
-            while (st.hasMoreTokens())
-            {
-                String id = st.nextToken();
-                try
-                {
-                    long l = Long.parseLong(id);
-                    Bundle bundle = m_context.getBundle(l);
-                    if (bundle != null)
-                    {
-                        RequiredBundle[] rbs = pa.getRequiredBundles(bundle.getSymbolicName());
-                        for (int i = 0; (rbs != null) && (i < rbs.length); i++)
-                        {
-                            if (rbs[i].getBundle() == bundle)
-                            {
-                                if (separatorNeeded)
-                                {
-                                    out.println("");
-                                }
-                                printRequiredBundles(out, bundle, rbs[i].getRequiringBundles());
-                                separatorNeeded = true;
-                            }
-                        }
-                    }
-                    else
-                    {
-                        err.println("Bundle ID " + id + " is invalid.");
-                    }
-                }
-                catch (NumberFormatException ex)
-                {
-                    err.println("Unable to parse id '" + id + "'.");
-                }
-                catch (Exception ex)
-                {
-                    err.println(ex.toString());
-                }
-            }
-        }
-    }
-
-    private void printRequiredBundles(PrintStream out, Bundle target, Bundle[] requirers)
-    {
-        String title = target + " required by:";
-        out.println(title);
-        out.println(Util.getUnderlineString(title));
-        if ((requirers != null) && (requirers.length > 0))
-        {
-            for (int i = 0; i < requirers.length; i++)
-            {
-                out.println(requirers[i]);
-            }
-        }
-        else
-        {
-            out.println("Nothing");
-        }
-    }
-}
\ No newline at end of file
diff --git a/shell/src/main/java/org/apache/felix/shell/impl/RequiresCommandImpl.java b/shell/src/main/java/org/apache/felix/shell/impl/RequiresCommandImpl.java
deleted file mode 100644
index c5b3c57..0000000
--- a/shell/src/main/java/org/apache/felix/shell/impl/RequiresCommandImpl.java
+++ /dev/null
@@ -1,151 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.shell.impl;
-
-import java.io.PrintStream;
-import java.util.StringTokenizer;
-
-import org.apache.felix.shell.Command;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.service.packageadmin.PackageAdmin;
-import org.osgi.service.packageadmin.RequiredBundle;
-
-public class RequiresCommandImpl implements Command
-{
-    private final BundleContext m_context;
-    private ServiceReference m_ref = null;
-
-    public RequiresCommandImpl(BundleContext context)
-    {
-        m_context = context;
-    }
-
-    public String getName()
-    {
-        return "requires";
-    }
-
-    public String getUsage()
-    {
-        return "requires <id> ...";
-    }
-
-    public String getShortDescription()
-    {
-        return "list required bundles.";
-    }
-
-    public void execute(String s, PrintStream out, PrintStream err)
-    {
-        StringTokenizer st = new StringTokenizer(s, " ");
-
-        // Ignore the command name.
-        st.nextToken();
-
-        if (st.hasMoreTokens())
-        {
-            boolean separatorNeeded = false;
-            while (st.hasMoreTokens())
-            {
-                String id = st.nextToken().trim();
-
-                try
-                {
-                    long l = Long.parseLong(id);
-                    Bundle bundle = m_context.getBundle(l);
-                    if (bundle != null)
-                    {
-                        if (separatorNeeded)
-                        {
-                            out.println("");
-                        }
-                        getImportedPackages(bundle, out, err);
-                        separatorNeeded = true;
-                    }
-                    else
-                    {
-                        err.println("Bundle ID " + id + " is invalid.");
-                    }
-                }
-                catch (NumberFormatException ex)
-                {
-                    err.println("Unable to parse id '" + id + "'.");
-                }
-                catch (Exception ex)
-                {
-                    err.println(ex.toString());
-                }
-            }
-        }
-    }
-
-    private void getImportedPackages(Bundle bundle, PrintStream out, PrintStream err)
-    {
-        // Get package admin service.
-        PackageAdmin pa = getPackageAdmin();
-        if (pa == null)
-        {
-            out.println("PackageAdmin service is unavailable.");
-        }
-        else
-        {
-            RequiredBundle[] rbs = pa.getRequiredBundles(null);
-            String title = bundle + " requires:";
-            out.println(title);
-            out.println(Util.getUnderlineString(title));
-            boolean found = false;
-            for (int rbIdx = 0; rbIdx < rbs.length; rbIdx++)
-            {
-                Bundle[] requirers = rbs[rbIdx].getRequiringBundles();
-                for (int reqIdx = 0; (requirers != null) && (reqIdx < requirers.length); reqIdx++)
-                {
-                    if (requirers[reqIdx] == bundle)
-                    {
-                        out.println(rbs[reqIdx]);
-                        found = true;
-                    }
-                }
-            }
-            if (!found)
-            {
-                out.println("Nothing");
-            }
-            ungetPackageAdmin();
-        }
-    }
-
-    private PackageAdmin getPackageAdmin()
-    {
-        PackageAdmin pa = null;
-        m_ref = m_context.getServiceReference(
-            org.osgi.service.packageadmin.PackageAdmin.class.getName());
-        if (m_ref != null)
-        {
-            pa = (PackageAdmin) m_context.getService(m_ref);
-        }
-        return pa;
-    }
-
-    private void ungetPackageAdmin()
-    {
-        m_context.ungetService(m_ref);
-    }
-}
\ No newline at end of file
diff --git a/shell/src/main/java/org/apache/felix/shell/impl/ServicesCommandImpl.java b/shell/src/main/java/org/apache/felix/shell/impl/ServicesCommandImpl.java
deleted file mode 100644
index 47ffe72..0000000
--- a/shell/src/main/java/org/apache/felix/shell/impl/ServicesCommandImpl.java
+++ /dev/null
@@ -1,255 +0,0 @@
-/* 
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.felix.shell.impl;
-
-import java.io.PrintStream;
-import java.util.*;
-
-import org.apache.felix.shell.Command;
-import org.osgi.framework.*;
-
-public class ServicesCommandImpl implements Command
-{
-    private static final String IN_USE_SWITCH = "-u";
-    private static final String SHOW_ALL_SWITCH = "-a";
-
-    private BundleContext m_context = null;
-
-    public ServicesCommandImpl(BundleContext context)
-    {
-        m_context = context;
-    }
-
-    public String getName()
-    {
-        return "services";
-    }
-
-    public String getUsage()
-    {
-        return "services [-u] [-a] [<id> ...]";
-    }
-
-    public String getShortDescription()
-    {
-        return "list registered or used services.";
-    }
-
-    public void execute(String s, PrintStream out, PrintStream err)
-    {
-        StringTokenizer st = new StringTokenizer(s, " ");
-
-        // Ignore the command name.
-        st.nextToken();
-
-        // Put the remaining tokens into a list.
-        List tokens = new ArrayList();
-        for (int i = 0; st.hasMoreTokens(); i++)
-        {
-            tokens.add(st.nextToken());
-        }
-
-        // Default switch values.
-        boolean inUse = false;
-        boolean showAll = false;
-
-        // Check for "in use" switch.
-        if (tokens.contains(IN_USE_SWITCH))
-        {
-            // Remove the switch and set boolean flag.
-            tokens.remove(IN_USE_SWITCH);
-            inUse = true;
-        }
-
-        // Check for "show all" switch.
-        if (tokens.contains(SHOW_ALL_SWITCH))
-        {
-            // Remove the switch and set boolean flag.
-            tokens.remove(SHOW_ALL_SWITCH);
-            showAll = true;
-        }
-
-        // If there are bundle IDs specified then print their
-        // services and associated service properties, otherwise
-        // list all bundles and services.
-        if (tokens.size() >= 1)
-        {
-            while (tokens.size() > 0)
-            {
-                String id = (String) tokens.remove(0);
-
-                boolean headerPrinted = false;
-                boolean needSeparator = false;
-
-                try
-                {
-                    long l = Long.parseLong(id);
-                    Bundle bundle = m_context.getBundle(l);
-                    if (bundle != null)
-                    {
-                        ServiceReference[] refs = null;
-                        
-                        // Get registered or in-use services.
-                        if (inUse)
-                        {
-                            refs = bundle.getServicesInUse();
-                        }
-                        else
-                        {
-                            refs = bundle.getRegisteredServices();
-                        }
-
-                        // Print properties for each service.
-                        for (int refIdx = 0;
-                            (refs != null) && (refIdx < refs.length);
-                            refIdx++)
-                        {
-                            String[] objectClass = (String[])
-                                refs[refIdx].getProperty("objectClass");
-
-                            // Determine if we need to print the service, depending
-                            // on whether it is a command service or not.
-                            boolean print = true;
-                            for (int ocIdx = 0;
-                                !showAll && (ocIdx < objectClass.length);
-                                ocIdx++)
-                            {
-                                if (objectClass[ocIdx].equals(
-                                    org.apache.felix.shell.Command.class.getName()))
-                                {
-                                    print = false;
-                                }
-                            }
-
-                            // Print header if we have not already done so.
-                            if (!headerPrinted)
-                            {
-                                headerPrinted = true;
-                                String title = Util.getBundleName(bundle);
-                                title = (inUse)
-                                    ? title + " uses:"
-                                    : title + " provides:";
-                                out.println("");
-                                out.println(title);
-                                out.println(Util.getUnderlineString(title));
-                            }
-
-                            if (showAll || print)
-                            {
-                                // Print service separator if necessary.
-                                if (needSeparator)
-                                {
-                                    out.println("----");
-                                }
-
-                                // Print service properties.
-                                String[] keys = refs[refIdx].getPropertyKeys();
-                                for (int keyIdx = 0;
-                                    (keys != null) && (keyIdx < keys.length);
-                                    keyIdx++)
-                                {
-                                    Object v = refs[refIdx].getProperty(keys[keyIdx]);
-                                    out.println(
-                                        keys[keyIdx] + " = " + Util.getValueString(v));
-                                }
-                                
-                                needSeparator = true;
-                            }
-                        }
-                    }
-                    else
-                    {
-                        err.println("Bundle ID " + id + " is invalid.");
-                    }
-                }
-                catch (NumberFormatException ex)
-                {
-                    err.println("Unable to parse id '" + id + "'.");
-                }
-                catch (Exception ex)
-                {
-                    err.println(ex.toString());
-                }
-            }
-        }
-        else
-        {
-            Bundle[] bundles = m_context.getBundles();
-            if (bundles != null)
-            {
-                // TODO: Sort list.
-                for (int bundleIdx = 0; bundleIdx < bundles.length; bundleIdx++)
-                {
-                    boolean headerPrinted = false;
-                    ServiceReference[] refs = null;
-
-                    // Get registered or in-use services.
-                    if (inUse)
-                    {
-                        refs = bundles[bundleIdx].getServicesInUse();
-                    }
-                    else
-                    {
-                        refs = bundles[bundleIdx].getRegisteredServices();
-                    }
-
-                    for (int refIdx = 0; (refs != null) && (refIdx < refs.length); refIdx++)
-                    { 
-                        String[] objectClass = (String[])
-                            refs[refIdx].getProperty("objectClass");
-
-                        // Determine if we need to print the service, depending
-                        // on whether it is a command service or not.
-                        boolean print = true;
-                        for (int ocIdx = 0;
-                            !showAll && (ocIdx < objectClass.length);
-                            ocIdx++)
-                        {
-                            if (objectClass[ocIdx].equals(
-                                org.apache.felix.shell.Command.class.getName()))
-                            {
-                                print = false;
-                            }
-                        }
-
-                        // Print the service if necessary.
-                        if (showAll || print)
-                        {
-                            if (!headerPrinted)
-                            {
-                                headerPrinted = true;
-                                String title = Util.getBundleName(bundles[bundleIdx]);
-                                title = (inUse)
-                                    ? title + " uses:"
-                                    : title + " provides:";
-                                out.println("\n" + title);
-                                out.println(Util.getUnderlineString(title));
-                            }
-                            out.println(Util.getValueString(objectClass));
-                        }
-                    }
-                }
-            }
-            else
-            {
-                out.println("There are no registered services.");
-            }
-        }
-    }
-}
