diff --git a/org.apache.felix.shell.gui.plugin/pom.xml b/org.apache.felix.shell.gui.plugin/pom.xml
new file mode 100644
index 0000000..121e833
--- /dev/null
+++ b/org.apache.felix.shell.gui.plugin/pom.xml
@@ -0,0 +1,61 @@
+<project>
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>osgi-bundle</packaging>
+  <name>Apache Felix Shell GUI Plugin</name>
+  <artifactId>org.apache.felix.shell.gui.plugin</artifactId>
+  <dependencies>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.shell</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.bundlerepository</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>${pom.groupId}</groupId>
+      <artifactId>org.apache.felix.shell.gui</artifactId>
+      <version>${pom.version}</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix.plugins</groupId>
+        <artifactId>maven-osgi-plugin</artifactId>
+        <version>${pom.version}</version>
+        <extensions>true</extensions>
+        <configuration>
+          <osgiManifest>
+            <bundleName>ShellGUIPlugin</bundleName>
+            <bundleDescription>A simple set of plugins for the ShellGUI bundle.</bundleDescription>
+            <bundleActivator>org.apache.felix.shell.gui.plugin.Activator</bundleActivator>
+            <bundleDocUrl>http://oscar-osgi.sf.net/obr2/shellguiplugin/</bundleDocUrl>
+            <bundleUrl>http://oscar-osgi.sf.net/obr2/shellguiplugin/org.apache.felix.shell.gui.plugin.jar</bundleUrl>
+            <bundleSource>http://oscar-osgi.sf.net/obr2/shellguiplugin/org.apache.felix.shell.gui.plugin-src.jar</bundleSource>
+            <bundleSymbolicName>org.apache.felix.shell.gui.plugin</bundleSymbolicName>
+            <importPackage>org.osgi.framework,javax.swing,javax.swing.event,javax.swing.table,javax.swing.tree,javax.swing.border,javax.swing.text,org.apache.felix.shell,org.apache.felix.shell.gui,org.osgi.service.obr</importPackage>
+            <exportService>org.apache.felix.shell.gui.Plugin</exportService>
+            <importService>org.apache.felix.shell.ShellService,org.apache.felix.bundlerepository.RepostioryAdmin</importService>
+          </osgiManifest>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git a/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/Activator.java b/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/Activator.java
new file mode 100644
index 0000000..b1fdeb6
--- /dev/null
+++ b/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/Activator.java
@@ -0,0 +1,49 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.shell.gui.plugin;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+public class Activator implements BundleActivator
+{
+    private BundleContext m_context = null;
+
+    public void start(BundleContext context)
+    {
+        m_context = context;
+
+        // Register the bundle list plugin.
+        m_context.registerService(
+            org.apache.felix.shell.gui.Plugin.class.getName(),
+            new BundleListPlugin(m_context), null);
+
+        // Register the shell plugin.
+        m_context.registerService(
+            org.apache.felix.shell.gui.Plugin.class.getName(),
+            new ShellPlugin(m_context), null);
+
+        // Register the OBR plugin.
+        m_context.registerService(
+            org.apache.felix.shell.gui.Plugin.class.getName(),
+            new OBRPlugin(m_context), null);
+    }
+
+    public void stop(BundleContext context)
+    {
+    }
+}
\ No newline at end of file
diff --git a/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/BundleListPlugin.java b/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/BundleListPlugin.java
new file mode 100644
index 0000000..2933861
--- /dev/null
+++ b/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/BundleListPlugin.java
@@ -0,0 +1,342 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.shell.gui.plugin;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.*;
+import javax.swing.table.AbstractTableModel;
+
+import org.apache.felix.shell.gui.Plugin;
+import org.osgi.framework.*;
+import org.osgi.service.packageadmin.PackageAdmin;
+
+public class BundleListPlugin extends JPanel implements Plugin
+{
+    private BundleContext m_context = null;
+    private JTextField m_urlField = null;
+    private JButton m_installButton = null;
+    private JTable m_bundleTable = null;
+    private JButton m_startButton = null;
+    private JButton m_stopButton = null;
+    private JButton m_updateButton = null;
+    private JButton m_refreshButton = null;
+    private JButton m_uninstallButton = null;
+
+    // Plugin interface methods.
+
+    public String getName()
+    {
+        return "Bundle List";    
+    }
+    
+    public Component getGUI()
+    {
+        return this;
+    }
+    
+    // Implementation.
+    
+    public BundleListPlugin(BundleContext context)
+    {
+        m_context = context;
+
+        // Create user interface components.
+        setLayout(new BorderLayout());
+        JScrollPane scroll = null;
+        add(createURLPanel(), BorderLayout.NORTH);
+        add(scroll = new JScrollPane(m_bundleTable = new JTable()), BorderLayout.CENTER);
+        add(createButtonPanel(), BorderLayout.SOUTH);
+
+        // Set table model to display bundles.
+        m_bundleTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
+        m_bundleTable.setModel(new SimpleTableModel());
+        m_bundleTable.getColumnModel().getColumn(0).setPreferredWidth(75);
+        m_bundleTable.getColumnModel().getColumn(1).setPreferredWidth(100);
+        m_bundleTable.getColumnModel().getColumn(2).setPreferredWidth(350);
+
+        createEventListeners();
+    }
+
+    private JPanel createURLPanel()
+    {
+        JPanel panel = new JPanel(new BorderLayout());
+        panel.add(new JLabel("URL"), BorderLayout.WEST);
+        panel.add(m_urlField = new JTextField(20), BorderLayout.CENTER);
+        panel.add(m_installButton = new JButton("Install"), BorderLayout.EAST);
+        m_installButton.setMnemonic('I');
+        return panel;
+    }
+
+    private JPanel createButtonPanel()
+    {
+        JPanel panel = new JPanel();
+        panel.add(m_startButton = new JButton("Start"));
+        panel.add(m_stopButton = new JButton("Stop"));
+        panel.add(m_updateButton = new JButton("Update"));
+        panel.add(m_refreshButton = new JButton("Refresh"));
+        panel.add(m_uninstallButton = new JButton("Uninstall"));
+        m_startButton.setMnemonic('S');
+        m_stopButton.setMnemonic('p');
+        m_updateButton.setMnemonic('a');
+        m_refreshButton.setMnemonic('R');
+        m_uninstallButton.setMnemonic('U');
+        return panel;
+    }
+
+    private void createEventListeners()
+    {
+        // Listen for bundle events in order to update
+        // the GUI bundle list.
+        BundleListener bl = new BundleListener() {
+            public void bundleChanged(BundleEvent event)
+            {
+                ((SimpleTableModel) m_bundleTable.getModel()).update();
+            }
+        };
+        m_context.addBundleListener(bl);
+
+        // Create action listeners.
+        m_installButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event)
+            {
+                if (m_urlField.getText().length() > 0)
+                {
+                    try
+                    {
+                        m_context.installBundle(m_urlField.getText(), null);
+                    }
+                    catch (BundleException ex)
+                    {
+                        JOptionPane.showMessageDialog(
+                            JOptionPane.getFrameForComponent(BundleListPlugin.this),
+                            ex.getMessage(), "Error",
+                            JOptionPane.ERROR_MESSAGE);
+                    }
+                }
+            }
+        });
+
+        m_startButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event)
+            {
+                int[] rows = m_bundleTable.getSelectedRows();
+                for (int i = 0; i < rows.length; i++)
+                {
+                    try
+                    {
+                        m_context.getBundles()[rows[i]].start();
+                    }
+                    catch (BundleException ex)
+                    {
+                        JOptionPane.showMessageDialog(
+                            JOptionPane.getFrameForComponent(BundleListPlugin.this),
+                            ex.getMessage(), "Error",
+                            JOptionPane.ERROR_MESSAGE);
+                    }
+                }
+            }
+        });
+
+        m_stopButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event)
+            {
+                int[] rows = m_bundleTable.getSelectedRows();
+                for (int i = 0; i < rows.length; i++)
+                {
+                    try
+                    {
+                        m_context.getBundles()[rows[i]].stop();
+                    }
+                    catch (BundleException ex)
+                    {
+                        JOptionPane.showMessageDialog(
+                            JOptionPane.getFrameForComponent(BundleListPlugin.this),
+                            ex.getMessage(), "Error",
+                            JOptionPane.ERROR_MESSAGE);
+                    }
+                }
+            }
+        });
+
+        m_updateButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event)
+            {
+                int[] rows = m_bundleTable.getSelectedRows();
+                for (int i = 0; i < rows.length; i++)
+                {
+                    try
+                    {
+                        m_context.getBundles()[rows[i]].update();
+                    }
+                    catch (BundleException ex)
+                    {
+                        JOptionPane.showMessageDialog(
+                            JOptionPane.getFrameForComponent(BundleListPlugin.this),
+                            ex.getMessage(), "Error",
+                            JOptionPane.ERROR_MESSAGE);
+                    }
+                }
+            }
+        });
+
+        m_refreshButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event)
+            {
+                // Get package admin service.
+                ServiceReference ref = m_context.getServiceReference(
+                    PackageAdmin.class.getName());
+                if (ref == null)
+                {
+                    JOptionPane.showMessageDialog(
+                        JOptionPane.getFrameForComponent(BundleListPlugin.this),
+                        "Unable to obtain PackageAdmin service.", "Error",
+                        JOptionPane.ERROR_MESSAGE);
+                    return;
+                }
+
+                PackageAdmin pa = (PackageAdmin) m_context.getService(ref);
+                if (pa == null)
+                {
+                    JOptionPane.showMessageDialog(
+                        JOptionPane.getFrameForComponent(BundleListPlugin.this),
+                        "Unable to obtain PackageAdmin service.", "Error",
+                        JOptionPane.ERROR_MESSAGE);
+                    return;
+                }
+
+                pa.refreshPackages(null);
+            }
+        });
+
+        m_uninstallButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event)
+            {
+                int[] rows = m_bundleTable.getSelectedRows();
+                // We need to uninstall in reverse order, otherwise
+                // the index will get messed up.
+                for (int i = rows.length - 1; i >= 0; i--)
+                {
+                    try
+                    {
+                        m_context.getBundles()[rows[i]].uninstall();
+                    }
+                    catch (BundleException ex)
+                    {
+                        JOptionPane.showMessageDialog(
+                            JOptionPane.getFrameForComponent(BundleListPlugin.this),
+                            ex.getMessage(), "Error",
+                            JOptionPane.ERROR_MESSAGE);
+                    }
+                }
+            }
+        });
+    }
+
+    private class SimpleTableModel extends AbstractTableModel
+    {
+        public int getRowCount()
+        {
+            return (m_context.getBundles() == null)
+                ? 0 : m_context.getBundles().length;
+        }
+
+        public int getColumnCount()
+        {
+            return 3;
+        }
+
+        public String getColumnName(int column)
+        {
+            if (column == 0)
+            {
+                return "Id";
+            }
+            else if (column == 1)
+            {
+                return "State";
+            }
+            else if (column == 2)
+            {
+                return "Location";
+            }
+            return "";
+        }
+
+        public Class getColumnClass(int column)
+        {
+            if (column == 0)
+            {
+                return Long.class;
+            }
+
+            return String.class;
+        }
+
+        public boolean isCellEditable(int row, int column)
+        {
+            return false;
+        }
+
+        public Object getValueAt(int row, int column)
+        {
+            if (column == 0)
+            {
+                return new Long(m_context.getBundles()[row].getBundleId());
+            }
+            else if (column == 1)
+            {
+                return getStateString(m_context.getBundles()[row].getState());
+            }
+            else if (column == 2)
+            {
+                String name = (String)
+                    m_context.getBundles()[row].getHeaders().get(Constants.BUNDLE_NAME);
+                name = (name == null)
+                    ? m_context.getBundles()[row].getLocation() : name;
+                return name;
+            }
+            return null;
+        }
+
+        public void update()
+        {
+            fireTableDataChanged();
+        }
+
+        private String getStateString(int state)
+        {
+            switch (state)
+            {
+                case Bundle.INSTALLED:
+                    return "Installed";
+                case Bundle.RESOLVED:
+                    return "Resolved";
+                case Bundle.STARTING:
+                    return "Starting";
+                case Bundle.ACTIVE:
+                    return "Active";
+                case Bundle.STOPPING:
+                    return "Stopping";
+            }
+            return "[unknown]";
+        }
+    }
+}
\ No newline at end of file
diff --git a/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/OBRPlugin.java b/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/OBRPlugin.java
new file mode 100644
index 0000000..71d9efa
--- /dev/null
+++ b/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/OBRPlugin.java
@@ -0,0 +1,728 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.shell.gui.plugin;
+
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.PrintStream;
+import java.net.URL;
+import java.util.*;
+
+import javax.swing.*;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.*;
+
+import org.apache.felix.shell.gui.Plugin;
+import org.osgi.framework.*;
+import org.osgi.service.obr.*;
+
+public class OBRPlugin extends JPanel implements Plugin
+{
+    private static final String DEPLOY_BUTTON = "Deploy";
+    private static final String START_BUTTON = "Deploy & start";
+
+    private BundleContext m_context = null;
+    private ServiceReference m_repoRef = null;
+    private RepositoryAdmin m_repoAdmin = null;
+
+    private SimpleTreeNode m_rootNode = null;
+    private CreateRootRunnable m_createRootRunnable = new CreateRootRunnable();
+    private SetRootRunnable m_setRootRunnable = new SetRootRunnable();
+
+    private JButton m_addRepoButton = null;
+    private JButton m_removeRepoButton = null;
+    private JButton m_refreshRepoButton = null;
+    private JTree m_bundleTree = null;
+    private JButton m_deployButton = null;
+    private JButton m_startButton = null;
+    private JButton m_infoButton = null;
+    private ScrollableOutputArea m_soa = null;
+    private JButton m_clearButton = null;
+
+    private PrintStream m_out = null;
+
+    // Plugin interface methods.
+
+    public String getName()
+    {
+        return "OBR";
+    }
+    
+    public Component getGUI()
+    {
+        return this;
+    }
+    
+    // Implementation.
+    
+    public OBRPlugin(BundleContext context)
+    {
+        m_context = context;
+        m_out = new PrintStream(
+            new OutputAreaStream(
+                m_soa = new ScrollableOutputArea(5, 30)));
+
+        // Create the gui.
+        createUserInterface();
+
+        synchronized (this)
+        {
+            // Listen for registering/unregistering bundle repository services.
+            ServiceListener sl = new ServiceListener() {
+                public void serviceChanged(ServiceEvent event)
+                {
+                    synchronized (OBRPlugin.this)
+                    {
+                        // Ignore additional services if we already have one.
+                        if ((event.getType() == ServiceEvent.REGISTERED)
+                            && (m_repoRef != null))
+                        {
+                            return;
+                        }
+                        // Initialize the service if we don't have one.
+                        else if ((event.getType() == ServiceEvent.REGISTERED)
+                            && (m_repoRef == null))
+                        {
+                            lookupService();
+                        }
+                        // Unget the service if it is unregistering.
+                        else if ((event.getType() == ServiceEvent.UNREGISTERING)
+                            && event.getServiceReference().equals(m_repoRef))
+                        {
+                            m_context.ungetService(m_repoRef);
+                            m_repoRef = null;
+                            m_repoAdmin = null;
+                            // Try to get another service.
+                            lookupService();
+                        }
+                    }
+                }
+            };
+
+            try
+            {
+                m_context.addServiceListener(sl,
+                    "(objectClass=" + RepositoryAdmin.class.getName() + ")");
+            }
+            catch (InvalidSyntaxException ex)
+            {
+                System.err.println("OBRPlugin: " + ex);
+            }
+
+            // Now try to manually initialize the shell service
+            // since one might already be available.
+            lookupService();
+        }
+    }
+
+    private synchronized void lookupService()
+    {
+        if (m_repoAdmin != null)
+        {
+            return;
+        }
+        m_repoRef = m_context.getServiceReference(RepositoryAdmin.class.getName());
+        if (m_repoRef == null)
+        {
+        }
+        else
+        {
+            m_repoAdmin = (RepositoryAdmin) m_context.getService(m_repoRef);
+        }
+
+        // Update the model.
+        initializeRootNode();
+    }
+
+    private void createEventListeners()
+    {
+        // Create action listeners.
+        m_addRepoButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event)
+            {
+                synchronized (OBRPlugin.this)
+                {
+                    if (m_repoAdmin == null)
+                    {
+                        return;
+                    }
+
+                    String s = JOptionPane.showInputDialog(
+                        OBRPlugin.this, "Enter repository URL:");
+
+                    if (s != null)
+                    {
+                        try
+                        {
+                            m_repoAdmin.addRepository(new URL(s));
+                        }
+                        catch (Exception ex)
+                        {
+                            ex.printStackTrace();
+                        }
+                    }
+
+                    // Update the table.
+                    initializeRootNode();
+                }
+            }
+        });
+
+        m_removeRepoButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event)
+            {
+                synchronized (OBRPlugin.this)
+                {
+                    if (m_repoAdmin == null)
+                    {
+                        return;
+                    }
+
+                    TreePath[] paths = m_bundleTree.getSelectionPaths();
+                    for (int i = 0; i < paths.length; i++)
+                    {
+                        SimpleTreeNode node = (SimpleTreeNode) paths[i].getLastPathComponent();
+                        if (node.getObject() instanceof Repository)
+                        {
+                            m_repoAdmin.removeRepository(
+                                ((Repository)
+                                    ((SimpleTreeNode)
+                                        paths[i].getLastPathComponent()).getObject()).getURL());
+                        }
+                    }
+
+                    // Update the table.
+                    initializeRootNode();
+                }
+            }
+        });
+
+        m_refreshRepoButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event)
+            {
+                synchronized (OBRPlugin.this)
+                {
+                    if (m_repoAdmin == null)
+                    {
+                        return;
+                    }
+
+                    TreePath[] paths = m_bundleTree.getSelectionPaths();
+                    for (int i = 0; i < paths.length; i++)
+                    {
+                        SimpleTreeNode node = (SimpleTreeNode) paths[i].getLastPathComponent();
+                        if (node.getObject() instanceof Repository)
+                        {
+                            try
+                            {
+                                // Adding the repository again causes it to be reparsed.
+                                m_repoAdmin.addRepository(
+                                    ((Repository) node.getObject()).getURL());
+                            } catch (Exception ex)
+                            {
+                                ex.printStackTrace();
+                            }
+                        }
+                    }
+
+                    // Update the table.
+                    initializeRootNode();
+                }
+            }
+        });
+
+        ActionListener al = new ActionListener() {
+            public void actionPerformed(ActionEvent event)
+            {
+                boolean start = event.getActionCommand().equals(START_BUTTON);
+
+                synchronized (OBRPlugin.this)
+                {
+                    if (m_repoAdmin == null)
+                    {
+                        return;
+                    }
+
+                    Resolver resolver = m_repoAdmin.resolver();
+                    TreePath[] paths = m_bundleTree.getSelectionPaths();
+                    for (int i = 0; i < paths.length; i++)
+                    {
+                        SimpleTreeNode node = (SimpleTreeNode) paths[i].getLastPathComponent();
+                        if (node.getObject() instanceof Resource)
+                        {
+                            resolver.add((Resource) node.getObject());
+                        }
+                    }
+
+                    if ((resolver.getAddedResources() != null) &&
+                        (resolver.getAddedResources().length > 0))
+                    {
+                        if (resolver.resolve())
+                        {
+                            m_out.println("Target resource(s):");
+                            printUnderline(m_out, 19);
+                            Resource[] resources = resolver.getAddedResources();
+                            for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++)
+                            {
+                                m_out.println("   " + resources[resIdx].getPresentationName()
+                                    + " (" + resources[resIdx].getVersion() + ")");
+                            }
+                            resources = resolver.getRequiredResources();
+                            if ((resources != null) && (resources.length > 0))
+                            {
+                                m_out.println("\nRequired resource(s):");
+                                printUnderline(m_out, 21);
+                                for (int resIdx = 0; resIdx < resources.length; resIdx++)
+                                {
+                                    m_out.println("   " + resources[resIdx].getPresentationName()
+                                        + " (" + resources[resIdx].getVersion() + ")");
+                                }
+                            }
+                            resources = resolver.getOptionalResources();
+                            if ((resources != null) && (resources.length > 0))
+                            {
+                                m_out.println("\nOptional resource(s):");
+                                printUnderline(m_out, 21);
+                                for (int resIdx = 0; resIdx < resources.length; resIdx++)
+                                {
+                                    m_out.println("   " + resources[resIdx].getPresentationName()
+                                        + " (" + resources[resIdx].getVersion() + ")");
+                                }
+                            }
+
+                            try
+                            {
+                                m_out.print("\nDeploying...");
+                                resolver.deploy(start);
+                                m_out.println("done.");
+                            }
+                            catch (IllegalStateException ex)
+                            {
+                                m_out.println(ex);
+                            }
+                        }
+                        else
+                        {
+                            Requirement[] reqs = resolver.getUnsatisfiedRequirements();
+                            if ((reqs != null) && (reqs.length > 0))
+                            {
+                                m_out.println("Unsatisfied requirement(s):");
+                                printUnderline(m_out, 27);
+                                for (int reqIdx = 0; reqIdx < reqs.length; reqIdx++)
+                                {
+                                    m_out.println("   " + reqs[reqIdx].getFilter());
+                                    Resource[] resources = resolver.getResources(reqs[reqIdx]);
+                                    for (int resIdx = 0; resIdx < resources.length; resIdx++)
+                                    {
+                                        m_out.println("      " + resources[resIdx].getPresentationName());
+                                    }
+                                }
+                            }
+                            else
+                            {
+                                m_out.println("Could not resolve targets.");
+                            }
+                        }
+
+                        m_out.println("");
+                    }
+                }
+            }
+        };
+
+        m_deployButton.addActionListener(al);
+        m_startButton.addActionListener(al);
+
+        m_infoButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event)
+            {
+                synchronized (OBRPlugin.this)
+                {
+                    if (m_repoAdmin == null)
+                    {
+                        return;
+                    }
+                    TreePath[] paths = m_bundleTree.getSelectionPaths();
+                    for (int i = 0; i < paths.length; i++)
+                    {
+                        if (i != 0)
+                        {
+                            m_out.println("");
+                        }
+                        printInfo(m_out,
+                            ((SimpleTreeNode) paths[i].getLastPathComponent()).getObject());
+                    }
+                    m_out.println("");
+                }
+            }
+        });
+
+        m_clearButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent event)
+            {
+                synchronized (OBRPlugin.this)
+                {
+                    m_soa.setText("");
+                }
+            }
+        });
+
+        m_bundleTree.addTreeSelectionListener(new TreeSelectionListener() {
+            public void valueChanged(TreeSelectionEvent e)
+            {
+                if (m_repoAdmin == null)
+                {
+                    return;
+                }
+                TreePath[] paths = m_bundleTree.getSelectionPaths();
+                boolean repoOnly = true;
+                if (paths != null)
+                {
+                    for (int i = 0; repoOnly && (i < paths.length); i++)
+                    {
+                        SimpleTreeNode node = (SimpleTreeNode) paths[i].getLastPathComponent();
+                        if (!(node.getObject() instanceof Repository))
+                        {
+                            repoOnly = false;
+                        }
+                    }
+                }
+                m_removeRepoButton.setEnabled((paths != null) && repoOnly);
+                m_refreshRepoButton.setEnabled((paths != null) && repoOnly);
+                m_infoButton.setEnabled((paths != null) && (paths.length > 0));
+            }
+        });
+    }
+
+    private void printInfo(PrintStream out, Object obj)
+    {
+        if (obj != null)
+        {
+            if (obj instanceof Repository)
+            {
+                Repository repo = (Repository) obj;
+                out.println(repo.getName());
+                out.println("   URL = " + repo.getURL());
+                out.println("   Modified = " + new Date(repo.getLastModified()));
+            }
+            else if (obj instanceof Resource)
+            {
+                Resource res = (Resource) obj;
+                out.println(res.getPresentationName());
+
+                // Print properties.
+                Map map = res.getProperties();
+                Iterator iter = map.entrySet().iterator();
+                while (iter.hasNext())
+                {
+                    Map.Entry entry = (Map.Entry) iter.next();
+                    out.println("   " + entry.getKey() + " = " + entry.getValue());
+                }
+
+                // Print requirements.
+                Requirement[] reqs = res.getRequirements();
+                for (int i = 0; (reqs != null) && (i < reqs.length); i++)
+                {
+                    if (i == 0)
+                    {
+                        out.println("   requirements:");
+                    }
+                    out.println("      " + reqs[i].getFilter());
+                }
+
+                // Print capabilities.
+                Capability[] caps = res.getCapabilities();
+                for (int i = 0; (caps != null) && (i < caps.length); i++)
+                {
+                    if (i == 0)
+                    {
+                        out.println("   capabilities:");
+                    }
+                    out.println("      " + caps[i].getName() + " = " + caps[i].getProperties());
+                }
+            }
+        }
+    }
+
+    private void createUserInterface()
+    {
+        JSplitPane split = new JSplitPane(
+            JSplitPane.VERTICAL_SPLIT, createTree(), createConsole());
+        split.setResizeWeight(1.0);
+        split.setDividerSize(5);
+        setLayout(new BorderLayout());
+        add(split, BorderLayout.CENTER);
+        createEventListeners();
+    }
+
+    private JPanel createTree()
+    {
+        JPanel panel = new JPanel(new BorderLayout());
+        panel.add(createRepoPanel(), BorderLayout.NORTH);
+        panel.add(createResourcePanel(), BorderLayout.CENTER);
+        return panel;
+    }
+
+    private JPanel createRepoPanel()
+    {
+        JPanel panel = new JPanel();
+        panel.setBorder(BorderFactory.createTitledBorder("Repositories"));
+        panel.add(m_addRepoButton = new JButton("Add"));
+        m_addRepoButton.setMnemonic('A');
+        panel.add(m_removeRepoButton = new JButton("Remove"));
+        m_removeRepoButton.setMnemonic('R');
+        panel.add(m_refreshRepoButton = new JButton("Refresh"));
+        m_refreshRepoButton.setMnemonic('f');
+        m_removeRepoButton.setEnabled(false);
+        m_refreshRepoButton.setEnabled(false);
+        return panel;
+    }
+
+    private JPanel createResourcePanel()
+    {
+        JPanel panel = new JPanel(new BorderLayout());
+        panel.setBorder(BorderFactory.createTitledBorder("Resources"));
+        JScrollPane scroll = null;
+        panel.add(
+            scroll = new JScrollPane(
+                m_bundleTree = new JTree(new SimpleTreeNode(null, null))), BorderLayout.CENTER);
+        panel.add(createButtonPanel(), BorderLayout.SOUTH);
+
+        // Set table scroll pane to reasonable size.
+        scroll.setPreferredSize(new Dimension(100, 100));
+        m_bundleTree.setMinimumSize(new Dimension(0, 0));
+
+        // We don't need to see the root.
+        m_bundleTree.setRootVisible(false);
+        m_bundleTree.setShowsRootHandles(true);
+
+        return panel;
+    }
+
+    private JPanel createButtonPanel()
+    {
+        JPanel panel = new JPanel();
+        panel.add(m_deployButton = new JButton(DEPLOY_BUTTON));
+        panel.add(m_startButton = new JButton(START_BUTTON));
+        panel.add(m_infoButton = new JButton("Info"));
+        m_deployButton.setMnemonic('D');
+        m_startButton.setMnemonic('S');
+        m_infoButton.setMnemonic('I');
+        m_infoButton.setEnabled(false);
+        return panel;
+    }
+
+    private JPanel createConsole()
+    {
+        JPanel panel = new JPanel(new BorderLayout());
+        panel.add(m_soa, BorderLayout.CENTER);
+        panel.add(m_clearButton = new JButton("Clear"), BorderLayout.EAST);
+        m_clearButton.setMnemonic('C');
+
+        return panel;
+    }
+
+    private static void printUnderline(PrintStream out, int length)
+    {
+        for (int i = 0; i < length; i++)
+        {
+            out.print('-');
+        }
+        out.println("");
+    }
+
+    private void initializeRootNode()
+    {
+        synchronized (m_createRootRunnable)
+        {
+            new Thread(m_createRootRunnable).start();
+        }
+    }
+
+    private class CreateRootRunnable implements Runnable
+    {
+        public void run()
+        {
+            synchronized (OBRPlugin.this)
+            {
+                // HACK ALERT: This next if statement is a hack to force
+                // the OBR service to retrieve its repository files on
+                // this thread, rather than the Swing thread. This hack
+                // assumes that this GUI is working with Felix' OBR service,
+                // which defers retrieving repository URLs until needed.
+                if (m_repoAdmin != null)
+                {
+                    m_repoAdmin.listRepositories();
+                }
+
+                // Create the new root node and then set it.
+                m_rootNode = new SimpleTreeNode(null, m_repoAdmin);
+                try
+                {
+                    SwingUtilities.invokeAndWait(m_setRootRunnable);
+                }
+                catch (Exception ex)
+                {
+                    // Ignore.
+                }
+            }
+        }
+    }
+
+    private class SetRootRunnable implements Runnable
+    {
+        public void run()
+        {
+            ((DefaultTreeModel) m_bundleTree.getModel()).setRoot(m_rootNode);
+        }
+    }
+
+    private static class SimpleTreeNode implements TreeNode
+    {
+        private TreeNode m_parent = null;
+        private Object m_obj = null;
+        private TreeNode[] m_children = null;
+        private String m_toString = null;
+
+        public SimpleTreeNode(TreeNode parent, Object obj)
+        {
+            m_parent = parent;
+            m_obj = obj;
+        }
+
+        public Object getObject()
+        {
+            return m_obj;
+        }
+
+        public TreeNode getChildAt(int index)
+        {
+            if (m_children == null)
+            {
+                initialize();
+            }
+
+            if ((m_children != null) && (index >= 0) && (index < m_children.length))
+            {
+                return m_children[index];
+            }
+
+            return null;
+        }
+
+        public int getChildCount()
+        {
+            if (m_children == null)
+            {
+                initialize();
+            }
+            return (m_children == null) ? 0 : m_children.length;
+        }
+
+        public TreeNode getParent()
+        {
+            return m_parent;
+        }
+
+        public int getIndex(TreeNode node)
+        {
+            if (m_children == null)
+            {
+                initialize();
+            }
+            for (int i = 0; (m_children != null) && (i < m_children.length); i++)
+            {
+                if (m_children[i] == node)
+                {
+                    return i;
+                }
+            }
+            return -1;
+        }
+
+        public boolean getAllowsChildren()
+        {
+            return true;
+        }
+
+        public boolean isLeaf()
+        {
+            return (getChildCount() == 0);
+        }
+
+        public Enumeration children()
+        {
+            return null;
+        }
+
+        private void initialize()
+        {
+            // The current node might be the root repository admin.
+            if ((m_obj != null) && (m_obj instanceof RepositoryAdmin))
+            {
+                Object[] objs = ((RepositoryAdmin) m_obj).listRepositories();
+                if (objs != null)
+                {
+                    m_children = new TreeNode[objs.length];
+                    for (int i = 0; i < objs.length; i++)
+                    {
+                        m_children[i] = new SimpleTreeNode(this, objs[i]);
+                    }
+                }
+            }
+            else if (m_obj instanceof Repository)
+            {
+                Object[] objs = ((Repository) m_obj).getResources();
+                if (objs != null)
+                {
+                    m_children = new TreeNode[objs.length];
+                    for (int i = 0; i < objs.length; i++)
+                    {
+                        m_children[i] = new SimpleTreeNode(this, objs[i]);
+                    }
+                }
+            }
+        }
+
+        public String toString()
+        {
+            if (m_toString == null)
+            {
+                if (m_obj instanceof RepositoryAdmin)
+                {
+                    m_toString = "ROOT";
+                }
+                else if (m_obj instanceof Repository)
+                {
+                    m_toString = ((Repository) m_obj).getName();
+                }
+                else if (m_obj instanceof Resource)
+                {
+                    m_toString = ((Resource) m_obj).getPresentationName()
+                        + " (" + ((Resource) m_obj).getVersion() + ")";
+                }
+                else
+                {
+                    m_toString = (m_obj != null) ? m_obj.toString() : "null";
+                }
+            }
+            return m_toString;
+        }
+    }
+}
\ No newline at end of file
diff --git a/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/OutputAreaStream.java b/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/OutputAreaStream.java
new file mode 100644
index 0000000..992b673
--- /dev/null
+++ b/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/OutputAreaStream.java
@@ -0,0 +1,47 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.shell.gui.plugin;
+
+import java.io.OutputStream;
+
+class OutputAreaStream extends OutputStream
+{
+    private ScrollableOutputArea m_soa;
+
+    public OutputAreaStream(ScrollableOutputArea soa)
+    {
+        m_soa = soa;
+    }
+
+    public void write(byte[] b)
+    {
+        String tmp = new String(b);
+        m_soa.addText(tmp);
+    }
+
+    public void write(byte[] b, int off, int len)
+    {
+        String tmp = new String(b, off, len);
+        m_soa.addText(tmp);
+    }
+
+    public void write(int b)
+    {
+        byte[] ba = { (byte) b };
+        m_soa.addText(new String(ba));
+    }
+}
\ No newline at end of file
diff --git a/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/ScrollableOutputArea.java b/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/ScrollableOutputArea.java
new file mode 100644
index 0000000..c454e51
--- /dev/null
+++ b/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/ScrollableOutputArea.java
@@ -0,0 +1,78 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.shell.gui.plugin;
+
+import java.awt.Font;
+
+import javax.swing.*;
+
+public class ScrollableOutputArea extends JScrollPane
+{
+    private JTextArea m_textArea = null;
+
+    public ScrollableOutputArea()
+    {
+        super();
+        m_textArea = new JTextArea();
+        initialize();
+    }
+
+    public ScrollableOutputArea(int rows, int columns)
+    {
+        super();
+        m_textArea = new JTextArea(rows, columns);
+        initialize();
+    }
+
+    private void initialize()
+    {
+        setViewportView(m_textArea);
+        m_textArea.setLineWrap(true);
+        m_textArea.setAutoscrolls(true);
+        m_textArea.setEnabled(true);
+        m_textArea.setEditable(false);
+        m_textArea.setFont(new Font("Monospaced", 0, 12));
+        setAutoscrolls(true);
+    }
+
+    public void setText(String s)
+    {
+        m_textArea.setText(s);
+    }
+
+    public void addText(String text)
+    {
+        m_textArea.append(text);
+        if (m_textArea.isDisplayable())
+        {
+            try
+            {
+                m_textArea.setCaretPosition(Integer.MAX_VALUE); // Scroll to end of window
+            }
+            catch (Exception e)
+            {
+                // Just for safety
+            }
+        }
+        validate();
+        JScrollBar sb = getVerticalScrollBar();
+        if ((sb != null) && (sb.isVisible()))
+        {
+            sb.setValue(Integer.MAX_VALUE);
+        }
+    }
+}
\ No newline at end of file
diff --git a/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/ShellPlugin.java b/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/ShellPlugin.java
new file mode 100644
index 0000000..aaaba36
--- /dev/null
+++ b/org.apache.felix.shell.gui.plugin/src/main/java/org/apache/felix/shell/gui/plugin/ShellPlugin.java
@@ -0,0 +1,183 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+package org.apache.felix.shell.gui.plugin;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.io.PrintStream;
+
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import org.apache.felix.shell.ShellService;
+import org.apache.felix.shell.gui.Plugin;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+
+public class ShellPlugin extends JPanel implements Plugin
+{
+    private BundleContext m_context = null;
+    private PrintStream m_out = null;
+
+    private JTextField m_commandField = new JTextField();
+    private String[] m_history = new String[25];
+    private int m_historyCount = -1;
+    private int m_current = 0; // current history counter
+
+    private ScrollableOutputArea m_soa = new ScrollableOutputArea();
+
+    // Plugin interface methods.
+
+    public String getName()
+    {
+        return "Shell";    
+    }
+    
+    public Component getGUI()
+    {
+        return this;
+    }
+    
+    // Implementation.
+    
+    public ShellPlugin(BundleContext context)
+    {
+        m_context = context;
+        m_out = new PrintStream(new OutputAreaStream(m_soa));
+        initialize();
+    }
+
+    private void initialize()
+    {
+        setLayout(new BorderLayout());
+        m_commandField.addKeyListener(new KeyAdapter() {
+            public void keyPressed(KeyEvent event)
+            {
+                commandFieldKeyPressed(event);
+            }
+        });
+        m_commandField.setFont(new java.awt.Font("Monospaced", 0, 12));
+        add(m_commandField, BorderLayout.SOUTH);
+        add(m_soa, BorderLayout.CENTER);
+    }
+
+    void processCommand(String line)
+    {
+        if (line == null)
+        {
+            return;
+        }
+
+        line = line.trim();
+
+        if (line.length() == 0)
+        {
+            return;
+        }
+
+        // Get shell service.
+        ServiceReference ref = m_context.getServiceReference(
+            org.apache.felix.shell.ShellService.class.getName());
+        if (ref == null)
+        {
+            m_out.println("No shell service is available.");
+            return;
+        }
+
+        ShellService shell = (ShellService) m_context.getService(ref);
+
+        // Print the command line in the output window.
+        m_out.println("-> " + line);
+
+        try {
+            shell.executeCommand(line, m_out, m_out);
+        } catch (Exception ex) {
+            m_out.println(ex.toString());
+            ex.printStackTrace(m_out);
+        }
+
+        m_context.ungetService(ref);
+    }
+
+    private void addToHistory(String command)
+    {
+        m_historyCount++;
+        if (m_historyCount >= m_history.length)
+        {
+            m_historyCount = m_history.length - 1;
+            for (int i = 0; i < m_history.length - 1; i++)
+            {
+                m_history[i] = m_history[i + 1];
+            }
+        }
+        m_history[m_historyCount] = new String(command);
+    }
+
+    private String getFromHistory(int num)
+    {
+        if (num < 0)
+        {
+            return ("");
+        }
+        else if (num > m_historyCount)
+        {
+            return("");
+        }
+        return m_history[num];
+    }
+
+    protected void commandFieldKeyPressed(KeyEvent event)
+    {
+        String command = null;
+        int c = event.getKeyCode();
+        // Cursor up.
+        if (c == 38)
+        {
+            m_current--;
+            if (m_current < 0)
+            {
+                m_current = 0;
+            }
+            m_commandField.setText(getFromHistory(m_current));
+            m_commandField.setCaretPosition(m_commandField.getText().length());
+        }
+        // Cursor down.
+        else if (c == 40)
+        {
+            m_current++;
+            if (m_current > m_historyCount)
+            {
+                m_current = m_historyCount + 1;
+            }
+            m_commandField.setText(getFromHistory(m_current));
+            m_commandField.setCaretPosition(m_commandField.getText().length());
+        }
+        else if (c == 10)
+        {
+            command = m_commandField.getText();
+            if (!command.equals(""))
+            {
+                addToHistory(command);
+                m_current = m_historyCount + 1;
+                processCommand(command);
+            }
+            m_commandField.setText("");
+        }
+    }
+}
\ No newline at end of file
