changeset 889:55f03d096318

Make swing client view implementation classes internal Move SearchFieldSwingView out of view implementation classes and into c.r.t.client.swing.components. All other classes in c.r.t.client.swing.views are internal and can be marked as such. Reviewed-by: jerboaa Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-December/004955.html
author Omair Majid <omajid@redhat.com>
date Mon, 07 Jan 2013 10:44:01 -0500
parents f3e413458c04
children 7765a6857a8d
files client/core/src/main/java/com/redhat/thermostat/client/core/views/SearchFieldView.java client/swing/pom.xml client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SearchField.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/Main.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindow.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivator.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/AgentInformationDisplayFrame.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationSwing.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/HostInformationPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/MemorySpacePanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SummaryPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SwingAgentInformationViewProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SwingClientConfigurationViewProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SwingHostInformationViewProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SwingSummaryViewProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SwingVmInformationViewProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/VmInformationPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/AgentInformationDisplayFrame.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/ClientConfigurationPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/ClientConfigurationSwing.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/HostInformationPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/MemorySpacePanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SearchFieldSwingView.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SummaryPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingAgentInformationViewProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingClientConfigurationViewProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingHostInformationViewProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingSummaryViewProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingVmInformationViewProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/VmInformationPanel.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/SearchFieldTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/SearchFieldSwingViewTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivatorTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/AgentInformationDisplayFrameTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationSwingTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/HostInformationPanelTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/views/AgentInformationDisplayFrameTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/views/ClientConfigurationSwingTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/views/HostInformationPanelTest.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanel.java vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanelTest.java
diffstat 43 files changed, 2737 insertions(+), 2796 deletions(-) [+]
line wrap: on
line diff
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/SearchFieldView.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.core.views;
-
-import com.redhat.thermostat.client.core.views.View;
-import com.redhat.thermostat.common.ActionListener;
-
-public interface SearchFieldView extends View {
-
-    /** For use by tests only */
-    public static final String VIEW_NAME = "searchField";
-
-    public enum SearchAction {
-        TEXT_CHANGED,
-        PERFORM_SEARCH,
-    }
-
-    public String getSearchText();
-
-    public void setSearchText(String text);
-
-    void setLabel(String label);
-
-    void setTooltip(String tooltip);
-
-    public void addActionListener(ActionListener<SearchAction> listener);
-    public void removeActionListener(ActionListener<SearchAction> listener);
-
-}
--- a/client/swing/pom.xml	Fri Dec 21 15:35:21 2012 +0100
+++ b/client/swing/pom.xml	Mon Jan 07 10:44:01 2013 -0500
@@ -148,13 +148,13 @@
               com.redhat.thermostat.client.swing,
               com.redhat.thermostat.client.swing.components,
               com.redhat.thermostat.client.swing.components.models,
-              com.redhat.thermostat.client.swing.views,
             </Export-Package>
             <Private-Package>
               com.redhat.thermostat.client.swing.internal,
               com.redhat.thermostat.client.swing.internal.components,
               com.redhat.thermostat.client.swing.internal.osgi,
-              com.redhat.thermostat.client.swing.internal.config
+              com.redhat.thermostat.client.swing.internal.config,
+              com.redhat.thermostat.client.swing.internal.views,
             </Private-Package>
             <!-- Do not autogenerate uses clauses in Manifests -->
             <_nouses>true</_nouses>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SearchField.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,209 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.swing.BorderFactory;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.swing.EdtHelper;
+import com.redhat.thermostat.client.swing.IconResource;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.ActionNotifier;
+import com.redhat.thermostat.common.locale.Translate;
+
+/**
+ * A swing component meant for entering search terms.
+ * <p>
+ * Similar to other swing components, this component should only be
+ * modified on the swing EDT.
+ */
+public class SearchField extends JPanel {
+
+    /** For use by tests only */
+    public static final String VIEW_NAME = "searchField";
+
+    public enum SearchAction {
+        TEXT_CHANGED,
+        PERFORM_SEARCH,
+    }
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private final ActionNotifier<SearchAction> notifier = new ActionNotifier<>(this);
+    private final JTextField searchField = new JTextField();
+
+    private final AtomicReference<String> searchText = new AtomicReference<String>("");
+    private final AtomicReference<String> label = new AtomicReference<>(translator.localize(LocaleResources.SEARCH_HINT));
+    private final AtomicBoolean labelDisplayed = new AtomicBoolean(true);
+
+    public SearchField() {
+        super(new BorderLayout());
+
+        // TODO move this icon inside the search field
+        JLabel searchIcon = new JLabel(IconResource.SEARCH.getIcon());
+        searchIcon.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
+
+        searchField.setText(label.get());
+        searchField.setName(VIEW_NAME);
+        /* the insets are so we can place the actual icon inside the searchField */
+        searchField.setMargin(new Insets(0, 0, 0, 30));
+
+        searchField.getDocument().addDocumentListener(new DocumentListener() {
+
+            private String previousText = searchText.get();
+
+            @Override
+            public void removeUpdate(DocumentEvent event) {
+                changed(event.getDocument());
+            }
+
+            @Override
+            public void insertUpdate(DocumentEvent event) {
+                changed(event.getDocument());
+            }
+
+            @Override
+            public void changedUpdate(DocumentEvent event) {
+                changed(event.getDocument());
+            }
+
+            private void changed(Document doc) {
+                if (!labelDisplayed.get()) {
+                    String filter = null;
+                    try {
+                        filter = doc.getText(0, doc.getLength());
+                    } catch (BadLocationException ble) {
+                        // ignore
+                    }
+
+                    searchText.set(filter);
+                    if (!(filter.equals(previousText))) {
+                        previousText = filter;
+                        fireViewAction(SearchAction.TEXT_CHANGED);
+                    }
+                }
+            }
+        });
+
+        final Color originalForegroundColor = searchField.getForeground();
+        searchField.addFocusListener(new FocusListener() {
+
+            @Override
+            public void focusLost(FocusEvent e) {
+                if (searchText.get().equals("")) {
+                    labelDisplayed.set(true);
+                    searchField.setForeground(Color.GRAY);
+                    searchField.setText(label.get());
+                }
+            }
+
+            @Override
+            public void focusGained(FocusEvent e) {
+                if (labelDisplayed.get()) {
+                    labelDisplayed.set(false);
+                    searchField.setForeground(originalForegroundColor);
+                    searchField.setText("");
+                }
+
+            }
+        });
+
+        final java.awt.event.ActionListener searchActionListener = new java.awt.event.ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                fireViewAction(SearchAction.PERFORM_SEARCH);
+            }
+        };
+
+        searchField.addActionListener(searchActionListener);
+
+        add(searchField);
+        add(searchIcon, BorderLayout.LINE_END);
+
+    }
+
+    public String getSearchText() {
+        return searchText.get();
+    }
+
+    public void setSearchText(final String text) {
+        searchText.set(text);
+        searchField.setText(text);
+    }
+
+    public void setLabel(String label) {
+        this.label.set(label);
+        if (labelDisplayed.get()) {
+            searchField.setText(this.label.get());
+        }
+    }
+
+    public void setTooltip(final String tooltip) {
+        searchField.setToolTipText(tooltip);
+    }
+
+    public void addActionListener(ActionListener<SearchAction> listener) {
+        notifier.addActionListener(listener);
+    }
+
+    public void removeActionListener(ActionListener<SearchAction> listener) {
+        notifier.removeActionListener(listener);
+    }
+
+    private void fireViewAction(SearchAction action) {
+        notifier.fireAction(action);
+    }
+}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/Main.java	Fri Dec 21 15:35:21 2012 +0100
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/Main.java	Mon Jan 07 10:44:01 2013 -0500
@@ -52,7 +52,7 @@
 import com.redhat.thermostat.client.core.views.ClientConfigurationView;
 import com.redhat.thermostat.client.locale.LocaleResources;
 import com.redhat.thermostat.client.swing.internal.config.ConnectionConfiguration;
-import com.redhat.thermostat.client.swing.views.ClientConfigurationSwing;
+import com.redhat.thermostat.client.swing.internal.views.ClientConfigurationSwing;
 import com.redhat.thermostat.client.ui.ClientConfigReconnector;
 import com.redhat.thermostat.client.ui.ClientConfigurationController;
 import com.redhat.thermostat.client.ui.MainWindowController;
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindow.java	Fri Dec 21 15:35:21 2012 +0100
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindow.java	Mon Jan 07 10:44:01 2013 -0500
@@ -92,7 +92,6 @@
 
 import com.redhat.thermostat.client.core.Filter;
 import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.SearchFieldView.SearchAction;
 import com.redhat.thermostat.client.locale.LocaleResources;
 import com.redhat.thermostat.client.osgi.service.DecoratorProvider;
 import com.redhat.thermostat.client.osgi.service.MenuAction;
@@ -101,10 +100,11 @@
 import com.redhat.thermostat.client.swing.HtmlTextBuilder;
 import com.redhat.thermostat.client.swing.MenuHelper;
 import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.client.swing.components.SearchField;
+import com.redhat.thermostat.client.swing.components.SearchField.SearchAction;
 import com.redhat.thermostat.client.swing.components.StatusBar;
 import com.redhat.thermostat.client.swing.components.ThermostatPopupMenu;
 import com.redhat.thermostat.client.swing.internal.components.DecoratedDefaultMutableTreeNode;
-import com.redhat.thermostat.client.swing.views.SearchFieldSwingView;
 import com.redhat.thermostat.client.ui.Decorator;
 import com.redhat.thermostat.client.ui.IconDescriptor;
 import com.redhat.thermostat.common.ActionEvent;
@@ -321,7 +321,7 @@
     private final MenuHelper mainMenuHelper = new MenuHelper(mainMenuBar);
     private JPanel contentArea = null;
 
-    private SearchFieldSwingView searchField = new SearchFieldSwingView();
+    private SearchField searchField = new SearchField();
     private JTree agentVmTree = null;
 
     private final ShutdownClient shutdownAction;
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivator.java	Fri Dec 21 15:35:21 2012 +0100
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivator.java	Mon Jan 07 10:44:01 2013 -0500
@@ -55,11 +55,11 @@
 import com.redhat.thermostat.client.swing.internal.HostIconDecoratorProvider;
 import com.redhat.thermostat.client.swing.internal.Main;
 import com.redhat.thermostat.client.swing.internal.UiFacadeFactoryImpl;
-import com.redhat.thermostat.client.swing.views.SwingAgentInformationViewProvider;
-import com.redhat.thermostat.client.swing.views.SwingClientConfigurationViewProvider;
-import com.redhat.thermostat.client.swing.views.SwingHostInformationViewProvider;
-import com.redhat.thermostat.client.swing.views.SwingSummaryViewProvider;
-import com.redhat.thermostat.client.swing.views.SwingVmInformationViewProvider;
+import com.redhat.thermostat.client.swing.internal.views.SwingAgentInformationViewProvider;
+import com.redhat.thermostat.client.swing.internal.views.SwingClientConfigurationViewProvider;
+import com.redhat.thermostat.client.swing.internal.views.SwingHostInformationViewProvider;
+import com.redhat.thermostat.client.swing.internal.views.SwingSummaryViewProvider;
+import com.redhat.thermostat.client.swing.internal.views.SwingVmInformationViewProvider;
 import com.redhat.thermostat.client.ui.UiFacadeFactory;
 import com.redhat.thermostat.common.Constants;
 import com.redhat.thermostat.common.cli.CommandRegistry;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/AgentInformationDisplayFrame.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,477 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import java.awt.BorderLayout;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.swing.DefaultListModel;
+import javax.swing.GroupLayout;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTable;
+import javax.swing.LayoutStyle.ComponentPlacement;
+import javax.swing.ListSelectionModel;
+import javax.swing.SwingUtilities;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.DefaultTableModel;
+
+import com.redhat.thermostat.client.core.views.AgentInformationDisplayView;
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.swing.components.LabelField;
+import com.redhat.thermostat.client.swing.components.SectionHeader;
+import com.redhat.thermostat.client.swing.components.ValueField;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.Translate;
+
+public class AgentInformationDisplayFrame extends AgentInformationDisplayView {
+
+    private static final Translate<LocaleResources> translate = LocaleResources.createLocalizer();
+
+    private static final String[] BACKEND_TABLE_COLUMN_NAMES = new String[] {
+        translate.localize(LocaleResources.AGENT_INFO_BACKEND_NAME_COLUMN),
+        translate.localize(LocaleResources.AGENT_INFO_BACKEND_STATUS_COLUMN),
+    };
+
+    private final CopyOnWriteArrayList<ActionListener<ConfigurationAction>> listeners = new CopyOnWriteArrayList<>();
+
+    private final JFrame frame;
+
+    private final ConfigurationCompleteListener configurationComplete;
+    private final AgentChangedListener agentChanged;
+    private final WindowClosingListener windowListener;
+
+    private final JButton closeButton;
+
+    private final JList<String> agentList;
+    private final DefaultListModel<String> listModel;
+
+    private final ValueField currentAgentName;
+    private final ValueField currentAgentId;
+    private final ValueField currentAgentCommandAddress;
+    private final ValueField currentAgentStartTime;
+    private final ValueField currentAgentStopTime;
+
+    private final JTable backendsTable;
+    private final DefaultTableModel backendsTableModel;
+    private final ValueField backendDescription;
+
+    public AgentInformationDisplayFrame() {
+        assertInEDT();
+
+        configurationComplete = new ConfigurationCompleteListener();
+        agentChanged = new AgentChangedListener();
+        windowListener = new WindowClosingListener();
+
+        frame = new JFrame();
+        frame.setTitle(translate.localize(LocaleResources.AGENT_INFO_WINDOW_TITLE));
+        frame.addWindowListener(windowListener);
+
+        closeButton = new JButton(translate.localize(LocaleResources.BUTTON_CLOSE));
+        closeButton.addActionListener(configurationComplete);
+        closeButton.setName("close");
+
+        JSplitPane splitPane = new JSplitPane();
+        splitPane.setResizeWeight(0.35);
+
+        GroupLayout mainLayout = new GroupLayout(frame.getContentPane());
+        mainLayout.setHorizontalGroup(
+            mainLayout.createParallelGroup(Alignment.TRAILING)
+                .addGroup(mainLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addGroup(mainLayout.createParallelGroup(Alignment.TRAILING)
+                        .addComponent(splitPane, GroupLayout.DEFAULT_SIZE, 664, Short.MAX_VALUE)
+                        .addComponent(closeButton))
+                    .addContainerGap()));
+
+        mainLayout.setVerticalGroup(
+            mainLayout.createParallelGroup(Alignment.TRAILING)
+                .addGroup(mainLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addComponent(splitPane, GroupLayout.DEFAULT_SIZE, 472, Short.MAX_VALUE)
+                    .addPreferredGap(ComponentPlacement.UNRELATED)
+                    .addComponent(closeButton)
+                    .addContainerGap()));
+
+        JPanel agentListPanel = new JPanel();
+        splitPane.setLeftComponent(agentListPanel);
+
+        JLabel agentLabel = new JLabel(translate.localize(LocaleResources.AGENT_INFO_AGENTS_LIST));
+
+        JScrollPane scrollPane = new JScrollPane();
+
+        listModel = new DefaultListModel<String>();
+        agentList = new JList<String>(listModel);
+        agentList.setName("agentList");
+        agentList.addListSelectionListener(agentChanged);
+        agentListPanel.setLayout(new BorderLayout());
+
+        scrollPane.setViewportView(agentList);
+        agentListPanel.add(scrollPane);
+        agentListPanel.add(agentLabel, BorderLayout.NORTH);
+
+        JPanel agentConfigurationPanel = new JPanel();
+        splitPane.setRightComponent(agentConfigurationPanel);
+
+        SectionHeader agentSectionTitle = new SectionHeader(translate.localize(LocaleResources.AGENT_INFO_AGENT_SECTION_TITLE));
+
+        LabelField agentNameLabel = new LabelField(translate.localize(LocaleResources.AGENT_INFO_AGENT_NAME_LABEL));
+        LabelField agentIdLabel = new LabelField(translate.localize(LocaleResources.AGENT_INFO_AGENT_ID_LABEL));
+        LabelField agentConfigurationAddressLabel = new LabelField(translate.localize(LocaleResources.AGENT_INFO_AGENT_COMMAND_ADDRESS_LABEL));
+        LabelField agentStartTimeLabel = new LabelField(translate.localize(LocaleResources.AGENT_INFO_AGENT_START_TIME_LABEL));
+        LabelField agentStopTimeLabel = new LabelField(translate.localize(LocaleResources.AGENT_INFO_AGENT_STOP_TIME_LABEL));
+
+        String notAvailable = translate.localize(LocaleResources.INFORMATION_NOT_AVAILABLE);
+
+        currentAgentName = new ValueField(notAvailable);
+        currentAgentName.setName("agentName");
+        currentAgentId = new ValueField(notAvailable);
+        currentAgentId.setName("agentId");
+        currentAgentCommandAddress = new ValueField(notAvailable);
+        currentAgentCommandAddress.setName("commandAddress");
+        currentAgentStartTime = new ValueField(notAvailable);
+        currentAgentStartTime.setName("startTime");
+        currentAgentStopTime = new ValueField(notAvailable);
+        currentAgentStopTime.setName("stopTime");
+
+        SectionHeader backendSectionTitle = new SectionHeader(translate.localize(LocaleResources.AGENT_INFO_BACKENDS_SECTION_TITLE));
+
+        backendsTableModel = new BackendsTableModel();
+        backendsTableModel.setColumnIdentifiers(BACKEND_TABLE_COLUMN_NAMES);
+
+        backendsTable = new JTable(backendsTableModel);
+        backendsTable.setName("backends");
+        backendsTable.setCellSelectionEnabled(false);
+        backendsTable.setColumnSelectionAllowed(false);
+        backendsTable.setRowSelectionAllowed(true);
+        backendsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        backendsTable.getSelectionModel().addListSelectionListener(new BackendSelectionListener());
+
+        JScrollPane backendsTableScollPane = new JScrollPane(backendsTable);
+
+        JLabel backendDescriptionLabel = new JLabel(translate.localize(LocaleResources.AGENT_INFO_BACKEND_DESCRIPTION_LABEL));
+        backendDescription = new ValueField(notAvailable);
+        backendDescription.setName("backendDescription");
+
+        GroupLayout agentConfigurationPanelLayout = new GroupLayout(agentConfigurationPanel);
+        agentConfigurationPanelLayout.setHorizontalGroup(
+            agentConfigurationPanelLayout.createParallelGroup()
+                .addComponent(agentSectionTitle, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addGroup(agentConfigurationPanelLayout.createSequentialGroup()
+                    .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.LEADING, true)
+                        .addComponent(agentNameLabel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addComponent(agentIdLabel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addComponent(agentConfigurationAddressLabel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addComponent(agentStartTimeLabel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addComponent(agentStopTimeLabel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                    .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.LEADING, true)
+                        .addComponent(currentAgentName, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
+                        .addComponent(currentAgentId, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
+                        .addComponent(currentAgentCommandAddress, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
+                        .addComponent(currentAgentStartTime, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
+                        .addComponent(currentAgentStopTime, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)))
+                .addComponent(backendSectionTitle, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
+                .addComponent(backendsTableScollPane, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
+                .addComponent(backendDescriptionLabel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addComponent(backendDescription, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE));
+
+        agentConfigurationPanelLayout.setVerticalGroup(
+            agentConfigurationPanelLayout.createSequentialGroup()
+                .addComponent(agentSectionTitle)
+                .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.BASELINE, false)
+                    .addComponent(agentNameLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                    .addComponent(currentAgentName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.BASELINE, false)
+                    .addComponent(agentIdLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                    .addComponent(currentAgentId, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.BASELINE, false)
+                    .addComponent(agentConfigurationAddressLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                    .addComponent(currentAgentCommandAddress, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.BASELINE, false)
+                    .addComponent(agentStartTimeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                    .addComponent(currentAgentStartTime, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.BASELINE, false)
+                    .addComponent(agentStopTimeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                    .addComponent(currentAgentStopTime, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                .addComponent(backendSectionTitle)
+                .addComponent(backendsTableScollPane)
+                .addComponent(backendDescriptionLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE)
+                .addComponent(backendDescription, 30, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE));
+
+        agentConfigurationPanelLayout.setAutoCreateGaps(true);
+        agentConfigurationPanelLayout.setAutoCreateContainerGaps(true);
+        agentConfigurationPanel.setLayout(agentConfigurationPanelLayout);
+
+        frame.getContentPane().setLayout(mainLayout);
+
+    }
+
+    @Override
+    public void addConfigurationListener(ActionListener<ConfigurationAction> listener) {
+        listeners.add(listener);
+    }
+
+    @Override
+    public void removeConfigurationListener(ActionListener<ConfigurationAction> listener) {
+        listeners.remove(listener);
+    }
+
+    @Override
+    public void addAgent(final String agentName) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                listModel.addElement(agentName);
+                if (agentList.getSelectedIndex() == -1) {
+                    agentList.setSelectedIndex(0);
+                }
+            }
+        });
+    }
+
+    @Override
+    public String getSelectedAgent() {
+        assertInEDT();
+        return agentList.getSelectedValue();
+    }
+
+    @Override
+    public void clearAllAgents() {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                listModel.clear();
+            }
+        });
+    }
+
+    @Override
+    public void setSelectedAgentName(final String agentName) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                currentAgentName.setText(agentName);
+            }
+        });
+    }
+
+    @Override
+    public void setSelectedAgentId(final String agentId) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                currentAgentId.setText(agentId);
+            }
+        });
+    }
+
+    @Override
+    public void setSelectedAgentCommandAddress(final String address) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                currentAgentCommandAddress.setText(address);
+            }
+        });
+    }
+
+    @Override
+    public void setSelectedAgentStartTime(final String startTime) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                currentAgentStartTime.setText(startTime);
+            }
+        });
+    }
+
+    @Override
+    public void setSelectedAgentStopTime(final String stopTime) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                currentAgentStopTime.setText(stopTime);
+            }
+        });
+    }
+
+    @Override
+    public void setSelectedAgentBackendStatus(final Map<String, String> backendStatus) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                int i = 0;
+                for (Entry<String, String> entry : backendStatus.entrySet()) {
+                    String backendName = entry.getKey();
+                    String status = entry.getValue();
+                    int rowCount = backendsTableModel.getRowCount();
+                    if (i >= rowCount) {
+                        Object[] rowData = new String[] { backendName, status };
+                        backendsTableModel.insertRow(i, rowData);
+                    } else {
+                        backendsTableModel.setValueAt(backendName, i, 0);
+                        backendsTableModel.setValueAt(status, i, 1);
+                    }
+                    i++;
+                }
+
+                if (backendsTable.getRowCount() > 0 && backendsTable.getSelectedRow() == -1) {
+                    backendsTable.setRowSelectionInterval(0, 0);
+                }
+            }
+        });
+    }
+
+    @Override
+    public void setSelectedAgentBackendDescription(final String description) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                backendDescription.setText(description);
+            }
+        });
+    }
+
+    @Override
+    public void showDialog() {
+        assertInEDT();
+
+        frame.pack();
+        frame.setVisible(true);
+
+        agentList.setSelectedIndex(0);
+    }
+
+    @Override
+    public void hideDialog() {
+        assertInEDT();
+
+        frame.setVisible(false);
+        frame.dispose();
+    }
+
+    /** This is for tests only */
+    JFrame getFrame() {
+        return frame;
+    }
+
+    private void fireAction(ActionEvent<ConfigurationAction> actionEvent) {
+        for (ActionListener<ConfigurationAction> l : listeners) {
+            l.actionPerformed(actionEvent);
+        }
+    }
+
+    private static void assertInEDT() {
+        if (!SwingUtilities.isEventDispatchThread()) {
+            throw new IllegalStateException("must be called from within the swing EDT");
+        }
+    }
+
+    private class ConfigurationCompleteListener implements java.awt.event.ActionListener {
+        @Override
+        public void actionPerformed(java.awt.event.ActionEvent e) {
+            Object source = e.getSource();
+            if (source == closeButton) {
+                fireAction(new ActionEvent<>(AgentInformationDisplayFrame.this, ConfigurationAction.CLOSE));
+            }
+        }
+    }
+
+    private class WindowClosingListener extends WindowAdapter {
+        @Override
+        public void windowClosing(WindowEvent e) {
+            fireAction(new ActionEvent<>(AgentInformationDisplayFrame.this, ConfigurationAction.CLOSE));
+        }
+    }
+
+    private class AgentChangedListener implements ListSelectionListener {
+        @Override
+        public void valueChanged(ListSelectionEvent e) {
+            if (e.getSource() == agentList) {
+                if (e.getValueIsAdjusting()) {
+                    return;
+                }
+                fireAction(new ActionEvent<>(AgentInformationDisplayFrame.this, ConfigurationAction.SWITCH_AGENT));
+            } else {
+                throw new IllegalStateException("unknown trigger");
+            }
+        }
+    }
+
+    private class BackendSelectionListener implements ListSelectionListener {
+
+        @Override
+        public void valueChanged(ListSelectionEvent e) {
+            if (e.getValueIsAdjusting()) {
+                return;
+            }
+
+            ListSelectionModel model = (ListSelectionModel) e.getSource();
+            int rowIndex = model.getMinSelectionIndex();
+            String backendName = (String) backendsTableModel.getValueAt(rowIndex, 0);
+            ActionEvent<ConfigurationAction> event = new ActionEvent<>(AgentInformationDisplayFrame.this,
+                    ConfigurationAction.SHOW_BACKEND_DESCRIPTION);
+            event.setPayload(backendName);
+            fireAction(event);
+        }
+
+    }
+    
+    private class BackendsTableModel extends DefaultTableModel {
+
+        private static final long serialVersionUID = 8635399933525019537L;
+
+        @Override
+        public boolean isCellEditable(int row, int column) {
+            // Not editable
+            return false;
+        }
+    };
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationPanel.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import javax.swing.GroupLayout;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JTextField;
+import javax.swing.LayoutStyle.ComponentPlacement;
+import javax.swing.border.TitledBorder;
+
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.common.locale.Translate;
+
+@SuppressWarnings("serial")
+class ClientConfigurationPanel extends JPanel {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    final JTextField storageUrl = new JTextField();
+    final JTextField userName = new JTextField();
+    final JPasswordField password = new JPasswordField();
+    
+    final JCheckBox saveEntitlements;
+    
+    public ClientConfigurationPanel() {
+        setBorder(new TitledBorder(null,
+                  translator.localize(LocaleResources.CLIENT_PREFS_CONNECTION),
+                  TitledBorder.LEFT, TitledBorder.TOP, null, null));
+
+        JLabel storageURLText = new JLabel(translator.localize(LocaleResources.CLIENT_PREFS_STORAGE_URL));
+        storageURLText.setName("");
+        
+        storageUrl.setColumns(10);
+        storageUrl.setName("connectionUrl");
+        
+        JLabel userNameText = new JLabel(translator.localize(LocaleResources.CLIENT_PREFS_STORAGE_USERNAME));
+        userNameText.setName("userNameText");
+        
+        userName.setName("username");
+        userName.setColumns(10);
+        
+        JLabel passowrdText = new JLabel("Password");
+        passowrdText.setName("passwordText");
+        
+        password.setName("password");
+        password.setColumns(10);
+        
+        saveEntitlements = new JCheckBox(translator.localize(LocaleResources.CLIENT_PREFS_STORAGE_SAVE_ENTITLEMENTS));
+        saveEntitlements.setName("saveEntitlements");
+        saveEntitlements.setSelected(false);
+
+        GroupLayout groupLayout = new GroupLayout(this);
+        groupLayout.setHorizontalGroup(
+            groupLayout.createParallelGroup(Alignment.TRAILING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
+                        .addComponent(saveEntitlements)
+                        .addGroup(groupLayout.createSequentialGroup()
+                            .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+                                .addComponent(storageURLText, GroupLayout.PREFERRED_SIZE, 83, GroupLayout.PREFERRED_SIZE)
+                                .addGroup(groupLayout.createParallelGroup(Alignment.LEADING, false)
+                                    .addComponent(passowrdText, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                    .addComponent(userNameText, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+                            .addPreferredGap(ComponentPlacement.UNRELATED)
+                            .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+                                .addComponent(userName, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 326, Short.MAX_VALUE)
+                                .addComponent(storageUrl, GroupLayout.DEFAULT_SIZE, 326, Short.MAX_VALUE)
+                                .addComponent(password, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 326, Short.MAX_VALUE))))
+                    .addGap(24))
+        );
+        groupLayout.setVerticalGroup(
+            groupLayout.createParallelGroup(Alignment.LEADING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
+                        .addComponent(storageURLText)
+                        .addComponent(storageUrl, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+                        .addGroup(groupLayout.createSequentialGroup()
+                            .addGap(8)
+                            .addComponent(userNameText))
+                        .addGroup(groupLayout.createSequentialGroup()
+                            .addPreferredGap(ComponentPlacement.RELATED)
+                            .addComponent(userName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
+                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+                        .addGroup(groupLayout.createSequentialGroup()
+                            .addGap(8)
+                            .addComponent(passowrdText))
+                        .addGroup(groupLayout.createSequentialGroup()
+                            .addPreferredGap(ComponentPlacement.RELATED)
+                            .addComponent(password, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
+                    .addPreferredGap(ComponentPlacement.UNRELATED)
+                    .addComponent(saveEntitlements)
+                    .addContainerGap(15, Short.MAX_VALUE))
+        );
+        setLayout(groupLayout);
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationSwing.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import java.awt.Frame;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.swing.JDialog;
+import javax.swing.JOptionPane;
+import javax.swing.SwingUtilities;
+import javax.swing.WindowConstants;
+
+import com.redhat.thermostat.client.core.views.ClientConfigurationView;
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.swing.EdtHelper;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.Translate;
+
+public class ClientConfigurationSwing implements ClientConfigurationView {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private final WindowClosingListener windowClosingListener;
+
+    private final ClientConfigurationPanel configurationPanel;
+
+    private final CopyOnWriteArrayList<ActionListener<Action>> listeners = new CopyOnWriteArrayList<>();
+
+    private JDialog dialog;
+
+    public ClientConfigurationSwing() {
+        assertInEDT();
+
+        windowClosingListener = new WindowClosingListener();
+        configurationPanel = new ClientConfigurationPanel();
+        
+        final JOptionPane optionPane = new JOptionPane(configurationPanel);
+        optionPane.setOptionType(JOptionPane.OK_CANCEL_OPTION);
+        optionPane.addPropertyChangeListener(new PropertyChangeListener() {
+            @Override
+            public void propertyChange(PropertyChangeEvent evt) {
+                String propertyName = evt.getPropertyName();
+                if ((evt.getSource() == optionPane) &&
+                    (propertyName.equals(JOptionPane.VALUE_PROPERTY))) {
+                    if (dialog.isVisible()) {
+                        if (evt.getNewValue().equals(JOptionPane.OK_OPTION)) {
+                            fireAction(new ActionEvent<>(ClientConfigurationSwing.this, Action.CLOSE_ACCEPT));
+                        } else if (evt.getNewValue().equals(JOptionPane.CANCEL_OPTION)) {
+                            fireAction(new ActionEvent<>(ClientConfigurationSwing.this, Action.CLOSE_CANCEL));
+                        }
+                    }
+                }
+            }
+        });
+
+        dialog = new JDialog((Frame) null, translator.localize(LocaleResources.CLIENT_PREFS_WINDOW_TITLE));
+        dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
+        dialog.setContentPane(optionPane);
+        dialog.addWindowListener(windowClosingListener);
+    }
+
+    JDialog getDialog() {
+        return dialog;
+    }
+
+    @Override
+    public void showDialog() {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                dialog.pack();
+                dialog.setVisible(true);
+            }
+        });
+    }
+
+    @Override
+    public void hideDialog() {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                dialog.setVisible(false);
+                dialog.dispose();
+                dialog = null;
+            }
+
+        });
+    }
+
+    @Override
+    public String getConnectionUrl() {
+        try {
+            return new EdtHelper().callAndWait(new Callable<String>() {
+                @Override
+                public String call() throws Exception {
+                    return configurationPanel.storageUrl.getText();
+                }
+            });
+        } catch (InvocationTargetException | InterruptedException e) {
+            InternalError error = new InternalError();
+            error.initCause(e);
+            throw error;
+        }
+    }
+
+    @Override
+    public void setConnectionUrl(final String url) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                configurationPanel.storageUrl.setText(url);
+            }
+        });
+    }
+
+    @Override
+    public void addListener(ActionListener<Action> listener) {
+        listeners.add(listener);
+    }
+
+    @Override
+    public void removeListener(ActionListener<Action> listener) {
+        listeners.remove(listener);
+    }
+
+    private void fireAction(ActionEvent<Action> actionEvent) {
+        for (ActionListener<Action> listener: listeners) {
+            listener.actionPerformed(actionEvent);
+        }
+    }
+
+    private void assertInEDT() {
+        if (!SwingUtilities.isEventDispatchThread()) {
+            throw new IllegalStateException("must be invoked in the EDT");
+        }
+    }
+
+    class WindowClosingListener extends WindowAdapter {
+        @Override
+        public void windowClosing(WindowEvent e) {
+            fireAction(new ActionEvent<>(ClientConfigurationSwing.this, Action.CLOSE_CANCEL));
+        }
+    }
+
+    @Override
+    public void setPassword(final String password) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                configurationPanel.password.setText(password);
+            }
+        });
+    }
+    
+    @Override
+    public void setUserName(final String username) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                configurationPanel.userName.setText(username);
+            }
+        });
+    };
+    
+    @Override
+    public String getPassword() {
+        try {
+            return new EdtHelper().callAndWait(new Callable<String>() {
+                @Override
+                public String call() throws Exception {
+                    return configurationPanel.password.getText();
+                }
+            });
+        } catch (InvocationTargetException | InterruptedException e) {
+            InternalError error = new InternalError();
+            error.initCause(e);
+            throw error;
+        }
+    }
+    
+    @Override
+    public String getUserName() {
+        try {
+            return new EdtHelper().callAndWait(new Callable<String>() {
+                @Override
+                public String call() throws Exception {
+                    return configurationPanel.userName.getText();
+                }
+            });
+        } catch (InvocationTargetException | InterruptedException e) {
+            InternalError error = new InternalError();
+            error.initCause(e);
+            throw error;
+        }
+    }
+    
+    @Override
+    public boolean getSaveEntitlements() {
+        try {
+            return new EdtHelper().callAndWait(new Callable<Boolean>() {
+                @Override
+                public Boolean call() throws Exception {
+                    return configurationPanel.saveEntitlements.isSelected();
+                }
+            });
+        } catch (InvocationTargetException | InterruptedException e) {
+            InternalError error = new InternalError();
+            error.initCause(e);
+            throw error;
+        }
+    }
+    
+    @Override
+    public void setSaveEntitlemens(final boolean save) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                configurationPanel.saveEntitlements.setSelected(save);
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/HostInformationPanel.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.SwingUtilities;
+
+import com.redhat.thermostat.client.core.views.HostInformationView;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.client.swing.SwingComponent;
+
+public class HostInformationPanel extends HostInformationView implements SwingComponent {
+
+    private JPanel visiblePanel;
+    private final JTabbedPane tabPane;
+
+    private int viewCount = 0;
+
+    public HostInformationPanel() {
+        super();
+        visiblePanel = new JPanel();
+        visiblePanel.setLayout(new BorderLayout());
+        tabPane = new JTabbedPane();
+        visiblePanel.add(tabPane);
+    }
+
+    @Override
+    public void addChildView(final String title, final UIComponent view) {
+        if (view instanceof SwingComponent) {
+            final SwingComponent component = (SwingComponent)view;
+            SwingUtilities.invokeLater(new Runnable() {
+                @Override
+                public void run() {
+                    tabPane.insertTab(title, null, component.getUiComponent(), null, viewCount);
+                    viewCount++;
+                }
+                
+            });
+        }
+    }
+
+    @Override
+    public void removeChildView(final String title) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                for (int i = 0; i < viewCount; i++) {
+                    if (tabPane.getTitleAt(i).equals(title)) {
+                        tabPane.remove(i);
+                        return;
+                    }
+                }
+            }
+        });
+    }
+
+    @Override
+    public Component getUiComponent() {
+        return visiblePanel;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/MemorySpacePanel.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import javax.swing.GroupLayout;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JProgressBar;
+import javax.swing.LayoutStyle.ComponentPlacement;
+
+import com.redhat.thermostat.client.swing.IconResource;
+
+
+public class MemorySpacePanel extends JPanel {
+
+    private final JProgressBar percentagePanel;
+    private final JLabel additionalDetailsIcon;
+    private final JLabel lblUsed;
+    private final JLabel lblAvailable;
+
+    public MemorySpacePanel(String regionName) {
+        JLabel lblRegionName = new JLabel(regionName);
+
+        percentagePanel = new JProgressBar(0, 100);
+
+        additionalDetailsIcon = new JLabel(IconResource.ARROW_RIGHT.getIcon());
+
+        lblUsed = new JLabel("${USED}");
+        lblAvailable = new JLabel("${AVAILABLE}");
+
+        GroupLayout groupLayout = new GroupLayout(this);
+        groupLayout.setHorizontalGroup(
+            groupLayout.createParallelGroup(Alignment.LEADING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+                        .addComponent(lblRegionName)
+                        .addGroup(groupLayout.createSequentialGroup()
+                            .addGap(12)
+                            .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+                                .addComponent(percentagePanel, GroupLayout.DEFAULT_SIZE, 574, Short.MAX_VALUE)
+                                .addGroup(groupLayout.createSequentialGroup()
+                                    .addComponent(lblUsed)
+                                    .addPreferredGap(ComponentPlacement.RELATED, 441, Short.MAX_VALUE)
+                                    .addComponent(lblAvailable)))))
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addComponent(additionalDetailsIcon)
+                    .addContainerGap())
+        );
+        groupLayout.setVerticalGroup(
+            groupLayout.createParallelGroup(Alignment.LEADING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addComponent(lblRegionName)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+                        .addComponent(additionalDetailsIcon, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                        .addComponent(percentagePanel, GroupLayout.DEFAULT_SIZE, 44, Short.MAX_VALUE))
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
+                        .addComponent(lblUsed)
+                        .addComponent(lblAvailable))
+                    .addGap(5))
+        );
+        setLayout(groupLayout);
+    }
+
+
+    public void updateRegionData(int percentageUsed, String currentlyUsed, String currentlyAvailable, String allocatable) {
+        percentagePanel.setValue(percentageUsed);
+
+        lblUsed.setText(currentlyUsed);
+        lblAvailable.setText(currentlyAvailable);
+        additionalDetailsIcon.setToolTipText(allocatable);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SummaryPanel.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import java.awt.Component;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.AbstractListModel;
+import javax.swing.GroupLayout;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.LayoutStyle.ComponentPlacement;
+import javax.swing.ListModel;
+import javax.swing.SwingUtilities;
+import javax.swing.text.JTextComponent;
+
+import com.redhat.thermostat.client.core.views.SummaryView;
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.swing.ComponentVisibleListener;
+import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.client.swing.components.SectionHeader;
+import com.redhat.thermostat.client.swing.components.ValueField;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.Translate;
+
+public class SummaryPanel extends SummaryView implements SwingComponent {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private JPanel visiblePanel;
+    
+    private final JTextComponent totalMonitoredHosts;
+    private final JTextComponent totalMonitoredVms;
+
+    private final List<String> issuesList;
+
+    public SummaryPanel() {
+        super();
+        visiblePanel = new JPanel();
+        JLabel lblHomepanel = new SectionHeader(translator.localize(LocaleResources.HOME_PANEL_SECTION_SUMMARY));
+
+        JLabel lblTotalHosts = new JLabel(translator.localize(LocaleResources.HOME_PANEL_TOTAL_MACHINES));
+
+        totalMonitoredHosts = new ValueField("${TOTAL_MONITORED_HOSTS}");
+
+        JLabel lblTotal = new JLabel(translator.localize(LocaleResources.HOME_PANEL_TOTAL_JVMS));
+
+        totalMonitoredVms = new ValueField("${TOTAL_MONITORED_VMS}");
+
+        JLabel lblIssues = new SectionHeader(translator.localize(LocaleResources.HOME_PANEL_SECTION_ISSUES));
+
+        JScrollPane scrollPane = new JScrollPane();
+
+        GroupLayout groupLayout = new GroupLayout(visiblePanel);
+        groupLayout.setHorizontalGroup(
+            groupLayout.createParallelGroup(Alignment.TRAILING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+                        .addGroup(groupLayout.createSequentialGroup()
+                            .addContainerGap()
+                            .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+                                .addComponent(lblHomepanel)
+                                .addGroup(groupLayout.createSequentialGroup()
+                                    .addGap(12)
+                                    .addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
+                                        .addComponent(lblTotal)
+                                        .addComponent(lblTotalHosts))
+                                    .addGap(18)
+                                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+                                        .addComponent(totalMonitoredVms, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                        .addComponent(totalMonitoredHosts, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+                                .addComponent(lblIssues)))
+                        .addGroup(groupLayout.createSequentialGroup()
+                            .addGap(24)
+                            .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+                    .addContainerGap())
+        );
+        groupLayout.setVerticalGroup(
+            groupLayout.createParallelGroup(Alignment.LEADING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addComponent(lblHomepanel)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
+                        .addComponent(lblTotalHosts)
+                        .addComponent(totalMonitoredHosts, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
+                        .addComponent(lblTotal)
+                        .addComponent(totalMonitoredVms, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                    .addGap(18)
+                    .addComponent(lblIssues)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .addContainerGap())
+        );
+
+        issuesList = new ArrayList<>();
+        ListModel<Object> issuesListModel = new IssuesListModel(issuesList);
+        JList<Object> issuesList = new JList<>();
+        issuesList.setModel(issuesListModel);
+        scrollPane.setViewportView(issuesList);
+        visiblePanel.setLayout(groupLayout);
+
+        visiblePanel.addHierarchyListener(new ComponentVisibleListener() {
+            @Override
+            public void componentShown(Component component) {
+                notifier.fireAction(Action.VISIBLE);
+            }
+
+            @Override
+            public void componentHidden(Component component) {
+                notifier.fireAction(Action.HIDDEN);
+            }
+        });
+    }
+
+    @Override
+    public void addActionListener(ActionListener<Action> listener) {
+        notifier.addActionListener(listener);
+    }
+
+    @Override
+    public void removeActionListener(ActionListener<Action> listener) {
+        notifier.removeActionListener(listener);
+    }
+
+    @Override
+    public void setTotalHosts(final String count) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                totalMonitoredHosts.setText(count);
+            }
+        });
+    }
+
+    @Override
+    public void setTotalVms(final String count) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                totalMonitoredVms.setText(count);
+            }
+        });
+    }
+
+    @Override
+    public Component getUiComponent() {
+        return visiblePanel;
+    }
+
+    private static class IssuesListModel extends AbstractListModel<Object> {
+
+        private static final long serialVersionUID = 7131506292620902850L;
+
+        private List<? extends Object> delegate;
+
+        private String emptyElement = translator.localize(LocaleResources.HOME_PANEL_NO_ISSUES);
+
+        public IssuesListModel(List<? extends Object> actualList) {
+            this.delegate = actualList;
+            // TODO observe the delegate for changes
+        }
+
+        @Override
+        public int getSize() {
+            if (delegate.isEmpty()) {
+                return 1;
+            }
+            return delegate.size();
+        }
+
+        @Override
+        public Object getElementAt(int index) {
+            if (delegate.isEmpty()) {
+                return emptyElement;
+            }
+            return delegate.get(index);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SwingAgentInformationViewProvider.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import com.redhat.thermostat.client.core.views.AgentInformationDisplayView;
+import com.redhat.thermostat.client.core.views.AgentInformationViewProvider;
+
+public class SwingAgentInformationViewProvider implements
+        AgentInformationViewProvider {
+
+    @Override
+    public AgentInformationDisplayView createView() {
+        return new AgentInformationDisplayFrame();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SwingClientConfigurationViewProvider.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import com.redhat.thermostat.client.core.views.ClientConfigViewProvider;
+import com.redhat.thermostat.client.core.views.ClientConfigurationView;
+
+public class SwingClientConfigurationViewProvider implements
+        ClientConfigViewProvider {
+
+    @Override
+    public ClientConfigurationView createView() {
+        return new ClientConfigurationSwing();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SwingHostInformationViewProvider.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import com.redhat.thermostat.client.core.views.HostInformationView;
+import com.redhat.thermostat.client.core.views.HostInformationViewProvider;
+
+public class SwingHostInformationViewProvider implements HostInformationViewProvider {
+
+    @Override
+    public HostInformationView createView() {
+        return new HostInformationPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SwingSummaryViewProvider.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import com.redhat.thermostat.client.core.views.SummaryView;
+import com.redhat.thermostat.client.core.views.SummaryViewProvider;
+
+public class SwingSummaryViewProvider implements SummaryViewProvider {
+
+    @Override
+    public SummaryView createView() {
+        return new SummaryPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/SwingVmInformationViewProvider.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import com.redhat.thermostat.client.core.views.VmInformationView;
+import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
+
+public class SwingVmInformationViewProvider implements VmInformationViewProvider {
+
+    @Override
+    public VmInformationView createView() {
+        return new VmInformationPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/views/VmInformationPanel.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.client.core.views.VmInformationView;
+import com.redhat.thermostat.client.swing.SwingComponent;
+
+public class VmInformationPanel extends VmInformationView implements SwingComponent {
+
+    private final JTabbedPane tabPane = new JTabbedPane();
+    private JPanel visiblePanel;
+
+    private int tabCount = 0;
+
+    public VmInformationPanel() {
+        super();
+        visiblePanel = new JPanel();
+        visiblePanel.setLayout(new BorderLayout());
+        tabPane.setName("tabPane");
+        visiblePanel.add(tabPane);
+    }
+
+    @Override
+    public void addChildView(String title, UIComponent view) {
+        if (view instanceof SwingComponent) {
+            SwingComponent panel = (SwingComponent)view;
+            tabPane.insertTab(title, null, panel.getUiComponent(), null, tabCount);
+            tabCount++;
+        }
+    }
+
+    public Component getUiComponent() {
+        return visiblePanel;
+    }
+
+    @Override
+    public int getSelectedChildID() {
+        return tabPane.getSelectedIndex();
+    }
+
+    @Override
+    public boolean selectChildID(int id) {
+        if (tabPane.getComponentCount() > id) {
+            tabPane.setSelectedIndex(id);
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public int getNumChildren() {
+        return tabPane.getComponentCount();
+    }
+}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/AgentInformationDisplayFrame.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,477 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import java.awt.BorderLayout;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import javax.swing.DefaultListModel;
-import javax.swing.GroupLayout;
-import javax.swing.GroupLayout.Alignment;
-import javax.swing.JButton;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.JSplitPane;
-import javax.swing.JTable;
-import javax.swing.LayoutStyle.ComponentPlacement;
-import javax.swing.ListSelectionModel;
-import javax.swing.SwingUtilities;
-import javax.swing.event.ListSelectionEvent;
-import javax.swing.event.ListSelectionListener;
-import javax.swing.table.DefaultTableModel;
-
-import com.redhat.thermostat.client.core.views.AgentInformationDisplayView;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.client.swing.components.LabelField;
-import com.redhat.thermostat.client.swing.components.SectionHeader;
-import com.redhat.thermostat.client.swing.components.ValueField;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.locale.Translate;
-
-public class AgentInformationDisplayFrame extends AgentInformationDisplayView {
-
-    private static final Translate<LocaleResources> translate = LocaleResources.createLocalizer();
-
-    private static final String[] BACKEND_TABLE_COLUMN_NAMES = new String[] {
-        translate.localize(LocaleResources.AGENT_INFO_BACKEND_NAME_COLUMN),
-        translate.localize(LocaleResources.AGENT_INFO_BACKEND_STATUS_COLUMN),
-    };
-
-    private final CopyOnWriteArrayList<ActionListener<ConfigurationAction>> listeners = new CopyOnWriteArrayList<>();
-
-    private final JFrame frame;
-
-    private final ConfigurationCompleteListener configurationComplete;
-    private final AgentChangedListener agentChanged;
-    private final WindowClosingListener windowListener;
-
-    private final JButton closeButton;
-
-    private final JList<String> agentList;
-    private final DefaultListModel<String> listModel;
-
-    private final ValueField currentAgentName;
-    private final ValueField currentAgentId;
-    private final ValueField currentAgentCommandAddress;
-    private final ValueField currentAgentStartTime;
-    private final ValueField currentAgentStopTime;
-
-    private final JTable backendsTable;
-    private final DefaultTableModel backendsTableModel;
-    private final ValueField backendDescription;
-
-    public AgentInformationDisplayFrame() {
-        assertInEDT();
-
-        configurationComplete = new ConfigurationCompleteListener();
-        agentChanged = new AgentChangedListener();
-        windowListener = new WindowClosingListener();
-
-        frame = new JFrame();
-        frame.setTitle(translate.localize(LocaleResources.AGENT_INFO_WINDOW_TITLE));
-        frame.addWindowListener(windowListener);
-
-        closeButton = new JButton(translate.localize(LocaleResources.BUTTON_CLOSE));
-        closeButton.addActionListener(configurationComplete);
-        closeButton.setName("close");
-
-        JSplitPane splitPane = new JSplitPane();
-        splitPane.setResizeWeight(0.35);
-
-        GroupLayout mainLayout = new GroupLayout(frame.getContentPane());
-        mainLayout.setHorizontalGroup(
-            mainLayout.createParallelGroup(Alignment.TRAILING)
-                .addGroup(mainLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addGroup(mainLayout.createParallelGroup(Alignment.TRAILING)
-                        .addComponent(splitPane, GroupLayout.DEFAULT_SIZE, 664, Short.MAX_VALUE)
-                        .addComponent(closeButton))
-                    .addContainerGap()));
-
-        mainLayout.setVerticalGroup(
-            mainLayout.createParallelGroup(Alignment.TRAILING)
-                .addGroup(mainLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addComponent(splitPane, GroupLayout.DEFAULT_SIZE, 472, Short.MAX_VALUE)
-                    .addPreferredGap(ComponentPlacement.UNRELATED)
-                    .addComponent(closeButton)
-                    .addContainerGap()));
-
-        JPanel agentListPanel = new JPanel();
-        splitPane.setLeftComponent(agentListPanel);
-
-        JLabel agentLabel = new JLabel(translate.localize(LocaleResources.AGENT_INFO_AGENTS_LIST));
-
-        JScrollPane scrollPane = new JScrollPane();
-
-        listModel = new DefaultListModel<String>();
-        agentList = new JList<String>(listModel);
-        agentList.setName("agentList");
-        agentList.addListSelectionListener(agentChanged);
-        agentListPanel.setLayout(new BorderLayout());
-
-        scrollPane.setViewportView(agentList);
-        agentListPanel.add(scrollPane);
-        agentListPanel.add(agentLabel, BorderLayout.NORTH);
-
-        JPanel agentConfigurationPanel = new JPanel();
-        splitPane.setRightComponent(agentConfigurationPanel);
-
-        SectionHeader agentSectionTitle = new SectionHeader(translate.localize(LocaleResources.AGENT_INFO_AGENT_SECTION_TITLE));
-
-        LabelField agentNameLabel = new LabelField(translate.localize(LocaleResources.AGENT_INFO_AGENT_NAME_LABEL));
-        LabelField agentIdLabel = new LabelField(translate.localize(LocaleResources.AGENT_INFO_AGENT_ID_LABEL));
-        LabelField agentConfigurationAddressLabel = new LabelField(translate.localize(LocaleResources.AGENT_INFO_AGENT_COMMAND_ADDRESS_LABEL));
-        LabelField agentStartTimeLabel = new LabelField(translate.localize(LocaleResources.AGENT_INFO_AGENT_START_TIME_LABEL));
-        LabelField agentStopTimeLabel = new LabelField(translate.localize(LocaleResources.AGENT_INFO_AGENT_STOP_TIME_LABEL));
-
-        String notAvailable = translate.localize(LocaleResources.INFORMATION_NOT_AVAILABLE);
-
-        currentAgentName = new ValueField(notAvailable);
-        currentAgentName.setName("agentName");
-        currentAgentId = new ValueField(notAvailable);
-        currentAgentId.setName("agentId");
-        currentAgentCommandAddress = new ValueField(notAvailable);
-        currentAgentCommandAddress.setName("commandAddress");
-        currentAgentStartTime = new ValueField(notAvailable);
-        currentAgentStartTime.setName("startTime");
-        currentAgentStopTime = new ValueField(notAvailable);
-        currentAgentStopTime.setName("stopTime");
-
-        SectionHeader backendSectionTitle = new SectionHeader(translate.localize(LocaleResources.AGENT_INFO_BACKENDS_SECTION_TITLE));
-
-        backendsTableModel = new BackendsTableModel();
-        backendsTableModel.setColumnIdentifiers(BACKEND_TABLE_COLUMN_NAMES);
-
-        backendsTable = new JTable(backendsTableModel);
-        backendsTable.setName("backends");
-        backendsTable.setCellSelectionEnabled(false);
-        backendsTable.setColumnSelectionAllowed(false);
-        backendsTable.setRowSelectionAllowed(true);
-        backendsTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-        backendsTable.getSelectionModel().addListSelectionListener(new BackendSelectionListener());
-
-        JScrollPane backendsTableScollPane = new JScrollPane(backendsTable);
-
-        JLabel backendDescriptionLabel = new JLabel(translate.localize(LocaleResources.AGENT_INFO_BACKEND_DESCRIPTION_LABEL));
-        backendDescription = new ValueField(notAvailable);
-        backendDescription.setName("backendDescription");
-
-        GroupLayout agentConfigurationPanelLayout = new GroupLayout(agentConfigurationPanel);
-        agentConfigurationPanelLayout.setHorizontalGroup(
-            agentConfigurationPanelLayout.createParallelGroup()
-                .addComponent(agentSectionTitle, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addGroup(agentConfigurationPanelLayout.createSequentialGroup()
-                    .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.LEADING, true)
-                        .addComponent(agentNameLabel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                        .addComponent(agentIdLabel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                        .addComponent(agentConfigurationAddressLabel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                        .addComponent(agentStartTimeLabel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                        .addComponent(agentStopTimeLabel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
-                    .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.LEADING, true)
-                        .addComponent(currentAgentName, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
-                        .addComponent(currentAgentId, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
-                        .addComponent(currentAgentCommandAddress, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
-                        .addComponent(currentAgentStartTime, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
-                        .addComponent(currentAgentStopTime, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)))
-                .addComponent(backendSectionTitle, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
-                .addComponent(backendsTableScollPane, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
-                .addComponent(backendDescriptionLabel, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                .addComponent(backendDescription, 0, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE));
-
-        agentConfigurationPanelLayout.setVerticalGroup(
-            agentConfigurationPanelLayout.createSequentialGroup()
-                .addComponent(agentSectionTitle)
-                .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.BASELINE, false)
-                    .addComponent(agentNameLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                    .addComponent(currentAgentName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.BASELINE, false)
-                    .addComponent(agentIdLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                    .addComponent(currentAgentId, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.BASELINE, false)
-                    .addComponent(agentConfigurationAddressLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                    .addComponent(currentAgentCommandAddress, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.BASELINE, false)
-                    .addComponent(agentStartTimeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                    .addComponent(currentAgentStartTime, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                .addGroup(agentConfigurationPanelLayout.createParallelGroup(Alignment.BASELINE, false)
-                    .addComponent(agentStopTimeLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                    .addComponent(currentAgentStopTime, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                .addComponent(backendSectionTitle)
-                .addComponent(backendsTableScollPane)
-                .addComponent(backendDescriptionLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE)
-                .addComponent(backendDescription, 30, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE));
-
-        agentConfigurationPanelLayout.setAutoCreateGaps(true);
-        agentConfigurationPanelLayout.setAutoCreateContainerGaps(true);
-        agentConfigurationPanel.setLayout(agentConfigurationPanelLayout);
-
-        frame.getContentPane().setLayout(mainLayout);
-
-    }
-
-    @Override
-    public void addConfigurationListener(ActionListener<ConfigurationAction> listener) {
-        listeners.add(listener);
-    }
-
-    @Override
-    public void removeConfigurationListener(ActionListener<ConfigurationAction> listener) {
-        listeners.remove(listener);
-    }
-
-    @Override
-    public void addAgent(final String agentName) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                listModel.addElement(agentName);
-                if (agentList.getSelectedIndex() == -1) {
-                    agentList.setSelectedIndex(0);
-                }
-            }
-        });
-    }
-
-    @Override
-    public String getSelectedAgent() {
-        assertInEDT();
-        return agentList.getSelectedValue();
-    }
-
-    @Override
-    public void clearAllAgents() {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                listModel.clear();
-            }
-        });
-    }
-
-    @Override
-    public void setSelectedAgentName(final String agentName) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                currentAgentName.setText(agentName);
-            }
-        });
-    }
-
-    @Override
-    public void setSelectedAgentId(final String agentId) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                currentAgentId.setText(agentId);
-            }
-        });
-    }
-
-    @Override
-    public void setSelectedAgentCommandAddress(final String address) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                currentAgentCommandAddress.setText(address);
-            }
-        });
-    }
-
-    @Override
-    public void setSelectedAgentStartTime(final String startTime) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                currentAgentStartTime.setText(startTime);
-            }
-        });
-    }
-
-    @Override
-    public void setSelectedAgentStopTime(final String stopTime) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                currentAgentStopTime.setText(stopTime);
-            }
-        });
-    }
-
-    @Override
-    public void setSelectedAgentBackendStatus(final Map<String, String> backendStatus) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                int i = 0;
-                for (Entry<String, String> entry : backendStatus.entrySet()) {
-                    String backendName = entry.getKey();
-                    String status = entry.getValue();
-                    int rowCount = backendsTableModel.getRowCount();
-                    if (i >= rowCount) {
-                        Object[] rowData = new String[] { backendName, status };
-                        backendsTableModel.insertRow(i, rowData);
-                    } else {
-                        backendsTableModel.setValueAt(backendName, i, 0);
-                        backendsTableModel.setValueAt(status, i, 1);
-                    }
-                    i++;
-                }
-
-                if (backendsTable.getRowCount() > 0 && backendsTable.getSelectedRow() == -1) {
-                    backendsTable.setRowSelectionInterval(0, 0);
-                }
-            }
-        });
-    }
-
-    @Override
-    public void setSelectedAgentBackendDescription(final String description) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                backendDescription.setText(description);
-            }
-        });
-    }
-
-    @Override
-    public void showDialog() {
-        assertInEDT();
-
-        frame.pack();
-        frame.setVisible(true);
-
-        agentList.setSelectedIndex(0);
-    }
-
-    @Override
-    public void hideDialog() {
-        assertInEDT();
-
-        frame.setVisible(false);
-        frame.dispose();
-    }
-
-    /** This is for tests only */
-    JFrame getFrame() {
-        return frame;
-    }
-
-    private void fireAction(ActionEvent<ConfigurationAction> actionEvent) {
-        for (ActionListener<ConfigurationAction> l : listeners) {
-            l.actionPerformed(actionEvent);
-        }
-    }
-
-    private static void assertInEDT() {
-        if (!SwingUtilities.isEventDispatchThread()) {
-            throw new IllegalStateException("must be called from within the swing EDT");
-        }
-    }
-
-    private class ConfigurationCompleteListener implements java.awt.event.ActionListener {
-        @Override
-        public void actionPerformed(java.awt.event.ActionEvent e) {
-            Object source = e.getSource();
-            if (source == closeButton) {
-                fireAction(new ActionEvent<>(AgentInformationDisplayFrame.this, ConfigurationAction.CLOSE));
-            }
-        }
-    }
-
-    private class WindowClosingListener extends WindowAdapter {
-        @Override
-        public void windowClosing(WindowEvent e) {
-            fireAction(new ActionEvent<>(AgentInformationDisplayFrame.this, ConfigurationAction.CLOSE));
-        }
-    }
-
-    private class AgentChangedListener implements ListSelectionListener {
-        @Override
-        public void valueChanged(ListSelectionEvent e) {
-            if (e.getSource() == agentList) {
-                if (e.getValueIsAdjusting()) {
-                    return;
-                }
-                fireAction(new ActionEvent<>(AgentInformationDisplayFrame.this, ConfigurationAction.SWITCH_AGENT));
-            } else {
-                throw new IllegalStateException("unknown trigger");
-            }
-        }
-    }
-
-    private class BackendSelectionListener implements ListSelectionListener {
-
-        @Override
-        public void valueChanged(ListSelectionEvent e) {
-            if (e.getValueIsAdjusting()) {
-                return;
-            }
-
-            ListSelectionModel model = (ListSelectionModel) e.getSource();
-            int rowIndex = model.getMinSelectionIndex();
-            String backendName = (String) backendsTableModel.getValueAt(rowIndex, 0);
-            ActionEvent<ConfigurationAction> event = new ActionEvent<>(AgentInformationDisplayFrame.this,
-                    ConfigurationAction.SHOW_BACKEND_DESCRIPTION);
-            event.setPayload(backendName);
-            fireAction(event);
-        }
-
-    }
-    
-    private class BackendsTableModel extends DefaultTableModel {
-
-        private static final long serialVersionUID = 8635399933525019537L;
-
-        @Override
-        public boolean isCellEditable(int row, int column) {
-            // Not editable
-            return false;
-        }
-    };
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/ClientConfigurationPanel.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,137 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import javax.swing.GroupLayout;
-import javax.swing.GroupLayout.Alignment;
-import javax.swing.JCheckBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JPasswordField;
-import javax.swing.JTextField;
-import javax.swing.LayoutStyle.ComponentPlacement;
-import javax.swing.border.TitledBorder;
-
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.locale.Translate;
-
-@SuppressWarnings("serial")
-class ClientConfigurationPanel extends JPanel {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    final JTextField storageUrl = new JTextField();
-    final JTextField userName = new JTextField();
-    final JPasswordField password = new JPasswordField();
-    
-    final JCheckBox saveEntitlements;
-    
-    public ClientConfigurationPanel() {
-        setBorder(new TitledBorder(null,
-                  translator.localize(LocaleResources.CLIENT_PREFS_CONNECTION),
-                  TitledBorder.LEFT, TitledBorder.TOP, null, null));
-
-        JLabel storageURLText = new JLabel(translator.localize(LocaleResources.CLIENT_PREFS_STORAGE_URL));
-        storageURLText.setName("");
-        
-        storageUrl.setColumns(10);
-        storageUrl.setName("connectionUrl");
-        
-        JLabel userNameText = new JLabel(translator.localize(LocaleResources.CLIENT_PREFS_STORAGE_USERNAME));
-        userNameText.setName("userNameText");
-        
-        userName.setName("username");
-        userName.setColumns(10);
-        
-        JLabel passowrdText = new JLabel("Password");
-        passowrdText.setName("passwordText");
-        
-        password.setName("password");
-        password.setColumns(10);
-        
-        saveEntitlements = new JCheckBox(translator.localize(LocaleResources.CLIENT_PREFS_STORAGE_SAVE_ENTITLEMENTS));
-        saveEntitlements.setName("saveEntitlements");
-        saveEntitlements.setSelected(false);
-
-        GroupLayout groupLayout = new GroupLayout(this);
-        groupLayout.setHorizontalGroup(
-            groupLayout.createParallelGroup(Alignment.TRAILING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
-                        .addComponent(saveEntitlements)
-                        .addGroup(groupLayout.createSequentialGroup()
-                            .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
-                                .addComponent(storageURLText, GroupLayout.PREFERRED_SIZE, 83, GroupLayout.PREFERRED_SIZE)
-                                .addGroup(groupLayout.createParallelGroup(Alignment.LEADING, false)
-                                    .addComponent(passowrdText, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                                    .addComponent(userNameText, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
-                            .addPreferredGap(ComponentPlacement.UNRELATED)
-                            .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
-                                .addComponent(userName, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 326, Short.MAX_VALUE)
-                                .addComponent(storageUrl, GroupLayout.DEFAULT_SIZE, 326, Short.MAX_VALUE)
-                                .addComponent(password, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 326, Short.MAX_VALUE))))
-                    .addGap(24))
-        );
-        groupLayout.setVerticalGroup(
-            groupLayout.createParallelGroup(Alignment.LEADING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
-                        .addComponent(storageURLText)
-                        .addComponent(storageUrl, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
-                        .addGroup(groupLayout.createSequentialGroup()
-                            .addGap(8)
-                            .addComponent(userNameText))
-                        .addGroup(groupLayout.createSequentialGroup()
-                            .addPreferredGap(ComponentPlacement.RELATED)
-                            .addComponent(userName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
-                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
-                        .addGroup(groupLayout.createSequentialGroup()
-                            .addGap(8)
-                            .addComponent(passowrdText))
-                        .addGroup(groupLayout.createSequentialGroup()
-                            .addPreferredGap(ComponentPlacement.RELATED)
-                            .addComponent(password, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)))
-                    .addPreferredGap(ComponentPlacement.UNRELATED)
-                    .addComponent(saveEntitlements)
-                    .addContainerGap(15, Short.MAX_VALUE))
-        );
-        setLayout(groupLayout);
-    }
-}
\ No newline at end of file
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/ClientConfigurationSwing.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,263 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import java.awt.Frame;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.lang.reflect.InvocationTargetException;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import javax.swing.JDialog;
-import javax.swing.JOptionPane;
-import javax.swing.SwingUtilities;
-import javax.swing.WindowConstants;
-
-import com.redhat.thermostat.client.core.views.ClientConfigurationView;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.client.swing.EdtHelper;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.locale.Translate;
-
-public class ClientConfigurationSwing implements ClientConfigurationView {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private final WindowClosingListener windowClosingListener;
-
-    private final ClientConfigurationPanel configurationPanel;
-
-    private final CopyOnWriteArrayList<ActionListener<Action>> listeners = new CopyOnWriteArrayList<>();
-
-    private JDialog dialog;
-
-    public ClientConfigurationSwing() {
-        assertInEDT();
-
-        windowClosingListener = new WindowClosingListener();
-        configurationPanel = new ClientConfigurationPanel();
-        
-        final JOptionPane optionPane = new JOptionPane(configurationPanel);
-        optionPane.setOptionType(JOptionPane.OK_CANCEL_OPTION);
-        optionPane.addPropertyChangeListener(new PropertyChangeListener() {
-            @Override
-            public void propertyChange(PropertyChangeEvent evt) {
-                String propertyName = evt.getPropertyName();
-                if ((evt.getSource() == optionPane) &&
-                    (propertyName.equals(JOptionPane.VALUE_PROPERTY))) {
-                    if (dialog.isVisible()) {
-                        if (evt.getNewValue().equals(JOptionPane.OK_OPTION)) {
-                            fireAction(new ActionEvent<>(ClientConfigurationSwing.this, Action.CLOSE_ACCEPT));
-                        } else if (evt.getNewValue().equals(JOptionPane.CANCEL_OPTION)) {
-                            fireAction(new ActionEvent<>(ClientConfigurationSwing.this, Action.CLOSE_CANCEL));
-                        }
-                    }
-                }
-            }
-        });
-
-        dialog = new JDialog((Frame) null, translator.localize(LocaleResources.CLIENT_PREFS_WINDOW_TITLE));
-        dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
-        dialog.setContentPane(optionPane);
-        dialog.addWindowListener(windowClosingListener);
-    }
-
-    JDialog getDialog() {
-        return dialog;
-    }
-
-    @Override
-    public void showDialog() {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                dialog.pack();
-                dialog.setVisible(true);
-            }
-        });
-    }
-
-    @Override
-    public void hideDialog() {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                dialog.setVisible(false);
-                dialog.dispose();
-                dialog = null;
-            }
-
-        });
-    }
-
-    @Override
-    public String getConnectionUrl() {
-        try {
-            return new EdtHelper().callAndWait(new Callable<String>() {
-                @Override
-                public String call() throws Exception {
-                    return configurationPanel.storageUrl.getText();
-                }
-            });
-        } catch (InvocationTargetException | InterruptedException e) {
-            InternalError error = new InternalError();
-            error.initCause(e);
-            throw error;
-        }
-    }
-
-    @Override
-    public void setConnectionUrl(final String url) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                configurationPanel.storageUrl.setText(url);
-            }
-        });
-    }
-
-    @Override
-    public void addListener(ActionListener<Action> listener) {
-        listeners.add(listener);
-    }
-
-    @Override
-    public void removeListener(ActionListener<Action> listener) {
-        listeners.remove(listener);
-    }
-
-    private void fireAction(ActionEvent<Action> actionEvent) {
-        for (ActionListener<Action> listener: listeners) {
-            listener.actionPerformed(actionEvent);
-        }
-    }
-
-    private void assertInEDT() {
-        if (!SwingUtilities.isEventDispatchThread()) {
-            throw new IllegalStateException("must be invoked in the EDT");
-        }
-    }
-
-    class WindowClosingListener extends WindowAdapter {
-        @Override
-        public void windowClosing(WindowEvent e) {
-            fireAction(new ActionEvent<>(ClientConfigurationSwing.this, Action.CLOSE_CANCEL));
-        }
-    }
-
-    @Override
-    public void setPassword(final String password) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                configurationPanel.password.setText(password);
-            }
-        });
-    }
-    
-    @Override
-    public void setUserName(final String username) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                configurationPanel.userName.setText(username);
-            }
-        });
-    };
-    
-    @Override
-    public String getPassword() {
-        try {
-            return new EdtHelper().callAndWait(new Callable<String>() {
-                @Override
-                public String call() throws Exception {
-                    return configurationPanel.password.getText();
-                }
-            });
-        } catch (InvocationTargetException | InterruptedException e) {
-            InternalError error = new InternalError();
-            error.initCause(e);
-            throw error;
-        }
-    }
-    
-    @Override
-    public String getUserName() {
-        try {
-            return new EdtHelper().callAndWait(new Callable<String>() {
-                @Override
-                public String call() throws Exception {
-                    return configurationPanel.userName.getText();
-                }
-            });
-        } catch (InvocationTargetException | InterruptedException e) {
-            InternalError error = new InternalError();
-            error.initCause(e);
-            throw error;
-        }
-    }
-    
-    @Override
-    public boolean getSaveEntitlements() {
-        try {
-            return new EdtHelper().callAndWait(new Callable<Boolean>() {
-                @Override
-                public Boolean call() throws Exception {
-                    return configurationPanel.saveEntitlements.isSelected();
-                }
-            });
-        } catch (InvocationTargetException | InterruptedException e) {
-            InternalError error = new InternalError();
-            error.initCause(e);
-            throw error;
-        }
-    }
-    
-    @Override
-    public void setSaveEntitlemens(final boolean save) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                configurationPanel.saveEntitlements.setSelected(save);
-            }
-        });
-    }
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/HostInformationPanel.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-
-import javax.swing.JPanel;
-import javax.swing.JTabbedPane;
-import javax.swing.SwingUtilities;
-
-import com.redhat.thermostat.client.core.views.HostInformationView;
-import com.redhat.thermostat.client.core.views.UIComponent;
-import com.redhat.thermostat.client.swing.SwingComponent;
-
-public class HostInformationPanel extends HostInformationView implements SwingComponent {
-
-    private JPanel visiblePanel;
-    private final JTabbedPane tabPane;
-
-    private int viewCount = 0;
-
-    public HostInformationPanel() {
-        super();
-        visiblePanel = new JPanel();
-        visiblePanel.setLayout(new BorderLayout());
-        tabPane = new JTabbedPane();
-        visiblePanel.add(tabPane);
-    }
-
-    @Override
-    public void addChildView(final String title, final UIComponent view) {
-        if (view instanceof SwingComponent) {
-            final SwingComponent component = (SwingComponent)view;
-            SwingUtilities.invokeLater(new Runnable() {
-                @Override
-                public void run() {
-                    tabPane.insertTab(title, null, component.getUiComponent(), null, viewCount);
-                    viewCount++;
-                }
-                
-            });
-        }
-    }
-
-    @Override
-    public void removeChildView(final String title) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                for (int i = 0; i < viewCount; i++) {
-                    if (tabPane.getTitleAt(i).equals(title)) {
-                        tabPane.remove(i);
-                        return;
-                    }
-                }
-            }
-        });
-    }
-
-    @Override
-    public Component getUiComponent() {
-        return visiblePanel;
-    }
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/MemorySpacePanel.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import javax.swing.GroupLayout;
-import javax.swing.GroupLayout.Alignment;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JProgressBar;
-import javax.swing.LayoutStyle.ComponentPlacement;
-
-import com.redhat.thermostat.client.swing.IconResource;
-
-
-public class MemorySpacePanel extends JPanel {
-
-    private final JProgressBar percentagePanel;
-    private final JLabel additionalDetailsIcon;
-    private final JLabel lblUsed;
-    private final JLabel lblAvailable;
-
-    public MemorySpacePanel(String regionName) {
-        JLabel lblRegionName = new JLabel(regionName);
-
-        percentagePanel = new JProgressBar(0, 100);
-
-        additionalDetailsIcon = new JLabel(IconResource.ARROW_RIGHT.getIcon());
-
-        lblUsed = new JLabel("${USED}");
-        lblAvailable = new JLabel("${AVAILABLE}");
-
-        GroupLayout groupLayout = new GroupLayout(this);
-        groupLayout.setHorizontalGroup(
-            groupLayout.createParallelGroup(Alignment.LEADING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
-                        .addComponent(lblRegionName)
-                        .addGroup(groupLayout.createSequentialGroup()
-                            .addGap(12)
-                            .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
-                                .addComponent(percentagePanel, GroupLayout.DEFAULT_SIZE, 574, Short.MAX_VALUE)
-                                .addGroup(groupLayout.createSequentialGroup()
-                                    .addComponent(lblUsed)
-                                    .addPreferredGap(ComponentPlacement.RELATED, 441, Short.MAX_VALUE)
-                                    .addComponent(lblAvailable)))))
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addComponent(additionalDetailsIcon)
-                    .addContainerGap())
-        );
-        groupLayout.setVerticalGroup(
-            groupLayout.createParallelGroup(Alignment.LEADING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addComponent(lblRegionName)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
-                        .addComponent(additionalDetailsIcon, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                        .addComponent(percentagePanel, GroupLayout.DEFAULT_SIZE, 44, Short.MAX_VALUE))
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
-                        .addComponent(lblUsed)
-                        .addComponent(lblAvailable))
-                    .addGap(5))
-        );
-        setLayout(groupLayout);
-    }
-
-
-    public void updateRegionData(int percentageUsed, String currentlyUsed, String currentlyAvailable, String allocatable) {
-        percentagePanel.setValue(percentageUsed);
-
-        lblUsed.setText(currentlyUsed);
-        lblAvailable.setText(currentlyAvailable);
-        additionalDetailsIcon.setToolTipText(allocatable);
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SearchFieldSwingView.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,226 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Insets;
-import java.awt.event.ActionEvent;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
-import java.lang.reflect.InvocationTargetException;
-import java.util.concurrent.Callable;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import javax.swing.BorderFactory;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-import javax.swing.SwingUtilities;
-import javax.swing.event.DocumentEvent;
-import javax.swing.event.DocumentListener;
-import javax.swing.text.BadLocationException;
-import javax.swing.text.Document;
-
-import com.redhat.thermostat.client.core.views.SearchFieldView;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.client.swing.EdtHelper;
-import com.redhat.thermostat.client.swing.IconResource;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.ActionNotifier;
-import com.redhat.thermostat.common.locale.Translate;
-
-public class SearchFieldSwingView extends JPanel implements SearchFieldView {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private final ActionNotifier<SearchAction> notifier = new ActionNotifier<>(this);
-    private final JTextField searchField = new JTextField();
-
-    private final AtomicReference<String> searchText = new AtomicReference<String>("");
-    private final AtomicReference<String> label = new AtomicReference<>(translator.localize(LocaleResources.SEARCH_HINT));
-    private final AtomicBoolean labelDisplayed = new AtomicBoolean(true);
-
-    public SearchFieldSwingView() {
-        super(new BorderLayout());
-
-        // TODO move this icon inside the search field
-        JLabel searchIcon = new JLabel(IconResource.SEARCH.getIcon());
-        searchIcon.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
-
-        searchField.setText(label.get());
-        searchField.setName(VIEW_NAME);
-        /* the insets are so we can place the actual icon inside the searchField */
-        searchField.setMargin(new Insets(0, 0, 0, 30));
-
-        searchField.getDocument().addDocumentListener(new DocumentListener() {
-
-            private String previousText = searchText.get();
-
-            @Override
-            public void removeUpdate(DocumentEvent event) {
-                changed(event.getDocument());
-            }
-
-            @Override
-            public void insertUpdate(DocumentEvent event) {
-                changed(event.getDocument());
-            }
-
-            @Override
-            public void changedUpdate(DocumentEvent event) {
-                changed(event.getDocument());
-            }
-
-            private void changed(Document doc) {
-                if (!labelDisplayed.get()) {
-                    String filter = null;
-                    try {
-                        filter = doc.getText(0, doc.getLength());
-                    } catch (BadLocationException ble) {
-                        // ignore
-                    }
-
-                    searchText.set(filter);
-                    if (!(filter.equals(previousText))) {
-                        previousText = filter;
-                        fireViewAction(SearchAction.TEXT_CHANGED);
-                    }
-                }
-            }
-        });
-
-        final Color originalForegroundColor = searchField.getForeground();
-        searchField.addFocusListener(new FocusListener() {
-
-            @Override
-            public void focusLost(FocusEvent e) {
-                if (searchText.get().equals("")) {
-                    labelDisplayed.set(true);
-                    searchField.setForeground(Color.GRAY);
-                    searchField.setText(label.get());
-                }
-            }
-
-            @Override
-            public void focusGained(FocusEvent e) {
-                if (labelDisplayed.get()) {
-                    labelDisplayed.set(false);
-                    searchField.setForeground(originalForegroundColor);
-                    searchField.setText("");
-                }
-
-            }
-        });
-
-        final java.awt.event.ActionListener searchActionListener = new java.awt.event.ActionListener() {
-            @Override
-            public void actionPerformed(ActionEvent e) {
-                fireViewAction(SearchAction.PERFORM_SEARCH);
-            }
-        };
-
-        searchField.addActionListener(searchActionListener);
-
-        add(searchField);
-        add(searchIcon, BorderLayout.LINE_END);
-
-    }
-
-    @Override
-    public String getSearchText() {
-        try {
-            return new EdtHelper().callAndWait(new Callable<String>() {
-                @Override
-                public String call() throws Exception {
-                    return searchText.get();
-                }
-            });
-        } catch (InvocationTargetException | InterruptedException e) {
-            return null;
-        }
-    }
-
-    @Override
-    public void setSearchText(final String text) {
-        searchText.set(text);
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                searchField.setText(text);
-            }
-        });
-    }
-
-    @Override
-    public void setLabel(String label) {
-        this.label.set(label);
-        if (labelDisplayed.get()) {
-            SwingUtilities.invokeLater(new Runnable() {
-                @Override
-                public void run() {
-                    searchField.setText(SearchFieldSwingView.this.label.get());
-                }
-            });
-        }
-    }
-
-    @Override
-    public void setTooltip(final String tooltip) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                searchField.setToolTipText(tooltip);
-            }
-        });
-    }
-
-    @Override
-    public void addActionListener(ActionListener<SearchAction> listener) {
-        notifier.addActionListener(listener);
-    }
-
-    @Override
-    public void removeActionListener(ActionListener<SearchAction> listener) {
-        notifier.removeActionListener(listener);
-    }
-
-    private void fireViewAction(SearchAction action) {
-        notifier.fireAction(action);
-    }
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SummaryPanel.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,220 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import java.awt.Component;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.AbstractListModel;
-import javax.swing.GroupLayout;
-import javax.swing.GroupLayout.Alignment;
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.JScrollPane;
-import javax.swing.LayoutStyle.ComponentPlacement;
-import javax.swing.ListModel;
-import javax.swing.SwingUtilities;
-import javax.swing.text.JTextComponent;
-
-import com.redhat.thermostat.client.core.views.SummaryView;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.client.swing.ComponentVisibleListener;
-import com.redhat.thermostat.client.swing.SwingComponent;
-import com.redhat.thermostat.client.swing.components.SectionHeader;
-import com.redhat.thermostat.client.swing.components.ValueField;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.locale.Translate;
-
-public class SummaryPanel extends SummaryView implements SwingComponent {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private JPanel visiblePanel;
-    
-    private final JTextComponent totalMonitoredHosts;
-    private final JTextComponent totalMonitoredVms;
-
-    private final List<String> issuesList;
-
-    public SummaryPanel() {
-        super();
-        visiblePanel = new JPanel();
-        JLabel lblHomepanel = new SectionHeader(translator.localize(LocaleResources.HOME_PANEL_SECTION_SUMMARY));
-
-        JLabel lblTotalHosts = new JLabel(translator.localize(LocaleResources.HOME_PANEL_TOTAL_MACHINES));
-
-        totalMonitoredHosts = new ValueField("${TOTAL_MONITORED_HOSTS}");
-
-        JLabel lblTotal = new JLabel(translator.localize(LocaleResources.HOME_PANEL_TOTAL_JVMS));
-
-        totalMonitoredVms = new ValueField("${TOTAL_MONITORED_VMS}");
-
-        JLabel lblIssues = new SectionHeader(translator.localize(LocaleResources.HOME_PANEL_SECTION_ISSUES));
-
-        JScrollPane scrollPane = new JScrollPane();
-
-        GroupLayout groupLayout = new GroupLayout(visiblePanel);
-        groupLayout.setHorizontalGroup(
-            groupLayout.createParallelGroup(Alignment.TRAILING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
-                        .addGroup(groupLayout.createSequentialGroup()
-                            .addContainerGap()
-                            .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
-                                .addComponent(lblHomepanel)
-                                .addGroup(groupLayout.createSequentialGroup()
-                                    .addGap(12)
-                                    .addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
-                                        .addComponent(lblTotal)
-                                        .addComponent(lblTotalHosts))
-                                    .addGap(18)
-                                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
-                                        .addComponent(totalMonitoredVms, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                                        .addComponent(totalMonitoredHosts, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
-                                .addComponent(lblIssues)))
-                        .addGroup(groupLayout.createSequentialGroup()
-                            .addGap(24)
-                            .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
-                    .addContainerGap())
-        );
-        groupLayout.setVerticalGroup(
-            groupLayout.createParallelGroup(Alignment.LEADING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addComponent(lblHomepanel)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
-                        .addComponent(lblTotalHosts)
-                        .addComponent(totalMonitoredHosts, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
-                        .addComponent(lblTotal)
-                        .addComponent(totalMonitoredVms, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                    .addGap(18)
-                    .addComponent(lblIssues)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                    .addContainerGap())
-        );
-
-        issuesList = new ArrayList<>();
-        ListModel<Object> issuesListModel = new IssuesListModel(issuesList);
-        JList<Object> issuesList = new JList<>();
-        issuesList.setModel(issuesListModel);
-        scrollPane.setViewportView(issuesList);
-        visiblePanel.setLayout(groupLayout);
-
-        visiblePanel.addHierarchyListener(new ComponentVisibleListener() {
-            @Override
-            public void componentShown(Component component) {
-                notifier.fireAction(Action.VISIBLE);
-            }
-
-            @Override
-            public void componentHidden(Component component) {
-                notifier.fireAction(Action.HIDDEN);
-            }
-        });
-    }
-
-    @Override
-    public void addActionListener(ActionListener<Action> listener) {
-        notifier.addActionListener(listener);
-    }
-
-    @Override
-    public void removeActionListener(ActionListener<Action> listener) {
-        notifier.removeActionListener(listener);
-    }
-
-    @Override
-    public void setTotalHosts(final String count) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                totalMonitoredHosts.setText(count);
-            }
-        });
-    }
-
-    @Override
-    public void setTotalVms(final String count) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                totalMonitoredVms.setText(count);
-            }
-        });
-    }
-
-    @Override
-    public Component getUiComponent() {
-        return visiblePanel;
-    }
-
-    private static class IssuesListModel extends AbstractListModel<Object> {
-
-        private static final long serialVersionUID = 7131506292620902850L;
-
-        private List<? extends Object> delegate;
-
-        private String emptyElement = translator.localize(LocaleResources.HOME_PANEL_NO_ISSUES);
-
-        public IssuesListModel(List<? extends Object> actualList) {
-            this.delegate = actualList;
-            // TODO observe the delegate for changes
-        }
-
-        @Override
-        public int getSize() {
-            if (delegate.isEmpty()) {
-                return 1;
-            }
-            return delegate.size();
-        }
-
-        @Override
-        public Object getElementAt(int index) {
-            if (delegate.isEmpty()) {
-                return emptyElement;
-            }
-            return delegate.get(index);
-        }
-    }
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingAgentInformationViewProvider.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import com.redhat.thermostat.client.core.views.AgentInformationDisplayView;
-import com.redhat.thermostat.client.core.views.AgentInformationViewProvider;
-
-public class SwingAgentInformationViewProvider implements
-        AgentInformationViewProvider {
-
-    @Override
-    public AgentInformationDisplayView createView() {
-        return new AgentInformationDisplayFrame();
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingClientConfigurationViewProvider.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import com.redhat.thermostat.client.core.views.ClientConfigViewProvider;
-import com.redhat.thermostat.client.core.views.ClientConfigurationView;
-
-public class SwingClientConfigurationViewProvider implements
-        ClientConfigViewProvider {
-
-    @Override
-    public ClientConfigurationView createView() {
-        return new ClientConfigurationSwing();
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingHostInformationViewProvider.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import com.redhat.thermostat.client.core.views.HostInformationView;
-import com.redhat.thermostat.client.core.views.HostInformationViewProvider;
-
-public class SwingHostInformationViewProvider implements HostInformationViewProvider {
-
-    @Override
-    public HostInformationView createView() {
-        return new HostInformationPanel();
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingSummaryViewProvider.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import com.redhat.thermostat.client.core.views.SummaryView;
-import com.redhat.thermostat.client.core.views.SummaryViewProvider;
-
-public class SwingSummaryViewProvider implements SummaryViewProvider {
-
-    @Override
-    public SummaryView createView() {
-        return new SummaryPanel();
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingVmInformationViewProvider.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import com.redhat.thermostat.client.core.views.VmInformationView;
-import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
-
-public class SwingVmInformationViewProvider implements VmInformationViewProvider {
-
-    @Override
-    public VmInformationView createView() {
-        return new VmInformationPanel();
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/VmInformationPanel.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-
-import javax.swing.JPanel;
-import javax.swing.JTabbedPane;
-
-import com.redhat.thermostat.client.core.views.UIComponent;
-import com.redhat.thermostat.client.core.views.VmInformationView;
-import com.redhat.thermostat.client.swing.SwingComponent;
-
-public class VmInformationPanel extends VmInformationView implements SwingComponent {
-
-    private final JTabbedPane tabPane = new JTabbedPane();
-    private JPanel visiblePanel;
-
-    private int tabCount = 0;
-
-    public VmInformationPanel() {
-        super();
-        visiblePanel = new JPanel();
-        visiblePanel.setLayout(new BorderLayout());
-        tabPane.setName("tabPane");
-        visiblePanel.add(tabPane);
-    }
-
-    @Override
-    public void addChildView(String title, UIComponent view) {
-        if (view instanceof SwingComponent) {
-            SwingComponent panel = (SwingComponent)view;
-            tabPane.insertTab(title, null, panel.getUiComponent(), null, tabCount);
-            tabCount++;
-        }
-    }
-
-    public Component getUiComponent() {
-        return visiblePanel;
-    }
-
-    @Override
-    public int getSelectedChildID() {
-        return tabPane.getSelectedIndex();
-    }
-
-    @Override
-    public boolean selectChildID(int id) {
-        if (tabPane.getComponentCount() > id) {
-            tabPane.setSelectedIndex(id);
-            return true;
-        }
-        return false;
-    }
-
-    @Override
-    public int getNumChildren() {
-        return tabPane.getComponentCount();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/SearchFieldTest.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,216 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import java.awt.FlowLayout;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+
+import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner;
+
+import org.fest.swing.annotation.GUITest;
+import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
+import org.fest.swing.edt.GuiActionRunner;
+import org.fest.swing.edt.GuiTask;
+import org.fest.swing.fixture.FrameFixture;
+import org.fest.swing.fixture.JButtonFixture;
+import org.fest.swing.fixture.JTextComponentFixture;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import com.redhat.thermostat.client.swing.components.SearchField;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+
+@RunWith(CacioFESTRunner.class)
+public class SearchFieldTest {
+
+    private final String OTHER_COMPONENT_NAME = "other";
+
+    private JFrame frame;
+    private SearchField searchField;
+    private JButton otherComponent;
+    private FrameFixture frameFixture;
+
+    @BeforeClass
+    public static void setUpOnce() {
+        FailOnThreadViolationRepaintManager.install();
+    }
+
+    @Before
+    public void setUp() {
+        GuiActionRunner.execute(new GuiTask() {
+
+
+            @Override
+            protected void executeInEDT() throws Throwable {
+                frame = new JFrame();
+                frame.setLayout(new FlowLayout());
+                searchField = new SearchField();
+                frame.add(searchField);
+                otherComponent = new JButton();
+                otherComponent.setName(OTHER_COMPONENT_NAME);
+                frame.add(otherComponent);
+            }
+        });
+        frameFixture = new FrameFixture(frame);
+    }
+
+    @After
+    public void tearDown() {
+        frameFixture.cleanUp();
+        frameFixture = null;
+    }
+
+    @Test
+    public void verifyInitialSearchString() {
+        frameFixture.show();
+
+        assertEquals("", searchField.getSearchText());
+    }
+
+    @Category(GUITest.class)
+    @GUITest
+    @Test
+    public void verifyLabelShownByDefault() {
+        final String LABEL = "search label to help users";
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                searchField.setLabel(LABEL);            }
+        });
+
+        frameFixture.show();
+        JTextComponentFixture textBox = frameFixture.textBox(SearchField.VIEW_NAME);
+        assertEquals(LABEL, textBox.text());
+    }
+
+    @Category(GUITest.class)
+    @GUITest
+    @Test
+    public void verifyLabelHiddenAndShownProperly() {
+        final String LABEL = "search label to help users";
+        final String USER_TEXT = "java";
+
+        GuiActionRunner.execute(new GuiTask() {
+
+            @Override
+            protected void executeInEDT() throws Throwable {
+                searchField.setLabel(LABEL);
+            }
+        });
+
+        frameFixture.show();
+        JTextComponentFixture textBox = frameFixture.textBox(SearchField.VIEW_NAME);
+        assertEquals(LABEL, textBox.text());
+
+        textBox.enterText(USER_TEXT);
+
+        textBox.deleteText();
+
+        JButtonFixture button = frameFixture.button(OTHER_COMPONENT_NAME);
+        button.focus();
+
+        assertEquals(LABEL, textBox.text());
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void verifySearchTextTypedIsReturned() {
+        frameFixture.show();
+
+        final String SEARCH_TEXT = "test";
+        JTextComponentFixture textBox = frameFixture.textBox(SearchField.VIEW_NAME);
+        textBox.enterText(SEARCH_TEXT);
+        String actual = searchField.getSearchText();
+        assertEquals(SEARCH_TEXT, actual);
+    }
+
+    @Category(GUITest.class)
+    @GUITest
+    @Test
+    public void verifyTextSetIsShown() {
+        frameFixture.show();
+
+        final String SEARCH_TEXT = "test";
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                searchField.setSearchText(SEARCH_TEXT);
+            }
+        });
+        JTextComponentFixture textBox = frameFixture.textBox(SearchField.VIEW_NAME);
+        String actual = textBox.text();
+        assertEquals(SEARCH_TEXT, actual);
+    }
+
+    @Category(GUITest.class)
+    @GUITest
+    @Test
+    public void verifyListenersAreFiredOnTextEntry() {
+        frameFixture.show();
+
+        final String SEARCH_TEXT = "test";
+        ActionListener<SearchField.SearchAction> listener = mock(ActionListener.class);
+
+        JTextComponentFixture textBox = frameFixture.textBox(SearchField.VIEW_NAME);
+
+        searchField.addActionListener(listener);
+
+        textBox.enterText(SEARCH_TEXT);
+
+        verify(listener, times(SEARCH_TEXT.length())).actionPerformed(
+                new ActionEvent<SearchField.SearchAction>(searchField, SearchField.SearchAction.TEXT_CHANGED));
+
+        textBox.enterText("\n");
+
+        verify(listener).actionPerformed(
+                new ActionEvent<SearchField.SearchAction>(searchField, SearchField.SearchAction.PERFORM_SEARCH));
+
+    }
+
+}
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowTest.java	Fri Dec 21 15:35:21 2012 +0100
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowTest.java	Mon Jan 07 10:44:01 2013 -0500
@@ -73,9 +73,9 @@
 import org.junit.runner.RunWith;
 
 import com.redhat.thermostat.client.core.Filter;
-import com.redhat.thermostat.client.core.views.SearchFieldView;
 import com.redhat.thermostat.client.osgi.service.DecoratorProvider;
 import com.redhat.thermostat.client.osgi.service.MenuAction;
+import com.redhat.thermostat.client.swing.components.SearchField;
 import com.redhat.thermostat.client.swing.internal.MainView;
 import com.redhat.thermostat.client.swing.internal.MainWindow;
 import com.redhat.thermostat.client.ui.Decorator;
@@ -174,7 +174,7 @@
     public void testHostVMTreeFilterPropertySupport() {
         String SEARCH_TEXT = "test";
         frameFixture.show();
-        JTextComponentFixture hostVMTreeFilterField = frameFixture.textBox(SearchFieldView.VIEW_NAME);
+        JTextComponentFixture hostVMTreeFilterField = frameFixture.textBox(SearchField.VIEW_NAME);
         hostVMTreeFilterField.enterText(SEARCH_TEXT);
 
         verify(l, times(SEARCH_TEXT.length())).actionPerformed(new ActionEvent<MainView.Action>(window, MainView.Action.HOST_VM_TREE_FILTER));
@@ -338,7 +338,7 @@
     @Test
     public void testGetHostVMTreeFilter() {
         frameFixture.show();
-        JTextComponentFixture hostVMTreeFilterField = frameFixture.textBox(SearchFieldView.VIEW_NAME);
+        JTextComponentFixture hostVMTreeFilterField = frameFixture.textBox(SearchField.VIEW_NAME);
         hostVMTreeFilterField.enterText("test");
         String actual = window.getHostVmTreeFilterText();
         assertEquals("test", actual);
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/SearchFieldSwingViewTest.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-
-import java.awt.FlowLayout;
-
-import javax.swing.JButton;
-import javax.swing.JFrame;
-
-import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner;
-
-import org.fest.swing.annotation.GUITest;
-import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
-import org.fest.swing.edt.GuiActionRunner;
-import org.fest.swing.edt.GuiTask;
-import org.fest.swing.fixture.FrameFixture;
-import org.fest.swing.fixture.JButtonFixture;
-import org.fest.swing.fixture.JTextComponentFixture;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-
-import com.redhat.thermostat.client.core.views.SearchFieldView;
-import com.redhat.thermostat.client.swing.views.SearchFieldSwingView;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-
-@RunWith(CacioFESTRunner.class)
-public class SearchFieldSwingViewTest {
-
-    private final String OTHER_COMPONENT_NAME = "other";
-
-    private JFrame frame;
-    private SearchFieldSwingView searchField;
-    private JButton otherComponent;
-    private FrameFixture frameFixture;
-
-    @BeforeClass
-    public static void setUpOnce() {
-        FailOnThreadViolationRepaintManager.install();
-    }
-
-    @Before
-    public void setUp() {
-        GuiActionRunner.execute(new GuiTask() {
-
-
-            @Override
-            protected void executeInEDT() throws Throwable {
-                frame = new JFrame();
-                frame.setLayout(new FlowLayout());
-                searchField = new SearchFieldSwingView();
-                frame.add(searchField);
-                otherComponent = new JButton();
-                otherComponent.setName(OTHER_COMPONENT_NAME);
-                frame.add(otherComponent);
-            }
-        });
-        frameFixture = new FrameFixture(frame);
-    }
-
-    @After
-    public void tearDown() {
-        frameFixture.cleanUp();
-        frameFixture = null;
-    }
-
-    @Test
-    public void verifyInitialSearchString() {
-        frameFixture.show();
-
-        assertEquals("", searchField.getSearchText());
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void verifyLabelShownByDefault() {
-        final String LABEL = "search label to help users";
-        searchField.setLabel(LABEL);
-
-        frameFixture.show();
-        JTextComponentFixture textBox = frameFixture.textBox(SearchFieldView.VIEW_NAME);
-        assertEquals(LABEL, textBox.text());
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void verifyLabelHiddenAndShownProperly() {
-        final String LABEL = "search label to help users";
-        final String USER_TEXT = "java";
-        searchField.setLabel(LABEL);
-
-        frameFixture.show();
-        JTextComponentFixture textBox = frameFixture.textBox(SearchFieldView.VIEW_NAME);
-        assertEquals(LABEL, textBox.text());
-
-        textBox.enterText(USER_TEXT);
-
-        textBox.deleteText();
-
-        JButtonFixture button = frameFixture.button(OTHER_COMPONENT_NAME);
-        button.focus();
-
-        assertEquals(LABEL, textBox.text());
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void verifySearchTextTypedIsReturned() {
-        frameFixture.show();
-
-        final String SEARCH_TEXT = "test";
-        JTextComponentFixture textBox = frameFixture.textBox(SearchFieldView.VIEW_NAME);
-        textBox.enterText(SEARCH_TEXT);
-        String actual = searchField.getSearchText();
-        assertEquals(SEARCH_TEXT, actual);
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void verifyTextSetIsShown() {
-        frameFixture.show();
-
-        final String SEARCH_TEXT = "test";
-        searchField.setSearchText(SEARCH_TEXT);
-        JTextComponentFixture textBox = frameFixture.textBox(SearchFieldView.VIEW_NAME);
-        String actual = textBox.text();
-        assertEquals(SEARCH_TEXT, actual);
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void verifyListenersAreFiredOnTextEntry() {
-        frameFixture.show();
-
-        final String SEARCH_TEXT = "test";
-        ActionListener<SearchFieldView.SearchAction> listener = mock(ActionListener.class);
-
-        JTextComponentFixture textBox = frameFixture.textBox(SearchFieldView.VIEW_NAME);
-
-        searchField.addActionListener(listener);
-
-        textBox.enterText(SEARCH_TEXT);
-
-        verify(listener, times(SEARCH_TEXT.length())).actionPerformed(
-                new ActionEvent<SearchFieldView.SearchAction>(searchField, SearchFieldView.SearchAction.TEXT_CHANGED));
-
-        textBox.enterText("\n");
-
-        verify(listener).actionPerformed(
-                new ActionEvent<SearchFieldView.SearchAction>(searchField, SearchFieldView.SearchAction.PERFORM_SEARCH));
-
-    }
-
-}
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivatorTest.java	Fri Dec 21 15:35:21 2012 +0100
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivatorTest.java	Mon Jan 07 10:44:01 2013 -0500
@@ -48,11 +48,11 @@
 import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
 import com.redhat.thermostat.client.osgi.service.DecoratorProvider;
 import com.redhat.thermostat.client.swing.internal.HostIconDecoratorProvider;
-import com.redhat.thermostat.client.swing.views.SwingAgentInformationViewProvider;
-import com.redhat.thermostat.client.swing.views.SwingClientConfigurationViewProvider;
-import com.redhat.thermostat.client.swing.views.SwingHostInformationViewProvider;
-import com.redhat.thermostat.client.swing.views.SwingSummaryViewProvider;
-import com.redhat.thermostat.client.swing.views.SwingVmInformationViewProvider;
+import com.redhat.thermostat.client.swing.internal.views.SwingAgentInformationViewProvider;
+import com.redhat.thermostat.client.swing.internal.views.SwingClientConfigurationViewProvider;
+import com.redhat.thermostat.client.swing.internal.views.SwingHostInformationViewProvider;
+import com.redhat.thermostat.client.swing.internal.views.SwingSummaryViewProvider;
+import com.redhat.thermostat.client.swing.internal.views.SwingVmInformationViewProvider;
 import com.redhat.thermostat.test.StubBundleContext;
 
 public class ThermostatActivatorTest {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/AgentInformationDisplayFrameTest.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,301 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.atLeast;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner;
+
+import org.fest.swing.annotation.GUITest;
+import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
+import org.fest.swing.edt.GuiActionRunner;
+import org.fest.swing.edt.GuiQuery;
+import org.fest.swing.edt.GuiTask;
+import org.fest.swing.fixture.FrameFixture;
+import org.fest.swing.fixture.JListFixture;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import com.redhat.thermostat.client.core.views.AgentInformationDisplayView;
+import com.redhat.thermostat.client.core.views.AgentInformationDisplayView.ConfigurationAction;
+import com.redhat.thermostat.client.swing.internal.views.AgentInformationDisplayFrame;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+
+@RunWith(CacioFESTRunner.class)
+public class AgentInformationDisplayFrameTest {
+
+    private AgentInformationDisplayFrame agentConfigFrame;
+    private FrameFixture fixture;
+    private ActionListener<AgentInformationDisplayView.ConfigurationAction> l;
+
+    @BeforeClass
+    public static void setUpOnce() {
+        FailOnThreadViolationRepaintManager.install();
+    }
+
+    @Before
+    public void setUp() {
+        agentConfigFrame = GuiActionRunner.execute(new GuiQuery<AgentInformationDisplayFrame>() {
+
+            @Override
+            protected AgentInformationDisplayFrame executeInEDT() throws Throwable {
+                return new AgentInformationDisplayFrame();
+            }
+        });
+
+        @SuppressWarnings("unchecked")
+        ActionListener<AgentInformationDisplayView.ConfigurationAction> listener = mock(ActionListener.class);
+        l = listener;
+        agentConfigFrame.addConfigurationListener(l);
+
+        fixture = new FrameFixture(agentConfigFrame.getFrame());
+    }
+
+    @After
+    public void tearDown() {
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                agentConfigFrame.hideDialog();
+            }
+        });
+
+        fixture.requireNotVisible();
+        agentConfigFrame.removeConfigurationListener(l);
+
+        fixture.cleanUp();
+        fixture = null;
+    }
+
+    @Category(GUITest.class)
+    @GUITest
+    @Test
+    public void testWindowClose() {
+        fixture.show();
+
+        fixture.close();
+
+        verify(l).actionPerformed(eq(new ActionEvent<>(agentConfigFrame, AgentInformationDisplayView.ConfigurationAction.CLOSE)));
+    }
+
+    @Category(GUITest.class)
+    @GUITest
+    @Test
+    public void testClickOnCloseButton() {
+        fixture.show();
+
+        fixture.button("close").click();
+
+        fixture.robot.waitForIdle();
+
+        verify(l).actionPerformed(eq(new ActionEvent<>(agentConfigFrame, AgentInformationDisplayView.ConfigurationAction.CLOSE)));
+    }
+
+    @Category(GUITest.class)
+    @GUITest
+    @Test
+    public void testAddingAgentWorks() {
+        fixture.show();
+        JListFixture list = fixture.list("agentList");
+        assertArrayEquals(new String[0], list.contents());
+
+        agentConfigFrame.addAgent("test-agent");
+
+        assertArrayEquals(new String[] { "test-agent" }, list.contents());
+    }
+
+    @Category(GUITest.class)
+    @GUITest
+    @Test
+    public void testSelectingAgentWorks() {
+        fixture.show();
+        agentConfigFrame.addAgent("testAgent");
+        JListFixture list = fixture.list("agentList");
+
+        list.selectItem("testAgent");
+
+        verify(l, atLeast(1)).actionPerformed(eq(new ActionEvent<>(agentConfigFrame, AgentInformationDisplayView.ConfigurationAction.SWITCH_AGENT)));
+    }
+
+    @Category(GUITest.class)
+    @GUITest
+    @Test
+    public void testFirstAddedAgentIsAutomaticallySelected() {
+        fixture.show();
+        agentConfigFrame.addAgent("testAgent");
+
+        fixture.robot.waitForIdle();
+
+        verify(l).actionPerformed(eq(new ActionEvent<>(agentConfigFrame, AgentInformationDisplayView.ConfigurationAction.SWITCH_AGENT)));
+    }
+
+    @Category(GUITest.class)
+    @GUITest
+    @Test
+    public void testRemovingAllAgentsWorks() {
+        fixture.show();
+        agentConfigFrame.addAgent("test-agent");
+        JListFixture list = fixture.list("agentList");
+
+        agentConfigFrame.clearAllAgents();
+
+        assertArrayEquals(new String[0], list.contents());
+    }
+
+    @Category(GUITest.class)
+    @GUITest
+    @Test
+    public void testInitialInformation() {
+        fixture.show();
+
+        String EMPTY_TEXT = "---";
+
+        assertEquals(EMPTY_TEXT, fixture.textBox("agentName").text());
+        assertEquals(EMPTY_TEXT, fixture.textBox("agentId").text());
+        assertEquals(EMPTY_TEXT, fixture.textBox("commandAddress").text());
+        assertEquals(EMPTY_TEXT, fixture.textBox("startTime").text());
+        assertEquals(EMPTY_TEXT, fixture.textBox("stopTime").text());
+        assertEquals(EMPTY_TEXT, fixture.textBox("backendDescription").text());
+
+    }
+
+    @Category(GUITest.class)
+    @GUITest
+    @Test
+    public void testUpdatingAgentInformationWorks() {
+
+        final String AGENT_NAME = "the-agent-name";
+        final String AGENT_ID = "the-agent-id";
+        final String COMMAND_ADDRESS = "agent-command-channel-address";
+        final String START_TIME = "some-start-time";
+        final String STOP_TIME = "a-certain-stop-time";
+
+        agentConfigFrame.setSelectedAgentName(AGENT_NAME);
+        agentConfigFrame.setSelectedAgentId(AGENT_ID);
+        agentConfigFrame.setSelectedAgentCommandAddress(COMMAND_ADDRESS);
+        agentConfigFrame.setSelectedAgentStartTime(START_TIME);
+        agentConfigFrame.setSelectedAgentStopTime(STOP_TIME);
+
+        fixture.show();
+
+        assertEquals(AGENT_NAME, fixture.textBox("agentName").text());
+        assertEquals(AGENT_ID, fixture.textBox("agentId").text());
+        assertEquals(COMMAND_ADDRESS, fixture.textBox("commandAddress").text());
+        assertEquals(START_TIME, fixture.textBox("startTime").text());
+        assertEquals(STOP_TIME, fixture.textBox("stopTime").text());
+    }
+
+    @Category(GUITest.class)
+    @GUITest
+    @Test
+    public void testBackendDescriptionIsQueriedAndDisplayed() {
+        final ActionEvent<ConfigurationAction> action = 
+                new ActionEvent<>(agentConfigFrame, ConfigurationAction.SHOW_BACKEND_DESCRIPTION);
+        final String[] BACKEND_NAMES = { "foo1", "foo2", "foo3" };
+        final String[] BACKEND_STATUSES = { "bar1", "bar2", "bar3" };
+        final String[] BACKEND_DESCRIPTIONS = { "baz1", "baz2", "baz3" };
+
+        // Ordered by insertion
+        Map<String, String> statusMap = new LinkedHashMap<>();
+        statusMap.put(BACKEND_NAMES[0], BACKEND_STATUSES[0]);
+        statusMap.put(BACKEND_NAMES[1], BACKEND_STATUSES[1]);
+        statusMap.put(BACKEND_NAMES[2], BACKEND_STATUSES[2]);
+        
+        final Map<String, String> descMap = new HashMap<>();
+        descMap.put(BACKEND_NAMES[0], BACKEND_DESCRIPTIONS[0]);
+        descMap.put(BACKEND_NAMES[1], BACKEND_DESCRIPTIONS[1]);
+        descMap.put(BACKEND_NAMES[2], BACKEND_DESCRIPTIONS[2]);
+        
+        // Add hook for ActionListener
+        doAnswer(new Answer<Object>() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable {
+                Object arg = invocation.getArguments()[0];
+                ActionEvent<?> event = (ActionEvent<?>) arg;
+                String backendName = (String) event.getPayload();
+                String description = descMap.get(backendName);
+                agentConfigFrame.setSelectedAgentBackendDescription(description);
+                return null;
+            }
+        }).when(l).actionPerformed(eq(action));
+
+        fixture.show();
+
+        agentConfigFrame.setSelectedAgentBackendStatus(statusMap);
+
+        assertEquals(3, fixture.table("backends").rowCount());
+
+        String[] rowContents = fixture.table("backends").contents()[0];
+        assertArrayEquals(new String[] { BACKEND_NAMES[0], BACKEND_STATUSES[0] }, rowContents);
+        rowContents = fixture.table("backends").contents()[1];
+        assertArrayEquals(new String[] { BACKEND_NAMES[1], BACKEND_STATUSES[1] }, rowContents);
+        rowContents = fixture.table("backends").contents()[2];
+        assertArrayEquals(new String[] { BACKEND_NAMES[2], BACKEND_STATUSES[2] }, rowContents);
+
+        // selectRows(0) doesn't trigger listener, since it is selected by default
+        // so start with row 1
+        fixture.table("backends").selectRows(1);
+        fixture.robot.waitForIdle();
+        assertEquals(BACKEND_DESCRIPTIONS[1], fixture.textBox("backendDescription").text());
+        
+        fixture.table("backends").selectRows(2);
+        fixture.robot.waitForIdle();
+        assertEquals(BACKEND_DESCRIPTIONS[2], fixture.textBox("backendDescription").text());
+        
+        fixture.table("backends").selectRows(0);
+        fixture.robot.waitForIdle();
+        assertEquals(BACKEND_DESCRIPTIONS[0], fixture.textBox("backendDescription").text());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/ClientConfigurationSwingTest.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import javax.swing.UIManager;
+
+import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner;
+
+import org.fest.swing.annotation.GUITest;
+import org.fest.swing.core.matcher.JButtonMatcher;
+import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
+import org.fest.swing.edt.GuiActionRunner;
+import org.fest.swing.edt.GuiQuery;
+import org.fest.swing.fixture.DialogFixture;
+import org.fest.swing.fixture.JButtonFixture;
+import org.fest.swing.fixture.JCheckBoxFixture;
+import org.fest.swing.fixture.JTextComponentFixture;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.junit.runner.RunWith;
+
+import com.redhat.thermostat.client.core.views.ClientConfigurationView;
+import com.redhat.thermostat.client.swing.internal.views.ClientConfigurationSwing;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.test.Bug;
+
+@RunWith(CacioFESTRunner.class)
+public class ClientConfigurationSwingTest {
+    
+    private ClientConfigurationSwing frame;
+    private DialogFixture frameFixture;
+    private ActionListener<ClientConfigurationView.Action> l;
+
+    @BeforeClass
+    public static void setUpOnce() {
+        FailOnThreadViolationRepaintManager.install();
+    }
+
+    @SuppressWarnings("unchecked") // ActionListener
+    @Before
+    public void setUp() {
+        
+        frame = GuiActionRunner.execute(new GuiQuery<ClientConfigurationSwing>() {
+
+            @Override
+            protected ClientConfigurationSwing executeInEDT() throws Throwable {
+                return new ClientConfigurationSwing();
+            }
+        });
+        l = mock(ActionListener.class);
+        frame.addListener(l);
+        frame.showDialog();
+        assertNotNull(frame.getDialog());
+        frameFixture = new DialogFixture(frame.getDialog());
+
+    }
+
+    @After
+    public void tearDown() {
+        frame.hideDialog();
+
+        frameFixture.cleanUp();
+        frame.removeListener(l);
+        frame = null;
+        l = null;
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void testConnectionUrlText() {
+
+        JTextComponentFixture textBox = frameFixture.textBox("connectionUrl");
+        textBox.enterText("foobar");
+
+        assertEquals("foobar", frame.getConnectionUrl());
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void testPasswordText() {
+
+        JTextComponentFixture textBox = frameFixture.textBox("password");
+        textBox.enterText("foobar");
+
+        assertEquals("foobar", frame.getPassword());
+    }
+    
+    @Category(GUITest.class)
+    @Test
+    public void testUsernameText() {
+
+        JTextComponentFixture textBox = frameFixture.textBox("username");
+        textBox.enterText("foobar");
+
+        assertEquals("foobar", frame.getUserName());
+    }
+    
+    @Category(GUITest.class)
+    @Test
+    public void testSaveEntitlements() {
+
+        JCheckBoxFixture saveBox = frameFixture.checkBox("saveEntitlements");
+        saveBox.requireEnabled();
+        saveBox.requireNotSelected();
+
+        saveBox.click();
+        assertEquals(true, frame.getSaveEntitlements());
+        
+        saveBox.click();
+        assertEquals(false, frame.getSaveEntitlements());
+    }
+    
+    @Category(GUITest.class)
+    @Test
+    public void testOkayButton() {
+        JButtonFixture button = frameFixture.button(JButtonMatcher.withText("OK"));
+        button.click();
+
+        verify(l).actionPerformed(eq(new ActionEvent<>(frame, ClientConfigurationView.Action.CLOSE_ACCEPT)));
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void testCancelButton() {
+        JButtonFixture button = frameFixture.button(JButtonMatcher.withText(UIManager.getString("OptionPane.cancelButtonText")));
+        button.click();
+
+        verify(l).actionPerformed(eq(new ActionEvent<>(frame, ClientConfigurationView.Action.CLOSE_CANCEL)));
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void testCloseWindow() {
+        frameFixture.close();
+
+        verify(l).actionPerformed(eq(new ActionEvent<>(frame, ClientConfigurationView.Action.CLOSE_CANCEL)));
+    }
+
+    @Bug(id="1030",
+         summary="Buttons in client preferences dialog should have the same size",
+         url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1030")
+    @Category(GUITest.class)
+    @Test
+    public void testButtonsSameSize() {
+        JButtonFixture cancel = frameFixture.button(JButtonMatcher.withText(UIManager.getString("OptionPane.cancelButtonText")));
+        JButtonFixture ok = frameFixture.button(JButtonMatcher.withText("OK"));
+
+        assertEquals(cancel.target.getSize(), ok.target.getSize());
+
+        frameFixture.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/views/HostInformationPanelTest.java	Mon Jan 07 10:44:01 2013 -0500
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal.views;
+
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.JFrame;
+import javax.swing.JTabbedPane;
+
+import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
+import org.fest.swing.edt.GuiActionRunner;
+import org.fest.swing.edt.GuiQuery;
+import org.fest.swing.edt.GuiTask;
+import org.fest.swing.fixture.FrameFixture;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.redhat.thermostat.client.core.views.BasicView;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.client.swing.TabbedPaneMatcher;
+import com.redhat.thermostat.client.swing.internal.views.HostInformationPanel;
+
+public class HostInformationPanelTest {
+
+    private HostInformationPanel panel;
+    private JFrame frame;
+    private FrameFixture window;
+
+    @BeforeClass
+    public static void setUpOnce() {
+        FailOnThreadViolationRepaintManager.install();
+    }
+
+    @Before
+    public void setUp() {
+        panel = createHostInfoPanel();
+
+        frame = GuiActionRunner.execute(new GuiQuery<JFrame>() {
+            @Override
+            protected JFrame executeInEDT() throws Throwable {
+                JFrame jFrame = new JFrame();
+                panel.getUiComponent().setName("panel");
+                jFrame.add(panel.getUiComponent());
+                return jFrame;
+            }
+        });
+
+        window = new FrameFixture(frame);
+        window.show();
+    }
+
+    @After
+    public void tearDown() {
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                frame.dispose();
+            }
+        });
+        window.cleanUp();
+    }
+    
+    private HostInformationPanel createHostInfoPanel() {
+        return GuiActionRunner.execute(new GuiQuery<HostInformationPanel>() {
+            @Override
+            protected HostInformationPanel executeInEDT() throws Throwable {
+                return new HostInformationPanel();
+            }
+        });
+    }
+
+    @Test
+    public void testAddTwice() throws InvocationTargetException, InterruptedException {
+        UIComponent mock1 = createHostInfoPanel();
+
+        panel.addChildView("foo1", mock1);
+
+        // The panel in test has no views added so the matcher with a tab count > 0 works
+        // in order to select the right panel.
+        window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("foo1");
+
+        UIComponent mock2 = createHostInfoPanel();
+        panel.addChildView("foo2", mock2);
+
+        window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("foo1", "foo2");
+    }
+
+    @Test
+    public void testAddRemove() throws InvocationTargetException, InterruptedException {
+        UIComponent test1 = createHostInfoPanel();
+        UIComponent test2 = createHostInfoPanel();
+
+        panel.addChildView("test1", test1);
+        panel.addChildView("test2", test2);
+
+        // The panel in test has no views added so the matcher with a tab count > 0 works
+        // in order to select the right panel.
+        window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("test1", "test2");
+
+        panel.removeChildView("test1");
+
+        window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("test2");
+    }
+}
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/views/AgentInformationDisplayFrameTest.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,300 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import java.util.HashMap;
-import java.util.LinkedHashMap;
-import java.util.Map;
-
-import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner;
-
-import org.fest.swing.annotation.GUITest;
-import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
-import org.fest.swing.edt.GuiActionRunner;
-import org.fest.swing.edt.GuiQuery;
-import org.fest.swing.edt.GuiTask;
-import org.fest.swing.fixture.FrameFixture;
-import org.fest.swing.fixture.JListFixture;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import com.redhat.thermostat.client.core.views.AgentInformationDisplayView;
-import com.redhat.thermostat.client.core.views.AgentInformationDisplayView.ConfigurationAction;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-
-@RunWith(CacioFESTRunner.class)
-public class AgentInformationDisplayFrameTest {
-
-    private AgentInformationDisplayFrame agentConfigFrame;
-    private FrameFixture fixture;
-    private ActionListener<AgentInformationDisplayView.ConfigurationAction> l;
-
-    @BeforeClass
-    public static void setUpOnce() {
-        FailOnThreadViolationRepaintManager.install();
-    }
-
-    @Before
-    public void setUp() {
-        agentConfigFrame = GuiActionRunner.execute(new GuiQuery<AgentInformationDisplayFrame>() {
-
-            @Override
-            protected AgentInformationDisplayFrame executeInEDT() throws Throwable {
-                return new AgentInformationDisplayFrame();
-            }
-        });
-
-        @SuppressWarnings("unchecked")
-        ActionListener<AgentInformationDisplayView.ConfigurationAction> listener = mock(ActionListener.class);
-        l = listener;
-        agentConfigFrame.addConfigurationListener(l);
-
-        fixture = new FrameFixture(agentConfigFrame.getFrame());
-    }
-
-    @After
-    public void tearDown() {
-        GuiActionRunner.execute(new GuiTask() {
-            @Override
-            protected void executeInEDT() throws Throwable {
-                agentConfigFrame.hideDialog();
-            }
-        });
-
-        fixture.requireNotVisible();
-        agentConfigFrame.removeConfigurationListener(l);
-
-        fixture.cleanUp();
-        fixture = null;
-    }
-
-    @Category(GUITest.class)
-    @GUITest
-    @Test
-    public void testWindowClose() {
-        fixture.show();
-
-        fixture.close();
-
-        verify(l).actionPerformed(eq(new ActionEvent<>(agentConfigFrame, AgentInformationDisplayView.ConfigurationAction.CLOSE)));
-    }
-
-    @Category(GUITest.class)
-    @GUITest
-    @Test
-    public void testClickOnCloseButton() {
-        fixture.show();
-
-        fixture.button("close").click();
-
-        fixture.robot.waitForIdle();
-
-        verify(l).actionPerformed(eq(new ActionEvent<>(agentConfigFrame, AgentInformationDisplayView.ConfigurationAction.CLOSE)));
-    }
-
-    @Category(GUITest.class)
-    @GUITest
-    @Test
-    public void testAddingAgentWorks() {
-        fixture.show();
-        JListFixture list = fixture.list("agentList");
-        assertArrayEquals(new String[0], list.contents());
-
-        agentConfigFrame.addAgent("test-agent");
-
-        assertArrayEquals(new String[] { "test-agent" }, list.contents());
-    }
-
-    @Category(GUITest.class)
-    @GUITest
-    @Test
-    public void testSelectingAgentWorks() {
-        fixture.show();
-        agentConfigFrame.addAgent("testAgent");
-        JListFixture list = fixture.list("agentList");
-
-        list.selectItem("testAgent");
-
-        verify(l, atLeast(1)).actionPerformed(eq(new ActionEvent<>(agentConfigFrame, AgentInformationDisplayView.ConfigurationAction.SWITCH_AGENT)));
-    }
-
-    @Category(GUITest.class)
-    @GUITest
-    @Test
-    public void testFirstAddedAgentIsAutomaticallySelected() {
-        fixture.show();
-        agentConfigFrame.addAgent("testAgent");
-
-        fixture.robot.waitForIdle();
-
-        verify(l).actionPerformed(eq(new ActionEvent<>(agentConfigFrame, AgentInformationDisplayView.ConfigurationAction.SWITCH_AGENT)));
-    }
-
-    @Category(GUITest.class)
-    @GUITest
-    @Test
-    public void testRemovingAllAgentsWorks() {
-        fixture.show();
-        agentConfigFrame.addAgent("test-agent");
-        JListFixture list = fixture.list("agentList");
-
-        agentConfigFrame.clearAllAgents();
-
-        assertArrayEquals(new String[0], list.contents());
-    }
-
-    @Category(GUITest.class)
-    @GUITest
-    @Test
-    public void testInitialInformation() {
-        fixture.show();
-
-        String EMPTY_TEXT = "---";
-
-        assertEquals(EMPTY_TEXT, fixture.textBox("agentName").text());
-        assertEquals(EMPTY_TEXT, fixture.textBox("agentId").text());
-        assertEquals(EMPTY_TEXT, fixture.textBox("commandAddress").text());
-        assertEquals(EMPTY_TEXT, fixture.textBox("startTime").text());
-        assertEquals(EMPTY_TEXT, fixture.textBox("stopTime").text());
-        assertEquals(EMPTY_TEXT, fixture.textBox("backendDescription").text());
-
-    }
-
-    @Category(GUITest.class)
-    @GUITest
-    @Test
-    public void testUpdatingAgentInformationWorks() {
-
-        final String AGENT_NAME = "the-agent-name";
-        final String AGENT_ID = "the-agent-id";
-        final String COMMAND_ADDRESS = "agent-command-channel-address";
-        final String START_TIME = "some-start-time";
-        final String STOP_TIME = "a-certain-stop-time";
-
-        agentConfigFrame.setSelectedAgentName(AGENT_NAME);
-        agentConfigFrame.setSelectedAgentId(AGENT_ID);
-        agentConfigFrame.setSelectedAgentCommandAddress(COMMAND_ADDRESS);
-        agentConfigFrame.setSelectedAgentStartTime(START_TIME);
-        agentConfigFrame.setSelectedAgentStopTime(STOP_TIME);
-
-        fixture.show();
-
-        assertEquals(AGENT_NAME, fixture.textBox("agentName").text());
-        assertEquals(AGENT_ID, fixture.textBox("agentId").text());
-        assertEquals(COMMAND_ADDRESS, fixture.textBox("commandAddress").text());
-        assertEquals(START_TIME, fixture.textBox("startTime").text());
-        assertEquals(STOP_TIME, fixture.textBox("stopTime").text());
-    }
-
-    @Category(GUITest.class)
-    @GUITest
-    @Test
-    public void testBackendDescriptionIsQueriedAndDisplayed() {
-        final ActionEvent<ConfigurationAction> action = 
-                new ActionEvent<>(agentConfigFrame, ConfigurationAction.SHOW_BACKEND_DESCRIPTION);
-        final String[] BACKEND_NAMES = { "foo1", "foo2", "foo3" };
-        final String[] BACKEND_STATUSES = { "bar1", "bar2", "bar3" };
-        final String[] BACKEND_DESCRIPTIONS = { "baz1", "baz2", "baz3" };
-
-        // Ordered by insertion
-        Map<String, String> statusMap = new LinkedHashMap<>();
-        statusMap.put(BACKEND_NAMES[0], BACKEND_STATUSES[0]);
-        statusMap.put(BACKEND_NAMES[1], BACKEND_STATUSES[1]);
-        statusMap.put(BACKEND_NAMES[2], BACKEND_STATUSES[2]);
-        
-        final Map<String, String> descMap = new HashMap<>();
-        descMap.put(BACKEND_NAMES[0], BACKEND_DESCRIPTIONS[0]);
-        descMap.put(BACKEND_NAMES[1], BACKEND_DESCRIPTIONS[1]);
-        descMap.put(BACKEND_NAMES[2], BACKEND_DESCRIPTIONS[2]);
-        
-        // Add hook for ActionListener
-        doAnswer(new Answer<Object>() {
-            @Override
-            public Object answer(InvocationOnMock invocation) throws Throwable {
-                Object arg = invocation.getArguments()[0];
-                ActionEvent<?> event = (ActionEvent<?>) arg;
-                String backendName = (String) event.getPayload();
-                String description = descMap.get(backendName);
-                agentConfigFrame.setSelectedAgentBackendDescription(description);
-                return null;
-            }
-        }).when(l).actionPerformed(eq(action));
-
-        fixture.show();
-
-        agentConfigFrame.setSelectedAgentBackendStatus(statusMap);
-
-        assertEquals(3, fixture.table("backends").rowCount());
-
-        String[] rowContents = fixture.table("backends").contents()[0];
-        assertArrayEquals(new String[] { BACKEND_NAMES[0], BACKEND_STATUSES[0] }, rowContents);
-        rowContents = fixture.table("backends").contents()[1];
-        assertArrayEquals(new String[] { BACKEND_NAMES[1], BACKEND_STATUSES[1] }, rowContents);
-        rowContents = fixture.table("backends").contents()[2];
-        assertArrayEquals(new String[] { BACKEND_NAMES[2], BACKEND_STATUSES[2] }, rowContents);
-
-        // selectRows(0) doesn't trigger listener, since it is selected by default
-        // so start with row 1
-        fixture.table("backends").selectRows(1);
-        fixture.robot.waitForIdle();
-        assertEquals(BACKEND_DESCRIPTIONS[1], fixture.textBox("backendDescription").text());
-        
-        fixture.table("backends").selectRows(2);
-        fixture.robot.waitForIdle();
-        assertEquals(BACKEND_DESCRIPTIONS[2], fixture.textBox("backendDescription").text());
-        
-        fixture.table("backends").selectRows(0);
-        fixture.robot.waitForIdle();
-        assertEquals(BACKEND_DESCRIPTIONS[0], fixture.textBox("backendDescription").text());
-    }
-
-}
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/views/ClientConfigurationSwingTest.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,195 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import javax.swing.UIManager;
-
-import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner;
-
-import org.fest.swing.annotation.GUITest;
-import org.fest.swing.core.matcher.JButtonMatcher;
-import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
-import org.fest.swing.edt.GuiActionRunner;
-import org.fest.swing.edt.GuiQuery;
-import org.fest.swing.fixture.DialogFixture;
-import org.fest.swing.fixture.JButtonFixture;
-import org.fest.swing.fixture.JCheckBoxFixture;
-import org.fest.swing.fixture.JTextComponentFixture;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.experimental.categories.Category;
-import org.junit.runner.RunWith;
-
-import com.redhat.thermostat.client.core.views.ClientConfigurationView;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.test.Bug;
-
-@RunWith(CacioFESTRunner.class)
-public class ClientConfigurationSwingTest {
-    
-    private ClientConfigurationSwing frame;
-    private DialogFixture frameFixture;
-    private ActionListener<ClientConfigurationView.Action> l;
-
-    @BeforeClass
-    public static void setUpOnce() {
-        FailOnThreadViolationRepaintManager.install();
-    }
-
-    @SuppressWarnings("unchecked") // ActionListener
-    @Before
-    public void setUp() {
-        
-        frame = GuiActionRunner.execute(new GuiQuery<ClientConfigurationSwing>() {
-
-            @Override
-            protected ClientConfigurationSwing executeInEDT() throws Throwable {
-                return new ClientConfigurationSwing();
-            }
-        });
-        l = mock(ActionListener.class);
-        frame.addListener(l);
-        frame.showDialog();
-        assertNotNull(frame.getDialog());
-        frameFixture = new DialogFixture(frame.getDialog());
-
-    }
-
-    @After
-    public void tearDown() {
-        frame.hideDialog();
-
-        frameFixture.cleanUp();
-        frame.removeListener(l);
-        frame = null;
-        l = null;
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void testConnectionUrlText() {
-
-        JTextComponentFixture textBox = frameFixture.textBox("connectionUrl");
-        textBox.enterText("foobar");
-
-        assertEquals("foobar", frame.getConnectionUrl());
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void testPasswordText() {
-
-        JTextComponentFixture textBox = frameFixture.textBox("password");
-        textBox.enterText("foobar");
-
-        assertEquals("foobar", frame.getPassword());
-    }
-    
-    @Category(GUITest.class)
-    @Test
-    public void testUsernameText() {
-
-        JTextComponentFixture textBox = frameFixture.textBox("username");
-        textBox.enterText("foobar");
-
-        assertEquals("foobar", frame.getUserName());
-    }
-    
-    @Category(GUITest.class)
-    @Test
-    public void testSaveEntitlements() {
-
-        JCheckBoxFixture saveBox = frameFixture.checkBox("saveEntitlements");
-        saveBox.requireEnabled();
-        saveBox.requireNotSelected();
-
-        saveBox.click();
-        assertEquals(true, frame.getSaveEntitlements());
-        
-        saveBox.click();
-        assertEquals(false, frame.getSaveEntitlements());
-    }
-    
-    @Category(GUITest.class)
-    @Test
-    public void testOkayButton() {
-        JButtonFixture button = frameFixture.button(JButtonMatcher.withText("OK"));
-        button.click();
-
-        verify(l).actionPerformed(eq(new ActionEvent<>(frame, ClientConfigurationView.Action.CLOSE_ACCEPT)));
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void testCancelButton() {
-        JButtonFixture button = frameFixture.button(JButtonMatcher.withText(UIManager.getString("OptionPane.cancelButtonText")));
-        button.click();
-
-        verify(l).actionPerformed(eq(new ActionEvent<>(frame, ClientConfigurationView.Action.CLOSE_CANCEL)));
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void testCloseWindow() {
-        frameFixture.close();
-
-        verify(l).actionPerformed(eq(new ActionEvent<>(frame, ClientConfigurationView.Action.CLOSE_CANCEL)));
-    }
-
-    @Bug(id="1030",
-         summary="Buttons in client preferences dialog should have the same size",
-         url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=1030")
-    @Category(GUITest.class)
-    @Test
-    public void testButtonsSameSize() {
-        JButtonFixture cancel = frameFixture.button(JButtonMatcher.withText(UIManager.getString("OptionPane.cancelButtonText")));
-        JButtonFixture ok = frameFixture.button(JButtonMatcher.withText("OK"));
-
-        assertEquals(cancel.target.getSize(), ok.target.getSize());
-
-        frameFixture.close();
-    }
-}
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/views/HostInformationPanelTest.java	Fri Dec 21 15:35:21 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import java.lang.reflect.InvocationTargetException;
-
-import javax.swing.JFrame;
-import javax.swing.JTabbedPane;
-
-import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
-import org.fest.swing.edt.GuiActionRunner;
-import org.fest.swing.edt.GuiQuery;
-import org.fest.swing.edt.GuiTask;
-import org.fest.swing.fixture.FrameFixture;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.UIComponent;
-import com.redhat.thermostat.client.swing.TabbedPaneMatcher;
-import com.redhat.thermostat.client.swing.views.HostInformationPanel;
-
-public class HostInformationPanelTest {
-
-    private HostInformationPanel panel;
-    private JFrame frame;
-    private FrameFixture window;
-
-    @BeforeClass
-    public static void setUpOnce() {
-        FailOnThreadViolationRepaintManager.install();
-    }
-
-    @Before
-    public void setUp() {
-        panel = createHostInfoPanel();
-
-        frame = GuiActionRunner.execute(new GuiQuery<JFrame>() {
-            @Override
-            protected JFrame executeInEDT() throws Throwable {
-                JFrame jFrame = new JFrame();
-                panel.getUiComponent().setName("panel");
-                jFrame.add(panel.getUiComponent());
-                return jFrame;
-            }
-        });
-
-        window = new FrameFixture(frame);
-        window.show();
-    }
-
-    @After
-    public void tearDown() {
-        GuiActionRunner.execute(new GuiTask() {
-            @Override
-            protected void executeInEDT() throws Throwable {
-                frame.dispose();
-            }
-        });
-        window.cleanUp();
-    }
-    
-    private HostInformationPanel createHostInfoPanel() {
-        return GuiActionRunner.execute(new GuiQuery<HostInformationPanel>() {
-            @Override
-            protected HostInformationPanel executeInEDT() throws Throwable {
-                return new HostInformationPanel();
-            }
-        });
-    }
-
-    @Test
-    public void testAddTwice() throws InvocationTargetException, InterruptedException {
-        UIComponent mock1 = createHostInfoPanel();
-
-        panel.addChildView("foo1", mock1);
-
-        // The panel in test has no views added so the matcher with a tab count > 0 works
-        // in order to select the right panel.
-        window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("foo1");
-
-        UIComponent mock2 = createHostInfoPanel();
-        panel.addChildView("foo2", mock2);
-
-        window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("foo1", "foo2");
-    }
-
-    @Test
-    public void testAddRemove() throws InvocationTargetException, InterruptedException {
-        UIComponent test1 = createHostInfoPanel();
-        UIComponent test2 = createHostInfoPanel();
-
-        panel.addChildView("test1", test1);
-        panel.addChildView("test2", test2);
-
-        // The panel in test has no views added so the matcher with a tab count > 0 works
-        // in order to select the right panel.
-        window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("test1", "test2");
-
-        panel.removeChildView("test1");
-
-        window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("test2");
-    }
-}
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanel.java	Fri Dec 21 15:35:21 2012 +0100
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanel.java	Mon Jan 07 10:44:01 2013 -0500
@@ -54,10 +54,10 @@
 import javax.swing.GroupLayout.Alignment;
 import javax.swing.JLabel;
 
-import com.redhat.thermostat.client.core.views.SearchFieldView.SearchAction;
 import com.redhat.thermostat.client.swing.EdtHelper;
 import com.redhat.thermostat.client.swing.SwingComponent;
-import com.redhat.thermostat.client.swing.views.SearchFieldSwingView;
+import com.redhat.thermostat.client.swing.components.SearchField;
+import com.redhat.thermostat.client.swing.components.SearchField.SearchAction;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionNotifier;
@@ -103,7 +103,7 @@
 
     private final JPanel panel;
 
-    private final SearchFieldSwingView searchField;
+    private final SearchField searchField;
 
     private final LazyMutableTreeNode ROOT = new LazyMutableTreeNode(null);
     /** all the nodes in this model must be {@link LazyMutableTreeNode}s */
@@ -124,7 +124,7 @@
 
         JLabel searchLabel = new JLabel(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_SEARCH_LABEL));
 
-        searchField = new SearchFieldSwingView();
+        searchField = new SearchField();
         searchField.setTooltip(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_SEARCH_PATTERN_HELP));
 
         JSplitPane splitPane = new JSplitPane();
--- a/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanelTest.java	Fri Dec 21 15:35:21 2012 +0100
+++ b/vm-heap-analysis/client-swing/src/test/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanelTest.java	Mon Jan 07 10:44:01 2013 -0500
@@ -66,7 +66,7 @@
 import org.junit.Test;
 import org.junit.runner.RunWith;
 
-import com.redhat.thermostat.client.core.views.SearchFieldView;
+import com.redhat.thermostat.client.swing.components.SearchField;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.vm.heap.analysis.client.core.HeapObjectUI;
@@ -119,7 +119,7 @@
 
         frameFixture.show();
 
-        JTextComponentFixture searchBox = frameFixture.textBox(SearchFieldView.VIEW_NAME);
+        JTextComponentFixture searchBox = frameFixture.textBox(SearchField.VIEW_NAME);
         searchBox.enterText(SEARCH_TEXT);
 
         verify(listener, times(SEARCH_TEXT.length())).actionPerformed(new ActionEvent<ObjectAction>(view, ObjectAction.SEARCH));