changeset 716:f1a4570624dd

Move Swing-dependent code into separate bundles: client-swing This commit moves Swing-dependent code from client-core into a new client-swing bundle. The swing-components bundle has also been merged into this new client-swing bundle. Reviewed-by: omajid Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-October/003817.html
author Elliott Baron <ebaron@redhat.com>
date Tue, 23 Oct 2012 11:19:24 -0400
parents 864eb6f85042
children 01f4973a06dc
files client/core/src/main/java/com/redhat/thermostat/client/internal/ChangeableText.java client/core/src/main/java/com/redhat/thermostat/client/internal/GUIClientCommand.java client/core/src/main/java/com/redhat/thermostat/client/internal/HostFilterRegistry.java client/core/src/main/java/com/redhat/thermostat/client/internal/HostIconDecorator.java client/core/src/main/java/com/redhat/thermostat/client/internal/HostTreeDecoratorRegistry.java client/core/src/main/java/com/redhat/thermostat/client/internal/Main.java client/core/src/main/java/com/redhat/thermostat/client/internal/MainView.java client/core/src/main/java/com/redhat/thermostat/client/internal/MainWindowControllerImpl.java client/core/src/main/java/com/redhat/thermostat/client/internal/MenuRegistry.java client/core/src/main/java/com/redhat/thermostat/client/internal/RegistryFactory.java client/core/src/main/java/com/redhat/thermostat/client/internal/UiFacadeFactoryImpl.java client/core/src/main/java/com/redhat/thermostat/client/internal/VMInformationRegistry.java client/core/src/main/java/com/redhat/thermostat/client/internal/VMTreeDecoratorRegistry.java client/core/src/main/java/com/redhat/thermostat/client/internal/VmFilterRegistry.java client/core/src/main/java/com/redhat/thermostat/client/internal/config/ConnectionConfiguration.java client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ApplicationServiceProvider.java client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ContextActionServiceProvider.java client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ThermostatActivator.java client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/VMContextActionServiceTracker.java client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/VmInformationServiceTracker.java client/core/src/main/java/com/redhat/thermostat/client/internal/ui/swing/AboutDialog.java client/core/src/main/java/com/redhat/thermostat/client/internal/ui/swing/WrapLayout.java client/core/src/main/java/com/redhat/thermostat/client/swing/SwingAgentInformationViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/swing/SwingClientConfigurationViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/swing/SwingHostCpuViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/swing/SwingHostInformationViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/swing/SwingHostMemoryViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/swing/SwingHostOverviewViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/swing/SwingSummaryViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/swing/SwingVmCpuViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/swing/SwingVmGcViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/swing/SwingVmInformationViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/swing/SwingVmOverviewViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/ui/AgentInformationDisplayFrame.java client/core/src/main/java/com/redhat/thermostat/client/ui/ClientConfigurationPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/ClientConfigurationSwing.java client/core/src/main/java/com/redhat/thermostat/client/ui/Components.java client/core/src/main/java/com/redhat/thermostat/client/ui/DecoratedDefaultMutableTreeNode.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostCpuPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostInformationPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostMemoryPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostOverviewPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/HtmlTextBuilder.java client/core/src/main/java/com/redhat/thermostat/client/ui/IconResource.java client/core/src/main/java/com/redhat/thermostat/client/ui/LabelField.java client/core/src/main/java/com/redhat/thermostat/client/ui/LayoutDebugHelper.java client/core/src/main/java/com/redhat/thermostat/client/ui/MainWindow.java client/core/src/main/java/com/redhat/thermostat/client/ui/MemorySpacePanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/MenuHelper.java client/core/src/main/java/com/redhat/thermostat/client/ui/RecentTimeSeriesChartPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/SearchFieldSwingView.java client/core/src/main/java/com/redhat/thermostat/client/ui/SectionHeader.java client/core/src/main/java/com/redhat/thermostat/client/ui/SimpleTable.java client/core/src/main/java/com/redhat/thermostat/client/ui/SummaryPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/SwingComponent.java client/core/src/main/java/com/redhat/thermostat/client/ui/UIResources.java client/core/src/main/java/com/redhat/thermostat/client/ui/ValueField.java client/core/src/main/java/com/redhat/thermostat/client/ui/VmCpuPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/VmGcPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/VmInformationPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/VmOverviewPanel.java client/core/src/main/resources/duke.png client/core/src/test/java/com/redhat/thermostat/client/internal/GUIClientCommandTest.java client/core/src/test/java/com/redhat/thermostat/client/internal/HostIconDecoratorTest.java client/core/src/test/java/com/redhat/thermostat/client/internal/MainTest.java client/core/src/test/java/com/redhat/thermostat/client/internal/MainWindowControllerImplTest.java client/core/src/test/java/com/redhat/thermostat/client/internal/MenuRegistryTest.java client/core/src/test/java/com/redhat/thermostat/client/internal/SearchFieldSwingViewTest.java client/core/src/test/java/com/redhat/thermostat/client/internal/osgi/ApplicationServiceProviderTest.java client/core/src/test/java/com/redhat/thermostat/client/internal/osgi/ThermostatActivatorTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/AgentInformationDisplayFrameTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/ClientConfigurationSwingTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/HostInformationPanelTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/IconDescriptorTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/MainWindowTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/MenuHelperTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/TabbedPaneMatcher.java client/core/src/test/java/com/redhat/thermostat/client/ui/UIResourcesTest.java client/pom.xml client/swing-components/pom.xml client/swing-components/src/main/java/com/redhat/thermostat/swing/ActionButton.java client/swing-components/src/main/java/com/redhat/thermostat/swing/ActionButtonUI.java client/swing-components/src/main/java/com/redhat/thermostat/swing/ActionToggleButton.java client/swing-components/src/main/java/com/redhat/thermostat/swing/ChartPanel.java client/swing-components/src/main/java/com/redhat/thermostat/swing/DebugBorder.java client/swing-components/src/main/java/com/redhat/thermostat/swing/EdtHelper.java client/swing-components/src/main/java/com/redhat/thermostat/swing/EmptyIcon.java client/swing-components/src/main/java/com/redhat/thermostat/swing/GradientPanel.java client/swing-components/src/main/java/com/redhat/thermostat/swing/GradientRoundBorder.java client/swing-components/src/main/java/com/redhat/thermostat/swing/GraphicsUtils.java client/swing-components/src/main/java/com/redhat/thermostat/swing/HeaderPanel.java client/swing-components/src/main/java/com/redhat/thermostat/swing/ShadowLabel.java client/swing-components/src/main/java/com/redhat/thermostat/swing/StatusBar.java client/swing-components/src/main/java/com/redhat/thermostat/swing/ThermostatTable.java client/swing-components/src/main/java/com/redhat/thermostat/swing/ThermostatTableColumnResizer.java client/swing-components/src/main/java/com/redhat/thermostat/swing/ThermostatTableRenderer.java client/swing-components/src/main/java/com/redhat/thermostat/swing/ToolbarButton.java client/swing-components/src/main/java/com/redhat/thermostat/swing/models/LongRange.java client/swing-components/src/main/java/com/redhat/thermostat/swing/models/LongRangeNormalizer.java client/swing-components/src/main/java/com/redhat/thermostat/swing/models/NullSelectionModel.java client/swing-components/src/main/resources/icons/resize-grip.png client/swing-components/src/main/resources/icons/resize-grip.svg client/swing-components/src/main/resources/icons/scale-slider-vert-backdrop.png client/swing-components/src/main/resources/icons/scale-slider-vert.png client/swing-components/src/test/java/com/redhat/thermostat/swing/EdtHelperTest.java client/swing-components/src/test/java/com/redhat/thermostat/swing/StatusBarTest.java client/swing-components/src/test/java/com/redhat/thermostat/swing/models/LongRangeNormalizerTest.java client/swing-components/src/test/java/com/redhat/thermostat/swing/models/NullSelectionModelTest.java client/swing/pom.xml client/swing/src/main/java/com/redhat/thermostat/client/swing/IconResource.java client/swing/src/main/java/com/redhat/thermostat/client/swing/LayoutDebugHelper.java client/swing/src/main/java/com/redhat/thermostat/client/swing/MainWindow.java client/swing/src/main/java/com/redhat/thermostat/client/swing/MenuHelper.java client/swing/src/main/java/com/redhat/thermostat/client/swing/SwingComponent.java client/swing/src/main/java/com/redhat/thermostat/client/swing/UIResources.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionButton.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionButtonUI.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionToggleButton.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ChartPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/Components.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/DebugBorder.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/EdtHelper.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/EmptyIcon.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/GradientPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/GradientRoundBorder.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/GraphicsUtils.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/HeaderPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/HtmlTextBuilder.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/LabelField.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/RecentTimeSeriesChartPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SectionHeader.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ShadowLabel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SimpleTable.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/StatusBar.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ThermostatTable.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ThermostatTableColumnResizer.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ThermostatTableRenderer.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ToolbarButton.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ValueField.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/models/LongRange.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/models/LongRangeNormalizer.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/models/NullSelectionModel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/AboutDialog.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/ChangeableText.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/GUIClientCommand.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/HostFilterRegistry.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/HostIconDecorator.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/HostTreeDecoratorRegistry.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/MainView.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImpl.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MenuRegistry.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/RegistryFactory.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/UiFacadeFactoryImpl.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/VMInformationRegistry.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/VMTreeDecoratorRegistry.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/VmFilterRegistry.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/WrapLayout.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/components/DecoratedDefaultMutableTreeNode.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/config/ConnectionConfiguration.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/ApplicationServiceProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/ContextActionServiceProvider.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/osgi/VMContextActionServiceTracker.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/VmInformationServiceTracker.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/HostCpuPanel.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/HostMemoryPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/HostOverviewPanel.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/SwingHostCpuViewProvider.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/SwingHostMemoryViewProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingHostOverviewViewProvider.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/SwingVmCpuViewProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingVmGcViewProvider.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/SwingVmOverviewViewProvider.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/VmCpuPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/VmGcPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/VmInformationPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/views/VmOverviewPanel.java client/swing/src/main/resources/duke.png client/swing/src/main/resources/icons/resize-grip.png client/swing/src/main/resources/icons/resize-grip.svg client/swing/src/main/resources/icons/scale-slider-vert-backdrop.png client/swing/src/main/resources/icons/scale-slider-vert.png client/swing/src/test/java/com/redhat/thermostat/client/swing/IconDescriptorTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/MainWindowTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/MenuHelperTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/TabbedPaneMatcher.java client/swing/src/test/java/com/redhat/thermostat/client/swing/UIResourcesTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/EdtHelperTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/StatusBarTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/models/LongRangeNormalizerTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/models/NullSelectionModelTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/GUIClientCommandTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/HostIconDecoratorTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImplTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MenuRegistryTest.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/ApplicationServiceProviderTest.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/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 eclipse/core-p2-repository/pom.xml thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/chart/ChartColors.java thread/client-swing/pom.xml thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadDetailsView.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTableView.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTimelineChart.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTimelineView.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadView.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingVMThreadCapabilitiesView.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadMainPanel.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadTimelineLegendPanel.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/VMCapsSummaryPanel.java
diffstat 227 files changed, 14303 insertions(+), 14169 deletions(-) [+]
line wrap: on
line diff
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/ChangeableText.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +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.internal;
-
-import java.util.HashSet;
-import java.util.Set;
-
-public class ChangeableText {
-
-    private final Set<TextListener> listeners = new HashSet<TextListener>();
-    private String text;
-
-    public static interface TextListener {
-        public void textChanged(ChangeableText text);
-    }
-
-    public ChangeableText(String text) {
-        this.text = text;
-    }
-
-    public synchronized void setText(String text) {
-        if (this.text.equals(text)) {
-            return;
-        }
-        this.text = text;
-        fireChanged();
-    }
-
-    public synchronized String getText() {
-        return text;
-    }
-
-    public synchronized void addListener(TextListener listener) {
-        this.listeners.add(listener);
-    }
-
-    public synchronized void removeListener(TextListener listener) {
-        this.listeners.remove(listener);
-    }
-
-    private void fireChanged() {
-        for (TextListener listener: listeners) {
-            listener.textChanged(this);
-        }
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/GUIClientCommand.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,87 +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.internal;
-
-import org.osgi.framework.BundleContext;
-
-import com.redhat.thermostat.client.internal.osgi.ApplicationServiceProvider;
-import com.redhat.thermostat.client.internal.osgi.ContextActionServiceProvider;
-import com.redhat.thermostat.client.osgi.service.ApplicationService;
-import com.redhat.thermostat.client.osgi.service.ContextAction;
-import com.redhat.thermostat.common.cli.CommandContext;
-import com.redhat.thermostat.common.cli.CommandException;
-import com.redhat.thermostat.common.cli.OSGiContext;
-import com.redhat.thermostat.common.cli.SimpleCommand;
-
-public class GUIClientCommand extends SimpleCommand implements OSGiContext {
-
-    private BundleContext context;
-    private Main clientMain;
-
-    public GUIClientCommand(Main clientMain) {
-        this.clientMain = clientMain;
-    }
-
-    @Override
-    public void setBundleContext(BundleContext context) {
-        this.context = context;
-    }
-    
-    @Override
-    public void run(CommandContext ctx) throws CommandException {
-        ApplicationService service = new ApplicationServiceProvider();
-        
-        context.registerService(ApplicationService.class.getName(), service, null);
-        context.registerService(ContextAction.class.getName(), new ContextActionServiceProvider(), null);
-        
-        // this blocks, everything else needs to be done before
-        clientMain.run();
-
-        service.getApplicationExecutor().shutdown();
-    }
-
-    @Override
-    public String getName() {
-        return "gui";
-    }
-
-    @Override
-    public boolean isStorageRequired() {
-        return false;
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/HostFilterRegistry.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +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.internal;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-
-import com.redhat.thermostat.client.core.HostFilter;
-import com.redhat.thermostat.common.ThermostatExtensionRegistry;
-
-class HostFilterRegistry extends ThermostatExtensionRegistry<HostFilter> {
-
-    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + HostFilter.class.getName() + ")";
-
-    public HostFilterRegistry(BundleContext context) throws InvalidSyntaxException {
-        super(context, FILTER, HostFilter.class);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/HostIconDecorator.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +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.internal;
-
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.ByteBuffer;
-
-import com.redhat.thermostat.client.core.HostFilter;
-import com.redhat.thermostat.client.osgi.service.HostDecorator;
-import com.redhat.thermostat.client.ui.Decorator;
-import com.redhat.thermostat.client.ui.IconDescriptor;
-import com.redhat.thermostat.client.ui.IconResource;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.utils.StreamUtils;
-
-public class HostIconDecorator implements HostDecorator {
-
-    private final HostFilter anyHost = new AnyHostMatcher();
-
-    @Override
-    public Decorator getDecorator() {
-        return new IconDecorator();
-    }
-
-    @Override
-    public HostFilter getFilter() {
-        return anyHost;
-    }
-
-    private static class IconDecorator implements Decorator {
-
-        private final IconDescriptor icon;
-
-        public IconDecorator() {
-            IconDescriptor icon = null;
-            try {
-                InputStream in = new FileInputStream(IconResource.HOST.getPath());
-                icon = new IconDescriptor(ByteBuffer.wrap(StreamUtils.readAll(in)));
-            } catch (IOException ioe) {
-                ioe.printStackTrace();
-            }
-            this.icon = icon;
-        }
-
-        @Override
-        public String getLabel(String originalLabel) {
-            return originalLabel;
-        }
-
-        @Override
-        public IconDescriptor getIconDescriptor() {
-            return icon;
-        }
-
-        @Override
-        public Quadrant getQuadrant() {
-            return Quadrant.MAIN;
-        }
-
-    }
-
-    private static class AnyHostMatcher implements HostFilter {
-        @Override
-        public boolean matches(HostRef toMatch) {
-            return true;
-        }
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/HostTreeDecoratorRegistry.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +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.internal;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-
-import com.redhat.thermostat.client.osgi.service.HostDecorator;
-import com.redhat.thermostat.common.ThermostatExtensionRegistry;
-
-class HostTreeDecoratorRegistry extends ThermostatExtensionRegistry<HostDecorator> {
-
-    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + HostDecorator.class.getName() + ")";
-
-    public HostTreeDecoratorRegistry(BundleContext context) throws InvalidSyntaxException {
-        super(context, FILTER, HostDecorator.class);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/Main.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,329 +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.internal;
-
-import java.awt.EventQueue;
-import java.util.concurrent.ExecutorService;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.JOptionPane;
-import javax.swing.JPopupMenu;
-import javax.swing.SwingConstants;
-import javax.swing.SwingUtilities;
-import javax.swing.UIManager;
-import javax.swing.UnsupportedLookAndFeelException;
-
-import com.redhat.swing.laf.dolphin.DolphinLookAndFeel;
-import com.redhat.thermostat.client.core.views.ClientConfigurationView;
-import com.redhat.thermostat.client.internal.config.ConnectionConfiguration;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.client.osgi.service.ApplicationService;
-import com.redhat.thermostat.client.ui.ClientConfigurationController;
-import com.redhat.thermostat.client.ui.ClientConfigurationSwing;
-import com.redhat.thermostat.client.ui.MainWindowController;
-import com.redhat.thermostat.client.ui.UiFacadeFactory;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.Constants;
-import com.redhat.thermostat.common.ThreadPoolTimerFactory;
-import com.redhat.thermostat.common.TimerFactory;
-import com.redhat.thermostat.common.appctx.ApplicationContext;
-import com.redhat.thermostat.common.config.ClientPreferences;
-import com.redhat.thermostat.common.config.StartupConfiguration;
-import com.redhat.thermostat.common.dao.DAOFactory;
-import com.redhat.thermostat.common.dao.MongoDAOFactory;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.common.storage.Connection;
-import com.redhat.thermostat.common.storage.Connection.ConnectionListener;
-import com.redhat.thermostat.common.storage.Connection.ConnectionStatus;
-import com.redhat.thermostat.common.storage.Connection.ConnectionType;
-import com.redhat.thermostat.common.storage.MongoStorageProvider;
-import com.redhat.thermostat.common.storage.StorageProvider;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-import com.redhat.thermostat.common.utils.OSGIUtils;
-import com.redhat.thermostat.utils.keyring.Keyring;
-
-public class Main {
-    
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private static final Logger logger = LoggingUtils.getLogger(Main.class);
-
-    private OSGIUtils serviceProvider;
-    private UiFacadeFactory uiFacadeFactory;
-    private DAOFactory daoFactory;
-    
-    public Main(Keyring keyring, UiFacadeFactory uiFacadeFactory, String[] args) {
-        ClientPreferences prefs = new ClientPreferences(keyring);
-        StartupConfiguration config = new ConnectionConfiguration(prefs);
-        StorageProvider connProv = new MongoStorageProvider(config);
-
-        DAOFactory daoFactory = new MongoDAOFactory(connProv);
-        TimerFactory timerFactory = new ThreadPoolTimerFactory(1);
-
-        init(OSGIUtils.getInstance(), uiFacadeFactory, daoFactory, timerFactory);
-    }
-
-    Main(OSGIUtils serviceProvider, UiFacadeFactory uiFacadeFactory, DAOFactory daoFactory, TimerFactory timerFactory) {
-        init(serviceProvider, uiFacadeFactory, daoFactory, timerFactory);
-    }
-
-    private void init(OSGIUtils serviceProvider, UiFacadeFactory uiFacadeFactory, DAOFactory daoFactory, TimerFactory timerFactory) {
-        this.serviceProvider = serviceProvider;
-        this.uiFacadeFactory = uiFacadeFactory;
-        this.daoFactory = daoFactory;
-        ApplicationContext.getInstance().setTimerFactory(timerFactory);
-    }
-
-    public void run() {
-        EventQueue.invokeLater(new Runnable() {
-
-            @Override
-            public void run() {
-
-                // check if the user has other preferences...
-                // not that there is any reason!
-                String laf = System.getProperty("swing.defaultlaf");
-                if (laf == null) {
-                    try {
-                        UIManager.setLookAndFeel(new DolphinLookAndFeel());
-                    } catch (UnsupportedLookAndFeelException e) {
-                        logger.log(Level.WARNING, "cannot use DolphinLookAndFeel");
-                    }
-                }
-
-                // TODO: move them in an appropriate place
-                JPopupMenu.setDefaultLightWeightPopupEnabled(false);
-                UIManager.getDefaults().put("OptionPane.buttonOrientation", SwingConstants.RIGHT);
-                UIManager.getDefaults().put("OptionPane.isYesLast", true);
-                UIManager.getDefaults().put("OptionPane.sameSizeButtons", true);
-                
-                showGui();
-            }
-
-        });
-
-        try {
-            uiFacadeFactory.awaitShutdown();
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-        }
-    }
-
-    private void showGui() {
-        ApplicationService appSrv = serviceProvider.getService(ApplicationService.class);
-        final ExecutorService service = appSrv.getApplicationExecutor();
-        service.execute(new ConnectorSetup(service));
-    }
-    
-    private class ConnectorSetup implements Runnable {
-        
-        private ExecutorService service;
-        public ConnectorSetup(ExecutorService service) {
-            this.service = service;
-        }
-        
-        @Override
-        public void run() {
-            
-            Connection connection = daoFactory.getConnection();
-            connection.setType(ConnectionType.LOCAL);
-            ConnectionListener connectionListener = new ConnectionHandler(connection, service);
-            connection.addListener(connectionListener);
-            try {
-                connection.connect();
-            } catch (Throwable t) {
-                logger.log(Level.WARNING, "connection attempt failed: ", t);
-            }
-        }
-    }
-    
-    private class Connector implements Runnable {
-        private Connection connection;
-        Connector(Connection connection) {
-            this.connection = connection;
-        }
-        
-        @Override
-        public void run() {
-            try {
-                connection.connect();
-            } catch (Throwable t) {
-                logger.log(Level.WARNING, "connection attempt failed: ", t);
-            }
-        }
-    }
-    
-    private class ConnectionAttemp implements Runnable {
-        private Connection connection;
-        private ExecutorService service;
-        public ConnectionAttemp(Connection connection, ExecutorService service) {
-            this.connection = connection;
-            this.service = service;
-        }
-        
-        @Override
-        public void run() {
-            Object[] options = {
-                    translator.localize(LocaleResources.CONNECTION_WIZARD),
-                    translator.localize(LocaleResources.CONNECTION_QUIT),
-            };
-            int n = JOptionPane
-                    .showOptionDialog(
-                            null,
-                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_DESCRIPTION),
-                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_TITLE),
-                            JOptionPane.OK_CANCEL_OPTION,
-                            JOptionPane.ERROR_MESSAGE, null, options,
-                            options[0]);
-
-            switch (n) {
-
-            case JOptionPane.CANCEL_OPTION:
-            case JOptionPane.CLOSED_OPTION:
-            case JOptionPane.NO_OPTION:
-                uiFacadeFactory
-                        .shutdown(Constants.EXIT_UNABLE_TO_CONNECT_TO_DATABASE);
-                break;
-
-            case JOptionPane.YES_OPTION:
-            default:
-                createPreferencesDialog(connection, service);
-                break;
-            }
-        }
-    }
-    
-    private void connect(Connection connection, ExecutorService service) {
-        service.execute(new Connector(connection));
-    }
-    
-    private class ConfigDialogListener implements ActionListener<ClientConfigurationView.Action> {
-        private Connection connection;
-        private ExecutorService service;
-        public ConfigDialogListener(Connection connection, ExecutorService service) {
-            this.connection = connection;
-            this.service = service;
-        }
-        
-        @Override
-        public void actionPerformed(ActionEvent<ClientConfigurationView.Action> actionEvent) {
-            switch (actionEvent.getActionId()) {
-            case CLOSE_CANCEL:
-                uiFacadeFactory.shutdown(Constants.EXIT_UNABLE_TO_CONNECT_TO_DATABASE);
-                break;
-            
-            case CLOSE_ACCEPT:
-            default:
-                connect(connection, service);
-                break;
-            }
-        }
-    }
-    
-    private void createPreferencesDialog(final Connection connection, final ExecutorService service) {
-
-        ClientPreferences prefs = new ClientPreferences(OSGIUtils.getInstance().getService(Keyring.class));
-        ClientConfigurationView configDialog = new ClientConfigurationSwing();
-        ClientConfigurationController controller =
-                new ClientConfigurationController(prefs, configDialog);
-        
-        configDialog.addListener(new ConfigDialogListener(connection, service));
-        controller.showDialog();
-    }
-    
-    private class ConnectionHandler implements ConnectionListener {
-        private boolean retry;
-        private Connection connection;
-        private ExecutorService service;
-        public ConnectionHandler(Connection connection, ExecutorService service) {
-            this.connection = connection;
-            this.retry = true;
-            this.service = service;
-        }
-        
-        private void showConnectionAttemptWarning() {
-            SwingUtilities.invokeLater(new ConnectionAttemp(connection, service));
-        }
-        
-        @Override
-        public void changed(ConnectionStatus newStatus) {
-            if (newStatus == ConnectionStatus.CONNECTED) {
-                
-                // register the storage, so other services can request it
-                daoFactory.registerDAOsAndStorageAsOSGiServices();
-                uiFacadeFactory.setHostInfoDao(daoFactory.getHostInfoDAO());
-                uiFacadeFactory.setCpuStatDao(daoFactory.getCpuStatDAO());
-                uiFacadeFactory.setMemoryStatDao(daoFactory.getMemoryStatDAO());
-                uiFacadeFactory.setNetworkInfoDao(daoFactory.getNetworkInterfaceInfoDAO());
-
-                uiFacadeFactory.setVmInfoDao(daoFactory.getVmInfoDAO());
-                uiFacadeFactory.setVmCpuStatDao(daoFactory.getVmCpuStatDAO());
-                uiFacadeFactory.setVmMemoryStatDao(daoFactory.getVmMemoryStatDAO());
-                uiFacadeFactory.setVmGcStatDao(daoFactory.getVmGcStatDAO());
-
-                showMainWindow();
-            } else if (newStatus == ConnectionStatus.FAILED_TO_CONNECT) {
-                if (retry) {
-                    retry = false;
-                    showConnectionAttemptWarning();
-                } else {
-                    JOptionPane.showMessageDialog(
-                            null,
-                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_DESCRIPTION),
-                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_TITLE),
-                            JOptionPane.ERROR_MESSAGE);
-                    uiFacadeFactory.shutdown(Constants.EXIT_UNABLE_TO_CONNECT_TO_DATABASE);
-                }
-            }
-        }
-    }
-
-
-    private void showMainWindow() {
-        SwingUtilities.invokeLater(new ShowMainWindow());
-    }
-    
-    private class ShowMainWindow implements Runnable {
-        @Override
-        public void run() {
-            MainWindowController mainController = uiFacadeFactory.getMainWindow();
-            mainController.showMainMainWindow();                        
-        }
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/MainView.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,102 +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.internal;
-
-import java.awt.event.MouseEvent;
-import java.util.List;
-
-import com.redhat.thermostat.client.core.HostFilter;
-import com.redhat.thermostat.client.core.VmFilter;
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.osgi.service.HostDecorator;
-import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.client.osgi.service.VmDecorator;
-import com.redhat.thermostat.client.osgi.service.VMContextAction;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.HostsVMsLoader;
-import com.redhat.thermostat.common.dao.Ref;
-
-public interface MainView {
-
-    enum Action {
-        VISIBLE,
-        HIDDEN,
-        HOST_VM_TREE_FILTER,
-        HOST_VM_SELECTION_CHANGED,
-        SHOW_AGENT_CONFIG,
-        SHOW_CLIENT_CONFIG,
-        SWITCH_HISTORY_MODE,
-        SHOW_ABOUT_DIALOG,
-        SHUTDOWN,
-        SHOW_VM_CONTEXT_MENU,
-        VM_CONTEXT_ACTION,
-    }
-
-    void addActionListener(ActionListener<Action> capture);
-
-    void updateTree(List<HostFilter> hostFilters, List<VmFilter> vmFilters,
-            List<HostDecorator> hostDecorators, List<VmDecorator> vmDecorators,
-            HostsVMsLoader any);
-
-    String getHostVmTreeFilterText();
-    
-    void setWindowTitle(String title);
-
-    void showMainWindow();
-
-    void hideMainWindow();
-
-    Ref getSelectedHostOrVm();
-
-    void setSubView(BasicView view);
-
-    void setStatusBarPrimaryStatus(String primaryStatus);
-    
-    /**
-     * Adds a menu item to the window. Assumes the menu path is valid (has a
-     * non-zero length) and doesn't collide with existing menus.
-     */
-    void addMenu(MenuAction action);
-
-    /**
-     * Removes a menu item to the window. Assumes the menu path is valid (has a
-     * non-zero length) and doesn't collide with existing menus.
-     */
-    void removeMenu(MenuAction action);
-
-    void showVMContextActions(List<VMContextAction> actions, MouseEvent e);
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/MainWindowControllerImpl.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,512 +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.internal;
-
-import java.awt.event.MouseEvent;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.osgi.framework.InvalidSyntaxException;
-
-import com.redhat.thermostat.client.core.HostFilter;
-import com.redhat.thermostat.client.core.VmFilter;
-import com.redhat.thermostat.client.core.views.AgentInformationDisplayView;
-import com.redhat.thermostat.client.core.views.AgentInformationViewProvider;
-import com.redhat.thermostat.client.core.views.ClientConfigViewProvider;
-import com.redhat.thermostat.client.core.views.ClientConfigurationView;
-import com.redhat.thermostat.client.internal.MainView.Action;
-import com.redhat.thermostat.client.internal.ui.swing.AboutDialog;
-import com.redhat.thermostat.client.osgi.service.HostDecorator;
-import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.client.osgi.service.VMContextAction;
-import com.redhat.thermostat.client.osgi.service.VmDecorator;
-import com.redhat.thermostat.client.ui.AgentInformationDisplayController;
-import com.redhat.thermostat.client.ui.AgentInformationDisplayModel;
-import com.redhat.thermostat.client.ui.ClientConfigurationController;
-import com.redhat.thermostat.client.ui.HostInformationController;
-import com.redhat.thermostat.client.ui.HostVmFilter;
-import com.redhat.thermostat.client.ui.MainWindowController;
-import com.redhat.thermostat.client.ui.SummaryController;
-import com.redhat.thermostat.client.ui.UiFacadeFactory;
-import com.redhat.thermostat.client.ui.VmInformationController;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.ApplicationInfo;
-import com.redhat.thermostat.common.DefaultHostsVMsLoader;
-import com.redhat.thermostat.common.HostsVMsLoader;
-import com.redhat.thermostat.common.ThermostatExtensionRegistry;
-import com.redhat.thermostat.common.Timer;
-import com.redhat.thermostat.common.Timer.SchedulingType;
-import com.redhat.thermostat.common.appctx.ApplicationContext;
-import com.redhat.thermostat.common.config.ClientPreferences;
-import com.redhat.thermostat.common.dao.HostInfoDAO;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.Ref;
-import com.redhat.thermostat.common.dao.VmInfoDAO;
-import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-import com.redhat.thermostat.common.utils.OSGIUtils;
-import com.redhat.thermostat.utils.keyring.Keyring;
-
-public class MainWindowControllerImpl implements MainWindowController {
-
-    private static final Logger logger = LoggingUtils.getLogger(MainWindowControllerImpl.class);
-
-    private final CopyOnWriteArrayList<HostFilter> hostFilters = new CopyOnWriteArrayList<>();
-    private final CopyOnWriteArrayList<VmFilter> vmFilters = new CopyOnWriteArrayList<>();
-
-    private final CopyOnWriteArrayList<HostDecorator> hostTreeDecorators = new CopyOnWriteArrayList<>();
-    private final CopyOnWriteArrayList<VmDecorator> vmTreeDecorators = new CopyOnWriteArrayList<>();
-
-    private Timer backgroundUpdater;
-
-    private MainView view;
-
-    private final HostInfoDAO hostsDAO;
-    private final VmInfoDAO vmsDAO;
-
-    private ApplicationInfo appInfo;
-
-    private UiFacadeFactory facadeFactory;
-
-    private MenuRegistry menuRegistry;
-    private ActionListener<ThermostatExtensionRegistry.Action> menuListener =
-            new ActionListener<ThermostatExtensionRegistry.Action>()
-    {
-        @Override
-        public void actionPerformed(
-            ActionEvent<ThermostatExtensionRegistry.Action> actionEvent) {
-            MenuAction action = (MenuAction) actionEvent.getPayload();
-
-            switch (actionEvent.getActionId()) {
-            case SERVICE_ADDED:
-                view.addMenu(action);
-                break;
-
-            case SERVICE_REMOVED:
-                view.removeMenu(action);
-                break;
-
-            default:
-                logger.log(Level.WARNING, "received unknown event from MenuRegistry: " +
-                                           actionEvent.getActionId());
-                break;
-            }
-        }
-    };
-
-    private HostVmFilter searchFilter;
-    private VmFilterRegistry vmFilterRegistry;
-    private HostFilterRegistry hostFilterRegistry;
-
-    private ActionListener<ThermostatExtensionRegistry.Action> hostFilterListener = new UpdateListAndTree<>(HostFilter.class, hostFilters);
-    private ActionListener<ThermostatExtensionRegistry.Action> vmFilterListener = new UpdateListAndTree<>(VmFilter.class, vmFilters);
-
-    private HostTreeDecoratorRegistry hostDecoratorRegistry;
-    private VMTreeDecoratorRegistry vmDecoratorRegistry;
-
-    private ActionListener<ThermostatExtensionRegistry.Action> hostDecoratorListener = new UpdateListAndTree<>(HostDecorator.class, hostTreeDecorators);
-    private ActionListener<ThermostatExtensionRegistry.Action> vmDecoratorListener = new UpdateListAndTree<>(VmDecorator.class, vmTreeDecorators);
-
-    private VMInformationRegistry vmInfoRegistry;
-    private ActionListener<ThermostatExtensionRegistry.Action> vmInfoRegistryListener =
-            new ActionListener<ThermostatExtensionRegistry.Action> ()
-    {
-        public void actionPerformed(com.redhat.thermostat.common.ActionEvent<ThermostatExtensionRegistry.Action>
-                                    actionEvent)
-        {
-            updateView();
-        };
-    };
-            
-    private boolean showHistory;
-
-    private VmInformationControllerProvider vmInfoControllerProvider;
-
-    public MainWindowControllerImpl(UiFacadeFactory facadeFactory, MainView view, RegistryFactory registryFactory, HostInfoDAO hostsDao, VmInfoDAO vmsDAO)
-    {
-        try {
-            vmFilterRegistry = registryFactory.createVmFilterRegistry();
-            hostFilterRegistry = registryFactory.createHostFilterRegistry();
-            hostDecoratorRegistry = registryFactory.createHostTreeDecoratorRegistry();
-            vmDecoratorRegistry = registryFactory.createVMTreeDecoratorRegistry();
-            menuRegistry = registryFactory.createMenuRegistry();
-            vmInfoRegistry = registryFactory.createVMInformationRegistry();
-            
-        } catch (InvalidSyntaxException e) {
-            throw new RuntimeException(e);
-        }
-
-        searchFilter = new HostVmFilter();
-        hostFilters.add(searchFilter);
-        vmFilters.add(searchFilter);
-        
-        this.facadeFactory = facadeFactory;
-
-        this.hostsDAO = hostsDao;
-        this.vmsDAO = vmsDAO;
-
-        initView(view);
-
-        vmInfoControllerProvider = new VmInformationControllerProvider();
-
-        appInfo = new ApplicationInfo();
-        view.setWindowTitle(appInfo.getName());
-        initializeTimer();
-
-        updateView();
-
-        installListenersAndStartRegistries();
-    }
-
-    /**
-     * This method is for testing purposes only
-     */
-    HostVmFilter getSearchFilter() {
-        return searchFilter;
-    }
-    
-    /**
-     * This method is for testing purposes only
-     */ 
-    List<VmDecorator> getVmTreeDecorators() {
-        return vmTreeDecorators;
-    }
-    
-    /**
-     * This method is for testing purposes only
-     */
-    ActionListener<ThermostatExtensionRegistry.Action> getMenuListener() {
-        return menuListener;
-    }
-    
-    private void initializeTimer() {
-        ApplicationContext ctx = ApplicationContext.getInstance();
-        backgroundUpdater = ctx.getTimerFactory().createTimer();
-        backgroundUpdater.setAction(new Runnable() {
-            @Override
-            public void run() {
-                doUpdateTreeAsync();
-            }
-        });
-        backgroundUpdater.setInitialDelay(0);
-        backgroundUpdater.setDelay(3);
-        backgroundUpdater.setTimeUnit(TimeUnit.SECONDS);
-        backgroundUpdater.setSchedulingType(SchedulingType.FIXED_RATE);
-    }
-
-    private void startBackgroundUpdates() {
-        backgroundUpdater.start();
-    }
-
-    public void stopBackgroundUpdates() {
-        backgroundUpdater.stop();
-    }
-
-    @Override
-    public void setHostVmTreeFilter(String filter) {
-        this.searchFilter.setFilter(filter);
-        doUpdateTreeAsync();
-    }
-
-    public void doUpdateTreeAsync() {
-        HostsVMsLoader loader = new DefaultHostsVMsLoader(hostsDAO, vmsDAO, !showHistory);
-        view.updateTree(hostFilters, vmFilters, hostTreeDecorators, vmTreeDecorators, loader);
-    }
-
-    private void initView(MainView mainView) {
-        this.view = mainView;
-        mainView.addActionListener(new ActionListener<MainView.Action>() {
-
-            @Override
-            public void actionPerformed(ActionEvent<MainView.Action> evt) {
-                MainView.Action action = evt.getActionId();
-                switch (action) {
-                case VISIBLE:
-                    startBackgroundUpdates();
-                    break;
-                case HIDDEN:
-                    stopBackgroundUpdates();
-                    break;
-                case HOST_VM_SELECTION_CHANGED:
-                    updateView();
-                    break;
-                case HOST_VM_TREE_FILTER:
-                    String filter = view.getHostVmTreeFilterText();
-                    setHostVmTreeFilter(filter);
-                    break;
-                case SHOW_AGENT_CONFIG:
-                    showAgentConfiguration();
-                    break;
-                case SHOW_CLIENT_CONFIG:
-                    showConfigureClientPreferences();
-                    break;
-                case SWITCH_HISTORY_MODE:
-                    switchHistoryMode();
-                    break;
-                case SHOW_ABOUT_DIALOG:
-                    showAboutDialog();
-                    break;
-                case SHOW_VM_CONTEXT_MENU:
-                    showContextMenu(evt);
-                    break;
-                case VM_CONTEXT_ACTION:
-                    handleVMHooks(evt);
-                    break;
-                case SHUTDOWN:
-                    shutdownApplication();
-                    break;
-                default:
-                    throw new IllegalStateException("unhandled action");
-                }
-            }
-
-        });
-    }
-
-    private void shutdownApplication() {
-        uninstallListenersAndStopRegistries();
-
-        view.hideMainWindow();
-        ApplicationContext.getInstance().getTimerFactory().shutdown();
-        shutdownOSGiFramework();
-    }
-
-    private void installListenersAndStartRegistries() {
-        menuRegistry.addActionListener(menuListener);
-        menuRegistry.start();
-
-        hostFilterRegistry.addActionListener(hostFilterListener);
-        hostFilterRegistry.start();
-
-        vmFilterRegistry.addActionListener(vmFilterListener);
-        vmFilterRegistry.start();
-
-        hostDecoratorRegistry.addActionListener(hostDecoratorListener);
-        hostDecoratorRegistry.start();
-
-        vmDecoratorRegistry.addActionListener(vmDecoratorListener);
-        vmDecoratorRegistry.start();
-
-        vmInfoRegistry.addActionListener(vmInfoRegistryListener);
-        vmInfoRegistry.start();
-    }
-
-    private void uninstallListenersAndStopRegistries() {
-        menuRegistry.removeActionListener(menuListener);
-        menuListener = null;
-        menuRegistry.stop();
-
-        hostFilterRegistry.removeActionListener(hostFilterListener);
-        hostFilterListener = null;
-        hostFilterRegistry.stop();
-
-        vmFilterRegistry.removeActionListener(vmFilterListener);
-        vmFilterListener = null;
-        vmFilterRegistry.stop();
-
-        hostDecoratorRegistry.removeActionListener(hostDecoratorListener);
-        hostDecoratorListener = null;
-        hostDecoratorRegistry.stop();
-
-        vmDecoratorRegistry.removeActionListener(vmDecoratorListener);
-        vmDecoratorListener = null;
-        vmDecoratorRegistry.stop();
-
-        vmInfoRegistry.removeActionListener(vmInfoRegistryListener);
-        vmInfoRegistryListener = null;
-        vmInfoRegistry.stop();
-    }
-
-    private void shutdownOSGiFramework() {
-        facadeFactory.shutdown();
-    }
-
-    private void showContextMenu(ActionEvent<Action> evt) {
-        List<VMContextAction> toShow = new ArrayList<>();
-        VmRef vm = (VmRef) view.getSelectedHostOrVm();
-
-        logger.log(Level.INFO, "registering applicable VMContextActions actions to show");
-
-        for (VMContextAction action : facadeFactory.getVMContextActions()) {
-            if (action.getFilter().matches(vm)) {
-                toShow.add(action);
-            }
-        }
-
-        view.showVMContextActions(toShow, (MouseEvent)evt.getPayload());
-    }
-
-    private void handleVMHooks(ActionEvent<MainView.Action> event) {
-        Object payload = event.getPayload();
-        if (payload instanceof VMContextAction) { 
-            try {
-                VMContextAction action = (VMContextAction) payload;
-                action.execute((VmRef) view.getSelectedHostOrVm());
-            } catch (Throwable error) {
-                logger.log(Level.SEVERE, "");
-            }
-        }
-    }
-    
-    @Override
-    public void showMainMainWindow() {
-        view.showMainWindow();
-    }
-
-    private void showAboutDialog() {
-        AboutDialog aboutDialog = new AboutDialog(appInfo);
-        aboutDialog.setModal(true);
-        aboutDialog.pack();
-        aboutDialog.setVisible(true);
-    }
-
-    private void showAgentConfiguration() {
-        AgentInformationDisplayModel model = new AgentInformationDisplayModel();
-        AgentInformationViewProvider viewProvider = OSGIUtils.getInstance().getService(AgentInformationViewProvider.class);
-        AgentInformationDisplayView view = viewProvider.createView();
-        AgentInformationDisplayController controller = new AgentInformationDisplayController(model, view);
-        controller.showView();
-    }
-
-    private void showConfigureClientPreferences() {
-        ClientPreferences prefs = new ClientPreferences(OSGIUtils.getInstance().getService(Keyring.class));
-        ClientConfigViewProvider viewProvider = OSGIUtils.getInstance().getService(ClientConfigViewProvider.class);
-        ClientConfigurationView view = viewProvider.createView();
-        ClientConfigurationController controller = new ClientConfigurationController(prefs, view);
-        controller.showDialog();
-    }
-
-    private void switchHistoryMode() {
-        showHistory = !showHistory;
-        doUpdateTreeAsync();
-    }
-
-    private void updateView() {
-        // this is quite an ugly method. there must be a cleaner way to do this
-        Ref ref = view.getSelectedHostOrVm();
-
-        if (ref == null) {
-            SummaryController controller = facadeFactory.getSummary();
-            view.setSubView(controller.getView());
-        } else if (ref instanceof HostRef) {
-            HostRef hostRef = (HostRef) ref;
-            HostInformationController hostController = facadeFactory.getHostController(hostRef);
-            view.setSubView(hostController.getView());
-            view.setStatusBarPrimaryStatus("host: " + hostRef.getHostName() + ", id: " + hostRef.getAgentId());
-        } else if (ref instanceof VmRef) {
-            VmRef vmRef = (VmRef) ref;
-            VmInformationController vmInformation =
-                    vmInfoControllerProvider.getVmInfoController(vmRef);
-            view.setSubView(vmInformation.getView());
-            view.setStatusBarPrimaryStatus("vm: " + vmRef.getName() + ", pid: " + vmRef.getStringID() +
-                                           ", host: " + vmRef.getAgent().getHostName());
-        } else {
-            throw new IllegalArgumentException("unknown type of ref");
-        }
-    }
-
-    private class UpdateListAndTree<T> implements ActionListener<ThermostatExtensionRegistry.Action> {
-
-        private final Class<T> extensionClass;
-        private final CopyOnWriteArrayList<T> extensionList;
-
-        public UpdateListAndTree(Class<T> extensionClass, CopyOnWriteArrayList<T> addRemoveExtensionsFrom) {
-            this.extensionClass = extensionClass;
-            this.extensionList = addRemoveExtensionsFrom;
-        }
-
-        @SuppressWarnings("unchecked")
-        @Override
-        public void actionPerformed(ActionEvent<com.redhat.thermostat.common.ThermostatExtensionRegistry.Action> actionEvent) {
-
-            Object payload = actionEvent.getPayload();
-            if (!extensionClass.isInstance(payload)) {
-                throw new IllegalArgumentException("unexpected payload type. expected a " + extensionClass.getName() + " but got " + payload.getClass().getName());
-            }
-
-            T filter = (T) payload;
-
-            switch (actionEvent.getActionId()) {
-            case SERVICE_ADDED:
-                extensionList.add(filter);
-                doUpdateTreeAsync();
-                break;
-
-            case SERVICE_REMOVED:
-                extensionList.remove(filter);
-                doUpdateTreeAsync();
-                break;
-
-            default:
-                logger.log(Level.WARNING, "received unknown event from ExtensionRegistry: " +
-                                           actionEvent.getActionId());
-                break;
-            }
-        }
-    }
-
-    private class VmInformationControllerProvider {
-        private VmInformationController lastSelectedVM;
-        private Map<VmRef, Integer> selectedForVM = new ConcurrentHashMap<>();
-        
-        VmInformationController getVmInfoController(VmRef vmRef) {
-            int id = 0;
-            if (lastSelectedVM != null) {
-                id = lastSelectedVM.getSelectedChildID();
-            }
-            
-            lastSelectedVM = facadeFactory.getVmController(vmRef);
-            if (!lastSelectedVM.selectChildID(id)) {
-                Integer _id = selectedForVM.get(vmRef);
-                id = _id != null? _id : 0;
-                lastSelectedVM.selectChildID(id);
-            }
-
-            selectedForVM.put(vmRef, id);
-            
-            return lastSelectedVM;
-        }
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/MenuRegistry.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +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.internal;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-
-import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.common.ThermostatExtensionRegistry;
-
-public class MenuRegistry extends ThermostatExtensionRegistry<MenuAction> {
-
-    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + MenuAction.class.getName() + ")";
-
-    public MenuRegistry(BundleContext context) throws InvalidSyntaxException {
-    	super(context, FILTER, MenuAction.class);
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/RegistryFactory.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +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.internal;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-
-class RegistryFactory {
-
-    private BundleContext context;
-    RegistryFactory(BundleContext context) {
-        this.context = context;
-    }
-
-    HostTreeDecoratorRegistry createHostTreeDecoratorRegistry() throws InvalidSyntaxException {
-        return new HostTreeDecoratorRegistry(context);
-    }
-    
-    VMTreeDecoratorRegistry createVMTreeDecoratorRegistry() throws InvalidSyntaxException {
-        return new VMTreeDecoratorRegistry(context);
-    }
-    
-    HostFilterRegistry createHostFilterRegistry() throws InvalidSyntaxException {
-        return new HostFilterRegistry(context);
-    }
-
-    VmFilterRegistry createVmFilterRegistry() throws InvalidSyntaxException {
-        return new VmFilterRegistry(context);
-    }
-    
-    MenuRegistry createMenuRegistry() throws InvalidSyntaxException {
-        return new MenuRegistry(context);
-    }
-    
-    VMInformationRegistry createVMInformationRegistry() throws InvalidSyntaxException {
-        return new VMInformationRegistry(context);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/UiFacadeFactoryImpl.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,199 +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.internal;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.concurrent.CountDownLatch;
-
-import org.osgi.framework.BundleContext;
-
-import com.redhat.thermostat.client.core.VmInformationService;
-import com.redhat.thermostat.client.core.views.HostInformationViewProvider;
-import com.redhat.thermostat.client.core.views.SummaryViewProvider;
-import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
-import com.redhat.thermostat.client.osgi.service.VMContextAction;
-import com.redhat.thermostat.client.ui.HostInformationController;
-import com.redhat.thermostat.client.ui.MainWindow;
-import com.redhat.thermostat.client.ui.MainWindowController;
-import com.redhat.thermostat.client.ui.SummaryController;
-import com.redhat.thermostat.client.ui.UiFacadeFactory;
-import com.redhat.thermostat.client.ui.VmInformationController;
-import com.redhat.thermostat.common.dao.CpuStatDAO;
-import com.redhat.thermostat.common.dao.HostInfoDAO;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.MemoryStatDAO;
-import com.redhat.thermostat.common.dao.NetworkInterfaceInfoDAO;
-import com.redhat.thermostat.common.dao.VmCpuStatDAO;
-import com.redhat.thermostat.common.dao.VmGcStatDAO;
-import com.redhat.thermostat.common.dao.VmInfoDAO;
-import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
-import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.common.utils.OSGIUtils;
-
-public class UiFacadeFactoryImpl implements UiFacadeFactory {
-
-    private CountDownLatch shutdown = new CountDownLatch(1);
-
-    private Collection<VmInformationService> vmInformationServices = new ArrayList<>();
-    private Collection<VMContextAction> contextAction = new ArrayList<>();
-
-    private BundleContext context;
-
-    private HostInfoDAO hostInfoDao;
-    private CpuStatDAO cpuStatDao;
-    private MemoryStatDAO memoryStatDao;
-    private NetworkInterfaceInfoDAO networkInfoDao;
-
-    private VmInfoDAO vmInfoDao;
-    private VmCpuStatDAO vmCpuStatDao;
-    private VmMemoryStatDAO vmMemoryStatDao;
-    private VmGcStatDAO vmGcStatDao;
-
-    private OSGIUtils serviceProvider;
-    
-    UiFacadeFactoryImpl(OSGIUtils serviceProvider, BundleContext context) {
-        this.context = context;
-        this.serviceProvider = serviceProvider;
-    }
-    
-    public UiFacadeFactoryImpl(BundleContext context) {
-        this(OSGIUtils.getInstance(), context);
-    }
-
-    @Override
-    public void setHostInfoDao(HostInfoDAO hostInfoDao) {
-        this.hostInfoDao = hostInfoDao;
-    }
-
-    public void setCpuStatDao(CpuStatDAO cpuStatDao) {
-        this.cpuStatDao = cpuStatDao;
-    }
-
-    public void setMemoryStatDao(MemoryStatDAO memoryStatDao) {
-        this.memoryStatDao = memoryStatDao;
-    }
-
-    public void setNetworkInfoDao(NetworkInterfaceInfoDAO networkInfoDao) {
-        this.networkInfoDao = networkInfoDao;
-    }
-
-    public void setVmInfoDao(VmInfoDAO vmInfoDao) {
-        this.vmInfoDao = vmInfoDao;
-    }
-
-    public void setVmCpuStatDao(VmCpuStatDAO vmCpuStatDao) {
-        this.vmCpuStatDao = vmCpuStatDao;
-    }
-
-    @Override
-    public void setVmMemoryStatDao(VmMemoryStatDAO vmMemoryStatDao) {
-        this.vmMemoryStatDao = vmMemoryStatDao;
-    }
-
-    @Override
-    public void setVmGcStatDao(VmGcStatDAO vmGcStatDao) {
-        this.vmGcStatDao = vmGcStatDao;
-    }
-
-    @Override
-    public MainWindowController getMainWindow() {
-        MainView mainView = new MainWindow();
-        RegistryFactory registryFactory = new RegistryFactory(context);
-        return new MainWindowControllerImpl(this, mainView, registryFactory, hostInfoDao, vmInfoDao);
-    }
-
-    @Override
-    public SummaryController getSummary() {
-        SummaryViewProvider viewProvider = serviceProvider.getService(SummaryViewProvider.class);
-        return new SummaryController(hostInfoDao, vmInfoDao, viewProvider);
-    }
-
-    @Override
-    public HostInformationController getHostController(HostRef ref) {
-        HostInformationViewProvider viewProvider = serviceProvider.getService(HostInformationViewProvider.class);
-        return new HostInformationController(hostInfoDao, networkInfoDao, cpuStatDao, memoryStatDao, ref, viewProvider);
-    }
-
-    @Override
-    public VmInformationController getVmController(VmRef ref) {
-        VmInformationViewProvider viewProvider = serviceProvider.getService(VmInformationViewProvider.class);
-        return new VmInformationController(this, vmInfoDao, vmCpuStatDao, vmMemoryStatDao, vmGcStatDao, ref, viewProvider);
-    }
-
-    @Override
-    public Collection<VmInformationService> getVmInformationServices() {
-        return vmInformationServices;
-    }
-
-    @Override
-    public void addVmInformationService(VmInformationService vmInfoService) {
-        vmInformationServices.add(vmInfoService);
-    }
-
-    @Override
-    public void removeVmInformationService(VmInformationService vmInfoService) {
-        vmInformationServices.remove(vmInfoService);
-    }
-
-    @Override
-    public Collection<VMContextAction> getVMContextActions() {
-        return contextAction;
-    }
-
-    @Override
-    public void addVMContextAction(VMContextAction service) {
-        contextAction.add(service);
-    }
-
-    @Override
-    public void shutdown() {
-        shutdown.countDown();
-    }
-
-    @Override
-    public void shutdown(int exitCode) {
-        // TODO implement returning exit codes
-        shutdown();
-    }
-
-    @Override
-    public void awaitShutdown() throws InterruptedException {
-        shutdown.await();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/VMInformationRegistry.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +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.internal;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-
-import com.redhat.thermostat.client.core.VmInformationService;
-import com.redhat.thermostat.common.ThermostatExtensionRegistry;
-
-class VMInformationRegistry extends ThermostatExtensionRegistry<VmInformationService> {
-
-    private static final String FILTER = "(&(" + Constants.OBJECTCLASS + "=" + VmInformationService.class.getName() + "))";
-    
-    public VMInformationRegistry(BundleContext context) throws InvalidSyntaxException {
-        super(context, FILTER, VmInformationService.class);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/VMTreeDecoratorRegistry.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +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.internal;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-
-import com.redhat.thermostat.client.osgi.service.VmDecorator;
-import com.redhat.thermostat.common.ThermostatExtensionRegistry;
-
-class VMTreeDecoratorRegistry extends ThermostatExtensionRegistry<VmDecorator> {
-
-    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + VmDecorator.class.getName() + ")";
-    
-    public VMTreeDecoratorRegistry(BundleContext context) throws InvalidSyntaxException {
-        super(context, FILTER, VmDecorator.class);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/VmFilterRegistry.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,53 +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.internal;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-
-import com.redhat.thermostat.client.core.VmFilter;
-import com.redhat.thermostat.common.ThermostatExtensionRegistry;
-
-class VmFilterRegistry extends ThermostatExtensionRegistry<VmFilter> {
-
-    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + VmFilter.class.getName() + ")";
-
-    public VmFilterRegistry(BundleContext context) throws InvalidSyntaxException {
-        super(context, FILTER, VmFilter.class);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/config/ConnectionConfiguration.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +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.internal.config;
-
-import com.redhat.thermostat.common.cli.AuthenticationConfiguration;
-import com.redhat.thermostat.common.config.ClientPreferences;
-import com.redhat.thermostat.common.config.StartupConfiguration;
-
-public class ConnectionConfiguration implements StartupConfiguration, AuthenticationConfiguration {
-
-    private final ClientPreferences clientPrefs;
-
-    public ConnectionConfiguration(ClientPreferences clientPrefs) {
-        this.clientPrefs = clientPrefs;
-    }
-
-    @Override
-    public String getDBConnectionString() {
-        return clientPrefs.getConnectionUrl();
-    }
-    
-    @Override
-    public String getPassword() {
-        return clientPrefs.getPassword();
-    }
-    
-    @Override
-    public String getUsername() {
-        return clientPrefs.getUserName();
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ApplicationServiceProvider.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,64 +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.internal.osgi;
-
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-
-import com.redhat.thermostat.client.osgi.service.ApplicationCache;
-import com.redhat.thermostat.client.osgi.service.ApplicationService;
-
-public class ApplicationServiceProvider implements ApplicationService {
-
-    private ApplicationCache cache = new ApplicationCache();
-
-    // NOTE: When merging with ApplicationContext, this could be provided by the same
-    // thread pool that does the timer scheduling. Not sure we want this though,
-    // as scheduled thread pools are always limited in number of threads (could lead to deadlocks
-    // when used carelessly).
-    private ExecutorService executor = Executors.newCachedThreadPool();
-
-    @Override
-    public ApplicationCache getApplicationCache() {
-        return cache;
-    }
-
-    @Override
-    public ExecutorService getApplicationExecutor() {
-        return executor;
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ContextActionServiceProvider.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +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.internal.osgi;
-
-import com.redhat.thermostat.client.osgi.service.ContextAction;
-
-public class ContextActionServiceProvider implements ContextAction {
-  
-    @Override
-    public String getName() {
-        return "system context";
-    }
-
-    @Override
-    public String getDescription() {
-        return "system context";
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ThermostatActivator.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +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.internal.osgi;
-
-import java.util.Arrays;
-
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-
-import com.redhat.thermostat.client.core.views.AgentInformationViewProvider;
-import com.redhat.thermostat.client.core.views.ClientConfigViewProvider;
-import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
-import com.redhat.thermostat.client.core.views.HostInformationViewProvider;
-import com.redhat.thermostat.client.core.views.HostMemoryViewProvider;
-import com.redhat.thermostat.client.core.views.HostOverviewViewProvider;
-import com.redhat.thermostat.client.core.views.SummaryViewProvider;
-import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
-import com.redhat.thermostat.client.core.views.VmGcViewProvider;
-import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
-import com.redhat.thermostat.client.core.views.VmOverviewViewProvider;
-import com.redhat.thermostat.client.internal.GUIClientCommand;
-import com.redhat.thermostat.client.internal.HostIconDecorator;
-import com.redhat.thermostat.client.internal.Main;
-import com.redhat.thermostat.client.internal.UiFacadeFactoryImpl;
-import com.redhat.thermostat.client.osgi.service.HostDecorator;
-import com.redhat.thermostat.client.swing.SwingAgentInformationViewProvider;
-import com.redhat.thermostat.client.swing.SwingClientConfigurationViewProvider;
-import com.redhat.thermostat.client.swing.SwingHostCpuViewProvider;
-import com.redhat.thermostat.client.swing.SwingHostInformationViewProvider;
-import com.redhat.thermostat.client.swing.SwingHostMemoryViewProvider;
-import com.redhat.thermostat.client.swing.SwingHostOverviewViewProvider;
-import com.redhat.thermostat.client.swing.SwingSummaryViewProvider;
-import com.redhat.thermostat.client.swing.SwingVmCpuViewProvider;
-import com.redhat.thermostat.client.swing.SwingVmGcViewProvider;
-import com.redhat.thermostat.client.swing.SwingVmInformationViewProvider;
-import com.redhat.thermostat.client.swing.SwingVmOverviewViewProvider;
-import com.redhat.thermostat.client.ui.UiFacadeFactory;
-import com.redhat.thermostat.common.cli.CommandRegistry;
-import com.redhat.thermostat.common.cli.CommandRegistryImpl;
-import com.redhat.thermostat.utils.keyring.Keyring;
-
-public class ThermostatActivator implements BundleActivator {
-
-    private VmInformationServiceTracker vmInfoServiceTracker;
-    private VMContextActionServiceTracker contextActionTracker;
-
-    private CommandRegistry cmdReg;
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Override
-    public void start(final BundleContext context) throws Exception {
-        
-        HostDecorator hostDecorator = new HostIconDecorator();
-        context.registerService(HostDecorator.class.getName(), hostDecorator, null);
-        
-        // Host views
-        HostInformationViewProvider infoProvider = new SwingHostInformationViewProvider();
-        context.registerService(HostInformationViewProvider.class.getName(), infoProvider, null);
-        HostCpuViewProvider cpuProvider = new SwingHostCpuViewProvider();
-        context.registerService(HostCpuViewProvider.class.getName(), cpuProvider, null);
-        HostOverviewViewProvider provider = new SwingHostOverviewViewProvider();
-        context.registerService(HostOverviewViewProvider.class.getName(), provider, null);
-        HostMemoryViewProvider memoryProvider = new SwingHostMemoryViewProvider();
-        context.registerService(HostMemoryViewProvider.class.getName(), memoryProvider, null);
-        
-        // Vm views
-        VmInformationViewProvider vmInfoProvider = new SwingVmInformationViewProvider();
-        context.registerService(VmInformationViewProvider.class.getName(), vmInfoProvider, null);
-        VmOverviewViewProvider vmOverviewProvider = new SwingVmOverviewViewProvider();
-        context.registerService(VmOverviewViewProvider.class.getName(), vmOverviewProvider, null);
-        VmGcViewProvider vmGcProvider = new SwingVmGcViewProvider();
-        context.registerService(VmGcViewProvider.class.getName(), vmGcProvider, null);
-        VmCpuViewProvider vmCpuProvider = new SwingVmCpuViewProvider();
-        context.registerService(VmCpuViewProvider.class.getName(), vmCpuProvider, null);
-        
-        // Summary view
-        SummaryViewProvider summaryViewProvider = new SwingSummaryViewProvider();
-        context.registerService(SummaryViewProvider.class.getName(), summaryViewProvider, null);
-
-        // AgentInformation and ClientConfiguraiton view
-        AgentInformationViewProvider agentViewProvider = new SwingAgentInformationViewProvider();
-        context.registerService(AgentInformationViewProvider.class.getName(), agentViewProvider, null);
-        ClientConfigViewProvider clientConfigViewProvider = new SwingClientConfigurationViewProvider();
-        context.registerService(ClientConfigViewProvider.class, clientConfigViewProvider, null);
-        
-        ServiceTracker tracker = new ServiceTracker(context, Keyring.class.getName(), null) {
-            @Override
-            public Object addingService(ServiceReference reference) {
-              
-                Keyring keyring = (Keyring) context.getService(reference);
-                
-                UiFacadeFactory uiFacadeFactory = new UiFacadeFactoryImpl(context);
-
-                vmInfoServiceTracker = new VmInformationServiceTracker(context, uiFacadeFactory);
-                vmInfoServiceTracker.open();
-                contextActionTracker = new VMContextActionServiceTracker(context, uiFacadeFactory);
-                contextActionTracker.open();
-
-                cmdReg = new CommandRegistryImpl(context);
-                Main main = new Main(keyring, uiFacadeFactory, new String[0]);
-                
-                GUIClientCommand cmd = new GUIClientCommand(main);
-                cmd.setBundleContext(context);
-                cmdReg.registerCommands(Arrays.asList(cmd));
-                
-                return super.addingService(reference);
-            }
-        };
-        tracker.open();
-    }
-
-    @Override
-    public void stop(BundleContext context) throws Exception {
-        vmInfoServiceTracker.close(); //context.removeServiceListener(vmInfoServiceTracker);
-        contextActionTracker.close();
-        cmdReg.unregisterCommands();
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/VMContextActionServiceTracker.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +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.internal.osgi;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-
-import com.redhat.thermostat.client.osgi.service.VMContextAction;
-import com.redhat.thermostat.client.ui.UiFacadeFactory;
-
-@SuppressWarnings("rawtypes")
-class VMContextActionServiceTracker extends ServiceTracker {
-
-    private UiFacadeFactory uiFacadeFactory;
-
-    private BundleContext context;
-
-    @SuppressWarnings("unchecked")
-    VMContextActionServiceTracker(BundleContext context, UiFacadeFactory uiFacadeFactory) {
-        super(context, VMContextAction.class.getName(), null);
-        this.context = context;
-        this.uiFacadeFactory = uiFacadeFactory;
-    }
-
-    @Override
-    public Object addingService(ServiceReference reference) {
-        @SuppressWarnings("unchecked")
-        VMContextAction service = (VMContextAction) context.getService(reference);
-        uiFacadeFactory.addVMContextAction(service);
-        return service;
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/VmInformationServiceTracker.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +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.internal.osgi;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-
-import com.redhat.thermostat.client.core.VmInformationService;
-import com.redhat.thermostat.client.ui.UiFacadeFactory;
-
-class VmInformationServiceTracker extends ServiceTracker {
-
-    private UiFacadeFactory uiFacadeFactory;
-
-    private BundleContext context;
-
-    VmInformationServiceTracker(BundleContext context, UiFacadeFactory uiFacadeFactory) {
-        super(context, VmInformationService.class.getName(), null);
-        this.context = context;
-        this.uiFacadeFactory = uiFacadeFactory;
-    }
-
-    @Override
-    public Object addingService(ServiceReference reference) {
-        VmInformationService service = (VmInformationService) super.addingService(reference);
-        uiFacadeFactory.addVmInformationService(service);
-        return service;
-    }
-
-    @Override
-    public void removedService(ServiceReference reference, Object service) {
-        uiFacadeFactory.removeVmInformationService((VmInformationService)service);
-        super.removedService(reference, service);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/ui/swing/AboutDialog.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,288 +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.internal.ui.swing;
-
-import java.awt.Cursor;
-import java.awt.Desktop;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.net.URI;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.GroupLayout;
-import javax.swing.GroupLayout.Alignment;
-import javax.swing.Icon;
-import javax.swing.JButton;
-import javax.swing.JDialog;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.LayoutStyle.ComponentPlacement;
-import javax.swing.SwingConstants;
-import javax.swing.SwingWorker;
-
-import javax.swing.border.TitledBorder;
-
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.client.ui.IconResource;
-import com.redhat.thermostat.client.ui.UIResources;
-import com.redhat.thermostat.common.ApplicationInfo;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-
-public class AboutDialog extends JDialog {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-    private static final long serialVersionUID = -7611616871710076514L;
-
-    private static final Logger logger = LoggingUtils.getLogger(AboutDialog.class);
-
-    private String name;
-    private String description;
-    private String version;
-    private Icon icon;
-    private String copyright;
-    private String license;
-    private String website;
-    private String email;
-    
-    /**
-     * Create the dialog.
-     * @param applicationInfo 
-     */
-    public AboutDialog(ApplicationInfo appInfo) {
-        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-        setResizable(false);
-        
-        name = appInfo.getName();
-        description = appInfo.getDescription();
-        version = appInfo.getVersion().getVersionNumber();
-        icon = IconResource.QUESTION.getIcon();
-        copyright = appInfo.getCopyright();
-        license = appInfo.getLicenseSummary();
-        website = appInfo.getWebsite();
-        email = appInfo.getEmail();
-        
-        initComponents();
-    }
-    
-    private void initComponents() {
-        setBounds(100, 100, 450, 338);
-        
-        UIResources res = UIResources.getInstance();
-        
-        JPanel panel = new JPanel();
-        panel.setBorder(new TitledBorder(""));
-        
-        JButton closeButton = new JButton(translator.localize(LocaleResources.BUTTON_CLOSE));
-        closeButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                AboutDialog.this.setVisible(false);
-                AboutDialog.this.dispose();  
-            }
-        });
-        
-        GroupLayout groupLayout = new GroupLayout(getContentPane());
-        groupLayout.setHorizontalGroup(
-            groupLayout.createParallelGroup(Alignment.TRAILING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
-                        .addComponent(closeButton, GroupLayout.PREFERRED_SIZE, 92, GroupLayout.PREFERRED_SIZE)
-                        .addComponent(panel, GroupLayout.DEFAULT_SIZE, 424, Short.MAX_VALUE))
-                    .addContainerGap())
-        );
-        groupLayout.setVerticalGroup(
-            groupLayout.createParallelGroup(Alignment.LEADING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addComponent(panel, GroupLayout.DEFAULT_SIZE, 245, Short.MAX_VALUE)
-                    .addGap(18)
-                    .addComponent(closeButton)
-                    .addGap(9))
-        );
-        
-        JLabel iconLabel = new JLabel("");
-        iconLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        
-        iconLabel.setIcon(icon);
-        
-        JLabel versionLabel = new JLabel(version);
-        versionLabel.setFont(res.footerFont());
-        versionLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        
-        JLabel nameLabel = new JLabel(name);
-        nameLabel.setFont(res.headerFont());
-        nameLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        
-        JLabel descriptionLabel = new JLabel(description);
-        descriptionLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        descriptionLabel.setFont(res.standardFont());
-        
-        JLabel homePageLabel = new JLabel(website);
-        homePageLabel.setForeground(res.hyperlinkColor());
-        homePageLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        homePageLabel.setFont(res.footerFont());        
-        homePageLabel.addMouseListener(new Browse(homePageLabel));
-
-        JLabel copyrightLabel = new JLabel(copyright);
-        copyrightLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        copyrightLabel.setFont(res.footerFont());
-        
-        JLabel licenseString = new JLabel(license);
-        licenseString.setHorizontalAlignment(SwingConstants.CENTER);
-        licenseString.setFont(res.footerFont());
-        
-        JLabel emailLabel = new JLabel(email);
-        emailLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        emailLabel.setForeground(res.hyperlinkColor());
-        emailLabel.setFont(res.footerFont());
-        emailLabel.addMouseListener(new Mailer(emailLabel));
-        
-        GroupLayout gl_panel = new GroupLayout(panel);
-        gl_panel.setHorizontalGroup(
-            gl_panel.createParallelGroup(Alignment.TRAILING)
-                .addGroup(gl_panel.createSequentialGroup()
-                    .addContainerGap()
-                    .addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
-                        .addComponent(iconLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(nameLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(versionLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(descriptionLabel, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(copyrightLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(licenseString, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(emailLabel, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(homePageLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE))
-                    .addContainerGap())
-        );
-        gl_panel.setVerticalGroup(
-            gl_panel.createParallelGroup(Alignment.LEADING)
-                .addGroup(gl_panel.createSequentialGroup()
-                    .addContainerGap()
-                    .addComponent(iconLabel)
-                    .addGap(4)
-                    .addComponent(nameLabel, GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addComponent(versionLabel, GroupLayout.DEFAULT_SIZE, 13, Short.MAX_VALUE)
-                    .addPreferredGap(ComponentPlacement.UNRELATED)
-                    .addComponent(descriptionLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                    .addGap(12)
-                    .addComponent(homePageLabel, GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE)
-                    .addGap(3)
-                    .addComponent(emailLabel, GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addComponent(copyrightLabel, GroupLayout.DEFAULT_SIZE, 13, Short.MAX_VALUE)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addComponent(licenseString, GroupLayout.DEFAULT_SIZE, 13, Short.MAX_VALUE)
-                    .addContainerGap())
-        );
-        panel.setLayout(gl_panel);
-        getContentPane().setLayout(groupLayout);
-    }
-    
-    private abstract class HyperLinkAction extends MouseAdapter {
-        
-        private JLabel hyperLinkLabel;
-        public HyperLinkAction(JLabel hyperLinkLabel) {
-            this.hyperLinkLabel = hyperLinkLabel;
-        }
-        
-        @Override
-        public void mouseEntered(MouseEvent e) {
-            hyperLinkLabel.setForeground(UIResources.getInstance().hyperlinkActiveColor());
-            Cursor cursor = new Cursor(Cursor.HAND_CURSOR);
-            setCursor(cursor);
-        }
-        @Override
-        public void mouseExited(MouseEvent e) {
-            hyperLinkLabel.setForeground(UIResources.getInstance().hyperlinkColor());
-            Cursor cursor = new Cursor(Cursor.DEFAULT_CURSOR);
-            setCursor(cursor);
-        }
-        
-        @Override
-        public void mouseClicked(MouseEvent e) {
-            if (Desktop.isDesktopSupported()) {
-                new SwingWorker<Void, Void>() {
-                    @Override
-                    protected Void doInBackground() throws Exception {
-                        doAction();
-                        return null;
-                    }
-                    @Override
-                    protected void done() {
-                        hyperLinkLabel.setForeground(UIResources.getInstance().hyperlinkColor());
-                    }
-                }.execute();
-            }
-        }
-        
-        protected abstract void doAction();
-    }
-    
-    private class Mailer extends HyperLinkAction {
-        public Mailer(JLabel hyperLinkLabel) {
-            super(hyperLinkLabel);
-        }
-
-        @Override
-        protected void doAction() {
-            try {
-                Desktop.getDesktop().mail(new URI("mailto:" + email));
-            } catch (Exception ex) {
-                logger.log(Level.WARNING, "Cannot send mail to Thermosat mail", ex);
-            }
-        }
-    }
-    
-    private class Browse extends HyperLinkAction {
-        public Browse(JLabel hyperLinkLabel) {
-            super(hyperLinkLabel);
-        }
-        
-        @Override
-        protected void doAction() {
-            try {
-                Desktop.getDesktop().browse(new URI(website));
-            } catch (Exception ex) {
-                logger.log(Level.WARNING, "Cannot open Thermostat website URL", ex);
-            }
-        }
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/ui/swing/WrapLayout.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,229 +0,0 @@
-/*
- * Copyright 2008 Rob Camick, 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.
- */
-
-/*
- * Taken from http://tips4java.wordpress.com/2008/11/06/wrap-layout/
- *
- * The about page (http://tips4java.wordpress.com/about/) says this:
- * "You are free to use and/or modify any or all code posted on the Java Tips
- * Weblog without restriction. A credit in the code comments would be nice,
- * but not in any way mandatory."
- */
-
-package com.redhat.thermostat.client.internal.ui.swing;
-
-import java.awt.*;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-
-/**
- *  FlowLayout subclass that fully supports wrapping of components.
- */
-public class WrapLayout extends FlowLayout {
-
-    private static final long serialVersionUID = -9169664895883997422L;
-
-    /**
-	* Constructs a new <code>WrapLayout</code> with a left
-	* alignment and a default 5-unit horizontal and vertical gap.
-	*/
-	public WrapLayout()
-	{
-		super();
-	}
-
-	/**
-	* Constructs a new <code>FlowLayout</code> with the specified
-	* alignment and a default 5-unit horizontal and vertical gap.
-	* The value of the alignment argument must be one of
-	* <code>WrapLayout</code>, <code>WrapLayout</code>,
-	* or <code>WrapLayout</code>.
-	* @param align the alignment value
-	*/
-	public WrapLayout(int align)
-	{
-		super(align);
-	}
-
-	/**
-	* Creates a new flow layout manager with the indicated alignment
-	* and the indicated horizontal and vertical gaps.
-	* <p>
-	* The value of the alignment argument must be one of
-	* <code>WrapLayout</code>, <code>WrapLayout</code>,
-	* or <code>WrapLayout</code>.
-	* @param align the alignment value
-	* @param hgap the horizontal gap between components
-	* @param vgap the vertical gap between components
-	*/
-	public WrapLayout(int align, int hgap, int vgap)
-	{
-		super(align, hgap, vgap);
-	}
-
-	/**
-	* Returns the preferred dimensions for this layout given the
-	* <i>visible</i> components in the specified target container.
-	* @param target the component which needs to be laid out
-	* @return the preferred dimensions to lay out the
-	* subcomponents of the specified container
-	*/
-	@Override
-	public Dimension preferredLayoutSize(Container target)
-	{
-		return layoutSize(target, true);
-	}
-
-	/**
-	* Returns the minimum dimensions needed to layout the <i>visible</i>
-	* components contained in the specified target container.
-	* @param target the component which needs to be laid out
-	* @return the minimum dimensions to lay out the
-	* subcomponents of the specified container
-	*/
-	@Override
-	public Dimension minimumLayoutSize(Container target)
-	{
-		Dimension minimum = layoutSize(target, false);
-		minimum.width -= (getHgap() + 1);
-		return minimum;
-	}
-
-	/**
-	* Returns the minimum or preferred dimension needed to layout the target
-	* container.
-	*
-	* @param target target to get layout size for
-	* @param preferred should preferred size be calculated
-	* @return the dimension to layout the target container
-	*/
-	private Dimension layoutSize(Container target, boolean preferred)
-	{
-	synchronized (target.getTreeLock())
-	{
-		//  Each row must fit with the width allocated to the containter.
-		//  When the container width = 0, the preferred width of the container
-		//  has not yet been calculated so lets ask for the maximum.
-
-		int targetWidth = target.getSize().width;
-
-		if (targetWidth == 0)
-			targetWidth = Integer.MAX_VALUE;
-
-		int hgap = getHgap();
-		int vgap = getVgap();
-		Insets insets = target.getInsets();
-		int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
-		int maxWidth = targetWidth - horizontalInsetsAndGap;
-
-		//  Fit components into the allowed width
-
-		Dimension dim = new Dimension(0, 0);
-		int rowWidth = 0;
-		int rowHeight = 0;
-
-		int nmembers = target.getComponentCount();
-
-		for (int i = 0; i < nmembers; i++)
-		{
-			Component m = target.getComponent(i);
-
-			if (m.isVisible())
-			{
-				Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
-
-				//  Can't add the component to current row. Start a new row.
-
-				if (rowWidth + d.width > maxWidth)
-				{
-					addRow(dim, rowWidth, rowHeight);
-					rowWidth = 0;
-					rowHeight = 0;
-				}
-
-				//  Add a horizontal gap for all components after the first
-
-				if (rowWidth != 0)
-				{
-					rowWidth += hgap;
-				}
-
-				rowWidth += d.width;
-				rowHeight = Math.max(rowHeight, d.height);
-			}
-		}
-
-		addRow(dim, rowWidth, rowHeight);
-
-		dim.width += horizontalInsetsAndGap;
-		dim.height += insets.top + insets.bottom + vgap * 2;
-
-		//	When using a scroll pane or the DecoratedLookAndFeel we need to
-		//  make sure the preferred size is less than the size of the
-		//  target containter so shrinking the container size works
-		//  correctly. Removing the horizontal gap is an easy way to do this.
-
-		Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);
-
-		if (scrollPane != null)
-		{
-			dim.width -= (hgap + 1);
-		}
-
-		return dim;
-	}
-	}
-
-	/*
-	 *  A new row has been completed. Use the dimensions of this row
-	 *  to update the preferred size for the container.
-	 *
-	 *  @param dim update the width and height when appropriate
-	 *  @param rowWidth the width of the row to add
-	 *  @param rowHeight the height of the row to add
-	 */
-	private void addRow(Dimension dim, int rowWidth, int rowHeight)
-	{
-		dim.width = Math.max(dim.width, rowWidth);
-
-		if (dim.height > 0)
-		{
-			dim.height += getVgap();
-		}
-
-		dim.height += rowHeight;
-	}
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/swing/SwingAgentInformationViewProvider.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +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;
-
-import com.redhat.thermostat.client.core.views.AgentInformationDisplayView;
-import com.redhat.thermostat.client.core.views.AgentInformationViewProvider;
-import com.redhat.thermostat.client.ui.AgentInformationDisplayFrame;
-
-public class SwingAgentInformationViewProvider implements
-        AgentInformationViewProvider {
-
-    @Override
-    public AgentInformationDisplayView createView() {
-        return new AgentInformationDisplayFrame();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/swing/SwingClientConfigurationViewProvider.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +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;
-
-import com.redhat.thermostat.client.core.views.ClientConfigViewProvider;
-import com.redhat.thermostat.client.core.views.ClientConfigurationView;
-import com.redhat.thermostat.client.ui.ClientConfigurationSwing;
-
-public class SwingClientConfigurationViewProvider implements
-        ClientConfigViewProvider {
-
-    @Override
-    public ClientConfigurationView createView() {
-        return new ClientConfigurationSwing();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/swing/SwingHostCpuViewProvider.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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;
-
-import com.redhat.thermostat.client.core.views.HostCpuView;
-import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
-import com.redhat.thermostat.client.ui.HostCpuPanel;
-
-public class SwingHostCpuViewProvider implements HostCpuViewProvider {
-
-    @Override
-    public HostCpuView createView() {
-        return new HostCpuPanel();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/swing/SwingHostInformationViewProvider.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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;
-
-import com.redhat.thermostat.client.core.views.HostInformationView;
-import com.redhat.thermostat.client.core.views.HostInformationViewProvider;
-import com.redhat.thermostat.client.ui.HostInformationPanel;
-
-public class SwingHostInformationViewProvider implements HostInformationViewProvider {
-
-    @Override
-    public HostInformationView createView() {
-        return new HostInformationPanel();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/swing/SwingHostMemoryViewProvider.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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;
-
-import com.redhat.thermostat.client.core.views.HostMemoryView;
-import com.redhat.thermostat.client.core.views.HostMemoryViewProvider;
-import com.redhat.thermostat.client.ui.HostMemoryPanel;
-
-public class SwingHostMemoryViewProvider implements HostMemoryViewProvider {
-
-    @Override
-    public HostMemoryView createView() {
-        return new HostMemoryPanel();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/swing/SwingHostOverviewViewProvider.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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;
-
-import com.redhat.thermostat.client.core.views.HostOverviewView;
-import com.redhat.thermostat.client.core.views.HostOverviewViewProvider;
-import com.redhat.thermostat.client.ui.HostOverviewPanel;
-
-public class SwingHostOverviewViewProvider implements HostOverviewViewProvider {
-
-    @Override
-    public HostOverviewView createView() {
-        return new HostOverviewPanel();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/swing/SwingSummaryViewProvider.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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;
-
-import com.redhat.thermostat.client.core.views.SummaryView;
-import com.redhat.thermostat.client.core.views.SummaryViewProvider;
-import com.redhat.thermostat.client.ui.SummaryPanel;
-
-public class SwingSummaryViewProvider implements SummaryViewProvider {
-
-    @Override
-    public SummaryView createView() {
-        return new SummaryPanel();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/swing/SwingVmCpuViewProvider.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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;
-
-import com.redhat.thermostat.client.core.views.VmCpuView;
-import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
-import com.redhat.thermostat.client.ui.VmCpuPanel;
-
-public class SwingVmCpuViewProvider implements VmCpuViewProvider {
-
-    @Override
-    public VmCpuView createView() {
-        return new VmCpuPanel();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/swing/SwingVmGcViewProvider.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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;
-
-import com.redhat.thermostat.client.core.views.VmGcView;
-import com.redhat.thermostat.client.core.views.VmGcViewProvider;
-import com.redhat.thermostat.client.ui.VmGcPanel;
-
-public class SwingVmGcViewProvider implements VmGcViewProvider {
-
-    @Override
-    public VmGcView createView() {
-        return new VmGcPanel();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/swing/SwingVmInformationViewProvider.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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;
-
-import com.redhat.thermostat.client.core.views.VmInformationView;
-import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
-import com.redhat.thermostat.client.ui.VmInformationPanel;
-
-public class SwingVmInformationViewProvider implements VmInformationViewProvider {
-
-    @Override
-    public VmInformationView createView() {
-        return new VmInformationPanel();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/swing/SwingVmOverviewViewProvider.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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;
-
-import com.redhat.thermostat.client.core.views.VmOverviewView;
-import com.redhat.thermostat.client.core.views.VmOverviewViewProvider;
-import com.redhat.thermostat.client.ui.VmOverviewPanel;
-
-public class SwingVmOverviewViewProvider implements VmOverviewViewProvider {
-
-    @Override
-    public VmOverviewView createView() {
-        return new VmOverviewPanel();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/AgentInformationDisplayFrame.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,462 +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.ui;
-
-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.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 DefaultTableModel();
-        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;
-            }
-
-            int rowIndex = e.getFirstIndex();
-            String backendName = (String) backendsTableModel.getValueAt(rowIndex, 0);
-            ActionEvent<ConfigurationAction> event = new ActionEvent<>(AgentInformationDisplayFrame.this,
-                    ConfigurationAction.SHOW_BACKEND_DESCRIPTION);
-            event.setPayload(backendName);
-            fireAction(event);
-        }
-
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/ClientConfigurationPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,138 +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.ui;
-
-import javax.swing.GroupLayout;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JPasswordField;
-import javax.swing.JTextField;
-import javax.swing.GroupLayout.Alignment;
-import javax.swing.LayoutStyle.ComponentPlacement;
-
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.locale.Translate;
-
-import javax.swing.border.TitledBorder;
-import javax.swing.JCheckBox;
-
-@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/core/src/main/java/com/redhat/thermostat/client/ui/ClientConfigurationSwing.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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.ui;
-
-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.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.swing.EdtHelper;
-
-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/core/src/main/java/com/redhat/thermostat/client/ui/Components.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +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.ui;
-
-import javax.swing.BorderFactory;
-import javax.swing.JLabel;
-import javax.swing.SwingConstants;
-import javax.swing.border.Border;
-
-public class Components {
-    public static JLabel header(String text) {
-        JLabel label = new JLabel(HtmlTextBuilder.boldHtml(text));
-        label.setHorizontalAlignment(SwingConstants.LEADING);
-        return label;
-    }
-
-    public static JLabel label(String string) {
-        JLabel label = new JLabel(string);
-        label.setHorizontalAlignment(SwingConstants.TRAILING);
-        return label;
-    }
-
-    public static Border smallBorder() {
-        return BorderFactory.createEmptyBorder(5, 5, 5, 5);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/DecoratedDefaultMutableTreeNode.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +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.ui;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.tree.DefaultMutableTreeNode;
-
-import com.redhat.thermostat.client.osgi.service.VmDecorator;
-import com.redhat.thermostat.common.dao.Ref;
-
-class DecoratedDefaultMutableTreeNode  extends DefaultMutableTreeNode {
-    
-    private List<Decorator> decorators;
-    
-    DecoratedDefaultMutableTreeNode(Ref ref) {
-        super(ref);
-        decorators = new ArrayList<>();
-    }
-    
-    public void addDecorator(Decorator decorator) {
-        decorators.add(decorator);
-    }
-    
-    public void setDecorators(List<Decorator> decorators) {
-        this.decorators = decorators;
-    }
-    
-    public List<Decorator> getDecorators() {
-        return decorators;
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostCpuPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,289 +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.ui;
-
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.FlowLayout;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-
-import javax.swing.GroupLayout;
-import javax.swing.GroupLayout.Alignment;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.LayoutStyle.ComponentPlacement;
-import javax.swing.SwingUtilities;
-import javax.swing.text.JTextComponent;
-
-import org.jfree.chart.ChartFactory;
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.renderer.xy.XYItemRenderer;
-import org.jfree.data.time.FixedMillisecond;
-import org.jfree.data.time.RegularTimePeriod;
-import org.jfree.data.time.TimeSeries;
-import org.jfree.data.time.TimeSeriesCollection;
-
-import com.redhat.thermostat.client.core.views.HostCpuView;
-import com.redhat.thermostat.client.internal.ui.swing.WrapLayout;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.common.model.DiscreteTimeData;
-
-public class HostCpuPanel extends HostCpuView implements SwingComponent {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private JPanel visiblePanel;
-
-    private final JTextComponent cpuModel = new ValueField("${CPU_MODEL}");
-    private final JTextComponent cpuCount = new ValueField("${CPU_COUNT}");
-
-    private final TimeSeriesCollection datasetCollection = new TimeSeriesCollection();
-    private final Map<Integer, TimeSeries> datasets = new HashMap<>();
-    private final Map<String, Color> colors = new HashMap<>();
-    private final Map<String, JLabel> labels = new HashMap<>();
-
-    private JFreeChart chart;
-
-    private JPanel legendPanel;
-
-    public HostCpuPanel() {
-        super();
-        initializePanel();
-
-        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 setCpuCount(final String count) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                cpuCount.setText(count);
-            }
-        });
-    }
-
-    @Override
-    public void setCpuModel(final String model) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                cpuModel.setText(model);
-            }
-        });
-    }
-
-    @Override
-    public void addCpuUsageChart(final int cpuIndex, final String humanReadableName) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                TimeSeries series = new TimeSeries(humanReadableName);
-                Color color = ChartColors.getColor(colors.size());
-                colors.put(humanReadableName, color);
-
-                datasets.put(cpuIndex, series);
-                datasetCollection.addSeries(series);
-
-                updateColors();
-
-                JLabel label = createLabelWithLegend(humanReadableName, color);
-                labels.put(humanReadableName, label);
-
-                legendPanel.add(label);
-                legendPanel.revalidate();
-            }
-        });
-    }
-
-    @Override
-    public void addCpuUsageData(final int cpuIndex, List<DiscreteTimeData<Double>> data) {
-        final ArrayList<DiscreteTimeData<Double>> copy = new ArrayList<>(data);
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                TimeSeries dataset = datasets.get(cpuIndex);
-                for (DiscreteTimeData<Double> timeData: copy) {
-                    RegularTimePeriod period = new FixedMillisecond(timeData.getTimeInMillis());
-                    if (dataset.getDataItem(period) == null) {
-                        dataset.add(period, timeData.getData(), false);
-                    }
-                }
-                dataset.fireSeriesChanged();
-            }
-        });
-    }
-
-    @Override
-    public void clearCpuUsageData() {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                for (Iterator<Map.Entry<Integer, TimeSeries>> iter = datasets.entrySet().iterator(); iter.hasNext();) {
-                    Map.Entry<Integer, TimeSeries> entry = iter.next();
-                    datasetCollection.removeSeries(entry.getValue());
-                    entry.getValue().clear();
-
-                    iter.remove();
-
-                }
-                updateColors();
-            }
-        });
-    }
-
-    @Override
-    public Component getUiComponent() {
-        return visiblePanel;
-    }
-
-    private void initializePanel() {
-
-        visiblePanel = new JPanel();
-
-        JLabel summaryLabel = new SectionHeader(translator.localize(LocaleResources.HOST_CPU_SECTION_OVERVIEW));
-
-        JLabel cpuModelLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_CPU_MODEL));
-
-        JLabel cpuCountLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_CPU_COUNT));
-
-        chart = ChartFactory.createTimeSeriesChart(
-                null,
-                translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_TIME_LABEL),
-                translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_VALUE_LABEL),
-                datasetCollection,
-                false, false, false);
-
-        chart.getPlot().setBackgroundPaint( new Color(255,255,255,0) );
-        chart.getPlot().setBackgroundImageAlpha(0.0f);
-        chart.getPlot().setOutlinePaint(new Color(0,0,0,0));
-
-        JPanel chartPanel = new RecentTimeSeriesChartPanel(new RecentTimeSeriesChartController(chart));
-        chartPanel.setOpaque(false);
-
-        legendPanel = new JPanel(new WrapLayout(FlowLayout.LEADING));
-        legendPanel.setOpaque(false);
-
-        GroupLayout groupLayout = new GroupLayout(visiblePanel);
-        groupLayout.setHorizontalGroup(
-            groupLayout.createParallelGroup(Alignment.TRAILING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
-                        .addComponent(legendPanel, GroupLayout.DEFAULT_SIZE, 427, Short.MAX_VALUE)
-                        .addComponent(chartPanel, GroupLayout.DEFAULT_SIZE, 427, Short.MAX_VALUE)
-                        .addComponent(summaryLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                        .addGroup(groupLayout.createSequentialGroup()
-                            .addGap(12)
-                            .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
-                                .addGroup(groupLayout.createSequentialGroup()
-                                    .addPreferredGap(ComponentPlacement.RELATED)
-                                    .addComponent(cpuCountLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                                    .addGap(18)
-                                    .addComponent(cpuCount, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
-                                .addGroup(groupLayout.createSequentialGroup()
-                                    .addComponent(cpuModelLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                                    .addGap(18)
-                                    .addComponent(cpuModel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))))
-                    .addGap(11))
-        );
-        groupLayout.setVerticalGroup(
-            groupLayout.createParallelGroup(Alignment.LEADING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addComponent(summaryLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
-                        .addComponent(cpuModelLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                        .addComponent(cpuModel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                    .addGap(10)
-                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
-                        .addComponent(cpuCount, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                        .addComponent(cpuCountLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                    .addGap(18)
-                    .addComponent(chartPanel, GroupLayout.DEFAULT_SIZE, 263, Short.MAX_VALUE)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addComponent(legendPanel, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE)
-                    .addContainerGap())
-        );
-        visiblePanel.setLayout(groupLayout);
-    }
-
-    /**
-     * Adding or removing series to the series collection may change the order
-     * of existing items. Plus the paint for the index is now out-of-date. So
-     * let's walk through all the series and set the right paint for those.
-     */
-    private void updateColors() {
-        XYItemRenderer itemRenderer = chart.getXYPlot().getRenderer();
-        for (int i = 0; i < datasetCollection.getSeriesCount(); i++) {
-            String tag = (String) datasetCollection.getSeriesKey(i);
-            Color color = colors.get(tag);
-            itemRenderer.setSeriesPaint(i, color);
-        }
-    }
-
-    private JLabel createLabelWithLegend(String text, Color color) {
-        String hexColor = "#" + Integer.toHexString(color.getRGB() & 0x00ffffff);
-        return new JLabel("<html> <font color='" + hexColor + "'>\u2588</font> " + text + "</html>");
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostInformationPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +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.ui;
-
-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.BasicView;
-import com.redhat.thermostat.client.core.views.HostInformationView;
-
-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 BasicView 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/core/src/main/java/com/redhat/thermostat/client/ui/HostMemoryPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,347 +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.ui;
-
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.FlowLayout;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import javax.swing.GroupLayout;
-import javax.swing.GroupLayout.Alignment;
-import javax.swing.JCheckBox;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.LayoutStyle.ComponentPlacement;
-import javax.swing.SwingUtilities;
-import javax.swing.text.JTextComponent;
-
-import org.jfree.chart.ChartFactory;
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.axis.NumberAxis;
-import org.jfree.chart.renderer.xy.XYItemRenderer;
-import org.jfree.data.time.FixedMillisecond;
-import org.jfree.data.time.RegularTimePeriod;
-import org.jfree.data.time.TimeSeries;
-import org.jfree.data.time.TimeSeriesCollection;
-
-import com.redhat.thermostat.client.core.views.HostMemoryView;
-import com.redhat.thermostat.client.internal.ui.swing.WrapLayout;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.common.model.DiscreteTimeData;
-import com.redhat.thermostat.common.utils.DisplayableValues;
-import com.redhat.thermostat.common.utils.DisplayableValues.Scale;
-
-public class HostMemoryPanel extends HostMemoryView implements SwingComponent {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private JPanel visiblePanel;
-
-    private final MemoryCheckboxListener memoryCheckboxListener = new MemoryCheckboxListener();
-
-    private final JTextComponent totalMemory = new ValueField("${TOTAL_MEMORY}");
-
-    private final JPanel memoryCheckBoxPanel = new JPanel(new WrapLayout(FlowLayout.LEADING));
-    private final CopyOnWriteArrayList<GraphVisibilityChangeListener> listeners = new CopyOnWriteArrayList<>();
-    private final TimeSeriesCollection memoryCollection = new TimeSeriesCollection();
-    private final Map<String, TimeSeries> dataset = new HashMap<>();
-    private final Map<String, JCheckBox> checkBoxes = new HashMap<>();
-    private final Map<String, Color> colors = new HashMap<>();
-
-    private JFreeChart chart;
-
-    public HostMemoryPanel() {
-        super();
-        initializePanel();
-
-        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 setTotalMemory(final String newValue) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                totalMemory.setText(newValue);
-            }
-        });
-    }
-
-    @Override
-    public Component getUiComponent() {
-        return visiblePanel;
-    }
-
-    @Override
-    public void addMemoryChart(final String tag, final String humanReadableName) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                int colorIndex = colors.size();
-                colors.put(tag, ChartColors.getColor(colorIndex));
-                TimeSeries series = new TimeSeries(tag);
-                dataset.put(tag, series);
-                JCheckBox newCheckBox = new JCheckBox(createLabelWithLegend(humanReadableName, colors.get(tag)));
-                newCheckBox.setActionCommand(tag);
-                newCheckBox.setSelected(true);
-                newCheckBox.addActionListener(memoryCheckboxListener);
-                newCheckBox.setOpaque(false);
-                checkBoxes.put(tag, newCheckBox);
-                memoryCheckBoxPanel.add(newCheckBox);
-
-                updateColors();
-            }
-        });
-
-    }
-
-    private String createLabelWithLegend(String text, Color color) {
-        String hexColor = "#" + Integer.toHexString(color.getRGB() & 0x00ffffff);
-        return "<html> <font color='" + hexColor + "'>\u2588</font> " + text + "</html>";
-    }
-
-    @Override
-    public void removeMemoryChart(final String tag) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                TimeSeries series = dataset.remove(tag);
-                memoryCollection.removeSeries(series);
-                JCheckBox box = checkBoxes.remove(tag);
-                memoryCheckBoxPanel.remove(box);
-
-                updateColors();
-            }
-        });
-    }
-
-    @Override
-    public void showMemoryChart(final String tag) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                TimeSeries series = dataset.get(tag);
-                memoryCollection.addSeries(series);
-
-                updateColors();
-            }
-        });
-    }
-
-    @Override
-    public void hideMemoryChart(final String tag) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                TimeSeries series = dataset.get(tag);
-                memoryCollection.removeSeries(series);
-
-                updateColors();
-            }
-        });
-    }
-
-    @Override
-    public void addMemoryData(final String tag, List<DiscreteTimeData<? extends Number>> data) {
-        final List<DiscreteTimeData<? extends Number>> copy = new ArrayList<>(data);
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                final TimeSeries series = dataset.get(tag);
-                for (DiscreteTimeData<? extends Number> timeData: copy) {
-                    RegularTimePeriod period = new FixedMillisecond(timeData.getTimeInMillis());
-                    if (series.getDataItem(period) == null) {
-                        Long sizeInBytes = (Long) timeData.getData();
-                        Double sizeInMegaBytes = DisplayableValues.Scale.convertTo(Scale.MiB, sizeInBytes);
-                        series.add(new FixedMillisecond(timeData.getTimeInMillis()), sizeInMegaBytes, false);
-                    }
-                }
-                series.fireSeriesChanged();
-            }
-        });
-    }
-
-    @Override
-    public void clearMemoryData(final String tag) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                TimeSeries series = dataset.get(tag);
-                series.clear();
-            }
-        });
-    }
-
-    @Override
-    public void addGraphVisibilityListener(GraphVisibilityChangeListener listener) {
-        listeners.add(listener);
-    }
-
-    @Override
-    public void removeGraphVisibilityListener(GraphVisibilityChangeListener listener) {
-        listeners.remove(listener);
-    }
-
-    @Override
-    public void addActionListener(ActionListener<Action> listener) {
-        notifier.addActionListener(listener);
-    }
-
-    @Override
-    public void removeActionListener(ActionListener<Action> listener) {
-        notifier.removeActionListener(listener);
-    }
-
-    private void initializePanel() {
-        visiblePanel = new JPanel();
-        visiblePanel.setOpaque(false);
-
-        chart = createMemoryChart();
-
-        JPanel chartPanel = new RecentTimeSeriesChartPanel(new RecentTimeSeriesChartController(chart));
-        chartPanel.setOpaque(false);
-
-        JLabel lblMemory = Components.header(translator.localize(LocaleResources.HOST_MEMORY_SECTION_OVERVIEW));
-
-        JLabel totalMemoryLabel = Components.label(translator.localize(LocaleResources.HOST_INFO_MEMORY_TOTAL));
-
-        memoryCheckBoxPanel.setOpaque(false);
-
-        GroupLayout groupLayout = new GroupLayout(visiblePanel);
-        groupLayout.setHorizontalGroup(
-            groupLayout.createParallelGroup(Alignment.LEADING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
-                        .addComponent(chartPanel, GroupLayout.DEFAULT_SIZE, 883, Short.MAX_VALUE)
-                        .addGroup(groupLayout.createSequentialGroup()
-                            .addGap(12)
-                            .addComponent(totalMemoryLabel)
-                            .addPreferredGap(ComponentPlacement.RELATED)
-                            .addComponent(totalMemory, GroupLayout.DEFAULT_SIZE, 751, Short.MAX_VALUE))
-                        .addComponent(lblMemory)
-                        .addComponent(memoryCheckBoxPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
-                    .addContainerGap())
-        );
-        groupLayout.setVerticalGroup(
-            groupLayout.createParallelGroup(Alignment.LEADING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addComponent(lblMemory)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
-                        .addComponent(totalMemory, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                        .addComponent(totalMemoryLabel))
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addComponent(chartPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addComponent(memoryCheckBoxPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
-                    .addContainerGap())
-        );
-        visiblePanel.setLayout(groupLayout);
-    }
-
-    private JFreeChart createMemoryChart() {
-        JFreeChart chart = ChartFactory.createTimeSeriesChart(
-                translator.localize(LocaleResources.HOST_MEMORY_CHART_TITLE), // Title
-                translator.localize(LocaleResources.HOST_MEMORY_CHART_TIME_LABEL), // x-axis Label
-                translator.localize(LocaleResources.HOST_MEMORY_CHART_SIZE_LABEL, Scale.MiB.name()), // y-axis Label
-                memoryCollection, // Dataset
-                false, // Show Legend
-                false, // Use tooltips
-                false // Configure chart to generate URLs?
-                );
-
-        chart.getPlot().setBackgroundPaint( new Color(255,255,255,0) );
-        chart.getPlot().setBackgroundImageAlpha(0.0f);
-        chart.getPlot().setOutlinePaint(new Color(0,0,0,0));
-
-        NumberAxis rangeAxis = (NumberAxis) chart.getXYPlot().getRangeAxis();
-        rangeAxis.setAutoRangeMinimumSize(100);
-
-        return chart;
-    }
-
-    private void fireShowHideHandlers(boolean show, String tag) {
-        for (GraphVisibilityChangeListener listener: listeners) {
-            if (show) {
-                listener.show(tag);
-            } else {
-                listener.hide(tag);
-            }
-        }
-    }
-
-    /**
-     * Adding or removing series to the series collection may change the order
-     * of existing items. Plus the paint for the index is now out-of-date. So
-     * let's walk through all the series and set the right paint for those.
-     */
-    private void updateColors() {
-        XYItemRenderer itemRenderer = chart.getXYPlot().getRenderer();
-        for (int i = 0; i < memoryCollection.getSeriesCount(); i++) {
-            String tag = (String) memoryCollection.getSeriesKey(i);
-            Color color = colors.get(tag);
-            itemRenderer.setSeriesPaint(i, color);
-        }
-    }
-
-    private class MemoryCheckboxListener implements java.awt.event.ActionListener {
-        @Override
-        public void actionPerformed(java.awt.event.ActionEvent e) {
-            JCheckBox source = (JCheckBox) e.getSource();
-            fireShowHideHandlers(source.isSelected(), source.getActionCommand());
-        }
-
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostOverviewPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +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.ui;
-
-import java.awt.Component;
-
-import javax.swing.JPanel;
-import javax.swing.JTable;
-import javax.swing.SwingUtilities;
-import javax.swing.table.DefaultTableModel;
-import javax.swing.table.JTableHeader;
-
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.HostOverviewView;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.locale.Translate;
-
-import javax.swing.GroupLayout;
-import javax.swing.GroupLayout.Alignment;
-import javax.swing.LayoutStyle.ComponentPlacement;
-import java.awt.BorderLayout;
-
-public class HostOverviewPanel extends HostOverviewView implements SwingComponent {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private JPanel visiblePanel;
-
-    private final ValueField hostname = new ValueField("${hostname}");
-    private final ValueField cpuModel = new ValueField("${cpu-model}");
-    private final ValueField cpuCount = new ValueField("${cpu-count}");
-    private final ValueField totalMemory = new ValueField("${total-memory}");
-    private final ValueField osName = new ValueField("${os-name}");
-    private final ValueField osKernel = new ValueField("${os-kernel}");
-
-    private final DefaultTableModel networkTableModel = new DefaultTableModel() {
-        @Override
-        public boolean isCellEditable(int row, int column) {
-            return false;
-        }
-    };
-
-    private Object[] networkTableColumns;
-    private Object[][] networkTableData;
-
-    public HostOverviewPanel() {
-        super();
-        initializePanel();
-
-        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 setHostName(final String newHostName) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                hostname.setText(newHostName);
-            }
-        });
-    }
-
-    @Override
-    public void setCpuModel(final String newCpuModel) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                cpuModel.setText(newCpuModel);
-            }
-        });
-    }
-
-    @Override
-    public void setCpuCount(final String newCpuCount) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                cpuCount.setText(newCpuCount);
-            }
-        });
-    }
-
-    @Override
-    public void setTotalMemory(final String newTotalMemory) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                totalMemory.setText(newTotalMemory);
-            }
-        });
-    }
-
-    @Override
-    public void setOsName(final String newOsName) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                osName.setText(newOsName);
-            }
-        });
-    }
-
-    @Override
-    public void setOsKernel(final String newOsKernel) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                osKernel.setText(newOsKernel);
-            }
-        });
-    }
-
-    @Override
-    public void setNetworkTableColumns(final Object[] columns) {
-        this.networkTableColumns = columns;
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                networkTableModel.setColumnIdentifiers(networkTableColumns);
-            }
-        });
-    }
-
-    @Override
-    public void setInitialNetworkTableData(final Object[][] data) {
-        this.networkTableData = data;
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                networkTableModel.setDataVector(networkTableData, networkTableColumns);
-            }
-        });
-    }
-
-    @Override
-    public void updateNetworkTableData(final int row, final int column, final String data) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                networkTableModel.setValueAt(data, row, column);
-            }
-        });
-    }
-
-    @Override
-    public Component getUiComponent() {
-        return visiblePanel;
-    }
-
-    private void initializePanel() {
-        visiblePanel = new JPanel();
-        SectionHeader overviewSection = new SectionHeader(translator.localize(LocaleResources.HOST_OVERVIEW_SECTION_BASICS));
-        LabelField hostnameLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_HOSTNAME));
-        SectionHeader hardwareSection = new SectionHeader(translator.localize(LocaleResources.HOST_OVERVIEW_SECTION_HARDWARE));
-        LabelField cpuModelLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_CPU_MODEL));
-        LabelField cpuCountLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_CPU_COUNT));
-        LabelField memoryTotalLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_MEMORY_TOTAL));
-        LabelField networkLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_NETWORK));
-        SectionHeader softwareSection = new SectionHeader(translator.localize(LocaleResources.HOST_OVERVIEW_SECTION_SOFTWARE));
-        LabelField osNameLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_OS_NAME));
-        LabelField osKernelLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_OS_KERNEL));
-
-        JPanel panel = new JPanel();
-
-        GroupLayout gl_visiblePanel = new GroupLayout(visiblePanel);
-        gl_visiblePanel.setHorizontalGroup(
-            gl_visiblePanel.createParallelGroup(Alignment.LEADING)
-                .addGroup(gl_visiblePanel.createSequentialGroup()
-                    .addContainerGap()
-                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
-                        .addComponent(hardwareSection, GroupLayout.DEFAULT_SIZE, 620, Short.MAX_VALUE)
-                        .addComponent(overviewSection, GroupLayout.DEFAULT_SIZE, 620, Short.MAX_VALUE)
-                        .addGroup(gl_visiblePanel.createSequentialGroup()
-                            .addGroup(gl_visiblePanel.createParallelGroup(Alignment.TRAILING, false)
-                                .addGroup(gl_visiblePanel.createSequentialGroup()
-                                    .addGap(12)
-                                    .addComponent(hostnameLabel, GroupLayout.DEFAULT_SIZE, 134, Short.MAX_VALUE))
-                                .addComponent(cpuCountLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                                .addComponent(cpuModelLabel, GroupLayout.DEFAULT_SIZE, 134, Short.MAX_VALUE)
-                                .addComponent(memoryTotalLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                                .addGroup(gl_visiblePanel.createSequentialGroup()
-                                    .addGap(12)
-                                    .addComponent(networkLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
-                            .addPreferredGap(ComponentPlacement.RELATED)
-                            .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
-                                .addComponent(panel, GroupLayout.DEFAULT_SIZE, 462, Short.MAX_VALUE)
-                                .addComponent(cpuCount, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                                .addComponent(cpuModel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                                .addComponent(hostname, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                                .addComponent(totalMemory, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
-                        .addComponent(softwareSection, GroupLayout.DEFAULT_SIZE, 620, Short.MAX_VALUE)
-                        .addGroup(gl_visiblePanel.createSequentialGroup()
-                            .addGap(12)
-                            .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING, false)
-                                .addComponent(osKernelLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                                .addComponent(osNameLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE))
-                            .addPreferredGap(ComponentPlacement.RELATED)
-                            .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
-                                .addComponent(osKernel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                                .addComponent(osName, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
-                    .addContainerGap())
-        );
-        gl_visiblePanel.setVerticalGroup(
-            gl_visiblePanel.createParallelGroup(Alignment.LEADING)
-                .addGroup(gl_visiblePanel.createSequentialGroup()
-                    .addContainerGap()
-                    .addComponent(overviewSection, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING, false)
-                        .addComponent(hostname, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
-                        .addComponent(hostnameLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                    .addPreferredGap(ComponentPlacement.UNRELATED)
-                    .addComponent(hardwareSection, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING, false)
-                        .addComponent(cpuModelLabel, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
-                        .addComponent(cpuModel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING, false)
-                        .addComponent(cpuCountLabel, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
-                        .addComponent(cpuCount, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
-                        .addComponent(memoryTotalLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                        .addComponent(totalMemory, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
-                        .addComponent(networkLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                        .addComponent(panel, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE))
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addComponent(softwareSection, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
-                        .addComponent(osNameLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                        .addComponent(osName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
-                        .addComponent(osKernelLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
-                        .addComponent(osKernel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
-                    .addGap(128))
-        );
-
-        panel.setLayout(new BorderLayout(0, 0));
-
-        JTable networkTable = new JTable(networkTableModel);
-        panel.add(networkTable);
-        JTableHeader header = networkTable.getTableHeader();
-        panel.add(header, BorderLayout.PAGE_START);
-        visiblePanel.setLayout(gl_visiblePanel);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HtmlTextBuilder.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,118 +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.ui;
-
-public class HtmlTextBuilder {
-
-    /*
-     * The api provided by this class needs to be cleaned up.
-     */
-
-    private final StringBuilder text = new StringBuilder();
-
-    public HtmlTextBuilder() {
-        // do nothing
-    }
-
-    public HtmlTextBuilder(String text) {
-        text = escape(text);
-        this.text.append(text);
-    }
-
-    public HtmlTextBuilder bold(boolean on) {
-        if (on) {
-            this.text.append("<b>");
-        } else {
-            this.text.append("</b>");
-        }
-        return this;
-    }
-
-    public HtmlTextBuilder bold(String toBold) {
-        text.append("<b>").append(toBold).append("</b>");
-        return this;
-    }
-
-    public HtmlTextBuilder larger(String toAppend) {
-        text.append("<font size='+2'>").append(escape(toAppend)).append("</font>");
-        return this;
-    }
-
-    public HtmlTextBuilder huge(String toAppend) {
-        text.append("<font size='+6'>").append(escape(toAppend)).append("</font>");
-        return this;
-    }
-
-    @Override
-    public String toString() {
-        // FIXME
-        return null;
-    }
-
-    public String toHtml() {
-        return "<html>" + text.toString() + "</html>";
-    }
-
-    public String toPartialHtml() {
-        return text.toString();
-    }
-
-    private static String escape(String toEscape) {
-        // FIXME implement this
-        return toEscape;
-    }
-
-    public HtmlTextBuilder append(String toAppend) {
-        text.append(escape(toAppend));
-        return this;
-    }
-
-    public HtmlTextBuilder appendRaw(String toAppend) {
-        text.append(toAppend);
-        return this;
-    }
-
-    public static String boldHtml(String toBold) {
-        return new HtmlTextBuilder().bold(toBold).toHtml();
-    }
-
-    public HtmlTextBuilder newLine() {
-        text.append("<br>");
-        return this;
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/IconResource.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,93 +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.ui;
-
-import java.io.File;
-
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
-
-public class IconResource {
-    /* FIXME we need to pick up the icons dynamically */
-
-    private static final String ICON_PREFIX = "/usr/share/icons/gnome/";
-
-    // an icon that should always be available and indicate that the actual icon
-    // is missing.
-    public static final IconResource MISSING_ICON = null;
-
-    public static final IconResource JAVA_APPLICATION = new IconResource("duke.png");
-    public static final IconResource HOST = new IconResource(ICON_PREFIX + "16x16/devices/computer.png");
-    
-    public static final IconResource ERROR = new IconResource(ICON_PREFIX + "48x48/status/dialog-error.png");
-    public static final IconResource QUESTION = new IconResource(ICON_PREFIX + "48x48/status/dialog-question.png");
-    public static final IconResource WARNING = new IconResource(ICON_PREFIX + "48x48/status/dialog-warning.png");
-
-    public static final IconResource COMPUTER = new IconResource(ICON_PREFIX + "48x48/devices/computer.png");
-    public static final IconResource NETWORK_SERVER = new IconResource(ICON_PREFIX + "48x48/places/network-server.png");
-    public static final IconResource NETWORK_GROUP = new IconResource(ICON_PREFIX + "48x48/places/network-workgroup.png");
-
-    public static final IconResource ARROW_RIGHT = new IconResource(ICON_PREFIX + "48x48/actions/go-next.png");
-
-    public static final IconResource SEARCH = new IconResource(ICON_PREFIX + "16x16/actions/search.png");
-
-    private final String path;
-
-    private IconResource(String descriptor) {
-        this.path = descriptor;
-    }
-
-    public static IconResource fromPath(String path) {
-        // TODO implement this
-        return null;
-    }
-
-    public Icon getIcon() {
-        if (new File(path).exists()) {
-            return new ImageIcon(path);
-        }
-        return null;
-    }
-
-    public String getPath() {
-        return path;
-    }
-
-    public String getUrl() {
-        return "file:" + getPath();
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/LabelField.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +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.ui;
-
-import javax.swing.JLabel;
-import javax.swing.SwingConstants;
-
-public class LabelField extends JLabel {
-
-    public LabelField(String text) {
-        super(text);
-        setHorizontalAlignment(SwingConstants.TRAILING);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/LayoutDebugHelper.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +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.ui;
-
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Window;
-
-import javax.swing.BorderFactory;
-import javax.swing.JComponent;
-
-/**
- * This class goes through the swing container hierarchy and adds random colored
- * borders to the components themselves. it makes it easier to see what the
- * {@code LayoutManager}s are doing
- */
-public class LayoutDebugHelper {
-
-    private Color[] colors = new Color[] { Color.BLACK, Color.BLUE, Color.CYAN, Color.GREEN, Color.MAGENTA, Color.PINK, Color.ORANGE, Color.RED, Color.YELLOW };
-    private int colorIndex = 0;
-
-    public void debugLayout(Window w) {
-        Component[] children = w.getComponents();
-        debugLayout(children);
-    }
-
-    public void debugLayout(Component c) {
-        if (c instanceof JComponent) {
-            JComponent panel = (JComponent) c;
-            try {
-                panel.setBorder(BorderFactory.createLineBorder(colors[colorIndex % colors.length]));
-            } catch (IllegalArgumentException iae) {
-                // never mind then
-            }
-            colorIndex++;
-            debugLayout(panel.getComponents());
-        }
-    }
-
-    public void debugLayout(Component[] components) {
-        for (Component aComponent : components) {
-            debugLayout(aComponent);
-        }
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/MainWindow.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,790 +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.ui;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.Graphics2D;
-import java.awt.event.ComponentAdapter;
-import java.awt.event.ComponentEvent;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-import java.awt.image.BufferedImage;
-import java.io.PrintStream;
-import java.lang.reflect.InvocationTargetException;
-import java.nio.ByteBuffer;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.ExecutionException;
-
-import javax.swing.BorderFactory;
-import javax.swing.Icon;
-import javax.swing.ImageIcon;
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JFrame;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-import javax.swing.JPanel;
-import javax.swing.JPopupMenu;
-import javax.swing.JScrollPane;
-import javax.swing.JSplitPane;
-import javax.swing.JTree;
-import javax.swing.KeyStroke;
-import javax.swing.SwingUtilities;
-import javax.swing.SwingWorker;
-import javax.swing.ToolTipManager;
-import javax.swing.event.TreeExpansionEvent;
-import javax.swing.event.TreeSelectionEvent;
-import javax.swing.event.TreeSelectionListener;
-import javax.swing.event.TreeWillExpandListener;
-import javax.swing.tree.DefaultMutableTreeNode;
-import javax.swing.tree.DefaultTreeCellRenderer;
-import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.ExpandVetoException;
-import javax.swing.tree.TreeNode;
-import javax.swing.tree.TreePath;
-import javax.swing.tree.TreeSelectionModel;
-
-import sun.misc.Signal;
-
-import com.redhat.thermostat.client.core.HostFilter;
-import com.redhat.thermostat.client.core.VmFilter;
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.internal.MainView;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.client.osgi.service.HostDecorator;
-import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.client.osgi.service.VmDecorator;
-import com.redhat.thermostat.client.osgi.service.VMContextAction;
-import com.redhat.thermostat.client.ui.SearchFieldView.SearchAction;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.ActionNotifier;
-import com.redhat.thermostat.common.HostsVMsLoader;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.Ref;
-import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.common.utils.StringUtils;
-import com.redhat.thermostat.swing.EdtHelper;
-import com.redhat.thermostat.swing.StatusBar;
-
-public class MainWindow extends JFrame implements MainView {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    /**
-     * Updates a TreeModel in the background in an Swing EDT-safe manner.
-     */
-    private static class BackgroundTreeModelWorker extends SwingWorker<DefaultMutableTreeNode, Void> {
-
-        private JTree tree;
-
-        private final DefaultTreeModel treeModel;
-        private DefaultMutableTreeNode treeRoot;
-        
-        private List<HostFilter> hostFilters;
-        private List<VmFilter> vmFilters;
-        private List<HostDecorator> hostDecorators;
-        private List<VmDecorator> vmDecorators;
-        
-        private HostsVMsLoader hostsVMsLoader;
-
-        public BackgroundTreeModelWorker(DefaultTreeModel model, DefaultMutableTreeNode root,
-                                         List<HostFilter> hostFilters, List<VmFilter> vmFilters,
-                                         List<HostDecorator> hostDecorators, List<VmDecorator> vmDecorators,
-                                         HostsVMsLoader hostsVMsLoader, JTree tree)
-        {
-            this.hostFilters = hostFilters;
-            this.vmFilters = vmFilters;
-
-            this.vmDecorators = vmDecorators;
-            this.hostDecorators = hostDecorators;
-
-            this.treeModel = model;
-            this.treeRoot = root;
-            this.hostsVMsLoader = hostsVMsLoader;
-            this.tree = tree;
-        }
-
-        @Override
-        protected DefaultMutableTreeNode doInBackground() throws Exception {
-            DefaultMutableTreeNode root = new DefaultMutableTreeNode();
-            
-            Collection<HostRef> hostsInRemoteModel = hostsVMsLoader.getHosts();
-            buildHostSubTree(root, hostsInRemoteModel);
-            return root;
-        }
-
-        private boolean buildHostSubTree(DefaultMutableTreeNode parent, Collection<HostRef> objectsInRemoteModel) {
-            boolean subTreeMatches = false;
-            for (HostRef inRemoteModel : objectsInRemoteModel) {
-                DecoratedDefaultMutableTreeNode inTreeNode =
-                        new DecoratedDefaultMutableTreeNode(inRemoteModel);
-
-                boolean shouldInsert = false;
-                if (hostFilters == null) {
-                    shouldInsert = true;
-                } else {
-                    shouldInsert = true;
-                    for (HostFilter filter : hostFilters) {
-                        if (!filter.matches(inRemoteModel)) {
-                            shouldInsert = false;
-                            break;
-                        }
-                    }
-                }
-                
-                Collection<VmRef> children = hostsVMsLoader.getVMs(inRemoteModel);
-                boolean subtreeResult = buildVmSubTree(inTreeNode, children);
-                if (subtreeResult) {
-                    shouldInsert = true;
-                }
-
-                if (shouldInsert) {
-                    for (HostDecorator decorator : hostDecorators) {
-                        HostFilter filter = decorator.getFilter();
-                        if (filter != null && filter.matches(inRemoteModel)) {
-                            inTreeNode.addDecorator(decorator.getDecorator());
-                        }
-                    }
-                    
-                    parent.add(inTreeNode);
-                    subTreeMatches = true;
-                }
-            }
-            
-            return subTreeMatches;
-        }
-
-        private boolean buildVmSubTree(DefaultMutableTreeNode parent, Collection<VmRef> objectsInRemoteModel) {
-            boolean subTreeMatches = false;
-            for (VmRef inRemoteModel : objectsInRemoteModel) {
-                DecoratedDefaultMutableTreeNode inTreeNode =
-                        new DecoratedDefaultMutableTreeNode(inRemoteModel);
-
-                boolean shouldInsert = false;
-                if (vmFilters == null) {
-                    shouldInsert = true;
-                } else {
-                    shouldInsert = true;
-                    for (VmFilter filter : vmFilters) {
-                        if (!filter.matches(inRemoteModel)) {
-                            shouldInsert = false;
-                            break;
-                        }
-                    }
-                }
-
-                if (shouldInsert) {
-                    for (VmDecorator decorator : vmDecorators) {
-                        VmFilter filter = decorator.getFilter();
-                        if (filter != null && filter.matches(inRemoteModel)) {
-                            inTreeNode.addDecorator(decorator.getDecorator());
-                        }
-                    }
-
-                    parent.add(inTreeNode);
-                    subTreeMatches = true;
-                }
-            }
-
-            return subTreeMatches;
-        }
-
-        @Override
-        protected void done() {
-            DefaultMutableTreeNode sourceRoot;
-            try {
-                sourceRoot = get();
-                syncTree(sourceRoot, treeModel, treeRoot);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            } catch (ExecutionException e) {
-                e.printStackTrace();
-            }
-        }
-
-        private void syncTree(DefaultMutableTreeNode sourceRoot, DefaultTreeModel targetModel, DefaultMutableTreeNode targetNode) {
-            
-            @SuppressWarnings("unchecked") // We know what we put into these trees.
-            List<DefaultMutableTreeNode> sourceChildren = Collections.list(sourceRoot.children());
-
-            @SuppressWarnings("unchecked")
-            List<DefaultMutableTreeNode> targetChildren = Collections.list(targetNode.children());
-            for (DefaultMutableTreeNode sourceChild : sourceChildren) {
-                Ref sourceRef = (Ref) sourceChild.getUserObject();
-                DefaultMutableTreeNode targetChild = null;
-                for (DefaultMutableTreeNode aChild : targetChildren) {
-                    Ref targetRef = (Ref) aChild.getUserObject();
-                    if (targetRef.equals(sourceRef)) {
-                        targetChild = aChild;
-                        if (sourceChild instanceof DecoratedDefaultMutableTreeNode) {
-                            DecoratedDefaultMutableTreeNode source = (DecoratedDefaultMutableTreeNode) sourceChild;
-                            ((DecoratedDefaultMutableTreeNode) targetChild).setDecorators(source.getDecorators());
-                        }
-                        break;
-                    }
-                }
-
-                if (targetChild == null) {
-                    targetChild = new DecoratedDefaultMutableTreeNode(sourceRef);
-                    if (sourceChild instanceof DecoratedDefaultMutableTreeNode) {
-                        DecoratedDefaultMutableTreeNode source = (DecoratedDefaultMutableTreeNode) sourceChild;
-                        ((DecoratedDefaultMutableTreeNode) targetChild).setDecorators(source.getDecorators());
-                    }
-                    targetModel.insertNodeInto(targetChild, targetNode, targetNode.getChildCount());
-                }
-
-                syncTree(sourceChild, targetModel, targetChild);
-            }
-
-            for (DefaultMutableTreeNode targetChild : targetChildren) {
-                Ref targetRef = (Ref) targetChild.getUserObject();
-                boolean matchFound = false;
-                for (DefaultMutableTreeNode sourceChild : sourceChildren) {
-                    Ref sourceRef = (Ref) sourceChild.getUserObject();
-                    if (targetRef.equals(sourceRef)) {
-                        matchFound = true;
-                        break;
-                    }
-                }
-
-                if (!matchFound) {
-                    targetModel.removeNodeFromParent(targetChild);
-                }
-            }
-            ensureRootIsExpanded(targetModel);
-        }
-
-        private void ensureRootIsExpanded(final DefaultTreeModel model) {
-            DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
-            tree.expandPath(new TreePath(root.getPath()));
-        }
-
-    }
-
-    private static final long serialVersionUID = 5608972421496808177L;
-
-    private final JMenuBar mainMenuBar = new JMenuBar();
-    private final MenuHelper mainMenuHelper = new MenuHelper(mainMenuBar);
-    private JPanel contentArea = null;
-
-    private SearchFieldSwingView searchField = new SearchFieldSwingView();
-    private JTree agentVmTree = null;
-
-    private final ShutdownClient shutdownAction;
-
-    private ActionNotifier<Action> actionNotifier = new ActionNotifier<>(this);
-
-    private JPopupMenu vmContextMenu;
-    private StatusBar statusBar;
-    
-    private final DefaultMutableTreeNode publishedRoot =
-            new DefaultMutableTreeNode(translator.localize(LocaleResources.MAIN_WINDOW_TREE_ROOT_NAME));
-    private final DefaultTreeModel publishedTreeModel = new DefaultTreeModel(publishedRoot);
-
-    @SuppressWarnings("restriction")
-    public MainWindow() {
-        super();
-
-        shutdownAction = new ShutdownClient();
-
-        searchField.addActionListener(new ActionListener<SearchAction>() {
-            @Override
-            public void actionPerformed(ActionEvent<SearchAction> actionEvent) {
-                switch (actionEvent.getActionId()) {
-                case TEXT_CHANGED:
-                    fireViewAction(Action.HOST_VM_TREE_FILTER);
-                    break;
-                }
-            }
-        });
-        agentVmTree = new JTree(publishedTreeModel);
-        agentVmTree.setName("agentVmTree");
-        agentVmTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
-        agentVmTree.setCellRenderer(new AgentVmTreeCellRenderer());
-        agentVmTree.addTreeWillExpandListener(new TreeWillExpandListener() {
-            @Override
-            public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
-                /* Yup, tree will expand */
-            }
-
-            @Override
-            public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
-                if (new TreePath(publishedRoot.getPath()).equals(event.getPath())) {
-                    throw new ExpandVetoException(event, "root cant be collapsed");
-                }
-            }
-        });
-        ToolTipManager.sharedInstance().registerComponent(agentVmTree);
-        contentArea = new JPanel(new BorderLayout());
-
-        setupMenus();
-        setupPanels();
-
-        this.setPreferredSize(new Dimension(800, 600));
-
-        agentVmTree.setSelectionPath(new TreePath(((DefaultMutableTreeNode) publishedTreeModel.getRoot()).getPath()));
-        
-        //agentVmTree.setLargeModel(true);
-        agentVmTree.setRowHeight(25);
-        
-        statusBar = new StatusBar();
-        getContentPane().add(statusBar, BorderLayout.SOUTH);
-        
-        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
-        addWindowListener(shutdownAction);
-
-        // Handle SIGTERM/SIGINT properly
-        Signal.handle(new Signal("TERM"), shutdownAction);
-        Signal.handle(new Signal("INT"), shutdownAction);
-        
-        addComponentListener(new ComponentAdapter() {
-
-            @Override
-            public void componentShown(ComponentEvent e) {
-                fireViewAction(Action.VISIBLE);
-            }
-
-            @Override
-            public void componentHidden(ComponentEvent e) {
-                fireViewAction(Action.HIDDEN);
-            }
-        });
-
-    }
-
-    private void setupMenus() {
-
-        JMenu fileMenu = new JMenu(translator.localize(LocaleResources.MENU_FILE));
-        fileMenu.getPopupMenu().setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
-        mainMenuBar.add(fileMenu);
-
-        JMenuItem fileExitMenu = new JMenuItem(translator.localize(LocaleResources.MENU_FILE_EXIT));
-        fileExitMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_DOWN_MASK));
-        fileExitMenu.addActionListener(shutdownAction);
-        fileMenu.add(fileExitMenu);
-
-        JMenu editMenu = new JMenu(translator.localize(LocaleResources.MENU_EDIT));
-        mainMenuBar.add(editMenu);
-
-        JMenuItem configureClientMenuItem = new JMenuItem(translator.localize(LocaleResources.MENU_EDIT_CONFIGURE_CLIENT));
-        configureClientMenuItem.setName("showClientConfig");
-        configureClientMenuItem.addActionListener(new java.awt.event.ActionListener() {
-            @Override
-            public void actionPerformed(java.awt.event.ActionEvent e) {
-                fireViewAction(Action.SHOW_CLIENT_CONFIG);
-            }
-        });
-        editMenu.add(configureClientMenuItem);
-
-        editMenu.addSeparator();
-        JMenuItem historyModeMenuItem = new JCheckBoxMenuItem(translator.localize(LocaleResources.MENU_EDIT_ENABLE_HISTORY_MODE));
-        historyModeMenuItem.setName("historyModeSwitch");
-        historyModeMenuItem.setSelected(false);
-        historyModeMenuItem.addActionListener(new java.awt.event.ActionListener() {
-            @Override
-            public void actionPerformed(java.awt.event.ActionEvent e) {
-                fireViewAction(Action.SWITCH_HISTORY_MODE);
-            }
-        });
-        editMenu.add(historyModeMenuItem);
-
-        JMenu viewMenu = new JMenu(translator.localize(LocaleResources.MENU_VIEW));
-        mainMenuBar.add(viewMenu);
-        JMenuItem configureAgentMenuItem = new JMenuItem(translator.localize(LocaleResources.MENU_VIEW_AGENTS));
-        configureAgentMenuItem.setName("showAgentConfig");
-        configureAgentMenuItem.addActionListener(new java.awt.event.ActionListener() {
-            @Override
-            public void actionPerformed(java.awt.event.ActionEvent e) {
-                fireViewAction(Action.SHOW_AGENT_CONFIG);
-            }
-        });
-        viewMenu.add(configureAgentMenuItem);
-
-        JMenu helpMenu = new JMenu(translator.localize(LocaleResources.MENU_HELP));
-        helpMenu.getPopupMenu().setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
-        mainMenuBar.add(helpMenu);
-
-        JMenuItem helpAboutMenu = new JMenuItem(translator.localize(LocaleResources.MENU_HELP_ABOUT));
-        helpAboutMenu.addActionListener(new java.awt.event.ActionListener() {
-            @Override
-            public void actionPerformed(java.awt.event.ActionEvent e) {
-                fireViewAction(Action.SHOW_ABOUT_DIALOG);
-            }
-        });
-        helpMenu.add(helpAboutMenu);
-        setJMenuBar(mainMenuBar);
-    }
-
-    private void setupPanels() {
-        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
-        splitPane.setOneTouchExpandable(true);
-        
-        JPanel navigationPanel = new JPanel(new BorderLayout());
-
-        navigationPanel.add(searchField, BorderLayout.PAGE_START);
-
-        agentVmTree.addTreeSelectionListener(new TreeSelectionListener() {
-            @Override
-            public void valueChanged(TreeSelectionEvent e) {
-                if (e.isAddedPath()) {
-                    fireViewAction(Action.HOST_VM_SELECTION_CHANGED);
-                }
-            }
-        });
-        registerContextActionListener(agentVmTree);
-        
-        JScrollPane treeScrollPane = new JScrollPane(agentVmTree);
-        
-        navigationPanel.add(treeScrollPane);
-
-        JPanel detailsPanel = createDetailsPanel();
-
-        navigationPanel.setMinimumSize(new Dimension(200,500));
-        detailsPanel.setMinimumSize(new Dimension(500, 500));
-
-        splitPane.add(navigationPanel);
-        splitPane.add(detailsPanel);
-
-        getContentPane().add(splitPane);
-    }
-
-    private void registerContextActionListener(JTree agentVmTree2) {
-        vmContextMenu = new JPopupMenu();
-        agentVmTree2.addMouseListener(new MouseAdapter() {
-            @Override
-            public void mousePressed(MouseEvent e) {
-                if (e.isPopupTrigger()) {
-                    Ref ref = getSelectedHostOrVm();
-                    if (ref instanceof VmRef) {
-                        fireViewAction(Action.SHOW_VM_CONTEXT_MENU, e);
-                    }
-                }
-            }
-        });
-    }
-
-    @Override
-    public void showVMContextActions(final List<VMContextAction> actions, final MouseEvent e) {
-        SwingUtilities.invokeLater(new Runnable() {
-
-            @Override
-            public void run() {
-                vmContextMenu.removeAll();
-
-                for (final VMContextAction action: actions) {
-                    JMenuItem contextAction = new JMenuItem();
-                    contextAction.setText(action.getName());
-                    contextAction.setToolTipText(action.getDescription());
-
-                    contextAction.addActionListener(new java.awt.event.ActionListener() {
-                        @Override
-                        public void actionPerformed(java.awt.event.ActionEvent e) {
-                            fireViewAction(Action.VM_CONTEXT_ACTION, action);
-                        }
-                    });
-                    vmContextMenu.add(contextAction);
-                }
-
-                vmContextMenu.show((Component)e.getSource(), e.getX(), e.getY());
-            }
-
-        });
-    }
-    
-    private JPanel createDetailsPanel() {
-        JPanel result = new JPanel(new BorderLayout());
-        result.add(contentArea, BorderLayout.CENTER);
-        return result;
-    }
-
-    @SuppressWarnings("restriction")
-    public class ShutdownClient extends WindowAdapter implements java.awt.event.ActionListener, sun.misc.SignalHandler {
-
-        @Override
-        public void windowClosing(WindowEvent e) {
-            shutdown();
-        }
-
-        @Override
-        public void actionPerformed(java.awt.event.ActionEvent e) {
-            shutdown();
-        }
-        
-        @Override
-        public void handle(Signal arg0) {
-            shutdown();
-        }
-
-        private void shutdown() {
-            dispose();
-            fireViewAction(Action.SHUTDOWN);
-        }
-
-    }
-
-    private static class AgentVmTreeCellRenderer extends DefaultTreeCellRenderer {
-        private static final long serialVersionUID = 4444642511815252481L;
-
-        @Override
-        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
-            
-            Object node = ((DefaultMutableTreeNode) value).getUserObject();
-            setToolTipText(createToolTipText(node));
-            
-            Component component = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
-            if (value instanceof DecoratedDefaultMutableTreeNode) {
-                DecoratedDefaultMutableTreeNode treeNode = (DecoratedDefaultMutableTreeNode) value;
-                setAnnotation(treeNode, node, component);
-            }
-
-            return component;
-        }
-        
-        // TODO: we can cache more, for example the full icon, not just the decoration
-        private Map<Decorator, ImageIcon> decoratorsCache = new HashMap<>();
-        private void setAnnotation(DecoratedDefaultMutableTreeNode treeNode, Object value, Component component) {
-
-            List<Decorator> decorators = treeNode.getDecorators();
-            for (Decorator dec : decorators) {
-                String newText = dec.getLabel(getText());
-                setText(newText);
-                setLabelFor(component);
-                
-                ImageIcon icon = decoratorsCache.get(dec);
-                if (icon == null) {
-                    //System.err.println("cache miss: " + dec);
-                    IconDescriptor iconDescriptor = dec.getIconDescriptor();
-                    if (iconDescriptor != null) {
-                        ByteBuffer data = iconDescriptor.getData();
-                        icon = new ImageIcon(data.array());
-                        decoratorsCache.put(dec, icon);
-                    }
-                }
-                
-                if (icon == null) {
-                    return;
-                }
-                
-                Icon currentIcon = getIcon();
-                switch (dec.getQuadrant()) {
-                case BOTTOM_LEFT:
-                    int y = currentIcon.getIconHeight() - icon.getIconHeight();
-                    paintCustomIcon(currentIcon, icon, y);
-                    break;
-                    
-                case TOP_LEFT:
-                    paintCustomIcon(currentIcon, icon, 0);
-                    break;
-                    
-                case MAIN:
-                default:
-                    setIcon(icon);
-                    break;
-                }
-            }
-        }
-        
-        private void paintCustomIcon(Icon currentIcon, ImageIcon icon, int y) {
-            BufferedImage image = new BufferedImage(currentIcon.getIconWidth(),
-                                                    currentIcon.getIconHeight(),
-                                                    BufferedImage.TYPE_INT_ARGB);
-            Graphics2D graphics = (Graphics2D) image.getGraphics();
-            
-            currentIcon.paintIcon(null, graphics, 0, 0);
-            graphics.drawImage(icon.getImage(), 0, y, null);
-            
-            setIcon(new ImageIcon(image));
-        }
-        
-        private String createToolTipText(Object value) {
-            if (value instanceof HostRef) {
-                HostRef hostRef = (HostRef) value;
-                String hostNameHtml = new HtmlTextBuilder().bold(hostRef.getHostName()).toPartialHtml();
-                String agentIdHtml = new HtmlTextBuilder().bold(hostRef.getAgentId()).toPartialHtml();
-                HtmlTextBuilder builder = new HtmlTextBuilder()
-                    .appendRaw(translator.localize(LocaleResources.TREE_HOST_TOOLTIP_HOST_NAME, hostNameHtml))
-                    .newLine()
-                    .appendRaw(translator.localize(LocaleResources.TREE_HOST_TOOLTIP_AGENT_ID, agentIdHtml));
-                return builder.toHtml();
-            } else if (value instanceof VmRef) {
-                VmRef vmRef = (VmRef) value;
-                String vmNameHtml= new HtmlTextBuilder().bold(vmRef.getName()).toPartialHtml();
-                String vmIdHtml = new HtmlTextBuilder().bold(vmRef.getIdString()).toPartialHtml();
-                HtmlTextBuilder builder = new HtmlTextBuilder()
-                    .appendRaw(translator.localize(LocaleResources.TREE_HOST_TOOLTIP_VM_NAME, vmNameHtml))
-                    .newLine()
-                    .appendRaw(translator.localize(LocaleResources.TREE_HOST_TOOLTIP_VM_ID, vmIdHtml));
-                return builder.toHtml();
-            } else {
-                return null;
-            }
-        }
-    }
-
-    @Override
-    public void addActionListener(ActionListener<Action> l) {
-        actionNotifier.addActionListener(l);
-    }
-
-    public void removeViewActionListener(ActionListener<Action> l) {
-        actionNotifier.removeActionListener(l);
-    }
-
-    private void fireViewAction(Action action) {
-        actionNotifier.fireAction(action);
-    }
-    
-    private void fireViewAction(Action action, Object payload) {
-        actionNotifier.fireAction(action, payload);
-    }
-    
-    @Override
-    public void updateTree(List<HostFilter> hostFilters, List<VmFilter> vmFilters,
-            List<HostDecorator> hostDecorators, List<VmDecorator> vmDecorators,
-            HostsVMsLoader hostsVMsLoader)
-    {
-        BackgroundTreeModelWorker worker =
-                new BackgroundTreeModelWorker(publishedTreeModel, publishedRoot,
-                                              hostFilters, vmFilters, hostDecorators, vmDecorators, hostsVMsLoader, agentVmTree);
-        worker.execute();
-    }
-
-    @SuppressWarnings("unused") // Used for debugging but not in production code.
-    private static void printTree(PrintStream out, TreeNode node, int depth) {
-        out.println(StringUtils.repeat("  ", depth) + node.toString());
-        @SuppressWarnings("unchecked")
-        List<TreeNode> children = Collections.list(node.children());
-        for (TreeNode child : children) {
-            printTree(out, child, depth + 1);
-        }
-    }
-
-    @Override
-    public void setWindowTitle(String title) {
-        setTitle(title);
-    }
-
-    @Override
-    public void showMainWindow() {
-        try {
-            new EdtHelper().callAndWait(new Runnable() {
-
-                @Override
-                public void run() {
-                    pack();
-                    setVisible(true);
-                }
-            });
-        } catch (InvocationTargetException e) {
-            throw new RuntimeException(e);
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-        }
-    }
-
-    @Override
-    public void hideMainWindow() {
-        setVisible(false);
-        dispose();
-    }
-
-    @Override
-    public void setStatusBarPrimaryStatus(final String primaryStatus) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                statusBar.setPrimaryStatus(primaryStatus);
-            }
-        });
-    }
-    
-    @Override
-    public void setSubView(final BasicView view) {
-        if (view instanceof SwingComponent) {
-            final SwingComponent swingComp = (SwingComponent)view;
-            SwingUtilities.invokeLater(new Runnable() {
-                @Override
-                public void run() {
-                    contentArea.removeAll();
-                    Component toAdd = swingComp.getUiComponent();
-                    contentArea.add(toAdd);
-                    contentArea.revalidate();
-                }
-            });
-        }
-    }
-
-    @Override
-    public void addMenu(MenuAction action) {
-        mainMenuHelper.addMenuAction(action);
-    }
-
-    @Override
-    public void removeMenu(MenuAction action) {
-        mainMenuHelper.removeMenuAction(action);
-    }
-
-    /**
-     * Returns null to indicate no Ref is selected
-     */
-    @Override
-    public Ref getSelectedHostOrVm() {
-        TreePath path = agentVmTree.getSelectionPath();
-        if (path == null || path.getPathCount() == 1) {
-            return null;
-        }
-        return (Ref) ((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject();
-    }
-
-    @Override
-    public String getHostVmTreeFilterText() {
-        return searchField.getSearchText();
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/MemorySpacePanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,109 +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.ui;
-
-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;
-
-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/core/src/main/java/com/redhat/thermostat/client/ui/MenuHelper.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,287 +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.ui;
-
-import java.awt.event.ActionEvent;
-import java.lang.reflect.InvocationTargetException;
-import java.util.Arrays;
-import java.util.logging.Logger;
-
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JMenuItem;
-import javax.swing.JPopupMenu;
-import javax.swing.JRadioButtonMenuItem;
-import javax.swing.MenuElement;
-
-import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-import com.redhat.thermostat.common.utils.StringUtils;
-import com.redhat.thermostat.swing.EdtHelper;
-
-public class MenuHelper {
-
-    private static final Logger logger = LoggingUtils.getLogger(MenuHelper.class);
-
-    private final JMenuBar menuBar;
-
-    public MenuHelper(JMenuBar menuBar) {
-        this.menuBar = menuBar;
-    }
-
-    /**
-     * Add a menu item as specified though the {@link MenuAction} argument.
-     */
-    public void addMenuAction(final MenuAction action) {
-        try {
-            new EdtHelper().callAndWait(new Runnable() {
-                @Override
-                public void run() {
-                    String[] path = action.getPath();
-                    Menu parent = findMenuParent(menuBar, path, true);
-                    JMenuItem menu = null;
-                    switch (action.getType()) {
-                    case RADIO:
-                        menu = new JRadioButtonMenuItem();
-                        break;
-                    case CHECK:
-                        menu = new JCheckBoxMenuItem();
-                        break;
-
-                    case STANDARD:
-                    default:
-                        menu = new JMenuItem();
-                        break;
-                    }
-
-                    menu.setText(action.getName());
-                    menu.addActionListener(new java.awt.event.ActionListener() {
-                        @Override
-                        public void actionPerformed(ActionEvent e) {
-                            action.execute();
-                        }
-                    });
-                    parent.add(new Menu(menu));
-
-                    menuBar.revalidate();
-                }
-            });
-        } catch (InvocationTargetException ite) {
-            Throwable cause = ite.getCause();
-            if (cause instanceof IllegalArgumentException) {
-                throw (IllegalArgumentException) cause;
-            }
-            throw new RuntimeException(cause);
-        } catch (InterruptedException ie) {
-            Thread.currentThread().interrupt();
-            throw new RuntimeException(ie);
-        }
-
-    }
-
-    /**
-     * Remove a existing menu item as specified though the {@link MenuAction}
-     * argument.
-     *
-     * @throws IllegalArgumentException if the path specified in
-     * {@link MenuAction#getPath()} can not be found
-     */
-    public void removeMenuAction(final MenuAction action) {
-        try {
-            new EdtHelper().callAndWait(new Runnable() {
-                @Override
-                public void run() {
-                    String[] path = action.getPath();
-                    Menu parent = findMenuParent(menuBar, path, false);
-                    parent.remove(path[path.length - 1]);
-                    menuBar.revalidate();
-                }
-            });
-        } catch (InterruptedException ie) {
-            Thread.currentThread().interrupt();
-            throw new RuntimeException(ie);
-        } catch (InvocationTargetException roe) {
-            Throwable cause = roe.getCause();
-            if (cause instanceof IllegalArgumentException) {
-                throw (IllegalArgumentException) cause;
-            }
-            throw new RuntimeException(cause);
-        }
-
-    }
-
-    private static Menu findMenuParent(JMenuBar menuBar, String[] path, boolean createIfNotFound) {
-        Menu parent = null;
-        int mainMenuCount = menuBar.getMenuCount();
-        for (int i = 0; i < mainMenuCount; i++) {
-            JMenu menu = menuBar.getMenu(i);
-            if (menu.getText().equals(path[0])) {
-                parent = new Menu(menuBar.getMenu(i));
-                break;
-            }
-        }
-        if (parent == null) {
-            if (createIfNotFound) {
-                JMenu delegate = new JMenu(path[0]);
-                parent = new Menu(delegate);
-                menuBar.add(delegate);
-            } else {
-                throw new IllegalArgumentException("top-level " + path[0] + " not found (using path" + Arrays.toString(path) + ")");
-            }
-        }
-
-        for (int i = 1; i < path.length - 1; i++) {
-            Menu[] children = parent.children();
-            boolean found = false;
-            for (int j = 0; j < children.length; j++) {
-                Menu menu = children[j];
-                if (menu.getText().equals(path[i])) {
-                    parent = menu;
-                    found = true;
-                }
-            }
-            if (!found) {
-                if (createIfNotFound) {
-                    Menu newMenu = new Menu(new JMenu(path[i]));
-                    parent.add(newMenu);
-                    parent = newMenu;
-                } else {
-                    throw new IllegalArgumentException("path not found");
-                }
-            }
-        }
-
-        return parent;
-    }
-
-    private static String getText(MenuElement element) {
-        if (element instanceof JMenuItem) {
-            return ((JMenuItem) element).getText();
-        }
-        return "";
-    }
-
-    @SuppressWarnings("unused") // this method is for debugging only
-    private static void printMenu(MenuElement parent, int nestingLevel) {
-        System.out.println(StringUtils.repeat(" ", nestingLevel * 2) + getText(parent) + " [" + parent.getClass() + "]");
-        for (MenuElement element : parent.getSubElements()) {
-            printMenu(element, nestingLevel + 1);
-        }
-    }
-
-    /**
-     * The swing menu hierarchy makes uniform operations very difficult. This
-     * is a hack around that.
-     */
-    private static final class Menu {
-        private Object swingDelegate;
-
-        public Menu() { /* no op */}
-
-        public Menu(JMenuItem actual) {
-            this.swingDelegate = actual;
-        }
-
-        public String getText() {
-            if (swingDelegate instanceof JMenuItem) {
-                return ((JMenuItem) swingDelegate).getText();
-            }
-            return null;
-        }
-
-        public Menu[] children() {
-            if (swingDelegate instanceof MenuElement) {
-                MenuElement[] actualChildren = ((MenuElement) swingDelegate).getSubElements();
-                if (actualChildren.length == 1 && actualChildren[0] instanceof JPopupMenu) {
-                    actualChildren = actualChildren[0].getSubElements();
-                }
-
-                Menu[] children = new Menu[actualChildren.length];
-                for (int i = 0; i < children.length; i++) {
-                    children[i] = new Menu((JMenuItem) actualChildren[i]);
-                }
-                return children;
-            }
-            return new Menu[0];
-        }
-
-        public void add(Menu menu) {
-            if (swingDelegate instanceof JPopupMenu) {
-                ((JPopupMenu) swingDelegate).add((JMenuItem) menu.swingDelegate);
-            } else if (swingDelegate instanceof JMenu) {
-                ((JMenu) swingDelegate).add((JMenuItem) menu.swingDelegate);
-            } else {
-                logger.warning("Unable to add menu. Menu is of unrecognized type: " + menu.swingDelegate);
-            }
-        }
-
-        public void remove(String string) {
-            JPopupMenu removeParent = null;
-
-            if (swingDelegate instanceof JMenu) {
-                JMenu parent = (JMenu) swingDelegate;
-                MenuElement[] actualChildren = parent.getSubElements();
-                if (actualChildren.length == 1 && actualChildren[0] instanceof JPopupMenu) {
-                    removeParent = (JPopupMenu) actualChildren[0];
-                }
-            }
-
-            if (removeParent == null) {
-                if (swingDelegate instanceof JPopupMenu) {
-                    removeParent = (JPopupMenu) swingDelegate;
-                } else {
-                    logger.warning("BUG: problem while removing menu. delegate is not a JPopupMenu, cant remove");
-                    return;
-                }
-            }
-
-            JPopupMenu parent = removeParent;
-            for (MenuElement element : parent.getSubElements()) {
-                if (((JMenuItem) element).getText().equals(string)) {
-                    parent.remove((JMenuItem) element);
-                }
-            }
-        }
-
-        @Override
-        public String toString() {
-            return "Menu [" + swingDelegate.toString() + "]";
-        }
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/RecentTimeSeriesChartPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,219 +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.ui;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.util.concurrent.TimeUnit;
-
-import javax.swing.DefaultComboBoxModel;
-import javax.swing.JComboBox;
-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 javax.swing.text.JTextComponent;
-
-import org.jfree.chart.ChartPanel;
-
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.locale.Translate;
-
-public class RecentTimeSeriesChartPanel extends JPanel {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private static final long serialVersionUID = -1733906800911900456L;
-    private static final int MINIMUM_DRAW_SIZE = 100;
-
-    private final RecentTimeSeriesChartController controller;
-
-    private JPanel labelContainer;
-    private JTextComponent label;
-
-    public RecentTimeSeriesChartPanel(RecentTimeSeriesChartController controller) {
-        this.controller = controller;
-
-        this.setLayout(new BorderLayout());
-
-        final ChartPanel cp = controller.getChartPanel();
-
-        cp.setDisplayToolTips(false);
-        cp.setDoubleBuffered(true);
-        cp.setMouseZoomable(false);
-        cp.setPopupMenu(null);
-
-        /*
-         * By default, ChartPanel scales itself instead of redrawing things when
-         * it's resized. To have it resize automatically, we need to set minimum
-         * and maximum sizes. Lets constrain the minimum, but not the maximum
-         * size.
-         */
-        cp.setMinimumDrawHeight(MINIMUM_DRAW_SIZE);
-        cp.setMaximumDrawHeight(Integer.MAX_VALUE);
-        cp.setMinimumDrawWidth(MINIMUM_DRAW_SIZE);
-        cp.setMaximumDrawWidth(Integer.MAX_VALUE);
-
-        add(getControlsAndAdditionalDisplay(), BorderLayout.SOUTH);
-
-        add(cp, BorderLayout.CENTER);
-    }
-
-    private Component getControlsAndAdditionalDisplay() {
-        JPanel container = new JPanel();
-        container.setOpaque(false);
-
-        container.setLayout(new BorderLayout());
-
-        container.add(getChartControls(), BorderLayout.LINE_START);
-        container.add(getAdditionalDataDisplay(), BorderLayout.LINE_END);
-
-        return container;
-    }
-
-    private Component getChartControls() {
-        JPanel container = new JPanel();
-        container.setOpaque(false);
-
-        final JTextField durationSelector = new JTextField(5);
-        final JComboBox<TimeUnit> unitSelector = new JComboBox<>();
-        unitSelector.setModel(new DefaultComboBoxModel<>(controller.getTimeUnits()));
-
-        int defaultValue = controller.getTimeValue();
-        TimeUnit defaultUnit = controller.getTimeUnit();
-
-        TimeUnitChangeListener timeUnitChangeListener = new TimeUnitChangeListener(controller, defaultValue, defaultUnit);
-
-        durationSelector.getDocument().addDocumentListener(timeUnitChangeListener);
-        unitSelector.addActionListener(timeUnitChangeListener);
-
-        durationSelector.setText(String.valueOf(defaultValue));
-        unitSelector.setSelectedItem(defaultUnit);
-
-        container.add(new JLabel(translator.localize(LocaleResources.CHART_DURATION_SELECTOR_LABEL)));
-        container.add(durationSelector);
-        container.add(unitSelector);
-
-        return container;
-    }
-
-    private Component getAdditionalDataDisplay() {
-        JPanel panel = new JPanel(new GridBagLayout());
-        panel.setOpaque(false);
-        labelContainer = new JPanel();
-        labelContainer.setOpaque(false);
-        GridBagConstraints constraints = new GridBagConstraints();
-        constraints.fill = GridBagConstraints.BOTH;
-        constraints.anchor = GridBagConstraints.CENTER;
-        panel.add(labelContainer, constraints);
-        return panel;
-    }
-
-    public void setDataInformationLabel(final String text) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                if (label == null) {
-                    label = new ValueField(text);
-                    labelContainer.add(label);
-                }
-
-                label.setText(text);
-            }
-        });
-    }
-
-    private static class TimeUnitChangeListener implements DocumentListener, ActionListener {
-
-        private final RecentTimeSeriesChartController controller;
-        private int value;
-        private TimeUnit unit;
-
-        public TimeUnitChangeListener(RecentTimeSeriesChartController controller, int defaultValue, TimeUnit defaultUnit) {
-            this.controller = controller;
-            this.value = defaultValue;
-            this.unit = defaultUnit;
-        }
-
-        @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) {
-            try {
-                this.value = Integer.valueOf(doc.getText(0, doc.getLength()));
-            } catch (NumberFormatException nfe) {
-                // ignore
-            } catch (BadLocationException ble) {
-                // ignore
-            }
-            updateChartParameters();
-        }
-
-        private void updateChartParameters() {
-            controller.setTime(value, unit);
-        }
-
-        @Override
-        public void actionPerformed(ActionEvent e) {
-            @SuppressWarnings("unchecked") // We are a TimeUnitChangeListener, specifically.
-            JComboBox<TimeUnit> comboBox = (JComboBox<TimeUnit>) e.getSource();
-            TimeUnit time = (TimeUnit) comboBox.getSelectedItem();
-            this.unit = time;
-            updateChartParameters();
-        }
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/SearchFieldSwingView.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,224 +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.ui;
-
-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.common.ActionListener;
-import com.redhat.thermostat.common.ActionNotifier;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.swing.EdtHelper;
-
-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/core/src/main/java/com/redhat/thermostat/client/ui/SectionHeader.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +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.ui;
-
-import javax.swing.JLabel;
-import javax.swing.SwingConstants;
-
-public class SectionHeader extends JLabel {
-
-    public SectionHeader(String text) {
-        super(HtmlTextBuilder.boldHtml(text));
-        setHorizontalAlignment(SwingConstants.LEADING);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/SimpleTable.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,289 +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.ui;
-
-import java.awt.Component;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Set;
-
-import javax.swing.Box;
-import javax.swing.JComponent;
-import javax.swing.JEditorPane;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JTextArea;
-import javax.swing.JTextField;
-import javax.swing.SwingUtilities;
-
-import com.redhat.thermostat.client.internal.ChangeableText;
-
-public class SimpleTable implements ChangeableText.TextListener {
-
-    Map<ChangeableText, Set<JComponent>> updateMap = new HashMap<ChangeableText, Set<JComponent>>();
-
-    public static class Section {
-        private final String sectionName;
-        private final List<TableEntry> tableEntries = new ArrayList<TableEntry>();
-
-        public Section(String name) {
-            this.sectionName = name;
-        }
-
-        public String getText() {
-            return sectionName;
-        }
-
-        public void add(TableEntry entry) {
-            tableEntries.add(entry);
-        }
-
-        public void add(Key key, List<Value> values) {
-            tableEntries.add(new TableEntry(key, values));
-        }
-
-        public void add(Key key, Value value) {
-            tableEntries.add(new TableEntry(key, value));
-        }
-
-        public TableEntry[] getEntries() {
-            return tableEntries.toArray(new TableEntry[0]);
-        }
-    }
-
-    public static class TableEntry {
-        private final Key key;
-        private final List<Value> values;
-
-        public TableEntry(String key, ChangeableText value) {
-            this(new Key(key), new Value(value));
-        }
-
-        public TableEntry(Key key, Value value) {
-            this.key = key;
-            this.values = new ArrayList<Value>();
-            this.values.add(value);
-        }
-
-        public TableEntry(Key key, List<Value> values) {
-            this.key = key;
-            this.values = new ArrayList<Value>(values);
-        }
-
-        public Key getKey() {
-            return key;
-        }
-
-        public Value[] getValues() {
-            return values.toArray(new Value[0]);
-        }
-    }
-
-    public static class Key {
-        private final String text;
-
-        public Key(String text) {
-            this.text = text;
-        }
-
-        public String getText() {
-            return text;
-        }
-    }
-
-    public static class Value {
-        private final ChangeableText text;
-        private final Component actualComponent;
-
-        public Value(String text) {
-            this(new ChangeableText(text));
-        }
-
-        public Value(ChangeableText text) {
-            this.text = text;
-            this.actualComponent = null;
-        }
-
-        public Value(Component component) {
-            this.actualComponent = component;
-            this.text = null;
-        }
-
-        public Component getComponent() {
-            return actualComponent;
-        }
-
-        public ChangeableText getChangeableText() {
-            return text;
-        }
-    }
-
-    public JPanel createTable(List<Section> sections) {
-        final int SECTION_TOP_GAP = 10;
-        final int ROW_VERTICAL_GAP = 0;
-        final int ROW_HORIZONTAL_GAP = 10;
-
-        Insets sectionHeaderInsets = new Insets(SECTION_TOP_GAP, 0, 0, 0);
-        Insets rowInsets = new Insets(ROW_VERTICAL_GAP, ROW_HORIZONTAL_GAP, ROW_VERTICAL_GAP, ROW_HORIZONTAL_GAP);
-
-        JPanel container = new JPanel();
-        container.setLayout(new GridBagLayout());
-
-        GridBagConstraints keyConstraints = new GridBagConstraints();
-        GridBagConstraints valueConstraints = new GridBagConstraints();
-        GridBagConstraints sectionHeaderConstraints = new GridBagConstraints();
-
-        keyConstraints.insets = valueConstraints.insets = rowInsets;
-        keyConstraints.gridy = valueConstraints.gridy = 0;
-        keyConstraints.gridx = 0;
-        keyConstraints.anchor = GridBagConstraints.FIRST_LINE_END;
-        valueConstraints.gridx = 1;
-        keyConstraints.fill = valueConstraints.fill = GridBagConstraints.HORIZONTAL;
-
-        sectionHeaderConstraints.gridx = 0;
-        sectionHeaderConstraints.gridwidth = GridBagConstraints.REMAINDER;
-        sectionHeaderConstraints.fill = GridBagConstraints.HORIZONTAL;
-        sectionHeaderConstraints.insets = sectionHeaderInsets;
-
-        for (Section section : sections) {
-            sectionHeaderConstraints.gridy = keyConstraints.gridy = ++valueConstraints.gridy;
-            container.add(Components.header(section.getText()), sectionHeaderConstraints);
-            for (TableEntry tableEntry : section.getEntries()) {
-                keyConstraints.gridy = ++valueConstraints.gridy;
-                container.add(Components.label(tableEntry.getKey().getText()), keyConstraints);
-
-                for (Value value : tableEntry.getValues()) {
-                    if (value.getComponent() == null) {
-                        ChangeableText text = value.getChangeableText();
-                        JComponent valueLabel = new ValueField(text.getText());
-                        if (updateMap.containsKey(text)) {
-                            updateMap.get(text).add(valueLabel);
-                        } else {
-                            Set<JComponent> set = new HashSet<JComponent>();
-                            set.add(valueLabel);
-                            updateMap.put(text, set);
-                        }
-                        container.add(valueLabel, valueConstraints);
-                    } else {
-                        container.add(value.getComponent(), valueConstraints);
-                    }
-                    keyConstraints.gridy = ++valueConstraints.gridy;
-                }
-            }
-        }
-
-        GridBagConstraints glueConstraints = new GridBagConstraints();
-        glueConstraints.gridy = keyConstraints.gridy + 1;
-        glueConstraints.gridx = 0;
-        glueConstraints.weightx = 1;
-        glueConstraints.weighty = 1;
-        glueConstraints.fill = GridBagConstraints.BOTH;
-        glueConstraints.gridheight = GridBagConstraints.REMAINDER;
-        glueConstraints.gridwidth = GridBagConstraints.REMAINDER;
-        Component filler = Box.createGlue();
-        container.add(filler, glueConstraints);
-
-        container.addHierarchyListener(new ComponentVisibleListener() {
-            @Override
-            public void componentShown(Component c) {
-                updateAllValues();
-                addAllListeners();
-            }
-
-            @Override
-            public void componentHidden(Component c) {
-                removeAllListeners();
-            }
-        });
-
-        return container;
-    }
-
-
-    private void updateAllValues() {
-        for (Entry<ChangeableText, Set<JComponent>> entry: updateMap.entrySet()) {
-            for (JComponent label: entry.getValue()) {
-                setText(label, entry.getKey().getText());
-            }
-        }
-    }
-
-    private static void setText(JComponent target, String text) {
-        if (target instanceof JLabel) {
-            ((JLabel)target).setText(text);
-        } else if (target instanceof JTextField) {
-            ((JTextField)target).setText(text);
-        } else if (target instanceof JTextArea) {
-            ((JTextArea)target).setText(text);
-        } else if (target instanceof JEditorPane) {
-            ((JEditorPane)target).setText(text);
-        }
-    }
-
-    @Override
-    public void textChanged(final ChangeableText text) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                String newValue = text.getText();
-                for (JComponent label: updateMap.get(text)) {
-                    setText(label, newValue);
-                }
-            }
-        });
-    }
-
-    public void addAllListeners() {
-        for (ChangeableText text : updateMap.keySet()) {
-            text.addListener(this);
-        }
-    }
-
-    public void removeAllListeners() {
-        for (ChangeableText text : updateMap.keySet()) {
-            text.removeListener(this);
-        }
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/SummaryPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,216 +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.ui;
-
-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.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 = Components.header(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 = Components.header(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/core/src/main/java/com/redhat/thermostat/client/ui/SwingComponent.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-package com.redhat.thermostat.client.ui;
-
-import java.awt.Component;
-
-import com.redhat.thermostat.client.core.views.UIComponent;
-
-public interface SwingComponent extends UIComponent {
-
-    Component getUiComponent();
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/UIResources.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,115 +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.ui;
-
-import java.awt.Color;
-import java.awt.Font;
-
-import javax.swing.UIManager;
-import javax.swing.plaf.ColorUIResource;
-
-public class UIResources {
-
-    private static final UIResources resource = new UIResources();
-    
-    private static final ColorUIResource hyperLinkColor;
-    private static final ColorUIResource hyperLinkActiveColor;
-
-    private static final ColorUIResource selectionColor;
-    
-    private static final Font standard;
-    
-    static {
-        Color color = UIManager.getColor("Button.darkShadow");
-        if (color == null) {
-            color = Color.BLUE;
-        }
-        hyperLinkColor = new ColorUIResource(color);
-
-        color = UIManager.getColor("Button.focus");
-        if (color == null) {
-            color = Color.BLUE;
-        }
-        hyperLinkActiveColor = new ColorUIResource(color);
-        selectionColor = hyperLinkActiveColor;
-        
-        Font font = UIManager.getFont("Label.font");
-        if (font == null) {
-            font = Font.decode(Font.DIALOG);
-        }
-        standard = font;
-    }
-    
-    private static final Font header = standard.deriveFont(Font.BOLD);
-    
-    // TODO: check when size is too small
-    private static final Font footer = standard.deriveFont(Font.PLAIN, standard.getSize() - 2);
-    
-    private UIResources() { /* nothing to do */ }
-    
-    // colors
-
-    public static UIResources getInstance() {
-        return resource;
-    }
-    
-    public ColorUIResource hyperlinkColor() {
-        return hyperLinkColor;
-    }
-    
-    public ColorUIResource hyperlinkActiveColor() {
-        return hyperLinkActiveColor;
-    }
-    
-    public ColorUIResource getSelectionColor() {
-        return selectionColor;
-    }
-    
-    // font resources
-    
-    public Font footerFont() {
-        return footer;
-    }
-    
-    public Font headerFont() {
-        return header;
-    }
-    
-    public Font standardFont() {
-        return standard;
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/ValueField.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +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.ui;
-
-import javax.swing.JEditorPane;
-import javax.swing.UIManager;
-
-/**
- * A custom swing component meant for showing values. Use it like you would use
- * any other JTextComponent.
- */
-public class ValueField extends JEditorPane {
-
-    public ValueField(String text) {
-        setText(text);
-        setBorder(null);
-        setOpaque(false);
-        setBackground(UIManager.getColor("Label.background"));
-        setForeground(UIManager.getColor("Label.foreground"));
-        setFont(UIManager.getFont("Label.font"));
-        setEditable(false);
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/VmCpuPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +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.ui;
-
-import java.awt.Component;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.JPanel;
-import javax.swing.SwingUtilities;
-
-import org.jfree.chart.ChartFactory;
-import org.jfree.chart.JFreeChart;
-import org.jfree.data.time.FixedMillisecond;
-import org.jfree.data.time.RegularTimePeriod;
-import org.jfree.data.time.TimeSeries;
-import org.jfree.data.time.TimeSeriesCollection;
-
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.VmCpuView;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.common.model.DiscreteTimeData;
-import com.redhat.thermostat.swing.HeaderPanel;
-
-public class VmCpuPanel extends VmCpuView implements SwingComponent {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private HeaderPanel visiblePanel;
-    
-    private final TimeSeriesCollection data = new TimeSeriesCollection();
-    private final TimeSeries cpuTimeSeries = new TimeSeries("cpu-stats");
-
-    public VmCpuPanel() {
-        super();
-        data.addSeries(cpuTimeSeries);
-
-        initializePanel();
-
-        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 Component getUiComponent() {
-        return visiblePanel;
-    }
-
-    private void initializePanel() {
-        visiblePanel = new HeaderPanel();
-        visiblePanel.setHeader(translator.localize(LocaleResources.VM_CPU_TITLE));
-
-        JFreeChart chart = ChartFactory.createTimeSeriesChart(
-                null,
-                translator.localize(LocaleResources.VM_CPU_CHART_TIME_LABEL),
-                translator.localize(LocaleResources.VM_CPU_CHART_LOAD_LABEL),
-                data,
-                false, false, false);
-
-        chart.getXYPlot().getRangeAxis().setLowerBound(0.0);
-
-        JPanel chartPanel = new RecentTimeSeriesChartPanel(new RecentTimeSeriesChartController(chart));
-
-        visiblePanel.setContent(chartPanel);
-    }
-
-    @Override
-    public void addData(List<DiscreteTimeData<? extends Number>> data) {
-        final List<DiscreteTimeData<? extends Number>> copy = new ArrayList<>(data);
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                for (DiscreteTimeData<? extends Number> data: copy) {
-                    RegularTimePeriod period = new FixedMillisecond(data.getTimeInMillis());
-                    if (cpuTimeSeries.getDataItem(period) == null) {
-                        cpuTimeSeries.add(period, data.getData(), false);
-                    }
-                }
-                cpuTimeSeries.fireSeriesChanged();
-            }
-        });
-    }
-
-    @Override
-    public void clearData() {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                cpuTimeSeries.clear();
-            }
-        });
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/VmGcPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,245 +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.ui;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.swing.JPanel;
-import javax.swing.SwingUtilities;
-
-import org.jfree.chart.ChartFactory;
-import org.jfree.chart.JFreeChart;
-import org.jfree.chart.axis.DateAxis;
-import org.jfree.chart.axis.NumberAxis;
-import org.jfree.chart.event.ChartProgressEvent;
-import org.jfree.chart.event.ChartProgressListener;
-import org.jfree.chart.plot.PlotOrientation;
-import org.jfree.chart.plot.XYPlot;
-import org.jfree.chart.renderer.xy.StandardXYBarPainter;
-import org.jfree.chart.renderer.xy.XYBarRenderer;
-import org.jfree.data.RangeType;
-import org.jfree.data.xy.IntervalXYDataset;
-
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.VmGcView;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.common.model.IntervalTimeData;
-import com.redhat.thermostat.swing.HeaderPanel;
-
-public class VmGcPanel extends VmGcView implements SwingComponent {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private HeaderPanel visiblePanel = new HeaderPanel();
-    private JPanel realPanel = new JPanel();
-
-    private final Map<String, SampledDataset> dataset = new HashMap<>();
-    private final Map<String, JPanel> subPanels = new HashMap<>();
-
-    private final GridBagConstraints gcPanelConstraints;
-
-    public VmGcPanel() {
-        super();
-        initializePanel();
-
-        gcPanelConstraints = new GridBagConstraints();
-        gcPanelConstraints.gridx = 0;
-        gcPanelConstraints.gridy = 0;
-        gcPanelConstraints.fill = GridBagConstraints.BOTH;
-        gcPanelConstraints.weightx = 1;
-        gcPanelConstraints.weighty = 1;
-
-        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 Component getUiComponent() {
-        return visiblePanel;
-    }
-
-    private void initializePanel() {
-        visiblePanel.setContent(realPanel);
-        visiblePanel.setHeader(translator.localize(LocaleResources.VM_GC_TITLE));
-        realPanel.setLayout(new GridBagLayout());
-    }
-
-    private JPanel createCollectorDetailsPanel(IntervalXYDataset collectorData, String title, String units) {
-        JPanel detailsPanel = new JPanel();
-        detailsPanel.setBorder(Components.smallBorder());
-        detailsPanel.setLayout(new BorderLayout());
-
-        detailsPanel.add(Components.header(title), BorderLayout.NORTH);
-
-        JFreeChart chart = ChartFactory.createHistogram(
-            null,
-            translator.localize(LocaleResources.VM_GC_COLLECTOR_CHART_REAL_TIME_LABEL),
-            translator.localize(LocaleResources.VM_GC_COLLECTOR_CHART_GC_TIME_LABEL, units),
-            collectorData,
-            PlotOrientation.VERTICAL,
-            false,
-            false,
-            false);
-
-        ((XYBarRenderer)(chart.getXYPlot().getRenderer())).setBarPainter(new StandardXYBarPainter());
-
-        setupPlotAxes(chart.getXYPlot());
-
-        chart.getXYPlot().setDomainCrosshairLockedOnData(true);
-        chart.getXYPlot().setDomainCrosshairVisible(true);
-
-        final RecentTimeSeriesChartPanel chartPanel = new RecentTimeSeriesChartPanel(new RecentTimeSeriesChartController(chart));
-
-        chart.addProgressListener(new ChartProgressListener() {
-
-            @Override
-            public void chartProgress(ChartProgressEvent event) {
-                if (event.getType() != ChartProgressEvent.DRAWING_FINISHED) {
-                    return;
-                }
-
-                double rangeCrossHairValue = event.getChart().getXYPlot().getRangeCrosshairValue();
-                chartPanel.setDataInformationLabel(String.valueOf(rangeCrossHairValue));
-            }
-        });
-
-        detailsPanel.add(chartPanel, BorderLayout.CENTER);
-
-        return detailsPanel;
-    }
-
-    private void setupPlotAxes(XYPlot plot) {
-        setupDomainAxis(plot);
-        setupRangeAxis(plot);
-    }
-
-    private void setupDomainAxis(XYPlot plot) {
-        plot.setDomainAxis(new DateAxis());
-    }
-
-    private void setupRangeAxis(XYPlot plot) {
-        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
-
-        rangeAxis.setRangeType(RangeType.POSITIVE);
-        rangeAxis.setAutoRange(true);
-        rangeAxis.setAutoRangeMinimumSize(1);
-    }
-
-    @Override
-    public void addChart(final String tag, final String title, final String units) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                SampledDataset newData = new SampledDataset();
-                dataset.put(tag, newData);
-                JPanel subPanel = createCollectorDetailsPanel(newData, title, units);
-                subPanels.put(tag, subPanel);
-                realPanel.add(subPanel, gcPanelConstraints);
-                gcPanelConstraints.gridy++;
-                realPanel.revalidate();
-            }
-        });
-    }
-
-    @Override
-    public void removeChart(final String tag) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                dataset.remove(tag);
-                JPanel subPanel = subPanels.remove(tag);
-                realPanel.remove(subPanel);
-                realPanel.revalidate();
-                gcPanelConstraints.gridy--;
-            }
-        });
-    }
-
-    @Override
-    public void addData(final String tag, List<IntervalTimeData<Double>> data) {
-        final List<IntervalTimeData<Double>> copy = new ArrayList<>(data);
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                SampledDataset series = dataset.get(tag);
-                for (IntervalTimeData<Double> timeData: copy) {
-                    series.add(timeData.getStartTimeInMillis(), timeData.getEndTimeInMillis(), timeData.getData());
-                }
-                series.fireSeriesChanged();
-            }
-        });
-    }
-
-    @Override
-    public void clearData(final String tag) {
-        SwingUtilities.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                SampledDataset series = dataset.get(tag);
-                series.clear();
-            }
-        });
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/VmInformationPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,94 +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.ui;
-
-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;
-
-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/core/src/main/java/com/redhat/thermostat/client/ui/VmOverviewPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,189 +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.ui;
-
-import java.awt.Component;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.JPanel;
-
-import com.redhat.thermostat.client.core.views.VmOverviewView;
-import com.redhat.thermostat.client.internal.ChangeableText;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.client.ui.SimpleTable.Section;
-import com.redhat.thermostat.client.ui.SimpleTable.TableEntry;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.swing.HeaderPanel;
-
-public class VmOverviewPanel extends VmOverviewView implements SwingComponent {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-    
-    private HeaderPanel visiblePanel;
-
-    private final ChangeableText pid = new ChangeableText("");
-    private final ChangeableText startTimeStamp = new ChangeableText("");
-    private final ChangeableText stopTimeStamp = new ChangeableText("");
-    private final ChangeableText mainClass = new ChangeableText("");
-    private final ChangeableText javaCommandLine = new ChangeableText("");
-    private final ChangeableText javaHome = new ChangeableText("");
-    private final ChangeableText javaVersion = new ChangeableText("");
-    private final ChangeableText vmNameAndVersion = new ChangeableText("");
-    private final ChangeableText vmArguments = new ChangeableText("");
-
-    public VmOverviewPanel() {
-        super();
-        initializePanel();
-        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 setVmPid(String pid) {
-        this.pid.setText(pid);
-    }
-
-    @Override
-    public void setVmStartTimeStamp(String timeStamp) {
-        this.startTimeStamp.setText(timeStamp);
-    }
-
-    @Override
-    public void setVmStopTimeStamp(String timeStamp) {
-        this.stopTimeStamp.setText(timeStamp);
-    }
-
-    @Override
-    public void setMainClass(String mainClass) {
-        this.mainClass.setText(mainClass);
-    }
-
-    @Override
-    public void setJavaCommandLine(String javaCommandLine) {
-        this.javaCommandLine.setText(javaCommandLine);
-    }
-
-    @Override
-    public void setJavaHome(String javaHome) {
-        this.javaHome.setText(javaHome);
-
-    }
-
-    @Override
-    public void setJavaVersion(String javaVersion) {
-        this.javaVersion.setText(javaVersion);
-    }
-
-    @Override
-    public void setVmNameAndVersion(String vmNameAndVersion) {
-        this.vmNameAndVersion.setText(vmNameAndVersion);
-    }
-
-    @Override
-    public void setVmArguments(String vmArguments) {
-        this.vmArguments.setText(vmArguments);
-    }
-
-    @Override
-    public void setVmInfo(String string) {
-        // no-op
-    }
-
-    @Override
-    public Component getUiComponent() {
-        return visiblePanel;
-    }
-
-    private void initializePanel() {
-        visiblePanel = new HeaderPanel();
-
-        visiblePanel.setHeader(translator.localize(LocaleResources.VM_INFO_TITLE));
-
-        TableEntry entry;
-        List<Section> allSections = new ArrayList<Section>();
-
-        Section processSection = new Section(translator.localize(LocaleResources.VM_INFO_SECTION_PROCESS));
-        allSections.add(processSection);
-
-        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_PROCESS_ID), pid);
-        processSection.add(entry);
-        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_START_TIME), startTimeStamp);
-        processSection.add(entry);
-        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_STOP_TIME), stopTimeStamp);
-        processSection.add(entry);
-
-        Section javaSection = new Section(translator.localize(LocaleResources.VM_INFO_SECTION_JAVA));
-        allSections.add(javaSection);
-
-        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_MAIN_CLASS), mainClass);
-        javaSection.add(entry);
-        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_COMMAND_LINE), javaCommandLine);
-        javaSection.add(entry);
-        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_JAVA_VERSION), javaVersion);
-        javaSection.add(entry);
-        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_VM), vmNameAndVersion);
-        javaSection.add(entry);
-        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_VM_ARGUMENTS), vmArguments);
-        javaSection.add(entry);
-
-        SimpleTable simpleTable = new SimpleTable();
-        JPanel table = simpleTable.createTable(allSections);
-        table.setBorder(Components.smallBorder());
-        visiblePanel.setContent(table);
-    }
-}
Binary file client/core/src/main/resources/duke.png has changed
--- a/client/core/src/test/java/com/redhat/thermostat/client/internal/GUIClientCommandTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +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.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNotNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.Dictionary;
-
-import org.apache.commons.cli.Options;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.osgi.framework.BundleContext;
-
-import com.redhat.thermostat.client.internal.GUIClientCommand;
-import com.redhat.thermostat.client.internal.Main;
-import com.redhat.thermostat.client.osgi.service.ApplicationService;
-import com.redhat.thermostat.client.osgi.service.ContextAction;
-import com.redhat.thermostat.common.cli.CommandContext;
-import com.redhat.thermostat.common.cli.CommandContextFactory;
-import com.redhat.thermostat.common.cli.CommandException;
-
-public class GUIClientCommandTest {
-
-    private GUIClientCommand cmd;
-    private Main clientMain;
-
-    @Before
-    public void setUp() {
-        clientMain = mock(Main.class);
-        cmd = new GUIClientCommand(clientMain);
-    }
-
-    @After
-    public void tearDown() {
-        cmd = null;
-        clientMain = null;
-    }
-
-    @Test
-    public void testRun() throws CommandException {
-        BundleContext bCtx = mock(BundleContext.class);
-        CommandContextFactory cmdCtxFactory = mock(CommandContextFactory.class);
-
-        CommandContext cmdCtx = mock(CommandContext.class);
-        when(cmdCtx.getCommandContextFactory()).thenReturn(cmdCtxFactory);
-
-        cmd.setBundleContext(bCtx);
-        cmd.run(cmdCtx);
-
-        verify(clientMain).run();
-        verify(bCtx).registerService(eq(ApplicationService.class.getName()), isNotNull(), any(Dictionary.class));
-        verify(bCtx).registerService(eq(ContextAction.class.getName()), isNotNull(), any(Dictionary.class));
-    }
-
-    @Test
-    public void testName() {
-        assertEquals("gui", cmd.getName());
-    }
-
-    @Test
-    public void testDescAndUsage() {
-        assertNotNull(cmd.getDescription());
-        assertNotNull(cmd.getUsage());
-    }
-
-    @Test
-    public void testRequiresStorage() {
-        assertFalse(cmd.isStorageRequired());
-    }
-
-    @Test
-    public void testOptions() {
-        Options options = cmd.getOptions();
-        assertNotNull(options);
-        assertEquals(0, options.getOptions().size());
-    }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/internal/HostIconDecoratorTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +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.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-
-import java.awt.image.BufferedImage;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-
-import javax.imageio.ImageIO;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.client.core.HostFilter;
-import com.redhat.thermostat.client.ui.Decorator;
-import com.redhat.thermostat.common.dao.HostRef;
-
-public class HostIconDecoratorTest {
-
-    @Test
-    public void verifyFilter() {
-        HostIconDecorator decorator = new HostIconDecorator();
-
-        HostFilter filter = decorator.getFilter();
-        HostRef aHost = mock(HostRef.class);
-
-        assertTrue(filter.matches(aHost));
-    }
-
-    @Test
-    public void verifyHostDecoratorDoesNotModifyLabel() {
-        HostIconDecorator iconDecorator = new HostIconDecorator();
-
-        Decorator decorator = iconDecorator.getDecorator();
-
-        String INPUT = "testfoobarbaz";
-
-        assertEquals(INPUT, decorator.getLabel(INPUT));
-    }
-
-    @Test
-    public void verifyHostDecoratorHasAnIcon() throws IOException {
-        HostIconDecorator iconDecorator = new HostIconDecorator();
-
-        Decorator decorator = iconDecorator.getDecorator();
-
-        BufferedImage icon = ImageIO.read(new ByteArrayInputStream(decorator.getIconDescriptor().getData().array()));
-
-        assertNotNull(icon);
-    }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/internal/MainTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,202 +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.internal;
-
-import static org.mockito.Matchers.isA;
-import static org.mockito.Mockito.doAnswer;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.concurrent.ExecutorService;
-
-import javax.swing.SwingUtilities;
-
-import org.junit.Before;
-import org.junit.Ignore;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import com.redhat.thermostat.client.osgi.service.ApplicationService;
-import com.redhat.thermostat.client.ui.MainWindowController;
-import com.redhat.thermostat.client.ui.UiFacadeFactory;
-import com.redhat.thermostat.common.TimerFactory;
-import com.redhat.thermostat.common.dao.DAOFactory;
-import com.redhat.thermostat.common.storage.Connection;
-import com.redhat.thermostat.common.storage.Connection.ConnectionListener;
-import com.redhat.thermostat.common.storage.Connection.ConnectionStatus;
-import com.redhat.thermostat.common.utils.OSGIUtils;
-
-public class MainTest {
-
-    private ExecutorService executorService;
-    private OSGIUtils serviceProvider;
-
-    private MainWindowController mainWindowController;
-    private UiFacadeFactory uiFactory;
-
-    private Connection connection;
-    private ArgumentCaptor<ConnectionListener> connectionListenerCaptor;
-
-    private DAOFactory daoFactory;
-
-    private TimerFactory timerFactory;
-
-    @Before
-    public void setUp() {
-        ApplicationService appService = mock(ApplicationService.class);
-
-        executorService = mock(ExecutorService.class);
-        doAnswer(new Answer<Void>() {
-            @Override
-            public Void answer(InvocationOnMock invocation) throws Throwable {
-                Runnable runnable = (Runnable) invocation.getArguments()[0];
-                runnable.run();
-                return null;
-            }
-        }).when(executorService).execute(isA(Runnable.class));
-
-        when(appService.getApplicationExecutor()).thenReturn(executorService);
-
-        serviceProvider = mock(OSGIUtils.class);
-        when(serviceProvider.getService(ApplicationService.class)).thenReturn(appService);
-
-        mainWindowController = mock(MainWindowController.class);
-
-        uiFactory = mock(UiFacadeFactory.class);
-        when(uiFactory.getMainWindow()).thenReturn(mainWindowController);
-
-        connection = mock(Connection.class);
-        connectionListenerCaptor = ArgumentCaptor.forClass(ConnectionListener.class);
-        doNothing().when(connection).addListener(connectionListenerCaptor.capture());
-
-        daoFactory = mock(DAOFactory.class);
-        when(daoFactory.getConnection()).thenReturn(connection);
-
-        timerFactory = mock(TimerFactory.class);
-    }
-
-    /**
-     * Handle all outstanding EDT events by posting a no-op event and waiting
-     * until it completes.
-     */
-    private void handleAllEdtEvents() throws Exception {
-        SwingUtilities.invokeAndWait(new Runnable() {
-            @Override
-            public void run() {
-                /* NO-OP */
-            }
-        });
-    }
-
-    @Test
-    public void verifyRunWaitsForShutdown() throws Exception {
-        Main main = new Main(serviceProvider, uiFactory, daoFactory, timerFactory);
-
-        main.run();
-
-        handleAllEdtEvents();
-
-        verify(uiFactory).awaitShutdown();
-    }
-
-    @Test
-    public void verifyConnectionIsMade() throws Exception {
-        Main main = new Main(serviceProvider, uiFactory, daoFactory, timerFactory);
-
-        main.run();
-
-        handleAllEdtEvents();
-
-        verify(connection).connect();
-
-    }
-
-    @Test
-    public void verifySuccessfulConnectionTriggersMainWindowToBeShown() throws Exception {
-        Main main = new Main(serviceProvider, uiFactory, daoFactory, timerFactory);
-
-        main.run();
-
-        handleAllEdtEvents();
-
-        ConnectionListener connectionListener = connectionListenerCaptor.getValue();
-        connectionListener.changed(ConnectionStatus.CONNECTED);
-
-        handleAllEdtEvents();
-
-        verify(mainWindowController).showMainMainWindow();
-    }
-
-    @Test
-    public void verifySuccessfulConnectionRegistersDAOs() throws Exception {
-
-        Main main = new Main(serviceProvider, uiFactory, daoFactory, timerFactory);
-
-        main.run();
-
-        handleAllEdtEvents();
-
-        ConnectionListener connectionListener = connectionListenerCaptor.getValue();
-        connectionListener.changed(ConnectionStatus.CONNECTED);
-
-        handleAllEdtEvents();
-
-        verify(daoFactory).registerDAOsAndStorageAsOSGiServices();
-    }
-
-    @Ignore("this prompts the user with some gui")
-    @Test
-    public void verifyFailedConnectionTriggersShutdown() throws Exception {
-
-        Main main = new Main(serviceProvider, uiFactory, daoFactory, timerFactory);
-
-        main.run();
-
-        handleAllEdtEvents();
-
-        ConnectionListener connectionListener = connectionListenerCaptor.getValue();
-        connectionListener.changed(ConnectionStatus.FAILED_TO_CONNECT);
-
-        handleAllEdtEvents();
-
-        verify(uiFactory).shutdown();
-    }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/internal/MainWindowControllerImplTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,561 +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.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyInt;
-import static org.mockito.Matchers.isA;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.awt.event.MouseEvent;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.osgi.framework.BundleException;
-
-import com.redhat.thermostat.client.core.VmFilter;
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.client.osgi.service.VMContextAction;
-import com.redhat.thermostat.client.osgi.service.VmDecorator;
-import com.redhat.thermostat.client.ui.HostVmFilter;
-import com.redhat.thermostat.client.ui.SummaryController;
-import com.redhat.thermostat.client.ui.UiFacadeFactory;
-import com.redhat.thermostat.client.ui.VmInformationController;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.HostsVMsLoader;
-import com.redhat.thermostat.common.ThermostatExtensionRegistry;
-import com.redhat.thermostat.common.Timer;
-import com.redhat.thermostat.common.ThermostatExtensionRegistry.Action;
-import com.redhat.thermostat.common.Timer.SchedulingType;
-import com.redhat.thermostat.common.TimerFactory;
-import com.redhat.thermostat.common.appctx.ApplicationContext;
-import com.redhat.thermostat.common.appctx.ApplicationContextUtil;
-import com.redhat.thermostat.common.dao.HostInfoDAO;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.VmInfoDAO;
-import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.common.model.VmInfo;
-import com.redhat.thermostat.test.Bug;
-
-public class MainWindowControllerImplTest {
-
-    private ActionListener<MainView.Action> l;
-
-    private MainWindowControllerImpl controller;
-
-    private UiFacadeFactory uiFacadeFactory;
-    
-    private MainView view;
-
-    private Timer mainWindowTimer;
-
-    private HostInfoDAO mockHostsDAO;
-    private VmInfoDAO mockVmsDAO;
-
-    private VMContextAction action1;
-    private VMContextAction action2;
-
-    private HostFilterRegistry hostFilterRegistry;
-    private VmFilterRegistry vmFilterRegistry;
-    private HostTreeDecoratorRegistry hostDecoratorRegistry;
-    private VMTreeDecoratorRegistry vmDecoratorRegistry;
-    private VMInformationRegistry vmInfoRegistry;
-    private MenuRegistry menus;
-    
-    @SuppressWarnings("unused")
-    private ActionListener<ThermostatExtensionRegistry.Action> hostFiltersListener;
-    @SuppressWarnings("unused")
-    private ActionListener<ThermostatExtensionRegistry.Action> vmFiltersListener;
-    private ActionListener<ThermostatExtensionRegistry.Action> decoratorsListener;
-    
-    @BeforeClass
-    public static void setUpOnce() {
-        // TODO remove when controller uses mocked objects rather than real swing objects
-        FailOnThreadViolationRepaintManager.install();
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" }) // ActionListener fluff
-    @Before
-    public void setUp() throws Exception {
-        ApplicationContextUtil.resetApplicationContext();
-
-        // Setup timers
-        mainWindowTimer = mock(Timer.class);
-        Timer otherTimer = mock(Timer.class); // FIXME needed for SummaryView; remove later
-        TimerFactory timerFactory = mock(TimerFactory.class);
-        when(timerFactory.createTimer()).thenReturn(mainWindowTimer).thenReturn(otherTimer);
-        ApplicationContext.getInstance().setTimerFactory(timerFactory);
-
-        SummaryController summaryController = mock(SummaryController.class);
-
-        uiFacadeFactory = mock(UiFacadeFactory.class);
-        
-        when(uiFacadeFactory.getSummary()).thenReturn(summaryController);
-
-        mockHostsDAO = mock(HostInfoDAO.class);
-        mockVmsDAO = mock(VmInfoDAO.class);
-
-        // Setup View
-        view = mock(MainView.class);
-        ArgumentCaptor<ActionListener> grabListener = ArgumentCaptor.forClass(ActionListener.class);
-        doNothing().when(view).addActionListener(grabListener.capture());
-        
-        RegistryFactory registryFactory = mock(RegistryFactory.class);
-        hostFilterRegistry = mock(HostFilterRegistry.class);
-        vmFilterRegistry = mock(VmFilterRegistry.class);
-        hostDecoratorRegistry = mock(HostTreeDecoratorRegistry.class);
-        vmDecoratorRegistry = mock(VMTreeDecoratorRegistry.class);
-        vmInfoRegistry = mock(VMInformationRegistry.class);
-        menus = mock(MenuRegistry.class);
-
-        when(registryFactory.createMenuRegistry()).thenReturn(menus);
-        when(registryFactory.createHostTreeDecoratorRegistry()).thenReturn(hostDecoratorRegistry);
-        when(registryFactory.createVMTreeDecoratorRegistry()).thenReturn(vmDecoratorRegistry);
-        when(registryFactory.createHostFilterRegistry()).thenReturn(hostFilterRegistry);
-        when(registryFactory.createVmFilterRegistry()).thenReturn(vmFilterRegistry);
-        when(registryFactory.createVMInformationRegistry()).thenReturn(vmInfoRegistry);
-        
-        ArgumentCaptor<ActionListener> grabHostFiltersListener = ArgumentCaptor.forClass(ActionListener.class);
-        doNothing().when(hostFilterRegistry).addActionListener(grabHostFiltersListener.capture());
-
-        ArgumentCaptor<ActionListener> grabVmFiltersListener = ArgumentCaptor.forClass(ActionListener.class);
-        doNothing().when(vmFilterRegistry).addActionListener(grabVmFiltersListener.capture());
-
-        ArgumentCaptor<ActionListener> grabDecoratorsListener = ArgumentCaptor.forClass(ActionListener.class);
-        doNothing().when(vmDecoratorRegistry).addActionListener(grabDecoratorsListener.capture());
-        
-        ArgumentCaptor<ActionListener> grabInfoRegistry = ArgumentCaptor.forClass(ActionListener.class);
-        doNothing().when(vmInfoRegistry).addActionListener(grabInfoRegistry.capture());
-
-        setUpVMContextActions();
-
-        controller = new MainWindowControllerImpl(uiFacadeFactory, view, registryFactory, mockHostsDAO, mockVmsDAO);
-        l = grabListener.getValue();
-        
-        hostFiltersListener = grabHostFiltersListener.getValue();
-        vmFiltersListener = grabVmFiltersListener.getValue();
-        decoratorsListener = grabDecoratorsListener.getValue();
-    }
-
-    private void setUpVMContextActions() {
-        action1 = mock(VMContextAction.class);
-        VmFilter action1Filter = mock(VmFilter.class);
-        when(action1Filter.matches(isA(VmRef.class))).thenReturn(true);
-
-        when(action1.getName()).thenReturn("action1");
-        when(action1.getDescription()).thenReturn("action1desc");
-        when(action1.getFilter()).thenReturn(action1Filter);
-        
-        action2 = mock(VMContextAction.class);
-        VmFilter action2Filter = mock(VmFilter.class);
-        when(action2Filter.matches(isA(VmRef.class))).thenReturn(false);
-
-        when(action2.getName()).thenReturn("action2");
-        when(action2.getDescription()).thenReturn("action2desc");
-        when(action2.getFilter()).thenReturn(action2Filter);
-        
-        Collection<VMContextAction> actions = new ArrayList<>();
-        actions.add(action1);
-        actions.add(action2);
-        
-        when(uiFacadeFactory.getVMContextActions()).thenReturn(actions);
-    }
-
-    @After
-    public void tearDown() {
-        view = null;
-        controller = null;
-        mockHostsDAO = null;
-        mockVmsDAO = null;
-        l = null;
-        ApplicationContextUtil.resetApplicationContext();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void verifyDecoratorsAdded() {
-
-        List<VmDecorator> currentDecoratros = controller.getVmTreeDecorators();
-        assertEquals(0, currentDecoratros.size());
-        
-        ActionEvent<ThermostatExtensionRegistry.Action> event =
-                new ActionEvent<ThermostatExtensionRegistry.Action>(vmDecoratorRegistry,
-                        ThermostatExtensionRegistry.Action.SERVICE_ADDED);
-        
-        VmDecorator payload = mock(VmDecorator.class);
-        event.setPayload(payload);
-        
-        decoratorsListener.actionPerformed(event);
-
-        currentDecoratros = controller.getVmTreeDecorators();
-        assertEquals(1, currentDecoratros.size());
-        assertEquals(payload, currentDecoratros.get(0));
-        
-        verify(view).updateTree(any(List.class), isA(List.class), isA(List.class), any(List.class), any(HostsVMsLoader.class));
-    }
-    
-    @Test
-    public void verifyThatHiddenEventStopsController() {
-
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HIDDEN));
-
-        verify(mainWindowTimer).stop();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void verifyThatHostsVmsFilterChangeUpdatesTree() {
-
-        when(view.getHostVmTreeFilterText()).thenReturn("test");
-
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_TREE_FILTER));
-
-        verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), isA(HostsVMsLoader.class));
-    }
-    
-    @Test
-    public void verifyTimerGetsStartedOnBecomingVisible() {
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.VISIBLE));
-
-        verify(mainWindowTimer).setDelay(3);
-        verify(mainWindowTimer).setTimeUnit(TimeUnit.SECONDS);
-        verify(mainWindowTimer).setSchedulingType(SchedulingType.FIXED_RATE);
-        verify(mainWindowTimer).start();
-    }
-
-    @Test
-    public void verifyShowMainWindowActuallyCallsView() {
-        controller.showMainMainWindow();
-        verify(view).showMainWindow();
-    }
-
-    @Test
-    public void verifySubViewIsSetByDefault() throws InvocationTargetException, InterruptedException {
-        verify(view).setSubView(any(BasicView.class));
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void verifyUpdateHostsVMsLoadsCorrectHosts() {
-
-        Collection<HostRef> expectedHosts = new ArrayList<>();
-        expectedHosts.add(new HostRef("123", "fluffhost1"));
-        expectedHosts.add(new HostRef("456", "fluffhost2"));
-
-        when(mockHostsDAO.getAliveHosts()).thenReturn(expectedHosts);
-
-        controller.doUpdateTreeAsync();
-
-        ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
-        verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), arg.capture());
-        HostsVMsLoader loader = arg.getValue();
-
-        Collection<HostRef> actualHosts = loader.getHosts();
-        assertEqualCollection(expectedHosts, actualHosts);
-    }
-    
-    @SuppressWarnings("unchecked")
-    @Test
-    public void verifyHistoryModeUpdateHostsVMCorrectly() {
-
-        Collection<HostRef> liveHost = new ArrayList<>();
-        liveHost.add(new HostRef("123", "fluffhost1"));
-        liveHost.add(new HostRef("456", "fluffhost2"));
-
-        Collection<HostRef> allHosts = new ArrayList<>();
-        allHosts.addAll(liveHost);
-        allHosts.add(new HostRef("789", "fluffhost3"));
-
-        when(mockHostsDAO.getAliveHosts()).thenReturn(liveHost);
-        when(mockHostsDAO.getHosts()).thenReturn(allHosts);
-
-        controller.doUpdateTreeAsync();
-
-        ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
-        verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), arg.capture());
-        HostsVMsLoader loader = arg.getValue();
-
-        Collection<HostRef> actualHosts = loader.getHosts();
-        assertEqualCollection(liveHost, actualHosts);
-
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.SWITCH_HISTORY_MODE));
-        ArgumentCaptor<HostsVMsLoader> argCaptor = ArgumentCaptor.forClass(HostsVMsLoader.class);
-        // actionPerformed triggers updateTree
-        verify(view, times(2)).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), argCaptor.capture());
-        loader = argCaptor.getValue();
-
-        actualHosts = loader.getHosts();
-        assertEqualCollection(allHosts, actualHosts);
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void verifyUpdateHostsVMsLoadsCorrectVMs() {
-
-        Collection<VmRef> expectedVMs = new ArrayList<>();
-        HostRef host = new HostRef("123", "fluffhost1");
-        expectedVMs.add(new VmRef(host, 123, "vm1"));
-        expectedVMs.add(new VmRef(host, 456, "vm2"));
-
-        when(mockVmsDAO.getVMs(any(HostRef.class))).thenReturn(expectedVMs);
-
-        controller.doUpdateTreeAsync();
-
-        ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
-        verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), arg.capture());
-        HostsVMsLoader loader = arg.getValue();
-
-        Collection<VmRef> actualVMs = loader.getVMs(host);
-        assertEqualCollection(expectedVMs, actualVMs);
-    }
-
-    @Test
-    public void verifyUpdateHostsVMsLoadsCorrectVMWithFilter() {
-
-        VmRef ref1 = mock(VmRef.class);
-        when(ref1.getStringID()).thenReturn("test1");
-        when(ref1.getName()).thenReturn("test1");
-        
-        VmRef ref2 = mock(VmRef.class);
-        when(ref2.getStringID()).thenReturn("test2");
-        when(ref2.getName()).thenReturn("test2");
-        
-        controller.setHostVmTreeFilter("test1");
-                
-        HostVmFilter filter = controller.getSearchFilter();
-        assertTrue(filter.matches(ref1));
-        assertFalse(filter.matches(ref2));
-    }
-    
-    private void assertEqualCollection(Collection<?> expected, Collection<?> actual) {
-        assertEquals(expected.size(), actual.size());
-        assertTrue(expected.containsAll(actual));
-    }
-
-    @Test
-    @Bug(id="954",
-         summary="Thermostat GUI client should remember my last panel selected",
-         url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=954")
-    public void verifyOpenSameHostVMTab() throws Exception {
-
-        VmRef vmRef = mock(VmRef.class);
-        when(vmRef.getName()).thenReturn("testvm");
-        when(vmRef.getIdString()).thenReturn("testvmid");
-        HostRef ref = mock(HostRef.class);
-        when(ref.getAgentId()).thenReturn("agentId");
-        when(vmRef.getAgent()).thenReturn(ref);
-        
-        when(view.getSelectedHostOrVm()).thenReturn(vmRef);
-
-        VmInformationController vmInformationController = mock(VmInformationController.class);
-        when(vmInformationController.getSelectedChildID()).thenReturn(3);
-        when(uiFacadeFactory.getVmController(any(VmRef.class))).thenReturn(vmInformationController);
-        when(vmInformationController.selectChildID(anyInt())).thenReturn(true);
-
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
-
-        ArgumentCaptor<Integer> arg = ArgumentCaptor.forClass(Integer.class);
-        verify(vmInformationController).selectChildID(arg.capture());
-        verify(vmInformationController, times(0)).getSelectedChildID();
-
-        int id = arg.getValue();
-
-        assertEquals(0, id);
-
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
-
-        arg = ArgumentCaptor.forClass(Integer.class);
-        verify(vmInformationController, times(1)).getSelectedChildID();
-        verify(vmInformationController, times(2)).selectChildID(arg.capture());
-        id = arg.getValue();
-
-        assertEquals(3, id);
-    }
-    
-    @Test
-    public void verifyOpenSameHostVMTab2() {
-        
-        VmRef vmRef1 = mock(VmRef.class);
-        VmRef vmRef2 = mock(VmRef.class);
-        when(view.getSelectedHostOrVm()).thenReturn(vmRef1).thenReturn(vmRef1).thenReturn(vmRef2).thenReturn(vmRef1);
-
-        when(vmRef1.getName()).thenReturn("testvm");
-        when(vmRef1.getIdString()).thenReturn("testvmid");
-        HostRef ref = mock(HostRef.class);
-        when(ref.getAgentId()).thenReturn("agentId");
-        when(vmRef1.getAgent()).thenReturn(ref);
-        
-        when(vmRef2.getName()).thenReturn("testvm");
-        when(vmRef2.getIdString()).thenReturn("testvmid");
-        when(vmRef2.getAgent()).thenReturn(ref);
-        
-        VmInformationController vmInformationController1 = mock(VmInformationController.class);
-        VmInformationController vmInformationController2 = mock(VmInformationController.class);
-        
-        when(vmInformationController1.getSelectedChildID()).thenReturn(2).thenReturn(2);
-        when(vmInformationController2.getSelectedChildID()).thenReturn(3);
-        
-        when(vmInformationController1.selectChildID(0)).thenReturn(true);
-        when(vmInformationController1.selectChildID(2)).thenReturn(true);
-        when(vmInformationController1.selectChildID(3)).thenReturn(false);
-        
-        when(vmInformationController2.selectChildID(0)).thenReturn(true);
-        when(vmInformationController2.selectChildID(2)).thenReturn(true);
-        when(vmInformationController2.selectChildID(3)).thenReturn(true);
-        
-        when(uiFacadeFactory.getVmController(any(VmRef.class))).
-                             thenReturn(vmInformationController1).
-                             thenReturn(vmInformationController2).
-                             thenReturn(vmInformationController2).
-                             thenReturn(vmInformationController1);
-
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
-
-        ArgumentCaptor<Integer> arg = ArgumentCaptor.forClass(Integer.class);
-        verify(vmInformationController1).selectChildID(arg.capture());
-        verify(vmInformationController1, times(0)).getSelectedChildID();
-
-        int id = arg.getValue();
-
-        assertEquals(0, id);
-
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
-
-        arg = ArgumentCaptor.forClass(Integer.class);
-        verify(vmInformationController1).getSelectedChildID();
-        verify(vmInformationController2, times(1)).selectChildID(arg.capture());
-        id = arg.getValue();
-
-        assertEquals(2, id);
-        
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
-
-        arg = ArgumentCaptor.forClass(Integer.class);
-        verify(vmInformationController2, times(1)).getSelectedChildID();
-        verify(vmInformationController2, times(2)).selectChildID(arg.capture());
-        id = arg.getValue();
-
-        assertEquals(3, id);
-        
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
-
-        arg = ArgumentCaptor.forClass(Integer.class);
-        verify(vmInformationController2, times(2)).getSelectedChildID();
-        verify(vmInformationController1, times(3)).selectChildID(arg.capture());
-        id = arg.getValue();
-
-        assertEquals(2, id);
-    }
-    
-    @Test
-    public void verityVMActionsAreShown() {
-        VmInfo vmInfo = new VmInfo(0, 1, 2, null, null, null, null, null, null, null, null, null, null, null);
-        when(mockVmsDAO.getVmInfo(isA(VmRef.class))).thenReturn(vmInfo);
-
-        VmRef ref = mock(VmRef.class);
-        when(view.getSelectedHostOrVm()).thenReturn(ref);
-
-        MouseEvent uiEvent = mock(MouseEvent.class);
-        ActionEvent<MainView.Action> viewEvent = new ActionEvent<>(view, MainView.Action.SHOW_VM_CONTEXT_MENU);
-        viewEvent.setPayload(uiEvent);
-
-        l.actionPerformed(viewEvent);
-
-        verify(view).showVMContextActions(Arrays.asList(action1), uiEvent);
-    }
-    
-    @Test
-    public void verityVMActionsAreExecuted() {
-
-        VmRef vmRef = mock(VmRef.class);
-        when(view.getSelectedHostOrVm()).thenReturn(vmRef);
-
-        ActionEvent<MainView.Action> event = new ActionEvent<>(view, MainView.Action.VM_CONTEXT_ACTION);
-        event.setPayload(action1);
-        l.actionPerformed(event);
-        
-        verify(action1, times(1)).execute(any(VmRef.class));
-        verify(action2, times(0)).execute(any(VmRef.class));
-    }
-
-    @Test
-    public void verifyMenuItems() {
-        
-        ActionListener<ThermostatExtensionRegistry.Action> menuListener = controller.getMenuListener();
-
-        MenuAction action = mock(MenuAction.class);
-        when(action.getName()).thenReturn("Test1");
-
-        ActionEvent<Action> addEvent = new ActionEvent<ThermostatExtensionRegistry.Action>(
-        		menus, ThermostatExtensionRegistry.Action.SERVICE_ADDED);
-        addEvent.setPayload(action);
-        menuListener.actionPerformed(addEvent);
-        verify(view).addMenu(action);
-
-        ActionEvent<Action> removeEvent = new ActionEvent<ThermostatExtensionRegistry.Action>(menus, ThermostatExtensionRegistry.Action.SERVICE_REMOVED);
-        removeEvent.setPayload(action);
-        menuListener.actionPerformed(removeEvent);
-        verify(view).removeMenu(action);
-    }
-
-   @Test
-   public void testOSGiFrameworkShutdown() throws BundleException {
-
-       l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.SHUTDOWN));
-
-       verify(uiFacadeFactory).shutdown();
-   }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/internal/MenuRegistryTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,97 +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.internal;
-
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-
-import com.redhat.thermostat.client.internal.MenuRegistry;
-import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.ThermostatExtensionRegistry;
-
-public class MenuRegistryTest {
-
-    @Test
-    public void verifyMenuRegistryReactsToMenuActions() throws InvalidSyntaxException {
-        ArgumentCaptor<ServiceListener> serviceListenerCaptor = ArgumentCaptor.forClass(ServiceListener.class);
-        ArgumentCaptor<String> filterCaptor = ArgumentCaptor.forClass(String.class);
-
-        ActionListener<ThermostatExtensionRegistry.Action> menuListener = mock(ActionListener.class);
-        MenuAction menuAction = mock(MenuAction.class);
-
-        BundleContext context = mock(BundleContext.class);
-        doNothing().when(context).addServiceListener(serviceListenerCaptor.capture(), filterCaptor.capture());
-
-        ServiceReference ref = mock(ServiceReference.class);
-        when(ref.getProperty("objectClass")).thenReturn(MenuAction.class.getName());
-
-        when(context.getService(ref)).thenReturn(menuAction);
-
-        MenuRegistry registry = new MenuRegistry(context);
-        registry.addActionListener(menuListener);
-        registry.start();
-
-        ServiceListener serviceListener = serviceListenerCaptor.getValue();
-        serviceListener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, ref));
-
-        ArgumentCaptor<ActionEvent> eventCaptor = ArgumentCaptor.forClass(ActionEvent.class);
-        serviceListener.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, ref));
-
-        verify(menuListener, times(2)).actionPerformed(eventCaptor.capture());
-
-        ActionEvent firstEvent = eventCaptor.getAllValues().get(0);
-        ActionEvent secondEvent = eventCaptor.getAllValues().get(1);
-
-        assertEquals(ThermostatExtensionRegistry.Action.SERVICE_ADDED, firstEvent.getActionId());
-        assertEquals(ThermostatExtensionRegistry.Action.SERVICE_REMOVED, secondEvent.getActionId());
-
-    }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/internal/SearchFieldSwingViewTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,198 +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.internal;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-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.ui.SearchFieldSwingView;
-import com.redhat.thermostat.client.ui.SearchFieldView;
-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/core/src/test/java/com/redhat/thermostat/client/internal/osgi/ApplicationServiceProviderTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +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.internal.osgi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertSame;
-
-import java.util.concurrent.Callable;
-import java.util.concurrent.Future;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-public class ApplicationServiceProviderTest {
-
-    private ApplicationServiceProvider provider;
-
-    @Before
-    public void setUp() {
-        provider = new ApplicationServiceProvider();
-    }
-
-    @After
-    public void tearDown() {
-        provider = null;
-    }
-
-    @Test
-    public void testCache() {
-        provider.getApplicationCache().addAttribute("test", "fluff");
-        assertEquals("fluff", provider.getApplicationCache().getAttribute("test"));
-    }
-
-    @Test
-    public void testApplicationExecutor() throws Exception {
-        assertNotNull(provider.getApplicationExecutor());
-        final String obj = "test";
-        Future<String> future = provider.getApplicationExecutor().submit(new Callable<String>() {
-
-            @Override
-            public String call() throws Exception {
-                return obj;
-            }
-        });
-        String result = future.get();
-        assertSame(result, obj);
-    }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/internal/osgi/ThermostatActivatorTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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.internal.osgi;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.client.core.views.AgentInformationViewProvider;
-import com.redhat.thermostat.client.core.views.ClientConfigViewProvider;
-import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
-import com.redhat.thermostat.client.core.views.HostInformationViewProvider;
-import com.redhat.thermostat.client.core.views.HostMemoryViewProvider;
-import com.redhat.thermostat.client.core.views.HostOverviewViewProvider;
-import com.redhat.thermostat.client.core.views.SummaryViewProvider;
-import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
-import com.redhat.thermostat.client.core.views.VmGcViewProvider;
-import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
-import com.redhat.thermostat.client.core.views.VmOverviewViewProvider;
-import com.redhat.thermostat.client.internal.HostIconDecorator;
-import com.redhat.thermostat.client.osgi.service.HostDecorator;
-import com.redhat.thermostat.client.swing.SwingAgentInformationViewProvider;
-import com.redhat.thermostat.client.swing.SwingClientConfigurationViewProvider;
-import com.redhat.thermostat.client.swing.SwingHostCpuViewProvider;
-import com.redhat.thermostat.client.swing.SwingHostInformationViewProvider;
-import com.redhat.thermostat.client.swing.SwingHostMemoryViewProvider;
-import com.redhat.thermostat.client.swing.SwingHostOverviewViewProvider;
-import com.redhat.thermostat.client.swing.SwingSummaryViewProvider;
-import com.redhat.thermostat.client.swing.SwingVmCpuViewProvider;
-import com.redhat.thermostat.client.swing.SwingVmGcViewProvider;
-import com.redhat.thermostat.client.swing.SwingVmInformationViewProvider;
-import com.redhat.thermostat.client.swing.SwingVmOverviewViewProvider;
-import com.redhat.thermostat.test.StubBundleContext;
-
-public class ThermostatActivatorTest {
-
-    @Test
-    public void verifyAllExpectedServicesAreRegistered() throws Exception {
-        StubBundleContext ctx = new StubBundleContext();
-
-        ThermostatActivator activator = new ThermostatActivator();
-
-        activator.start(ctx);
-
-        assertTrue(ctx.isServiceRegistered(HostDecorator.class.getName(), HostIconDecorator.class));
-        assertTrue(ctx.isServiceRegistered(SummaryViewProvider.class.getName(), SwingSummaryViewProvider.class));
-        assertTrue(ctx.isServiceRegistered(HostInformationViewProvider.class.getName(), SwingHostInformationViewProvider.class));
-        assertTrue(ctx.isServiceRegistered(HostMemoryViewProvider.class.getName(), SwingHostMemoryViewProvider.class));
-        assertTrue(ctx.isServiceRegistered(HostCpuViewProvider.class.getName(), SwingHostCpuViewProvider.class));
-        assertTrue(ctx.isServiceRegistered(HostOverviewViewProvider.class.getName(), SwingHostOverviewViewProvider.class));
-        assertTrue(ctx.isServiceRegistered(VmInformationViewProvider.class.getName(), SwingVmInformationViewProvider.class));
-        assertTrue(ctx.isServiceRegistered(VmCpuViewProvider.class.getName(), SwingVmCpuViewProvider.class));
-        assertTrue(ctx.isServiceRegistered(VmGcViewProvider.class.getName(), SwingVmGcViewProvider.class));
-        assertTrue(ctx.isServiceRegistered(VmOverviewViewProvider.class.getName(), SwingVmOverviewViewProvider.class));
-        assertTrue(ctx.isServiceRegistered(AgentInformationViewProvider.class.getName(), SwingAgentInformationViewProvider.class));
-        assertTrue(ctx.isServiceRegistered(ClientConfigViewProvider.class.getName(), SwingClientConfigurationViewProvider.class));
-        
-        assertEquals(12, ctx.getAllServices().size());
-    }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/AgentInformationDisplayFrameTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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.ui;
-
-import static org.junit.Assert.assertArrayEquals;
-import static org.junit.Assert.assertEquals;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.eq;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import java.util.HashMap;
-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 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 String BACKEND_NAME = "foo";
-        final String BACKEND_STATUS = "bar";
-        final String BACKEND_DESCRIPTION = "baz";
-
-        Map<String, String> statusMap = new HashMap<>();
-        statusMap.put(BACKEND_NAME, BACKEND_STATUS);
-
-        fixture.show();
-
-        agentConfigFrame.setSelectedAgentBackendStatus(statusMap);
-
-        assertEquals(1, fixture.table("backends").rowCount());
-
-        String[] rowContents = fixture.table("backends").contents()[0];
-        assertArrayEquals(new String[] { BACKEND_NAME, BACKEND_STATUS }, rowContents);
-
-        fixture.table("backends").selectRows(0);
-
-        verify(l).actionPerformed(new ActionEvent<ConfigurationAction>(agentConfigFrame, ConfigurationAction.SHOW_BACKEND_DESCRIPTION));
-
-        agentConfigFrame.setSelectedAgentBackendDescription(BACKEND_DESCRIPTION);
-
-        assertEquals(BACKEND_DESCRIPTION, fixture.textBox("backendDescription").text());
-    }
-
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/ClientConfigurationSwingTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +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.ui;
-
-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.JCheckBox;
-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/core/src/test/java/com/redhat/thermostat/client/ui/HostInformationPanelTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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.ui;
-
-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;
-
-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 {
-        BasicView 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");
-
-        BasicView mock2 = createHostInfoPanel();
-        panel.addChildView("foo2", mock2);
-
-        window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("foo1", "foo2");
-    }
-
-    @Test
-    public void testAddRemove() throws InvocationTargetException, InterruptedException {
-        BasicView test1 = createHostInfoPanel();
-        BasicView 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/core/src/test/java/com/redhat/thermostat/client/ui/IconDescriptorTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,96 +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.ui;
-
-import static org.junit.Assert.*;
-
-import java.io.IOException;
-import java.nio.ByteBuffer;
-
-import org.junit.Test;
-
-public class IconDescriptorTest {
-
-    @Test
-    public void test() throws IOException {
-        ClassLoader classLoader = getClass().getClassLoader();
-        String resource = IconResource.JAVA_APPLICATION.getPath();
-        IconDescriptor descriptor = IconDescriptor.createFromClassloader(classLoader, resource);
-        ByteBuffer buffer = descriptor.getData();
-        
-        assertEquals(3512, buffer.capacity());
-        
-        byte[] data = buffer.array();
-        
-        // the first four bytes should be .PNG
-        int current = ((int) data[0]) & 0xFF;
-        assertEquals(0x89, current);
-        
-        current = ((int) data[1]) & 0xFF;
-        assertEquals(0x50, current);
-        
-        current = ((int) data[2]) & 0xFF;
-        assertEquals(0x4E, current);
-        
-        current = ((int) data[3]) & 0xFF;
-        assertEquals(0x47, current);
-        
-        // check IHDR chunk
-        current = ((int) data[12]) & 0xFF;
-        assertEquals(0x49, current);
-        
-        current = ((int) data[12]) & 0xFF;
-        assertEquals(0x49, current);
-        
-        current = ((int) data[13]) & 0xFF;
-        assertEquals(0x48, current);
-        
-        current = ((int) data[14]) & 0xFF;
-        assertEquals(0x44, current);
-        
-        current = ((int) data[15]) & 0xFF;
-        assertEquals(0x52, current);
-        
-        // get width and height, 4 bytes each, the icon is 16x16
-        current = ((int) data[16]) << 24 | ((int) data[17]) << 16 | ((int) data[18]) << 8 | (((int) data[19]) & 0xFF);
-        assertEquals(16, current);
-        
-        current = ((int) data[20]) << 24 | ((int) data[21]) << 16 | ((int) data[22]) << 8 | (((int) data[23]) & 0xFF);
-        assertEquals(16, current);
-    }
-    
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/MainWindowTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,356 +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.ui;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.any;
-import static org.mockito.Mockito.anyString;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.isA;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JRadioButtonMenuItem;
-
-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.exception.ComponentLookupException;
-import org.fest.swing.fixture.FrameFixture;
-import org.fest.swing.fixture.JMenuItemFixture;
-import org.fest.swing.fixture.JTextComponentFixture;
-import org.fest.swing.fixture.JTreeFixture;
-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.HostFilter;
-import com.redhat.thermostat.client.core.VmFilter;
-import com.redhat.thermostat.client.internal.MainView;
-import com.redhat.thermostat.client.osgi.service.HostDecorator;
-import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.client.osgi.service.VmDecorator;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.HostsVMsLoader;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.Ref;
-
-@RunWith(CacioFESTRunner.class)
-public class MainWindowTest {
-
-    private FrameFixture frameFixture;
-    private MainWindow window;
-    private ActionListener<MainView.Action> l;
-
-    @BeforeClass
-    public static void setUpOnce() {
-        FailOnThreadViolationRepaintManager.install();
-    }
-
-    @SuppressWarnings("unchecked") // mock(ActionListener.class)
-    @Before
-    public void setUp() {
-
-        GuiActionRunner.execute(new GuiTask() {
-            
-            @Override
-            protected void executeInEDT() throws Throwable {
-                window = new MainWindow();
-                l = mock(ActionListener.class);
-                window.addActionListener(l);
-            }
-        });
-
-        frameFixture = new FrameFixture(window);
-    }
-
-    @After
-    public void tearDown() {
-        frameFixture.cleanUp();
-        frameFixture = null;
-        window = null;
-        l = null;
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void testHostVmSelectionChangedSupport() {
-        frameFixture.show();
-        JTreeFixture hostVMTree = frameFixture.tree("agentVmTree");
-        hostVMTree.selectRows(0);
-
-        verify(l).actionPerformed(new ActionEvent<MainView.Action>(window, MainView.Action.HOST_VM_SELECTION_CHANGED));
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void testHostVmDecoratorsAdded() throws InterruptedException {
-        
-        List<HostDecorator> decorators = new ArrayList<>();
-        HostDecorator refDecorator = mock(HostDecorator.class);
-        final Decorator decorator = mock(Decorator.class);
-        when(decorator.getLabel(anyString())).thenReturn("fluff");
-        
-        when(refDecorator.getDecorator()).thenReturn(decorator);
-        
-        HostFilter filter = mock(HostFilter.class);
-        when(filter.matches(isA(HostRef.class))).thenReturn(false).thenReturn(true);
-
-        when(refDecorator.getFilter()).thenReturn(filter);
-        
-        decorators.add(refDecorator);
-        
-        HostsVMsLoader hostsVMsLoader = mock(HostsVMsLoader.class);
-        Collection<HostRef> expectedHosts = new ArrayList<>();
-        expectedHosts.add(new HostRef("123", "fluffhost1"));
-        expectedHosts.add(new HostRef("456", "fluffhost2"));
-        
-        when(hostsVMsLoader.getHosts()).thenReturn(expectedHosts);
-        
-        window.updateTree(null, null, decorators, null, hostsVMsLoader);
-
-        Thread.sleep(50);
-        
-        frameFixture.show();
-        frameFixture.requireVisible();
-        
-        verify(decorator, times(0)).getLabel("fluffhost1");
-        verify(decorator, atLeastOnce()).getLabel("fluffhost2");
-    }
-    
-    @Category(GUITest.class)
-    @Test
-    public void testHostVMTreeFilterPropertySupport() {
-        String SEARCH_TEXT = "test";
-        frameFixture.show();
-        JTextComponentFixture hostVMTreeFilterField = frameFixture.textBox(SearchFieldView.VIEW_NAME);
-        hostVMTreeFilterField.enterText(SEARCH_TEXT);
-
-        verify(l, times(SEARCH_TEXT.length())).actionPerformed(new ActionEvent<MainView.Action>(window, MainView.Action.HOST_VM_TREE_FILTER));
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void verifyThatCloseFiresShutdownEvent() {
-
-        frameFixture.show();
-
-        frameFixture.close();
-        frameFixture.requireNotVisible();
-        verify(l).actionPerformed(new ActionEvent<MainView.Action>(window, MainView.Action.SHUTDOWN));
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void verifyShowMainWindowShowsWindow() {
-        window.showMainWindow();
-        frameFixture.requireVisible();
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void verifyHideMainWindowHidesWindow() {
-        GuiActionRunner.execute(new GuiTask() {
-            @Override
-            protected void executeInEDT() throws Throwable {
-                window.showMainWindow();
-            }
-        });
-        frameFixture.requireVisible();
-        GuiActionRunner.execute(new GuiTask() {
-            @Override
-            protected void executeInEDT() throws Throwable {
-                window.hideMainWindow();
-            }
-        });
-        frameFixture.requireNotVisible();
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void verifyThatClientPreferencesMenuItemTriggersEvent() {
-        frameFixture.show();
-        JMenuItemFixture menuItem = frameFixture.menuItem("showClientConfig");
-        menuItem.click();
-        frameFixture.close();
-        frameFixture.requireNotVisible();
-
-        verify(l).actionPerformed(new ActionEvent<MainView.Action>(window, MainView.Action.SHOW_CLIENT_CONFIG));
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void verifyThatAgentPreferencesMenuItemTriggersEvent() {
-        frameFixture.show();
-        JMenuItemFixture menuItem = frameFixture.menuItem("showAgentConfig");
-        menuItem.click();
-        frameFixture.close();
-        frameFixture.requireNotVisible();
-
-        verify(l).actionPerformed(new ActionEvent<MainView.Action>(window, MainView.Action.SHOW_AGENT_CONFIG));
-    }
-
-
-    @Category(GUITest.class)
-    @Test
-    public void verifyThatHistorySwitchTriggersEvent() {
-        frameFixture.show();
-        JMenuItemFixture menuItem = frameFixture.menuItem("historyModeSwitch");
-        menuItem.click();
-        frameFixture.close();
-        frameFixture.requireNotVisible();
-
-        verify(l).actionPerformed(new ActionEvent<MainView.Action>(window, MainView.Action.SWITCH_HISTORY_MODE));
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void addRemoveMenu() {
-    	final String PARENT_NAME = "File";
-        final String MENU_NAME = "Test2";
-        MenuAction action = mock(MenuAction.class);
-        when(action.getName()).thenReturn(MENU_NAME);
-        when(action.getPath()).thenReturn(new String[] {PARENT_NAME, MENU_NAME});
-        when(action.getType()).thenReturn(MenuAction.Type.STANDARD);
-
-        JMenuItemFixture menuItem;
-
-        frameFixture.show();
-
-        window.addMenu(action);
-
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
-        assertNotNull(menuItem);
-        menuItem.click();
-
-        verify(action).execute();
-
-        window.removeMenu(action);
-
-        try {
-            menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
-            // should not reach here
-            assertTrue(false);
-        } catch (ComponentLookupException cle) {
-            // expected
-        }
-    }
-    
-    @Category(GUITest.class)
-    @Test
-    public void addRadioMenu() {
-    	final String PARENT_NAME = "File";
-        final String MENU_NAME = "Test";
-        MenuAction action = mock(MenuAction.class);
-        when(action.getName()).thenReturn(MENU_NAME);
-        when(action.getPath()).thenReturn(new String[] {PARENT_NAME, MENU_NAME});
-
-
-        when(action.getType()).thenReturn(MenuAction.Type.RADIO);
-
-        JMenuItemFixture menuItem;
-
-        frameFixture.show();
-
-        window.addMenu(action);
-
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
-        assertNotNull(menuItem);
-
-        assertTrue(menuItem.target instanceof JRadioButtonMenuItem);
-    }
-    
-    @Category(GUITest.class)
-    @Test
-    public void addCheckBoxMenu() {
-    	final String PARENT_NAME = "File";
-        final String MENU_NAME = "Test";
-        MenuAction action = mock(MenuAction.class);
-        when(action.getName()).thenReturn(MENU_NAME);
-        when(action.getType()).thenReturn(MenuAction.Type.CHECK);
-        when(action.getPath()).thenReturn(new String[] {PARENT_NAME, MENU_NAME});
-
-
-        JMenuItemFixture menuItem;
-
-        frameFixture.show();
-
-        window.addMenu(action);
-
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
-        assertNotNull(menuItem);
-
-        assertTrue(menuItem.target instanceof JCheckBoxMenuItem);
-    }
-    
-    @Category(GUITest.class)
-    @Test
-    public void testGetHostVMTreeFilter() {
-        frameFixture.show();
-        JTextComponentFixture hostVMTreeFilterField = frameFixture.textBox(SearchFieldView.VIEW_NAME);
-        hostVMTreeFilterField.enterText("test");
-        String actual = window.getHostVmTreeFilterText();
-        assertEquals("test", actual);
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void testGetSelectedHostOrVm() {
-        frameFixture.show();
-        JTreeFixture hostVMTree = frameFixture.tree("agentVmTree");
-        hostVMTree.selectRow(0);
-
-        assertEquals(null, window.getSelectedHostOrVm());
-    }
-
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/MenuHelperTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,241 +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.ui;
-
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JFrame;
-import javax.swing.JMenu;
-import javax.swing.JMenuBar;
-import javax.swing.JRadioButtonMenuItem;
-
-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.exception.ComponentLookupException;
-import org.fest.swing.fixture.FrameFixture;
-import org.fest.swing.fixture.JMenuItemFixture;
-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.osgi.service.MenuAction;
-
-@RunWith(CacioFESTRunner.class)
-public class MenuHelperTest {
-
-    private FrameFixture frameFixture;
-    private JFrame window;
-    private MenuHelper menu;
-
-    @BeforeClass
-    public static void setUpOnce() {
-        FailOnThreadViolationRepaintManager.install();
-    }
-
-    @Before
-    public void setUp() {
-        GuiActionRunner.execute(new GuiTask() {
-            @Override
-            protected void executeInEDT() throws Throwable {
-                window = new JFrame();
-                JMenuBar menuBar = new JMenuBar();
-                window.setJMenuBar(menuBar);
-                JMenu fileMenu = new JMenu("File");
-                fileMenu.setName("File");
-                menuBar.add(fileMenu);
-                menu = new MenuHelper(menuBar);
-                window.pack();
-            }
-        });
-
-        frameFixture = new FrameFixture(window);
-    }
-
-    @After
-    public void tearDown() {
-        frameFixture.cleanUp();
-        frameFixture = null;
-        window = null;
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void addRemoveWithNewTopLevelMenu() {
-        final String PARENT_NAME = "Test1";
-        final String MENU_NAME = "Test2";
-        MenuAction action = mock(MenuAction.class);
-        when(action.getName()).thenReturn(MENU_NAME);
-        when(action.getPath()).thenReturn(new String[] { PARENT_NAME, MENU_NAME });
-        when(action.getType()).thenReturn(MenuAction.Type.STANDARD);
-
-        JMenuItemFixture menuItem;
-
-        frameFixture.show();
-
-        menu.addMenuAction(action);
-
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
-        assertNotNull(menuItem);
-
-        menu.removeMenuAction(action);
-
-        try {
-            menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
-            // should not reach here
-            assertTrue(false);
-        } catch (ComponentLookupException cle) {
-            // expected
-        }
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void addRemoveToExistingMenu() {
-        final String PARENT_NAME = "File";
-        final String MENU_NAME = "Test2";
-        MenuAction action = mock(MenuAction.class);
-        when(action.getName()).thenReturn(MENU_NAME);
-        when(action.getPath()).thenReturn(new String[] { PARENT_NAME, MENU_NAME });
-        when(action.getType()).thenReturn(MenuAction.Type.STANDARD);
-
-        JMenuItemFixture menuItem;
-
-        frameFixture.show();
-
-        assertNotNull(frameFixture.menuItem("File"));
-
-        menu.addMenuAction(action);
-
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
-        assertNotNull(menuItem);
-
-        menu.removeMenuAction(action);
-
-        try {
-            menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
-            // should not reach here
-            assertTrue(false);
-        } catch (ComponentLookupException cle) {
-            // expected
-        }
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void addRemoveHighlyNextedMenu() {
-        final String[] path = new String[] { "View", "Filter", "Virtual Machine", "Show Only Running" };
-        MenuAction action = mock(MenuAction.class);
-        when(action.getName()).thenReturn(path[path.length - 1]);
-        when(action.getPath()).thenReturn(path);
-        when(action.getType()).thenReturn(MenuAction.Type.STANDARD);
-
-        JMenuItemFixture menuItem;
-
-        frameFixture.show();
-
-        menu.addMenuAction(action);
-
-        menuItem = frameFixture.menuItemWithPath(path);
-        assertNotNull(menuItem);
-
-        menu.removeMenuAction(action);
-
-        try {
-            menuItem = frameFixture.menuItemWithPath(path);
-            // should not reach here
-            assertTrue(false);
-        } catch (ComponentLookupException cle) {
-            // expected
-        }
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void addRadioMenu() {
-        final String PARENT_NAME = "File";
-        final String MENU_NAME = "Test";
-        MenuAction action = mock(MenuAction.class);
-        when(action.getName()).thenReturn(MENU_NAME);
-        when(action.getPath()).thenReturn(new String[] { PARENT_NAME, MENU_NAME });
-        when(action.getType()).thenReturn(MenuAction.Type.RADIO);
-
-        JMenuItemFixture menuItem;
-
-        frameFixture.show();
-
-        menu.addMenuAction(action);
-
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
-        assertNotNull(menuItem);
-
-        assertTrue(menuItem.target instanceof JRadioButtonMenuItem);
-    }
-
-    @Category(GUITest.class)
-    @Test
-    public void addCheckBoxMenu() {
-        final String PARENT_NAME = "File";
-        final String MENU_NAME = "Test";
-        MenuAction action = mock(MenuAction.class);
-        when(action.getName()).thenReturn(MENU_NAME);
-        when(action.getType()).thenReturn(MenuAction.Type.CHECK);
-        when(action.getPath()).thenReturn(new String[] { PARENT_NAME, MENU_NAME });
-
-        JMenuItemFixture menuItem;
-
-        frameFixture.show();
-
-        menu.addMenuAction(action);
-
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
-        assertNotNull(menuItem);
-
-        assertTrue(menuItem.target instanceof JCheckBoxMenuItem);
-    }
-
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/TabbedPaneMatcher.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-package com.redhat.thermostat.client.ui;
-
-import javax.swing.JTabbedPane;
-
-import org.fest.swing.core.GenericTypeMatcher;
-
-public class TabbedPaneMatcher extends GenericTypeMatcher<JTabbedPane> {
-
-    public TabbedPaneMatcher(Class<JTabbedPane> supportedType) {
-        super(supportedType);
-    }
-
-    @Override
-    protected boolean isMatching(JTabbedPane tab) {
-        return tab.getTabCount() > 0;
-    }
-
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/UIResourcesTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,141 +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.ui;
-
-import java.awt.Color;
-import java.awt.Font;
-
-import javax.swing.LookAndFeel;
-import javax.swing.UIDefaults;
-import javax.swing.UIManager;
-import javax.swing.plaf.basic.BasicLookAndFeel;
-
-import junit.framework.Assert;
-
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.redhat.thermostat.test.Bug;
-
-@Bug(id="976",
-     summary="About dialog creashes with GTK look and feel",
-     url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=976")
-public class UIResourcesTest {
-   
-    private static LookAndFeel originalLaf;
-    
-    @BeforeClass
-    public static void setUp() throws Exception {
-        final Object [] uiDefaults = new Object[] {
-            "Button.darkShadow", null,
-            "Button.focus", null,
-            "Label.font", null
-        };
-        
-        originalLaf = UIManager.getLookAndFeel();
-        UIManager.setLookAndFeel(new BasicLookAndFeel() {
-            
-            @Override
-            protected void initClassDefaults(UIDefaults table) {
-                super.initClassDefaults(table);
-                table.putDefaults(uiDefaults);
-            }
-            
-            @Override
-            protected void initSystemColorDefaults(UIDefaults table) {
-                super.initSystemColorDefaults(table);
-                table.putDefaults(uiDefaults);
-            }
-            
-            @Override
-            protected void initComponentDefaults(UIDefaults table) {
-                super.initComponentDefaults(table);
-                table.putDefaults(uiDefaults);
-            }
-            
-            @Override
-            public boolean isSupportedLookAndFeel() {
-                return true;
-            }
-            
-            @Override
-            public boolean isNativeLookAndFeel() {
-                return false;
-            }
-            
-            @Override
-            public String getName() {
-                return "fluff";
-            }
-            
-            @Override
-            public String getID() {
-                return "fluff";
-            }
-            
-            @Override
-            public String getDescription() {
-                return "fluff";
-            }
-        });
-    }
-    
-    @Test
-    public void testHyperlinkColor() {
-        Assert.assertEquals(Color.BLUE, UIResources.getInstance().hyperlinkColor());
-    }
-
-    @Test
-    public void testHyperlinkActiveColor() {
-        Assert.assertEquals(Color.BLUE, UIResources.getInstance().hyperlinkActiveColor());
-    }
-
-    @Test
-    public void testStandardFont() {
-        Assert.assertEquals(Font.DIALOG, UIResources.getInstance().standardFont().getName());
-    }
-    
-    @AfterClass
-    public static void tearDown() throws Exception {
-        if (originalLaf != null) {
-            UIManager.setLookAndFeel(originalLaf);
-        } else {
-            UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
-        }
-    }
-}
--- a/client/pom.xml	Tue Oct 23 11:17:50 2012 -0400
+++ b/client/pom.xml	Tue Oct 23 11:19:24 2012 -0400
@@ -65,7 +65,7 @@
     <module>memory-stats-panel</module>
     <module>living-vm-filter</module>
     <module>command</module>
-    <module>swing-components</module>
+    <module>swing</module>
   </modules>
 
 </project>
--- a/client/swing-components/pom.xml	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
-  <modelVersion>4.0.0</modelVersion>
-  
-  <parent>
-    <artifactId>thermostat-client</artifactId>
-    <groupId>com.redhat.thermostat</groupId>
-    <version>0.5.0-SNAPSHOT</version>
-  </parent>
-  
-  <artifactId>thermostat-swing-components</artifactId>
-  <packaging>bundle</packaging>
-  <name>Swing Components and Utilities</name>
-  
-  <properties>
-    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-  </properties>
-  
-  <dependencies>
-
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-common-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    
-    <dependency>
-      <groupId>org.jfree</groupId>
-      <artifactId>jfreechart</artifactId>
-    </dependency>
-    
-    <dependency>
-      <groupId>net.java.openjdk.cacio</groupId>
-      <artifactId>cacio-tta</artifactId>
-      <scope>test</scope>
-    </dependency>
-    
-  </dependencies>
-      
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.felix</groupId>
-        <artifactId>maven-bundle-plugin</artifactId>
-        <extensions>true</extensions>
-        <configuration>
-          <instructions>
-            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
-            <Bundle-SymbolicName>com.redhat.thermostat.client.swing.components</Bundle-SymbolicName>
-            <Export-Package>
-              com.redhat.thermostat.swing,
-              com.redhat.thermostat.models,
-              com.redhat.thermostat.swing.models,
-              com.redhat.thermostat.charts
-            </Export-Package>
-            <!-- Do not autogenerate uses clauses in Manifests -->
-            <_nouses>true</_nouses>
-          </instructions>
-        </configuration>
-      </plugin>
-    </plugins>
-
-  </build>
-  
-</project>
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/ActionButton.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +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.swing;
-
-import javax.swing.AbstractButton;
-import javax.swing.Icon;
-import javax.swing.JButton;
-
-@SuppressWarnings("serial")
-public class ActionButton extends JButton implements ToolbarButton {
-
-    private AbstractButton realButton;
-    
-    public ActionButton(final Icon icon) {
-        super(icon);
-        
-        realButton = new JButton() {
-            @Override
-            public int getWidth() {
-                return icon.getIconWidth() + 5;
-            }
-            
-            @Override
-            public int getHeight() {
-                return icon.getIconHeight() + 4;
-            }
-        };
-        setUI(new ActionButtonUI(realButton));
-        
-        setSize(realButton.getWidth(), realButton.getHeight());
-        setContentAreaFilled(false);
-        
-        setPreferredSize(getSize());
-        setMinimumSize(getSize());
-        setMaximumSize(getSize());
-        
-        realButton.setModel(getModel());
-
-        setBorderPainted(false);
-    }
-    
-    @Override
-    public AbstractButton getToolbarButton() {
-        return this;
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/ActionButtonUI.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +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.swing;
-
-import java.awt.Graphics;
-import java.awt.image.BufferedImage;
-import java.awt.image.BufferedImageOp;
-import java.awt.image.ConvolveOp;
-import java.awt.image.Kernel;
-
-import javax.swing.AbstractButton;
-import javax.swing.ButtonModel;
-import javax.swing.Icon;
-import javax.swing.JComponent;
-import javax.swing.border.Border;
-import javax.swing.plaf.metal.MetalButtonUI;
-
-class ActionButtonUI extends MetalButtonUI {
-
-    private BufferedImage sourceIcon;
-    private BufferedImage rollOverIcon;
-    private AbstractButton realButton;
-    
-    ActionButtonUI(AbstractButton button) {
-        this.realButton = button;
-    }
-    
-    private BufferedImage getBrighterImage(BufferedImage source) {
-        float[] kernel = new float[] { 0, 0, 0, 0, 1.2f, 0, 0, 0, 0 };
-
-        BufferedImageOp brighterOp = new ConvolveOp(new Kernel(3, 3, kernel),
-                ConvolveOp.EDGE_NO_OP, null);
-        return brighterOp.filter(source, new BufferedImage(source.getWidth(),
-                source.getHeight(), source.getType()));
-    }
-
-    @Override
-    public void paint(Graphics g, JComponent c) {
-
-        AbstractButton button = (AbstractButton) c;
-        ButtonModel model = button.getModel();
-        if (model.isPressed() || model.isArmed() || model.isSelected()) {
-            realButton.paint(g);
-        } else if (model.isRollover()) {
-            Border border = realButton.getBorder();
-            border.paintBorder(realButton, g, 0, 0, realButton.getWidth(),
-                    realButton.getHeight());
-        }
-        // paint the icon, always to the center
-        Icon icon = button.getIcon();
-        int w = icon.getIconWidth();
-        int h = icon.getIconHeight();
-
-        if (sourceIcon == null) {
-            sourceIcon = new BufferedImage(w + 1, h + 1,
-                    BufferedImage.TYPE_INT_ARGB);
-            Graphics imageGraphics = sourceIcon.getGraphics();
-            icon.paintIcon(null, imageGraphics, 0, 0);
-        }
-
-        if (rollOverIcon == null) {
-            rollOverIcon = getBrighterImage(sourceIcon);
-        }
-
-        int x = realButton.getWidth() / 2 - w / 2;
-        int y = realButton.getHeight() / 2 - h / 2;
-
-        if (model.isRollover()) {
-            g.drawImage(rollOverIcon, x, y, null);
-        } else {
-            g.drawImage(sourceIcon, x, y, null);
-        }
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/ActionToggleButton.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +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.swing;
-
-import javax.swing.AbstractButton;
-import javax.swing.Icon;
-import javax.swing.JToggleButton;
-
-@SuppressWarnings("serial")
-public class ActionToggleButton extends JToggleButton implements ToolbarButton {
-    private AbstractButton realButton;
-    
-    public ActionToggleButton(final Icon icon) {
-        super(icon);
-        
-        realButton = new JToggleButton() {
-            @Override
-            public int getWidth() {
-                return icon.getIconWidth() + 4;
-            }
-            
-            @Override
-            public int getHeight() {
-                return icon.getIconHeight() + 4;
-            }
-        };
-        setUI(new ActionButtonUI(realButton));
-        
-        setSize(realButton.getWidth(), realButton.getHeight());
-        setContentAreaFilled(false);
-        
-        setPreferredSize(getSize());
-        setMinimumSize(getSize());
-        setMaximumSize(getSize());
-        
-        realButton.setModel(getModel());
-
-        setBorderPainted(false);
-    }
-    
-    @Override
-    public AbstractButton getToolbarButton() {
-        return this;
-    }    
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/ChartPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +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.swing;
-
-import java.awt.Graphics;
-import java.awt.image.BufferedImage;
-
-import javax.swing.JPanel;
-
-import org.jfree.chart.ChartRenderingInfo;
-import org.jfree.chart.JFreeChart;
-
-@SuppressWarnings("serial")
-public class ChartPanel extends JPanel {
-
-    private JFreeChart chart;
-    private ChartRenderingInfo info;
-    
-    public ChartPanel(JFreeChart chart) {
-        this(chart, new ChartRenderingInfo());
-    }
-    
-    public ChartPanel(JFreeChart chart, ChartRenderingInfo info) {
-        this.chart = chart;
-        this.info = info;
-    }
-    
-    @Override
-    protected void paintComponent(Graphics g) {
-        BufferedImage image = chart.createBufferedImage(getWidth(), getHeight(), info);
-        g.drawImage(image, 0, 0, null);
-    }
-    
-    public ChartRenderingInfo getChartRenderingInfo() {
-        return info;
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/DebugBorder.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,89 +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.swing;
-
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Insets;
-import java.awt.Shape;
-import java.awt.geom.RoundRectangle2D;
-import java.io.Serializable;
-
-import javax.swing.border.AbstractBorder;
-import javax.swing.plaf.UIResource;
-
-@SuppressWarnings("serial")
-public class DebugBorder extends AbstractBorder implements UIResource, Serializable {
-
-    @Override
-    public void paintBorder(Component c, Graphics g, int x, int y, int width,
-                            int height)
-    {
-        Graphics2D graphics = (Graphics2D) g.create();
-
-        graphics.translate(x, y);
-        
-        graphics.setPaint(Color.RED);
-        
-        float dash[] = { 10.0f };
-        graphics.setStroke(new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f));
-        
-        Shape shape = new RoundRectangle2D.Float(0, 0, width - 1,
-                                                 height - 1, 4, 4);
-        graphics.draw(shape);
-        graphics.dispose();
-    }
-    
-    @Override
-    public Insets getBorderInsets(Component c) {
-        return getBorderInsets(c, new Insets(0, 0, 0, 0));
-    }
-
-    @Override
-    public Insets getBorderInsets(Component c, Insets insets) {
-        
-        insets.top = 4;
-        insets.left = 4;
-        insets.right = 4;
-        insets.bottom = 4;
-        
-        return insets;
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/EdtHelper.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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.swing;
-
-import java.awt.EventQueue;
-import java.lang.reflect.InvocationTargetException;
-import java.util.concurrent.Callable;
-
-public class EdtHelper {
-
-    @SuppressWarnings("serial")
-    private static class CallableException extends RuntimeException {
-
-        private CallableException(Exception ex) {
-            super(ex);
-        }
-        
-    }
-
-    private static class CallableWrapper<T> implements Runnable {
-
-        private Callable<T> callable;
-        private T result;
-
-        private CallableWrapper(Callable<T> c) {
-            callable = c;
-        }
-
-        @Override
-        public void run() {
-            try {
-                result = callable.call();
-            } catch (Exception ex) {
-                throw new CallableException(ex);
-            }
-        }
-
-        private T getResult() {
-            return result;
-        }
-    }
-
-    public void callAndWait(Runnable r) throws InvocationTargetException, InterruptedException {
-        if (EventQueue.isDispatchThread()) {
-            try {
-                r.run();
-            } catch (Exception ex) {
-                throw new InvocationTargetException(ex);
-            }
-        } else {
-            EventQueue.invokeAndWait(r);
-        }
-    }
-
-    public <T> T callAndWait(Callable<T> c) throws InvocationTargetException, InterruptedException {
-        CallableWrapper<T> w = new CallableWrapper<>(c);
-        callAndWait(w);
-        return w.getResult();
-    }
-
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/EmptyIcon.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +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.swing;
-
-import java.awt.Component;
-import java.awt.Graphics;
-
-import javax.swing.ImageIcon;
-
-@SuppressWarnings("serial")
-public class EmptyIcon extends ImageIcon  {
-
-    private int width;
-    private int height;
-    
-    public EmptyIcon() {
-        this(16, 16);
-    }
-    
-    public EmptyIcon(int width, int height) {
-        this.width = width;
-        this.height = height;
-    }
-    
-    @Override
-    public int getIconHeight() {
-        return height;
-    }
-    
-    @Override
-    public int getIconWidth() {
-        return width;
-    }
-    
-    @Override
-    public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
-        // no-op
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/GradientPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +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.swing;
-
-import java.awt.Color;
-import java.awt.GradientPaint;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Paint;
-
-import javax.swing.JPanel;
-
-
-@SuppressWarnings("serial")
-public class GradientPanel extends JPanel {
-
-    private Color top;
-    private Color bottom;
-    
-    public GradientPanel(Color top, Color bottom) {
-        this.top = top;
-        this.bottom = bottom;
-    }
-    
-    @Override
-    protected void paintComponent(Graphics g) {
-        
-        Graphics2D graphics = GraphicsUtils.getInstance().createAAGraphics(g);
-        
-        Paint gradient = new GradientPaint(0, 0, top, 0, getHeight(), bottom);
-        graphics.setPaint(gradient);
-        graphics.fillRect(0, 0, getWidth(), getHeight());
-        graphics.dispose();
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/GradientRoundBorder.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,74 +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.swing;
-
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.GradientPaint;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Paint;
-import java.awt.Shape;
-import java.io.Serializable;
-
-import javax.swing.UIManager;
-import javax.swing.border.AbstractBorder;
-import javax.swing.plaf.UIResource;
-
-@SuppressWarnings("serial")
-public class GradientRoundBorder extends AbstractBorder implements UIResource, Serializable {
-
-    @Override
-    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
-        GraphicsUtils utils = GraphicsUtils.getInstance();
-        Graphics2D graphics = utils.createAAGraphics(g);
-        
-        Color highlight = UIManager.getColor("textHighlight");
-        if (highlight == null) {
-            highlight = Palette.EGYPTIAN_BLUE.getColor();
-        }
-        Paint paint = new GradientPaint(x, y, highlight, 0, height, c.getBackground());
-        graphics.setPaint(paint);
-        
-        graphics.translate(x, y);
-        
-        Shape shape = utils.getRoundShape(width, height);
-        graphics.draw(shape);
-        
-        graphics.dispose();
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/GraphicsUtils.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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.swing;
-
-import java.awt.Color;
-import java.awt.Font;
-import java.awt.FontMetrics;
-import java.awt.GradientPaint;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Paint;
-import java.awt.RenderingHints;
-import java.awt.Shape;
-import java.awt.geom.RoundRectangle2D;
-
-import javax.swing.JComponent;
-
-import sun.swing.SwingUtilities2;
-
-@SuppressWarnings("restriction")
-public class GraphicsUtils {
-
-    private static GraphicsUtils instance = new GraphicsUtils();
-    public static GraphicsUtils getInstance() {
-        return instance;
-    }
-    
-    public Graphics2D createAAGraphics(Graphics g) {
-        Graphics2D graphics = (Graphics2D) g.create();
-        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
-        return graphics;
-    }
-    
-    public void drawStringWithShadow(JComponent component, Graphics2D graphics, String string, Color foreground, int x, int y) {
-        // paint it twice to give a subtle drop shadow effect
-        
-        graphics.setColor(new Color(0f, 0f, 0f, 0.1f));
-        SwingUtilities2.drawString(component, graphics, string, x, y + 1);
-        
-        graphics.setColor(foreground);
-        SwingUtilities2.drawString(component, graphics, string, x, y);
-    }
-    
-    public void drawString(JComponent component, Graphics2D graphics, String string, Color foreground, int x, int y) {
-        graphics.setColor(foreground);
-        SwingUtilities2.drawString(component, graphics, string, x, y);
-    }
-    
-    public FontMetrics getFontMetrics(JComponent component, Font font) {
-        return SwingUtilities2.getFontMetrics(component, font);
-    }
-    
-    public Shape getRoundShape(int width, int height) {
-        return new RoundRectangle2D.Double(0, 0, width, height, 4, 4);
-    }
-    
-    public void setGradientPaint(Graphics2D g, int x, int height, Color start, Color stop) {
-        Paint paint = new GradientPaint(x, 0, start, 0, height, stop);
-        g.setPaint(paint);
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/HeaderPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +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.swing;
-
-import java.awt.BorderLayout;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.FlowLayout;
-import java.lang.reflect.InvocationTargetException;
-
-import javax.swing.BoxLayout;
-import javax.swing.JComponent;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.SwingUtilities;
-
-/**
- * A component that host a panel with a nicely rendered header.
- */
-@SuppressWarnings("serial")
-public class HeaderPanel extends JPanel {
-    
-    private String header;
-    
-    private JPanel contentPanel;
-    private JLabel headerLabel;
-    private JPanel headerPanel;
-    private JPanel controlPanel;
-    
-    public HeaderPanel() {
-        this("");
-    }
-    
-    public HeaderPanel(String header) {
-        
-        this.header = header;
-        
-        setLayout(new BorderLayout(0, 0));
-
-        headerLabel = new ShadowLabel(header, new EmptyIcon(5, 5));
-        headerPanel = new GradientPanel(Color.WHITE, getBackground());
-        headerPanel.setPreferredSize(new Dimension(HeaderPanel.this.getWidth(), 40));
-        
-        headerPanel.setLayout(new BorderLayout(0, 0));
-        headerPanel.add(headerLabel, BorderLayout.WEST);
-        add(headerPanel, BorderLayout.NORTH);
-        
-        controlPanel = new JPanel();
-        controlPanel.setOpaque(false);
-        controlPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 2, 10));
-        
-        headerPanel.add(controlPanel, BorderLayout.EAST);
-        
-        contentPanel = new JPanel();
-        contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.X_AXIS));
-        
-        add(contentPanel, BorderLayout.CENTER);
-    }
-   
-    public String getHeader() {
-        return header;
-    }
-    
-    public void setHeader(String header) {
-        this.header = header;
-        headerLabel.setText(header);
-    }
-    
-    public void setContent(JComponent content) {
-        contentPanel.removeAll();
-        contentPanel.add(content);
-        contentPanel.revalidate();
-        repaint();
-    }
-
-    public void addToolBarButton(ToolbarButton button) {
-        controlPanel.add(button.getToolbarButton());
-    }
-    
-    public static void main(String[] args) throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-            
-            @Override
-            public void run() {
-               JFrame frame = new JFrame();
-               frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-               
-               HeaderPanel header = new HeaderPanel();
-               header.setHeader("Test");
-               frame.getContentPane().add(header);
-               frame.setSize(500, 500);
-               frame.setVisible(true);
-            }
-        });
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/ShadowLabel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +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.swing;
-
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-
-import javax.swing.Icon;
-import javax.swing.JLabel;
-import javax.swing.plaf.metal.MetalLabelUI;
-
-@SuppressWarnings("serial")
-public class ShadowLabel extends JLabel {
-
-    public ShadowLabel(String text, Icon icon) {
-        super(text);
-        this.setIcon(icon);
-        setUI(new ShadowLabelUI());
-    }
-    
-    public ShadowLabel(String text) {
-        this(text, null);
-    }
-
-    private class ShadowLabelUI extends MetalLabelUI {
-        
-        @Override
-        protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) {
-            GraphicsUtils graphicsUtils = GraphicsUtils.getInstance();
-            Graphics2D graphics = graphicsUtils.createAAGraphics(g);
-            graphicsUtils.drawStringWithShadow(l, graphics, s, getForeground(), textX, textY);
-        }
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/StatusBar.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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.swing;
-
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.beans.Transient;
-
-import javax.swing.ImageIcon;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.SwingUtilities;
-
-@SuppressWarnings("serial")
-public class StatusBar extends JPanel {
-
-    // some of this code is inspired by the book
-    // Swing Hacks: Tips & Tools for Building Killer GUIs
-    // By Joshua Marinacci, Chris Adamson
-    // ISBN: 0-596-00907-0
-    // website: http://www.oreilly.com/catalog/swinghks/
-
-    public static final String PRIMARY_STATUS_PROPERTY = "primaryStatus";
-    
-    private Dimension preferredSize;
-    
-    private String primaryStatus = "";
-    private JLabel primaryStatusLabel;
-    private JLabel iconLabel;
-    
-    public StatusBar() {
-        super();
-        setLayout(new BorderLayout(0, 0));
-        
-        primaryStatusLabel = new JLabel(primaryStatus);
-        primaryStatusLabel.setName("primaryStatusLabel");
-        primaryStatusLabel.setFont(getFont().deriveFont(10.0f));
-        primaryStatusLabel.setHorizontalAlignment(JLabel.LEADING);
-        primaryStatusLabel.setVerticalAlignment(JLabel.CENTER);
-
-        add(primaryStatusLabel, BorderLayout.WEST);
-        
-        iconLabel = new JLabel("");
-        ImageIcon grip = new ImageIcon(getClass().getResource("/icons/resize-grip.png"));
-        iconLabel.setIcon(grip);
-
-        iconLabel.setMinimumSize(new Dimension(grip.getIconWidth() + 1, grip.getIconHeight()));
-        iconLabel.setPreferredSize(new Dimension(grip.getIconWidth() + 1, grip.getIconHeight()));
-        iconLabel.setVerticalAlignment(JLabel.BOTTOM);
-
-        add(iconLabel, BorderLayout.EAST);
-        preferredSize = new Dimension(700, grip.getIconHeight() + 5);
-    }
-    
-    @Override
-    @Transient
-    public Dimension getMinimumSize() {
-        if (isMinimumSizeSet()) {
-            return super.getMinimumSize();
-        }
-        return preferredSize;
-    }
-    
-    @Override
-    @Transient
-    public Dimension getPreferredSize() {
-        if (isPreferredSizeSet()) {
-            return super.getPreferredSize();
-        }
-        return preferredSize;
-    }
-    
-    public void setPrimaryStatus(String primaryStatus) {
-        if (primaryStatus == null) throw new NullPointerException();
-        
-        String oldPrimaryStatus = this.primaryStatus;
-        this.primaryStatus = primaryStatus;
-        primaryStatusLabel.setText(" " + primaryStatus);
-        
-        firePropertyChange(PRIMARY_STATUS_PROPERTY, oldPrimaryStatus, this.primaryStatus);
-        repaint();
-    }
-
-    public String getPrimaryStatus() {
-        return primaryStatus;
-    }
-        
-    public static void main(String[] args) {
-        SwingUtilities.invokeLater(new Runnable() {
-            
-            @Override
-            public void run() {
-                JFrame frame = new JFrame();
-                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-                frame.getContentPane().setLayout(new BorderLayout());
-                
-                StatusBar statusBar = new StatusBar();
-                frame.getContentPane().add(statusBar, BorderLayout.SOUTH);
-                
-                frame.setSize(500, 500);
-                frame.setVisible(true);
-            }
-        });
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/ThermostatTable.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +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.swing;
-
-import java.awt.Dimension;
-
-import javax.swing.JScrollPane;
-import javax.swing.JTable;
-import javax.swing.table.DefaultTableModel;
-
-@SuppressWarnings("serial")
-public class ThermostatTable extends JTable {
-    
-    private ThermostatTableColumnResizer resizer;
-    
-    public ThermostatTable() {
-        this((DefaultTableModel) null);
-    }
-    
-    public ThermostatTable(int rowHeight) {
-        this((DefaultTableModel) null, rowHeight);
-    }
-    
-    public ThermostatTable(DefaultTableModel model) {
-        this((DefaultTableModel) model, 25);
-    }
-    
-    public ThermostatTable(DefaultTableModel model, int rowHeight) {
-        super(model);
-
-        setRowHeight(rowHeight);
-        
-        setIntercellSpacing(new Dimension(0, 0));
-        
-        setFillsViewportHeight(true);
-        setAutoCreateRowSorter(true);
-        
-        setDefaultRenderer(Object.class, new ThermostatTableRenderer());
-        setDefaultRenderer(Double.class, new ThermostatTableRenderer());
-        setDefaultRenderer(Long.class, new ThermostatTableRenderer());
-        setDefaultRenderer(String.class, new ThermostatTableRenderer());
-        setDefaultRenderer(Integer.class, new ThermostatTableRenderer());
-        
-        this.resizer = new ThermostatTableColumnResizer(this);
-    }
-    
-    public void repackCells() {
-        resizer.resize();
-        revalidate();
-    }
-    
-    public JScrollPane wrap() {        
-        JScrollPane scrollPane = new JScrollPane(this);
-        repackCells();
-        return scrollPane;
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/ThermostatTableColumnResizer.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +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.swing;
-
-import java.awt.Component;
-
-import javax.swing.table.TableCellRenderer;
-import javax.swing.table.TableColumn;
-import javax.swing.table.TableColumnModel;
-
-class ThermostatTableColumnResizer {
-    
-    // reference Swing Hacks book:
-    // http://shop.oreilly.com/product/9780596009076.do
-    
-    private ThermostatTable table;
-    
-    public ThermostatTableColumnResizer(ThermostatTable table) {
-        this.table = table;
-    }
-    
-    public void resize() {
-        TableColumnModel model = table.getColumnModel();
-        for (int column = 0; column < table.getColumnCount(); column++ ) {
-            int maxWidth = 0;
-            for (int row = 0; row < table.getRowCount(); row++ ) {
-                TableCellRenderer renderer = table.getCellRenderer(row, column);
-                Object value = table.getValueAt(row, column);
-                Component component = renderer.getTableCellRendererComponent(table, value, false, false, row, column);
-                maxWidth = Math.max(component.getPreferredSize().width, maxWidth);
-            }
-            
-            TableColumn tableColumn = model.getColumn(column);
-            TableCellRenderer headerRenderer = tableColumn.getHeaderRenderer();
-            if (headerRenderer == null) {
-                headerRenderer = table.getTableHeader().getDefaultRenderer(); 
-            }
-            
-            Object headerValue = tableColumn.getHeaderValue();
-            Component headerComponent = headerRenderer.getTableCellRendererComponent(table, headerValue, false, false, 0, column);
-            maxWidth = Math.max(maxWidth, headerComponent.getPreferredSize().width);
-            
-            tableColumn.setPreferredWidth(maxWidth);
-        }
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/ThermostatTableRenderer.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +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.swing;
-
-import java.awt.Component;
-
-import javax.swing.JTable;
-import javax.swing.table.DefaultTableCellRenderer;
-
-@SuppressWarnings("serial")
-public class ThermostatTableRenderer extends DefaultTableCellRenderer {
-
-    @Override
-    public Component getTableCellRendererComponent(JTable table, Object value,
-            boolean isSelected, boolean hasFocus, int row, int column) {
-
-        Component result = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
-        if (result == null || isSelected) {
-            // do nothing
-        } else if (!isEven(row)) {
-            result.setBackground(Palette.LIGHT_GRAY.getColor());
-        } else {
-            result.setBackground(Palette.WHITE.getColor());
-        }
-        
-        return result;
-    }
-
-    private boolean isEven(int row) {
-        return row % 2 == 0;
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/ToolbarButton.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,43 +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.swing;
-
-import javax.swing.AbstractButton;
-
-public interface ToolbarButton {
-    AbstractButton getToolbarButton();
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/models/LongRange.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +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.swing.models;
-
-public class LongRange {
-
-    long min;
-    long max;
-    
-    public void setMax(long max) {
-        this.max = max;
-    }
-    
-    public long getMax() {
-        return max;
-    }
-    
-    public void setMin(long min) {
-        this.min = min;
-    }
-    
-    
-    public long getMin() {
-        return min;
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/models/LongRangeNormalizer.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +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.swing.models;
-
-public class LongRangeNormalizer {
-
-    private long minNormalized;
-    
-    private long maxNormalized;
- 
-    private long value;
-
-    private LongRange range;
-    
-    public LongRangeNormalizer(LongRange range) {
-        this.range = range;
-    }
-
-    public void setMaxNormalized(long maxNormalized) {
-        this.maxNormalized = maxNormalized;
-    }
-    
-    public void setMinNormalized(long minNormalized) {
-        this.minNormalized = minNormalized;
-    }
-    
-    public long getValue() {
-        return value;
-    }
-
-    public void setValue(long newValue) {
-        this.value = newValue;
-    }
-    
-    public long getMaxNormalized() {
-        return maxNormalized;
-    }
-    
-    public long getMinNormalized() {
-        return minNormalized;
-    }
-    
-    public long getValueNormalized() {
-        double normalized = ((value - range.min) * (double)(maxNormalized - minNormalized)/(range.max - range.min)) + minNormalized;
-        return Math.round(normalized);
-    }
-}
--- a/client/swing-components/src/main/java/com/redhat/thermostat/swing/models/NullSelectionModel.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,132 +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.swing.models;
-
-import javax.swing.ListSelectionModel;
-import javax.swing.event.ListSelectionListener;
-
-public class NullSelectionModel implements ListSelectionModel {
-
-    @Override
-    public void setSelectionInterval(int index0, int index1) {
-    }
-
-    @Override
-    public void addSelectionInterval(int index0, int index1) {
-    }
-
-    @Override
-    public void removeSelectionInterval(int index0, int index1) {        
-    }
-
-    @Override
-    public int getMinSelectionIndex() {
-        return 0;
-    }
-
-    @Override
-    public int getMaxSelectionIndex() {
-        return 0;
-    }
-
-    @Override
-    public boolean isSelectedIndex(int index) {
-        return false;
-    }
-
-    @Override
-    public int getAnchorSelectionIndex() {
-        return 0;
-    }
-
-    @Override
-    public void setAnchorSelectionIndex(int index) {        
-    }
-
-    @Override
-    public int getLeadSelectionIndex() {
-        return -1;
-    }
-
-    @Override
-    public void setLeadSelectionIndex(int index) {
-    }
-
-    @Override
-    public void clearSelection() {
-    }
-
-    @Override
-    public boolean isSelectionEmpty() {
-        return true;
-    }
-
-    @Override
-    public void insertIndexInterval(int index, int length, boolean before) {
-    }
-
-    @Override
-    public void removeIndexInterval(int index0, int index1) {
-    }
-
-    @Override
-    public void setValueIsAdjusting(boolean valueIsAdjusting) {
-    }
-
-    @Override
-    public boolean getValueIsAdjusting() {
-        return false;
-    }
-
-    @Override
-    public void setSelectionMode(int selectionMode) {
-    }
-
-    @Override
-    public int getSelectionMode() {
-        return -1;
-    }
-
-    @Override
-    public void addListSelectionListener(ListSelectionListener x) {        
-    }
-
-    @Override
-    public void removeListSelectionListener(ListSelectionListener x) {
-    }
-
-}
Binary file client/swing-components/src/main/resources/icons/resize-grip.png has changed
--- a/client/swing-components/src/main/resources/icons/resize-grip.svg	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +0,0 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<!-- Created with Inkscape (http://www.inkscape.org/) -->
-
-<svg
-   xmlns:dc="http://purl.org/dc/elements/1.1/"
-   xmlns:cc="http://creativecommons.org/ns#"
-   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-   xmlns:svg="http://www.w3.org/2000/svg"
-   xmlns="http://www.w3.org/2000/svg"
-   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
-   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
-   width="13"
-   height="13"
-   id="svg17653"
-   version="1.1"
-   inkscape:version="0.48.2 r9819"
-   sodipodi:docname="resize-grip.svg">
-  <defs
-     id="defs17655" />
-  <sodipodi:namedview
-     id="base"
-     pagecolor="#ffffff"
-     bordercolor="#666666"
-     borderopacity="1.0"
-     inkscape:pageopacity="0.0"
-     inkscape:pageshadow="2"
-     inkscape:zoom="21.311078"
-     inkscape:cx="-8.2186936"
-     inkscape:cy="8.0008486"
-     inkscape:current-layer="layer1"
-     showgrid="true"
-     inkscape:grid-bbox="true"
-     inkscape:document-units="px"
-     inkscape:window-width="1920"
-     inkscape:window-height="1022"
-     inkscape:window-x="0"
-     inkscape:window-y="26"
-     inkscape:window-maximized="1" />
-  <metadata
-     id="metadata17658">
-    <rdf:RDF>
-      <cc:Work
-         rdf:about="">
-        <dc:format>image/svg+xml</dc:format>
-        <dc:type
-           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
-        <dc:title />
-      </cc:Work>
-    </rdf:RDF>
-  </metadata>
-  <g
-     id="layer1"
-     inkscape:label="Layer 1"
-     inkscape:groupmode="layer"
-     transform="translate(0,-3)">
-    <path
-       transform="matrix(0.65777374,0,0,0.65777374,-560.57081,-392.19484)"
-       d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z"
-       sodipodi:ry="1.9003495"
-       sodipodi:rx="1.9003495"
-       sodipodi:cy="617.14966"
-       sodipodi:cx="868.63647"
-       id="path5513"
-       style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new"
-       sodipodi:type="arc" />
-    <path
-       sodipodi:type="arc"
-       style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new"
-       id="path5515"
-       sodipodi:cx="868.63647"
-       sodipodi:cy="617.14966"
-       sodipodi:rx="1.9003495"
-       sodipodi:ry="1.9003495"
-       d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z"
-       transform="matrix(0.65777374,0,0,0.65777374,-563.84354,-392.19484)" />
-    <path
-       sodipodi:type="arc"
-       style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new"
-       id="path5517"
-       sodipodi:cx="868.63647"
-       sodipodi:cy="617.14966"
-       sodipodi:rx="1.9003495"
-       sodipodi:ry="1.9003495"
-       d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z"
-       transform="matrix(0.65777374,0,0,0.65777374,-560.57081,-395.46756)" />
-    <path
-       transform="matrix(0.65777374,0,0,0.65777374,-560.57081,-398.74029)"
-       d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z"
-       sodipodi:ry="1.9003495"
-       sodipodi:rx="1.9003495"
-       sodipodi:cy="617.14966"
-       sodipodi:cx="868.63647"
-       id="path5519"
-       style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new"
-       sodipodi:type="arc" />
-    <path
-       transform="matrix(0.65777374,0,0,0.65777374,-567.11626,-392.19484)"
-       d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z"
-       sodipodi:ry="1.9003495"
-       sodipodi:rx="1.9003495"
-       sodipodi:cy="617.14966"
-       sodipodi:cx="868.63647"
-       id="path5521"
-       style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new"
-       sodipodi:type="arc" />
-    <path
-       transform="matrix(0.65777374,0,0,0.65777374,-563.84354,-395.46756)"
-       d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z"
-       sodipodi:ry="1.9003495"
-       sodipodi:rx="1.9003495"
-       sodipodi:cy="617.14966"
-       sodipodi:cx="868.63647"
-       id="path5523"
-       style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new"
-       sodipodi:type="arc" />
-  </g>
-</svg>
Binary file client/swing-components/src/main/resources/icons/scale-slider-vert-backdrop.png has changed
Binary file client/swing-components/src/main/resources/icons/scale-slider-vert.png has changed
--- a/client/swing-components/src/test/java/com/redhat/thermostat/swing/EdtHelperTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,196 +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.swing;
-
-import static org.junit.Assert.assertSame;
-import static org.junit.Assert.assertTrue;
-
-import java.awt.EventQueue;
-import java.lang.reflect.InvocationTargetException;
-import java.util.concurrent.Callable;
-
-import javax.swing.SwingUtilities;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-
-import com.redhat.thermostat.swing.EdtHelper;
-
-public class EdtHelperTest {
-
-    private class ExceptionCallable implements Callable<Object>  {
-
-        @Override
-        public Object call() throws Exception {
-            throw new Exception("fluff");
-        }
-        
-    }
-
-    private class ResultCallable implements Callable<Object> {
-    
-        private Object result;
-        private ResultCallable(Object r) {
-            result = r;
-        }
-        @Override
-        public Object call() throws Exception {
-            // By waiting here, we make sure the EDTHelper actually waits for the call.
-            try {
-                Thread.sleep(100);
-            } catch (InterruptedException e) {
-                e.printStackTrace();
-            }
-            if (EventQueue.isDispatchThread()) {
-                calledOnEDT = true;
-            }
-            return result;
-        }
-        
-    }
-
-    private class TestRunnable implements Runnable {
-
-        @Override
-        public void run() {
-            // By waiting here, we make sure the EDTHelper actually waits for the call.
-            try {
-                Thread.sleep(100);
-            } catch (InterruptedException e) {
-                Thread.currentThread().interrupt();
-            }
-            if (EventQueue.isDispatchThread()) {
-                calledOnEDT = true;
-            }
-        }
-        
-    }
-
-    private volatile boolean calledOnEDT;
-
-    @Before
-    public void setUp() {
-        calledOnEDT = false;
-    }
-
-    @After
-    public void tearDown() {
-        calledOnEDT = false;
-    }
-
-    @Test
-    public void testCallRunnableFromNonEDT() throws InvocationTargetException, InterruptedException {
-        Runnable r = new TestRunnable();
-        new EdtHelper().callAndWait(r);
-        assertTrue(calledOnEDT);
-    }
-
-    @Test
-    public void testCallRunnableFromEDT() throws InvocationTargetException, InterruptedException {
-        final Runnable r = new TestRunnable();
-        SwingUtilities.invokeAndWait(new Runnable() {
-            
-            @Override
-            public void run() {
-                try {
-                    new EdtHelper().callAndWait(r);
-                } catch (InvocationTargetException e) {
-                    throw new RuntimeException(e);
-                } catch (InterruptedException e) {
-                    Thread.currentThread().interrupt();
-                }
-            }
-        });
-        assertTrue(calledOnEDT);
-    }
-
-    @Test
-    public void testCallCallableFromNoEDT() throws InvocationTargetException, InterruptedException {
-        final Object expected = new Object();
-        Callable<Object> c = new ResultCallable(expected);
-        Object result = new EdtHelper().callAndWait(c);
-        assertTrue(calledOnEDT);
-        assertSame(expected, result);
-    }
-
-    @Test
-    public void testCallCallableFromEDT() throws InvocationTargetException, InterruptedException {
-        final Object expected = new Object();
-        final Callable<Object> c = new ResultCallable(expected);
-        final Object[] result = new Object[1];
-        SwingUtilities.invokeAndWait(new Runnable() {
-            
-            @Override
-            public void run() {
-                try {
-                    result[0] = new EdtHelper().callAndWait(c);
-                } catch (InvocationTargetException | InterruptedException e) {
-                    throw new RuntimeException();
-                }
-            }
-        });
-        assertTrue(calledOnEDT);
-        assertSame(expected, result[0]);
-    }
-
-    @Test(expected=InvocationTargetException.class)
-    public void testCallCallableFromNoEDTThrowingException() throws InvocationTargetException, InterruptedException {
-        Callable<Object> c = new ExceptionCallable();
-        new EdtHelper().callAndWait(c);
-    }
-
-    @Test
-    public void testCallCallableFromEDTThrowingException() throws InvocationTargetException, InterruptedException {
-        final boolean[] exceptionThrown = new boolean[1];
-        final Callable<Object> c = new ExceptionCallable();
-        SwingUtilities.invokeAndWait(new Runnable() {
-            
-            @Override
-            public void run() {
-                try {
-                    new EdtHelper().callAndWait(c);
-                } catch (InvocationTargetException e) {
-                    exceptionThrown[0] = true;
-                } catch (InterruptedException e) {
-                    Thread.currentThread().interrupt();
-                }
-            }
-        });
-        assertTrue(exceptionThrown[0]);
-    }
-}
--- a/client/swing-components/src/test/java/com/redhat/thermostat/swing/StatusBarTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,154 +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.swing;
-
-import static org.junit.Assert.*;
-
-import java.awt.BorderLayout;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.concurrent.Semaphore;
-
-import javax.swing.JFrame;
-
-import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner;
-
-import org.fest.swing.annotation.GUITest;
-import org.fest.swing.annotation.RunsInEDT;
-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.JLabelFixture;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(CacioFESTRunner.class)
-public class StatusBarTest {
-
-    private JFrame frame;
-    private FrameFixture frameFixture;
-    
-    private StatusBar statusBar;
-    
-    @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.getContentPane().setLayout(new BorderLayout());
-                
-                statusBar = new StatusBar();
-                frame.getContentPane().add(statusBar, BorderLayout.SOUTH);
-                
-                frame.setSize(500, 500);
-            }
-        });
-        frameFixture = new FrameFixture(frame);
-    }
-    
-    @After
-    public void tearDown() {
-        frameFixture.cleanUp();
-        frameFixture = null;
-    }
-    
-    @Test
-    @GUITest
-    @RunsInEDT
-    public void testSetPrimaryStatusLabel() throws InterruptedException {
-        frameFixture.show();
-        
-        JLabelFixture labelfixture = frameFixture.label("primaryStatusLabel");
-        labelfixture.requireText("");
-        
-        final Semaphore sem = new Semaphore(0);
-        GuiActionRunner.execute(new GuiTask() {
-            @Override
-            protected void executeInEDT() throws Throwable {
-                statusBar.setPrimaryStatus("test");
-                sem.release();
-            }
-        });
-        sem.acquire();
-        
-        // the label has an extra space at the beginning
-        labelfixture.requireText(" test");
-    }
-    
-    @Test
-    @GUITest
-    @RunsInEDT
-    public void testSetPrimaryStatusLabelWithProperty() throws InterruptedException {
-        frameFixture.show();
-        
-        final String[] primaryStatus = new String[2];
-        
-        final Semaphore sem = new Semaphore(2);
-        statusBar.addPropertyChangeListener(StatusBar.PRIMARY_STATUS_PROPERTY,
-                                                      new PropertyChangeListener()
-        {
-            @Override
-            public void propertyChange(PropertyChangeEvent evt) {
-                primaryStatus[0] = (String) evt.getOldValue();
-                primaryStatus[1] = (String) evt.getNewValue();
-                sem.release();
-            }
-        });
-        
-        GuiActionRunner.execute(new GuiTask() {
-            @Override
-            protected void executeInEDT() throws Throwable {
-                statusBar.setPrimaryStatus("test");
-                sem.release();
-            }
-        });
-        sem.acquire(2);
-        
-        assertEquals("", primaryStatus[0]);
-        assertEquals("test", primaryStatus[1]);
-    }
-}
--- a/client/swing-components/src/test/java/com/redhat/thermostat/swing/models/LongRangeNormalizerTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +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.swing.models;
-
-import static org.junit.Assert.*;
-import junit.framework.Assert;
-
-import org.junit.Test;
-
-public class LongRangeNormalizerTest {
-
-    @Test
-    public void testSameRange() {
-        
-        LongRange range = new LongRange();
-        range.setMax(10);
-        range.setMin(0);
-        
-        LongRangeNormalizer model = new LongRangeNormalizer(range);
-        
-        model.setValue(5);
-        
-        model.setMaxNormalized(10);
-        model.setMinNormalized(0);
-        
-        
-        Assert.assertEquals((int) model.getValue(), model.getValueNormalized());
-    }
-
-    @Test
-    public void testDoubleRange() {
-        
-        LongRange range = new LongRange();
-        range.setMax(10);
-        range.setMin(0);
-        
-        LongRangeNormalizer model = new LongRangeNormalizer(range);
-        
-        model.setValue(5);
-        
-        model.setMaxNormalized(20);
-        model.setMinNormalized(0);
-        
-        
-        Assert.assertEquals(10, model.getValueNormalized());
-    }
-    
-    @Test
-    public void testRanges() {
-        
-        LongRange range = new LongRange();
-        range.setMax(10);
-        range.setMin(0);
-        
-        LongRangeNormalizer model = new LongRangeNormalizer(range);
-        
-        model.setValue(5);
-        
-        model.setMaxNormalized(40);
-        model.setMinNormalized(0);
-                
-        Assert.assertEquals(20, model.getValueNormalized());
-        
-        model.setMaxNormalized(60);
-        model.setMinNormalized(0);
-                
-        Assert.assertEquals(30, model.getValueNormalized());
-                
-        model.setMaxNormalized(200);
-        model.setMinNormalized(100);
-                
-        Assert.assertEquals(150, model.getValueNormalized());
-        
-        range.setMax(100);
-        range.setMin(0);
-        model.setValue(50);
-        
-        model.setMaxNormalized(1);
-        model.setMinNormalized(0);
-                
-        Assert.assertEquals(1, model.getValueNormalized());
-        
-        model.setValue(49);
-        Assert.assertEquals(0, model.getValueNormalized());
-    }
-}
--- a/client/swing-components/src/test/java/com/redhat/thermostat/swing/models/NullSelectionModelTest.java	Tue Oct 23 11:17:50 2012 -0400
+++ /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.swing.models;
-
-import static org.junit.Assert.*;
-
-import javax.swing.DefaultListModel;
-import javax.swing.JFrame;
-import javax.swing.JList;
-
-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.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(CacioFESTRunner.class)
-public class NullSelectionModelTest {
-
-    private JFrame frame;
-    private FrameFixture frameFixture;
-    private JList<String> list;
-    
-    @BeforeClass
-    public static void setUpOnce() {
-        FailOnThreadViolationRepaintManager.install();
-    }
-    
-    @Before
-    public void setUp() {
-        GuiActionRunner.execute(new GuiTask() {
-            @Override
-            protected void executeInEDT() throws Throwable {
-                frame = new JFrame();
-                
-                DefaultListModel<String> model = new DefaultListModel<>();
-                
-                model.addElement("fluff #1");
-                model.addElement("fluff #2");
-                model.addElement("fluff #3");
-                model.addElement("fluff #4");
-                model.addElement("fluff #5");
-
-                list = new JList<>(model);
-                list.setSelectionModel(new NullSelectionModel());
-                
-                frame.add(list);
-            }
-        });
-        frameFixture = new FrameFixture(frame);
-    }
-    
-    @After
-    public void tearDown() {
-        frameFixture.cleanUp();
-        frameFixture = null;
-    }
-    
-    @GUITest
-    @Test
-    public void testCellNotSelectable() {
-        frameFixture.show();
-        
-        String[] selection = frameFixture.list().selection();
-        assertEquals(0, selection.length);
-        frameFixture.list().clickItem(2);
-        selection = frameFixture.list().selection();
-        assertEquals(0, selection.length);
-    }
-
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/pom.xml	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 
+
+ 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.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>com.redhat.thermostat</groupId>
+    <artifactId>thermostat-client</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-client-swing</artifactId>
+  <packaging>bundle</packaging>
+
+  <name>Thermostat Swing Client</name>
+
+  <dependencies>
+      <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-laf</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.mockito</groupId>
+      <artifactId>mockito-core</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easytesting</groupId>
+      <artifactId>fest-swing</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>net.java.openjdk.cacio</groupId>
+      <artifactId>cacio-tta</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-api-mockito</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.powermock</groupId>
+      <artifactId>powermock-module-junit4</artifactId>
+      <scope>test</scope>
+    </dependency>
+
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.jfree</groupId>
+      <artifactId>jfreechart</artifactId>
+    </dependency>
+    
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+
+  <build>
+
+    <resources>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>true</filtering>
+        <excludes>
+          <exclude>**/*.png</exclude>
+        </excludes>
+      </resource>
+      <resource>
+        <directory>src/main/resources</directory>
+        <filtering>false</filtering>
+        <includes>
+          <include>**/*.png</include>
+        </includes>
+      </resource>
+    </resources>
+
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-Activator>com.redhat.thermostat.client.swing.internal.osgi.ThermostatActivator</Bundle-Activator>
+            <Bundle-SymbolicName>com.redhat.thermostat.client.swing</Bundle-SymbolicName>
+            <Export-Package>
+              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
+            </Private-Package>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/IconResource.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,93 @@
+/*
+ * 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;
+
+import java.io.File;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+
+public class IconResource {
+    /* FIXME we need to pick up the icons dynamically */
+
+    private static final String ICON_PREFIX = "/usr/share/icons/gnome/";
+
+    // an icon that should always be available and indicate that the actual icon
+    // is missing.
+    public static final IconResource MISSING_ICON = null;
+
+    public static final IconResource JAVA_APPLICATION = new IconResource("duke.png");
+    public static final IconResource HOST = new IconResource(ICON_PREFIX + "16x16/devices/computer.png");
+    
+    public static final IconResource ERROR = new IconResource(ICON_PREFIX + "48x48/status/dialog-error.png");
+    public static final IconResource QUESTION = new IconResource(ICON_PREFIX + "48x48/status/dialog-question.png");
+    public static final IconResource WARNING = new IconResource(ICON_PREFIX + "48x48/status/dialog-warning.png");
+
+    public static final IconResource COMPUTER = new IconResource(ICON_PREFIX + "48x48/devices/computer.png");
+    public static final IconResource NETWORK_SERVER = new IconResource(ICON_PREFIX + "48x48/places/network-server.png");
+    public static final IconResource NETWORK_GROUP = new IconResource(ICON_PREFIX + "48x48/places/network-workgroup.png");
+
+    public static final IconResource ARROW_RIGHT = new IconResource(ICON_PREFIX + "48x48/actions/go-next.png");
+
+    public static final IconResource SEARCH = new IconResource(ICON_PREFIX + "16x16/actions/search.png");
+
+    private final String path;
+
+    private IconResource(String descriptor) {
+        this.path = descriptor;
+    }
+
+    public static IconResource fromPath(String path) {
+        // TODO implement this
+        return null;
+    }
+
+    public Icon getIcon() {
+        if (new File(path).exists()) {
+            return new ImageIcon(path);
+        }
+        return null;
+    }
+
+    public String getPath() {
+        return path;
+    }
+
+    public String getUrl() {
+        return "file:" + getPath();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/LayoutDebugHelper.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Window;
+
+import javax.swing.BorderFactory;
+import javax.swing.JComponent;
+
+/**
+ * This class goes through the swing container hierarchy and adds random colored
+ * borders to the components themselves. it makes it easier to see what the
+ * {@code LayoutManager}s are doing
+ */
+public class LayoutDebugHelper {
+
+    private Color[] colors = new Color[] { Color.BLACK, Color.BLUE, Color.CYAN, Color.GREEN, Color.MAGENTA, Color.PINK, Color.ORANGE, Color.RED, Color.YELLOW };
+    private int colorIndex = 0;
+
+    public void debugLayout(Window w) {
+        Component[] children = w.getComponents();
+        debugLayout(children);
+    }
+
+    public void debugLayout(Component c) {
+        if (c instanceof JComponent) {
+            JComponent panel = (JComponent) c;
+            try {
+                panel.setBorder(BorderFactory.createLineBorder(colors[colorIndex % colors.length]));
+            } catch (IllegalArgumentException iae) {
+                // never mind then
+            }
+            colorIndex++;
+            debugLayout(panel.getComponents());
+        }
+    }
+
+    public void debugLayout(Component[] components) {
+        for (Component aComponent : components) {
+            debugLayout(aComponent);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/MainWindow.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,795 @@
+/*
+ * 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;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics2D;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.image.BufferedImage;
+import java.io.PrintStream;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.ByteBuffer;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JTree;
+import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
+import javax.swing.SwingWorker;
+import javax.swing.ToolTipManager;
+import javax.swing.event.TreeExpansionEvent;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.event.TreeWillExpandListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.ExpandVetoException;
+import javax.swing.tree.TreeNode;
+import javax.swing.tree.TreePath;
+import javax.swing.tree.TreeSelectionModel;
+
+import sun.misc.Signal;
+
+import com.redhat.thermostat.client.core.HostFilter;
+import com.redhat.thermostat.client.core.VmFilter;
+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.HostDecorator;
+import com.redhat.thermostat.client.osgi.service.MenuAction;
+import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.osgi.service.VmDecorator;
+import com.redhat.thermostat.client.swing.components.EdtHelper;
+import com.redhat.thermostat.client.swing.components.HtmlTextBuilder;
+import com.redhat.thermostat.client.swing.components.StatusBar;
+import com.redhat.thermostat.client.swing.internal.MainView;
+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;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.ActionNotifier;
+import com.redhat.thermostat.common.HostsVMsLoader;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.Ref;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.common.utils.StringUtils;
+
+public class MainWindow extends JFrame implements MainView {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    /**
+     * Updates a TreeModel in the background in an Swing EDT-safe manner.
+     */
+    private static class BackgroundTreeModelWorker extends SwingWorker<DefaultMutableTreeNode, Void> {
+
+        private JTree tree;
+
+        private final DefaultTreeModel treeModel;
+        private DefaultMutableTreeNode treeRoot;
+        
+        private List<HostFilter> hostFilters;
+        private List<VmFilter> vmFilters;
+        private List<HostDecorator> hostDecorators;
+        private List<VmDecorator> vmDecorators;
+        
+        private HostsVMsLoader hostsVMsLoader;
+
+        public BackgroundTreeModelWorker(DefaultTreeModel model, DefaultMutableTreeNode root,
+                                         List<HostFilter> hostFilters, List<VmFilter> vmFilters,
+                                         List<HostDecorator> hostDecorators, List<VmDecorator> vmDecorators,
+                                         HostsVMsLoader hostsVMsLoader, JTree tree)
+        {
+            this.hostFilters = hostFilters;
+            this.vmFilters = vmFilters;
+
+            this.vmDecorators = vmDecorators;
+            this.hostDecorators = hostDecorators;
+
+            this.treeModel = model;
+            this.treeRoot = root;
+            this.hostsVMsLoader = hostsVMsLoader;
+            this.tree = tree;
+        }
+
+        @Override
+        protected DefaultMutableTreeNode doInBackground() throws Exception {
+            DefaultMutableTreeNode root = new DefaultMutableTreeNode();
+            
+            Collection<HostRef> hostsInRemoteModel = hostsVMsLoader.getHosts();
+            buildHostSubTree(root, hostsInRemoteModel);
+            return root;
+        }
+
+        private boolean buildHostSubTree(DefaultMutableTreeNode parent, Collection<HostRef> objectsInRemoteModel) {
+            boolean subTreeMatches = false;
+            for (HostRef inRemoteModel : objectsInRemoteModel) {
+                DecoratedDefaultMutableTreeNode inTreeNode =
+                        new DecoratedDefaultMutableTreeNode(inRemoteModel);
+
+                boolean shouldInsert = false;
+                if (hostFilters == null) {
+                    shouldInsert = true;
+                } else {
+                    shouldInsert = true;
+                    for (HostFilter filter : hostFilters) {
+                        if (!filter.matches(inRemoteModel)) {
+                            shouldInsert = false;
+                            break;
+                        }
+                    }
+                }
+                
+                Collection<VmRef> children = hostsVMsLoader.getVMs(inRemoteModel);
+                boolean subtreeResult = buildVmSubTree(inTreeNode, children);
+                if (subtreeResult) {
+                    shouldInsert = true;
+                }
+
+                if (shouldInsert) {
+                    for (HostDecorator decorator : hostDecorators) {
+                        HostFilter filter = decorator.getFilter();
+                        if (filter != null && filter.matches(inRemoteModel)) {
+                            inTreeNode.addDecorator(decorator.getDecorator());
+                        }
+                    }
+                    
+                    parent.add(inTreeNode);
+                    subTreeMatches = true;
+                }
+            }
+            
+            return subTreeMatches;
+        }
+
+        private boolean buildVmSubTree(DefaultMutableTreeNode parent, Collection<VmRef> objectsInRemoteModel) {
+            boolean subTreeMatches = false;
+            for (VmRef inRemoteModel : objectsInRemoteModel) {
+                DecoratedDefaultMutableTreeNode inTreeNode =
+                        new DecoratedDefaultMutableTreeNode(inRemoteModel);
+
+                boolean shouldInsert = false;
+                if (vmFilters == null) {
+                    shouldInsert = true;
+                } else {
+                    shouldInsert = true;
+                    for (VmFilter filter : vmFilters) {
+                        if (!filter.matches(inRemoteModel)) {
+                            shouldInsert = false;
+                            break;
+                        }
+                    }
+                }
+
+                if (shouldInsert) {
+                    for (VmDecorator decorator : vmDecorators) {
+                        VmFilter filter = decorator.getFilter();
+                        if (filter != null && filter.matches(inRemoteModel)) {
+                            inTreeNode.addDecorator(decorator.getDecorator());
+                        }
+                    }
+
+                    parent.add(inTreeNode);
+                    subTreeMatches = true;
+                }
+            }
+
+            return subTreeMatches;
+        }
+
+        @Override
+        protected void done() {
+            DefaultMutableTreeNode sourceRoot;
+            try {
+                sourceRoot = get();
+                syncTree(sourceRoot, treeModel, treeRoot);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            } catch (ExecutionException e) {
+                e.printStackTrace();
+            }
+        }
+
+        private void syncTree(DefaultMutableTreeNode sourceRoot, DefaultTreeModel targetModel, DefaultMutableTreeNode targetNode) {
+            
+            @SuppressWarnings("unchecked") // We know what we put into these trees.
+            List<DefaultMutableTreeNode> sourceChildren = Collections.list(sourceRoot.children());
+
+            @SuppressWarnings("unchecked")
+            List<DefaultMutableTreeNode> targetChildren = Collections.list(targetNode.children());
+            for (DefaultMutableTreeNode sourceChild : sourceChildren) {
+                Ref sourceRef = (Ref) sourceChild.getUserObject();
+                DefaultMutableTreeNode targetChild = null;
+                for (DefaultMutableTreeNode aChild : targetChildren) {
+                    Ref targetRef = (Ref) aChild.getUserObject();
+                    if (targetRef.equals(sourceRef)) {
+                        targetChild = aChild;
+                        if (sourceChild instanceof DecoratedDefaultMutableTreeNode) {
+                            DecoratedDefaultMutableTreeNode source = (DecoratedDefaultMutableTreeNode) sourceChild;
+                            ((DecoratedDefaultMutableTreeNode) targetChild).setDecorators(source.getDecorators());
+                        }
+                        break;
+                    }
+                }
+
+                if (targetChild == null) {
+                    targetChild = new DecoratedDefaultMutableTreeNode(sourceRef);
+                    if (sourceChild instanceof DecoratedDefaultMutableTreeNode) {
+                        DecoratedDefaultMutableTreeNode source = (DecoratedDefaultMutableTreeNode) sourceChild;
+                        ((DecoratedDefaultMutableTreeNode) targetChild).setDecorators(source.getDecorators());
+                    }
+                    targetModel.insertNodeInto(targetChild, targetNode, targetNode.getChildCount());
+                }
+
+                syncTree(sourceChild, targetModel, targetChild);
+            }
+
+            for (DefaultMutableTreeNode targetChild : targetChildren) {
+                Ref targetRef = (Ref) targetChild.getUserObject();
+                boolean matchFound = false;
+                for (DefaultMutableTreeNode sourceChild : sourceChildren) {
+                    Ref sourceRef = (Ref) sourceChild.getUserObject();
+                    if (targetRef.equals(sourceRef)) {
+                        matchFound = true;
+                        break;
+                    }
+                }
+
+                if (!matchFound) {
+                    targetModel.removeNodeFromParent(targetChild);
+                }
+            }
+            ensureRootIsExpanded(targetModel);
+        }
+
+        private void ensureRootIsExpanded(final DefaultTreeModel model) {
+            DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot();
+            tree.expandPath(new TreePath(root.getPath()));
+        }
+
+    }
+
+    private static final long serialVersionUID = 5608972421496808177L;
+
+    private final JMenuBar mainMenuBar = new JMenuBar();
+    private final MenuHelper mainMenuHelper = new MenuHelper(mainMenuBar);
+    private JPanel contentArea = null;
+
+    private SearchFieldSwingView searchField = new SearchFieldSwingView();
+    private JTree agentVmTree = null;
+
+    private final ShutdownClient shutdownAction;
+
+    private ActionNotifier<Action> actionNotifier = new ActionNotifier<>(this);
+
+    private JPopupMenu vmContextMenu;
+    private StatusBar statusBar;
+    
+    private final DefaultMutableTreeNode publishedRoot =
+            new DefaultMutableTreeNode(translator.localize(LocaleResources.MAIN_WINDOW_TREE_ROOT_NAME));
+    private final DefaultTreeModel publishedTreeModel = new DefaultTreeModel(publishedRoot);
+
+    @SuppressWarnings("restriction")
+    public MainWindow() {
+        super();
+
+        shutdownAction = new ShutdownClient();
+
+        searchField.addActionListener(new ActionListener<SearchAction>() {
+            @Override
+            public void actionPerformed(ActionEvent<SearchAction> actionEvent) {
+                switch (actionEvent.getActionId()) {
+                case TEXT_CHANGED:
+                    fireViewAction(Action.HOST_VM_TREE_FILTER);
+                    break;
+                }
+            }
+        });
+        agentVmTree = new JTree(publishedTreeModel);
+        agentVmTree.setName("agentVmTree");
+        agentVmTree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
+        agentVmTree.setCellRenderer(new AgentVmTreeCellRenderer());
+        agentVmTree.addTreeWillExpandListener(new TreeWillExpandListener() {
+            @Override
+            public void treeWillExpand(TreeExpansionEvent event) throws ExpandVetoException {
+                /* Yup, tree will expand */
+            }
+
+            @Override
+            public void treeWillCollapse(TreeExpansionEvent event) throws ExpandVetoException {
+                if (new TreePath(publishedRoot.getPath()).equals(event.getPath())) {
+                    throw new ExpandVetoException(event, "root cant be collapsed");
+                }
+            }
+        });
+        ToolTipManager.sharedInstance().registerComponent(agentVmTree);
+        contentArea = new JPanel(new BorderLayout());
+
+        setupMenus();
+        setupPanels();
+
+        this.setPreferredSize(new Dimension(800, 600));
+
+        agentVmTree.setSelectionPath(new TreePath(((DefaultMutableTreeNode) publishedTreeModel.getRoot()).getPath()));
+        
+        //agentVmTree.setLargeModel(true);
+        agentVmTree.setRowHeight(25);
+        
+        statusBar = new StatusBar();
+        getContentPane().add(statusBar, BorderLayout.SOUTH);
+        
+        setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
+        addWindowListener(shutdownAction);
+
+        // Handle SIGTERM/SIGINT properly
+        Signal.handle(new Signal("TERM"), shutdownAction);
+        Signal.handle(new Signal("INT"), shutdownAction);
+        
+        addComponentListener(new ComponentAdapter() {
+
+            @Override
+            public void componentShown(ComponentEvent e) {
+                fireViewAction(Action.VISIBLE);
+            }
+
+            @Override
+            public void componentHidden(ComponentEvent e) {
+                fireViewAction(Action.HIDDEN);
+            }
+        });
+
+    }
+
+    private void setupMenus() {
+
+        JMenu fileMenu = new JMenu(translator.localize(LocaleResources.MENU_FILE));
+        fileMenu.getPopupMenu().setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
+        mainMenuBar.add(fileMenu);
+
+        JMenuItem fileExitMenu = new JMenuItem(translator.localize(LocaleResources.MENU_FILE_EXIT));
+        fileExitMenu.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, InputEvent.CTRL_DOWN_MASK));
+        fileExitMenu.addActionListener(shutdownAction);
+        fileMenu.add(fileExitMenu);
+
+        JMenu editMenu = new JMenu(translator.localize(LocaleResources.MENU_EDIT));
+        mainMenuBar.add(editMenu);
+
+        JMenuItem configureClientMenuItem = new JMenuItem(translator.localize(LocaleResources.MENU_EDIT_CONFIGURE_CLIENT));
+        configureClientMenuItem.setName("showClientConfig");
+        configureClientMenuItem.addActionListener(new java.awt.event.ActionListener() {
+            @Override
+            public void actionPerformed(java.awt.event.ActionEvent e) {
+                fireViewAction(Action.SHOW_CLIENT_CONFIG);
+            }
+        });
+        editMenu.add(configureClientMenuItem);
+
+        editMenu.addSeparator();
+        JMenuItem historyModeMenuItem = new JCheckBoxMenuItem(translator.localize(LocaleResources.MENU_EDIT_ENABLE_HISTORY_MODE));
+        historyModeMenuItem.setName("historyModeSwitch");
+        historyModeMenuItem.setSelected(false);
+        historyModeMenuItem.addActionListener(new java.awt.event.ActionListener() {
+            @Override
+            public void actionPerformed(java.awt.event.ActionEvent e) {
+                fireViewAction(Action.SWITCH_HISTORY_MODE);
+            }
+        });
+        editMenu.add(historyModeMenuItem);
+
+        JMenu viewMenu = new JMenu(translator.localize(LocaleResources.MENU_VIEW));
+        mainMenuBar.add(viewMenu);
+        JMenuItem configureAgentMenuItem = new JMenuItem(translator.localize(LocaleResources.MENU_VIEW_AGENTS));
+        configureAgentMenuItem.setName("showAgentConfig");
+        configureAgentMenuItem.addActionListener(new java.awt.event.ActionListener() {
+            @Override
+            public void actionPerformed(java.awt.event.ActionEvent e) {
+                fireViewAction(Action.SHOW_AGENT_CONFIG);
+            }
+        });
+        viewMenu.add(configureAgentMenuItem);
+
+        JMenu helpMenu = new JMenu(translator.localize(LocaleResources.MENU_HELP));
+        helpMenu.getPopupMenu().setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
+        mainMenuBar.add(helpMenu);
+
+        JMenuItem helpAboutMenu = new JMenuItem(translator.localize(LocaleResources.MENU_HELP_ABOUT));
+        helpAboutMenu.addActionListener(new java.awt.event.ActionListener() {
+            @Override
+            public void actionPerformed(java.awt.event.ActionEvent e) {
+                fireViewAction(Action.SHOW_ABOUT_DIALOG);
+            }
+        });
+        helpMenu.add(helpAboutMenu);
+        setJMenuBar(mainMenuBar);
+    }
+
+    private void setupPanels() {
+        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+        splitPane.setOneTouchExpandable(true);
+        
+        JPanel navigationPanel = new JPanel(new BorderLayout());
+
+        navigationPanel.add(searchField, BorderLayout.PAGE_START);
+
+        agentVmTree.addTreeSelectionListener(new TreeSelectionListener() {
+            @Override
+            public void valueChanged(TreeSelectionEvent e) {
+                if (e.isAddedPath()) {
+                    fireViewAction(Action.HOST_VM_SELECTION_CHANGED);
+                }
+            }
+        });
+        registerContextActionListener(agentVmTree);
+        
+        JScrollPane treeScrollPane = new JScrollPane(agentVmTree);
+        
+        navigationPanel.add(treeScrollPane);
+
+        JPanel detailsPanel = createDetailsPanel();
+
+        navigationPanel.setMinimumSize(new Dimension(200,500));
+        detailsPanel.setMinimumSize(new Dimension(500, 500));
+
+        splitPane.add(navigationPanel);
+        splitPane.add(detailsPanel);
+
+        getContentPane().add(splitPane);
+    }
+
+    private void registerContextActionListener(JTree agentVmTree2) {
+        vmContextMenu = new JPopupMenu();
+        agentVmTree2.addMouseListener(new MouseAdapter() {
+            @Override
+            public void mousePressed(MouseEvent e) {
+                if (e.isPopupTrigger()) {
+                    Ref ref = getSelectedHostOrVm();
+                    if (ref instanceof VmRef) {
+                        fireViewAction(Action.SHOW_VM_CONTEXT_MENU, e);
+                    }
+                }
+            }
+        });
+    }
+
+    @Override
+    public void showVMContextActions(final List<VMContextAction> actions, final MouseEvent e) {
+        SwingUtilities.invokeLater(new Runnable() {
+
+            @Override
+            public void run() {
+                vmContextMenu.removeAll();
+
+                for (final VMContextAction action: actions) {
+                    JMenuItem contextAction = new JMenuItem();
+                    contextAction.setText(action.getName());
+                    contextAction.setToolTipText(action.getDescription());
+
+                    contextAction.addActionListener(new java.awt.event.ActionListener() {
+                        @Override
+                        public void actionPerformed(java.awt.event.ActionEvent e) {
+                            fireViewAction(Action.VM_CONTEXT_ACTION, action);
+                        }
+                    });
+                    vmContextMenu.add(contextAction);
+                }
+
+                vmContextMenu.show((Component)e.getSource(), e.getX(), e.getY());
+            }
+
+        });
+    }
+    
+    private JPanel createDetailsPanel() {
+        JPanel result = new JPanel(new BorderLayout());
+        result.add(contentArea, BorderLayout.CENTER);
+        return result;
+    }
+
+    @SuppressWarnings("restriction")
+    public class ShutdownClient extends WindowAdapter implements java.awt.event.ActionListener, sun.misc.SignalHandler {
+
+        @Override
+        public void windowClosing(WindowEvent e) {
+            shutdown();
+        }
+
+        @Override
+        public void actionPerformed(java.awt.event.ActionEvent e) {
+            shutdown();
+        }
+        
+        @Override
+        public void handle(Signal arg0) {
+            shutdown();
+        }
+
+        private void shutdown() {
+            dispose();
+            fireViewAction(Action.SHUTDOWN);
+        }
+
+    }
+
+    private static class AgentVmTreeCellRenderer extends DefaultTreeCellRenderer {
+        private static final long serialVersionUID = 4444642511815252481L;
+
+        @Override
+        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+            
+            Object node = ((DefaultMutableTreeNode) value).getUserObject();
+            setToolTipText(createToolTipText(node));
+            
+            Component component = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
+            if (value instanceof DecoratedDefaultMutableTreeNode) {
+                DecoratedDefaultMutableTreeNode treeNode = (DecoratedDefaultMutableTreeNode) value;
+                setAnnotation(treeNode, node, component);
+            }
+
+            return component;
+        }
+        
+        // TODO: we can cache more, for example the full icon, not just the decoration
+        private Map<Decorator, ImageIcon> decoratorsCache = new HashMap<>();
+        private void setAnnotation(DecoratedDefaultMutableTreeNode treeNode, Object value, Component component) {
+
+            List<Decorator> decorators = treeNode.getDecorators();
+            for (Decorator dec : decorators) {
+                String newText = dec.getLabel(getText());
+                setText(newText);
+                setLabelFor(component);
+                
+                ImageIcon icon = decoratorsCache.get(dec);
+                if (icon == null) {
+                    //System.err.println("cache miss: " + dec);
+                    IconDescriptor iconDescriptor = dec.getIconDescriptor();
+                    if (iconDescriptor != null) {
+                        ByteBuffer data = iconDescriptor.getData();
+                        icon = new ImageIcon(data.array());
+                        decoratorsCache.put(dec, icon);
+                    }
+                }
+                
+                if (icon == null) {
+                    return;
+                }
+                
+                Icon currentIcon = getIcon();
+                switch (dec.getQuadrant()) {
+                case BOTTOM_LEFT:
+                    int y = currentIcon.getIconHeight() - icon.getIconHeight();
+                    paintCustomIcon(currentIcon, icon, y);
+                    break;
+                    
+                case TOP_LEFT:
+                    paintCustomIcon(currentIcon, icon, 0);
+                    break;
+                    
+                case MAIN:
+                default:
+                    setIcon(icon);
+                    break;
+                }
+            }
+        }
+        
+        private void paintCustomIcon(Icon currentIcon, ImageIcon icon, int y) {
+            BufferedImage image = new BufferedImage(currentIcon.getIconWidth(),
+                                                    currentIcon.getIconHeight(),
+                                                    BufferedImage.TYPE_INT_ARGB);
+            Graphics2D graphics = (Graphics2D) image.getGraphics();
+            
+            currentIcon.paintIcon(null, graphics, 0, 0);
+            graphics.drawImage(icon.getImage(), 0, y, null);
+            
+            setIcon(new ImageIcon(image));
+        }
+        
+        private String createToolTipText(Object value) {
+            if (value instanceof HostRef) {
+                HostRef hostRef = (HostRef) value;
+                String hostNameHtml = new HtmlTextBuilder().bold(hostRef.getHostName()).toPartialHtml();
+                String agentIdHtml = new HtmlTextBuilder().bold(hostRef.getAgentId()).toPartialHtml();
+                HtmlTextBuilder builder = new HtmlTextBuilder()
+                    .appendRaw(translator.localize(LocaleResources.TREE_HOST_TOOLTIP_HOST_NAME, hostNameHtml))
+                    .newLine()
+                    .appendRaw(translator.localize(LocaleResources.TREE_HOST_TOOLTIP_AGENT_ID, agentIdHtml));
+                return builder.toHtml();
+            } else if (value instanceof VmRef) {
+                VmRef vmRef = (VmRef) value;
+                String vmNameHtml= new HtmlTextBuilder().bold(vmRef.getName()).toPartialHtml();
+                String vmIdHtml = new HtmlTextBuilder().bold(vmRef.getIdString()).toPartialHtml();
+                HtmlTextBuilder builder = new HtmlTextBuilder()
+                    .appendRaw(translator.localize(LocaleResources.TREE_HOST_TOOLTIP_VM_NAME, vmNameHtml))
+                    .newLine()
+                    .appendRaw(translator.localize(LocaleResources.TREE_HOST_TOOLTIP_VM_ID, vmIdHtml));
+                return builder.toHtml();
+            } else {
+                return null;
+            }
+        }
+    }
+
+    @Override
+    public void addActionListener(ActionListener<Action> l) {
+        actionNotifier.addActionListener(l);
+    }
+
+    public void removeViewActionListener(ActionListener<Action> l) {
+        actionNotifier.removeActionListener(l);
+    }
+
+    private void fireViewAction(Action action) {
+        actionNotifier.fireAction(action);
+    }
+    
+    private void fireViewAction(Action action, Object payload) {
+        actionNotifier.fireAction(action, payload);
+    }
+    
+    @Override
+    public void updateTree(List<HostFilter> hostFilters, List<VmFilter> vmFilters,
+            List<HostDecorator> hostDecorators, List<VmDecorator> vmDecorators,
+            HostsVMsLoader hostsVMsLoader)
+    {
+        BackgroundTreeModelWorker worker =
+                new BackgroundTreeModelWorker(publishedTreeModel, publishedRoot,
+                                              hostFilters, vmFilters, hostDecorators, vmDecorators, hostsVMsLoader, agentVmTree);
+        worker.execute();
+    }
+
+    @SuppressWarnings("unused") // Used for debugging but not in production code.
+    private static void printTree(PrintStream out, TreeNode node, int depth) {
+        out.println(StringUtils.repeat("  ", depth) + node.toString());
+        @SuppressWarnings("unchecked")
+        List<TreeNode> children = Collections.list(node.children());
+        for (TreeNode child : children) {
+            printTree(out, child, depth + 1);
+        }
+    }
+
+    @Override
+    public void setWindowTitle(String title) {
+        setTitle(title);
+    }
+
+    @Override
+    public void showMainWindow() {
+        try {
+            new EdtHelper().callAndWait(new Runnable() {
+
+                @Override
+                public void run() {
+                    pack();
+                    setVisible(true);
+                }
+            });
+        } catch (InvocationTargetException e) {
+            throw new RuntimeException(e);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    @Override
+    public void hideMainWindow() {
+        setVisible(false);
+        dispose();
+    }
+
+    @Override
+    public void setStatusBarPrimaryStatus(final String primaryStatus) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                statusBar.setPrimaryStatus(primaryStatus);
+            }
+        });
+    }
+    
+    @Override
+    public void setSubView(final BasicView view) {
+        if (view instanceof SwingComponent) {
+            final SwingComponent swingComp = (SwingComponent)view;
+            SwingUtilities.invokeLater(new Runnable() {
+                @Override
+                public void run() {
+                    contentArea.removeAll();
+                    Component toAdd = swingComp.getUiComponent();
+                    contentArea.add(toAdd);
+                    contentArea.revalidate();
+                }
+            });
+        }
+    }
+
+    @Override
+    public void addMenu(MenuAction action) {
+        mainMenuHelper.addMenuAction(action);
+    }
+
+    @Override
+    public void removeMenu(MenuAction action) {
+        mainMenuHelper.removeMenuAction(action);
+    }
+
+    /**
+     * Returns null to indicate no Ref is selected
+     */
+    @Override
+    public Ref getSelectedHostOrVm() {
+        TreePath path = agentVmTree.getSelectionPath();
+        if (path == null || path.getPathCount() == 1) {
+            return null;
+        }
+        return (Ref) ((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject();
+    }
+
+    @Override
+    public String getHostVmTreeFilterText() {
+        return searchField.getSearchText();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/MenuHelper.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,287 @@
+/*
+ * 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;
+
+import java.awt.event.ActionEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.util.Arrays;
+import java.util.logging.Logger;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPopupMenu;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.MenuElement;
+
+import com.redhat.thermostat.client.osgi.service.MenuAction;
+import com.redhat.thermostat.client.swing.components.EdtHelper;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.common.utils.StringUtils;
+
+public class MenuHelper {
+
+    private static final Logger logger = LoggingUtils.getLogger(MenuHelper.class);
+
+    private final JMenuBar menuBar;
+
+    public MenuHelper(JMenuBar menuBar) {
+        this.menuBar = menuBar;
+    }
+
+    /**
+     * Add a menu item as specified though the {@link MenuAction} argument.
+     */
+    public void addMenuAction(final MenuAction action) {
+        try {
+            new EdtHelper().callAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    String[] path = action.getPath();
+                    Menu parent = findMenuParent(menuBar, path, true);
+                    JMenuItem menu = null;
+                    switch (action.getType()) {
+                    case RADIO:
+                        menu = new JRadioButtonMenuItem();
+                        break;
+                    case CHECK:
+                        menu = new JCheckBoxMenuItem();
+                        break;
+
+                    case STANDARD:
+                    default:
+                        menu = new JMenuItem();
+                        break;
+                    }
+
+                    menu.setText(action.getName());
+                    menu.addActionListener(new java.awt.event.ActionListener() {
+                        @Override
+                        public void actionPerformed(ActionEvent e) {
+                            action.execute();
+                        }
+                    });
+                    parent.add(new Menu(menu));
+
+                    menuBar.revalidate();
+                }
+            });
+        } catch (InvocationTargetException ite) {
+            Throwable cause = ite.getCause();
+            if (cause instanceof IllegalArgumentException) {
+                throw (IllegalArgumentException) cause;
+            }
+            throw new RuntimeException(cause);
+        } catch (InterruptedException ie) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException(ie);
+        }
+
+    }
+
+    /**
+     * Remove a existing menu item as specified though the {@link MenuAction}
+     * argument.
+     *
+     * @throws IllegalArgumentException if the path specified in
+     * {@link MenuAction#getPath()} can not be found
+     */
+    public void removeMenuAction(final MenuAction action) {
+        try {
+            new EdtHelper().callAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    String[] path = action.getPath();
+                    Menu parent = findMenuParent(menuBar, path, false);
+                    parent.remove(path[path.length - 1]);
+                    menuBar.revalidate();
+                }
+            });
+        } catch (InterruptedException ie) {
+            Thread.currentThread().interrupt();
+            throw new RuntimeException(ie);
+        } catch (InvocationTargetException roe) {
+            Throwable cause = roe.getCause();
+            if (cause instanceof IllegalArgumentException) {
+                throw (IllegalArgumentException) cause;
+            }
+            throw new RuntimeException(cause);
+        }
+
+    }
+
+    private static Menu findMenuParent(JMenuBar menuBar, String[] path, boolean createIfNotFound) {
+        Menu parent = null;
+        int mainMenuCount = menuBar.getMenuCount();
+        for (int i = 0; i < mainMenuCount; i++) {
+            JMenu menu = menuBar.getMenu(i);
+            if (menu.getText().equals(path[0])) {
+                parent = new Menu(menuBar.getMenu(i));
+                break;
+            }
+        }
+        if (parent == null) {
+            if (createIfNotFound) {
+                JMenu delegate = new JMenu(path[0]);
+                parent = new Menu(delegate);
+                menuBar.add(delegate);
+            } else {
+                throw new IllegalArgumentException("top-level " + path[0] + " not found (using path" + Arrays.toString(path) + ")");
+            }
+        }
+
+        for (int i = 1; i < path.length - 1; i++) {
+            Menu[] children = parent.children();
+            boolean found = false;
+            for (int j = 0; j < children.length; j++) {
+                Menu menu = children[j];
+                if (menu.getText().equals(path[i])) {
+                    parent = menu;
+                    found = true;
+                }
+            }
+            if (!found) {
+                if (createIfNotFound) {
+                    Menu newMenu = new Menu(new JMenu(path[i]));
+                    parent.add(newMenu);
+                    parent = newMenu;
+                } else {
+                    throw new IllegalArgumentException("path not found");
+                }
+            }
+        }
+
+        return parent;
+    }
+
+    private static String getText(MenuElement element) {
+        if (element instanceof JMenuItem) {
+            return ((JMenuItem) element).getText();
+        }
+        return "";
+    }
+
+    @SuppressWarnings("unused") // this method is for debugging only
+    private static void printMenu(MenuElement parent, int nestingLevel) {
+        System.out.println(StringUtils.repeat(" ", nestingLevel * 2) + getText(parent) + " [" + parent.getClass() + "]");
+        for (MenuElement element : parent.getSubElements()) {
+            printMenu(element, nestingLevel + 1);
+        }
+    }
+
+    /**
+     * The swing menu hierarchy makes uniform operations very difficult. This
+     * is a hack around that.
+     */
+    private static final class Menu {
+        private Object swingDelegate;
+
+        public Menu() { /* no op */}
+
+        public Menu(JMenuItem actual) {
+            this.swingDelegate = actual;
+        }
+
+        public String getText() {
+            if (swingDelegate instanceof JMenuItem) {
+                return ((JMenuItem) swingDelegate).getText();
+            }
+            return null;
+        }
+
+        public Menu[] children() {
+            if (swingDelegate instanceof MenuElement) {
+                MenuElement[] actualChildren = ((MenuElement) swingDelegate).getSubElements();
+                if (actualChildren.length == 1 && actualChildren[0] instanceof JPopupMenu) {
+                    actualChildren = actualChildren[0].getSubElements();
+                }
+
+                Menu[] children = new Menu[actualChildren.length];
+                for (int i = 0; i < children.length; i++) {
+                    children[i] = new Menu((JMenuItem) actualChildren[i]);
+                }
+                return children;
+            }
+            return new Menu[0];
+        }
+
+        public void add(Menu menu) {
+            if (swingDelegate instanceof JPopupMenu) {
+                ((JPopupMenu) swingDelegate).add((JMenuItem) menu.swingDelegate);
+            } else if (swingDelegate instanceof JMenu) {
+                ((JMenu) swingDelegate).add((JMenuItem) menu.swingDelegate);
+            } else {
+                logger.warning("Unable to add menu. Menu is of unrecognized type: " + menu.swingDelegate);
+            }
+        }
+
+        public void remove(String string) {
+            JPopupMenu removeParent = null;
+
+            if (swingDelegate instanceof JMenu) {
+                JMenu parent = (JMenu) swingDelegate;
+                MenuElement[] actualChildren = parent.getSubElements();
+                if (actualChildren.length == 1 && actualChildren[0] instanceof JPopupMenu) {
+                    removeParent = (JPopupMenu) actualChildren[0];
+                }
+            }
+
+            if (removeParent == null) {
+                if (swingDelegate instanceof JPopupMenu) {
+                    removeParent = (JPopupMenu) swingDelegate;
+                } else {
+                    logger.warning("BUG: problem while removing menu. delegate is not a JPopupMenu, cant remove");
+                    return;
+                }
+            }
+
+            JPopupMenu parent = removeParent;
+            for (MenuElement element : parent.getSubElements()) {
+                if (((JMenuItem) element).getText().equals(string)) {
+                    parent.remove((JMenuItem) element);
+                }
+            }
+        }
+
+        @Override
+        public String toString() {
+            return "Menu [" + swingDelegate.toString() + "]";
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/SwingComponent.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,10 @@
+package com.redhat.thermostat.client.swing;
+
+import java.awt.Component;
+
+import com.redhat.thermostat.client.core.views.UIComponent;
+
+public interface SwingComponent extends UIComponent {
+
+    Component getUiComponent();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/UIResources.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,115 @@
+/*
+ * 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;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import javax.swing.UIManager;
+import javax.swing.plaf.ColorUIResource;
+
+public class UIResources {
+
+    private static final UIResources resource = new UIResources();
+    
+    private static final ColorUIResource hyperLinkColor;
+    private static final ColorUIResource hyperLinkActiveColor;
+
+    private static final ColorUIResource selectionColor;
+    
+    private static final Font standard;
+    
+    static {
+        Color color = UIManager.getColor("Button.darkShadow");
+        if (color == null) {
+            color = Color.BLUE;
+        }
+        hyperLinkColor = new ColorUIResource(color);
+
+        color = UIManager.getColor("Button.focus");
+        if (color == null) {
+            color = Color.BLUE;
+        }
+        hyperLinkActiveColor = new ColorUIResource(color);
+        selectionColor = hyperLinkActiveColor;
+        
+        Font font = UIManager.getFont("Label.font");
+        if (font == null) {
+            font = Font.decode(Font.DIALOG);
+        }
+        standard = font;
+    }
+    
+    private static final Font header = standard.deriveFont(Font.BOLD);
+    
+    // TODO: check when size is too small
+    private static final Font footer = standard.deriveFont(Font.PLAIN, standard.getSize() - 2);
+    
+    private UIResources() { /* nothing to do */ }
+    
+    // colors
+
+    public static UIResources getInstance() {
+        return resource;
+    }
+    
+    public ColorUIResource hyperlinkColor() {
+        return hyperLinkColor;
+    }
+    
+    public ColorUIResource hyperlinkActiveColor() {
+        return hyperLinkActiveColor;
+    }
+    
+    public ColorUIResource getSelectionColor() {
+        return selectionColor;
+    }
+    
+    // font resources
+    
+    public Font footerFont() {
+        return footer;
+    }
+    
+    public Font headerFont() {
+        return header;
+    }
+    
+    public Font standardFont() {
+        return standard;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionButton.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,80 @@
+/*
+ * 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 javax.swing.AbstractButton;
+import javax.swing.Icon;
+import javax.swing.JButton;
+
+@SuppressWarnings("serial")
+public class ActionButton extends JButton implements ToolbarButton {
+
+    private AbstractButton realButton;
+    
+    public ActionButton(final Icon icon) {
+        super(icon);
+        
+        realButton = new JButton() {
+            @Override
+            public int getWidth() {
+                return icon.getIconWidth() + 5;
+            }
+            
+            @Override
+            public int getHeight() {
+                return icon.getIconHeight() + 4;
+            }
+        };
+        setUI(new ActionButtonUI(realButton));
+        
+        setSize(realButton.getWidth(), realButton.getHeight());
+        setContentAreaFilled(false);
+        
+        setPreferredSize(getSize());
+        setMinimumSize(getSize());
+        setMaximumSize(getSize());
+        
+        realButton.setModel(getModel());
+
+        setBorderPainted(false);
+    }
+    
+    @Override
+    public AbstractButton getToolbarButton() {
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionButtonUI.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,108 @@
+/*
+ * 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.Graphics;
+import java.awt.image.BufferedImage;
+import java.awt.image.BufferedImageOp;
+import java.awt.image.ConvolveOp;
+import java.awt.image.Kernel;
+
+import javax.swing.AbstractButton;
+import javax.swing.ButtonModel;
+import javax.swing.Icon;
+import javax.swing.JComponent;
+import javax.swing.border.Border;
+import javax.swing.plaf.metal.MetalButtonUI;
+
+class ActionButtonUI extends MetalButtonUI {
+
+    private BufferedImage sourceIcon;
+    private BufferedImage rollOverIcon;
+    private AbstractButton realButton;
+    
+    ActionButtonUI(AbstractButton button) {
+        this.realButton = button;
+    }
+    
+    private BufferedImage getBrighterImage(BufferedImage source) {
+        float[] kernel = new float[] { 0, 0, 0, 0, 1.2f, 0, 0, 0, 0 };
+
+        BufferedImageOp brighterOp = new ConvolveOp(new Kernel(3, 3, kernel),
+                ConvolveOp.EDGE_NO_OP, null);
+        return brighterOp.filter(source, new BufferedImage(source.getWidth(),
+                source.getHeight(), source.getType()));
+    }
+
+    @Override
+    public void paint(Graphics g, JComponent c) {
+
+        AbstractButton button = (AbstractButton) c;
+        ButtonModel model = button.getModel();
+        if (model.isPressed() || model.isArmed() || model.isSelected()) {
+            realButton.paint(g);
+        } else if (model.isRollover()) {
+            Border border = realButton.getBorder();
+            border.paintBorder(realButton, g, 0, 0, realButton.getWidth(),
+                    realButton.getHeight());
+        }
+        // paint the icon, always to the center
+        Icon icon = button.getIcon();
+        int w = icon.getIconWidth();
+        int h = icon.getIconHeight();
+
+        if (sourceIcon == null) {
+            sourceIcon = new BufferedImage(w + 1, h + 1,
+                    BufferedImage.TYPE_INT_ARGB);
+            Graphics imageGraphics = sourceIcon.getGraphics();
+            icon.paintIcon(null, imageGraphics, 0, 0);
+        }
+
+        if (rollOverIcon == null) {
+            rollOverIcon = getBrighterImage(sourceIcon);
+        }
+
+        int x = realButton.getWidth() / 2 - w / 2;
+        int y = realButton.getHeight() / 2 - h / 2;
+
+        if (model.isRollover()) {
+            g.drawImage(rollOverIcon, x, y, null);
+        } else {
+            g.drawImage(sourceIcon, x, y, null);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionToggleButton.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,79 @@
+/*
+ * 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 javax.swing.AbstractButton;
+import javax.swing.Icon;
+import javax.swing.JToggleButton;
+
+@SuppressWarnings("serial")
+public class ActionToggleButton extends JToggleButton implements ToolbarButton {
+    private AbstractButton realButton;
+    
+    public ActionToggleButton(final Icon icon) {
+        super(icon);
+        
+        realButton = new JToggleButton() {
+            @Override
+            public int getWidth() {
+                return icon.getIconWidth() + 4;
+            }
+            
+            @Override
+            public int getHeight() {
+                return icon.getIconHeight() + 4;
+            }
+        };
+        setUI(new ActionButtonUI(realButton));
+        
+        setSize(realButton.getWidth(), realButton.getHeight());
+        setContentAreaFilled(false);
+        
+        setPreferredSize(getSize());
+        setMinimumSize(getSize());
+        setMaximumSize(getSize());
+        
+        realButton.setModel(getModel());
+
+        setBorderPainted(false);
+    }
+    
+    @Override
+    public AbstractButton getToolbarButton() {
+        return this;
+    }    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ChartPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,71 @@
+/*
+ * 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.Graphics;
+import java.awt.image.BufferedImage;
+
+import javax.swing.JPanel;
+
+import org.jfree.chart.ChartRenderingInfo;
+import org.jfree.chart.JFreeChart;
+
+@SuppressWarnings("serial")
+public class ChartPanel extends JPanel {
+
+    private JFreeChart chart;
+    private ChartRenderingInfo info;
+    
+    public ChartPanel(JFreeChart chart) {
+        this(chart, new ChartRenderingInfo());
+    }
+    
+    public ChartPanel(JFreeChart chart, ChartRenderingInfo info) {
+        this.chart = chart;
+        this.info = info;
+    }
+    
+    @Override
+    protected void paintComponent(Graphics g) {
+        BufferedImage image = chart.createBufferedImage(getWidth(), getHeight(), info);
+        g.drawImage(image, 0, 0, null);
+    }
+    
+    public ChartRenderingInfo getChartRenderingInfo() {
+        return info;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/Components.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,60 @@
+/*
+ * 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 javax.swing.BorderFactory;
+import javax.swing.JLabel;
+import javax.swing.SwingConstants;
+import javax.swing.border.Border;
+
+public class Components {
+    public static JLabel header(String text) {
+        JLabel label = new JLabel(HtmlTextBuilder.boldHtml(text));
+        label.setHorizontalAlignment(SwingConstants.LEADING);
+        return label;
+    }
+
+    public static JLabel label(String string) {
+        JLabel label = new JLabel(string);
+        label.setHorizontalAlignment(SwingConstants.TRAILING);
+        return label;
+    }
+
+    public static Border smallBorder() {
+        return BorderFactory.createEmptyBorder(5, 5, 5, 5);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/DebugBorder.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,89 @@
+/*
+ * 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.BasicStroke;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.Shape;
+import java.awt.geom.RoundRectangle2D;
+import java.io.Serializable;
+
+import javax.swing.border.AbstractBorder;
+import javax.swing.plaf.UIResource;
+
+@SuppressWarnings("serial")
+public class DebugBorder extends AbstractBorder implements UIResource, Serializable {
+
+    @Override
+    public void paintBorder(Component c, Graphics g, int x, int y, int width,
+                            int height)
+    {
+        Graphics2D graphics = (Graphics2D) g.create();
+
+        graphics.translate(x, y);
+        
+        graphics.setPaint(Color.RED);
+        
+        float dash[] = { 10.0f };
+        graphics.setStroke(new BasicStroke(3.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f));
+        
+        Shape shape = new RoundRectangle2D.Float(0, 0, width - 1,
+                                                 height - 1, 4, 4);
+        graphics.draw(shape);
+        graphics.dispose();
+    }
+    
+    @Override
+    public Insets getBorderInsets(Component c) {
+        return getBorderInsets(c, new Insets(0, 0, 0, 0));
+    }
+
+    @Override
+    public Insets getBorderInsets(Component c, Insets insets) {
+        
+        insets.top = 4;
+        insets.left = 4;
+        insets.right = 4;
+        insets.bottom = 4;
+        
+        return insets;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/EdtHelper.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.components;
+
+import java.awt.EventQueue;
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.Callable;
+
+public class EdtHelper {
+
+    @SuppressWarnings("serial")
+    private static class CallableException extends RuntimeException {
+
+        private CallableException(Exception ex) {
+            super(ex);
+        }
+        
+    }
+
+    private static class CallableWrapper<T> implements Runnable {
+
+        private Callable<T> callable;
+        private T result;
+
+        private CallableWrapper(Callable<T> c) {
+            callable = c;
+        }
+
+        @Override
+        public void run() {
+            try {
+                result = callable.call();
+            } catch (Exception ex) {
+                throw new CallableException(ex);
+            }
+        }
+
+        private T getResult() {
+            return result;
+        }
+    }
+
+    public void callAndWait(Runnable r) throws InvocationTargetException, InterruptedException {
+        if (EventQueue.isDispatchThread()) {
+            try {
+                r.run();
+            } catch (Exception ex) {
+                throw new InvocationTargetException(ex);
+            }
+        } else {
+            EventQueue.invokeAndWait(r);
+        }
+    }
+
+    public <T> T callAndWait(Callable<T> c) throws InvocationTargetException, InterruptedException {
+        CallableWrapper<T> w = new CallableWrapper<>(c);
+        callAndWait(w);
+        return w.getResult();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/EmptyIcon.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,73 @@
+/*
+ * 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.Component;
+import java.awt.Graphics;
+
+import javax.swing.ImageIcon;
+
+@SuppressWarnings("serial")
+public class EmptyIcon extends ImageIcon  {
+
+    private int width;
+    private int height;
+    
+    public EmptyIcon() {
+        this(16, 16);
+    }
+    
+    public EmptyIcon(int width, int height) {
+        this.width = width;
+        this.height = height;
+    }
+    
+    @Override
+    public int getIconHeight() {
+        return height;
+    }
+    
+    @Override
+    public int getIconWidth() {
+        return width;
+    }
+    
+    @Override
+    public synchronized void paintIcon(Component c, Graphics g, int x, int y) {
+        // no-op
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/GradientPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,69 @@
+/*
+ * 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.Color;
+import java.awt.GradientPaint;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Paint;
+
+import javax.swing.JPanel;
+
+
+@SuppressWarnings("serial")
+public class GradientPanel extends JPanel {
+
+    private Color top;
+    private Color bottom;
+    
+    public GradientPanel(Color top, Color bottom) {
+        this.top = top;
+        this.bottom = bottom;
+    }
+    
+    @Override
+    protected void paintComponent(Graphics g) {
+        
+        Graphics2D graphics = GraphicsUtils.getInstance().createAAGraphics(g);
+        
+        Paint gradient = new GradientPaint(0, 0, top, 0, getHeight(), bottom);
+        graphics.setPaint(gradient);
+        graphics.fillRect(0, 0, getWidth(), getHeight());
+        graphics.dispose();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/GradientRoundBorder.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,76 @@
+/*
+ * 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.Color;
+import java.awt.Component;
+import java.awt.GradientPaint;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.Shape;
+import java.io.Serializable;
+
+import javax.swing.UIManager;
+import javax.swing.border.AbstractBorder;
+import javax.swing.plaf.UIResource;
+
+import com.redhat.thermostat.client.ui.Palette;
+
+@SuppressWarnings("serial")
+public class GradientRoundBorder extends AbstractBorder implements UIResource, Serializable {
+
+    @Override
+    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
+        GraphicsUtils utils = GraphicsUtils.getInstance();
+        Graphics2D graphics = utils.createAAGraphics(g);
+        
+        Color highlight = UIManager.getColor("textHighlight");
+        if (highlight == null) {
+            highlight = Palette.EGYPTIAN_BLUE.getColor();
+        }
+        Paint paint = new GradientPaint(x, y, highlight, 0, height, c.getBackground());
+        graphics.setPaint(paint);
+        
+        graphics.translate(x, y);
+        
+        Shape shape = utils.getRoundShape(width, height);
+        graphics.draw(shape);
+        
+        graphics.dispose();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/GraphicsUtils.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.components;
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.GradientPaint;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Paint;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.geom.RoundRectangle2D;
+
+import javax.swing.JComponent;
+
+import sun.swing.SwingUtilities2;
+
+@SuppressWarnings("restriction")
+public class GraphicsUtils {
+
+    private static GraphicsUtils instance = new GraphicsUtils();
+    public static GraphicsUtils getInstance() {
+        return instance;
+    }
+    
+    public Graphics2D createAAGraphics(Graphics g) {
+        Graphics2D graphics = (Graphics2D) g.create();
+        graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+        return graphics;
+    }
+    
+    public void drawStringWithShadow(JComponent component, Graphics2D graphics, String string, Color foreground, int x, int y) {
+        // paint it twice to give a subtle drop shadow effect
+        
+        graphics.setColor(new Color(0f, 0f, 0f, 0.1f));
+        SwingUtilities2.drawString(component, graphics, string, x, y + 1);
+        
+        graphics.setColor(foreground);
+        SwingUtilities2.drawString(component, graphics, string, x, y);
+    }
+    
+    public void drawString(JComponent component, Graphics2D graphics, String string, Color foreground, int x, int y) {
+        graphics.setColor(foreground);
+        SwingUtilities2.drawString(component, graphics, string, x, y);
+    }
+    
+    public FontMetrics getFontMetrics(JComponent component, Font font) {
+        return SwingUtilities2.getFontMetrics(component, font);
+    }
+    
+    public Shape getRoundShape(int width, int height) {
+        return new RoundRectangle2D.Double(0, 0, width, height, 4, 4);
+    }
+    
+    public void setGradientPaint(Graphics2D g, int x, int height, Color start, Color stop) {
+        Paint paint = new GradientPaint(x, 0, start, 0, height, stop);
+        g.setPaint(paint);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/HeaderPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,131 @@
+/*
+ * 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.Dimension;
+import java.awt.FlowLayout;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.BoxLayout;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+/**
+ * A component that host a panel with a nicely rendered header.
+ */
+@SuppressWarnings("serial")
+public class HeaderPanel extends JPanel {
+    
+    private String header;
+    
+    private JPanel contentPanel;
+    private JLabel headerLabel;
+    private JPanel headerPanel;
+    private JPanel controlPanel;
+    
+    public HeaderPanel() {
+        this("");
+    }
+    
+    public HeaderPanel(String header) {
+        
+        this.header = header;
+        
+        setLayout(new BorderLayout(0, 0));
+
+        headerLabel = new ShadowLabel(header, new EmptyIcon(5, 5));
+        headerPanel = new GradientPanel(Color.WHITE, getBackground());
+        headerPanel.setPreferredSize(new Dimension(HeaderPanel.this.getWidth(), 40));
+        
+        headerPanel.setLayout(new BorderLayout(0, 0));
+        headerPanel.add(headerLabel, BorderLayout.WEST);
+        add(headerPanel, BorderLayout.NORTH);
+        
+        controlPanel = new JPanel();
+        controlPanel.setOpaque(false);
+        controlPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 2, 10));
+        
+        headerPanel.add(controlPanel, BorderLayout.EAST);
+        
+        contentPanel = new JPanel();
+        contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.X_AXIS));
+        
+        add(contentPanel, BorderLayout.CENTER);
+    }
+   
+    public String getHeader() {
+        return header;
+    }
+    
+    public void setHeader(String header) {
+        this.header = header;
+        headerLabel.setText(header);
+    }
+    
+    public void setContent(JComponent content) {
+        contentPanel.removeAll();
+        contentPanel.add(content);
+        contentPanel.revalidate();
+        repaint();
+    }
+
+    public void addToolBarButton(ToolbarButton button) {
+        controlPanel.add(button.getToolbarButton());
+    }
+    
+    public static void main(String[] args) throws InvocationTargetException, InterruptedException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            
+            @Override
+            public void run() {
+               JFrame frame = new JFrame();
+               frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+               
+               HeaderPanel header = new HeaderPanel();
+               header.setHeader("Test");
+               frame.getContentPane().add(header);
+               frame.setSize(500, 500);
+               frame.setVisible(true);
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/HtmlTextBuilder.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,118 @@
+/*
+ * 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;
+
+public class HtmlTextBuilder {
+
+    /*
+     * The api provided by this class needs to be cleaned up.
+     */
+
+    private final StringBuilder text = new StringBuilder();
+
+    public HtmlTextBuilder() {
+        // do nothing
+    }
+
+    public HtmlTextBuilder(String text) {
+        text = escape(text);
+        this.text.append(text);
+    }
+
+    public HtmlTextBuilder bold(boolean on) {
+        if (on) {
+            this.text.append("<b>");
+        } else {
+            this.text.append("</b>");
+        }
+        return this;
+    }
+
+    public HtmlTextBuilder bold(String toBold) {
+        text.append("<b>").append(toBold).append("</b>");
+        return this;
+    }
+
+    public HtmlTextBuilder larger(String toAppend) {
+        text.append("<font size='+2'>").append(escape(toAppend)).append("</font>");
+        return this;
+    }
+
+    public HtmlTextBuilder huge(String toAppend) {
+        text.append("<font size='+6'>").append(escape(toAppend)).append("</font>");
+        return this;
+    }
+
+    @Override
+    public String toString() {
+        // FIXME
+        return null;
+    }
+
+    public String toHtml() {
+        return "<html>" + text.toString() + "</html>";
+    }
+
+    public String toPartialHtml() {
+        return text.toString();
+    }
+
+    private static String escape(String toEscape) {
+        // FIXME implement this
+        return toEscape;
+    }
+
+    public HtmlTextBuilder append(String toAppend) {
+        text.append(escape(toAppend));
+        return this;
+    }
+
+    public HtmlTextBuilder appendRaw(String toAppend) {
+        text.append(toAppend);
+        return this;
+    }
+
+    public static String boldHtml(String toBold) {
+        return new HtmlTextBuilder().bold(toBold).toHtml();
+    }
+
+    public HtmlTextBuilder newLine() {
+        text.append("<br>");
+        return this;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/LabelField.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,48 @@
+/*
+ * 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 javax.swing.JLabel;
+import javax.swing.SwingConstants;
+
+public class LabelField extends JLabel {
+
+    public LabelField(String text) {
+        super(text);
+        setHorizontalAlignment(SwingConstants.TRAILING);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/RecentTimeSeriesChartPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.components;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.concurrent.TimeUnit;
+
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JComboBox;
+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 javax.swing.text.JTextComponent;
+
+import org.jfree.chart.ChartPanel;
+
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.ui.RecentTimeSeriesChartController;
+import com.redhat.thermostat.common.locale.Translate;
+
+public class RecentTimeSeriesChartPanel extends JPanel {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private static final long serialVersionUID = -1733906800911900456L;
+    private static final int MINIMUM_DRAW_SIZE = 100;
+
+    private final RecentTimeSeriesChartController controller;
+
+    private JPanel labelContainer;
+    private JTextComponent label;
+
+    public RecentTimeSeriesChartPanel(RecentTimeSeriesChartController controller) {
+        this.controller = controller;
+
+        this.setLayout(new BorderLayout());
+
+        final ChartPanel cp = controller.getChartPanel();
+
+        cp.setDisplayToolTips(false);
+        cp.setDoubleBuffered(true);
+        cp.setMouseZoomable(false);
+        cp.setPopupMenu(null);
+
+        /*
+         * By default, ChartPanel scales itself instead of redrawing things when
+         * it's resized. To have it resize automatically, we need to set minimum
+         * and maximum sizes. Lets constrain the minimum, but not the maximum
+         * size.
+         */
+        cp.setMinimumDrawHeight(MINIMUM_DRAW_SIZE);
+        cp.setMaximumDrawHeight(Integer.MAX_VALUE);
+        cp.setMinimumDrawWidth(MINIMUM_DRAW_SIZE);
+        cp.setMaximumDrawWidth(Integer.MAX_VALUE);
+
+        add(getControlsAndAdditionalDisplay(), BorderLayout.SOUTH);
+
+        add(cp, BorderLayout.CENTER);
+    }
+
+    private Component getControlsAndAdditionalDisplay() {
+        JPanel container = new JPanel();
+        container.setOpaque(false);
+
+        container.setLayout(new BorderLayout());
+
+        container.add(getChartControls(), BorderLayout.LINE_START);
+        container.add(getAdditionalDataDisplay(), BorderLayout.LINE_END);
+
+        return container;
+    }
+
+    private Component getChartControls() {
+        JPanel container = new JPanel();
+        container.setOpaque(false);
+
+        final JTextField durationSelector = new JTextField(5);
+        final JComboBox<TimeUnit> unitSelector = new JComboBox<>();
+        unitSelector.setModel(new DefaultComboBoxModel<>(controller.getTimeUnits()));
+
+        int defaultValue = controller.getTimeValue();
+        TimeUnit defaultUnit = controller.getTimeUnit();
+
+        TimeUnitChangeListener timeUnitChangeListener = new TimeUnitChangeListener(controller, defaultValue, defaultUnit);
+
+        durationSelector.getDocument().addDocumentListener(timeUnitChangeListener);
+        unitSelector.addActionListener(timeUnitChangeListener);
+
+        durationSelector.setText(String.valueOf(defaultValue));
+        unitSelector.setSelectedItem(defaultUnit);
+
+        container.add(new JLabel(translator.localize(LocaleResources.CHART_DURATION_SELECTOR_LABEL)));
+        container.add(durationSelector);
+        container.add(unitSelector);
+
+        return container;
+    }
+
+    private Component getAdditionalDataDisplay() {
+        JPanel panel = new JPanel(new GridBagLayout());
+        panel.setOpaque(false);
+        labelContainer = new JPanel();
+        labelContainer.setOpaque(false);
+        GridBagConstraints constraints = new GridBagConstraints();
+        constraints.fill = GridBagConstraints.BOTH;
+        constraints.anchor = GridBagConstraints.CENTER;
+        panel.add(labelContainer, constraints);
+        return panel;
+    }
+
+    public void setDataInformationLabel(final String text) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                if (label == null) {
+                    label = new ValueField(text);
+                    labelContainer.add(label);
+                }
+
+                label.setText(text);
+            }
+        });
+    }
+
+    private static class TimeUnitChangeListener implements DocumentListener, ActionListener {
+
+        private final RecentTimeSeriesChartController controller;
+        private int value;
+        private TimeUnit unit;
+
+        public TimeUnitChangeListener(RecentTimeSeriesChartController controller, int defaultValue, TimeUnit defaultUnit) {
+            this.controller = controller;
+            this.value = defaultValue;
+            this.unit = defaultUnit;
+        }
+
+        @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) {
+            try {
+                this.value = Integer.valueOf(doc.getText(0, doc.getLength()));
+            } catch (NumberFormatException nfe) {
+                // ignore
+            } catch (BadLocationException ble) {
+                // ignore
+            }
+            updateChartParameters();
+        }
+
+        private void updateChartParameters() {
+            controller.setTime(value, unit);
+        }
+
+        @Override
+        public void actionPerformed(ActionEvent e) {
+            @SuppressWarnings("unchecked") // We are a TimeUnitChangeListener, specifically.
+            JComboBox<TimeUnit> comboBox = (JComboBox<TimeUnit>) e.getSource();
+            TimeUnit time = (TimeUnit) comboBox.getSelectedItem();
+            this.unit = time;
+            updateChartParameters();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SectionHeader.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.components;
+
+import javax.swing.JLabel;
+import javax.swing.SwingConstants;
+
+
+public class SectionHeader extends JLabel {
+
+    public SectionHeader(String text) {
+        super(HtmlTextBuilder.boldHtml(text));
+        setHorizontalAlignment(SwingConstants.LEADING);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ShadowLabel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,68 @@
+/*
+ * 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.Graphics;
+import java.awt.Graphics2D;
+
+import javax.swing.Icon;
+import javax.swing.JLabel;
+import javax.swing.plaf.metal.MetalLabelUI;
+
+@SuppressWarnings("serial")
+public class ShadowLabel extends JLabel {
+
+    public ShadowLabel(String text, Icon icon) {
+        super(text);
+        this.setIcon(icon);
+        setUI(new ShadowLabelUI());
+    }
+    
+    public ShadowLabel(String text) {
+        this(text, null);
+    }
+
+    private class ShadowLabelUI extends MetalLabelUI {
+        
+        @Override
+        protected void paintEnabledText(JLabel l, Graphics g, String s, int textX, int textY) {
+            GraphicsUtils graphicsUtils = GraphicsUtils.getInstance();
+            Graphics2D graphics = graphicsUtils.createAAGraphics(g);
+            graphicsUtils.drawStringWithShadow(l, graphics, s, getForeground(), textX, textY);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SimpleTable.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,290 @@
+/*
+ * 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.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.swing.Box;
+import javax.swing.JComponent;
+import javax.swing.JEditorPane;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+
+import com.redhat.thermostat.client.swing.internal.ChangeableText;
+import com.redhat.thermostat.client.ui.ComponentVisibleListener;
+
+public class SimpleTable implements ChangeableText.TextListener {
+
+    Map<ChangeableText, Set<JComponent>> updateMap = new HashMap<ChangeableText, Set<JComponent>>();
+
+    public static class Section {
+        private final String sectionName;
+        private final List<TableEntry> tableEntries = new ArrayList<TableEntry>();
+
+        public Section(String name) {
+            this.sectionName = name;
+        }
+
+        public String getText() {
+            return sectionName;
+        }
+
+        public void add(TableEntry entry) {
+            tableEntries.add(entry);
+        }
+
+        public void add(Key key, List<Value> values) {
+            tableEntries.add(new TableEntry(key, values));
+        }
+
+        public void add(Key key, Value value) {
+            tableEntries.add(new TableEntry(key, value));
+        }
+
+        public TableEntry[] getEntries() {
+            return tableEntries.toArray(new TableEntry[0]);
+        }
+    }
+
+    public static class TableEntry {
+        private final Key key;
+        private final List<Value> values;
+
+        public TableEntry(String key, ChangeableText value) {
+            this(new Key(key), new Value(value));
+        }
+
+        public TableEntry(Key key, Value value) {
+            this.key = key;
+            this.values = new ArrayList<Value>();
+            this.values.add(value);
+        }
+
+        public TableEntry(Key key, List<Value> values) {
+            this.key = key;
+            this.values = new ArrayList<Value>(values);
+        }
+
+        public Key getKey() {
+            return key;
+        }
+
+        public Value[] getValues() {
+            return values.toArray(new Value[0]);
+        }
+    }
+
+    public static class Key {
+        private final String text;
+
+        public Key(String text) {
+            this.text = text;
+        }
+
+        public String getText() {
+            return text;
+        }
+    }
+
+    public static class Value {
+        private final ChangeableText text;
+        private final Component actualComponent;
+
+        public Value(String text) {
+            this(new ChangeableText(text));
+        }
+
+        public Value(ChangeableText text) {
+            this.text = text;
+            this.actualComponent = null;
+        }
+
+        public Value(Component component) {
+            this.actualComponent = component;
+            this.text = null;
+        }
+
+        public Component getComponent() {
+            return actualComponent;
+        }
+
+        public ChangeableText getChangeableText() {
+            return text;
+        }
+    }
+
+    public JPanel createTable(List<Section> sections) {
+        final int SECTION_TOP_GAP = 10;
+        final int ROW_VERTICAL_GAP = 0;
+        final int ROW_HORIZONTAL_GAP = 10;
+
+        Insets sectionHeaderInsets = new Insets(SECTION_TOP_GAP, 0, 0, 0);
+        Insets rowInsets = new Insets(ROW_VERTICAL_GAP, ROW_HORIZONTAL_GAP, ROW_VERTICAL_GAP, ROW_HORIZONTAL_GAP);
+
+        JPanel container = new JPanel();
+        container.setLayout(new GridBagLayout());
+
+        GridBagConstraints keyConstraints = new GridBagConstraints();
+        GridBagConstraints valueConstraints = new GridBagConstraints();
+        GridBagConstraints sectionHeaderConstraints = new GridBagConstraints();
+
+        keyConstraints.insets = valueConstraints.insets = rowInsets;
+        keyConstraints.gridy = valueConstraints.gridy = 0;
+        keyConstraints.gridx = 0;
+        keyConstraints.anchor = GridBagConstraints.FIRST_LINE_END;
+        valueConstraints.gridx = 1;
+        keyConstraints.fill = valueConstraints.fill = GridBagConstraints.HORIZONTAL;
+
+        sectionHeaderConstraints.gridx = 0;
+        sectionHeaderConstraints.gridwidth = GridBagConstraints.REMAINDER;
+        sectionHeaderConstraints.fill = GridBagConstraints.HORIZONTAL;
+        sectionHeaderConstraints.insets = sectionHeaderInsets;
+
+        for (Section section : sections) {
+            sectionHeaderConstraints.gridy = keyConstraints.gridy = ++valueConstraints.gridy;
+            container.add(Components.header(section.getText()), sectionHeaderConstraints);
+            for (TableEntry tableEntry : section.getEntries()) {
+                keyConstraints.gridy = ++valueConstraints.gridy;
+                container.add(Components.label(tableEntry.getKey().getText()), keyConstraints);
+
+                for (Value value : tableEntry.getValues()) {
+                    if (value.getComponent() == null) {
+                        ChangeableText text = value.getChangeableText();
+                        JComponent valueLabel = new ValueField(text.getText());
+                        if (updateMap.containsKey(text)) {
+                            updateMap.get(text).add(valueLabel);
+                        } else {
+                            Set<JComponent> set = new HashSet<JComponent>();
+                            set.add(valueLabel);
+                            updateMap.put(text, set);
+                        }
+                        container.add(valueLabel, valueConstraints);
+                    } else {
+                        container.add(value.getComponent(), valueConstraints);
+                    }
+                    keyConstraints.gridy = ++valueConstraints.gridy;
+                }
+            }
+        }
+
+        GridBagConstraints glueConstraints = new GridBagConstraints();
+        glueConstraints.gridy = keyConstraints.gridy + 1;
+        glueConstraints.gridx = 0;
+        glueConstraints.weightx = 1;
+        glueConstraints.weighty = 1;
+        glueConstraints.fill = GridBagConstraints.BOTH;
+        glueConstraints.gridheight = GridBagConstraints.REMAINDER;
+        glueConstraints.gridwidth = GridBagConstraints.REMAINDER;
+        Component filler = Box.createGlue();
+        container.add(filler, glueConstraints);
+
+        container.addHierarchyListener(new ComponentVisibleListener() {
+            @Override
+            public void componentShown(Component c) {
+                updateAllValues();
+                addAllListeners();
+            }
+
+            @Override
+            public void componentHidden(Component c) {
+                removeAllListeners();
+            }
+        });
+
+        return container;
+    }
+
+
+    private void updateAllValues() {
+        for (Entry<ChangeableText, Set<JComponent>> entry: updateMap.entrySet()) {
+            for (JComponent label: entry.getValue()) {
+                setText(label, entry.getKey().getText());
+            }
+        }
+    }
+
+    private static void setText(JComponent target, String text) {
+        if (target instanceof JLabel) {
+            ((JLabel)target).setText(text);
+        } else if (target instanceof JTextField) {
+            ((JTextField)target).setText(text);
+        } else if (target instanceof JTextArea) {
+            ((JTextArea)target).setText(text);
+        } else if (target instanceof JEditorPane) {
+            ((JEditorPane)target).setText(text);
+        }
+    }
+
+    @Override
+    public void textChanged(final ChangeableText text) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                String newValue = text.getText();
+                for (JComponent label: updateMap.get(text)) {
+                    setText(label, newValue);
+                }
+            }
+        });
+    }
+
+    public void addAllListeners() {
+        for (ChangeableText text : updateMap.keySet()) {
+            text.addListener(this);
+        }
+    }
+
+    public void removeAllListeners() {
+        for (ChangeableText text : updateMap.keySet()) {
+            text.removeListener(this);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/StatusBar.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.components;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.beans.Transient;
+
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+@SuppressWarnings("serial")
+public class StatusBar extends JPanel {
+
+    // some of this code is inspired by the book
+    // Swing Hacks: Tips & Tools for Building Killer GUIs
+    // By Joshua Marinacci, Chris Adamson
+    // ISBN: 0-596-00907-0
+    // website: http://www.oreilly.com/catalog/swinghks/
+
+    public static final String PRIMARY_STATUS_PROPERTY = "primaryStatus";
+    
+    private Dimension preferredSize;
+    
+    private String primaryStatus = "";
+    private JLabel primaryStatusLabel;
+    private JLabel iconLabel;
+    
+    public StatusBar() {
+        super();
+        setLayout(new BorderLayout(0, 0));
+        
+        primaryStatusLabel = new JLabel(primaryStatus);
+        primaryStatusLabel.setName("primaryStatusLabel");
+        primaryStatusLabel.setFont(getFont().deriveFont(10.0f));
+        primaryStatusLabel.setHorizontalAlignment(JLabel.LEADING);
+        primaryStatusLabel.setVerticalAlignment(JLabel.CENTER);
+
+        add(primaryStatusLabel, BorderLayout.WEST);
+        
+        iconLabel = new JLabel("");
+        ImageIcon grip = new ImageIcon(getClass().getResource("/icons/resize-grip.png"));
+        iconLabel.setIcon(grip);
+
+        iconLabel.setMinimumSize(new Dimension(grip.getIconWidth() + 1, grip.getIconHeight()));
+        iconLabel.setPreferredSize(new Dimension(grip.getIconWidth() + 1, grip.getIconHeight()));
+        iconLabel.setVerticalAlignment(JLabel.BOTTOM);
+
+        add(iconLabel, BorderLayout.EAST);
+        preferredSize = new Dimension(700, grip.getIconHeight() + 5);
+    }
+    
+    @Override
+    @Transient
+    public Dimension getMinimumSize() {
+        if (isMinimumSizeSet()) {
+            return super.getMinimumSize();
+        }
+        return preferredSize;
+    }
+    
+    @Override
+    @Transient
+    public Dimension getPreferredSize() {
+        if (isPreferredSizeSet()) {
+            return super.getPreferredSize();
+        }
+        return preferredSize;
+    }
+    
+    public void setPrimaryStatus(String primaryStatus) {
+        if (primaryStatus == null) throw new NullPointerException();
+        
+        String oldPrimaryStatus = this.primaryStatus;
+        this.primaryStatus = primaryStatus;
+        primaryStatusLabel.setText(" " + primaryStatus);
+        
+        firePropertyChange(PRIMARY_STATUS_PROPERTY, oldPrimaryStatus, this.primaryStatus);
+        repaint();
+    }
+
+    public String getPrimaryStatus() {
+        return primaryStatus;
+    }
+        
+    public static void main(String[] args) {
+        SwingUtilities.invokeLater(new Runnable() {
+            
+            @Override
+            public void run() {
+                JFrame frame = new JFrame();
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.getContentPane().setLayout(new BorderLayout());
+                
+                StatusBar statusBar = new StatusBar();
+                frame.getContentPane().add(statusBar, BorderLayout.SOUTH);
+                
+                frame.setSize(500, 500);
+                frame.setVisible(true);
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ThermostatTable.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,91 @@
+/*
+ * 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.Dimension;
+
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableModel;
+
+@SuppressWarnings("serial")
+public class ThermostatTable extends JTable {
+    
+    private ThermostatTableColumnResizer resizer;
+    
+    public ThermostatTable() {
+        this((DefaultTableModel) null);
+    }
+    
+    public ThermostatTable(int rowHeight) {
+        this((DefaultTableModel) null, rowHeight);
+    }
+    
+    public ThermostatTable(DefaultTableModel model) {
+        this((DefaultTableModel) model, 25);
+    }
+    
+    public ThermostatTable(DefaultTableModel model, int rowHeight) {
+        super(model);
+
+        setRowHeight(rowHeight);
+        
+        setIntercellSpacing(new Dimension(0, 0));
+        
+        setFillsViewportHeight(true);
+        setAutoCreateRowSorter(true);
+        
+        setDefaultRenderer(Object.class, new ThermostatTableRenderer());
+        setDefaultRenderer(Double.class, new ThermostatTableRenderer());
+        setDefaultRenderer(Long.class, new ThermostatTableRenderer());
+        setDefaultRenderer(String.class, new ThermostatTableRenderer());
+        setDefaultRenderer(Integer.class, new ThermostatTableRenderer());
+        
+        this.resizer = new ThermostatTableColumnResizer(this);
+    }
+    
+    public void repackCells() {
+        resizer.resize();
+        revalidate();
+    }
+    
+    public JScrollPane wrap() {        
+        JScrollPane scrollPane = new JScrollPane(this);
+        repackCells();
+        return scrollPane;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ThermostatTableColumnResizer.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,80 @@
+/*
+ * 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.Component;
+
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
+
+class ThermostatTableColumnResizer {
+    
+    // reference Swing Hacks book:
+    // http://shop.oreilly.com/product/9780596009076.do
+    
+    private ThermostatTable table;
+    
+    public ThermostatTableColumnResizer(ThermostatTable table) {
+        this.table = table;
+    }
+    
+    public void resize() {
+        TableColumnModel model = table.getColumnModel();
+        for (int column = 0; column < table.getColumnCount(); column++ ) {
+            int maxWidth = 0;
+            for (int row = 0; row < table.getRowCount(); row++ ) {
+                TableCellRenderer renderer = table.getCellRenderer(row, column);
+                Object value = table.getValueAt(row, column);
+                Component component = renderer.getTableCellRendererComponent(table, value, false, false, row, column);
+                maxWidth = Math.max(component.getPreferredSize().width, maxWidth);
+            }
+            
+            TableColumn tableColumn = model.getColumn(column);
+            TableCellRenderer headerRenderer = tableColumn.getHeaderRenderer();
+            if (headerRenderer == null) {
+                headerRenderer = table.getTableHeader().getDefaultRenderer(); 
+            }
+            
+            Object headerValue = tableColumn.getHeaderValue();
+            Component headerComponent = headerRenderer.getTableCellRendererComponent(table, headerValue, false, false, 0, column);
+            maxWidth = Math.max(maxWidth, headerComponent.getPreferredSize().width);
+            
+            tableColumn.setPreferredWidth(maxWidth);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ThermostatTableRenderer.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,68 @@
+/*
+ * 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.Component;
+
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableCellRenderer;
+
+import com.redhat.thermostat.client.ui.Palette;
+
+@SuppressWarnings("serial")
+public class ThermostatTableRenderer extends DefaultTableCellRenderer {
+
+    @Override
+    public Component getTableCellRendererComponent(JTable table, Object value,
+            boolean isSelected, boolean hasFocus, int row, int column) {
+
+        Component result = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+        if (result == null || isSelected) {
+            // do nothing
+        } else if (!isEven(row)) {
+            result.setBackground(Palette.LIGHT_GRAY.getColor());
+        } else {
+            result.setBackground(Palette.WHITE.getColor());
+        }
+        
+        return result;
+    }
+
+    private boolean isEven(int row) {
+        return row % 2 == 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ToolbarButton.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,43 @@
+/*
+ * 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 javax.swing.AbstractButton;
+
+public interface ToolbarButton {
+    AbstractButton getToolbarButton();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ValueField.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,58 @@
+/*
+ * 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 javax.swing.JEditorPane;
+import javax.swing.UIManager;
+
+/**
+ * A custom swing component meant for showing values. Use it like you would use
+ * any other JTextComponent.
+ */
+public class ValueField extends JEditorPane {
+
+    public ValueField(String text) {
+        setText(text);
+        setBorder(null);
+        setOpaque(false);
+        setBackground(UIManager.getColor("Label.background"));
+        setForeground(UIManager.getColor("Label.foreground"));
+        setFont(UIManager.getFont("Label.font"));
+        setEditable(false);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/models/LongRange.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,60 @@
+/*
+ * 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.models;
+
+public class LongRange {
+
+    long min;
+    long max;
+    
+    public void setMax(long max) {
+        this.max = max;
+    }
+    
+    public long getMax() {
+        return max;
+    }
+    
+    public void setMin(long min) {
+        this.min = min;
+    }
+    
+    
+    public long getMin() {
+        return min;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/models/LongRangeNormalizer.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,81 @@
+/*
+ * 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.models;
+
+public class LongRangeNormalizer {
+
+    private long minNormalized;
+    
+    private long maxNormalized;
+ 
+    private long value;
+
+    private LongRange range;
+    
+    public LongRangeNormalizer(LongRange range) {
+        this.range = range;
+    }
+
+    public void setMaxNormalized(long maxNormalized) {
+        this.maxNormalized = maxNormalized;
+    }
+    
+    public void setMinNormalized(long minNormalized) {
+        this.minNormalized = minNormalized;
+    }
+    
+    public long getValue() {
+        return value;
+    }
+
+    public void setValue(long newValue) {
+        this.value = newValue;
+    }
+    
+    public long getMaxNormalized() {
+        return maxNormalized;
+    }
+    
+    public long getMinNormalized() {
+        return minNormalized;
+    }
+    
+    public long getValueNormalized() {
+        double normalized = ((value - range.min) * (double)(maxNormalized - minNormalized)/(range.max - range.min)) + minNormalized;
+        return Math.round(normalized);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/models/NullSelectionModel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,132 @@
+/*
+ * 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.models;
+
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ListSelectionListener;
+
+public class NullSelectionModel implements ListSelectionModel {
+
+    @Override
+    public void setSelectionInterval(int index0, int index1) {
+    }
+
+    @Override
+    public void addSelectionInterval(int index0, int index1) {
+    }
+
+    @Override
+    public void removeSelectionInterval(int index0, int index1) {        
+    }
+
+    @Override
+    public int getMinSelectionIndex() {
+        return 0;
+    }
+
+    @Override
+    public int getMaxSelectionIndex() {
+        return 0;
+    }
+
+    @Override
+    public boolean isSelectedIndex(int index) {
+        return false;
+    }
+
+    @Override
+    public int getAnchorSelectionIndex() {
+        return 0;
+    }
+
+    @Override
+    public void setAnchorSelectionIndex(int index) {        
+    }
+
+    @Override
+    public int getLeadSelectionIndex() {
+        return -1;
+    }
+
+    @Override
+    public void setLeadSelectionIndex(int index) {
+    }
+
+    @Override
+    public void clearSelection() {
+    }
+
+    @Override
+    public boolean isSelectionEmpty() {
+        return true;
+    }
+
+    @Override
+    public void insertIndexInterval(int index, int length, boolean before) {
+    }
+
+    @Override
+    public void removeIndexInterval(int index0, int index1) {
+    }
+
+    @Override
+    public void setValueIsAdjusting(boolean valueIsAdjusting) {
+    }
+
+    @Override
+    public boolean getValueIsAdjusting() {
+        return false;
+    }
+
+    @Override
+    public void setSelectionMode(int selectionMode) {
+    }
+
+    @Override
+    public int getSelectionMode() {
+        return -1;
+    }
+
+    @Override
+    public void addListSelectionListener(ListSelectionListener x) {        
+    }
+
+    @Override
+    public void removeListSelectionListener(ListSelectionListener x) {
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/AboutDialog.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,287 @@
+/*
+ * 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 java.awt.Cursor;
+import java.awt.Desktop;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.net.URI;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.GroupLayout;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.LayoutStyle.ComponentPlacement;
+import javax.swing.SwingConstants;
+import javax.swing.SwingWorker;
+import javax.swing.border.TitledBorder;
+
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.swing.IconResource;
+import com.redhat.thermostat.client.swing.UIResources;
+import com.redhat.thermostat.common.ApplicationInfo;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+
+public class AboutDialog extends JDialog {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+    private static final long serialVersionUID = -7611616871710076514L;
+
+    private static final Logger logger = LoggingUtils.getLogger(AboutDialog.class);
+
+    private String name;
+    private String description;
+    private String version;
+    private Icon icon;
+    private String copyright;
+    private String license;
+    private String website;
+    private String email;
+    
+    /**
+     * Create the dialog.
+     * @param applicationInfo 
+     */
+    public AboutDialog(ApplicationInfo appInfo) {
+        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+        setResizable(false);
+        
+        name = appInfo.getName();
+        description = appInfo.getDescription();
+        version = appInfo.getVersion().getVersionNumber();
+        icon = IconResource.QUESTION.getIcon();
+        copyright = appInfo.getCopyright();
+        license = appInfo.getLicenseSummary();
+        website = appInfo.getWebsite();
+        email = appInfo.getEmail();
+        
+        initComponents();
+    }
+    
+    private void initComponents() {
+        setBounds(100, 100, 450, 338);
+        
+        UIResources res = UIResources.getInstance();
+        
+        JPanel panel = new JPanel();
+        panel.setBorder(new TitledBorder(""));
+        
+        JButton closeButton = new JButton(translator.localize(LocaleResources.BUTTON_CLOSE));
+        closeButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                AboutDialog.this.setVisible(false);
+                AboutDialog.this.dispose();  
+            }
+        });
+        
+        GroupLayout groupLayout = new GroupLayout(getContentPane());
+        groupLayout.setHorizontalGroup(
+            groupLayout.createParallelGroup(Alignment.TRAILING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
+                        .addComponent(closeButton, GroupLayout.PREFERRED_SIZE, 92, GroupLayout.PREFERRED_SIZE)
+                        .addComponent(panel, GroupLayout.DEFAULT_SIZE, 424, Short.MAX_VALUE))
+                    .addContainerGap())
+        );
+        groupLayout.setVerticalGroup(
+            groupLayout.createParallelGroup(Alignment.LEADING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addComponent(panel, GroupLayout.DEFAULT_SIZE, 245, Short.MAX_VALUE)
+                    .addGap(18)
+                    .addComponent(closeButton)
+                    .addGap(9))
+        );
+        
+        JLabel iconLabel = new JLabel("");
+        iconLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        
+        iconLabel.setIcon(icon);
+        
+        JLabel versionLabel = new JLabel(version);
+        versionLabel.setFont(res.footerFont());
+        versionLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        
+        JLabel nameLabel = new JLabel(name);
+        nameLabel.setFont(res.headerFont());
+        nameLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        
+        JLabel descriptionLabel = new JLabel(description);
+        descriptionLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        descriptionLabel.setFont(res.standardFont());
+        
+        JLabel homePageLabel = new JLabel(website);
+        homePageLabel.setForeground(res.hyperlinkColor());
+        homePageLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        homePageLabel.setFont(res.footerFont());        
+        homePageLabel.addMouseListener(new Browse(homePageLabel));
+
+        JLabel copyrightLabel = new JLabel(copyright);
+        copyrightLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        copyrightLabel.setFont(res.footerFont());
+        
+        JLabel licenseString = new JLabel(license);
+        licenseString.setHorizontalAlignment(SwingConstants.CENTER);
+        licenseString.setFont(res.footerFont());
+        
+        JLabel emailLabel = new JLabel(email);
+        emailLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        emailLabel.setForeground(res.hyperlinkColor());
+        emailLabel.setFont(res.footerFont());
+        emailLabel.addMouseListener(new Mailer(emailLabel));
+        
+        GroupLayout gl_panel = new GroupLayout(panel);
+        gl_panel.setHorizontalGroup(
+            gl_panel.createParallelGroup(Alignment.TRAILING)
+                .addGroup(gl_panel.createSequentialGroup()
+                    .addContainerGap()
+                    .addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
+                        .addComponent(iconLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(nameLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(versionLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(descriptionLabel, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(copyrightLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(licenseString, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(emailLabel, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(homePageLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE))
+                    .addContainerGap())
+        );
+        gl_panel.setVerticalGroup(
+            gl_panel.createParallelGroup(Alignment.LEADING)
+                .addGroup(gl_panel.createSequentialGroup()
+                    .addContainerGap()
+                    .addComponent(iconLabel)
+                    .addGap(4)
+                    .addComponent(nameLabel, GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addComponent(versionLabel, GroupLayout.DEFAULT_SIZE, 13, Short.MAX_VALUE)
+                    .addPreferredGap(ComponentPlacement.UNRELATED)
+                    .addComponent(descriptionLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .addGap(12)
+                    .addComponent(homePageLabel, GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE)
+                    .addGap(3)
+                    .addComponent(emailLabel, GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addComponent(copyrightLabel, GroupLayout.DEFAULT_SIZE, 13, Short.MAX_VALUE)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addComponent(licenseString, GroupLayout.DEFAULT_SIZE, 13, Short.MAX_VALUE)
+                    .addContainerGap())
+        );
+        panel.setLayout(gl_panel);
+        getContentPane().setLayout(groupLayout);
+    }
+    
+    private abstract class HyperLinkAction extends MouseAdapter {
+        
+        private JLabel hyperLinkLabel;
+        public HyperLinkAction(JLabel hyperLinkLabel) {
+            this.hyperLinkLabel = hyperLinkLabel;
+        }
+        
+        @Override
+        public void mouseEntered(MouseEvent e) {
+            hyperLinkLabel.setForeground(UIResources.getInstance().hyperlinkActiveColor());
+            Cursor cursor = new Cursor(Cursor.HAND_CURSOR);
+            setCursor(cursor);
+        }
+        @Override
+        public void mouseExited(MouseEvent e) {
+            hyperLinkLabel.setForeground(UIResources.getInstance().hyperlinkColor());
+            Cursor cursor = new Cursor(Cursor.DEFAULT_CURSOR);
+            setCursor(cursor);
+        }
+        
+        @Override
+        public void mouseClicked(MouseEvent e) {
+            if (Desktop.isDesktopSupported()) {
+                new SwingWorker<Void, Void>() {
+                    @Override
+                    protected Void doInBackground() throws Exception {
+                        doAction();
+                        return null;
+                    }
+                    @Override
+                    protected void done() {
+                        hyperLinkLabel.setForeground(UIResources.getInstance().hyperlinkColor());
+                    }
+                }.execute();
+            }
+        }
+        
+        protected abstract void doAction();
+    }
+    
+    private class Mailer extends HyperLinkAction {
+        public Mailer(JLabel hyperLinkLabel) {
+            super(hyperLinkLabel);
+        }
+
+        @Override
+        protected void doAction() {
+            try {
+                Desktop.getDesktop().mail(new URI("mailto:" + email));
+            } catch (Exception ex) {
+                logger.log(Level.WARNING, "Cannot send mail to Thermosat mail", ex);
+            }
+        }
+    }
+    
+    private class Browse extends HyperLinkAction {
+        public Browse(JLabel hyperLinkLabel) {
+            super(hyperLinkLabel);
+        }
+        
+        @Override
+        protected void doAction() {
+            try {
+                Desktop.getDesktop().browse(new URI(website));
+            } catch (Exception ex) {
+                logger.log(Level.WARNING, "Cannot open Thermostat website URL", ex);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/ChangeableText.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,81 @@
+/*
+ * 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 java.util.HashSet;
+import java.util.Set;
+
+public class ChangeableText {
+
+    private final Set<TextListener> listeners = new HashSet<TextListener>();
+    private String text;
+
+    public static interface TextListener {
+        public void textChanged(ChangeableText text);
+    }
+
+    public ChangeableText(String text) {
+        this.text = text;
+    }
+
+    public synchronized void setText(String text) {
+        if (this.text.equals(text)) {
+            return;
+        }
+        this.text = text;
+        fireChanged();
+    }
+
+    public synchronized String getText() {
+        return text;
+    }
+
+    public synchronized void addListener(TextListener listener) {
+        this.listeners.add(listener);
+    }
+
+    public synchronized void removeListener(TextListener listener) {
+        this.listeners.remove(listener);
+    }
+
+    private void fireChanged() {
+        for (TextListener listener: listeners) {
+            listener.textChanged(this);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/GUIClientCommand.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,87 @@
+/*
+ * 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 org.osgi.framework.BundleContext;
+
+import com.redhat.thermostat.client.osgi.service.ApplicationService;
+import com.redhat.thermostat.client.osgi.service.ContextAction;
+import com.redhat.thermostat.client.swing.internal.osgi.ApplicationServiceProvider;
+import com.redhat.thermostat.client.swing.internal.osgi.ContextActionServiceProvider;
+import com.redhat.thermostat.common.cli.CommandContext;
+import com.redhat.thermostat.common.cli.CommandException;
+import com.redhat.thermostat.common.cli.OSGiContext;
+import com.redhat.thermostat.common.cli.SimpleCommand;
+
+public class GUIClientCommand extends SimpleCommand implements OSGiContext {
+
+    private BundleContext context;
+    private Main clientMain;
+
+    public GUIClientCommand(Main clientMain) {
+        this.clientMain = clientMain;
+    }
+
+    @Override
+    public void setBundleContext(BundleContext context) {
+        this.context = context;
+    }
+    
+    @Override
+    public void run(CommandContext ctx) throws CommandException {
+        ApplicationService service = new ApplicationServiceProvider();
+        
+        context.registerService(ApplicationService.class.getName(), service, null);
+        context.registerService(ContextAction.class.getName(), new ContextActionServiceProvider(), null);
+        
+        // this blocks, everything else needs to be done before
+        clientMain.run();
+
+        service.getApplicationExecutor().shutdown();
+    }
+
+    @Override
+    public String getName() {
+        return "gui";
+    }
+
+    @Override
+    public boolean isStorageRequired() {
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/HostFilterRegistry.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,53 @@
+/*
+ * 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 org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.core.HostFilter;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+
+class HostFilterRegistry extends ThermostatExtensionRegistry<HostFilter> {
+
+    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + HostFilter.class.getName() + ")";
+
+    public HostFilterRegistry(BundleContext context) throws InvalidSyntaxException {
+        super(context, FILTER, HostFilter.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/HostIconDecorator.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,105 @@
+/*
+ * 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 java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+import com.redhat.thermostat.client.core.HostFilter;
+import com.redhat.thermostat.client.osgi.service.HostDecorator;
+import com.redhat.thermostat.client.swing.IconResource;
+import com.redhat.thermostat.client.ui.Decorator;
+import com.redhat.thermostat.client.ui.IconDescriptor;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.utils.StreamUtils;
+
+public class HostIconDecorator implements HostDecorator {
+
+    private final HostFilter anyHost = new AnyHostMatcher();
+
+    @Override
+    public Decorator getDecorator() {
+        return new IconDecorator();
+    }
+
+    @Override
+    public HostFilter getFilter() {
+        return anyHost;
+    }
+
+    private static class IconDecorator implements Decorator {
+
+        private final IconDescriptor icon;
+
+        public IconDecorator() {
+            IconDescriptor icon = null;
+            try {
+                InputStream in = new FileInputStream(IconResource.HOST.getPath());
+                icon = new IconDescriptor(ByteBuffer.wrap(StreamUtils.readAll(in)));
+            } catch (IOException ioe) {
+                ioe.printStackTrace();
+            }
+            this.icon = icon;
+        }
+
+        @Override
+        public String getLabel(String originalLabel) {
+            return originalLabel;
+        }
+
+        @Override
+        public IconDescriptor getIconDescriptor() {
+            return icon;
+        }
+
+        @Override
+        public Quadrant getQuadrant() {
+            return Quadrant.MAIN;
+        }
+
+    }
+
+    private static class AnyHostMatcher implements HostFilter {
+        @Override
+        public boolean matches(HostRef toMatch) {
+            return true;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/HostTreeDecoratorRegistry.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,53 @@
+/*
+ * 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 org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.osgi.service.HostDecorator;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+
+class HostTreeDecoratorRegistry extends ThermostatExtensionRegistry<HostDecorator> {
+
+    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + HostDecorator.class.getName() + ")";
+
+    public HostTreeDecoratorRegistry(BundleContext context) throws InvalidSyntaxException {
+        super(context, FILTER, HostDecorator.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/Main.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,329 @@
+/*
+ * 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 java.awt.EventQueue;
+import java.util.concurrent.ExecutorService;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.JOptionPane;
+import javax.swing.JPopupMenu;
+import javax.swing.SwingConstants;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+import com.redhat.swing.laf.dolphin.DolphinLookAndFeel;
+import com.redhat.thermostat.client.core.views.ClientConfigurationView;
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.osgi.service.ApplicationService;
+import com.redhat.thermostat.client.swing.internal.config.ConnectionConfiguration;
+import com.redhat.thermostat.client.swing.views.ClientConfigurationSwing;
+import com.redhat.thermostat.client.ui.ClientConfigurationController;
+import com.redhat.thermostat.client.ui.MainWindowController;
+import com.redhat.thermostat.client.ui.UiFacadeFactory;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.Constants;
+import com.redhat.thermostat.common.ThreadPoolTimerFactory;
+import com.redhat.thermostat.common.TimerFactory;
+import com.redhat.thermostat.common.appctx.ApplicationContext;
+import com.redhat.thermostat.common.config.ClientPreferences;
+import com.redhat.thermostat.common.config.StartupConfiguration;
+import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.dao.MongoDAOFactory;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.common.storage.Connection;
+import com.redhat.thermostat.common.storage.Connection.ConnectionListener;
+import com.redhat.thermostat.common.storage.Connection.ConnectionStatus;
+import com.redhat.thermostat.common.storage.Connection.ConnectionType;
+import com.redhat.thermostat.common.storage.MongoStorageProvider;
+import com.redhat.thermostat.common.storage.StorageProvider;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.common.utils.OSGIUtils;
+import com.redhat.thermostat.utils.keyring.Keyring;
+
+public class Main {
+    
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private static final Logger logger = LoggingUtils.getLogger(Main.class);
+
+    private OSGIUtils serviceProvider;
+    private UiFacadeFactory uiFacadeFactory;
+    private DAOFactory daoFactory;
+    
+    public Main(Keyring keyring, UiFacadeFactory uiFacadeFactory, String[] args) {
+        ClientPreferences prefs = new ClientPreferences(keyring);
+        StartupConfiguration config = new ConnectionConfiguration(prefs);
+        StorageProvider connProv = new MongoStorageProvider(config);
+
+        DAOFactory daoFactory = new MongoDAOFactory(connProv);
+        TimerFactory timerFactory = new ThreadPoolTimerFactory(1);
+
+        init(OSGIUtils.getInstance(), uiFacadeFactory, daoFactory, timerFactory);
+    }
+
+    Main(OSGIUtils serviceProvider, UiFacadeFactory uiFacadeFactory, DAOFactory daoFactory, TimerFactory timerFactory) {
+        init(serviceProvider, uiFacadeFactory, daoFactory, timerFactory);
+    }
+
+    private void init(OSGIUtils serviceProvider, UiFacadeFactory uiFacadeFactory, DAOFactory daoFactory, TimerFactory timerFactory) {
+        this.serviceProvider = serviceProvider;
+        this.uiFacadeFactory = uiFacadeFactory;
+        this.daoFactory = daoFactory;
+        ApplicationContext.getInstance().setTimerFactory(timerFactory);
+    }
+
+    public void run() {
+        EventQueue.invokeLater(new Runnable() {
+
+            @Override
+            public void run() {
+
+                // check if the user has other preferences...
+                // not that there is any reason!
+                String laf = System.getProperty("swing.defaultlaf");
+                if (laf == null) {
+                    try {
+                        UIManager.setLookAndFeel(new DolphinLookAndFeel());
+                    } catch (UnsupportedLookAndFeelException e) {
+                        logger.log(Level.WARNING, "cannot use DolphinLookAndFeel");
+                    }
+                }
+
+                // TODO: move them in an appropriate place
+                JPopupMenu.setDefaultLightWeightPopupEnabled(false);
+                UIManager.getDefaults().put("OptionPane.buttonOrientation", SwingConstants.RIGHT);
+                UIManager.getDefaults().put("OptionPane.isYesLast", true);
+                UIManager.getDefaults().put("OptionPane.sameSizeButtons", true);
+                
+                showGui();
+            }
+
+        });
+
+        try {
+            uiFacadeFactory.awaitShutdown();
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    private void showGui() {
+        ApplicationService appSrv = serviceProvider.getService(ApplicationService.class);
+        final ExecutorService service = appSrv.getApplicationExecutor();
+        service.execute(new ConnectorSetup(service));
+    }
+    
+    private class ConnectorSetup implements Runnable {
+        
+        private ExecutorService service;
+        public ConnectorSetup(ExecutorService service) {
+            this.service = service;
+        }
+        
+        @Override
+        public void run() {
+            
+            Connection connection = daoFactory.getConnection();
+            connection.setType(ConnectionType.LOCAL);
+            ConnectionListener connectionListener = new ConnectionHandler(connection, service);
+            connection.addListener(connectionListener);
+            try {
+                connection.connect();
+            } catch (Throwable t) {
+                logger.log(Level.WARNING, "connection attempt failed: ", t);
+            }
+        }
+    }
+    
+    private class Connector implements Runnable {
+        private Connection connection;
+        Connector(Connection connection) {
+            this.connection = connection;
+        }
+        
+        @Override
+        public void run() {
+            try {
+                connection.connect();
+            } catch (Throwable t) {
+                logger.log(Level.WARNING, "connection attempt failed: ", t);
+            }
+        }
+    }
+    
+    private class ConnectionAttemp implements Runnable {
+        private Connection connection;
+        private ExecutorService service;
+        public ConnectionAttemp(Connection connection, ExecutorService service) {
+            this.connection = connection;
+            this.service = service;
+        }
+        
+        @Override
+        public void run() {
+            Object[] options = {
+                    translator.localize(LocaleResources.CONNECTION_WIZARD),
+                    translator.localize(LocaleResources.CONNECTION_QUIT),
+            };
+            int n = JOptionPane
+                    .showOptionDialog(
+                            null,
+                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_DESCRIPTION),
+                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_TITLE),
+                            JOptionPane.OK_CANCEL_OPTION,
+                            JOptionPane.ERROR_MESSAGE, null, options,
+                            options[0]);
+
+            switch (n) {
+
+            case JOptionPane.CANCEL_OPTION:
+            case JOptionPane.CLOSED_OPTION:
+            case JOptionPane.NO_OPTION:
+                uiFacadeFactory
+                        .shutdown(Constants.EXIT_UNABLE_TO_CONNECT_TO_DATABASE);
+                break;
+
+            case JOptionPane.YES_OPTION:
+            default:
+                createPreferencesDialog(connection, service);
+                break;
+            }
+        }
+    }
+    
+    private void connect(Connection connection, ExecutorService service) {
+        service.execute(new Connector(connection));
+    }
+    
+    private class ConfigDialogListener implements ActionListener<ClientConfigurationView.Action> {
+        private Connection connection;
+        private ExecutorService service;
+        public ConfigDialogListener(Connection connection, ExecutorService service) {
+            this.connection = connection;
+            this.service = service;
+        }
+        
+        @Override
+        public void actionPerformed(ActionEvent<ClientConfigurationView.Action> actionEvent) {
+            switch (actionEvent.getActionId()) {
+            case CLOSE_CANCEL:
+                uiFacadeFactory.shutdown(Constants.EXIT_UNABLE_TO_CONNECT_TO_DATABASE);
+                break;
+            
+            case CLOSE_ACCEPT:
+            default:
+                connect(connection, service);
+                break;
+            }
+        }
+    }
+    
+    private void createPreferencesDialog(final Connection connection, final ExecutorService service) {
+
+        ClientPreferences prefs = new ClientPreferences(OSGIUtils.getInstance().getService(Keyring.class));
+        ClientConfigurationView configDialog = new ClientConfigurationSwing();
+        ClientConfigurationController controller =
+                new ClientConfigurationController(prefs, configDialog);
+        
+        configDialog.addListener(new ConfigDialogListener(connection, service));
+        controller.showDialog();
+    }
+    
+    private class ConnectionHandler implements ConnectionListener {
+        private boolean retry;
+        private Connection connection;
+        private ExecutorService service;
+        public ConnectionHandler(Connection connection, ExecutorService service) {
+            this.connection = connection;
+            this.retry = true;
+            this.service = service;
+        }
+        
+        private void showConnectionAttemptWarning() {
+            SwingUtilities.invokeLater(new ConnectionAttemp(connection, service));
+        }
+        
+        @Override
+        public void changed(ConnectionStatus newStatus) {
+            if (newStatus == ConnectionStatus.CONNECTED) {
+                
+                // register the storage, so other services can request it
+                daoFactory.registerDAOsAndStorageAsOSGiServices();
+                uiFacadeFactory.setHostInfoDao(daoFactory.getHostInfoDAO());
+                uiFacadeFactory.setCpuStatDao(daoFactory.getCpuStatDAO());
+                uiFacadeFactory.setMemoryStatDao(daoFactory.getMemoryStatDAO());
+                uiFacadeFactory.setNetworkInfoDao(daoFactory.getNetworkInterfaceInfoDAO());
+
+                uiFacadeFactory.setVmInfoDao(daoFactory.getVmInfoDAO());
+                uiFacadeFactory.setVmCpuStatDao(daoFactory.getVmCpuStatDAO());
+                uiFacadeFactory.setVmMemoryStatDao(daoFactory.getVmMemoryStatDAO());
+                uiFacadeFactory.setVmGcStatDao(daoFactory.getVmGcStatDAO());
+
+                showMainWindow();
+            } else if (newStatus == ConnectionStatus.FAILED_TO_CONNECT) {
+                if (retry) {
+                    retry = false;
+                    showConnectionAttemptWarning();
+                } else {
+                    JOptionPane.showMessageDialog(
+                            null,
+                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_DESCRIPTION),
+                            translator.localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_TITLE),
+                            JOptionPane.ERROR_MESSAGE);
+                    uiFacadeFactory.shutdown(Constants.EXIT_UNABLE_TO_CONNECT_TO_DATABASE);
+                }
+            }
+        }
+    }
+
+
+    private void showMainWindow() {
+        SwingUtilities.invokeLater(new ShowMainWindow());
+    }
+    
+    private class ShowMainWindow implements Runnable {
+        @Override
+        public void run() {
+            MainWindowController mainController = uiFacadeFactory.getMainWindow();
+            mainController.showMainMainWindow();                        
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainView.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,102 @@
+/*
+ * 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 java.awt.event.MouseEvent;
+import java.util.List;
+
+import com.redhat.thermostat.client.core.HostFilter;
+import com.redhat.thermostat.client.core.VmFilter;
+import com.redhat.thermostat.client.core.views.BasicView;
+import com.redhat.thermostat.client.osgi.service.HostDecorator;
+import com.redhat.thermostat.client.osgi.service.MenuAction;
+import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.osgi.service.VmDecorator;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.HostsVMsLoader;
+import com.redhat.thermostat.common.dao.Ref;
+
+public interface MainView {
+
+    enum Action {
+        VISIBLE,
+        HIDDEN,
+        HOST_VM_TREE_FILTER,
+        HOST_VM_SELECTION_CHANGED,
+        SHOW_AGENT_CONFIG,
+        SHOW_CLIENT_CONFIG,
+        SWITCH_HISTORY_MODE,
+        SHOW_ABOUT_DIALOG,
+        SHUTDOWN,
+        SHOW_VM_CONTEXT_MENU,
+        VM_CONTEXT_ACTION,
+    }
+
+    void addActionListener(ActionListener<Action> capture);
+
+    void updateTree(List<HostFilter> hostFilters, List<VmFilter> vmFilters,
+            List<HostDecorator> hostDecorators, List<VmDecorator> vmDecorators,
+            HostsVMsLoader any);
+
+    String getHostVmTreeFilterText();
+    
+    void setWindowTitle(String title);
+
+    void showMainWindow();
+
+    void hideMainWindow();
+
+    Ref getSelectedHostOrVm();
+
+    void setSubView(BasicView view);
+
+    void setStatusBarPrimaryStatus(String primaryStatus);
+    
+    /**
+     * Adds a menu item to the window. Assumes the menu path is valid (has a
+     * non-zero length) and doesn't collide with existing menus.
+     */
+    void addMenu(MenuAction action);
+
+    /**
+     * Removes a menu item to the window. Assumes the menu path is valid (has a
+     * non-zero length) and doesn't collide with existing menus.
+     */
+    void removeMenu(MenuAction action);
+
+    void showVMContextActions(List<VMContextAction> actions, MouseEvent e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImpl.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,511 @@
+/*
+ * 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 java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.core.HostFilter;
+import com.redhat.thermostat.client.core.VmFilter;
+import com.redhat.thermostat.client.core.views.AgentInformationDisplayView;
+import com.redhat.thermostat.client.core.views.AgentInformationViewProvider;
+import com.redhat.thermostat.client.core.views.ClientConfigViewProvider;
+import com.redhat.thermostat.client.core.views.ClientConfigurationView;
+import com.redhat.thermostat.client.osgi.service.HostDecorator;
+import com.redhat.thermostat.client.osgi.service.MenuAction;
+import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.osgi.service.VmDecorator;
+import com.redhat.thermostat.client.swing.internal.MainView.Action;
+import com.redhat.thermostat.client.ui.AgentInformationDisplayController;
+import com.redhat.thermostat.client.ui.AgentInformationDisplayModel;
+import com.redhat.thermostat.client.ui.ClientConfigurationController;
+import com.redhat.thermostat.client.ui.HostInformationController;
+import com.redhat.thermostat.client.ui.HostVmFilter;
+import com.redhat.thermostat.client.ui.MainWindowController;
+import com.redhat.thermostat.client.ui.SummaryController;
+import com.redhat.thermostat.client.ui.UiFacadeFactory;
+import com.redhat.thermostat.client.ui.VmInformationController;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.ApplicationInfo;
+import com.redhat.thermostat.common.DefaultHostsVMsLoader;
+import com.redhat.thermostat.common.HostsVMsLoader;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+import com.redhat.thermostat.common.Timer;
+import com.redhat.thermostat.common.Timer.SchedulingType;
+import com.redhat.thermostat.common.appctx.ApplicationContext;
+import com.redhat.thermostat.common.config.ClientPreferences;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.Ref;
+import com.redhat.thermostat.common.dao.VmInfoDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.common.utils.OSGIUtils;
+import com.redhat.thermostat.utils.keyring.Keyring;
+
+public class MainWindowControllerImpl implements MainWindowController {
+
+    private static final Logger logger = LoggingUtils.getLogger(MainWindowControllerImpl.class);
+
+    private final CopyOnWriteArrayList<HostFilter> hostFilters = new CopyOnWriteArrayList<>();
+    private final CopyOnWriteArrayList<VmFilter> vmFilters = new CopyOnWriteArrayList<>();
+
+    private final CopyOnWriteArrayList<HostDecorator> hostTreeDecorators = new CopyOnWriteArrayList<>();
+    private final CopyOnWriteArrayList<VmDecorator> vmTreeDecorators = new CopyOnWriteArrayList<>();
+
+    private Timer backgroundUpdater;
+
+    private MainView view;
+
+    private final HostInfoDAO hostsDAO;
+    private final VmInfoDAO vmsDAO;
+
+    private ApplicationInfo appInfo;
+
+    private UiFacadeFactory facadeFactory;
+
+    private MenuRegistry menuRegistry;
+    private ActionListener<ThermostatExtensionRegistry.Action> menuListener =
+            new ActionListener<ThermostatExtensionRegistry.Action>()
+    {
+        @Override
+        public void actionPerformed(
+            ActionEvent<ThermostatExtensionRegistry.Action> actionEvent) {
+            MenuAction action = (MenuAction) actionEvent.getPayload();
+
+            switch (actionEvent.getActionId()) {
+            case SERVICE_ADDED:
+                view.addMenu(action);
+                break;
+
+            case SERVICE_REMOVED:
+                view.removeMenu(action);
+                break;
+
+            default:
+                logger.log(Level.WARNING, "received unknown event from MenuRegistry: " +
+                                           actionEvent.getActionId());
+                break;
+            }
+        }
+    };
+
+    private HostVmFilter searchFilter;
+    private VmFilterRegistry vmFilterRegistry;
+    private HostFilterRegistry hostFilterRegistry;
+
+    private ActionListener<ThermostatExtensionRegistry.Action> hostFilterListener = new UpdateListAndTree<>(HostFilter.class, hostFilters);
+    private ActionListener<ThermostatExtensionRegistry.Action> vmFilterListener = new UpdateListAndTree<>(VmFilter.class, vmFilters);
+
+    private HostTreeDecoratorRegistry hostDecoratorRegistry;
+    private VMTreeDecoratorRegistry vmDecoratorRegistry;
+
+    private ActionListener<ThermostatExtensionRegistry.Action> hostDecoratorListener = new UpdateListAndTree<>(HostDecorator.class, hostTreeDecorators);
+    private ActionListener<ThermostatExtensionRegistry.Action> vmDecoratorListener = new UpdateListAndTree<>(VmDecorator.class, vmTreeDecorators);
+
+    private VMInformationRegistry vmInfoRegistry;
+    private ActionListener<ThermostatExtensionRegistry.Action> vmInfoRegistryListener =
+            new ActionListener<ThermostatExtensionRegistry.Action> ()
+    {
+        public void actionPerformed(com.redhat.thermostat.common.ActionEvent<ThermostatExtensionRegistry.Action>
+                                    actionEvent)
+        {
+            updateView();
+        };
+    };
+            
+    private boolean showHistory;
+
+    private VmInformationControllerProvider vmInfoControllerProvider;
+
+    public MainWindowControllerImpl(UiFacadeFactory facadeFactory, MainView view, RegistryFactory registryFactory, HostInfoDAO hostsDao, VmInfoDAO vmsDAO)
+    {
+        try {
+            vmFilterRegistry = registryFactory.createVmFilterRegistry();
+            hostFilterRegistry = registryFactory.createHostFilterRegistry();
+            hostDecoratorRegistry = registryFactory.createHostTreeDecoratorRegistry();
+            vmDecoratorRegistry = registryFactory.createVMTreeDecoratorRegistry();
+            menuRegistry = registryFactory.createMenuRegistry();
+            vmInfoRegistry = registryFactory.createVMInformationRegistry();
+            
+        } catch (InvalidSyntaxException e) {
+            throw new RuntimeException(e);
+        }
+
+        searchFilter = new HostVmFilter();
+        hostFilters.add(searchFilter);
+        vmFilters.add(searchFilter);
+        
+        this.facadeFactory = facadeFactory;
+
+        this.hostsDAO = hostsDao;
+        this.vmsDAO = vmsDAO;
+
+        initView(view);
+
+        vmInfoControllerProvider = new VmInformationControllerProvider();
+
+        appInfo = new ApplicationInfo();
+        view.setWindowTitle(appInfo.getName());
+        initializeTimer();
+
+        updateView();
+
+        installListenersAndStartRegistries();
+    }
+
+    /**
+     * This method is for testing purposes only
+     */
+    HostVmFilter getSearchFilter() {
+        return searchFilter;
+    }
+    
+    /**
+     * This method is for testing purposes only
+     */ 
+    List<VmDecorator> getVmTreeDecorators() {
+        return vmTreeDecorators;
+    }
+    
+    /**
+     * This method is for testing purposes only
+     */
+    ActionListener<ThermostatExtensionRegistry.Action> getMenuListener() {
+        return menuListener;
+    }
+    
+    private void initializeTimer() {
+        ApplicationContext ctx = ApplicationContext.getInstance();
+        backgroundUpdater = ctx.getTimerFactory().createTimer();
+        backgroundUpdater.setAction(new Runnable() {
+            @Override
+            public void run() {
+                doUpdateTreeAsync();
+            }
+        });
+        backgroundUpdater.setInitialDelay(0);
+        backgroundUpdater.setDelay(3);
+        backgroundUpdater.setTimeUnit(TimeUnit.SECONDS);
+        backgroundUpdater.setSchedulingType(SchedulingType.FIXED_RATE);
+    }
+
+    private void startBackgroundUpdates() {
+        backgroundUpdater.start();
+    }
+
+    public void stopBackgroundUpdates() {
+        backgroundUpdater.stop();
+    }
+
+    @Override
+    public void setHostVmTreeFilter(String filter) {
+        this.searchFilter.setFilter(filter);
+        doUpdateTreeAsync();
+    }
+
+    public void doUpdateTreeAsync() {
+        HostsVMsLoader loader = new DefaultHostsVMsLoader(hostsDAO, vmsDAO, !showHistory);
+        view.updateTree(hostFilters, vmFilters, hostTreeDecorators, vmTreeDecorators, loader);
+    }
+
+    private void initView(MainView mainView) {
+        this.view = mainView;
+        mainView.addActionListener(new ActionListener<MainView.Action>() {
+
+            @Override
+            public void actionPerformed(ActionEvent<MainView.Action> evt) {
+                MainView.Action action = evt.getActionId();
+                switch (action) {
+                case VISIBLE:
+                    startBackgroundUpdates();
+                    break;
+                case HIDDEN:
+                    stopBackgroundUpdates();
+                    break;
+                case HOST_VM_SELECTION_CHANGED:
+                    updateView();
+                    break;
+                case HOST_VM_TREE_FILTER:
+                    String filter = view.getHostVmTreeFilterText();
+                    setHostVmTreeFilter(filter);
+                    break;
+                case SHOW_AGENT_CONFIG:
+                    showAgentConfiguration();
+                    break;
+                case SHOW_CLIENT_CONFIG:
+                    showConfigureClientPreferences();
+                    break;
+                case SWITCH_HISTORY_MODE:
+                    switchHistoryMode();
+                    break;
+                case SHOW_ABOUT_DIALOG:
+                    showAboutDialog();
+                    break;
+                case SHOW_VM_CONTEXT_MENU:
+                    showContextMenu(evt);
+                    break;
+                case VM_CONTEXT_ACTION:
+                    handleVMHooks(evt);
+                    break;
+                case SHUTDOWN:
+                    shutdownApplication();
+                    break;
+                default:
+                    throw new IllegalStateException("unhandled action");
+                }
+            }
+
+        });
+    }
+
+    private void shutdownApplication() {
+        uninstallListenersAndStopRegistries();
+
+        view.hideMainWindow();
+        ApplicationContext.getInstance().getTimerFactory().shutdown();
+        shutdownOSGiFramework();
+    }
+
+    private void installListenersAndStartRegistries() {
+        menuRegistry.addActionListener(menuListener);
+        menuRegistry.start();
+
+        hostFilterRegistry.addActionListener(hostFilterListener);
+        hostFilterRegistry.start();
+
+        vmFilterRegistry.addActionListener(vmFilterListener);
+        vmFilterRegistry.start();
+
+        hostDecoratorRegistry.addActionListener(hostDecoratorListener);
+        hostDecoratorRegistry.start();
+
+        vmDecoratorRegistry.addActionListener(vmDecoratorListener);
+        vmDecoratorRegistry.start();
+
+        vmInfoRegistry.addActionListener(vmInfoRegistryListener);
+        vmInfoRegistry.start();
+    }
+
+    private void uninstallListenersAndStopRegistries() {
+        menuRegistry.removeActionListener(menuListener);
+        menuListener = null;
+        menuRegistry.stop();
+
+        hostFilterRegistry.removeActionListener(hostFilterListener);
+        hostFilterListener = null;
+        hostFilterRegistry.stop();
+
+        vmFilterRegistry.removeActionListener(vmFilterListener);
+        vmFilterListener = null;
+        vmFilterRegistry.stop();
+
+        hostDecoratorRegistry.removeActionListener(hostDecoratorListener);
+        hostDecoratorListener = null;
+        hostDecoratorRegistry.stop();
+
+        vmDecoratorRegistry.removeActionListener(vmDecoratorListener);
+        vmDecoratorListener = null;
+        vmDecoratorRegistry.stop();
+
+        vmInfoRegistry.removeActionListener(vmInfoRegistryListener);
+        vmInfoRegistryListener = null;
+        vmInfoRegistry.stop();
+    }
+
+    private void shutdownOSGiFramework() {
+        facadeFactory.shutdown();
+    }
+
+    private void showContextMenu(ActionEvent<Action> evt) {
+        List<VMContextAction> toShow = new ArrayList<>();
+        VmRef vm = (VmRef) view.getSelectedHostOrVm();
+
+        logger.log(Level.INFO, "registering applicable VMContextActions actions to show");
+
+        for (VMContextAction action : facadeFactory.getVMContextActions()) {
+            if (action.getFilter().matches(vm)) {
+                toShow.add(action);
+            }
+        }
+
+        view.showVMContextActions(toShow, (MouseEvent)evt.getPayload());
+    }
+
+    private void handleVMHooks(ActionEvent<MainView.Action> event) {
+        Object payload = event.getPayload();
+        if (payload instanceof VMContextAction) { 
+            try {
+                VMContextAction action = (VMContextAction) payload;
+                action.execute((VmRef) view.getSelectedHostOrVm());
+            } catch (Throwable error) {
+                logger.log(Level.SEVERE, "");
+            }
+        }
+    }
+    
+    @Override
+    public void showMainMainWindow() {
+        view.showMainWindow();
+    }
+
+    private void showAboutDialog() {
+        AboutDialog aboutDialog = new AboutDialog(appInfo);
+        aboutDialog.setModal(true);
+        aboutDialog.pack();
+        aboutDialog.setVisible(true);
+    }
+
+    private void showAgentConfiguration() {
+        AgentInformationDisplayModel model = new AgentInformationDisplayModel();
+        AgentInformationViewProvider viewProvider = OSGIUtils.getInstance().getService(AgentInformationViewProvider.class);
+        AgentInformationDisplayView view = viewProvider.createView();
+        AgentInformationDisplayController controller = new AgentInformationDisplayController(model, view);
+        controller.showView();
+    }
+
+    private void showConfigureClientPreferences() {
+        ClientPreferences prefs = new ClientPreferences(OSGIUtils.getInstance().getService(Keyring.class));
+        ClientConfigViewProvider viewProvider = OSGIUtils.getInstance().getService(ClientConfigViewProvider.class);
+        ClientConfigurationView view = viewProvider.createView();
+        ClientConfigurationController controller = new ClientConfigurationController(prefs, view);
+        controller.showDialog();
+    }
+
+    private void switchHistoryMode() {
+        showHistory = !showHistory;
+        doUpdateTreeAsync();
+    }
+
+    private void updateView() {
+        // this is quite an ugly method. there must be a cleaner way to do this
+        Ref ref = view.getSelectedHostOrVm();
+
+        if (ref == null) {
+            SummaryController controller = facadeFactory.getSummary();
+            view.setSubView(controller.getView());
+        } else if (ref instanceof HostRef) {
+            HostRef hostRef = (HostRef) ref;
+            HostInformationController hostController = facadeFactory.getHostController(hostRef);
+            view.setSubView(hostController.getView());
+            view.setStatusBarPrimaryStatus("host: " + hostRef.getHostName() + ", id: " + hostRef.getAgentId());
+        } else if (ref instanceof VmRef) {
+            VmRef vmRef = (VmRef) ref;
+            VmInformationController vmInformation =
+                    vmInfoControllerProvider.getVmInfoController(vmRef);
+            view.setSubView(vmInformation.getView());
+            view.setStatusBarPrimaryStatus("vm: " + vmRef.getName() + ", pid: " + vmRef.getStringID() +
+                                           ", host: " + vmRef.getAgent().getHostName());
+        } else {
+            throw new IllegalArgumentException("unknown type of ref");
+        }
+    }
+
+    private class UpdateListAndTree<T> implements ActionListener<ThermostatExtensionRegistry.Action> {
+
+        private final Class<T> extensionClass;
+        private final CopyOnWriteArrayList<T> extensionList;
+
+        public UpdateListAndTree(Class<T> extensionClass, CopyOnWriteArrayList<T> addRemoveExtensionsFrom) {
+            this.extensionClass = extensionClass;
+            this.extensionList = addRemoveExtensionsFrom;
+        }
+
+        @SuppressWarnings("unchecked")
+        @Override
+        public void actionPerformed(ActionEvent<com.redhat.thermostat.common.ThermostatExtensionRegistry.Action> actionEvent) {
+
+            Object payload = actionEvent.getPayload();
+            if (!extensionClass.isInstance(payload)) {
+                throw new IllegalArgumentException("unexpected payload type. expected a " + extensionClass.getName() + " but got " + payload.getClass().getName());
+            }
+
+            T filter = (T) payload;
+
+            switch (actionEvent.getActionId()) {
+            case SERVICE_ADDED:
+                extensionList.add(filter);
+                doUpdateTreeAsync();
+                break;
+
+            case SERVICE_REMOVED:
+                extensionList.remove(filter);
+                doUpdateTreeAsync();
+                break;
+
+            default:
+                logger.log(Level.WARNING, "received unknown event from ExtensionRegistry: " +
+                                           actionEvent.getActionId());
+                break;
+            }
+        }
+    }
+
+    private class VmInformationControllerProvider {
+        private VmInformationController lastSelectedVM;
+        private Map<VmRef, Integer> selectedForVM = new ConcurrentHashMap<>();
+        
+        VmInformationController getVmInfoController(VmRef vmRef) {
+            int id = 0;
+            if (lastSelectedVM != null) {
+                id = lastSelectedVM.getSelectedChildID();
+            }
+            
+            lastSelectedVM = facadeFactory.getVmController(vmRef);
+            if (!lastSelectedVM.selectChildID(id)) {
+                Integer _id = selectedForVM.get(vmRef);
+                id = _id != null? _id : 0;
+                lastSelectedVM.selectChildID(id);
+            }
+
+            selectedForVM.put(vmRef, id);
+            
+            return lastSelectedVM;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MenuRegistry.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,53 @@
+/*
+ * 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 org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.osgi.service.MenuAction;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+
+public class MenuRegistry extends ThermostatExtensionRegistry<MenuAction> {
+
+    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + MenuAction.class.getName() + ")";
+
+    public MenuRegistry(BundleContext context) throws InvalidSyntaxException {
+    	super(context, FILTER, MenuAction.class);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/RegistryFactory.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,72 @@
+/*
+ * 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 org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+
+class RegistryFactory {
+
+    private BundleContext context;
+    RegistryFactory(BundleContext context) {
+        this.context = context;
+    }
+
+    HostTreeDecoratorRegistry createHostTreeDecoratorRegistry() throws InvalidSyntaxException {
+        return new HostTreeDecoratorRegistry(context);
+    }
+    
+    VMTreeDecoratorRegistry createVMTreeDecoratorRegistry() throws InvalidSyntaxException {
+        return new VMTreeDecoratorRegistry(context);
+    }
+    
+    HostFilterRegistry createHostFilterRegistry() throws InvalidSyntaxException {
+        return new HostFilterRegistry(context);
+    }
+
+    VmFilterRegistry createVmFilterRegistry() throws InvalidSyntaxException {
+        return new VmFilterRegistry(context);
+    }
+    
+    MenuRegistry createMenuRegistry() throws InvalidSyntaxException {
+        return new MenuRegistry(context);
+    }
+    
+    VMInformationRegistry createVMInformationRegistry() throws InvalidSyntaxException {
+        return new VMInformationRegistry(context);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/UiFacadeFactoryImpl.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,199 @@
+/*
+ * 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 java.util.ArrayList;
+import java.util.Collection;
+import java.util.concurrent.CountDownLatch;
+
+import org.osgi.framework.BundleContext;
+
+import com.redhat.thermostat.client.core.VmInformationService;
+import com.redhat.thermostat.client.core.views.HostInformationViewProvider;
+import com.redhat.thermostat.client.core.views.SummaryViewProvider;
+import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
+import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.swing.MainWindow;
+import com.redhat.thermostat.client.ui.HostInformationController;
+import com.redhat.thermostat.client.ui.MainWindowController;
+import com.redhat.thermostat.client.ui.SummaryController;
+import com.redhat.thermostat.client.ui.UiFacadeFactory;
+import com.redhat.thermostat.client.ui.VmInformationController;
+import com.redhat.thermostat.common.dao.CpuStatDAO;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.MemoryStatDAO;
+import com.redhat.thermostat.common.dao.NetworkInterfaceInfoDAO;
+import com.redhat.thermostat.common.dao.VmCpuStatDAO;
+import com.redhat.thermostat.common.dao.VmGcStatDAO;
+import com.redhat.thermostat.common.dao.VmInfoDAO;
+import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.utils.OSGIUtils;
+
+public class UiFacadeFactoryImpl implements UiFacadeFactory {
+
+    private CountDownLatch shutdown = new CountDownLatch(1);
+
+    private Collection<VmInformationService> vmInformationServices = new ArrayList<>();
+    private Collection<VMContextAction> contextAction = new ArrayList<>();
+
+    private BundleContext context;
+
+    private HostInfoDAO hostInfoDao;
+    private CpuStatDAO cpuStatDao;
+    private MemoryStatDAO memoryStatDao;
+    private NetworkInterfaceInfoDAO networkInfoDao;
+
+    private VmInfoDAO vmInfoDao;
+    private VmCpuStatDAO vmCpuStatDao;
+    private VmMemoryStatDAO vmMemoryStatDao;
+    private VmGcStatDAO vmGcStatDao;
+
+    private OSGIUtils serviceProvider;
+    
+    UiFacadeFactoryImpl(OSGIUtils serviceProvider, BundleContext context) {
+        this.context = context;
+        this.serviceProvider = serviceProvider;
+    }
+    
+    public UiFacadeFactoryImpl(BundleContext context) {
+        this(OSGIUtils.getInstance(), context);
+    }
+
+    @Override
+    public void setHostInfoDao(HostInfoDAO hostInfoDao) {
+        this.hostInfoDao = hostInfoDao;
+    }
+
+    public void setCpuStatDao(CpuStatDAO cpuStatDao) {
+        this.cpuStatDao = cpuStatDao;
+    }
+
+    public void setMemoryStatDao(MemoryStatDAO memoryStatDao) {
+        this.memoryStatDao = memoryStatDao;
+    }
+
+    public void setNetworkInfoDao(NetworkInterfaceInfoDAO networkInfoDao) {
+        this.networkInfoDao = networkInfoDao;
+    }
+
+    public void setVmInfoDao(VmInfoDAO vmInfoDao) {
+        this.vmInfoDao = vmInfoDao;
+    }
+
+    public void setVmCpuStatDao(VmCpuStatDAO vmCpuStatDao) {
+        this.vmCpuStatDao = vmCpuStatDao;
+    }
+
+    @Override
+    public void setVmMemoryStatDao(VmMemoryStatDAO vmMemoryStatDao) {
+        this.vmMemoryStatDao = vmMemoryStatDao;
+    }
+
+    @Override
+    public void setVmGcStatDao(VmGcStatDAO vmGcStatDao) {
+        this.vmGcStatDao = vmGcStatDao;
+    }
+
+    @Override
+    public MainWindowController getMainWindow() {
+        MainView mainView = new MainWindow();
+        RegistryFactory registryFactory = new RegistryFactory(context);
+        return new MainWindowControllerImpl(this, mainView, registryFactory, hostInfoDao, vmInfoDao);
+    }
+
+    @Override
+    public SummaryController getSummary() {
+        SummaryViewProvider viewProvider = serviceProvider.getService(SummaryViewProvider.class);
+        return new SummaryController(hostInfoDao, vmInfoDao, viewProvider);
+    }
+
+    @Override
+    public HostInformationController getHostController(HostRef ref) {
+        HostInformationViewProvider viewProvider = serviceProvider.getService(HostInformationViewProvider.class);
+        return new HostInformationController(hostInfoDao, networkInfoDao, cpuStatDao, memoryStatDao, ref, viewProvider);
+    }
+
+    @Override
+    public VmInformationController getVmController(VmRef ref) {
+        VmInformationViewProvider viewProvider = serviceProvider.getService(VmInformationViewProvider.class);
+        return new VmInformationController(this, vmInfoDao, vmCpuStatDao, vmMemoryStatDao, vmGcStatDao, ref, viewProvider);
+    }
+
+    @Override
+    public Collection<VmInformationService> getVmInformationServices() {
+        return vmInformationServices;
+    }
+
+    @Override
+    public void addVmInformationService(VmInformationService vmInfoService) {
+        vmInformationServices.add(vmInfoService);
+    }
+
+    @Override
+    public void removeVmInformationService(VmInformationService vmInfoService) {
+        vmInformationServices.remove(vmInfoService);
+    }
+
+    @Override
+    public Collection<VMContextAction> getVMContextActions() {
+        return contextAction;
+    }
+
+    @Override
+    public void addVMContextAction(VMContextAction service) {
+        contextAction.add(service);
+    }
+
+    @Override
+    public void shutdown() {
+        shutdown.countDown();
+    }
+
+    @Override
+    public void shutdown(int exitCode) {
+        // TODO implement returning exit codes
+        shutdown();
+    }
+
+    @Override
+    public void awaitShutdown() throws InterruptedException {
+        shutdown.await();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/VMInformationRegistry.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,53 @@
+/*
+ * 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 org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.core.VmInformationService;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+
+class VMInformationRegistry extends ThermostatExtensionRegistry<VmInformationService> {
+
+    private static final String FILTER = "(&(" + Constants.OBJECTCLASS + "=" + VmInformationService.class.getName() + "))";
+    
+    public VMInformationRegistry(BundleContext context) throws InvalidSyntaxException {
+        super(context, FILTER, VmInformationService.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/VMTreeDecoratorRegistry.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,53 @@
+/*
+ * 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 org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.osgi.service.VmDecorator;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+
+class VMTreeDecoratorRegistry extends ThermostatExtensionRegistry<VmDecorator> {
+
+    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + VmDecorator.class.getName() + ")";
+    
+    public VMTreeDecoratorRegistry(BundleContext context) throws InvalidSyntaxException {
+        super(context, FILTER, VmDecorator.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/VmFilterRegistry.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,53 @@
+/*
+ * 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 org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.core.VmFilter;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+
+class VmFilterRegistry extends ThermostatExtensionRegistry<VmFilter> {
+
+    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + VmFilter.class.getName() + ")";
+
+    public VmFilterRegistry(BundleContext context) throws InvalidSyntaxException {
+        super(context, FILTER, VmFilter.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/WrapLayout.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2008 Rob Camick, 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.
+ */
+
+/*
+ * Taken from http://tips4java.wordpress.com/2008/11/06/wrap-layout/
+ *
+ * The about page (http://tips4java.wordpress.com/about/) says this:
+ * "You are free to use and/or modify any or all code posted on the Java Tips
+ * Weblog without restriction. A credit in the code comments would be nice,
+ * but not in any way mandatory."
+ */
+
+package com.redhat.thermostat.client.swing.internal;
+
+import java.awt.*;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+
+/**
+ *  FlowLayout subclass that fully supports wrapping of components.
+ */
+public class WrapLayout extends FlowLayout {
+
+    private static final long serialVersionUID = -9169664895883997422L;
+
+    /**
+	* Constructs a new <code>WrapLayout</code> with a left
+	* alignment and a default 5-unit horizontal and vertical gap.
+	*/
+	public WrapLayout()
+	{
+		super();
+	}
+
+	/**
+	* Constructs a new <code>FlowLayout</code> with the specified
+	* alignment and a default 5-unit horizontal and vertical gap.
+	* The value of the alignment argument must be one of
+	* <code>WrapLayout</code>, <code>WrapLayout</code>,
+	* or <code>WrapLayout</code>.
+	* @param align the alignment value
+	*/
+	public WrapLayout(int align)
+	{
+		super(align);
+	}
+
+	/**
+	* Creates a new flow layout manager with the indicated alignment
+	* and the indicated horizontal and vertical gaps.
+	* <p>
+	* The value of the alignment argument must be one of
+	* <code>WrapLayout</code>, <code>WrapLayout</code>,
+	* or <code>WrapLayout</code>.
+	* @param align the alignment value
+	* @param hgap the horizontal gap between components
+	* @param vgap the vertical gap between components
+	*/
+	public WrapLayout(int align, int hgap, int vgap)
+	{
+		super(align, hgap, vgap);
+	}
+
+	/**
+	* Returns the preferred dimensions for this layout given the
+	* <i>visible</i> components in the specified target container.
+	* @param target the component which needs to be laid out
+	* @return the preferred dimensions to lay out the
+	* subcomponents of the specified container
+	*/
+	@Override
+	public Dimension preferredLayoutSize(Container target)
+	{
+		return layoutSize(target, true);
+	}
+
+	/**
+	* Returns the minimum dimensions needed to layout the <i>visible</i>
+	* components contained in the specified target container.
+	* @param target the component which needs to be laid out
+	* @return the minimum dimensions to lay out the
+	* subcomponents of the specified container
+	*/
+	@Override
+	public Dimension minimumLayoutSize(Container target)
+	{
+		Dimension minimum = layoutSize(target, false);
+		minimum.width -= (getHgap() + 1);
+		return minimum;
+	}
+
+	/**
+	* Returns the minimum or preferred dimension needed to layout the target
+	* container.
+	*
+	* @param target target to get layout size for
+	* @param preferred should preferred size be calculated
+	* @return the dimension to layout the target container
+	*/
+	private Dimension layoutSize(Container target, boolean preferred)
+	{
+	synchronized (target.getTreeLock())
+	{
+		//  Each row must fit with the width allocated to the containter.
+		//  When the container width = 0, the preferred width of the container
+		//  has not yet been calculated so lets ask for the maximum.
+
+		int targetWidth = target.getSize().width;
+
+		if (targetWidth == 0)
+			targetWidth = Integer.MAX_VALUE;
+
+		int hgap = getHgap();
+		int vgap = getVgap();
+		Insets insets = target.getInsets();
+		int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
+		int maxWidth = targetWidth - horizontalInsetsAndGap;
+
+		//  Fit components into the allowed width
+
+		Dimension dim = new Dimension(0, 0);
+		int rowWidth = 0;
+		int rowHeight = 0;
+
+		int nmembers = target.getComponentCount();
+
+		for (int i = 0; i < nmembers; i++)
+		{
+			Component m = target.getComponent(i);
+
+			if (m.isVisible())
+			{
+				Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
+
+				//  Can't add the component to current row. Start a new row.
+
+				if (rowWidth + d.width > maxWidth)
+				{
+					addRow(dim, rowWidth, rowHeight);
+					rowWidth = 0;
+					rowHeight = 0;
+				}
+
+				//  Add a horizontal gap for all components after the first
+
+				if (rowWidth != 0)
+				{
+					rowWidth += hgap;
+				}
+
+				rowWidth += d.width;
+				rowHeight = Math.max(rowHeight, d.height);
+			}
+		}
+
+		addRow(dim, rowWidth, rowHeight);
+
+		dim.width += horizontalInsetsAndGap;
+		dim.height += insets.top + insets.bottom + vgap * 2;
+
+		//	When using a scroll pane or the DecoratedLookAndFeel we need to
+		//  make sure the preferred size is less than the size of the
+		//  target containter so shrinking the container size works
+		//  correctly. Removing the horizontal gap is an easy way to do this.
+
+		Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);
+
+		if (scrollPane != null)
+		{
+			dim.width -= (hgap + 1);
+		}
+
+		return dim;
+	}
+	}
+
+	/*
+	 *  A new row has been completed. Use the dimensions of this row
+	 *  to update the preferred size for the container.
+	 *
+	 *  @param dim update the width and height when appropriate
+	 *  @param rowWidth the width of the row to add
+	 *  @param rowHeight the height of the row to add
+	 */
+	private void addRow(Dimension dim, int rowWidth, int rowHeight)
+	{
+		dim.width = Math.max(dim.width, rowWidth);
+
+		if (dim.height > 0)
+		{
+			dim.height += getVgap();
+		}
+
+		dim.height += rowHeight;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/components/DecoratedDefaultMutableTreeNode.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,67 @@
+/*
+ * 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.components;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+
+import com.redhat.thermostat.client.ui.Decorator;
+import com.redhat.thermostat.common.dao.Ref;
+
+public class DecoratedDefaultMutableTreeNode  extends DefaultMutableTreeNode {
+    
+    private List<Decorator> decorators;
+    
+    public DecoratedDefaultMutableTreeNode(Ref ref) {
+        super(ref);
+        decorators = new ArrayList<>();
+    }
+    
+    public void addDecorator(Decorator decorator) {
+        decorators.add(decorator);
+    }
+    
+    public void setDecorators(List<Decorator> decorators) {
+        this.decorators = decorators;
+    }
+    
+    public List<Decorator> getDecorators() {
+        return decorators;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/config/ConnectionConfiguration.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,65 @@
+/*
+ * 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.config;
+
+import com.redhat.thermostat.common.cli.AuthenticationConfiguration;
+import com.redhat.thermostat.common.config.ClientPreferences;
+import com.redhat.thermostat.common.config.StartupConfiguration;
+
+public class ConnectionConfiguration implements StartupConfiguration, AuthenticationConfiguration {
+
+    private final ClientPreferences clientPrefs;
+
+    public ConnectionConfiguration(ClientPreferences clientPrefs) {
+        this.clientPrefs = clientPrefs;
+    }
+
+    @Override
+    public String getDBConnectionString() {
+        return clientPrefs.getConnectionUrl();
+    }
+    
+    @Override
+    public String getPassword() {
+        return clientPrefs.getPassword();
+    }
+    
+    @Override
+    public String getUsername() {
+        return clientPrefs.getUserName();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/ApplicationServiceProvider.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,64 @@
+/*
+ * 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.osgi;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+import com.redhat.thermostat.client.osgi.service.ApplicationCache;
+import com.redhat.thermostat.client.osgi.service.ApplicationService;
+
+public class ApplicationServiceProvider implements ApplicationService {
+
+    private ApplicationCache cache = new ApplicationCache();
+
+    // NOTE: When merging with ApplicationContext, this could be provided by the same
+    // thread pool that does the timer scheduling. Not sure we want this though,
+    // as scheduled thread pools are always limited in number of threads (could lead to deadlocks
+    // when used carelessly).
+    private ExecutorService executor = Executors.newCachedThreadPool();
+
+    @Override
+    public ApplicationCache getApplicationCache() {
+        return cache;
+    }
+
+    @Override
+    public ExecutorService getApplicationExecutor() {
+        return executor;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/ContextActionServiceProvider.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,52 @@
+/*
+ * 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.osgi;
+
+import com.redhat.thermostat.client.osgi.service.ContextAction;
+
+public class ContextActionServiceProvider implements ContextAction {
+  
+    @Override
+    public String getName() {
+        return "system context";
+    }
+
+    @Override
+    public String getDescription() {
+        return "system context";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivator.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,154 @@
+/*
+ * 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.osgi;
+
+import java.util.Arrays;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+import com.redhat.thermostat.client.core.views.AgentInformationViewProvider;
+import com.redhat.thermostat.client.core.views.ClientConfigViewProvider;
+import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
+import com.redhat.thermostat.client.core.views.HostInformationViewProvider;
+import com.redhat.thermostat.client.core.views.HostMemoryViewProvider;
+import com.redhat.thermostat.client.core.views.HostOverviewViewProvider;
+import com.redhat.thermostat.client.core.views.SummaryViewProvider;
+import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
+import com.redhat.thermostat.client.core.views.VmGcViewProvider;
+import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
+import com.redhat.thermostat.client.core.views.VmOverviewViewProvider;
+import com.redhat.thermostat.client.osgi.service.HostDecorator;
+import com.redhat.thermostat.client.swing.internal.GUIClientCommand;
+import com.redhat.thermostat.client.swing.internal.HostIconDecorator;
+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.SwingHostCpuViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingHostInformationViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingHostMemoryViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingHostOverviewViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingSummaryViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingVmCpuViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingVmGcViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingVmInformationViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingVmOverviewViewProvider;
+import com.redhat.thermostat.client.ui.UiFacadeFactory;
+import com.redhat.thermostat.common.cli.CommandRegistry;
+import com.redhat.thermostat.common.cli.CommandRegistryImpl;
+import com.redhat.thermostat.utils.keyring.Keyring;
+
+public class ThermostatActivator implements BundleActivator {
+
+    private VmInformationServiceTracker vmInfoServiceTracker;
+    private VMContextActionServiceTracker contextActionTracker;
+
+    private CommandRegistry cmdReg;
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Override
+    public void start(final BundleContext context) throws Exception {
+        
+        HostDecorator hostDecorator = new HostIconDecorator();
+        context.registerService(HostDecorator.class.getName(), hostDecorator, null);
+        
+        // Host views
+        HostInformationViewProvider infoProvider = new SwingHostInformationViewProvider();
+        context.registerService(HostInformationViewProvider.class.getName(), infoProvider, null);
+        HostCpuViewProvider cpuProvider = new SwingHostCpuViewProvider();
+        context.registerService(HostCpuViewProvider.class.getName(), cpuProvider, null);
+        HostOverviewViewProvider provider = new SwingHostOverviewViewProvider();
+        context.registerService(HostOverviewViewProvider.class.getName(), provider, null);
+        HostMemoryViewProvider memoryProvider = new SwingHostMemoryViewProvider();
+        context.registerService(HostMemoryViewProvider.class.getName(), memoryProvider, null);
+        
+        // Vm views
+        VmInformationViewProvider vmInfoProvider = new SwingVmInformationViewProvider();
+        context.registerService(VmInformationViewProvider.class.getName(), vmInfoProvider, null);
+        VmOverviewViewProvider vmOverviewProvider = new SwingVmOverviewViewProvider();
+        context.registerService(VmOverviewViewProvider.class.getName(), vmOverviewProvider, null);
+        VmGcViewProvider vmGcProvider = new SwingVmGcViewProvider();
+        context.registerService(VmGcViewProvider.class.getName(), vmGcProvider, null);
+        VmCpuViewProvider vmCpuProvider = new SwingVmCpuViewProvider();
+        context.registerService(VmCpuViewProvider.class.getName(), vmCpuProvider, null);
+        
+        // Summary view
+        SummaryViewProvider summaryViewProvider = new SwingSummaryViewProvider();
+        context.registerService(SummaryViewProvider.class.getName(), summaryViewProvider, null);
+
+        // AgentInformation and ClientConfiguraiton view
+        AgentInformationViewProvider agentViewProvider = new SwingAgentInformationViewProvider();
+        context.registerService(AgentInformationViewProvider.class.getName(), agentViewProvider, null);
+        ClientConfigViewProvider clientConfigViewProvider = new SwingClientConfigurationViewProvider();
+        context.registerService(ClientConfigViewProvider.class, clientConfigViewProvider, null);
+        
+        ServiceTracker tracker = new ServiceTracker(context, Keyring.class.getName(), null) {
+            @Override
+            public Object addingService(ServiceReference reference) {
+              
+                Keyring keyring = (Keyring) context.getService(reference);
+                
+                UiFacadeFactory uiFacadeFactory = new UiFacadeFactoryImpl(context);
+
+                vmInfoServiceTracker = new VmInformationServiceTracker(context, uiFacadeFactory);
+                vmInfoServiceTracker.open();
+                contextActionTracker = new VMContextActionServiceTracker(context, uiFacadeFactory);
+                contextActionTracker.open();
+
+                cmdReg = new CommandRegistryImpl(context);
+                Main main = new Main(keyring, uiFacadeFactory, new String[0]);
+                
+                GUIClientCommand cmd = new GUIClientCommand(main);
+                cmd.setBundleContext(context);
+                cmdReg.registerCommands(Arrays.asList(cmd));
+                
+                return super.addingService(reference);
+            }
+        };
+        tracker.open();
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        vmInfoServiceTracker.close(); //context.removeServiceListener(vmInfoServiceTracker);
+        contextActionTracker.close();
+        cmdReg.unregisterCommands();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/VMContextActionServiceTracker.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,67 @@
+/*
+ * 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.osgi;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.ui.UiFacadeFactory;
+
+@SuppressWarnings("rawtypes")
+class VMContextActionServiceTracker extends ServiceTracker {
+
+    private UiFacadeFactory uiFacadeFactory;
+
+    private BundleContext context;
+
+    @SuppressWarnings("unchecked")
+    VMContextActionServiceTracker(BundleContext context, UiFacadeFactory uiFacadeFactory) {
+        super(context, VMContextAction.class.getName(), null);
+        this.context = context;
+        this.uiFacadeFactory = uiFacadeFactory;
+    }
+
+    @Override
+    public Object addingService(ServiceReference reference) {
+        @SuppressWarnings("unchecked")
+        VMContextAction service = (VMContextAction) context.getService(reference);
+        uiFacadeFactory.addVMContextAction(service);
+        return service;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/VmInformationServiceTracker.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,70 @@
+/*
+ * 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.osgi;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+import com.redhat.thermostat.client.core.VmInformationService;
+import com.redhat.thermostat.client.ui.UiFacadeFactory;
+
+class VmInformationServiceTracker extends ServiceTracker {
+
+    private UiFacadeFactory uiFacadeFactory;
+
+    private BundleContext context;
+
+    VmInformationServiceTracker(BundleContext context, UiFacadeFactory uiFacadeFactory) {
+        super(context, VmInformationService.class.getName(), null);
+        this.context = context;
+        this.uiFacadeFactory = uiFacadeFactory;
+    }
+
+    @Override
+    public Object addingService(ServiceReference reference) {
+        VmInformationService service = (VmInformationService) super.addingService(reference);
+        uiFacadeFactory.addVmInformationService(service);
+        return service;
+    }
+
+    @Override
+    public void removedService(ServiceReference reference, Object service) {
+        uiFacadeFactory.removeVmInformationService((VmInformationService)service);
+        super.removedService(reference, service);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/AgentInformationDisplayFrame.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,465 @@
+/*
+ * 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 DefaultTableModel();
+        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;
+            }
+
+            int rowIndex = e.getFirstIndex();
+            String backendName = (String) backendsTableModel.getValueAt(rowIndex, 0);
+            ActionEvent<ConfigurationAction> event = new ActionEvent<>(AgentInformationDisplayFrame.this,
+                    ConfigurationAction.SHOW_BACKEND_DESCRIPTION);
+            event.setPayload(backendName);
+            fireAction(event);
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/ClientConfigurationPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.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/views/ClientConfigurationSwing.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.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.components.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/views/HostCpuPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,297 @@
+/*
+ * 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.Color;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.GroupLayout;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.LayoutStyle.ComponentPlacement;
+import javax.swing.SwingUtilities;
+import javax.swing.text.JTextComponent;
+
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.renderer.xy.XYItemRenderer;
+import org.jfree.data.time.FixedMillisecond;
+import org.jfree.data.time.RegularTimePeriod;
+import org.jfree.data.time.TimeSeries;
+import org.jfree.data.time.TimeSeriesCollection;
+
+import com.redhat.thermostat.client.core.views.HostCpuView;
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.client.swing.components.LabelField;
+import com.redhat.thermostat.client.swing.components.RecentTimeSeriesChartPanel;
+import com.redhat.thermostat.client.swing.components.SectionHeader;
+import com.redhat.thermostat.client.swing.components.ValueField;
+import com.redhat.thermostat.client.swing.internal.WrapLayout;
+import com.redhat.thermostat.client.ui.ChartColors;
+import com.redhat.thermostat.client.ui.ComponentVisibleListener;
+import com.redhat.thermostat.client.ui.RecentTimeSeriesChartController;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.common.model.DiscreteTimeData;
+
+public class HostCpuPanel extends HostCpuView implements SwingComponent {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private JPanel visiblePanel;
+
+    private final JTextComponent cpuModel = new ValueField("${CPU_MODEL}");
+    private final JTextComponent cpuCount = new ValueField("${CPU_COUNT}");
+
+    private final TimeSeriesCollection datasetCollection = new TimeSeriesCollection();
+    private final Map<Integer, TimeSeries> datasets = new HashMap<>();
+    private final Map<String, Color> colors = new HashMap<>();
+    private final Map<String, JLabel> labels = new HashMap<>();
+
+    private JFreeChart chart;
+
+    private JPanel legendPanel;
+
+    public HostCpuPanel() {
+        super();
+        initializePanel();
+
+        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 setCpuCount(final String count) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                cpuCount.setText(count);
+            }
+        });
+    }
+
+    @Override
+    public void setCpuModel(final String model) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                cpuModel.setText(model);
+            }
+        });
+    }
+
+    @Override
+    public void addCpuUsageChart(final int cpuIndex, final String humanReadableName) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                TimeSeries series = new TimeSeries(humanReadableName);
+                Color color = ChartColors.getColor(colors.size());
+                colors.put(humanReadableName, color);
+
+                datasets.put(cpuIndex, series);
+                datasetCollection.addSeries(series);
+
+                updateColors();
+
+                JLabel label = createLabelWithLegend(humanReadableName, color);
+                labels.put(humanReadableName, label);
+
+                legendPanel.add(label);
+                legendPanel.revalidate();
+            }
+        });
+    }
+
+    @Override
+    public void addCpuUsageData(final int cpuIndex, List<DiscreteTimeData<Double>> data) {
+        final ArrayList<DiscreteTimeData<Double>> copy = new ArrayList<>(data);
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                TimeSeries dataset = datasets.get(cpuIndex);
+                for (DiscreteTimeData<Double> timeData: copy) {
+                    RegularTimePeriod period = new FixedMillisecond(timeData.getTimeInMillis());
+                    if (dataset.getDataItem(period) == null) {
+                        dataset.add(period, timeData.getData(), false);
+                    }
+                }
+                dataset.fireSeriesChanged();
+            }
+        });
+    }
+
+    @Override
+    public void clearCpuUsageData() {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                for (Iterator<Map.Entry<Integer, TimeSeries>> iter = datasets.entrySet().iterator(); iter.hasNext();) {
+                    Map.Entry<Integer, TimeSeries> entry = iter.next();
+                    datasetCollection.removeSeries(entry.getValue());
+                    entry.getValue().clear();
+
+                    iter.remove();
+
+                }
+                updateColors();
+            }
+        });
+    }
+
+    @Override
+    public Component getUiComponent() {
+        return visiblePanel;
+    }
+
+    private void initializePanel() {
+
+        visiblePanel = new JPanel();
+
+        JLabel summaryLabel = new SectionHeader(translator.localize(LocaleResources.HOST_CPU_SECTION_OVERVIEW));
+
+        JLabel cpuModelLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_CPU_MODEL));
+
+        JLabel cpuCountLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_CPU_COUNT));
+
+        chart = ChartFactory.createTimeSeriesChart(
+                null,
+                translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_TIME_LABEL),
+                translator.localize(LocaleResources.HOST_CPU_USAGE_CHART_VALUE_LABEL),
+                datasetCollection,
+                false, false, false);
+
+        chart.getPlot().setBackgroundPaint( new Color(255,255,255,0) );
+        chart.getPlot().setBackgroundImageAlpha(0.0f);
+        chart.getPlot().setOutlinePaint(new Color(0,0,0,0));
+
+        JPanel chartPanel = new RecentTimeSeriesChartPanel(new RecentTimeSeriesChartController(chart));
+        chartPanel.setOpaque(false);
+
+        legendPanel = new JPanel(new WrapLayout(FlowLayout.LEADING));
+        legendPanel.setOpaque(false);
+
+        GroupLayout groupLayout = new GroupLayout(visiblePanel);
+        groupLayout.setHorizontalGroup(
+            groupLayout.createParallelGroup(Alignment.TRAILING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+                        .addComponent(legendPanel, GroupLayout.DEFAULT_SIZE, 427, Short.MAX_VALUE)
+                        .addComponent(chartPanel, GroupLayout.DEFAULT_SIZE, 427, Short.MAX_VALUE)
+                        .addComponent(summaryLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                        .addGroup(groupLayout.createSequentialGroup()
+                            .addGap(12)
+                            .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+                                .addGroup(groupLayout.createSequentialGroup()
+                                    .addPreferredGap(ComponentPlacement.RELATED)
+                                    .addComponent(cpuCountLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                    .addGap(18)
+                                    .addComponent(cpuCount, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                                .addGroup(groupLayout.createSequentialGroup()
+                                    .addComponent(cpuModelLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                                    .addGap(18)
+                                    .addComponent(cpuModel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))))
+                    .addGap(11))
+        );
+        groupLayout.setVerticalGroup(
+            groupLayout.createParallelGroup(Alignment.LEADING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addComponent(summaryLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
+                        .addComponent(cpuModelLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                        .addComponent(cpuModel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                    .addGap(10)
+                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
+                        .addComponent(cpuCount, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                        .addComponent(cpuCountLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                    .addGap(18)
+                    .addComponent(chartPanel, GroupLayout.DEFAULT_SIZE, 263, Short.MAX_VALUE)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addComponent(legendPanel, GroupLayout.PREFERRED_SIZE, 30, GroupLayout.PREFERRED_SIZE)
+                    .addContainerGap())
+        );
+        visiblePanel.setLayout(groupLayout);
+    }
+
+    /**
+     * Adding or removing series to the series collection may change the order
+     * of existing items. Plus the paint for the index is now out-of-date. So
+     * let's walk through all the series and set the right paint for those.
+     */
+    private void updateColors() {
+        XYItemRenderer itemRenderer = chart.getXYPlot().getRenderer();
+        for (int i = 0; i < datasetCollection.getSeriesCount(); i++) {
+            String tag = (String) datasetCollection.getSeriesKey(i);
+            Color color = colors.get(tag);
+            itemRenderer.setSeriesPaint(i, color);
+        }
+    }
+
+    private JLabel createLabelWithLegend(String text, Color color) {
+        String hexColor = "#" + Integer.toHexString(color.getRGB() & 0x00ffffff);
+        return new JLabel("<html> <font color='" + hexColor + "'>\u2588</font> " + text + "</html>");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/HostInformationPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.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.BasicView;
+import com.redhat.thermostat.client.core.views.HostInformationView;
+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 BasicView 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/views/HostMemoryPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,354 @@
+/*
+ * 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.Color;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import javax.swing.GroupLayout;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.LayoutStyle.ComponentPlacement;
+import javax.swing.SwingUtilities;
+import javax.swing.text.JTextComponent;
+
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.renderer.xy.XYItemRenderer;
+import org.jfree.data.time.FixedMillisecond;
+import org.jfree.data.time.RegularTimePeriod;
+import org.jfree.data.time.TimeSeries;
+import org.jfree.data.time.TimeSeriesCollection;
+
+import com.redhat.thermostat.client.core.views.HostMemoryView;
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.client.swing.components.Components;
+import com.redhat.thermostat.client.swing.components.RecentTimeSeriesChartPanel;
+import com.redhat.thermostat.client.swing.components.ValueField;
+import com.redhat.thermostat.client.swing.internal.WrapLayout;
+import com.redhat.thermostat.client.ui.ChartColors;
+import com.redhat.thermostat.client.ui.ComponentVisibleListener;
+import com.redhat.thermostat.client.ui.RecentTimeSeriesChartController;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.common.model.DiscreteTimeData;
+import com.redhat.thermostat.common.utils.DisplayableValues;
+import com.redhat.thermostat.common.utils.DisplayableValues.Scale;
+
+public class HostMemoryPanel extends HostMemoryView implements SwingComponent {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private JPanel visiblePanel;
+
+    private final MemoryCheckboxListener memoryCheckboxListener = new MemoryCheckboxListener();
+
+    private final JTextComponent totalMemory = new ValueField("${TOTAL_MEMORY}");
+
+    private final JPanel memoryCheckBoxPanel = new JPanel(new WrapLayout(FlowLayout.LEADING));
+    private final CopyOnWriteArrayList<GraphVisibilityChangeListener> listeners = new CopyOnWriteArrayList<>();
+    private final TimeSeriesCollection memoryCollection = new TimeSeriesCollection();
+    private final Map<String, TimeSeries> dataset = new HashMap<>();
+    private final Map<String, JCheckBox> checkBoxes = new HashMap<>();
+    private final Map<String, Color> colors = new HashMap<>();
+
+    private JFreeChart chart;
+
+    public HostMemoryPanel() {
+        super();
+        initializePanel();
+
+        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 setTotalMemory(final String newValue) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                totalMemory.setText(newValue);
+            }
+        });
+    }
+
+    @Override
+    public Component getUiComponent() {
+        return visiblePanel;
+    }
+
+    @Override
+    public void addMemoryChart(final String tag, final String humanReadableName) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                int colorIndex = colors.size();
+                colors.put(tag, ChartColors.getColor(colorIndex));
+                TimeSeries series = new TimeSeries(tag);
+                dataset.put(tag, series);
+                JCheckBox newCheckBox = new JCheckBox(createLabelWithLegend(humanReadableName, colors.get(tag)));
+                newCheckBox.setActionCommand(tag);
+                newCheckBox.setSelected(true);
+                newCheckBox.addActionListener(memoryCheckboxListener);
+                newCheckBox.setOpaque(false);
+                checkBoxes.put(tag, newCheckBox);
+                memoryCheckBoxPanel.add(newCheckBox);
+
+                updateColors();
+            }
+        });
+
+    }
+
+    private String createLabelWithLegend(String text, Color color) {
+        String hexColor = "#" + Integer.toHexString(color.getRGB() & 0x00ffffff);
+        return "<html> <font color='" + hexColor + "'>\u2588</font> " + text + "</html>";
+    }
+
+    @Override
+    public void removeMemoryChart(final String tag) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                TimeSeries series = dataset.remove(tag);
+                memoryCollection.removeSeries(series);
+                JCheckBox box = checkBoxes.remove(tag);
+                memoryCheckBoxPanel.remove(box);
+
+                updateColors();
+            }
+        });
+    }
+
+    @Override
+    public void showMemoryChart(final String tag) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                TimeSeries series = dataset.get(tag);
+                memoryCollection.addSeries(series);
+
+                updateColors();
+            }
+        });
+    }
+
+    @Override
+    public void hideMemoryChart(final String tag) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                TimeSeries series = dataset.get(tag);
+                memoryCollection.removeSeries(series);
+
+                updateColors();
+            }
+        });
+    }
+
+    @Override
+    public void addMemoryData(final String tag, List<DiscreteTimeData<? extends Number>> data) {
+        final List<DiscreteTimeData<? extends Number>> copy = new ArrayList<>(data);
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                final TimeSeries series = dataset.get(tag);
+                for (DiscreteTimeData<? extends Number> timeData: copy) {
+                    RegularTimePeriod period = new FixedMillisecond(timeData.getTimeInMillis());
+                    if (series.getDataItem(period) == null) {
+                        Long sizeInBytes = (Long) timeData.getData();
+                        Double sizeInMegaBytes = DisplayableValues.Scale.convertTo(Scale.MiB, sizeInBytes);
+                        series.add(new FixedMillisecond(timeData.getTimeInMillis()), sizeInMegaBytes, false);
+                    }
+                }
+                series.fireSeriesChanged();
+            }
+        });
+    }
+
+    @Override
+    public void clearMemoryData(final String tag) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                TimeSeries series = dataset.get(tag);
+                series.clear();
+            }
+        });
+    }
+
+    @Override
+    public void addGraphVisibilityListener(GraphVisibilityChangeListener listener) {
+        listeners.add(listener);
+    }
+
+    @Override
+    public void removeGraphVisibilityListener(GraphVisibilityChangeListener listener) {
+        listeners.remove(listener);
+    }
+
+    @Override
+    public void addActionListener(ActionListener<Action> listener) {
+        notifier.addActionListener(listener);
+    }
+
+    @Override
+    public void removeActionListener(ActionListener<Action> listener) {
+        notifier.removeActionListener(listener);
+    }
+
+    private void initializePanel() {
+        visiblePanel = new JPanel();
+        visiblePanel.setOpaque(false);
+
+        chart = createMemoryChart();
+
+        JPanel chartPanel = new RecentTimeSeriesChartPanel(new RecentTimeSeriesChartController(chart));
+        chartPanel.setOpaque(false);
+
+        JLabel lblMemory = Components.header(translator.localize(LocaleResources.HOST_MEMORY_SECTION_OVERVIEW));
+
+        JLabel totalMemoryLabel = Components.label(translator.localize(LocaleResources.HOST_INFO_MEMORY_TOTAL));
+
+        memoryCheckBoxPanel.setOpaque(false);
+
+        GroupLayout groupLayout = new GroupLayout(visiblePanel);
+        groupLayout.setHorizontalGroup(
+            groupLayout.createParallelGroup(Alignment.LEADING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
+                        .addComponent(chartPanel, GroupLayout.DEFAULT_SIZE, 883, Short.MAX_VALUE)
+                        .addGroup(groupLayout.createSequentialGroup()
+                            .addGap(12)
+                            .addComponent(totalMemoryLabel)
+                            .addPreferredGap(ComponentPlacement.RELATED)
+                            .addComponent(totalMemory, GroupLayout.DEFAULT_SIZE, 751, Short.MAX_VALUE))
+                        .addComponent(lblMemory)
+                        .addComponent(memoryCheckBoxPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE))
+                    .addContainerGap())
+        );
+        groupLayout.setVerticalGroup(
+            groupLayout.createParallelGroup(Alignment.LEADING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addComponent(lblMemory)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addGroup(groupLayout.createParallelGroup(Alignment.BASELINE)
+                        .addComponent(totalMemory, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                        .addComponent(totalMemoryLabel))
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addComponent(chartPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, Short.MAX_VALUE)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addComponent(memoryCheckBoxPanel, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE)
+                    .addContainerGap())
+        );
+        visiblePanel.setLayout(groupLayout);
+    }
+
+    private JFreeChart createMemoryChart() {
+        JFreeChart chart = ChartFactory.createTimeSeriesChart(
+                translator.localize(LocaleResources.HOST_MEMORY_CHART_TITLE), // Title
+                translator.localize(LocaleResources.HOST_MEMORY_CHART_TIME_LABEL), // x-axis Label
+                translator.localize(LocaleResources.HOST_MEMORY_CHART_SIZE_LABEL, Scale.MiB.name()), // y-axis Label
+                memoryCollection, // Dataset
+                false, // Show Legend
+                false, // Use tooltips
+                false // Configure chart to generate URLs?
+                );
+
+        chart.getPlot().setBackgroundPaint( new Color(255,255,255,0) );
+        chart.getPlot().setBackgroundImageAlpha(0.0f);
+        chart.getPlot().setOutlinePaint(new Color(0,0,0,0));
+
+        NumberAxis rangeAxis = (NumberAxis) chart.getXYPlot().getRangeAxis();
+        rangeAxis.setAutoRangeMinimumSize(100);
+
+        return chart;
+    }
+
+    private void fireShowHideHandlers(boolean show, String tag) {
+        for (GraphVisibilityChangeListener listener: listeners) {
+            if (show) {
+                listener.show(tag);
+            } else {
+                listener.hide(tag);
+            }
+        }
+    }
+
+    /**
+     * Adding or removing series to the series collection may change the order
+     * of existing items. Plus the paint for the index is now out-of-date. So
+     * let's walk through all the series and set the right paint for those.
+     */
+    private void updateColors() {
+        XYItemRenderer itemRenderer = chart.getXYPlot().getRenderer();
+        for (int i = 0; i < memoryCollection.getSeriesCount(); i++) {
+            String tag = (String) memoryCollection.getSeriesKey(i);
+            Color color = colors.get(tag);
+            itemRenderer.setSeriesPaint(i, color);
+        }
+    }
+
+    private class MemoryCheckboxListener implements java.awt.event.ActionListener {
+        @Override
+        public void actionPerformed(java.awt.event.ActionEvent e) {
+            JCheckBox source = (JCheckBox) e.getSource();
+            fireShowHideHandlers(source.isSelected(), source.getActionCommand());
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/HostOverviewPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,309 @@
+/*
+ * 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.GroupLayout;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.JPanel;
+import javax.swing.JTable;
+import javax.swing.LayoutStyle.ComponentPlacement;
+import javax.swing.SwingUtilities;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.JTableHeader;
+
+import com.redhat.thermostat.client.core.views.HostOverviewView;
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.swing.SwingComponent;
+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.client.ui.ComponentVisibleListener;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.Translate;
+
+public class HostOverviewPanel extends HostOverviewView implements SwingComponent {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private JPanel visiblePanel;
+
+    private final ValueField hostname = new ValueField("${hostname}");
+    private final ValueField cpuModel = new ValueField("${cpu-model}");
+    private final ValueField cpuCount = new ValueField("${cpu-count}");
+    private final ValueField totalMemory = new ValueField("${total-memory}");
+    private final ValueField osName = new ValueField("${os-name}");
+    private final ValueField osKernel = new ValueField("${os-kernel}");
+
+    private final DefaultTableModel networkTableModel = new DefaultTableModel() {
+        @Override
+        public boolean isCellEditable(int row, int column) {
+            return false;
+        }
+    };
+
+    private Object[] networkTableColumns;
+    private Object[][] networkTableData;
+
+    public HostOverviewPanel() {
+        super();
+        initializePanel();
+
+        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 setHostName(final String newHostName) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                hostname.setText(newHostName);
+            }
+        });
+    }
+
+    @Override
+    public void setCpuModel(final String newCpuModel) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                cpuModel.setText(newCpuModel);
+            }
+        });
+    }
+
+    @Override
+    public void setCpuCount(final String newCpuCount) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                cpuCount.setText(newCpuCount);
+            }
+        });
+    }
+
+    @Override
+    public void setTotalMemory(final String newTotalMemory) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                totalMemory.setText(newTotalMemory);
+            }
+        });
+    }
+
+    @Override
+    public void setOsName(final String newOsName) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                osName.setText(newOsName);
+            }
+        });
+    }
+
+    @Override
+    public void setOsKernel(final String newOsKernel) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                osKernel.setText(newOsKernel);
+            }
+        });
+    }
+
+    @Override
+    public void setNetworkTableColumns(final Object[] columns) {
+        this.networkTableColumns = columns;
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                networkTableModel.setColumnIdentifiers(networkTableColumns);
+            }
+        });
+    }
+
+    @Override
+    public void setInitialNetworkTableData(final Object[][] data) {
+        this.networkTableData = data;
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                networkTableModel.setDataVector(networkTableData, networkTableColumns);
+            }
+        });
+    }
+
+    @Override
+    public void updateNetworkTableData(final int row, final int column, final String data) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                networkTableModel.setValueAt(data, row, column);
+            }
+        });
+    }
+
+    @Override
+    public Component getUiComponent() {
+        return visiblePanel;
+    }
+
+    private void initializePanel() {
+        visiblePanel = new JPanel();
+        SectionHeader overviewSection = new SectionHeader(translator.localize(LocaleResources.HOST_OVERVIEW_SECTION_BASICS));
+        LabelField hostnameLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_HOSTNAME));
+        SectionHeader hardwareSection = new SectionHeader(translator.localize(LocaleResources.HOST_OVERVIEW_SECTION_HARDWARE));
+        LabelField cpuModelLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_CPU_MODEL));
+        LabelField cpuCountLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_CPU_COUNT));
+        LabelField memoryTotalLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_MEMORY_TOTAL));
+        LabelField networkLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_NETWORK));
+        SectionHeader softwareSection = new SectionHeader(translator.localize(LocaleResources.HOST_OVERVIEW_SECTION_SOFTWARE));
+        LabelField osNameLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_OS_NAME));
+        LabelField osKernelLabel = new LabelField(translator.localize(LocaleResources.HOST_INFO_OS_KERNEL));
+
+        JPanel panel = new JPanel();
+
+        GroupLayout gl_visiblePanel = new GroupLayout(visiblePanel);
+        gl_visiblePanel.setHorizontalGroup(
+            gl_visiblePanel.createParallelGroup(Alignment.LEADING)
+                .addGroup(gl_visiblePanel.createSequentialGroup()
+                    .addContainerGap()
+                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
+                        .addComponent(hardwareSection, GroupLayout.DEFAULT_SIZE, 620, Short.MAX_VALUE)
+                        .addComponent(overviewSection, GroupLayout.DEFAULT_SIZE, 620, Short.MAX_VALUE)
+                        .addGroup(gl_visiblePanel.createSequentialGroup()
+                            .addGroup(gl_visiblePanel.createParallelGroup(Alignment.TRAILING, false)
+                                .addGroup(gl_visiblePanel.createSequentialGroup()
+                                    .addGap(12)
+                                    .addComponent(hostnameLabel, GroupLayout.DEFAULT_SIZE, 134, Short.MAX_VALUE))
+                                .addComponent(cpuCountLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                .addComponent(cpuModelLabel, GroupLayout.DEFAULT_SIZE, 134, Short.MAX_VALUE)
+                                .addComponent(memoryTotalLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                .addGroup(gl_visiblePanel.createSequentialGroup()
+                                    .addGap(12)
+                                    .addComponent(networkLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+                            .addPreferredGap(ComponentPlacement.RELATED)
+                            .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
+                                .addComponent(panel, GroupLayout.DEFAULT_SIZE, 462, Short.MAX_VALUE)
+                                .addComponent(cpuCount, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                .addComponent(cpuModel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                .addComponent(hostname, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                .addComponent(totalMemory, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))
+                        .addComponent(softwareSection, GroupLayout.DEFAULT_SIZE, 620, Short.MAX_VALUE)
+                        .addGroup(gl_visiblePanel.createSequentialGroup()
+                            .addGap(12)
+                            .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING, false)
+                                .addComponent(osKernelLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                .addComponent(osNameLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE))
+                            .addPreferredGap(ComponentPlacement.RELATED)
+                            .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
+                                .addComponent(osKernel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                                .addComponent(osName, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
+                    .addContainerGap())
+        );
+        gl_visiblePanel.setVerticalGroup(
+            gl_visiblePanel.createParallelGroup(Alignment.LEADING)
+                .addGroup(gl_visiblePanel.createSequentialGroup()
+                    .addContainerGap()
+                    .addComponent(overviewSection, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING, false)
+                        .addComponent(hostname, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
+                        .addComponent(hostnameLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                    .addPreferredGap(ComponentPlacement.UNRELATED)
+                    .addComponent(hardwareSection, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING, false)
+                        .addComponent(cpuModelLabel, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
+                        .addComponent(cpuModel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING, false)
+                        .addComponent(cpuCountLabel, GroupLayout.PREFERRED_SIZE, 15, GroupLayout.PREFERRED_SIZE)
+                        .addComponent(cpuCount, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
+                        .addComponent(memoryTotalLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                        .addComponent(totalMemory, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
+                        .addComponent(networkLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                        .addComponent(panel, GroupLayout.PREFERRED_SIZE, 109, GroupLayout.PREFERRED_SIZE))
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addComponent(softwareSection, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
+                        .addComponent(osNameLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                        .addComponent(osName, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addGroup(gl_visiblePanel.createParallelGroup(Alignment.LEADING)
+                        .addComponent(osKernelLabel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
+                        .addComponent(osKernel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
+                    .addGap(128))
+        );
+
+        panel.setLayout(new BorderLayout(0, 0));
+
+        JTable networkTable = new JTable(networkTableModel);
+        panel.add(networkTable);
+        JTableHeader header = networkTable.getTableHeader();
+        panel.add(header, BorderLayout.PAGE_START);
+        visiblePanel.setLayout(gl_visiblePanel);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/MemorySpacePanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.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/views/SearchFieldSwingView.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,226 @@
+/*
+ * 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.IconResource;
+import com.redhat.thermostat.client.swing.components.EdtHelper;
+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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SummaryPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.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.SwingComponent;
+import com.redhat.thermostat.client.swing.components.Components;
+import com.redhat.thermostat.client.swing.components.ValueField;
+import com.redhat.thermostat.client.ui.ComponentVisibleListener;
+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 = Components.header(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 = Components.header(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/views/SwingAgentInformationViewProvider.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.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/views/SwingClientConfigurationViewProvider.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.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/views/SwingHostCpuViewProvider.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.views;
+
+import com.redhat.thermostat.client.core.views.HostCpuView;
+import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
+
+public class SwingHostCpuViewProvider implements HostCpuViewProvider {
+
+    @Override
+    public HostCpuView createView() {
+        return new HostCpuPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingHostInformationViewProvider.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.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/views/SwingHostMemoryViewProvider.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.views;
+
+import com.redhat.thermostat.client.core.views.HostMemoryView;
+import com.redhat.thermostat.client.core.views.HostMemoryViewProvider;
+
+public class SwingHostMemoryViewProvider implements HostMemoryViewProvider {
+
+    @Override
+    public HostMemoryView createView() {
+        return new HostMemoryPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingHostOverviewViewProvider.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.views;
+
+import com.redhat.thermostat.client.core.views.HostOverviewView;
+import com.redhat.thermostat.client.core.views.HostOverviewViewProvider;
+
+public class SwingHostOverviewViewProvider implements HostOverviewViewProvider {
+
+    @Override
+    public HostOverviewView createView() {
+        return new HostOverviewPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingSummaryViewProvider.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.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/views/SwingVmCpuViewProvider.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.views;
+
+import com.redhat.thermostat.client.core.views.VmCpuView;
+import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
+
+public class SwingVmCpuViewProvider implements VmCpuViewProvider {
+
+    @Override
+    public VmCpuView createView() {
+        return new VmCpuPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingVmGcViewProvider.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.views;
+
+import com.redhat.thermostat.client.core.views.VmGcView;
+import com.redhat.thermostat.client.core.views.VmGcViewProvider;
+
+public class SwingVmGcViewProvider implements VmGcViewProvider {
+
+    @Override
+    public VmGcView createView() {
+        return new VmGcPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingVmInformationViewProvider.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.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/views/SwingVmOverviewViewProvider.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.views;
+
+import com.redhat.thermostat.client.core.views.VmOverviewView;
+import com.redhat.thermostat.client.core.views.VmOverviewViewProvider;
+
+public class SwingVmOverviewViewProvider implements VmOverviewViewProvider {
+
+    @Override
+    public VmOverviewView createView() {
+        return new VmOverviewPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/VmCpuPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,151 @@
+/*
+ * 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.JPanel;
+import javax.swing.SwingUtilities;
+
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.data.time.FixedMillisecond;
+import org.jfree.data.time.RegularTimePeriod;
+import org.jfree.data.time.TimeSeries;
+import org.jfree.data.time.TimeSeriesCollection;
+
+import com.redhat.thermostat.client.core.views.VmCpuView;
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.client.swing.components.HeaderPanel;
+import com.redhat.thermostat.client.swing.components.RecentTimeSeriesChartPanel;
+import com.redhat.thermostat.client.ui.ComponentVisibleListener;
+import com.redhat.thermostat.client.ui.RecentTimeSeriesChartController;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.common.model.DiscreteTimeData;
+
+public class VmCpuPanel extends VmCpuView implements SwingComponent {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private HeaderPanel visiblePanel;
+    
+    private final TimeSeriesCollection data = new TimeSeriesCollection();
+    private final TimeSeries cpuTimeSeries = new TimeSeries("cpu-stats");
+
+    public VmCpuPanel() {
+        super();
+        data.addSeries(cpuTimeSeries);
+
+        initializePanel();
+
+        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 Component getUiComponent() {
+        return visiblePanel;
+    }
+
+    private void initializePanel() {
+        visiblePanel = new HeaderPanel();
+        visiblePanel.setHeader(translator.localize(LocaleResources.VM_CPU_TITLE));
+
+        JFreeChart chart = ChartFactory.createTimeSeriesChart(
+                null,
+                translator.localize(LocaleResources.VM_CPU_CHART_TIME_LABEL),
+                translator.localize(LocaleResources.VM_CPU_CHART_LOAD_LABEL),
+                data,
+                false, false, false);
+
+        chart.getXYPlot().getRangeAxis().setLowerBound(0.0);
+
+        JPanel chartPanel = new RecentTimeSeriesChartPanel(new RecentTimeSeriesChartController(chart));
+
+        visiblePanel.setContent(chartPanel);
+    }
+
+    @Override
+    public void addData(List<DiscreteTimeData<? extends Number>> data) {
+        final List<DiscreteTimeData<? extends Number>> copy = new ArrayList<>(data);
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                for (DiscreteTimeData<? extends Number> data: copy) {
+                    RegularTimePeriod period = new FixedMillisecond(data.getTimeInMillis());
+                    if (cpuTimeSeries.getDataItem(period) == null) {
+                        cpuTimeSeries.add(period, data.getData(), false);
+                    }
+                }
+                cpuTimeSeries.fireSeriesChanged();
+            }
+        });
+    }
+
+    @Override
+    public void clearData() {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                cpuTimeSeries.clear();
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/VmGcPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,250 @@
+/*
+ * 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 java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.JPanel;
+import javax.swing.SwingUtilities;
+
+import org.jfree.chart.ChartFactory;
+import org.jfree.chart.JFreeChart;
+import org.jfree.chart.axis.DateAxis;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.event.ChartProgressEvent;
+import org.jfree.chart.event.ChartProgressListener;
+import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.XYPlot;
+import org.jfree.chart.renderer.xy.StandardXYBarPainter;
+import org.jfree.chart.renderer.xy.XYBarRenderer;
+import org.jfree.data.RangeType;
+import org.jfree.data.xy.IntervalXYDataset;
+
+import com.redhat.thermostat.client.core.views.VmGcView;
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.client.swing.components.Components;
+import com.redhat.thermostat.client.swing.components.HeaderPanel;
+import com.redhat.thermostat.client.swing.components.RecentTimeSeriesChartPanel;
+import com.redhat.thermostat.client.ui.ComponentVisibleListener;
+import com.redhat.thermostat.client.ui.RecentTimeSeriesChartController;
+import com.redhat.thermostat.client.ui.SampledDataset;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.common.model.IntervalTimeData;
+
+public class VmGcPanel extends VmGcView implements SwingComponent {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private HeaderPanel visiblePanel = new HeaderPanel();
+    private JPanel realPanel = new JPanel();
+
+    private final Map<String, SampledDataset> dataset = new HashMap<>();
+    private final Map<String, JPanel> subPanels = new HashMap<>();
+
+    private final GridBagConstraints gcPanelConstraints;
+
+    public VmGcPanel() {
+        super();
+        initializePanel();
+
+        gcPanelConstraints = new GridBagConstraints();
+        gcPanelConstraints.gridx = 0;
+        gcPanelConstraints.gridy = 0;
+        gcPanelConstraints.fill = GridBagConstraints.BOTH;
+        gcPanelConstraints.weightx = 1;
+        gcPanelConstraints.weighty = 1;
+
+        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 Component getUiComponent() {
+        return visiblePanel;
+    }
+
+    private void initializePanel() {
+        visiblePanel.setContent(realPanel);
+        visiblePanel.setHeader(translator.localize(LocaleResources.VM_GC_TITLE));
+        realPanel.setLayout(new GridBagLayout());
+    }
+
+    private JPanel createCollectorDetailsPanel(IntervalXYDataset collectorData, String title, String units) {
+        JPanel detailsPanel = new JPanel();
+        detailsPanel.setBorder(Components.smallBorder());
+        detailsPanel.setLayout(new BorderLayout());
+
+        detailsPanel.add(Components.header(title), BorderLayout.NORTH);
+
+        JFreeChart chart = ChartFactory.createHistogram(
+            null,
+            translator.localize(LocaleResources.VM_GC_COLLECTOR_CHART_REAL_TIME_LABEL),
+            translator.localize(LocaleResources.VM_GC_COLLECTOR_CHART_GC_TIME_LABEL, units),
+            collectorData,
+            PlotOrientation.VERTICAL,
+            false,
+            false,
+            false);
+
+        ((XYBarRenderer)(chart.getXYPlot().getRenderer())).setBarPainter(new StandardXYBarPainter());
+
+        setupPlotAxes(chart.getXYPlot());
+
+        chart.getXYPlot().setDomainCrosshairLockedOnData(true);
+        chart.getXYPlot().setDomainCrosshairVisible(true);
+
+        final RecentTimeSeriesChartPanel chartPanel = new RecentTimeSeriesChartPanel(new RecentTimeSeriesChartController(chart));
+
+        chart.addProgressListener(new ChartProgressListener() {
+
+            @Override
+            public void chartProgress(ChartProgressEvent event) {
+                if (event.getType() != ChartProgressEvent.DRAWING_FINISHED) {
+                    return;
+                }
+
+                double rangeCrossHairValue = event.getChart().getXYPlot().getRangeCrosshairValue();
+                chartPanel.setDataInformationLabel(String.valueOf(rangeCrossHairValue));
+            }
+        });
+
+        detailsPanel.add(chartPanel, BorderLayout.CENTER);
+
+        return detailsPanel;
+    }
+
+    private void setupPlotAxes(XYPlot plot) {
+        setupDomainAxis(plot);
+        setupRangeAxis(plot);
+    }
+
+    private void setupDomainAxis(XYPlot plot) {
+        plot.setDomainAxis(new DateAxis());
+    }
+
+    private void setupRangeAxis(XYPlot plot) {
+        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
+
+        rangeAxis.setRangeType(RangeType.POSITIVE);
+        rangeAxis.setAutoRange(true);
+        rangeAxis.setAutoRangeMinimumSize(1);
+    }
+
+    @Override
+    public void addChart(final String tag, final String title, final String units) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                SampledDataset newData = new SampledDataset();
+                dataset.put(tag, newData);
+                JPanel subPanel = createCollectorDetailsPanel(newData, title, units);
+                subPanels.put(tag, subPanel);
+                realPanel.add(subPanel, gcPanelConstraints);
+                gcPanelConstraints.gridy++;
+                realPanel.revalidate();
+            }
+        });
+    }
+
+    @Override
+    public void removeChart(final String tag) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                dataset.remove(tag);
+                JPanel subPanel = subPanels.remove(tag);
+                realPanel.remove(subPanel);
+                realPanel.revalidate();
+                gcPanelConstraints.gridy--;
+            }
+        });
+    }
+
+    @Override
+    public void addData(final String tag, List<IntervalTimeData<Double>> data) {
+        final List<IntervalTimeData<Double>> copy = new ArrayList<>(data);
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                SampledDataset series = dataset.get(tag);
+                for (IntervalTimeData<Double> timeData: copy) {
+                    series.add(timeData.getStartTimeInMillis(), timeData.getEndTimeInMillis(), timeData.getData());
+                }
+                series.fireSeriesChanged();
+            }
+        });
+    }
+
+    @Override
+    public void clearData(final String tag) {
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                SampledDataset series = dataset.get(tag);
+                series.clear();
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/VmInformationPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.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/main/java/com/redhat/thermostat/client/swing/views/VmOverviewPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,193 @@
+/*
+ * 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.JPanel;
+
+import com.redhat.thermostat.client.core.views.VmOverviewView;
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.client.swing.components.Components;
+import com.redhat.thermostat.client.swing.components.HeaderPanel;
+import com.redhat.thermostat.client.swing.components.SimpleTable;
+import com.redhat.thermostat.client.swing.components.SimpleTable.Section;
+import com.redhat.thermostat.client.swing.components.SimpleTable.TableEntry;
+import com.redhat.thermostat.client.swing.internal.ChangeableText;
+import com.redhat.thermostat.client.ui.ComponentVisibleListener;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.Translate;
+
+public class VmOverviewPanel extends VmOverviewView implements SwingComponent {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+    
+    private HeaderPanel visiblePanel;
+
+    private final ChangeableText pid = new ChangeableText("");
+    private final ChangeableText startTimeStamp = new ChangeableText("");
+    private final ChangeableText stopTimeStamp = new ChangeableText("");
+    private final ChangeableText mainClass = new ChangeableText("");
+    private final ChangeableText javaCommandLine = new ChangeableText("");
+    private final ChangeableText javaHome = new ChangeableText("");
+    private final ChangeableText javaVersion = new ChangeableText("");
+    private final ChangeableText vmNameAndVersion = new ChangeableText("");
+    private final ChangeableText vmArguments = new ChangeableText("");
+
+    public VmOverviewPanel() {
+        super();
+        initializePanel();
+        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 setVmPid(String pid) {
+        this.pid.setText(pid);
+    }
+
+    @Override
+    public void setVmStartTimeStamp(String timeStamp) {
+        this.startTimeStamp.setText(timeStamp);
+    }
+
+    @Override
+    public void setVmStopTimeStamp(String timeStamp) {
+        this.stopTimeStamp.setText(timeStamp);
+    }
+
+    @Override
+    public void setMainClass(String mainClass) {
+        this.mainClass.setText(mainClass);
+    }
+
+    @Override
+    public void setJavaCommandLine(String javaCommandLine) {
+        this.javaCommandLine.setText(javaCommandLine);
+    }
+
+    @Override
+    public void setJavaHome(String javaHome) {
+        this.javaHome.setText(javaHome);
+
+    }
+
+    @Override
+    public void setJavaVersion(String javaVersion) {
+        this.javaVersion.setText(javaVersion);
+    }
+
+    @Override
+    public void setVmNameAndVersion(String vmNameAndVersion) {
+        this.vmNameAndVersion.setText(vmNameAndVersion);
+    }
+
+    @Override
+    public void setVmArguments(String vmArguments) {
+        this.vmArguments.setText(vmArguments);
+    }
+
+    @Override
+    public void setVmInfo(String string) {
+        // no-op
+    }
+
+    @Override
+    public Component getUiComponent() {
+        return visiblePanel;
+    }
+
+    private void initializePanel() {
+        visiblePanel = new HeaderPanel();
+
+        visiblePanel.setHeader(translator.localize(LocaleResources.VM_INFO_TITLE));
+
+        TableEntry entry;
+        List<Section> allSections = new ArrayList<Section>();
+
+        Section processSection = new Section(translator.localize(LocaleResources.VM_INFO_SECTION_PROCESS));
+        allSections.add(processSection);
+
+        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_PROCESS_ID), pid);
+        processSection.add(entry);
+        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_START_TIME), startTimeStamp);
+        processSection.add(entry);
+        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_STOP_TIME), stopTimeStamp);
+        processSection.add(entry);
+
+        Section javaSection = new Section(translator.localize(LocaleResources.VM_INFO_SECTION_JAVA));
+        allSections.add(javaSection);
+
+        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_MAIN_CLASS), mainClass);
+        javaSection.add(entry);
+        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_COMMAND_LINE), javaCommandLine);
+        javaSection.add(entry);
+        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_JAVA_VERSION), javaVersion);
+        javaSection.add(entry);
+        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_VM), vmNameAndVersion);
+        javaSection.add(entry);
+        entry = new TableEntry(translator.localize(LocaleResources.VM_INFO_VM_ARGUMENTS), vmArguments);
+        javaSection.add(entry);
+
+        SimpleTable simpleTable = new SimpleTable();
+        JPanel table = simpleTable.createTable(allSections);
+        table.setBorder(Components.smallBorder());
+        visiblePanel.setContent(table);
+    }
+}
Binary file client/swing/src/main/resources/duke.png has changed
Binary file client/swing/src/main/resources/icons/resize-grip.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/resources/icons/resize-grip.svg	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="13"
+   height="13"
+   id="svg17653"
+   version="1.1"
+   inkscape:version="0.48.2 r9819"
+   sodipodi:docname="resize-grip.svg">
+  <defs
+     id="defs17655" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="21.311078"
+     inkscape:cx="-8.2186936"
+     inkscape:cy="8.0008486"
+     inkscape:current-layer="layer1"
+     showgrid="true"
+     inkscape:grid-bbox="true"
+     inkscape:document-units="px"
+     inkscape:window-width="1920"
+     inkscape:window-height="1022"
+     inkscape:window-x="0"
+     inkscape:window-y="26"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata17658">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="layer1"
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     transform="translate(0,-3)">
+    <path
+       transform="matrix(0.65777374,0,0,0.65777374,-560.57081,-392.19484)"
+       d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z"
+       sodipodi:ry="1.9003495"
+       sodipodi:rx="1.9003495"
+       sodipodi:cy="617.14966"
+       sodipodi:cx="868.63647"
+       id="path5513"
+       style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new"
+       sodipodi:type="arc" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new"
+       id="path5515"
+       sodipodi:cx="868.63647"
+       sodipodi:cy="617.14966"
+       sodipodi:rx="1.9003495"
+       sodipodi:ry="1.9003495"
+       d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z"
+       transform="matrix(0.65777374,0,0,0.65777374,-563.84354,-392.19484)" />
+    <path
+       sodipodi:type="arc"
+       style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new"
+       id="path5517"
+       sodipodi:cx="868.63647"
+       sodipodi:cy="617.14966"
+       sodipodi:rx="1.9003495"
+       sodipodi:ry="1.9003495"
+       d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z"
+       transform="matrix(0.65777374,0,0,0.65777374,-560.57081,-395.46756)" />
+    <path
+       transform="matrix(0.65777374,0,0,0.65777374,-560.57081,-398.74029)"
+       d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z"
+       sodipodi:ry="1.9003495"
+       sodipodi:rx="1.9003495"
+       sodipodi:cy="617.14966"
+       sodipodi:cx="868.63647"
+       id="path5519"
+       style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new"
+       sodipodi:type="arc" />
+    <path
+       transform="matrix(0.65777374,0,0,0.65777374,-567.11626,-392.19484)"
+       d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z"
+       sodipodi:ry="1.9003495"
+       sodipodi:rx="1.9003495"
+       sodipodi:cy="617.14966"
+       sodipodi:cx="868.63647"
+       id="path5521"
+       style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new"
+       sodipodi:type="arc" />
+    <path
+       transform="matrix(0.65777374,0,0,0.65777374,-563.84354,-395.46756)"
+       d="m 870.53682,617.14966 a 1.9003495,1.9003495 0 1 1 -3.80069,0 1.9003495,1.9003495 0 1 1 3.80069,0 z"
+       sodipodi:ry="1.9003495"
+       sodipodi:rx="1.9003495"
+       sodipodi:cy="617.14966"
+       sodipodi:cx="868.63647"
+       id="path5523"
+       style="fill:#b9beb3;fill-opacity:1;stroke:none;display:inline;enable-background:new"
+       sodipodi:type="arc" />
+  </g>
+</svg>
Binary file client/swing/src/main/resources/icons/scale-slider-vert-backdrop.png has changed
Binary file client/swing/src/main/resources/icons/scale-slider-vert.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/IconDescriptorTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,98 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.ui.IconDescriptor;
+
+public class IconDescriptorTest {
+
+    @Test
+    public void test() throws IOException {
+        ClassLoader classLoader = IconResource.class.getClassLoader();
+        String resource = IconResource.JAVA_APPLICATION.getPath();
+        IconDescriptor descriptor = IconDescriptor.createFromClassloader(classLoader, resource);
+        ByteBuffer buffer = descriptor.getData();
+        
+        assertEquals(3512, buffer.capacity());
+        
+        byte[] data = buffer.array();
+        
+        // the first four bytes should be .PNG
+        int current = ((int) data[0]) & 0xFF;
+        assertEquals(0x89, current);
+        
+        current = ((int) data[1]) & 0xFF;
+        assertEquals(0x50, current);
+        
+        current = ((int) data[2]) & 0xFF;
+        assertEquals(0x4E, current);
+        
+        current = ((int) data[3]) & 0xFF;
+        assertEquals(0x47, current);
+        
+        // check IHDR chunk
+        current = ((int) data[12]) & 0xFF;
+        assertEquals(0x49, current);
+        
+        current = ((int) data[12]) & 0xFF;
+        assertEquals(0x49, current);
+        
+        current = ((int) data[13]) & 0xFF;
+        assertEquals(0x48, current);
+        
+        current = ((int) data[14]) & 0xFF;
+        assertEquals(0x44, current);
+        
+        current = ((int) data[15]) & 0xFF;
+        assertEquals(0x52, current);
+        
+        // get width and height, 4 bytes each, the icon is 16x16
+        current = ((int) data[16]) << 24 | ((int) data[17]) << 16 | ((int) data[18]) << 8 | (((int) data[19]) & 0xFF);
+        assertEquals(16, current);
+        
+        current = ((int) data[20]) << 24 | ((int) data[21]) << 16 | ((int) data[22]) << 8 | (((int) data[23]) & 0xFF);
+        assertEquals(16, current);
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/MainWindowTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,354 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.isA;
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JRadioButtonMenuItem;
+
+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.exception.ComponentLookupException;
+import org.fest.swing.fixture.FrameFixture;
+import org.fest.swing.fixture.JMenuItemFixture;
+import org.fest.swing.fixture.JTextComponentFixture;
+import org.fest.swing.fixture.JTreeFixture;
+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.HostFilter;
+import com.redhat.thermostat.client.core.views.SearchFieldView;
+import com.redhat.thermostat.client.osgi.service.HostDecorator;
+import com.redhat.thermostat.client.osgi.service.MenuAction;
+import com.redhat.thermostat.client.swing.internal.MainView;
+import com.redhat.thermostat.client.ui.Decorator;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.HostsVMsLoader;
+import com.redhat.thermostat.common.dao.HostRef;
+
+@RunWith(CacioFESTRunner.class)
+public class MainWindowTest {
+
+    private FrameFixture frameFixture;
+    private MainWindow window;
+    private ActionListener<MainView.Action> l;
+
+    @BeforeClass
+    public static void setUpOnce() {
+        FailOnThreadViolationRepaintManager.install();
+    }
+
+    @SuppressWarnings("unchecked") // mock(ActionListener.class)
+    @Before
+    public void setUp() {
+
+        GuiActionRunner.execute(new GuiTask() {
+            
+            @Override
+            protected void executeInEDT() throws Throwable {
+                window = new MainWindow();
+                l = mock(ActionListener.class);
+                window.addActionListener(l);
+            }
+        });
+
+        frameFixture = new FrameFixture(window);
+    }
+
+    @After
+    public void tearDown() {
+        frameFixture.cleanUp();
+        frameFixture = null;
+        window = null;
+        l = null;
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void testHostVmSelectionChangedSupport() {
+        frameFixture.show();
+        JTreeFixture hostVMTree = frameFixture.tree("agentVmTree");
+        hostVMTree.selectRows(0);
+
+        verify(l).actionPerformed(new ActionEvent<MainView.Action>(window, MainView.Action.HOST_VM_SELECTION_CHANGED));
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void testHostVmDecoratorsAdded() throws InterruptedException {
+        
+        List<HostDecorator> decorators = new ArrayList<>();
+        HostDecorator refDecorator = mock(HostDecorator.class);
+        final Decorator decorator = mock(Decorator.class);
+        when(decorator.getLabel(anyString())).thenReturn("fluff");
+        
+        when(refDecorator.getDecorator()).thenReturn(decorator);
+        
+        HostFilter filter = mock(HostFilter.class);
+        when(filter.matches(isA(HostRef.class))).thenReturn(false).thenReturn(true);
+
+        when(refDecorator.getFilter()).thenReturn(filter);
+        
+        decorators.add(refDecorator);
+        
+        HostsVMsLoader hostsVMsLoader = mock(HostsVMsLoader.class);
+        Collection<HostRef> expectedHosts = new ArrayList<>();
+        expectedHosts.add(new HostRef("123", "fluffhost1"));
+        expectedHosts.add(new HostRef("456", "fluffhost2"));
+        
+        when(hostsVMsLoader.getHosts()).thenReturn(expectedHosts);
+        
+        window.updateTree(null, null, decorators, null, hostsVMsLoader);
+
+        Thread.sleep(50);
+        
+        frameFixture.show();
+        frameFixture.requireVisible();
+        
+        verify(decorator, times(0)).getLabel("fluffhost1");
+        verify(decorator, atLeastOnce()).getLabel("fluffhost2");
+    }
+    
+    @Category(GUITest.class)
+    @Test
+    public void testHostVMTreeFilterPropertySupport() {
+        String SEARCH_TEXT = "test";
+        frameFixture.show();
+        JTextComponentFixture hostVMTreeFilterField = frameFixture.textBox(SearchFieldView.VIEW_NAME);
+        hostVMTreeFilterField.enterText(SEARCH_TEXT);
+
+        verify(l, times(SEARCH_TEXT.length())).actionPerformed(new ActionEvent<MainView.Action>(window, MainView.Action.HOST_VM_TREE_FILTER));
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void verifyThatCloseFiresShutdownEvent() {
+
+        frameFixture.show();
+
+        frameFixture.close();
+        frameFixture.requireNotVisible();
+        verify(l).actionPerformed(new ActionEvent<MainView.Action>(window, MainView.Action.SHUTDOWN));
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void verifyShowMainWindowShowsWindow() {
+        window.showMainWindow();
+        frameFixture.requireVisible();
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void verifyHideMainWindowHidesWindow() {
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                window.showMainWindow();
+            }
+        });
+        frameFixture.requireVisible();
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                window.hideMainWindow();
+            }
+        });
+        frameFixture.requireNotVisible();
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void verifyThatClientPreferencesMenuItemTriggersEvent() {
+        frameFixture.show();
+        JMenuItemFixture menuItem = frameFixture.menuItem("showClientConfig");
+        menuItem.click();
+        frameFixture.close();
+        frameFixture.requireNotVisible();
+
+        verify(l).actionPerformed(new ActionEvent<MainView.Action>(window, MainView.Action.SHOW_CLIENT_CONFIG));
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void verifyThatAgentPreferencesMenuItemTriggersEvent() {
+        frameFixture.show();
+        JMenuItemFixture menuItem = frameFixture.menuItem("showAgentConfig");
+        menuItem.click();
+        frameFixture.close();
+        frameFixture.requireNotVisible();
+
+        verify(l).actionPerformed(new ActionEvent<MainView.Action>(window, MainView.Action.SHOW_AGENT_CONFIG));
+    }
+
+
+    @Category(GUITest.class)
+    @Test
+    public void verifyThatHistorySwitchTriggersEvent() {
+        frameFixture.show();
+        JMenuItemFixture menuItem = frameFixture.menuItem("historyModeSwitch");
+        menuItem.click();
+        frameFixture.close();
+        frameFixture.requireNotVisible();
+
+        verify(l).actionPerformed(new ActionEvent<MainView.Action>(window, MainView.Action.SWITCH_HISTORY_MODE));
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void addRemoveMenu() {
+    	final String PARENT_NAME = "File";
+        final String MENU_NAME = "Test2";
+        MenuAction action = mock(MenuAction.class);
+        when(action.getName()).thenReturn(MENU_NAME);
+        when(action.getPath()).thenReturn(new String[] {PARENT_NAME, MENU_NAME});
+        when(action.getType()).thenReturn(MenuAction.Type.STANDARD);
+
+        JMenuItemFixture menuItem;
+
+        frameFixture.show();
+
+        window.addMenu(action);
+
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        assertNotNull(menuItem);
+        menuItem.click();
+
+        verify(action).execute();
+
+        window.removeMenu(action);
+
+        try {
+            menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+            // should not reach here
+            assertTrue(false);
+        } catch (ComponentLookupException cle) {
+            // expected
+        }
+    }
+    
+    @Category(GUITest.class)
+    @Test
+    public void addRadioMenu() {
+    	final String PARENT_NAME = "File";
+        final String MENU_NAME = "Test";
+        MenuAction action = mock(MenuAction.class);
+        when(action.getName()).thenReturn(MENU_NAME);
+        when(action.getPath()).thenReturn(new String[] {PARENT_NAME, MENU_NAME});
+
+
+        when(action.getType()).thenReturn(MenuAction.Type.RADIO);
+
+        JMenuItemFixture menuItem;
+
+        frameFixture.show();
+
+        window.addMenu(action);
+
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        assertNotNull(menuItem);
+
+        assertTrue(menuItem.target instanceof JRadioButtonMenuItem);
+    }
+    
+    @Category(GUITest.class)
+    @Test
+    public void addCheckBoxMenu() {
+    	final String PARENT_NAME = "File";
+        final String MENU_NAME = "Test";
+        MenuAction action = mock(MenuAction.class);
+        when(action.getName()).thenReturn(MENU_NAME);
+        when(action.getType()).thenReturn(MenuAction.Type.CHECK);
+        when(action.getPath()).thenReturn(new String[] {PARENT_NAME, MENU_NAME});
+
+
+        JMenuItemFixture menuItem;
+
+        frameFixture.show();
+
+        window.addMenu(action);
+
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        assertNotNull(menuItem);
+
+        assertTrue(menuItem.target instanceof JCheckBoxMenuItem);
+    }
+    
+    @Category(GUITest.class)
+    @Test
+    public void testGetHostVMTreeFilter() {
+        frameFixture.show();
+        JTextComponentFixture hostVMTreeFilterField = frameFixture.textBox(SearchFieldView.VIEW_NAME);
+        hostVMTreeFilterField.enterText("test");
+        String actual = window.getHostVmTreeFilterText();
+        assertEquals("test", actual);
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void testGetSelectedHostOrVm() {
+        frameFixture.show();
+        JTreeFixture hostVMTree = frameFixture.tree("agentVmTree");
+        hostVMTree.selectRow(0);
+
+        assertEquals(null, window.getSelectedHostOrVm());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/MenuHelperTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,241 @@
+/*
+ * 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;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import javax.swing.JCheckBoxMenuItem;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JRadioButtonMenuItem;
+
+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.exception.ComponentLookupException;
+import org.fest.swing.fixture.FrameFixture;
+import org.fest.swing.fixture.JMenuItemFixture;
+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.osgi.service.MenuAction;
+
+@RunWith(CacioFESTRunner.class)
+public class MenuHelperTest {
+
+    private FrameFixture frameFixture;
+    private JFrame window;
+    private MenuHelper menu;
+
+    @BeforeClass
+    public static void setUpOnce() {
+        FailOnThreadViolationRepaintManager.install();
+    }
+
+    @Before
+    public void setUp() {
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                window = new JFrame();
+                JMenuBar menuBar = new JMenuBar();
+                window.setJMenuBar(menuBar);
+                JMenu fileMenu = new JMenu("File");
+                fileMenu.setName("File");
+                menuBar.add(fileMenu);
+                menu = new MenuHelper(menuBar);
+                window.pack();
+            }
+        });
+
+        frameFixture = new FrameFixture(window);
+    }
+
+    @After
+    public void tearDown() {
+        frameFixture.cleanUp();
+        frameFixture = null;
+        window = null;
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void addRemoveWithNewTopLevelMenu() {
+        final String PARENT_NAME = "Test1";
+        final String MENU_NAME = "Test2";
+        MenuAction action = mock(MenuAction.class);
+        when(action.getName()).thenReturn(MENU_NAME);
+        when(action.getPath()).thenReturn(new String[] { PARENT_NAME, MENU_NAME });
+        when(action.getType()).thenReturn(MenuAction.Type.STANDARD);
+
+        JMenuItemFixture menuItem;
+
+        frameFixture.show();
+
+        menu.addMenuAction(action);
+
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        assertNotNull(menuItem);
+
+        menu.removeMenuAction(action);
+
+        try {
+            menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+            // should not reach here
+            assertTrue(false);
+        } catch (ComponentLookupException cle) {
+            // expected
+        }
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void addRemoveToExistingMenu() {
+        final String PARENT_NAME = "File";
+        final String MENU_NAME = "Test2";
+        MenuAction action = mock(MenuAction.class);
+        when(action.getName()).thenReturn(MENU_NAME);
+        when(action.getPath()).thenReturn(new String[] { PARENT_NAME, MENU_NAME });
+        when(action.getType()).thenReturn(MenuAction.Type.STANDARD);
+
+        JMenuItemFixture menuItem;
+
+        frameFixture.show();
+
+        assertNotNull(frameFixture.menuItem("File"));
+
+        menu.addMenuAction(action);
+
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        assertNotNull(menuItem);
+
+        menu.removeMenuAction(action);
+
+        try {
+            menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+            // should not reach here
+            assertTrue(false);
+        } catch (ComponentLookupException cle) {
+            // expected
+        }
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void addRemoveHighlyNextedMenu() {
+        final String[] path = new String[] { "View", "Filter", "Virtual Machine", "Show Only Running" };
+        MenuAction action = mock(MenuAction.class);
+        when(action.getName()).thenReturn(path[path.length - 1]);
+        when(action.getPath()).thenReturn(path);
+        when(action.getType()).thenReturn(MenuAction.Type.STANDARD);
+
+        JMenuItemFixture menuItem;
+
+        frameFixture.show();
+
+        menu.addMenuAction(action);
+
+        menuItem = frameFixture.menuItemWithPath(path);
+        assertNotNull(menuItem);
+
+        menu.removeMenuAction(action);
+
+        try {
+            menuItem = frameFixture.menuItemWithPath(path);
+            // should not reach here
+            assertTrue(false);
+        } catch (ComponentLookupException cle) {
+            // expected
+        }
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void addRadioMenu() {
+        final String PARENT_NAME = "File";
+        final String MENU_NAME = "Test";
+        MenuAction action = mock(MenuAction.class);
+        when(action.getName()).thenReturn(MENU_NAME);
+        when(action.getPath()).thenReturn(new String[] { PARENT_NAME, MENU_NAME });
+        when(action.getType()).thenReturn(MenuAction.Type.RADIO);
+
+        JMenuItemFixture menuItem;
+
+        frameFixture.show();
+
+        menu.addMenuAction(action);
+
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        assertNotNull(menuItem);
+
+        assertTrue(menuItem.target instanceof JRadioButtonMenuItem);
+    }
+
+    @Category(GUITest.class)
+    @Test
+    public void addCheckBoxMenu() {
+        final String PARENT_NAME = "File";
+        final String MENU_NAME = "Test";
+        MenuAction action = mock(MenuAction.class);
+        when(action.getName()).thenReturn(MENU_NAME);
+        when(action.getType()).thenReturn(MenuAction.Type.CHECK);
+        when(action.getPath()).thenReturn(new String[] { PARENT_NAME, MENU_NAME });
+
+        JMenuItemFixture menuItem;
+
+        frameFixture.show();
+
+        menu.addMenuAction(action);
+
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        assertNotNull(menuItem);
+
+        assertTrue(menuItem.target instanceof JCheckBoxMenuItem);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/TabbedPaneMatcher.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,18 @@
+package com.redhat.thermostat.client.swing;
+
+import javax.swing.JTabbedPane;
+
+import org.fest.swing.core.GenericTypeMatcher;
+
+public class TabbedPaneMatcher extends GenericTypeMatcher<JTabbedPane> {
+
+    public TabbedPaneMatcher(Class<JTabbedPane> supportedType) {
+        super(supportedType);
+    }
+
+    @Override
+    protected boolean isMatching(JTabbedPane tab) {
+        return tab.getTabCount() > 0;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/UIResourcesTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,141 @@
+/*
+ * 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;
+
+import java.awt.Color;
+import java.awt.Font;
+
+import javax.swing.LookAndFeel;
+import javax.swing.UIDefaults;
+import javax.swing.UIManager;
+import javax.swing.plaf.basic.BasicLookAndFeel;
+
+import junit.framework.Assert;
+
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.redhat.thermostat.test.Bug;
+
+@Bug(id="976",
+     summary="About dialog creashes with GTK look and feel",
+     url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=976")
+public class UIResourcesTest {
+   
+    private static LookAndFeel originalLaf;
+    
+    @BeforeClass
+    public static void setUp() throws Exception {
+        final Object [] uiDefaults = new Object[] {
+            "Button.darkShadow", null,
+            "Button.focus", null,
+            "Label.font", null
+        };
+        
+        originalLaf = UIManager.getLookAndFeel();
+        UIManager.setLookAndFeel(new BasicLookAndFeel() {
+            
+            @Override
+            protected void initClassDefaults(UIDefaults table) {
+                super.initClassDefaults(table);
+                table.putDefaults(uiDefaults);
+            }
+            
+            @Override
+            protected void initSystemColorDefaults(UIDefaults table) {
+                super.initSystemColorDefaults(table);
+                table.putDefaults(uiDefaults);
+            }
+            
+            @Override
+            protected void initComponentDefaults(UIDefaults table) {
+                super.initComponentDefaults(table);
+                table.putDefaults(uiDefaults);
+            }
+            
+            @Override
+            public boolean isSupportedLookAndFeel() {
+                return true;
+            }
+            
+            @Override
+            public boolean isNativeLookAndFeel() {
+                return false;
+            }
+            
+            @Override
+            public String getName() {
+                return "fluff";
+            }
+            
+            @Override
+            public String getID() {
+                return "fluff";
+            }
+            
+            @Override
+            public String getDescription() {
+                return "fluff";
+            }
+        });
+    }
+    
+    @Test
+    public void testHyperlinkColor() {
+        Assert.assertEquals(Color.BLUE, UIResources.getInstance().hyperlinkColor());
+    }
+
+    @Test
+    public void testHyperlinkActiveColor() {
+        Assert.assertEquals(Color.BLUE, UIResources.getInstance().hyperlinkActiveColor());
+    }
+
+    @Test
+    public void testStandardFont() {
+        Assert.assertEquals(Font.DIALOG, UIResources.getInstance().standardFont().getName());
+    }
+    
+    @AfterClass
+    public static void tearDown() throws Exception {
+        if (originalLaf != null) {
+            UIManager.setLookAndFeel(originalLaf);
+        } else {
+            UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/EdtHelperTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,194 @@
+/*
+ * 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.assertSame;
+import static org.junit.Assert.assertTrue;
+
+import java.awt.EventQueue;
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.Callable;
+
+import javax.swing.SwingUtilities;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class EdtHelperTest {
+
+    private class ExceptionCallable implements Callable<Object>  {
+
+        @Override
+        public Object call() throws Exception {
+            throw new Exception("fluff");
+        }
+        
+    }
+
+    private class ResultCallable implements Callable<Object> {
+    
+        private Object result;
+        private ResultCallable(Object r) {
+            result = r;
+        }
+        @Override
+        public Object call() throws Exception {
+            // By waiting here, we make sure the EDTHelper actually waits for the call.
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            if (EventQueue.isDispatchThread()) {
+                calledOnEDT = true;
+            }
+            return result;
+        }
+        
+    }
+
+    private class TestRunnable implements Runnable {
+
+        @Override
+        public void run() {
+            // By waiting here, we make sure the EDTHelper actually waits for the call.
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+            }
+            if (EventQueue.isDispatchThread()) {
+                calledOnEDT = true;
+            }
+        }
+        
+    }
+
+    private volatile boolean calledOnEDT;
+
+    @Before
+    public void setUp() {
+        calledOnEDT = false;
+    }
+
+    @After
+    public void tearDown() {
+        calledOnEDT = false;
+    }
+
+    @Test
+    public void testCallRunnableFromNonEDT() throws InvocationTargetException, InterruptedException {
+        Runnable r = new TestRunnable();
+        new EdtHelper().callAndWait(r);
+        assertTrue(calledOnEDT);
+    }
+
+    @Test
+    public void testCallRunnableFromEDT() throws InvocationTargetException, InterruptedException {
+        final Runnable r = new TestRunnable();
+        SwingUtilities.invokeAndWait(new Runnable() {
+            
+            @Override
+            public void run() {
+                try {
+                    new EdtHelper().callAndWait(r);
+                } catch (InvocationTargetException e) {
+                    throw new RuntimeException(e);
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                }
+            }
+        });
+        assertTrue(calledOnEDT);
+    }
+
+    @Test
+    public void testCallCallableFromNoEDT() throws InvocationTargetException, InterruptedException {
+        final Object expected = new Object();
+        Callable<Object> c = new ResultCallable(expected);
+        Object result = new EdtHelper().callAndWait(c);
+        assertTrue(calledOnEDT);
+        assertSame(expected, result);
+    }
+
+    @Test
+    public void testCallCallableFromEDT() throws InvocationTargetException, InterruptedException {
+        final Object expected = new Object();
+        final Callable<Object> c = new ResultCallable(expected);
+        final Object[] result = new Object[1];
+        SwingUtilities.invokeAndWait(new Runnable() {
+            
+            @Override
+            public void run() {
+                try {
+                    result[0] = new EdtHelper().callAndWait(c);
+                } catch (InvocationTargetException | InterruptedException e) {
+                    throw new RuntimeException();
+                }
+            }
+        });
+        assertTrue(calledOnEDT);
+        assertSame(expected, result[0]);
+    }
+
+    @Test(expected=InvocationTargetException.class)
+    public void testCallCallableFromNoEDTThrowingException() throws InvocationTargetException, InterruptedException {
+        Callable<Object> c = new ExceptionCallable();
+        new EdtHelper().callAndWait(c);
+    }
+
+    @Test
+    public void testCallCallableFromEDTThrowingException() throws InvocationTargetException, InterruptedException {
+        final boolean[] exceptionThrown = new boolean[1];
+        final Callable<Object> c = new ExceptionCallable();
+        SwingUtilities.invokeAndWait(new Runnable() {
+            
+            @Override
+            public void run() {
+                try {
+                    new EdtHelper().callAndWait(c);
+                } catch (InvocationTargetException e) {
+                    exceptionThrown[0] = true;
+                } catch (InterruptedException e) {
+                    Thread.currentThread().interrupt();
+                }
+            }
+        });
+        assertTrue(exceptionThrown[0]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/StatusBarTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,154 @@
+/*
+ * 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.*;
+
+import java.awt.BorderLayout;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.concurrent.Semaphore;
+
+import javax.swing.JFrame;
+
+import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner;
+
+import org.fest.swing.annotation.GUITest;
+import org.fest.swing.annotation.RunsInEDT;
+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.JLabelFixture;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(CacioFESTRunner.class)
+public class StatusBarTest {
+
+    private JFrame frame;
+    private FrameFixture frameFixture;
+    
+    private StatusBar statusBar;
+    
+    @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.getContentPane().setLayout(new BorderLayout());
+                
+                statusBar = new StatusBar();
+                frame.getContentPane().add(statusBar, BorderLayout.SOUTH);
+                
+                frame.setSize(500, 500);
+            }
+        });
+        frameFixture = new FrameFixture(frame);
+    }
+    
+    @After
+    public void tearDown() {
+        frameFixture.cleanUp();
+        frameFixture = null;
+    }
+    
+    @Test
+    @GUITest
+    @RunsInEDT
+    public void testSetPrimaryStatusLabel() throws InterruptedException {
+        frameFixture.show();
+        
+        JLabelFixture labelfixture = frameFixture.label("primaryStatusLabel");
+        labelfixture.requireText("");
+        
+        final Semaphore sem = new Semaphore(0);
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                statusBar.setPrimaryStatus("test");
+                sem.release();
+            }
+        });
+        sem.acquire();
+        
+        // the label has an extra space at the beginning
+        labelfixture.requireText(" test");
+    }
+    
+    @Test
+    @GUITest
+    @RunsInEDT
+    public void testSetPrimaryStatusLabelWithProperty() throws InterruptedException {
+        frameFixture.show();
+        
+        final String[] primaryStatus = new String[2];
+        
+        final Semaphore sem = new Semaphore(2);
+        statusBar.addPropertyChangeListener(StatusBar.PRIMARY_STATUS_PROPERTY,
+                                                      new PropertyChangeListener()
+        {
+            @Override
+            public void propertyChange(PropertyChangeEvent evt) {
+                primaryStatus[0] = (String) evt.getOldValue();
+                primaryStatus[1] = (String) evt.getNewValue();
+                sem.release();
+            }
+        });
+        
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                statusBar.setPrimaryStatus("test");
+                sem.release();
+            }
+        });
+        sem.acquire(2);
+        
+        assertEquals("", primaryStatus[0]);
+        assertEquals("test", primaryStatus[1]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/models/LongRangeNormalizerTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,120 @@
+/*
+ * 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.models;
+
+import static org.junit.Assert.*;
+import junit.framework.Assert;
+
+import org.junit.Test;
+
+public class LongRangeNormalizerTest {
+
+    @Test
+    public void testSameRange() {
+        
+        LongRange range = new LongRange();
+        range.setMax(10);
+        range.setMin(0);
+        
+        LongRangeNormalizer model = new LongRangeNormalizer(range);
+        
+        model.setValue(5);
+        
+        model.setMaxNormalized(10);
+        model.setMinNormalized(0);
+        
+        
+        Assert.assertEquals((int) model.getValue(), model.getValueNormalized());
+    }
+
+    @Test
+    public void testDoubleRange() {
+        
+        LongRange range = new LongRange();
+        range.setMax(10);
+        range.setMin(0);
+        
+        LongRangeNormalizer model = new LongRangeNormalizer(range);
+        
+        model.setValue(5);
+        
+        model.setMaxNormalized(20);
+        model.setMinNormalized(0);
+        
+        
+        Assert.assertEquals(10, model.getValueNormalized());
+    }
+    
+    @Test
+    public void testRanges() {
+        
+        LongRange range = new LongRange();
+        range.setMax(10);
+        range.setMin(0);
+        
+        LongRangeNormalizer model = new LongRangeNormalizer(range);
+        
+        model.setValue(5);
+        
+        model.setMaxNormalized(40);
+        model.setMinNormalized(0);
+                
+        Assert.assertEquals(20, model.getValueNormalized());
+        
+        model.setMaxNormalized(60);
+        model.setMinNormalized(0);
+                
+        Assert.assertEquals(30, model.getValueNormalized());
+                
+        model.setMaxNormalized(200);
+        model.setMinNormalized(100);
+                
+        Assert.assertEquals(150, model.getValueNormalized());
+        
+        range.setMax(100);
+        range.setMin(0);
+        model.setValue(50);
+        
+        model.setMaxNormalized(1);
+        model.setMinNormalized(0);
+                
+        Assert.assertEquals(1, model.getValueNormalized());
+        
+        model.setValue(49);
+        Assert.assertEquals(0, model.getValueNormalized());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/models/NullSelectionModelTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.components.models;
+
+import static org.junit.Assert.*;
+
+import javax.swing.DefaultListModel;
+import javax.swing.JFrame;
+import javax.swing.JList;
+
+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.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(CacioFESTRunner.class)
+public class NullSelectionModelTest {
+
+    private JFrame frame;
+    private FrameFixture frameFixture;
+    private JList<String> list;
+    
+    @BeforeClass
+    public static void setUpOnce() {
+        FailOnThreadViolationRepaintManager.install();
+    }
+    
+    @Before
+    public void setUp() {
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                frame = new JFrame();
+                
+                DefaultListModel<String> model = new DefaultListModel<>();
+                
+                model.addElement("fluff #1");
+                model.addElement("fluff #2");
+                model.addElement("fluff #3");
+                model.addElement("fluff #4");
+                model.addElement("fluff #5");
+
+                list = new JList<>(model);
+                list.setSelectionModel(new NullSelectionModel());
+                
+                frame.add(list);
+            }
+        });
+        frameFixture = new FrameFixture(frame);
+    }
+    
+    @After
+    public void tearDown() {
+        frameFixture.cleanUp();
+        frameFixture = null;
+    }
+    
+    @GUITest
+    @Test
+    public void testCellNotSelectable() {
+        frameFixture.show();
+        
+        String[] selection = frameFixture.list().selection();
+        assertEquals(0, selection.length);
+        frameFixture.list().clickItem(2);
+        selection = frameFixture.list().selection();
+        assertEquals(0, selection.length);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/GUIClientCommandTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,118 @@
+/*
+ * 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.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Dictionary;
+
+import org.apache.commons.cli.Options;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+
+import com.redhat.thermostat.client.osgi.service.ApplicationService;
+import com.redhat.thermostat.client.osgi.service.ContextAction;
+import com.redhat.thermostat.common.cli.CommandContext;
+import com.redhat.thermostat.common.cli.CommandContextFactory;
+import com.redhat.thermostat.common.cli.CommandException;
+
+public class GUIClientCommandTest {
+
+    private GUIClientCommand cmd;
+    private Main clientMain;
+
+    @Before
+    public void setUp() {
+        clientMain = mock(Main.class);
+        cmd = new GUIClientCommand(clientMain);
+    }
+
+    @After
+    public void tearDown() {
+        cmd = null;
+        clientMain = null;
+    }
+
+    @Test
+    public void testRun() throws CommandException {
+        BundleContext bCtx = mock(BundleContext.class);
+        CommandContextFactory cmdCtxFactory = mock(CommandContextFactory.class);
+
+        CommandContext cmdCtx = mock(CommandContext.class);
+        when(cmdCtx.getCommandContextFactory()).thenReturn(cmdCtxFactory);
+
+        cmd.setBundleContext(bCtx);
+        cmd.run(cmdCtx);
+
+        verify(clientMain).run();
+        verify(bCtx).registerService(eq(ApplicationService.class.getName()), isNotNull(), any(Dictionary.class));
+        verify(bCtx).registerService(eq(ContextAction.class.getName()), isNotNull(), any(Dictionary.class));
+    }
+
+    @Test
+    public void testName() {
+        assertEquals("gui", cmd.getName());
+    }
+
+    @Test
+    public void testDescAndUsage() {
+        assertNotNull(cmd.getDescription());
+        assertNotNull(cmd.getUsage());
+    }
+
+    @Test
+    public void testRequiresStorage() {
+        assertFalse(cmd.isStorageRequired());
+    }
+
+    @Test
+    public void testOptions() {
+        Options options = cmd.getOptions();
+        assertNotNull(options);
+        assertEquals(0, options.getOptions().size());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/HostIconDecoratorTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,89 @@
+/*
+ * 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.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import java.awt.image.BufferedImage;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+
+import javax.imageio.ImageIO;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.core.HostFilter;
+import com.redhat.thermostat.client.ui.Decorator;
+import com.redhat.thermostat.common.dao.HostRef;
+
+public class HostIconDecoratorTest {
+
+    @Test
+    public void verifyFilter() {
+        HostIconDecorator decorator = new HostIconDecorator();
+
+        HostFilter filter = decorator.getFilter();
+        HostRef aHost = mock(HostRef.class);
+
+        assertTrue(filter.matches(aHost));
+    }
+
+    @Test
+    public void verifyHostDecoratorDoesNotModifyLabel() {
+        HostIconDecorator iconDecorator = new HostIconDecorator();
+
+        Decorator decorator = iconDecorator.getDecorator();
+
+        String INPUT = "testfoobarbaz";
+
+        assertEquals(INPUT, decorator.getLabel(INPUT));
+    }
+
+    @Test
+    public void verifyHostDecoratorHasAnIcon() throws IOException {
+        HostIconDecorator iconDecorator = new HostIconDecorator();
+
+        Decorator decorator = iconDecorator.getDecorator();
+
+        BufferedImage icon = ImageIO.read(new ByteArrayInputStream(decorator.getIconDescriptor().getData().array()));
+
+        assertNotNull(icon);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,202 @@
+/*
+ * 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.mockito.Matchers.isA;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.concurrent.ExecutorService;
+
+import javax.swing.SwingUtilities;
+
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import com.redhat.thermostat.client.osgi.service.ApplicationService;
+import com.redhat.thermostat.client.ui.MainWindowController;
+import com.redhat.thermostat.client.ui.UiFacadeFactory;
+import com.redhat.thermostat.common.TimerFactory;
+import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.storage.Connection;
+import com.redhat.thermostat.common.storage.Connection.ConnectionListener;
+import com.redhat.thermostat.common.storage.Connection.ConnectionStatus;
+import com.redhat.thermostat.common.utils.OSGIUtils;
+
+public class MainTest {
+
+    private ExecutorService executorService;
+    private OSGIUtils serviceProvider;
+
+    private MainWindowController mainWindowController;
+    private UiFacadeFactory uiFactory;
+
+    private Connection connection;
+    private ArgumentCaptor<ConnectionListener> connectionListenerCaptor;
+
+    private DAOFactory daoFactory;
+
+    private TimerFactory timerFactory;
+
+    @Before
+    public void setUp() {
+        ApplicationService appService = mock(ApplicationService.class);
+
+        executorService = mock(ExecutorService.class);
+        doAnswer(new Answer<Void>() {
+            @Override
+            public Void answer(InvocationOnMock invocation) throws Throwable {
+                Runnable runnable = (Runnable) invocation.getArguments()[0];
+                runnable.run();
+                return null;
+            }
+        }).when(executorService).execute(isA(Runnable.class));
+
+        when(appService.getApplicationExecutor()).thenReturn(executorService);
+
+        serviceProvider = mock(OSGIUtils.class);
+        when(serviceProvider.getService(ApplicationService.class)).thenReturn(appService);
+
+        mainWindowController = mock(MainWindowController.class);
+
+        uiFactory = mock(UiFacadeFactory.class);
+        when(uiFactory.getMainWindow()).thenReturn(mainWindowController);
+
+        connection = mock(Connection.class);
+        connectionListenerCaptor = ArgumentCaptor.forClass(ConnectionListener.class);
+        doNothing().when(connection).addListener(connectionListenerCaptor.capture());
+
+        daoFactory = mock(DAOFactory.class);
+        when(daoFactory.getConnection()).thenReturn(connection);
+
+        timerFactory = mock(TimerFactory.class);
+    }
+
+    /**
+     * Handle all outstanding EDT events by posting a no-op event and waiting
+     * until it completes.
+     */
+    private void handleAllEdtEvents() throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                /* NO-OP */
+            }
+        });
+    }
+
+    @Test
+    public void verifyRunWaitsForShutdown() throws Exception {
+        Main main = new Main(serviceProvider, uiFactory, daoFactory, timerFactory);
+
+        main.run();
+
+        handleAllEdtEvents();
+
+        verify(uiFactory).awaitShutdown();
+    }
+
+    @Test
+    public void verifyConnectionIsMade() throws Exception {
+        Main main = new Main(serviceProvider, uiFactory, daoFactory, timerFactory);
+
+        main.run();
+
+        handleAllEdtEvents();
+
+        verify(connection).connect();
+
+    }
+
+    @Test
+    public void verifySuccessfulConnectionTriggersMainWindowToBeShown() throws Exception {
+        Main main = new Main(serviceProvider, uiFactory, daoFactory, timerFactory);
+
+        main.run();
+
+        handleAllEdtEvents();
+
+        ConnectionListener connectionListener = connectionListenerCaptor.getValue();
+        connectionListener.changed(ConnectionStatus.CONNECTED);
+
+        handleAllEdtEvents();
+
+        verify(mainWindowController).showMainMainWindow();
+    }
+
+    @Test
+    public void verifySuccessfulConnectionRegistersDAOs() throws Exception {
+
+        Main main = new Main(serviceProvider, uiFactory, daoFactory, timerFactory);
+
+        main.run();
+
+        handleAllEdtEvents();
+
+        ConnectionListener connectionListener = connectionListenerCaptor.getValue();
+        connectionListener.changed(ConnectionStatus.CONNECTED);
+
+        handleAllEdtEvents();
+
+        verify(daoFactory).registerDAOsAndStorageAsOSGiServices();
+    }
+
+    @Ignore("this prompts the user with some gui")
+    @Test
+    public void verifyFailedConnectionTriggersShutdown() throws Exception {
+
+        Main main = new Main(serviceProvider, uiFactory, daoFactory, timerFactory);
+
+        main.run();
+
+        handleAllEdtEvents();
+
+        ConnectionListener connectionListener = connectionListenerCaptor.getValue();
+        connectionListener.changed(ConnectionStatus.FAILED_TO_CONNECT);
+
+        handleAllEdtEvents();
+
+        verify(uiFactory).shutdown();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImplTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,561 @@
+/*
+ * 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.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyInt;
+import static org.mockito.Matchers.isA;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.awt.event.MouseEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.osgi.framework.BundleException;
+
+import com.redhat.thermostat.client.core.VmFilter;
+import com.redhat.thermostat.client.core.views.BasicView;
+import com.redhat.thermostat.client.osgi.service.MenuAction;
+import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.osgi.service.VmDecorator;
+import com.redhat.thermostat.client.ui.HostVmFilter;
+import com.redhat.thermostat.client.ui.SummaryController;
+import com.redhat.thermostat.client.ui.UiFacadeFactory;
+import com.redhat.thermostat.client.ui.VmInformationController;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.HostsVMsLoader;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+import com.redhat.thermostat.common.Timer;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry.Action;
+import com.redhat.thermostat.common.Timer.SchedulingType;
+import com.redhat.thermostat.common.TimerFactory;
+import com.redhat.thermostat.common.appctx.ApplicationContext;
+import com.redhat.thermostat.common.appctx.ApplicationContextUtil;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.VmInfoDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.model.VmInfo;
+import com.redhat.thermostat.test.Bug;
+
+public class MainWindowControllerImplTest {
+
+    private ActionListener<MainView.Action> l;
+
+    private MainWindowControllerImpl controller;
+
+    private UiFacadeFactory uiFacadeFactory;
+    
+    private MainView view;
+
+    private Timer mainWindowTimer;
+
+    private HostInfoDAO mockHostsDAO;
+    private VmInfoDAO mockVmsDAO;
+
+    private VMContextAction action1;
+    private VMContextAction action2;
+
+    private HostFilterRegistry hostFilterRegistry;
+    private VmFilterRegistry vmFilterRegistry;
+    private HostTreeDecoratorRegistry hostDecoratorRegistry;
+    private VMTreeDecoratorRegistry vmDecoratorRegistry;
+    private VMInformationRegistry vmInfoRegistry;
+    private MenuRegistry menus;
+    
+    @SuppressWarnings("unused")
+    private ActionListener<ThermostatExtensionRegistry.Action> hostFiltersListener;
+    @SuppressWarnings("unused")
+    private ActionListener<ThermostatExtensionRegistry.Action> vmFiltersListener;
+    private ActionListener<ThermostatExtensionRegistry.Action> decoratorsListener;
+    
+    @BeforeClass
+    public static void setUpOnce() {
+        // TODO remove when controller uses mocked objects rather than real swing objects
+        FailOnThreadViolationRepaintManager.install();
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" }) // ActionListener fluff
+    @Before
+    public void setUp() throws Exception {
+        ApplicationContextUtil.resetApplicationContext();
+
+        // Setup timers
+        mainWindowTimer = mock(Timer.class);
+        Timer otherTimer = mock(Timer.class); // FIXME needed for SummaryView; remove later
+        TimerFactory timerFactory = mock(TimerFactory.class);
+        when(timerFactory.createTimer()).thenReturn(mainWindowTimer).thenReturn(otherTimer);
+        ApplicationContext.getInstance().setTimerFactory(timerFactory);
+
+        SummaryController summaryController = mock(SummaryController.class);
+
+        uiFacadeFactory = mock(UiFacadeFactory.class);
+        
+        when(uiFacadeFactory.getSummary()).thenReturn(summaryController);
+
+        mockHostsDAO = mock(HostInfoDAO.class);
+        mockVmsDAO = mock(VmInfoDAO.class);
+
+        // Setup View
+        view = mock(MainView.class);
+        ArgumentCaptor<ActionListener> grabListener = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(view).addActionListener(grabListener.capture());
+        
+        RegistryFactory registryFactory = mock(RegistryFactory.class);
+        hostFilterRegistry = mock(HostFilterRegistry.class);
+        vmFilterRegistry = mock(VmFilterRegistry.class);
+        hostDecoratorRegistry = mock(HostTreeDecoratorRegistry.class);
+        vmDecoratorRegistry = mock(VMTreeDecoratorRegistry.class);
+        vmInfoRegistry = mock(VMInformationRegistry.class);
+        menus = mock(MenuRegistry.class);
+
+        when(registryFactory.createMenuRegistry()).thenReturn(menus);
+        when(registryFactory.createHostTreeDecoratorRegistry()).thenReturn(hostDecoratorRegistry);
+        when(registryFactory.createVMTreeDecoratorRegistry()).thenReturn(vmDecoratorRegistry);
+        when(registryFactory.createHostFilterRegistry()).thenReturn(hostFilterRegistry);
+        when(registryFactory.createVmFilterRegistry()).thenReturn(vmFilterRegistry);
+        when(registryFactory.createVMInformationRegistry()).thenReturn(vmInfoRegistry);
+        
+        ArgumentCaptor<ActionListener> grabHostFiltersListener = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(hostFilterRegistry).addActionListener(grabHostFiltersListener.capture());
+
+        ArgumentCaptor<ActionListener> grabVmFiltersListener = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(vmFilterRegistry).addActionListener(grabVmFiltersListener.capture());
+
+        ArgumentCaptor<ActionListener> grabDecoratorsListener = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(vmDecoratorRegistry).addActionListener(grabDecoratorsListener.capture());
+        
+        ArgumentCaptor<ActionListener> grabInfoRegistry = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(vmInfoRegistry).addActionListener(grabInfoRegistry.capture());
+
+        setUpVMContextActions();
+
+        controller = new MainWindowControllerImpl(uiFacadeFactory, view, registryFactory, mockHostsDAO, mockVmsDAO);
+        l = grabListener.getValue();
+        
+        hostFiltersListener = grabHostFiltersListener.getValue();
+        vmFiltersListener = grabVmFiltersListener.getValue();
+        decoratorsListener = grabDecoratorsListener.getValue();
+    }
+
+    private void setUpVMContextActions() {
+        action1 = mock(VMContextAction.class);
+        VmFilter action1Filter = mock(VmFilter.class);
+        when(action1Filter.matches(isA(VmRef.class))).thenReturn(true);
+
+        when(action1.getName()).thenReturn("action1");
+        when(action1.getDescription()).thenReturn("action1desc");
+        when(action1.getFilter()).thenReturn(action1Filter);
+        
+        action2 = mock(VMContextAction.class);
+        VmFilter action2Filter = mock(VmFilter.class);
+        when(action2Filter.matches(isA(VmRef.class))).thenReturn(false);
+
+        when(action2.getName()).thenReturn("action2");
+        when(action2.getDescription()).thenReturn("action2desc");
+        when(action2.getFilter()).thenReturn(action2Filter);
+        
+        Collection<VMContextAction> actions = new ArrayList<>();
+        actions.add(action1);
+        actions.add(action2);
+        
+        when(uiFacadeFactory.getVMContextActions()).thenReturn(actions);
+    }
+
+    @After
+    public void tearDown() {
+        view = null;
+        controller = null;
+        mockHostsDAO = null;
+        mockVmsDAO = null;
+        l = null;
+        ApplicationContextUtil.resetApplicationContext();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void verifyDecoratorsAdded() {
+
+        List<VmDecorator> currentDecoratros = controller.getVmTreeDecorators();
+        assertEquals(0, currentDecoratros.size());
+        
+        ActionEvent<ThermostatExtensionRegistry.Action> event =
+                new ActionEvent<ThermostatExtensionRegistry.Action>(vmDecoratorRegistry,
+                        ThermostatExtensionRegistry.Action.SERVICE_ADDED);
+        
+        VmDecorator payload = mock(VmDecorator.class);
+        event.setPayload(payload);
+        
+        decoratorsListener.actionPerformed(event);
+
+        currentDecoratros = controller.getVmTreeDecorators();
+        assertEquals(1, currentDecoratros.size());
+        assertEquals(payload, currentDecoratros.get(0));
+        
+        verify(view).updateTree(any(List.class), isA(List.class), isA(List.class), any(List.class), any(HostsVMsLoader.class));
+    }
+    
+    @Test
+    public void verifyThatHiddenEventStopsController() {
+
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HIDDEN));
+
+        verify(mainWindowTimer).stop();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void verifyThatHostsVmsFilterChangeUpdatesTree() {
+
+        when(view.getHostVmTreeFilterText()).thenReturn("test");
+
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_TREE_FILTER));
+
+        verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), isA(HostsVMsLoader.class));
+    }
+    
+    @Test
+    public void verifyTimerGetsStartedOnBecomingVisible() {
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.VISIBLE));
+
+        verify(mainWindowTimer).setDelay(3);
+        verify(mainWindowTimer).setTimeUnit(TimeUnit.SECONDS);
+        verify(mainWindowTimer).setSchedulingType(SchedulingType.FIXED_RATE);
+        verify(mainWindowTimer).start();
+    }
+
+    @Test
+    public void verifyShowMainWindowActuallyCallsView() {
+        controller.showMainMainWindow();
+        verify(view).showMainWindow();
+    }
+
+    @Test
+    public void verifySubViewIsSetByDefault() throws InvocationTargetException, InterruptedException {
+        verify(view).setSubView(any(BasicView.class));
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void verifyUpdateHostsVMsLoadsCorrectHosts() {
+
+        Collection<HostRef> expectedHosts = new ArrayList<>();
+        expectedHosts.add(new HostRef("123", "fluffhost1"));
+        expectedHosts.add(new HostRef("456", "fluffhost2"));
+
+        when(mockHostsDAO.getAliveHosts()).thenReturn(expectedHosts);
+
+        controller.doUpdateTreeAsync();
+
+        ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
+        verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), arg.capture());
+        HostsVMsLoader loader = arg.getValue();
+
+        Collection<HostRef> actualHosts = loader.getHosts();
+        assertEqualCollection(expectedHosts, actualHosts);
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void verifyHistoryModeUpdateHostsVMCorrectly() {
+
+        Collection<HostRef> liveHost = new ArrayList<>();
+        liveHost.add(new HostRef("123", "fluffhost1"));
+        liveHost.add(new HostRef("456", "fluffhost2"));
+
+        Collection<HostRef> allHosts = new ArrayList<>();
+        allHosts.addAll(liveHost);
+        allHosts.add(new HostRef("789", "fluffhost3"));
+
+        when(mockHostsDAO.getAliveHosts()).thenReturn(liveHost);
+        when(mockHostsDAO.getHosts()).thenReturn(allHosts);
+
+        controller.doUpdateTreeAsync();
+
+        ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
+        verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), arg.capture());
+        HostsVMsLoader loader = arg.getValue();
+
+        Collection<HostRef> actualHosts = loader.getHosts();
+        assertEqualCollection(liveHost, actualHosts);
+
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.SWITCH_HISTORY_MODE));
+        ArgumentCaptor<HostsVMsLoader> argCaptor = ArgumentCaptor.forClass(HostsVMsLoader.class);
+        // actionPerformed triggers updateTree
+        verify(view, times(2)).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), argCaptor.capture());
+        loader = argCaptor.getValue();
+
+        actualHosts = loader.getHosts();
+        assertEqualCollection(allHosts, actualHosts);
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void verifyUpdateHostsVMsLoadsCorrectVMs() {
+
+        Collection<VmRef> expectedVMs = new ArrayList<>();
+        HostRef host = new HostRef("123", "fluffhost1");
+        expectedVMs.add(new VmRef(host, 123, "vm1"));
+        expectedVMs.add(new VmRef(host, 456, "vm2"));
+
+        when(mockVmsDAO.getVMs(any(HostRef.class))).thenReturn(expectedVMs);
+
+        controller.doUpdateTreeAsync();
+
+        ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
+        verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), arg.capture());
+        HostsVMsLoader loader = arg.getValue();
+
+        Collection<VmRef> actualVMs = loader.getVMs(host);
+        assertEqualCollection(expectedVMs, actualVMs);
+    }
+
+    @Test
+    public void verifyUpdateHostsVMsLoadsCorrectVMWithFilter() {
+
+        VmRef ref1 = mock(VmRef.class);
+        when(ref1.getStringID()).thenReturn("test1");
+        when(ref1.getName()).thenReturn("test1");
+        
+        VmRef ref2 = mock(VmRef.class);
+        when(ref2.getStringID()).thenReturn("test2");
+        when(ref2.getName()).thenReturn("test2");
+        
+        controller.setHostVmTreeFilter("test1");
+                
+        HostVmFilter filter = controller.getSearchFilter();
+        assertTrue(filter.matches(ref1));
+        assertFalse(filter.matches(ref2));
+    }
+    
+    private void assertEqualCollection(Collection<?> expected, Collection<?> actual) {
+        assertEquals(expected.size(), actual.size());
+        assertTrue(expected.containsAll(actual));
+    }
+
+    @Test
+    @Bug(id="954",
+         summary="Thermostat GUI client should remember my last panel selected",
+         url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=954")
+    public void verifyOpenSameHostVMTab() throws Exception {
+
+        VmRef vmRef = mock(VmRef.class);
+        when(vmRef.getName()).thenReturn("testvm");
+        when(vmRef.getIdString()).thenReturn("testvmid");
+        HostRef ref = mock(HostRef.class);
+        when(ref.getAgentId()).thenReturn("agentId");
+        when(vmRef.getAgent()).thenReturn(ref);
+        
+        when(view.getSelectedHostOrVm()).thenReturn(vmRef);
+
+        VmInformationController vmInformationController = mock(VmInformationController.class);
+        when(vmInformationController.getSelectedChildID()).thenReturn(3);
+        when(uiFacadeFactory.getVmController(any(VmRef.class))).thenReturn(vmInformationController);
+        when(vmInformationController.selectChildID(anyInt())).thenReturn(true);
+
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
+
+        ArgumentCaptor<Integer> arg = ArgumentCaptor.forClass(Integer.class);
+        verify(vmInformationController).selectChildID(arg.capture());
+        verify(vmInformationController, times(0)).getSelectedChildID();
+
+        int id = arg.getValue();
+
+        assertEquals(0, id);
+
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
+
+        arg = ArgumentCaptor.forClass(Integer.class);
+        verify(vmInformationController, times(1)).getSelectedChildID();
+        verify(vmInformationController, times(2)).selectChildID(arg.capture());
+        id = arg.getValue();
+
+        assertEquals(3, id);
+    }
+    
+    @Test
+    public void verifyOpenSameHostVMTab2() {
+        
+        VmRef vmRef1 = mock(VmRef.class);
+        VmRef vmRef2 = mock(VmRef.class);
+        when(view.getSelectedHostOrVm()).thenReturn(vmRef1).thenReturn(vmRef1).thenReturn(vmRef2).thenReturn(vmRef1);
+
+        when(vmRef1.getName()).thenReturn("testvm");
+        when(vmRef1.getIdString()).thenReturn("testvmid");
+        HostRef ref = mock(HostRef.class);
+        when(ref.getAgentId()).thenReturn("agentId");
+        when(vmRef1.getAgent()).thenReturn(ref);
+        
+        when(vmRef2.getName()).thenReturn("testvm");
+        when(vmRef2.getIdString()).thenReturn("testvmid");
+        when(vmRef2.getAgent()).thenReturn(ref);
+        
+        VmInformationController vmInformationController1 = mock(VmInformationController.class);
+        VmInformationController vmInformationController2 = mock(VmInformationController.class);
+        
+        when(vmInformationController1.getSelectedChildID()).thenReturn(2).thenReturn(2);
+        when(vmInformationController2.getSelectedChildID()).thenReturn(3);
+        
+        when(vmInformationController1.selectChildID(0)).thenReturn(true);
+        when(vmInformationController1.selectChildID(2)).thenReturn(true);
+        when(vmInformationController1.selectChildID(3)).thenReturn(false);
+        
+        when(vmInformationController2.selectChildID(0)).thenReturn(true);
+        when(vmInformationController2.selectChildID(2)).thenReturn(true);
+        when(vmInformationController2.selectChildID(3)).thenReturn(true);
+        
+        when(uiFacadeFactory.getVmController(any(VmRef.class))).
+                             thenReturn(vmInformationController1).
+                             thenReturn(vmInformationController2).
+                             thenReturn(vmInformationController2).
+                             thenReturn(vmInformationController1);
+
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
+
+        ArgumentCaptor<Integer> arg = ArgumentCaptor.forClass(Integer.class);
+        verify(vmInformationController1).selectChildID(arg.capture());
+        verify(vmInformationController1, times(0)).getSelectedChildID();
+
+        int id = arg.getValue();
+
+        assertEquals(0, id);
+
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
+
+        arg = ArgumentCaptor.forClass(Integer.class);
+        verify(vmInformationController1).getSelectedChildID();
+        verify(vmInformationController2, times(1)).selectChildID(arg.capture());
+        id = arg.getValue();
+
+        assertEquals(2, id);
+        
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
+
+        arg = ArgumentCaptor.forClass(Integer.class);
+        verify(vmInformationController2, times(1)).getSelectedChildID();
+        verify(vmInformationController2, times(2)).selectChildID(arg.capture());
+        id = arg.getValue();
+
+        assertEquals(3, id);
+        
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
+
+        arg = ArgumentCaptor.forClass(Integer.class);
+        verify(vmInformationController2, times(2)).getSelectedChildID();
+        verify(vmInformationController1, times(3)).selectChildID(arg.capture());
+        id = arg.getValue();
+
+        assertEquals(2, id);
+    }
+    
+    @Test
+    public void verityVMActionsAreShown() {
+        VmInfo vmInfo = new VmInfo(0, 1, 2, null, null, null, null, null, null, null, null, null, null, null);
+        when(mockVmsDAO.getVmInfo(isA(VmRef.class))).thenReturn(vmInfo);
+
+        VmRef ref = mock(VmRef.class);
+        when(view.getSelectedHostOrVm()).thenReturn(ref);
+
+        MouseEvent uiEvent = mock(MouseEvent.class);
+        ActionEvent<MainView.Action> viewEvent = new ActionEvent<>(view, MainView.Action.SHOW_VM_CONTEXT_MENU);
+        viewEvent.setPayload(uiEvent);
+
+        l.actionPerformed(viewEvent);
+
+        verify(view).showVMContextActions(Arrays.asList(action1), uiEvent);
+    }
+    
+    @Test
+    public void verityVMActionsAreExecuted() {
+
+        VmRef vmRef = mock(VmRef.class);
+        when(view.getSelectedHostOrVm()).thenReturn(vmRef);
+
+        ActionEvent<MainView.Action> event = new ActionEvent<>(view, MainView.Action.VM_CONTEXT_ACTION);
+        event.setPayload(action1);
+        l.actionPerformed(event);
+        
+        verify(action1, times(1)).execute(any(VmRef.class));
+        verify(action2, times(0)).execute(any(VmRef.class));
+    }
+
+    @Test
+    public void verifyMenuItems() {
+        
+        ActionListener<ThermostatExtensionRegistry.Action> menuListener = controller.getMenuListener();
+
+        MenuAction action = mock(MenuAction.class);
+        when(action.getName()).thenReturn("Test1");
+
+        ActionEvent<Action> addEvent = new ActionEvent<ThermostatExtensionRegistry.Action>(
+        		menus, ThermostatExtensionRegistry.Action.SERVICE_ADDED);
+        addEvent.setPayload(action);
+        menuListener.actionPerformed(addEvent);
+        verify(view).addMenu(action);
+
+        ActionEvent<Action> removeEvent = new ActionEvent<ThermostatExtensionRegistry.Action>(menus, ThermostatExtensionRegistry.Action.SERVICE_REMOVED);
+        removeEvent.setPayload(action);
+        menuListener.actionPerformed(removeEvent);
+        verify(view).removeMenu(action);
+    }
+
+   @Test
+   public void testOSGiFrameworkShutdown() throws BundleException {
+
+       l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.SHUTDOWN));
+
+       verify(uiFacadeFactory).shutdown();
+   }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MenuRegistryTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,96 @@
+/*
+ * 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.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+import com.redhat.thermostat.client.osgi.service.MenuAction;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.ThermostatExtensionRegistry;
+
+public class MenuRegistryTest {
+
+    @Test
+    public void verifyMenuRegistryReactsToMenuActions() throws InvalidSyntaxException {
+        ArgumentCaptor<ServiceListener> serviceListenerCaptor = ArgumentCaptor.forClass(ServiceListener.class);
+        ArgumentCaptor<String> filterCaptor = ArgumentCaptor.forClass(String.class);
+
+        ActionListener<ThermostatExtensionRegistry.Action> menuListener = mock(ActionListener.class);
+        MenuAction menuAction = mock(MenuAction.class);
+
+        BundleContext context = mock(BundleContext.class);
+        doNothing().when(context).addServiceListener(serviceListenerCaptor.capture(), filterCaptor.capture());
+
+        ServiceReference ref = mock(ServiceReference.class);
+        when(ref.getProperty("objectClass")).thenReturn(MenuAction.class.getName());
+
+        when(context.getService(ref)).thenReturn(menuAction);
+
+        MenuRegistry registry = new MenuRegistry(context);
+        registry.addActionListener(menuListener);
+        registry.start();
+
+        ServiceListener serviceListener = serviceListenerCaptor.getValue();
+        serviceListener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, ref));
+
+        ArgumentCaptor<ActionEvent> eventCaptor = ArgumentCaptor.forClass(ActionEvent.class);
+        serviceListener.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, ref));
+
+        verify(menuListener, times(2)).actionPerformed(eventCaptor.capture());
+
+        ActionEvent firstEvent = eventCaptor.getAllValues().get(0);
+        ActionEvent secondEvent = eventCaptor.getAllValues().get(1);
+
+        assertEquals(ThermostatExtensionRegistry.Action.SERVICE_ADDED, firstEvent.getActionId());
+        assertEquals(ThermostatExtensionRegistry.Action.SERVICE_REMOVED, secondEvent.getActionId());
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/SearchFieldSwingViewTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,197 @@
+/*
+ * 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));
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/osgi/ApplicationServiceProviderTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,84 @@
+/*
+ * 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.osgi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
+
+import java.util.concurrent.Callable;
+import java.util.concurrent.Future;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ApplicationServiceProviderTest {
+
+    private ApplicationServiceProvider provider;
+
+    @Before
+    public void setUp() {
+        provider = new ApplicationServiceProvider();
+    }
+
+    @After
+    public void tearDown() {
+        provider = null;
+    }
+
+    @Test
+    public void testCache() {
+        provider.getApplicationCache().addAttribute("test", "fluff");
+        assertEquals("fluff", provider.getApplicationCache().getAttribute("test"));
+    }
+
+    @Test
+    public void testApplicationExecutor() throws Exception {
+        assertNotNull(provider.getApplicationExecutor());
+        final String obj = "test";
+        Future<String> future = provider.getApplicationExecutor().submit(new Callable<String>() {
+
+            @Override
+            public String call() throws Exception {
+                return obj;
+            }
+        });
+        String result = future.get();
+        assertSame(result, obj);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivatorTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -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.osgi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.core.views.AgentInformationViewProvider;
+import com.redhat.thermostat.client.core.views.ClientConfigViewProvider;
+import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
+import com.redhat.thermostat.client.core.views.HostInformationViewProvider;
+import com.redhat.thermostat.client.core.views.HostMemoryViewProvider;
+import com.redhat.thermostat.client.core.views.HostOverviewViewProvider;
+import com.redhat.thermostat.client.core.views.SummaryViewProvider;
+import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
+import com.redhat.thermostat.client.core.views.VmGcViewProvider;
+import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
+import com.redhat.thermostat.client.core.views.VmOverviewViewProvider;
+import com.redhat.thermostat.client.osgi.service.HostDecorator;
+import com.redhat.thermostat.client.swing.internal.HostIconDecorator;
+import com.redhat.thermostat.client.swing.views.SwingAgentInformationViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingClientConfigurationViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingHostCpuViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingHostInformationViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingHostMemoryViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingHostOverviewViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingSummaryViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingVmCpuViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingVmGcViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingVmInformationViewProvider;
+import com.redhat.thermostat.client.swing.views.SwingVmOverviewViewProvider;
+import com.redhat.thermostat.test.StubBundleContext;
+
+public class ThermostatActivatorTest {
+
+    @Test
+    public void verifyAllExpectedServicesAreRegistered() throws Exception {
+        StubBundleContext ctx = new StubBundleContext();
+
+        ThermostatActivator activator = new ThermostatActivator();
+
+        activator.start(ctx);
+
+        assertTrue(ctx.isServiceRegistered(HostDecorator.class.getName(), HostIconDecorator.class));
+        assertTrue(ctx.isServiceRegistered(SummaryViewProvider.class.getName(), SwingSummaryViewProvider.class));
+        assertTrue(ctx.isServiceRegistered(HostInformationViewProvider.class.getName(), SwingHostInformationViewProvider.class));
+        assertTrue(ctx.isServiceRegistered(HostMemoryViewProvider.class.getName(), SwingHostMemoryViewProvider.class));
+        assertTrue(ctx.isServiceRegistered(HostCpuViewProvider.class.getName(), SwingHostCpuViewProvider.class));
+        assertTrue(ctx.isServiceRegistered(HostOverviewViewProvider.class.getName(), SwingHostOverviewViewProvider.class));
+        assertTrue(ctx.isServiceRegistered(VmInformationViewProvider.class.getName(), SwingVmInformationViewProvider.class));
+        assertTrue(ctx.isServiceRegistered(VmCpuViewProvider.class.getName(), SwingVmCpuViewProvider.class));
+        assertTrue(ctx.isServiceRegistered(VmGcViewProvider.class.getName(), SwingVmGcViewProvider.class));
+        assertTrue(ctx.isServiceRegistered(VmOverviewViewProvider.class.getName(), SwingVmOverviewViewProvider.class));
+        assertTrue(ctx.isServiceRegistered(AgentInformationViewProvider.class.getName(), SwingAgentInformationViewProvider.class));
+        assertTrue(ctx.isServiceRegistered(ClientConfigViewProvider.class.getName(), SwingClientConfigurationViewProvider.class));
+        
+        assertEquals(12, ctx.getAllServices().size());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/views/AgentInformationDisplayFrameTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,264 @@
+/*
+ * 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.mock;
+import static org.mockito.Mockito.verify;
+
+import java.util.HashMap;
+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 com.redhat.thermostat.client.core.views.AgentInformationDisplayView;
+import com.redhat.thermostat.client.core.views.AgentInformationDisplayView.ConfigurationAction;
+import com.redhat.thermostat.client.swing.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 String BACKEND_NAME = "foo";
+        final String BACKEND_STATUS = "bar";
+        final String BACKEND_DESCRIPTION = "baz";
+
+        Map<String, String> statusMap = new HashMap<>();
+        statusMap.put(BACKEND_NAME, BACKEND_STATUS);
+
+        fixture.show();
+
+        agentConfigFrame.setSelectedAgentBackendStatus(statusMap);
+
+        assertEquals(1, fixture.table("backends").rowCount());
+
+        String[] rowContents = fixture.table("backends").contents()[0];
+        assertArrayEquals(new String[] { BACKEND_NAME, BACKEND_STATUS }, rowContents);
+
+        fixture.table("backends").selectRows(0);
+
+        verify(l).actionPerformed(new ActionEvent<ConfigurationAction>(agentConfigFrame, ConfigurationAction.SHOW_BACKEND_DESCRIPTION));
+
+        agentConfigFrame.setSelectedAgentBackendDescription(BACKEND_DESCRIPTION);
+
+        assertEquals(BACKEND_DESCRIPTION, 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/views/ClientConfigurationSwingTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,195 @@
+/*
+ * 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();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/views/HostInformationPanelTest.java	Tue Oct 23 11:19:24 2012 -0400
@@ -0,0 +1,139 @@
+/*
+ * 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.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 {
+        BasicView 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");
+
+        BasicView mock2 = createHostInfoPanel();
+        panel.addChildView("foo2", mock2);
+
+        window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("foo1", "foo2");
+    }
+
+    @Test
+    public void testAddRemove() throws InvocationTargetException, InterruptedException {
+        BasicView test1 = createHostInfoPanel();
+        BasicView 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/eclipse/core-p2-repository/pom.xml	Tue Oct 23 11:17:50 2012 -0400
+++ b/eclipse/core-p2-repository/pom.xml	Tue Oct 23 11:19:24 2012 -0400
@@ -172,11 +172,6 @@
                 </artifactItem>
                 <artifactItem>
                     <groupId>com.redhat.thermostat</groupId>
-                    <artifactId>thermostat-swing-components</artifactId>
-                    <version>${project.version}</version>
-                </artifactItem>
-                <artifactItem>
-                    <groupId>com.redhat.thermostat</groupId>
                     <artifactId>thermostat-keyring</artifactId>
                     <version>${project.version}</version>
                 </artifactItem>
--- a/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/chart/ChartColors.java	Tue Oct 23 11:17:50 2012 -0400
+++ b/thread/client-common/src/main/java/com/redhat/thermostat/thread/client/common/chart/ChartColors.java	Tue Oct 23 11:19:24 2012 -0400
@@ -38,7 +38,7 @@
 
 import java.awt.Color;
 
-import com.redhat.thermostat.swing.Palette;
+import com.redhat.thermostat.client.ui.Palette;
 
 public class ChartColors {
     
--- a/thread/client-swing/pom.xml	Tue Oct 23 11:17:50 2012 -0400
+++ b/thread/client-swing/pom.xml	Tue Oct 23 11:19:24 2012 -0400
@@ -90,6 +90,12 @@
       <scope>test</scope>
     </dependency>
     
+    <dependency>
+        <groupId>com.redhat.thermostat</groupId>
+        <artifactId>thermostat-client-swing</artifactId>
+        <version>${project.version}</version>
+    </dependency>
+
   </dependencies>
 
   <build>
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadDetailsView.java	Tue Oct 23 11:17:50 2012 -0400
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadDetailsView.java	Tue Oct 23 11:19:24 2012 -0400
@@ -43,9 +43,9 @@
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 
-import com.redhat.thermostat.client.ui.SwingComponent;
+import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.client.swing.components.ChartPanel;
 import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.swing.ChartPanel;
 import com.redhat.thermostat.thread.client.common.ThreadDetailsView;
 import com.redhat.thermostat.thread.client.common.ThreadTableBean;
 import com.redhat.thermostat.thread.client.common.chart.ThreadDeatailsPieChart;
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTableView.java	Tue Oct 23 11:17:50 2012 -0400
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTableView.java	Tue Oct 23 11:19:24 2012 -0400
@@ -49,9 +49,9 @@
 import javax.swing.event.TableModelListener;
 import javax.swing.table.DefaultTableModel;
 
+import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.client.swing.components.ThermostatTable;
 import com.redhat.thermostat.client.ui.ComponentVisibleListener;
-import com.redhat.thermostat.client.ui.SwingComponent;
-import com.redhat.thermostat.swing.ThermostatTable;
 import com.redhat.thermostat.thread.client.common.locale.LocaleResources;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.thread.client.common.ThreadTableBean;
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTimelineChart.java	Tue Oct 23 11:17:50 2012 -0400
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTimelineChart.java	Tue Oct 23 11:19:24 2012 -0400
@@ -57,11 +57,11 @@
 import javax.swing.JPanel;
 import javax.swing.SwingUtilities;
 
-import com.redhat.thermostat.swing.GradientRoundBorder;
-import com.redhat.thermostat.swing.GraphicsUtils;
-import com.redhat.thermostat.swing.Palette;
-import com.redhat.thermostat.swing.models.LongRange;
-import com.redhat.thermostat.swing.models.LongRangeNormalizer;
+import com.redhat.thermostat.client.swing.components.GradientRoundBorder;
+import com.redhat.thermostat.client.swing.components.GraphicsUtils;
+import com.redhat.thermostat.client.swing.components.models.LongRange;
+import com.redhat.thermostat.client.swing.components.models.LongRangeNormalizer;
+import com.redhat.thermostat.client.ui.Palette;
 import com.redhat.thermostat.thread.client.common.ThreadTimelineBean;
 import com.redhat.thermostat.thread.client.common.chart.ChartColors;
 
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTimelineView.java	Tue Oct 23 11:17:50 2012 -0400
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadTimelineView.java	Tue Oct 23 11:19:24 2012 -0400
@@ -56,8 +56,8 @@
 import javax.swing.SwingUtilities;
 import javax.swing.SwingWorker;
 
+import com.redhat.thermostat.client.swing.SwingComponent;
 import com.redhat.thermostat.client.ui.ComponentVisibleListener;
-import com.redhat.thermostat.client.ui.SwingComponent;
 import com.redhat.thermostat.thread.client.common.ThreadTimelineBean;
 import com.redhat.thermostat.thread.client.common.ThreadTimelineView;
 import com.redhat.thermostat.thread.model.ThreadInfoData;
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadView.java	Tue Oct 23 11:17:50 2012 -0400
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingThreadView.java	Tue Oct 23 11:19:24 2012 -0400
@@ -50,10 +50,10 @@
 import javax.swing.SwingWorker;
 
 import com.redhat.thermostat.client.osgi.service.ApplicationService;
+import com.redhat.thermostat.client.swing.SwingComponent;
+import com.redhat.thermostat.client.swing.components.ChartPanel;
 import com.redhat.thermostat.client.ui.ComponentVisibleListener;
-import com.redhat.thermostat.client.ui.SwingComponent;
 import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.swing.ChartPanel;
 import com.redhat.thermostat.thread.client.common.ThreadTableBean;
 import com.redhat.thermostat.thread.client.common.ThreadTableView;
 import com.redhat.thermostat.thread.client.common.ThreadTimelineView;
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingVMThreadCapabilitiesView.java	Tue Oct 23 11:17:50 2012 -0400
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/SwingVMThreadCapabilitiesView.java	Tue Oct 23 11:19:24 2012 -0400
@@ -41,8 +41,8 @@
 import javax.swing.SwingUtilities;
 import javax.swing.SwingWorker;
 
+import com.redhat.thermostat.client.swing.SwingComponent;
 import com.redhat.thermostat.client.ui.ComponentVisibleListener;
-import com.redhat.thermostat.client.ui.SwingComponent;
 import com.redhat.thermostat.thread.client.common.VMThreadCapabilitiesView;
 import com.redhat.thermostat.thread.model.VMThreadCapabilities;
 
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadMainPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadMainPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -43,9 +43,9 @@
 import javax.swing.JPanel;
 import javax.swing.JSplitPane;
 
+import com.redhat.thermostat.client.swing.components.ActionToggleButton;
+import com.redhat.thermostat.client.swing.components.HeaderPanel;
 import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.swing.ActionToggleButton;
-import com.redhat.thermostat.swing.HeaderPanel;
 import com.redhat.thermostat.thread.client.common.IconResources;
 import com.redhat.thermostat.thread.client.common.locale.LocaleResources;
 
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadTimelineLegendPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadTimelineLegendPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -50,7 +50,7 @@
 import javax.swing.SwingConstants;
 import javax.swing.SwingUtilities;
 
-import com.redhat.thermostat.swing.GraphicsUtils;
+import com.redhat.thermostat.client.swing.components.GraphicsUtils;
 import com.redhat.thermostat.thread.client.common.chart.ChartColors;
 
 @SuppressWarnings("serial")
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/VMCapsSummaryPanel.java	Tue Oct 23 11:17:50 2012 -0400
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/VMCapsSummaryPanel.java	Tue Oct 23 11:19:24 2012 -0400
@@ -43,7 +43,7 @@
 import javax.swing.JList;
 import javax.swing.JPanel;
 
-import com.redhat.thermostat.swing.models.NullSelectionModel;
+import com.redhat.thermostat.client.swing.components.models.NullSelectionModel;
 
 @SuppressWarnings("serial")
 class VMCapsSummaryPanel extends JPanel {