changeset 806:68eabdccc9b3

Merge
author Roman Kennke <rkennke@redhat.com>
date Wed, 28 Nov 2012 12:28:04 +0100
parents 1ba58e849ae8 (current diff) 094d4af7f231 (diff)
children fe21da90d83f
files client/core/src/main/java/com/redhat/thermostat/client/core/views/HostCpuView.java client/core/src/main/java/com/redhat/thermostat/client/core/views/HostCpuViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/core/views/HostMemoryView.java client/core/src/main/java/com/redhat/thermostat/client/core/views/HostMemoryViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/core/views/HostOverviewView.java client/core/src/main/java/com/redhat/thermostat/client/core/views/HostOverviewViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/core/views/VmCpuView.java client/core/src/main/java/com/redhat/thermostat/client/core/views/VmCpuViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/core/views/VmGcView.java client/core/src/main/java/com/redhat/thermostat/client/core/views/VmGcViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/core/views/VmOverviewView.java client/core/src/main/java/com/redhat/thermostat/client/core/views/VmOverviewViewProvider.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostCpuController.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostMemoryController.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostOverviewController.java client/core/src/main/java/com/redhat/thermostat/client/ui/VmCpuController.java client/core/src/main/java/com/redhat/thermostat/client/ui/VmGcController.java client/core/src/main/java/com/redhat/thermostat/client/ui/VmOverviewController.java client/core/src/test/java/com/redhat/thermostat/client/ui/HostCpuControllerTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/HostMemoryControllerTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/HostOverviewControllerTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/VmCpuControllerTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/VmGcControllerTest.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SimpleTable.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/WrapLayout.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/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/SwingHostCpuViewProvider.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/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/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/VmOverviewPanel.java gc/pom.xml gc/remote-collector-client-common/pom.xml gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/IconResources.java gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/LocaleResources.java gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/RequestGCAction.java gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/osgi/GCCommandActivator.java gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/common/GCRequest.java gc/remote-collector-client-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/strings.properties gc/remote-collector-client-common/src/test/java/com/redhat/thermostat/gc/remote/common/GCRequestTest.java gc/remote-collector-client-swing/pom.xml gc/remote-collector-client-swing/src/main/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButton.java gc/remote-collector-client-swing/src/test/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButtonTest.java gc/remote-collector-command/pom.xml gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/GCCommandReceiver.java gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/internal/GC.java gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/osgi/GCCommandReceiverActivator.java gc/remote-collector-common/pom.xml gc/remote-collector-common/src/main/java/com/redhat/thermostat/gc/remote/common/command/GCCommand.java gc/remote-collector-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/gcSmall.png gc/remote-collector-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/strings.properties
diffstat 214 files changed, 10219 insertions(+), 6689 deletions(-) [+]
line wrap: on
line diff
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/HostInformationService.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/core/src/main/java/com/redhat/thermostat/client/core/HostInformationService.java	Wed Nov 28 12:28:04 2012 +0100
@@ -42,7 +42,7 @@
 public interface HostInformationService extends InformationService {
 
     @Override
-    HostFilter getFilter();
+    public HostFilter getFilter();
 
-    HostInformationServiceController getInformationServiceController(HostRef ref);
+    public HostInformationServiceController getInformationServiceController(HostRef ref);
 }
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/VmInformationService.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/core/src/main/java/com/redhat/thermostat/client/core/VmInformationService.java	Wed Nov 28 12:28:04 2012 +0100
@@ -42,7 +42,7 @@
 public interface VmInformationService extends InformationService {
 
     @Override
-    VmFilter getFilter();
+    public VmFilter getFilter();
 
-    VmInformationServiceController getInformationServiceController(VmRef ref);
+    public VmInformationServiceController getInformationServiceController(VmRef ref);
 }
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/HostCpuView.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,55 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.core.views;
-
-import java.util.List;
-
-import com.redhat.thermostat.storage.model.DiscreteTimeData;
-
-public abstract class HostCpuView extends BasicView implements UIComponent {
-
-    public abstract void setCpuCount(String count);
-
-    public abstract void setCpuModel(String model);
-
-    public abstract void clearCpuUsageData();
-
-    public abstract void addCpuUsageChart(int cpuIndex, String humanReadableName);
-
-    public abstract void addCpuUsageData(int cpuIndex, List<DiscreteTimeData<Double>> data);
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/HostCpuViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ /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.client.core.views;
-
-public interface HostCpuViewProvider extends ViewProvider {
-
-    @Override
-    HostCpuView createView();
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/HostInformationView.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/core/src/main/java/com/redhat/thermostat/client/core/views/HostInformationView.java	Wed Nov 28 12:28:04 2012 +0100
@@ -39,7 +39,7 @@
 
 public abstract class HostInformationView extends BasicView implements UIComponent {
 
-    public abstract void addChildView(String title, BasicView view);
+    public abstract void addChildView(String title, UIComponent view);
 
     public abstract void removeChildView(String title);
 
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/HostMemoryView.java	Wed Nov 28 12:24:00 2012 +0100
+++ /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.client.core.views;
-
-import java.util.List;
-
-import com.redhat.thermostat.storage.model.DiscreteTimeData;
-
-public abstract class HostMemoryView extends BasicView implements UIComponent {
-
-    public interface GraphVisibilityChangeListener {
-        public void show(String tag);
-
-        public void hide(String tag);
-    }
-
-    public abstract void setTotalMemory(String totalMemory);
-
-    public abstract void addMemoryChart(String tag, String humanReadableName);
-
-    public abstract void removeMemoryChart(String tag);
-
-    public abstract void showMemoryChart(String tag);
-
-    public abstract void hideMemoryChart(String tag);
-
-    public abstract void addMemoryData(String tag, List<DiscreteTimeData<? extends Number>> data);
-
-    public abstract void clearMemoryData(String tag);
-
-    public abstract void addGraphVisibilityListener(GraphVisibilityChangeListener listener);
-
-    public abstract void removeGraphVisibilityListener(GraphVisibilityChangeListener listener);
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/HostMemoryViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.core.views;
-
-public interface HostMemoryViewProvider extends ViewProvider {
-
-    @Override
-    public HostMemoryView createView();
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/HostOverviewView.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.core.views;
-
-
-public abstract class HostOverviewView extends BasicView implements UIComponent {
-
-    public abstract void setHostName(String newHostName);
-
-    public abstract void setCpuModel(String newCpuModel);
-
-    public abstract void setCpuCount(String newCpuCount);
-
-    public abstract void setTotalMemory(String newTotalMemory);
-
-    public abstract void setOsName(String newOsName);
-
-    public abstract void setOsKernel(String newOsKernel);
-
-    public abstract void setNetworkTableColumns(Object[] columns);
-
-    public abstract void setInitialNetworkTableData(Object[][] table);
-
-    public abstract void updateNetworkTableData(int row, int column, String data);
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/HostOverviewViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ /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.client.core.views;
-
-public interface HostOverviewViewProvider extends ViewProvider {
-
-    @Override
-    public HostOverviewView createView();
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/VmCpuView.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.core.views;
-
-import java.util.List;
-
-import com.redhat.thermostat.storage.model.DiscreteTimeData;
-
-public abstract class VmCpuView extends BasicView implements UIComponent {
-
-    public abstract void addData(List<DiscreteTimeData<? extends Number>> data);
-
-    public abstract void clearData();
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/VmCpuViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ /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.client.core.views;
-
-public interface VmCpuViewProvider extends ViewProvider {
-
-    @Override
-    public VmCpuView createView();
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/VmGcView.java	Wed Nov 28 12:24:00 2012 +0100
+++ /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.core.views;
-
-import java.util.List;
-
-import com.redhat.thermostat.storage.model.IntervalTimeData;
-
-public abstract class VmGcView extends BasicView implements UIComponent {
-
-    public abstract void addChart(String tag, String title, String valueUnit);
-
-    public abstract void removeChart(String tag);
-
-    public abstract void addData(String tag, List<IntervalTimeData<Double>> data);
-
-    public abstract void clearData(String tag);
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/VmGcViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.core.views;
-
-public interface VmGcViewProvider extends ViewProvider {
-
-    @Override
-    public VmGcView createView();
-    
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/VmOverviewView.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.core.views;
-
-
-public abstract class VmOverviewView extends BasicView implements UIComponent {
-
-    public abstract void setVmPid(String pid);
-
-    public abstract void setVmStartTimeStamp(String timestamp);
-
-    public abstract void setVmStopTimeStamp(String timeStamp);
-
-    public abstract void setMainClass(String mainClass);
-
-    public abstract void setJavaCommandLine(String javaCommandLine);
-
-    public abstract void setJavaHome(String string);
-
-    public abstract void setJavaVersion(String javaVersion);
-
-    public abstract void setVmNameAndVersion(String vmNameAndVersion);
-
-    public abstract void setVmArguments(String vmArguments);
-
-    public abstract void setVmInfo(String string);
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/core/views/VmOverviewViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.core.views;
-
-public interface VmOverviewViewProvider extends ViewProvider {
-
-    @Override
-    public VmOverviewView createView();
-    
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/locale/LocaleResources.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/core/src/main/java/com/redhat/thermostat/client/locale/LocaleResources.java	Wed Nov 28 12:28:04 2012 +0100
@@ -65,16 +65,6 @@
     MENU_HELP,
     MENU_HELP_ABOUT,
 
-    GARBAGE_COLLECTION,
-    YOUNG_GEN,
-    EDEN_GEN,
-    S0_GEN,
-    S1_GEN,
-    OLD_GEN,
-    PERM_GEN,
-    UNKNOWN_GEN,
-    SOME_GENERATION,
-
     SECONDS,
     MINUTES,
     HOURS,
@@ -108,75 +98,8 @@
     HOME_PANEL_SECTION_ISSUES,
     HOME_PANEL_NO_ISSUES,
 
-    HOST_INFO_TAB_OVERVIEW,
-    HOST_INFO_TAB_MEMORY,
-    HOST_INFO_TAB_CPU,
     HOST_INFO_TAB_IO,
 
-    HOST_OVERVIEW_SECTION_BASICS,
-    HOST_OVERVIEW_SECTION_HARDWARE,
-    HOST_OVERVIEW_SECTION_SOFTWARE,
-
-    HOST_INFO_HOSTNAME,
-    HOST_INFO_CPU_COUNT,
-    HOST_INFO_CPU_MODEL,
-    HOST_INFO_OS_NAME,
-    HOST_INFO_OS_KERNEL,
-
-    HOST_INFO_MEMORY_TOTAL,
-    HOST_INFO_NETWORK,
-
-    NETWORK_INTERFACE_COLUMN,
-    NETWORK_IPV4_COLUMN,
-    NETWORK_IPV6_COLUMN,
-
-    HOST_CPU_SECTION_OVERVIEW,
-    HOST_CPU_ID,
-    HOST_CPU_USAGE_CHART_TIME_LABEL,
-    HOST_CPU_USAGE_CHART_VALUE_LABEL,
-    HOST_MEMORY_SECTION_OVERVIEW,
-    HOST_MEMORY_CHART_TITLE,
-    HOST_MEMORY_CHART_TIME_LABEL,
-    HOST_MEMORY_CHART_SIZE_LABEL,
-    HOST_MEMORY_TOTAL,
-    HOST_MEMORY_FREE,
-    HOST_MEMORY_USED,
-    HOST_SWAP_TOTAL,
-    HOST_SWAP_FREE,
-    HOST_BUFFERS,
-
-    VM_INFO_TAB_OVERVIEW,
-    VM_INFO_TAB_CPU,
-    VM_INFO_TAB_GC,
-
-    VM_INFO_TITLE,
-    VM_INFO_SECTION_PROCESS,
-    VM_INFO_SECTION_JAVA,
-
-    VM_INFO_PROCESS_ID,
-    VM_INFO_START_TIME,
-    VM_INFO_STOP_TIME,
-    VM_INFO_RUNNING,
-    VM_INFO_MAIN_CLASS,
-    VM_INFO_COMMAND_LINE,
-    VM_INFO_JAVA_VERSION,
-    VM_INFO_VM,
-    VM_INFO_VM_ARGUMENTS,
-    VM_INFO_VM_NAME_AND_VERSION,
-    VM_INFO_PROPERTIES,
-    VM_INFO_ENVIRONMENT,
-    VM_INFO_LIBRARIES,
-
-    VM_CPU_TITLE,
-    VM_CPU_CHART_LOAD_LABEL,
-    VM_CPU_CHART_TIME_LABEL,
-
-    VM_GC_TITLE,
-
-    VM_GC_COLLECTOR_OVER_GENERATION,
-    VM_GC_COLLECTOR_CHART_REAL_TIME_LABEL,
-    VM_GC_COLLECTOR_CHART_GC_TIME_LABEL,
-
     AGENT_INFO_WINDOW_TITLE,
     AGENT_INFO_AGENTS_LIST,
     AGENT_INFO_AGENT_SECTION_TITLE,
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostCpuController.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +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 java.util.concurrent.TimeUnit;
-
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.HostCpuView;
-import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
-import com.redhat.thermostat.client.core.views.BasicView.Action;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.NotImplementedException;
-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.dao.CpuStatDAO;
-import com.redhat.thermostat.common.dao.HostInfoDAO;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.storage.model.CpuStat;
-import com.redhat.thermostat.storage.model.DiscreteTimeData;
-import com.redhat.thermostat.storage.model.HostInfo;
-
-public class HostCpuController {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private final HostCpuView view;
-    private final Timer backgroundUpdateTimer;
-
-    private final HostInfoDAO hostInfoDAO;
-    private final CpuStatDAO cpuStatDAO;
-    private final HostRef ref;
-
-    private int chartsAdded = 0;
-    private long lastSeenTimeStamp = Long.MIN_VALUE;
-
-    public HostCpuController(HostInfoDAO hostInfoDao, CpuStatDAO cpuStatDAO, HostRef ref, HostCpuViewProvider provider) {
-        this.ref = ref;
-        view = provider.createView();
-        view.clearCpuUsageData();
-        this.hostInfoDAO = hostInfoDao;
-        this.cpuStatDAO = cpuStatDAO;
-
-        backgroundUpdateTimer = ApplicationContext.getInstance().getTimerFactory().createTimer();
-        backgroundUpdateTimer.setAction(new Runnable() {
-
-            @Override
-            public void run() {
-                updateView();
-            }
-
-        });
-        backgroundUpdateTimer.setInitialDelay(0);
-        backgroundUpdateTimer.setDelay(5);
-        backgroundUpdateTimer.setTimeUnit(TimeUnit.SECONDS);
-        backgroundUpdateTimer.setSchedulingType(SchedulingType.FIXED_RATE);
-
-        view.addActionListener(new ActionListener<HostCpuView.Action>() {
-            @Override
-            public void actionPerformed(ActionEvent<Action> actionEvent) {
-                switch (actionEvent.getActionId()) {
-                    case VISIBLE:
-                        start();
-                        break;
-                    case HIDDEN:
-                        stop();
-                        break;
-                    default:
-                        throw new NotImplementedException("unhandled action: " + actionEvent.getActionId());
-                }
-            }
-        });
-
-    }
-
-    // TODO: Consider doing this in a background thread (move to view and use SwingWorker or such).
-    private void updateView() {
-        HostInfo hostInfo = hostInfoDAO.getHostInfo(ref);
-
-        view.setCpuCount(String.valueOf(hostInfo.getCpuCount()));
-        view.setCpuModel(hostInfo.getCpuModel());
-
-        doCpuChartUpdate();
-    }
-
-    private void start() {
-        backgroundUpdateTimer.start();
-    }
-
-    private void stop() {
-        backgroundUpdateTimer.stop();
-    }
-
-    private void doCpuChartUpdate() {
-        List<CpuStat> cpuStats = cpuStatDAO.getLatestCpuStats(ref, lastSeenTimeStamp);
-        List<List<DiscreteTimeData<Double>>> results = new ArrayList<>();
-        for (CpuStat stat : cpuStats) {
-            double[] data = stat.getPerProcessorUsage();
-            for (int i = 0 ; i < data.length; i++) {
-                if (results.size() == i) {
-                    results.add(new ArrayList<DiscreteTimeData<Double>>());
-                }
-                results.get(i).add(new DiscreteTimeData<Double>(stat.getTimeStamp(), data[i]));
-                lastSeenTimeStamp = Math.max(lastSeenTimeStamp, stat.getTimeStamp());
-            }
-        }
-
-        for (int i = 0; i < results.size(); i++) {
-            if (i == chartsAdded) {
-                view.addCpuUsageChart(i, translator.localize(LocaleResources.HOST_CPU_ID, String.valueOf(i)));
-                chartsAdded++;
-            }
-            view.addCpuUsageData(i, results.get(i));
-        }
-    }
-
-    public BasicView getView() {
-        return view;
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostInformationController.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/HostInformationController.java	Wed Nov 28 12:28:04 2012 +0100
@@ -36,60 +36,32 @@
 
 package com.redhat.thermostat.client.ui;
 
+import java.util.Collection;
+
+import com.redhat.thermostat.client.core.HostInformationService;
+import com.redhat.thermostat.client.core.controllers.HostInformationServiceController;
 import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
 import com.redhat.thermostat.client.core.views.HostInformationView;
 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.locale.LocaleResources;
-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.locale.Translate;
-import com.redhat.thermostat.common.utils.OSGIUtils;
 
 public class HostInformationController {
 
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private final HostOverviewController overviewController;
-    private final HostCpuController cpuController;
-    private final HostMemoryController memoryController;
-
     private final HostInformationView view;
 
-    public HostInformationController(HostInfoDAO hostInfoDao, NetworkInterfaceInfoDAO networkInfoDao, CpuStatDAO cpuStatDao, MemoryStatDAO memoryStatDao, HostRef ref, HostInformationViewProvider provider) {
-        OSGIUtils utils = OSGIUtils.getInstance();
-        HostCpuViewProvider hostCpuProvider = utils.getService(HostCpuViewProvider.class);
-        HostOverviewViewProvider hostOverviewProvider = utils.getService(HostOverviewViewProvider.class);
-        HostMemoryViewProvider hostMemoryProvider = utils.getService(HostMemoryViewProvider.class);
-        overviewController = new HostOverviewController(hostInfoDao, networkInfoDao, ref, hostOverviewProvider);
-        cpuController = new HostCpuController(hostInfoDao, cpuStatDao, ref, hostCpuProvider);
-        memoryController = new HostMemoryController(hostInfoDao, memoryStatDao, ref, hostMemoryProvider);
-
+    public HostInformationController(UiFacadeFactory uiFacadeFactory, HostRef ref, HostInformationViewProvider provider) {
         view = provider.createView();
 
-        view.addChildView(translator.localize(LocaleResources.HOST_INFO_TAB_OVERVIEW), getOverviewController().getView());
-        view.addChildView(translator.localize(LocaleResources.HOST_INFO_TAB_CPU), getCpuController().getView());
-        view.addChildView(translator.localize(LocaleResources.HOST_INFO_TAB_MEMORY), getMemoryController().getView());
-
+        Collection<HostInformationService> hostInfoServices = uiFacadeFactory.getHostInformationServices();
+        for (HostInformationService hostInfoService : hostInfoServices) {
+            if (hostInfoService.getFilter().matches(ref)) {
+                HostInformationServiceController ctrl = hostInfoService.getInformationServiceController(ref);
+                String name = ctrl.getLocalizedName();
+                view.addChildView(name, ctrl.getView());
+            }
+        }
     }
 
-    public HostOverviewController getOverviewController() {
-        return overviewController;
-    }
-
-    public HostCpuController getCpuController() {
-        return cpuController;
-    }
-
-    public HostMemoryController getMemoryController() {
-        return memoryController;
-    }
-    
     public BasicView getView() {
         return view;
     }
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostMemoryController.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,182 +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.LinkedList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.HostMemoryView;
-import com.redhat.thermostat.client.core.views.HostMemoryViewProvider;
-import com.redhat.thermostat.client.core.views.BasicView.Action;
-import com.redhat.thermostat.client.core.views.HostMemoryView.GraphVisibilityChangeListener;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.NotImplementedException;
-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.dao.HostInfoDAO;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.MemoryStatDAO;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.common.utils.DisplayableValues;
-import com.redhat.thermostat.storage.model.DiscreteTimeData;
-import com.redhat.thermostat.storage.model.MemoryStat;
-import com.redhat.thermostat.storage.model.MemoryType;
-
-public class HostMemoryController {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private final HostMemoryView view;
-
-    private final HostInfoDAO hostInfoDAO;
-    private final MemoryStatDAO memoryStatDAO;
-    private final HostRef ref;
-
-    private final Timer backgroundUpdateTimer;
-    private final GraphVisibilityChangeListener listener = new ShowHideGraph();
-
-    private long lastSeenTimeStamp = Long.MIN_VALUE;
-
-    public HostMemoryController(HostInfoDAO hostInfoDAO, MemoryStatDAO memoryStatDAO, final HostRef ref, HostMemoryViewProvider provider) {
-        this.ref = ref;
-        this.hostInfoDAO = hostInfoDAO;
-        this.memoryStatDAO = memoryStatDAO;
-
-        view = provider.createView();
-
-        view.addMemoryChart(MemoryType.MEMORY_TOTAL.name(), translator.localize(LocaleResources.HOST_MEMORY_TOTAL));
-        view.addMemoryChart(MemoryType.MEMORY_FREE.name(), translator.localize(LocaleResources.HOST_MEMORY_FREE));
-        view.addMemoryChart(MemoryType.MEMORY_USED.name(), translator.localize(LocaleResources.HOST_MEMORY_USED));
-        view.addMemoryChart(MemoryType.SWAP_TOTAL.name(), translator.localize(LocaleResources.HOST_SWAP_TOTAL));
-        view.addMemoryChart(MemoryType.SWAP_FREE.name(), translator.localize(LocaleResources.HOST_SWAP_FREE));
-        view.addMemoryChart(MemoryType.BUFFERS.name(), translator.localize(LocaleResources.HOST_BUFFERS));
-
-        view.addGraphVisibilityListener(listener);
-        view.addActionListener(new ActionListener<HostMemoryView.Action>() {
-            @Override
-            public void actionPerformed(ActionEvent<Action> actionEvent) {
-                switch (actionEvent.getActionId()) {
-                    case HIDDEN:
-                        stopBackgroundUpdates();
-                        break;
-                    case VISIBLE:
-                        startBackgroundUpdates();
-                        break;
-                    default:
-                        throw new NotImplementedException("action event not handled: " + actionEvent.getActionId());
-                }
-            }
-        });
-
-        backgroundUpdateTimer = ApplicationContext.getInstance().getTimerFactory().createTimer();
-        backgroundUpdateTimer.setAction(new Runnable() {
-            @Override
-            public void run() {
-                long memorySize = HostMemoryController.this.hostInfoDAO.getHostInfo(ref).getTotalMemory();
-                String[] memorySizeParts = DisplayableValues.bytes(memorySize);
-                view.setTotalMemory(translator.localize(LocaleResources.NUMBER_AND_UNIT, memorySizeParts[0], memorySizeParts[1]));
-                doMemoryChartUpdate();
-            }
-        });
-        backgroundUpdateTimer.setSchedulingType(SchedulingType.FIXED_RATE);
-        backgroundUpdateTimer.setTimeUnit(TimeUnit.SECONDS);
-        backgroundUpdateTimer.setInitialDelay(0);
-        backgroundUpdateTimer.setDelay(5);
-    }
-
-    private void startBackgroundUpdates() {
-        for (MemoryType type : MemoryType.values()) {
-            view.showMemoryChart(type.name());
-        }
-
-        backgroundUpdateTimer.start();
-    }
-
-    private void stopBackgroundUpdates() {
-        backgroundUpdateTimer.stop();
-        for (MemoryType type : MemoryType.values()) {
-            view.hideMemoryChart(type.name());
-        }
-    }
-
-    public BasicView getView() {
-        return view;
-    }
-
-    private void doMemoryChartUpdate() {
-        List<DiscreteTimeData<? extends Number>> memFree = new LinkedList<>();
-        List<DiscreteTimeData<? extends Number>> memTotal = new LinkedList<>();
-        List<DiscreteTimeData<? extends Number>> memUsed = new LinkedList<>();
-        List<DiscreteTimeData<? extends Number>> buf = new LinkedList<>();
-        List<DiscreteTimeData<? extends Number>> swapTotal = new LinkedList<>();
-        List<DiscreteTimeData<? extends Number>> swapFree = new LinkedList<>();
-
-        for (MemoryStat stat : memoryStatDAO.getLatestMemoryStats(ref, lastSeenTimeStamp)) {
-            long timeStamp = stat.getTimeStamp();
-            memFree.add(new DiscreteTimeData<Long>(timeStamp, stat.getFree()));
-            memTotal.add(new DiscreteTimeData<Long>(timeStamp, stat.getTotal()));
-            memUsed.add(new DiscreteTimeData<Long>(timeStamp, stat.getTotal() - stat.getFree()));
-            buf.add(new DiscreteTimeData<Long>(timeStamp, stat.getBuffers()));
-            swapTotal.add(new DiscreteTimeData<Long>(timeStamp, stat.getSwapTotal()));
-            swapFree.add(new DiscreteTimeData<Long>(timeStamp, stat.getSwapFree()));
-            lastSeenTimeStamp = Math.max(lastSeenTimeStamp, stat.getTimeStamp());
-        }
-
-        view.addMemoryData(MemoryType.MEMORY_FREE.name(), memFree);
-        view.addMemoryData(MemoryType.MEMORY_TOTAL.name(), memTotal);
-        view.addMemoryData(MemoryType.MEMORY_USED.name(), memUsed);
-        view.addMemoryData(MemoryType.BUFFERS.name(), buf);
-        view.addMemoryData(MemoryType.SWAP_FREE.name(), swapFree);
-        view.addMemoryData(MemoryType.SWAP_TOTAL.name(), swapTotal);
-    }
-
-    private class ShowHideGraph implements GraphVisibilityChangeListener {
-        @Override
-        public void show(String tag) {
-            view.showMemoryChart(tag);
-        }
-        @Override
-        public void hide(String tag) {
-            view.hideMemoryChart(tag);
-        }
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostOverviewController.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +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 java.util.Vector;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Logger;
-
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.HostOverviewView;
-import com.redhat.thermostat.client.core.views.HostOverviewViewProvider;
-import com.redhat.thermostat.client.core.views.BasicView.Action;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.NotImplementedException;
-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.dao.HostInfoDAO;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.NetworkInterfaceInfoDAO;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.common.utils.DisplayableValues;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-import com.redhat.thermostat.storage.model.HostInfo;
-import com.redhat.thermostat.storage.model.NetworkInterfaceInfo;
-
-public class HostOverviewController {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private static final Logger logger = LoggingUtils.getLogger(HostOverviewController.class);
-
-    private final HostRef ref;
-    private final HostInfoDAO hostInfoDAO;
-    private final NetworkInterfaceInfoDAO networkInfoDAO;
-
-    private final Timer backgroundUpdateTimer;
-    private final List<String> knownNetworkIfaces = new ArrayList<>();
-
-    private final HostOverviewView view;
-
-    public HostOverviewController(HostInfoDAO hostInfoDAO, NetworkInterfaceInfoDAO networkInfoDAO, final HostRef ref, HostOverviewViewProvider provider) {
-        this.ref = ref;
-        this.hostInfoDAO = hostInfoDAO;
-        this.networkInfoDAO = networkInfoDAO;
-
-        final Vector<String> networkTableColumnVector;
-        networkTableColumnVector = new Vector<String>();
-        networkTableColumnVector.add(translator.localize(LocaleResources.NETWORK_INTERFACE_COLUMN));
-        networkTableColumnVector.add(translator.localize(LocaleResources.NETWORK_IPV4_COLUMN));
-        networkTableColumnVector.add(translator.localize(LocaleResources.NETWORK_IPV6_COLUMN));
-
-        backgroundUpdateTimer = ApplicationContext.getInstance().getTimerFactory().createTimer();
-        backgroundUpdateTimer.setAction(new Runnable() {
-            @Override
-            public void run() {
-                HostInfo hostInfo = HostOverviewController.this.hostInfoDAO.getHostInfo(ref);
-                view.setHostName(hostInfo.getHostname());
-                view.setOsName(hostInfo.getOsName());
-                view.setOsKernel(hostInfo.getOsKernel());
-                view.setCpuModel(hostInfo.getCpuModel());
-                view.setCpuCount(String.valueOf(hostInfo.getCpuCount()));
-
-                String[] parts = DisplayableValues.bytes(hostInfo.getTotalMemory());
-                String readableTotalMemory = translator.localize(LocaleResources.NUMBER_AND_UNIT, parts[0], parts[1]);
-                view.setTotalMemory(readableTotalMemory);
-
-                List<NetworkInterfaceInfo> networkInfo =
-                        HostOverviewController.this.networkInfoDAO.getNetworkInterfaces(ref);
-
-                boolean firstRun = knownNetworkIfaces.isEmpty();
-                if (firstRun) {
-                    List<Object[]> data = new ArrayList<Object[]>();
-                    for (NetworkInterfaceInfo info: networkInfo) {
-                        String ifaceName = info.getInterfaceName();
-                        String ipv4 = info.getIp4Addr();
-                        String ipv6 = info.getIp6Addr();
-                        data.add(new String[] { ifaceName, ipv4, ipv6 });
-                        knownNetworkIfaces.add(ifaceName);
-                    }
-                    view.setInitialNetworkTableData(data.toArray(new Object[0][0]));
-                } else {
-                    for (NetworkInterfaceInfo info: networkInfo) {
-                        String ifaceName = info.getInterfaceName();
-                        String ipv4 = info.getIp4Addr();
-                        String ipv6 = info.getIp6Addr();
-                        int index = knownNetworkIfaces.indexOf(ifaceName);
-                        int row = index;
-                        view.updateNetworkTableData(index, 0, ifaceName);
-                        view.updateNetworkTableData(row, 1, ipv4);
-                        view.updateNetworkTableData(row, 2, ipv6);
-                    }
-                }
-            }
-        });
-        backgroundUpdateTimer.setSchedulingType(SchedulingType.FIXED_RATE);
-        backgroundUpdateTimer.setTimeUnit(TimeUnit.SECONDS);
-        backgroundUpdateTimer.setInitialDelay(0);
-        backgroundUpdateTimer.setDelay(5);
-
-        view = provider.createView();
-
-        view.setNetworkTableColumns(networkTableColumnVector.toArray());
-
-        view.addActionListener(new ActionListener<Action>() {
-            @Override
-            public void actionPerformed(ActionEvent<Action> actionEvent) {
-                switch (actionEvent.getActionId()) {
-                    case HIDDEN:
-                        stop();
-                        break;
-                    case VISIBLE:
-                        start();
-                        break;
-                    default:
-                        throw new NotImplementedException("unhandled: " + actionEvent.getActionId());
-                }
-            }
-        });
-    }
-
-    private void start() {
-        backgroundUpdateTimer.start();
-    }
-
-    private void stop() {
-        backgroundUpdateTimer.stop();
-    }
-
-    public BasicView getView() {
-        return view;
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/UiFacadeFactory.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/UiFacadeFactory.java	Wed Nov 28 12:28:04 2012 +0100
@@ -38,36 +38,31 @@
 
 import java.util.Collection;
 
+import com.redhat.thermostat.client.core.HostInformationService;
 import com.redhat.thermostat.client.core.VmInformationService;
 import com.redhat.thermostat.client.osgi.service.VMContextAction;
-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;
 
 public interface UiFacadeFactory {
 
     void setHostInfoDao(HostInfoDAO hostInfoDao);
-    void setCpuStatDao(CpuStatDAO cpuStatDAO);
-    void setMemoryStatDao(MemoryStatDAO memoryStatDAO);
-    void setNetworkInfoDao(NetworkInterfaceInfoDAO networkInterfaceInfoDAO);
 
     void setVmInfoDao(VmInfoDAO vmInfoDAO);
-    void setVmCpuStatDao(VmCpuStatDAO vmCpuStatDAO);
-    void setVmMemoryStatDao(VmMemoryStatDAO vmMemoryStatDao);
-    void setVmGcStatDao(VmGcStatDAO vmGcStatDao);
 
     public MainWindowController getMainWindow();
 
     public SummaryController getSummary();
 
     public HostInformationController getHostController(HostRef ref);
+    
+    Collection<HostInformationService> getHostInformationServices();
+
+    void addHostInformationService(HostInformationService hostInfoService);
+
+    void removeHostInformationService(HostInformationService hostInfoService);
 
     public VmInformationController getVmController(VmRef ref);
 
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/VmCpuController.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,127 +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 java.util.concurrent.TimeUnit;
-
-import com.redhat.thermostat.client.core.views.UIComponent;
-import com.redhat.thermostat.client.core.views.VmCpuView;
-import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
-import com.redhat.thermostat.client.core.views.BasicView.Action;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.NotImplementedException;
-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.dao.VmCpuStatDAO;
-import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.storage.model.DiscreteTimeData;
-import com.redhat.thermostat.storage.model.VmCpuStat;
-
-public class VmCpuController {
-
-    private final VmRef ref;
-    private final VmCpuStatDAO dao;
-    private final VmCpuView view;
-
-    private final Timer timer;
-
-    private long lastSeenTimeStamp = Long.MIN_VALUE;
-
-    public VmCpuController(VmCpuStatDAO vmCpuStatDao, VmRef ref, VmCpuViewProvider provider) {
-        this.ref = ref;
-        dao = vmCpuStatDao;
-        timer = ApplicationContext.getInstance().getTimerFactory().createTimer();
-
-        timer.setAction(new Runnable() {
-            @Override
-            public void run() {
-                doUpdateVmCpuCharts();
-            }
-        });
-        timer.setTimeUnit(TimeUnit.SECONDS);
-        timer.setDelay(5);
-        timer.setInitialDelay(0);
-        timer.setSchedulingType(SchedulingType.FIXED_RATE);
-
-        view = provider.createView();
-
-        view.addActionListener(new ActionListener<VmCpuView.Action>() {
-            @Override
-            public void actionPerformed(ActionEvent<Action> actionEvent) {
-                switch (actionEvent.getActionId()) {
-                    case HIDDEN:
-                        stop();
-                        break;
-                    case VISIBLE:
-                        start();
-                        break;
-                    default:
-                        throw new NotImplementedException("unknown event : " + actionEvent.getActionId());
-                }
-            }
-        });
-    }
-
-    private void start() {
-        timer.start();
-    }
-
-    private void doUpdateVmCpuCharts() {
-        List<VmCpuStat> stats = dao.getLatestVmCpuStats(ref, lastSeenTimeStamp);
-        List<DiscreteTimeData<? extends Number>> toDisplay = new ArrayList<>(stats.size());
-        for (VmCpuStat stat: stats) {
-            DiscreteTimeData<? extends Number> data =
-                    new DiscreteTimeData<Number>(stat.getTimeStamp(), stat.getCpuLoad());
-            toDisplay.add(data);
-            lastSeenTimeStamp = Math.max(lastSeenTimeStamp, stat.getTimeStamp());
-        }
-
-        view.addData(toDisplay);
-    }
-
-    private void stop() {
-        timer.stop();
-    }
-
-    public UIComponent getView() {
-        return (UIComponent) view;
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/VmGcController.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,197 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.ui;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.TimeUnit;
-
-import com.redhat.thermostat.client.core.views.UIComponent;
-import com.redhat.thermostat.client.core.views.VmGcView;
-import com.redhat.thermostat.client.core.views.VmGcViewProvider;
-import com.redhat.thermostat.client.core.views.BasicView.Action;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.NotImplementedException;
-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.dao.VmGcStatDAO;
-import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
-import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.storage.model.IntervalTimeData;
-import com.redhat.thermostat.storage.model.TimeStampedPojoComparator;
-import com.redhat.thermostat.storage.model.VmGcStat;
-import com.redhat.thermostat.storage.model.VmMemoryStat;
-import com.redhat.thermostat.storage.model.VmMemoryStat.Generation;
-
-public class VmGcController {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private final VmRef ref;
-    private final VmGcView view;
-
-    private final VmGcStatDAO gcDao;
-    private final VmMemoryStatDAO memDao;
-
-    private final Set<String> addedCollectors = new TreeSet<>();
-    // the last value seen for each collector
-    private final Map<String, VmGcStat> lastValueSeen = new TreeMap<>();
-
-    private final Timer timer;
-
-    private long lastSeenTimeStamp = Long.MIN_VALUE;
-
-    public VmGcController(VmMemoryStatDAO vmMemoryStatDao, VmGcStatDAO vmGcStatDao, VmRef ref, VmGcViewProvider provider) {
-        this.ref = ref;
-        this.view = provider.createView();
-        this.timer = ApplicationContext.getInstance().getTimerFactory().createTimer();
-
-        gcDao = vmGcStatDao;
-        memDao = vmMemoryStatDao;
-
-        view.addActionListener(new ActionListener<VmGcView.Action>() {
-            @Override
-            public void actionPerformed(ActionEvent<Action> actionEvent) {
-                switch (actionEvent.getActionId()) {
-                    case HIDDEN:
-                        stop();
-                        break;
-                    case VISIBLE:
-                        start();
-                        break;
-                    default:
-                        throw new NotImplementedException("unkonwn action: " + actionEvent.getActionId());
-                }
-            }
-        });
-
-        timer.setAction(new Runnable() {
-            @Override
-            public void run() {
-                try {
-                    doUpdateCollectorData();
-                } catch (Throwable t) {
-                    t.printStackTrace();
-                    throw t;
-                }
-            }
-        });
-        timer.setSchedulingType(SchedulingType.FIXED_RATE);
-        timer.setInitialDelay(0);
-        timer.setDelay(5);
-        timer.setTimeUnit(TimeUnit.SECONDS);
-    }
-
-    private void start() {
-        timer.start();
-    }
-
-    private void stop() {
-         timer.stop();
-    }
-
-    // FIXME
-    private String chartName(String collectorName, String generationName) {
-        return translator.localize(LocaleResources.VM_GC_COLLECTOR_OVER_GENERATION,
-                collectorName, generationName);
-    }
-
-    private void doUpdateCollectorData() {
-        Map<String, List<IntervalTimeData<Double>>> dataToAdd = new HashMap<>();
-        List<VmGcStat> sortedList = gcDao.getLatestVmGcStats(ref, lastSeenTimeStamp);
-        Collections.sort(sortedList, new TimeStampedPojoComparator<>());
-
-        for (VmGcStat stat : sortedList) {
-            String collector = stat.getCollectorName();
-            List<IntervalTimeData<Double>> data = dataToAdd.get(collector);
-            if (data == null) {
-                data = new ArrayList<>();
-                dataToAdd.put(collector, data);
-            }
-            if (lastValueSeen.containsKey(collector)) {
-                if (stat.getTimeStamp() <= lastValueSeen.get(collector).getTimeStamp()) {
-                    System.out.println("new gc collector value is older than previous value");
-                }
-                VmGcStat last = lastValueSeen.get(collector);
-                lastSeenTimeStamp = Math.max(lastSeenTimeStamp, stat.getTimeStamp());
-                long diffInMicro = (stat.getWallTime() - last.getWallTime());
-                double diffInMillis = diffInMicro / 1000.0;
-                // TODO there is not much point in adding data when diff is 0,
-                // but we need to make the chart scroll automatically based on
-                // the current time when we do that
-                //  if (diff != 0) {
-                data.add(new IntervalTimeData<>(last.getTimeStamp(), stat.getTimeStamp(), diffInMillis));
-                // }
-            }
-            lastValueSeen.put(collector, stat);
-        }
-        for (Map.Entry<String, List<IntervalTimeData<Double>>> entry : dataToAdd.entrySet()) {
-            String name = entry.getKey();
-            if (!addedCollectors.contains(name)) {
-                view.addChart(name, chartName(name, getCollectorGeneration(name)), "ms");
-                addedCollectors.add(name);
-            }
-            view.addData(entry.getKey(), entry.getValue());
-        }
-    }
-
-    public String getCollectorGeneration(String collectorName) {
-        VmMemoryStat info = memDao.getLatestMemoryStat(ref);
-
-        for (Generation g: info.getGenerations()) {
-            if (g.getCollector().equals(collectorName)) {
-                return g.getName();
-            }
-        }
-        return translator.localize(LocaleResources.UNKNOWN_GEN);
-    }
-
-    public UIComponent getView() {
-        return (UIComponent) view;
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/VmInformationController.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/VmInformationController.java	Wed Nov 28 12:28:04 2012 +0100
@@ -41,46 +41,21 @@
 import com.redhat.thermostat.client.core.VmInformationService;
 import com.redhat.thermostat.client.core.controllers.VmInformationServiceController;
 import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
-import com.redhat.thermostat.client.core.views.VmGcViewProvider;
 import com.redhat.thermostat.client.core.views.VmInformationView;
 import com.redhat.thermostat.client.core.views.VmInformationViewProvider;
-import com.redhat.thermostat.client.core.views.VmOverviewViewProvider;
-import com.redhat.thermostat.client.locale.LocaleResources;
-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.locale.Translate;
 import com.redhat.thermostat.common.utils.OSGIUtils;
 
 public class VmInformationController {
 
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
     private final VmInformationView view;
 
-    private final VmOverviewController overviewController;
-    private final VmCpuController cpuController;
-    private final VmGcController gcController;
-
-    public VmInformationController(UiFacadeFactory uiFacadeFactory, VmInfoDAO vmInfoDao, VmCpuStatDAO vmCpuStatDao, VmMemoryStatDAO vmMemoryStatDao, VmGcStatDAO vmGcStatDao, VmRef vmRef, VmInformationViewProvider provider) {
-        this(OSGIUtils.getInstance(), uiFacadeFactory, vmInfoDao, vmCpuStatDao, vmMemoryStatDao,  vmGcStatDao, vmRef, provider);
+    public VmInformationController(UiFacadeFactory uiFacadeFactory, VmRef vmRef, VmInformationViewProvider provider) {
+        this(OSGIUtils.getInstance(), uiFacadeFactory, vmRef, provider);
     }
     
-    VmInformationController(OSGIUtils serviceProvider, UiFacadeFactory uiFacadeFactory, VmInfoDAO vmInfoDao, VmCpuStatDAO vmCpuStatDao, VmMemoryStatDAO vmMemoryStatDao, VmGcStatDAO vmGcStatDao, VmRef vmRef, VmInformationViewProvider provider) {
-        VmOverviewViewProvider vmOverviewProvider = serviceProvider.getService(VmOverviewViewProvider.class);
-        overviewController = new VmOverviewController(vmInfoDao, vmRef, vmOverviewProvider);
-        VmCpuViewProvider vmCpuProvider = serviceProvider.getService(VmCpuViewProvider.class);
-        cpuController = new VmCpuController(vmCpuStatDao, vmRef, vmCpuProvider);
-        VmGcViewProvider vmGCProvider = serviceProvider.getService(VmGcViewProvider.class);
-        gcController = new VmGcController(vmMemoryStatDao, vmGcStatDao, vmRef, vmGCProvider);
-
+    VmInformationController(OSGIUtils serviceProvider, UiFacadeFactory uiFacadeFactory, VmRef vmRef, VmInformationViewProvider provider) {
         view = provider.createView();
-        view.addChildView(translator.localize(LocaleResources.VM_INFO_TAB_OVERVIEW), overviewController.getView());
-        view.addChildView(translator.localize(LocaleResources.VM_INFO_TAB_CPU), cpuController.getView());
-        view.addChildView(translator.localize(LocaleResources.VM_INFO_TAB_GC), gcController.getView());
 
         Collection<VmInformationService> vmInfoServices = uiFacadeFactory.getVmInformationServices();
         for (VmInformationService vmInfoService : vmInfoServices) {
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/VmOverviewController.java	Wed Nov 28 12:24:00 2012 +0100
+++ /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.text.DateFormat;
-import java.util.Date;
-import java.util.concurrent.TimeUnit;
-
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.UIComponent;
-import com.redhat.thermostat.client.core.views.VmOverviewView;
-import com.redhat.thermostat.client.core.views.VmOverviewViewProvider;
-import com.redhat.thermostat.client.core.views.BasicView.Action;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.NotImplementedException;
-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.dao.VmInfoDAO;
-import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.common.locale.Translate;
-import com.redhat.thermostat.storage.model.VmInfo;
-
-class VmOverviewController {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-
-    private final VmRef ref;
-    private final VmInfoDAO dao;
-    private final DateFormat vmRunningTimeFormat;
-
-    private final Timer timer;
-
-    private final VmOverviewView view;
-
-    public VmOverviewController(VmInfoDAO vmDao, VmRef vmRef, VmOverviewViewProvider provider) {
-        this.ref = vmRef;
-        this.view = provider.createView();
-
-        dao = vmDao;
-        timer = ApplicationContext.getInstance().getTimerFactory().createTimer();
-
-        vmRunningTimeFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.FULL);
-
-        view.addActionListener(new ActionListener<Action>() {
-            @Override
-            public void actionPerformed(ActionEvent<Action> actionEvent) {
-                switch(actionEvent.getActionId()) {
-                    case HIDDEN:
-                        stop();
-                        break;
-                    case VISIBLE:
-                        start();
-                        break;
-                    default:
-                        throw new NotImplementedException("unknown event: " + actionEvent.getActionId());
-                }
-            }
-        });
-
-        timer.setAction(new Runnable() {
-
-            @Override
-            public void run() {
-                VmInfo info = dao.getVmInfo(ref);
-                view.setVmPid(((Integer) info.getVmPid()).toString());
-                long actualStartTime = info.getStartTimeStamp();
-                view.setVmStartTimeStamp(vmRunningTimeFormat.format(new Date(actualStartTime)));
-                long actualStopTime = info.getStopTimeStamp();
-                if (actualStopTime >= actualStartTime) {
-                    // Only show a stop time if we have actually stopped.
-                    view.setVmStopTimeStamp(vmRunningTimeFormat.format(new Date(actualStopTime)));
-                } else {
-                    view.setVmStopTimeStamp(translator.localize(LocaleResources.VM_INFO_RUNNING));
-                }
-                view.setJavaVersion(info.getJavaVersion());
-                view.setJavaHome(info.getJavaHome());
-                view.setMainClass(info.getMainClass());
-                view.setJavaCommandLine(info.getJavaCommandLine());
-                String actualVmName = info.getVmName();
-                view.setVmInfo(info.getVmInfo());
-                String actualVmVersion = info.getVmInfo();
-                view.setVmNameAndVersion(translator.localize(LocaleResources.VM_INFO_VM_NAME_AND_VERSION,
-                        actualVmName, actualVmVersion));
-                view.setVmArguments(info.getVmArguments());
-            }
-        });
-        timer.setInitialDelay(0);
-        timer.setDelay(5);
-        timer.setTimeUnit(TimeUnit.SECONDS);
-        timer.setSchedulingType(SchedulingType.FIXED_RATE);
-    }
-
-    private void start() {
-        timer.start();
-    }
-
-    private void stop() {
-        timer.stop();
-    }
-
-    public UIComponent getView() {
-        return (UIComponent) view;
-    }
-}
--- a/client/core/src/main/resources/com/redhat/thermostat/client/locale/strings.properties	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/core/src/main/resources/com/redhat/thermostat/client/locale/strings.properties	Wed Nov 28 12:28:04 2012 +0100
@@ -23,16 +23,6 @@
 MENU_HELP = Help
 MENU_HELP_ABOUT = About
 
-GARBAGE_COLLECTION = Garbage Collection
-YOUNG_GEN = Young
-EDEN_GEN = Eden
-S0_GEN = Survivor 0
-S1_GEN = Survivor 1
-OLD_GEN = Tenured
-PERM_GEN = Permanent
-UNKNOWN_GEN = Unknown
-SOME_GENERATION = {0} Generation
-
 SECONDS = Seconds
 MINUTES = Minutes
 HOURS = Hours
@@ -66,75 +56,8 @@
 HOME_PANEL_SECTION_ISSUES = Issues
 HOME_PANEL_NO_ISSUES = No Issues
 
-HOST_INFO_TAB_OVERVIEW = Overview
-HOST_INFO_TAB_CPU = Processor
-HOST_INFO_TAB_MEMORY = Memory
 HOST_INFO_TAB_IO = IO
 
-HOST_OVERVIEW_SECTION_BASICS = Basics
-HOST_OVERVIEW_SECTION_HARDWARE = Hardware
-HOST_OVERVIEW_SECTION_SOFTWARE = Software
-
-HOST_INFO_HOSTNAME = Host
-HOST_INFO_CPU_COUNT = Processor Count
-HOST_INFO_CPU_MODEL = Processor Model
-HOST_INFO_OS_NAME = OS Name
-HOST_INFO_OS_KERNEL = OS Kernel
-HOST_INFO_MEMORY_TOTAL = Total Memory
-HOST_INFO_NETWORK = Network
-
-NETWORK_INTERFACE_COLUMN = Interface
-NETWORK_IPV4_COLUMN = IPv4 Address
-NETWORK_IPV6_COLUMN = IPv6 Address
-
-HOST_CPU_SECTION_OVERVIEW = Processor
-HOST_CPU_ID = Cpu {0}
-HOST_CPU_USAGE_CHART_TIME_LABEL = Time
-HOST_CPU_USAGE_CHART_VALUE_LABEL = Cpu Usage (%)
-
-HOST_MEMORY_SECTION_OVERVIEW = Memory
-HOST_MEMORY_CHART_TITLE = Memory
-HOST_MEMORY_CHART_TIME_LABEL = Time
-HOST_MEMORY_CHART_SIZE_LABEL = Size ({0})
-
-HOST_MEMORY_TOTAL = Total Memory
-HOST_MEMORY_FREE = Free Memory
-HOST_MEMORY_USED = Used Memory
-HOST_SWAP_TOTAL = Total Swap
-HOST_SWAP_FREE = Free Swap
-HOST_BUFFERS = Buffers
-
-VM_INFO_TAB_OVERVIEW = Overview
-VM_INFO_TAB_CPU = CPU
-VM_INFO_TAB_GC = GC
-
-VM_INFO_TITLE = Virtual Machine Overview
-VM_INFO_SECTION_PROCESS = Process Information
-VM_INFO_SECTION_JAVA = Java Information
-
-VM_INFO_PROCESS_ID = Process Id
-VM_INFO_START_TIME = Start time
-VM_INFO_STOP_TIME = Stop time
-VM_INFO_RUNNING = Running
-VM_INFO_MAIN_CLASS = Main Class
-VM_INFO_COMMAND_LINE = Command Line
-VM_INFO_JAVA_VERSION = Java Version
-VM_INFO_VM = Virtual Machine
-VM_INFO_VM_ARGUMENTS = VM arguments
-VM_INFO_VM_NAME_AND_VERSION = {0} version {1}
-VM_INFO_PROPERTIES = Properties
-VM_INFO_ENVIRONMENT = Environment
-VM_INFO_LIBRARIES = Native Libraries
-
-VM_CPU_TITLE = Cpu Usage by Virtual Machine
-VM_CPU_CHART_LOAD_LABEL = % CPU
-VM_CPU_CHART_TIME_LABEL = Time
-
-VM_GC_TITLE = Garbage Collection in the VM
-VM_GC_COLLECTOR_OVER_GENERATION = Collector {0} running on {1}
-VM_GC_COLLECTOR_CHART_REAL_TIME_LABEL = Time
-VM_GC_COLLECTOR_CHART_GC_TIME_LABEL = GC Time ({0})
-
 AGENT_INFO_WINDOW_TITLE = Known Agents
 AGENT_INFO_AGENTS_LIST = Agents
 AGENT_INFO_AGENT_SECTION_TITLE = Agent Information
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/HostCpuControllerTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +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.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNotNull;
-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.Arrays;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-import com.redhat.thermostat.client.core.views.HostCpuView;
-import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.Timer;
-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.CpuStatDAO;
-import com.redhat.thermostat.common.dao.HostInfoDAO;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.storage.model.CpuStat;
-import com.redhat.thermostat.storage.model.DiscreteTimeData;
-import com.redhat.thermostat.storage.model.HostInfo;
-
-public class HostCpuControllerTest {
-
-    @SuppressWarnings("unused")
-    private HostCpuController controller;
-
-    private HostCpuView view;
-
-    private Timer timer;
-
-    private ActionListener<HostCpuView.Action> viewListener;
-    private Runnable timerAction;
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Before
-    public void setUp() {
-        // Setup timer.
-        ApplicationContextUtil.resetApplicationContext();
-        timer = mock(Timer.class);
-        ArgumentCaptor<Runnable> actionCaptor = ArgumentCaptor.forClass(Runnable.class);
-        doNothing().when(timer).setAction(actionCaptor.capture());
-
-        TimerFactory timerFactory = mock(TimerFactory.class);
-        when(timerFactory.createTimer()).thenReturn(timer);
-        ApplicationContext.getInstance().setTimerFactory(timerFactory);
-
-        // Setup DAOs.
-        HostInfo hostInfo = new HostInfo("fluffhost1", "fluffOs1", "fluffKernel1", "fluffCpu1", 12345, 98765);
-        HostInfoDAO hostInfoDAO = mock(HostInfoDAO.class);
-        when(hostInfoDAO.getHostInfo(any(HostRef.class))).thenReturn(hostInfo);
-
-        CpuStat cpuStat1 = new CpuStat(1l, new double[] {10.0, 20.0, 30.0});
-        CpuStat cpuStat2 = new CpuStat(2l, new double[] {15.0, 25.0, 35.0});
-        CpuStatDAO cpuStatDAO = mock(CpuStatDAO.class);
-        when(cpuStatDAO.getLatestCpuStats(any(HostRef.class), anyLong())).thenReturn(Arrays.asList(cpuStat1, cpuStat2));
-
-        // Set up View
-        view = mock(HostCpuView.class);
-        ArgumentCaptor<ActionListener> viewArgumentCaptor = ArgumentCaptor.forClass(ActionListener.class);
-        doNothing().when(view).addActionListener(viewArgumentCaptor.capture());
-        HostCpuViewProvider viewProvider = mock(HostCpuViewProvider.class);
-        when(viewProvider.createView()).thenReturn(view);
-
-        HostRef host = new HostRef("123", "fluffhost");
-        controller = new HostCpuController(hostInfoDAO, cpuStatDAO, host, viewProvider);
-
-        timerAction = actionCaptor.getValue();
-        viewListener = viewArgumentCaptor.getValue();
-    }
-
-    @After
-    public void tearDown() {
-        timerAction = null;
-        controller = null;
-        view = null;
-        timer = null;
-        ApplicationContextUtil.resetApplicationContext();
-    }
-
-    @Test
-    public void testTimer() {
-        viewListener.actionPerformed(new ActionEvent<>(view, HostCpuView.Action.VISIBLE));
-
-        verify(timer).setAction(isNotNull(Runnable.class));
-        verify(timer).setDelay(5);
-        verify(timer).setTimeUnit(TimeUnit.SECONDS);
-        verify(timer).setInitialDelay(0);
-        verify(timer).setSchedulingType(SchedulingType.FIXED_RATE);
-        verify(timer).start();
-
-        viewListener.actionPerformed(new ActionEvent<>(view, HostCpuView.Action.HIDDEN));
-
-        verify(timer).stop();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void testTimerAction() {
-        timerAction.run();
-        verify(view).setCpuModel("fluffCpu1");
-        verify(view).setCpuCount("12345");
-        @SuppressWarnings("rawtypes")
-        ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
-        verify(view).addCpuUsageChart(eq(0), anyString());
-        verify(view).addCpuUsageData(eq(0), captor.capture());
-        List<DiscreteTimeData<Double>> cpuLoadData = captor.getValue();
-        assertEquals(1, cpuLoadData.get(0).getTimeInMillis());
-        assertEquals(10.0, cpuLoadData.get(0).getData().doubleValue(), 0.0001);
-        assertEquals(2, cpuLoadData.get(1).getTimeInMillis());
-        assertEquals(15.0, cpuLoadData.get(1).getData().doubleValue(), 0.0001);
-    }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/HostMemoryControllerTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,125 +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.mockito.Matchers.any;
-import static org.mockito.Matchers.anyLong;
-import static org.mockito.Matchers.eq;
-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.util.LinkedList;
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-import com.redhat.thermostat.client.core.views.HostMemoryView;
-import com.redhat.thermostat.client.core.views.HostMemoryViewProvider;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.Timer;
-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.MemoryStatDAO;
-import com.redhat.thermostat.storage.model.HostInfo;
-import com.redhat.thermostat.storage.model.MemoryStat;
-
-public class HostMemoryControllerTest {
-
-    @Before
-    public void setUp() {
-        ApplicationContextUtil.resetApplicationContext();
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" }) // any(List.class)
-    @Test
-    public void testUpdate() {
-        final long TOTAL_MEMORY = 512;
-        HostInfo hostInfo = new HostInfo("someHost", "someOS", "linux_0.0.1", "lreally_fast_cpu", 2, TOTAL_MEMORY);
-        HostInfoDAO hostInfoDAO = mock(HostInfoDAO.class);
-        when(hostInfoDAO.getHostInfo(any(HostRef.class))).thenReturn(hostInfo);
-
-        MemoryStat memoryStat = new MemoryStat(1, 2, 3, 4, 5, 6, 7, 8);
-        List<MemoryStat> memoryStats = new LinkedList<>();
-        memoryStats.add(memoryStat);
-        MemoryStatDAO memoryStatDAO = mock(MemoryStatDAO.class);
-        when(memoryStatDAO.getLatestMemoryStats(any(HostRef.class), anyLong())).thenReturn(memoryStats);
-
-        Timer timer = mock(Timer.class);
-        ArgumentCaptor<Runnable> timerActionCaptor = ArgumentCaptor.forClass(Runnable.class);
-        doNothing().when(timer).setAction(timerActionCaptor.capture());
-
-        TimerFactory timerFactory = mock(TimerFactory.class);
-        when(timerFactory.createTimer()).thenReturn(timer);
-        ApplicationContext.getInstance().setTimerFactory(timerFactory);
-
-        HostRef ref = mock(HostRef.class);
-
-        HostMemoryView view = mock(HostMemoryView.class);
-        ArgumentCaptor<ActionListener> viewArgumentCaptor = ArgumentCaptor.forClass(ActionListener.class);
-        doNothing().when(view).addActionListener(viewArgumentCaptor.capture());
-
-        HostMemoryViewProvider viewProvider = mock(HostMemoryViewProvider.class);
-        when(viewProvider.createView()).thenReturn(view);
-
-        @SuppressWarnings("unused")
-        HostMemoryController controller = new HostMemoryController(hostInfoDAO, memoryStatDAO, ref, viewProvider);
-
-        ActionListener<HostMemoryView.Action> l = viewArgumentCaptor.getValue();
-
-        l.actionPerformed(new ActionEvent<>(view, HostMemoryView.Action.VISIBLE));
-
-        verify(timer).start();
-        timerActionCaptor.getValue().run();
-
-        verify(view, times(1)).setTotalMemory(eq(TOTAL_MEMORY + " B"));
-        verify(view, times(6)).addMemoryData(any(String.class), any(List.class));
-
-        l.actionPerformed(new ActionEvent<>(view, HostMemoryView.Action.HIDDEN));
-
-        verify(timer).stop();
-
-    }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/HostOverviewControllerTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +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.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNotNull;
-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.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-import com.redhat.thermostat.client.core.views.HostOverviewView;
-import com.redhat.thermostat.client.core.views.HostOverviewViewProvider;
-import com.redhat.thermostat.client.core.views.BasicView.Action;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.Timer;
-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.NetworkInterfaceInfoDAO;
-import com.redhat.thermostat.storage.model.HostInfo;
-import com.redhat.thermostat.storage.model.NetworkInterfaceInfo;
-
-public class HostOverviewControllerTest {
-
-    private static final String HOST_NAME = "host-name";
-    private static final String OS_NAME = "some os";
-    private static final String KERNEL_NAME = "korn";
-    private static final int CPU_COUNT = 99;
-    private static final String CPU_MODEL = "cpu-model";
-    private static final long TOTAL_MEMORY = 99+99;
-    private static final String NETWORK_INTERFACE = "iface0";
-    private static final String IPV4_ADDR = "0xcafef00d";
-    private static final String IPV6_ADDR = "HOME_SWEET_HOME";
-
-    private Timer timer;
-    private Runnable timerAction;
-    private HostOverviewView view;
-    private ActionListener<HostOverviewView.Action> listener;
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Before
-    public void setUp() {
-        ApplicationContextUtil.resetApplicationContext();
-
-        // Setup timer
-        timer = mock(Timer.class);
-        ArgumentCaptor<Runnable> timerActionCaptor = ArgumentCaptor.forClass(Runnable.class);
-        doNothing().when(timer).setAction(timerActionCaptor.capture());
-
-        TimerFactory timerFactory = mock(TimerFactory.class);
-        when(timerFactory.createTimer()).thenReturn(timer);
-        ApplicationContext.getInstance().setTimerFactory(timerFactory);
-
-        // Setup DAOs
-        HostInfo hostInfo = new HostInfo(HOST_NAME, OS_NAME, KERNEL_NAME, CPU_MODEL, CPU_COUNT, TOTAL_MEMORY);
-
-        List<NetworkInterfaceInfo> networkInfo = new ArrayList<NetworkInterfaceInfo>();
-        NetworkInterfaceInfo ifaceInfo = new NetworkInterfaceInfo(NETWORK_INTERFACE);
-        ifaceInfo.setIp4Addr(IPV4_ADDR);
-        ifaceInfo.setIp6Addr(IPV6_ADDR);
-        networkInfo.add(ifaceInfo);
-
-        HostRef ref = mock(HostRef.class);
-
-        HostInfoDAO hostInfoDao = mock(HostInfoDAO.class);
-        when(hostInfoDao.getHostInfo(any(HostRef.class))).thenReturn(hostInfo);
-
-        NetworkInterfaceInfoDAO networkInfoDao = mock(NetworkInterfaceInfoDAO.class);
-        when(networkInfoDao.getNetworkInterfaces(any(HostRef.class))).thenReturn(networkInfo);
-
-        // Setup View
-        ArgumentCaptor<ActionListener> listenerCaptor = ArgumentCaptor.forClass(ActionListener.class);
-        view = mock(HostOverviewView.class);
-        doNothing().when(view).addActionListener(listenerCaptor.capture());
-        HostOverviewViewProvider viewProvider = mock(HostOverviewViewProvider.class);
-        when(viewProvider.createView()).thenReturn(view);
-
-        @SuppressWarnings("unused")
-        HostOverviewController controller = new HostOverviewController(hostInfoDao, networkInfoDao, ref, viewProvider);
-
-        listener = listenerCaptor.getValue();
-        timerAction = timerActionCaptor.getValue();
-    }
-
-    @After
-    public void tearDown() {
-        ApplicationContextUtil.resetApplicationContext();
-    }
-
-    @Test
-    public void verifyViewIsUpdatedWithData() {
-        timerAction.run();
-
-        verify(view).setCpuCount(eq(String.valueOf(CPU_COUNT)));
-        verify(view).setCpuModel(eq(CPU_MODEL));
-        verify(view).setHostName(eq(HOST_NAME));
-
-        verify(view).setNetworkTableColumns(any(String[][].class));
-        verify(view).setInitialNetworkTableData(eq(new String[][] { new String[] { NETWORK_INTERFACE, IPV4_ADDR, IPV6_ADDR }, }));
-
-        verify(view).setOsKernel(eq(KERNEL_NAME));
-        verify(view).setOsName(eq(OS_NAME));
-
-        final String UNITS = " B";
-        verify(view).setTotalMemory(eq(String.valueOf(TOTAL_MEMORY + UNITS)));
-    }
-
-    @Test
-    public void verifyTimerIsSetUpCorrectly() {
-        assertNotNull(timer);
-
-        verify(timer).setAction(isNotNull(Runnable.class));
-        verify(timer).setDelay(5);
-        verify(timer).setTimeUnit(TimeUnit.SECONDS);
-        verify(timer).setInitialDelay(0);
-        verify(timer).setSchedulingType(SchedulingType.FIXED_RATE);
-    }
-
-    @Test
-    public void verifyTimerRunsWhenNeeded() {
-        listener.actionPerformed(new ActionEvent<>(view, Action.VISIBLE));
-
-        verify(timer).start();
-
-        listener.actionPerformed(new ActionEvent<>(view, Action.HIDDEN));
-
-        verify(timer).stop();
-    }
-
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/VmCpuControllerTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +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.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-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.ArrayList;
-import java.util.List;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-import com.redhat.thermostat.client.core.views.VmCpuView;
-import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.Timer;
-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.VmCpuStatDAO;
-import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.storage.model.VmCpuStat;
-
-
-public class VmCpuControllerTest {
-
-    @Before
-    public void setUp() {
-        ApplicationContextUtil.resetApplicationContext();
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" }) // any(List.class)
-    @Test
-    public void testChartUpdate() {
-
-        VmCpuStat stat1 = new VmCpuStat(123, 12345, 50.5);
-        List<VmCpuStat> stats = new ArrayList<VmCpuStat>();
-        stats.add(stat1);
-
-        VmCpuStatDAO vmCpuStatDAO = mock(VmCpuStatDAO.class);
-        when(vmCpuStatDAO.getLatestVmCpuStats(any(VmRef.class), eq(Long.MIN_VALUE))).thenReturn(stats).thenReturn(new ArrayList<VmCpuStat>());
-
-        VmRef ref = mock(VmRef.class);
-
-        Timer timer = mock(Timer.class);
-        ArgumentCaptor<Runnable> timerActionCaptor = ArgumentCaptor.forClass(Runnable.class);
-        doNothing().when(timer).setAction(timerActionCaptor.capture());
-
-        TimerFactory timerFactory = mock(TimerFactory.class);
-        when(timerFactory.createTimer()).thenReturn(timer);
-        ApplicationContext.getInstance().setTimerFactory(timerFactory);
-
-        final VmCpuView view = mock(VmCpuView.class);
-        ArgumentCaptor<ActionListener> viewArgumentCaptor = ArgumentCaptor.forClass(ActionListener.class);
-        doNothing().when(view).addActionListener(viewArgumentCaptor.capture());
-        
-        VmCpuViewProvider viewProvider = mock(VmCpuViewProvider.class);
-        when(viewProvider.createView()).thenReturn(view);
-
-        @SuppressWarnings("unused")
-        VmCpuController controller = new VmCpuController(vmCpuStatDAO, ref, viewProvider);
-
-        ActionListener<VmCpuView.Action> l = viewArgumentCaptor.getValue();
-
-        l.actionPerformed(new ActionEvent<>(view, VmCpuView.Action.VISIBLE));
-
-        verify(timer).start();
-
-        timerActionCaptor.getValue().run();
-
-        l.actionPerformed(new ActionEvent<>(view, VmCpuView.Action.HIDDEN));
-
-        verify(timer).stop();
-
-        verify(view).addData(any(List.class));
-        // We don't verify atMost() since we might increase the update rate in the future.
-    }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/VmGcControllerTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,165 +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.mockito.Matchers.eq;
-import static org.mockito.Matchers.isA;
-import static org.mockito.Matchers.isNotNull;
-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.ArrayList;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-
-import com.redhat.thermostat.client.core.views.VmGcView;
-import com.redhat.thermostat.client.core.views.VmGcViewProvider;
-import com.redhat.thermostat.common.ActionEvent;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.Timer;
-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.VmGcStatDAO;
-import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
-import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.storage.model.VmGcStat;
-import com.redhat.thermostat.storage.model.VmMemoryStat;
-import com.redhat.thermostat.storage.model.VmMemoryStat.Generation;
-
-public class VmGcControllerTest {
-
-    private Timer timer;
-    private Runnable timerAction;
-    private VmGcView view;
-    private ActionListener<VmGcView.Action> viewListener;
-
-    @SuppressWarnings({ "rawtypes", "unchecked" })
-    @Before
-    public void setUp() {
-        ApplicationContextUtil.resetApplicationContext();
-
-        // Setup Timer
-        timer = mock(Timer.class);
-        ArgumentCaptor<Runnable> timerActionCaptor = ArgumentCaptor.forClass(Runnable.class);
-        doNothing().when(timer).setAction(timerActionCaptor.capture());
-
-        TimerFactory timerFactory = mock(TimerFactory.class);
-        when(timerFactory.createTimer()).thenReturn(timer);
-        ApplicationContext.getInstance().setTimerFactory(timerFactory);
-
-        // Set up fake data
-        List<VmGcStat> stats = new ArrayList<>();
-        VmGcStat stat1 = new VmGcStat(42, 1, "collector1", 1, 10);
-        VmGcStat stat2 = new VmGcStat(42, 2, "collector1", 5, 20);
-        stats.add(stat1);
-        stats.add(stat2);
-
-        Generation gen;
-        gen = new Generation();
-        gen.setName("generation 1");
-        gen.setCollector("collector1");
-        VmMemoryStat memoryStat = new VmMemoryStat(1, 42, new Generation[] { gen });
-
-        // Setup DAO
-        VmGcStatDAO vmGcStatDAO = mock(VmGcStatDAO.class);
-        when(vmGcStatDAO.getLatestVmGcStats(isA(VmRef.class), eq(Long.MIN_VALUE))).thenReturn(stats);
-        VmMemoryStatDAO vmMemoryStatDAO = mock(VmMemoryStatDAO.class);
-        when(vmMemoryStatDAO.getLatestMemoryStat(isA(VmRef.class))).thenReturn(memoryStat);
-
-        // Setup View
-        view = mock(VmGcView.class);
-        ArgumentCaptor<ActionListener> viewArgumentCaptor = ArgumentCaptor.forClass(ActionListener.class);
-        doNothing().when(view).addActionListener(viewArgumentCaptor.capture());
-
-        VmGcViewProvider viewProvider = mock(VmGcViewProvider.class);
-        when(viewProvider.createView()).thenReturn(view);
-
-        // Now start the controller
-        VmRef ref = mock(VmRef.class);
-
-        new VmGcController(vmMemoryStatDAO, vmGcStatDAO, ref, viewProvider);
-
-        // Extract relevant objects
-        viewListener = viewArgumentCaptor.getValue();
-        timerAction = timerActionCaptor.getValue();
-    }
-
-    @After
-    public void tearDown() {
-        ApplicationContextUtil.resetApplicationContext();
-    }
-
-    @Test
-    public void verifyTimer() {
-        verify(timer).setAction(isNotNull(Runnable.class));
-        verify(timer).setAction(isA(Runnable.class));
-        verify(timer).setDelay(5);
-        verify(timer).setInitialDelay(0);
-        verify(timer).setTimeUnit(TimeUnit.SECONDS);
-        verify(timer).setSchedulingType(SchedulingType.FIXED_RATE);
-
-    }
-
-    @Test
-    public void verifyStartAndStop() {
-        viewListener.actionPerformed(new ActionEvent<>(view, VmGcView.Action.VISIBLE));
-
-        verify(timer).start();
-
-        viewListener.actionPerformed(new ActionEvent<>(view, VmGcView.Action.HIDDEN));
-
-        verify(timer).stop();
-    }
-
-    @SuppressWarnings("unchecked")
-    @Test
-    public void verifyAction() {
-        timerAction.run();
-
-        verify(view).addData(isA(String.class), isA(List.class));
-    }
-
-}
--- a/client/pom.xml	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -66,6 +66,7 @@
     <module>living-vm-filter</module>
     <module>command</module>
     <module>swing</module>
+    <module>swing-components</module>
   </modules>
 
 </project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing-components/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,70 @@
+<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.components,
+              com.redhat.thermostat.swing.components.models,
+              com.redhat.thermostat.swing.components.experimental
+            </Export-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-components/src/main/java/com/redhat/thermostat/swing/components/experimental/WrapLayout.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.swing.components.experimental;
+
+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/swing/pom.xml	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/swing/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -51,13 +51,18 @@
   <name>Thermostat Swing Client</name>
 
   <dependencies>
-      <dependency>
+    <dependency>
       <groupId>com.redhat.thermostat</groupId>
       <artifactId>thermostat-client-core</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-swing-components</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
       <artifactId>thermostat-laf</artifactId>
       <version>${project.version}</version>
     </dependency>
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SimpleTable.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,290 +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.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);
-        }
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/ChangeableText.java	Wed Nov 28 12:24:00 2012 +0100
+++ /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.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);
-        }
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/Main.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/Main.java	Wed Nov 28 12:28:04 2012 +0100
@@ -70,11 +70,11 @@
 import com.redhat.thermostat.common.utils.OSGIUtils;
 import com.redhat.thermostat.storage.config.StartupConfiguration;
 import com.redhat.thermostat.storage.core.Connection;
-import com.redhat.thermostat.storage.core.StorageProvider;
-import com.redhat.thermostat.storage.core.StorageProviderUtil;
 import com.redhat.thermostat.storage.core.Connection.ConnectionListener;
 import com.redhat.thermostat.storage.core.Connection.ConnectionStatus;
 import com.redhat.thermostat.storage.core.Connection.ConnectionType;
+import com.redhat.thermostat.storage.core.StorageProvider;
+import com.redhat.thermostat.storage.core.StorageProviderUtil;
 import com.redhat.thermostat.utils.keyring.Keyring;
 
 public class Main {
@@ -282,14 +282,7 @@
                 // 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) {
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/UiFacadeFactoryImpl.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/UiFacadeFactoryImpl.java	Wed Nov 28 12:28:04 2012 +0100
@@ -42,6 +42,7 @@
 
 import org.osgi.framework.BundleContext;
 
+import com.redhat.thermostat.client.core.HostInformationService;
 import com.redhat.thermostat.client.core.VmInformationService;
 import com.redhat.thermostat.client.core.views.HostInformationViewProvider;
 import com.redhat.thermostat.client.core.views.SummaryViewProvider;
@@ -53,15 +54,9 @@
 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;
 
@@ -69,20 +64,14 @@
 
     private CountDownLatch shutdown = new CountDownLatch(1);
 
+    private Collection<HostInformationService> hostInformationServices = new ArrayList<>();
     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;
     
@@ -100,36 +89,10 @@
         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();
@@ -146,13 +109,13 @@
     @Override
     public HostInformationController getHostController(HostRef ref) {
         HostInformationViewProvider viewProvider = serviceProvider.getService(HostInformationViewProvider.class);
-        return new HostInformationController(hostInfoDao, networkInfoDao, cpuStatDao, memoryStatDao, ref, viewProvider);
+        return new HostInformationController(this, ref, viewProvider);
     }
 
     @Override
     public VmInformationController getVmController(VmRef ref) {
         VmInformationViewProvider viewProvider = serviceProvider.getService(VmInformationViewProvider.class);
-        return new VmInformationController(this, vmInfoDao, vmCpuStatDao, vmMemoryStatDao, vmGcStatDao, ref, viewProvider);
+        return new VmInformationController(this, ref, viewProvider);
     }
 
     @Override
@@ -196,4 +159,19 @@
         shutdown.await();
     }
 
+    @Override
+    public Collection<HostInformationService> getHostInformationServices() {
+        return hostInformationServices;
+    }
+
+    @Override
+    public void addHostInformationService(HostInformationService hostInfoService) {
+        hostInformationServices.add(hostInfoService);
+    }
+
+    @Override
+    public void removeHostInformationService(HostInformationService hostInfoService) {
+        hostInformationServices.remove(hostInfoService);
+    }
+
 }
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/WrapLayout.java	Wed Nov 28 12:24:00 2012 +0100
+++ /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.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/osgi/HostInformationServiceTracker.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.HostInformationService;
+import com.redhat.thermostat.client.ui.UiFacadeFactory;
+
+class HostInformationServiceTracker extends ServiceTracker {
+
+    private UiFacadeFactory uiFacadeFactory;
+
+    private BundleContext context;
+
+    HostInformationServiceTracker(BundleContext context, UiFacadeFactory uiFacadeFactory) {
+        super(context, HostInformationService.class.getName(), null);
+        this.context = context;
+        this.uiFacadeFactory = uiFacadeFactory;
+    }
+
+    @Override
+    public Object addingService(ServiceReference reference) {
+        HostInformationService service = (HostInformationService) super.addingService(reference);
+        uiFacadeFactory.addHostInformationService(service);
+        return service;
+    }
+
+    @Override
+    public void removedService(ServiceReference reference, Object service) {
+        uiFacadeFactory.removeHostInformationService((HostInformationService)service);
+        super.removedService(reference, service);
+    }
+}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivator.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivator.java	Wed Nov 28 12:28:04 2012 +0100
@@ -45,15 +45,9 @@
 
 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;
@@ -61,15 +55,9 @@
 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;
@@ -77,6 +65,7 @@
 
 public class ThermostatActivator implements BundleActivator {
 
+    private HostInformationServiceTracker hostInfoServiceTracker;
     private VmInformationServiceTracker vmInfoServiceTracker;
     private VMContextActionServiceTracker contextActionTracker;
 
@@ -92,22 +81,10 @@
         // 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();
@@ -127,6 +104,8 @@
                 
                 UiFacadeFactory uiFacadeFactory = new UiFacadeFactoryImpl(context);
 
+                hostInfoServiceTracker = new HostInformationServiceTracker(context, uiFacadeFactory);
+                hostInfoServiceTracker.open();
                 vmInfoServiceTracker = new VmInformationServiceTracker(context, uiFacadeFactory);
                 vmInfoServiceTracker.open();
                 contextActionTracker = new VMContextActionServiceTracker(context, uiFacadeFactory);
@@ -146,6 +125,7 @@
 
     @Override
     public void stop(BundleContext context) throws Exception {
+        hostInfoServiceTracker.close();
         vmInfoServiceTracker.close(); //context.removeServiceListener(vmInfoServiceTracker);
         contextActionTracker.close();
         cmdReg.unregisterCommands();
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/HostCpuPanel.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,297 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import java.awt.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.storage.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/swing/src/main/java/com/redhat/thermostat/client/swing/views/HostInformationPanel.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/HostInformationPanel.java	Wed Nov 28 12:28:04 2012 +0100
@@ -45,6 +45,7 @@
 
 import com.redhat.thermostat.client.core.views.BasicView;
 import com.redhat.thermostat.client.core.views.HostInformationView;
+import com.redhat.thermostat.client.core.views.UIComponent;
 import com.redhat.thermostat.client.swing.SwingComponent;
 
 public class HostInformationPanel extends HostInformationView implements SwingComponent {
@@ -63,7 +64,7 @@
     }
 
     @Override
-    public void addChildView(final String title, final BasicView view) {
+    public void addChildView(final String title, final UIComponent view) {
         if (view instanceof SwingComponent) {
             final SwingComponent component = (SwingComponent)view;
             SwingUtilities.invokeLater(new Runnable() {
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/HostMemoryPanel.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,354 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import java.awt.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.utils.DisplayableValues;
-import com.redhat.thermostat.common.utils.DisplayableValues.Scale;
-import com.redhat.thermostat.storage.model.DiscreteTimeData;
-
-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/swing/src/main/java/com/redhat/thermostat/client/swing/views/HostOverviewPanel.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,309 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-
-import javax.swing.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);
-    }
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingHostCpuViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import com.redhat.thermostat.client.core.views.HostCpuView;
-import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
-
-public class SwingHostCpuViewProvider implements HostCpuViewProvider {
-
-    @Override
-    public HostCpuView createView() {
-        return new HostCpuPanel();
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingHostMemoryViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import com.redhat.thermostat.client.core.views.HostMemoryView;
-import com.redhat.thermostat.client.core.views.HostMemoryViewProvider;
-
-public class SwingHostMemoryViewProvider implements HostMemoryViewProvider {
-
-    @Override
-    public HostMemoryView createView() {
-        return new HostMemoryPanel();
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingHostOverviewViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import com.redhat.thermostat.client.core.views.HostOverviewView;
-import com.redhat.thermostat.client.core.views.HostOverviewViewProvider;
-
-public class SwingHostOverviewViewProvider implements HostOverviewViewProvider {
-
-    @Override
-    public HostOverviewView createView() {
-        return new HostOverviewPanel();
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingVmCpuViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import com.redhat.thermostat.client.core.views.VmCpuView;
-import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
-
-public class SwingVmCpuViewProvider implements VmCpuViewProvider {
-
-    @Override
-    public VmCpuView createView() {
-        return new VmCpuPanel();
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingVmGcViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import com.redhat.thermostat.client.core.views.VmGcView;
-import com.redhat.thermostat.client.core.views.VmGcViewProvider;
-
-public class SwingVmGcViewProvider implements VmGcViewProvider {
-
-    @Override
-    public VmGcView createView() {
-        return new VmGcPanel();
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/SwingVmOverviewViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import com.redhat.thermostat.client.core.views.VmOverviewView;
-import com.redhat.thermostat.client.core.views.VmOverviewViewProvider;
-
-public class SwingVmOverviewViewProvider implements VmOverviewViewProvider {
-
-    @Override
-    public VmOverviewView createView() {
-        return new VmOverviewPanel();
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/VmCpuPanel.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,151 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import java.awt.Component;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.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.storage.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();
-            }
-        });
-    }
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/VmGcPanel.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,250 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import 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.storage.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();
-            }
-        });
-    }
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/views/VmOverviewPanel.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.views;
-
-import java.awt.Component;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.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);
-    }
-}
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivatorTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/osgi/ThermostatActivatorTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -43,28 +43,16 @@
 
 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 {
@@ -80,16 +68,10 @@
         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());
+        assertEquals(6, ctx.getAllServices().size());
     }
 }
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/views/HostInformationPanelTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/views/HostInformationPanelTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -52,6 +52,7 @@
 import org.junit.Test;
 
 import com.redhat.thermostat.client.core.views.BasicView;
+import com.redhat.thermostat.client.core.views.UIComponent;
 import com.redhat.thermostat.client.swing.TabbedPaneMatcher;
 import com.redhat.thermostat.client.swing.views.HostInformationPanel;
 
@@ -106,7 +107,7 @@
 
     @Test
     public void testAddTwice() throws InvocationTargetException, InterruptedException {
-        BasicView mock1 = createHostInfoPanel();
+        UIComponent mock1 = createHostInfoPanel();
 
         panel.addChildView("foo1", mock1);
 
@@ -114,7 +115,7 @@
         // in order to select the right panel.
         window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("foo1");
 
-        BasicView mock2 = createHostInfoPanel();
+        UIComponent mock2 = createHostInfoPanel();
         panel.addChildView("foo2", mock2);
 
         window.panel("panel").tabbedPane(new TabbedPaneMatcher(JTabbedPane.class)).requireTabTitles("foo1", "foo2");
@@ -122,8 +123,8 @@
 
     @Test
     public void testAddRemove() throws InvocationTargetException, InterruptedException {
-        BasicView test1 = createHostInfoPanel();
-        BasicView test2 = createHostInfoPanel();
+        UIComponent test1 = createHostInfoPanel();
+        UIComponent test2 = createHostInfoPanel();
 
         panel.addChildView("test1", test1);
         panel.addChildView("test2", test2);
--- a/distribution/config/commands/gui.properties	Wed Nov 28 12:24:00 2012 +0100
+++ b/distribution/config/commands/gui.properties	Wed Nov 28 12:28:04 2012 +0100
@@ -5,7 +5,20 @@
           thermostat-common-command-@project.version@.jar, \
           thermostat-client-core-@project.version@.jar, \
           thermostat-client-swing-@project.version@.jar, \
+          thermostat-swing-components-@project.version@.jar, \
           thermostat-client-command-@project.version@.jar, \
+          thermostat-host-overview-client-core-@project.version@.jar, \
+          thermostat-host-overview-client-swing-@project.version@.jar, \
+          thermostat-host-cpu-client-core-@project.version@.jar, \
+          thermostat-host-cpu-client-swing-@project.version@.jar, \
+          thermostat-host-memory-client-core-@project.version@.jar, \
+          thermostat-host-memory-client-swing-@project.version@.jar, \
+          thermostat-vm-overview-client-core-@project.version@.jar, \
+          thermostat-vm-overview-client-swing-@project.version@.jar, \
+          thermostat-vm-cpu-client-core-@project.version@.jar, \
+          thermostat-vm-cpu-client-swing-@project.version@.jar, \
+          thermostat-vm-gc-client-core-@project.version@.jar, \
+          thermostat-vm-gc-client-swing-@project.version@.jar, \
           thermostat-client-heapdumper-core-@project.version@.jar, \
           thermostat-client-heapdumper-swing-@project.version@.jar, \
           thermostat-killvm-client-swing-@project.version@.jar, \
--- a/distribution/pom.xml	Wed Nov 28 12:24:00 2012 +0100
+++ b/distribution/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -303,11 +303,76 @@
     </dependency>
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-swing-components</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
       <artifactId>thermostat-client-command</artifactId>
       <version>${project.version}</version>
     </dependency>
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-overview-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-overview-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-cpu-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-cpu-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-memory-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-memory-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-overview-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-overview-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-cpu-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-cpu-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-gc-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-gc-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
       <artifactId>thermostat-client-vmclassstat-swing</artifactId>
       <version>${project.version}</version>
     </dependency>
--- a/eclipse/com.redhat.thermostat.client.feature/feature.xml	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.client.feature/feature.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -126,4 +126,39 @@
          version="0.0.0"
          unpack="false"/>
 
+   <plugin
+         id="com.redhat.thermostat.host.overview.client.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="com.redhat.thermostat.host.cpu.client.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="com.redhat.thermostat.host.memory.client.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="com.redhat.thermostat.vm.cpu.client.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="com.redhat.thermostat.vm.gc.client.core"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
 </feature>
--- a/eclipse/com.redhat.thermostat.client.feature/pom.xml	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.client.feature/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -21,6 +21,31 @@
     </dependency>
     <dependency>
       <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-overview-client-core</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-cpu-client-core</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-memory-client-core</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-cpu-client-core</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-gc-client-core</artifactId>
+      <version>0.5.0-SNAPSHOT</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
       <artifactId>thermostat-client-vmclassstat-core</artifactId>
       <version>0.5.0-SNAPSHOT</version>
     </dependency>
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/META-INF/MANIFEST.MF	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/META-INF/MANIFEST.MF	Wed Nov 28 12:28:04 2012 +0100
@@ -15,11 +15,19 @@
  com.redhat.thermostat.common.dao,
  com.redhat.thermostat.common.heap,
  com.redhat.thermostat.common.locale,
- com.redhat.thermostat.storage.model,
- com.redhat.thermostat.storage.core,
  com.redhat.thermostat.common.utils,
  com.redhat.thermostat.eclipse,
  com.redhat.thermostat.eclipse.views,
+ com.redhat.thermostat.host.cpu.client.core,
+ com.redhat.thermostat.host.cpu.client.locale,
+ com.redhat.thermostat.host.memory.client.core,
+ com.redhat.thermostat.host.memory.client.locale,
+ com.redhat.thermostat.storage.core,
+ com.redhat.thermostat.storage.model,
+ com.redhat.thermostat.vm.cpu.client.core,
+ com.redhat.thermostat.vm.cpu.client.locale,
+ com.redhat.thermostat.vm.gc.client.core,
+ com.redhat.thermostat.vm.gc.client.locale,
  org.jfree.chart,
  org.jfree.chart.axis,
  org.jfree.chart.event,
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/Activator.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/Activator.java	Wed Nov 28 12:28:04 2012 +0100
@@ -39,11 +39,11 @@
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
 
-import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
-import com.redhat.thermostat.client.core.views.HostMemoryViewProvider;
-import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
-import com.redhat.thermostat.client.core.views.VmGcViewProvider;
 import com.redhat.thermostat.common.utils.OSGIUtils;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuViewProvider;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryViewProvider;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuViewProvider;
+import com.redhat.thermostat.vm.gc.client.core.VmGcViewProvider;
 
 public class Activator extends AbstractUIPlugin {
 
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/HostCpuViewPart.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/HostCpuViewPart.java	Wed Nov 28 12:28:04 2012 +0100
@@ -38,14 +38,14 @@
 
 import org.eclipse.swt.widgets.Composite;
 
-import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
-import com.redhat.thermostat.client.ui.HostCpuController;
 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.utils.OSGIUtils;
 import com.redhat.thermostat.eclipse.SWTComponent;
 import com.redhat.thermostat.eclipse.views.HostRefViewPart;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuController;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuViewProvider;
 
 public class HostCpuViewPart extends HostRefViewPart {
 
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/HostMemoryViewPart.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/HostMemoryViewPart.java	Wed Nov 28 12:28:04 2012 +0100
@@ -38,14 +38,14 @@
 
 import org.eclipse.swt.widgets.Composite;
 
-import com.redhat.thermostat.client.core.views.HostMemoryViewProvider;
-import com.redhat.thermostat.client.ui.HostMemoryController;
 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.utils.OSGIUtils;
 import com.redhat.thermostat.eclipse.SWTComponent;
 import com.redhat.thermostat.eclipse.views.HostRefViewPart;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryController;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryViewProvider;
 
 public class HostMemoryViewPart extends HostRefViewPart {
 
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostCpuView.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostCpuView.java	Wed Nov 28 12:28:04 2012 +0100
@@ -62,8 +62,8 @@
 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.host.cpu.client.core.HostCpuView;
+import com.redhat.thermostat.host.cpu.client.locale.LocaleResources;
 import com.redhat.thermostat.client.ui.ChartColors;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.eclipse.SWTComponent;
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostCpuViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostCpuViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -36,9 +36,9 @@
 
 package com.redhat.thermostat.eclipse.chart.common;
 
-import com.redhat.thermostat.client.core.views.HostCpuView;
-import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
 import com.redhat.thermostat.eclipse.SWTViewProvider;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuView;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuViewProvider;
 
 public class SWTHostCpuViewProvider extends SWTViewProvider implements
         HostCpuViewProvider {
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostMemoryView.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostMemoryView.java	Wed Nov 28 12:28:04 2012 +0100
@@ -67,8 +67,8 @@
 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.host.memory.client.core.HostMemoryView;
+import com.redhat.thermostat.host.memory.client.locale.LocaleResources;
 import com.redhat.thermostat.client.ui.ChartColors;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.common.utils.DisplayableValues;
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostMemoryViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTHostMemoryViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -36,9 +36,9 @@
 
 package com.redhat.thermostat.eclipse.chart.common;
 
-import com.redhat.thermostat.client.core.views.HostMemoryView;
-import com.redhat.thermostat.client.core.views.HostMemoryViewProvider;
 import com.redhat.thermostat.eclipse.SWTViewProvider;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryView;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryViewProvider;
 
 public class SWTHostMemoryViewProvider extends SWTViewProvider implements
         HostMemoryViewProvider {
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmCpuView.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmCpuView.java	Wed Nov 28 12:28:04 2012 +0100
@@ -51,11 +51,11 @@
 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.common.locale.Translate;
 import com.redhat.thermostat.eclipse.SWTComponent;
 import com.redhat.thermostat.storage.model.DiscreteTimeData;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuView;
+import com.redhat.thermostat.vm.cpu.client.locale.LocaleResources;
 
 public class SWTVmCpuView extends VmCpuView implements SWTComponent {
     
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmCpuViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmCpuViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -36,9 +36,9 @@
 
 package com.redhat.thermostat.eclipse.chart.common;
 
-import com.redhat.thermostat.client.core.views.VmCpuView;
-import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
 import com.redhat.thermostat.eclipse.SWTViewProvider;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuView;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuViewProvider;
 
 public class SWTVmCpuViewProvider extends SWTViewProvider implements
         VmCpuViewProvider {
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmGcView.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmGcView.java	Wed Nov 28 12:28:04 2012 +0100
@@ -63,12 +63,12 @@
 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.ui.SampledDataset;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.eclipse.SWTComponent;
 import com.redhat.thermostat.storage.model.IntervalTimeData;
+import com.redhat.thermostat.vm.gc.client.core.VmGcView;
+import com.redhat.thermostat.vm.gc.client.locale.LocaleResources;
 
 public class SWTVmGcView extends VmGcView implements SWTComponent {
     
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmGcViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/SWTVmGcViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -36,9 +36,9 @@
 
 package com.redhat.thermostat.eclipse.chart.common;
 
-import com.redhat.thermostat.client.core.views.VmGcView;
-import com.redhat.thermostat.client.core.views.VmGcViewProvider;
 import com.redhat.thermostat.eclipse.SWTViewProvider;
+import com.redhat.thermostat.vm.gc.client.core.VmGcView;
+import com.redhat.thermostat.vm.gc.client.core.VmGcViewProvider;
 
 public class SWTVmGcViewProvider extends SWTViewProvider implements
         VmGcViewProvider {
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/VmCpuViewPart.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/VmCpuViewPart.java	Wed Nov 28 12:28:04 2012 +0100
@@ -38,13 +38,13 @@
 
 import org.eclipse.swt.widgets.Composite;
 
-import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
-import com.redhat.thermostat.client.ui.VmCpuController;
 import com.redhat.thermostat.common.dao.VmCpuStatDAO;
 import com.redhat.thermostat.common.dao.VmRef;
 import com.redhat.thermostat.common.utils.OSGIUtils;
 import com.redhat.thermostat.eclipse.SWTComponent;
 import com.redhat.thermostat.eclipse.views.VmRefViewPart;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuController;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuViewProvider;
 
 public class VmCpuViewPart extends VmRefViewPart {
 
--- a/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/VmGcViewPart.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.chart.common/src/com/redhat/thermostat/eclipse/chart/common/VmGcViewPart.java	Wed Nov 28 12:28:04 2012 +0100
@@ -38,14 +38,14 @@
 
 import org.eclipse.swt.widgets.Composite;
 
-import com.redhat.thermostat.client.core.views.VmGcViewProvider;
-import com.redhat.thermostat.client.ui.VmGcController;
 import com.redhat.thermostat.common.dao.VmGcStatDAO;
 import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
 import com.redhat.thermostat.common.dao.VmRef;
 import com.redhat.thermostat.common.utils.OSGIUtils;
 import com.redhat.thermostat.eclipse.SWTComponent;
 import com.redhat.thermostat.eclipse.views.VmRefViewPart;
+import com.redhat.thermostat.vm.gc.client.core.VmGcController;
+import com.redhat.thermostat.vm.gc.client.core.VmGcViewProvider;
 
 public class VmGcViewPart extends VmRefViewPart {
 
--- a/eclipse/com.redhat.thermostat.eclipse.test.ui/META-INF/MANIFEST.MF	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.test.ui/META-INF/MANIFEST.MF	Wed Nov 28 12:28:04 2012 +0100
@@ -15,11 +15,16 @@
  com.redhat.thermostat.client.vmclassstat.core,
  com.redhat.thermostat.common,
  com.redhat.thermostat.common.appctx,
- com.redhat.thermostat.storage.model,
  com.redhat.thermostat.eclipse,
  com.redhat.thermostat.eclipse.chart.common,
  com.redhat.thermostat.eclipse.chart.vmclassstat,
  com.redhat.thermostat.eclipse.internal.views,
+ com.redhat.thermostat.host.cpu.client.core,
+ com.redhat.thermostat.host.memory.client.core,
+ com.redhat.thermostat.host.overview.client.core,
+ com.redhat.thermostat.storage.model,
+ com.redhat.thermostat.vm.cpu.client.core,
+ com.redhat.thermostat.vm.gc.client.core,
  org.apache.log4j;version="1.2.13",
  org.eclipse.swtbot.eclipse.finder,
  org.eclipse.swtbot.eclipse.finder.matchers,
--- a/eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTHostMemoryViewTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.test.ui/src/com/redhat/thermostat/eclipse/test/ui/SWTHostMemoryViewTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -69,11 +69,11 @@
 
 import com.redhat.thermostat.client.core.views.BasicView;
 import com.redhat.thermostat.client.core.views.BasicView.Action;
-import com.redhat.thermostat.client.core.views.HostMemoryView.GraphVisibilityChangeListener;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.eclipse.ThermostatConstants;
 import com.redhat.thermostat.eclipse.chart.common.SWTHostMemoryView;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryView.GraphVisibilityChangeListener;
 import com.redhat.thermostat.storage.model.DiscreteTimeData;
 
 @RunWith(SWTBotJunit4ClassRunner.class)
--- a/eclipse/com.redhat.thermostat.eclipse.test/META-INF/MANIFEST.MF	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.test/META-INF/MANIFEST.MF	Wed Nov 28 12:28:04 2012 +0100
@@ -25,6 +25,11 @@
  com.redhat.thermostat.eclipse.internal.model,
  com.redhat.thermostat.eclipse.internal.views,
  com.redhat.thermostat.eclipse.views,
+ com.redhat.thermostat.host.cpu.client.core,
+ com.redhat.thermostat.host.memory.client.core,
+ com.redhat.thermostat.host.overview.client.core,
+ com.redhat.thermostat.vm.cpu.client.core,
+ com.redhat.thermostat.vm.gc.client.core,
  org.mockito,
  org.mockito.stubbing
 Export-Package: com.redhat.thermostat.eclipse.test.model,
--- a/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/HostCpuViewPartTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/HostCpuViewPartTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -50,9 +50,7 @@
 import org.junit.Test;
 import org.mockito.InOrder;
 
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.HostCpuViewProvider;
-import com.redhat.thermostat.client.ui.HostCpuController;
+import com.redhat.thermostat.client.core.views.UIComponent;
 import com.redhat.thermostat.common.dao.CpuStatDAO;
 import com.redhat.thermostat.common.dao.HostInfoDAO;
 import com.redhat.thermostat.common.dao.HostRef;
@@ -62,6 +60,8 @@
 import com.redhat.thermostat.eclipse.chart.common.SWTHostCpuView;
 import com.redhat.thermostat.eclipse.chart.common.SWTHostCpuViewProvider;
 import com.redhat.thermostat.eclipse.internal.views.RefViewPart;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuController;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuViewProvider;
 
 public class HostCpuViewPartTest extends AbstractRefViewPartTest<HostRef> {
     
@@ -150,7 +150,7 @@
         doReturn(controller).when(((HostCpuViewPart) view)).createController(
                 same(hostInfoDao), same(cpuStatDao), any(HostRef.class),
                 same(viewProvider));
-        when(controller.getView()).thenReturn((BasicView) thermoView);
+        when(controller.getView()).thenReturn((UIComponent) thermoView);
     }
 
     @Override
--- a/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/HostMemoryViewPartTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/HostMemoryViewPartTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -48,9 +48,7 @@
 import org.junit.Test;
 import org.mockito.InOrder;
 
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.HostMemoryViewProvider;
-import com.redhat.thermostat.client.ui.HostMemoryController;
+import com.redhat.thermostat.client.core.views.UIComponent;
 import com.redhat.thermostat.common.dao.HostInfoDAO;
 import com.redhat.thermostat.common.dao.HostRef;
 import com.redhat.thermostat.common.dao.MemoryStatDAO;
@@ -59,6 +57,8 @@
 import com.redhat.thermostat.eclipse.chart.common.SWTHostMemoryView;
 import com.redhat.thermostat.eclipse.chart.common.SWTHostMemoryViewProvider;
 import com.redhat.thermostat.eclipse.internal.views.RefViewPart;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryController;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryViewProvider;
 
 public class HostMemoryViewPartTest extends AbstractRefViewPartTest<HostRef> {
 
@@ -98,7 +98,7 @@
         doReturn(controller).when(((HostMemoryViewPart) view))
                 .createController(same(hostInfoDao), same(memStatDao),
                         any(HostRef.class), same(viewProvider));
-        when(controller.getView()).thenReturn((BasicView) thermoView);
+        when(controller.getView()).thenReturn((UIComponent) thermoView);
     }
 
     @Override
--- a/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/HostOverviewViewPartTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/HostOverviewViewPartTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -48,9 +48,7 @@
 import org.junit.Test;
 import org.mockito.InOrder;
 
-import com.redhat.thermostat.client.core.views.BasicView;
-import com.redhat.thermostat.client.core.views.HostOverviewViewProvider;
-import com.redhat.thermostat.client.ui.HostOverviewController;
+import com.redhat.thermostat.client.core.views.UIComponent;
 import com.redhat.thermostat.common.dao.HostInfoDAO;
 import com.redhat.thermostat.common.dao.HostRef;
 import com.redhat.thermostat.common.dao.NetworkInterfaceInfoDAO;
@@ -59,6 +57,8 @@
 import com.redhat.thermostat.eclipse.internal.views.RefViewPart;
 import com.redhat.thermostat.eclipse.internal.views.SWTHostOverviewView;
 import com.redhat.thermostat.eclipse.internal.views.SWTHostOverviewViewProvider;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewController;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewViewProvider;
 
 public class HostOverviewViewPartTest extends AbstractRefViewPartTest<HostRef> {
 
@@ -99,7 +99,7 @@
         doReturn(controller).when(((HostOverviewViewPart) view))
                 .createController(any(HostRef.class), same(hostInfoDao),
                         same(netIfaceDao), same(viewProvider));
-        when(controller.getView()).thenReturn((BasicView) thermoView);
+        when(controller.getView()).thenReturn((UIComponent) thermoView);
     }
 
     @Override
--- a/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/VmCpuViewPartTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/VmCpuViewPartTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -50,8 +50,6 @@
 import org.junit.Test;
 import org.mockito.InOrder;
 
-import com.redhat.thermostat.client.core.views.VmCpuViewProvider;
-import com.redhat.thermostat.client.ui.VmCpuController;
 import com.redhat.thermostat.common.dao.HostRef;
 import com.redhat.thermostat.common.dao.VmCpuStatDAO;
 import com.redhat.thermostat.common.dao.VmRef;
@@ -60,6 +58,8 @@
 import com.redhat.thermostat.eclipse.chart.common.SWTVmCpuViewProvider;
 import com.redhat.thermostat.eclipse.chart.common.VmCpuViewPart;
 import com.redhat.thermostat.eclipse.internal.views.RefViewPart;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuController;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuViewProvider;
 
 public class VmCpuViewPartTest extends AbstractRefViewPartTest<VmRef> {
 
--- a/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/VmGcViewPartTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse.test/src/com/redhat/thermostat/eclipse/test/views/VmGcViewPartTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -48,8 +48,6 @@
 import org.junit.Test;
 import org.mockito.InOrder;
 
-import com.redhat.thermostat.client.core.views.VmGcViewProvider;
-import com.redhat.thermostat.client.ui.VmGcController;
 import com.redhat.thermostat.common.dao.HostRef;
 import com.redhat.thermostat.common.dao.VmGcStatDAO;
 import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
@@ -59,6 +57,8 @@
 import com.redhat.thermostat.eclipse.chart.common.SWTVmGcViewProvider;
 import com.redhat.thermostat.eclipse.chart.common.VmGcViewPart;
 import com.redhat.thermostat.eclipse.internal.views.RefViewPart;
+import com.redhat.thermostat.vm.gc.client.core.VmGcController;
+import com.redhat.thermostat.vm.gc.client.core.VmGcViewProvider;
 
 public class VmGcViewPartTest extends AbstractRefViewPartTest<VmRef> {
 
--- a/eclipse/com.redhat.thermostat.eclipse/META-INF/MANIFEST.MF	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse/META-INF/MANIFEST.MF	Wed Nov 28 12:28:04 2012 +0100
@@ -15,12 +15,14 @@
  com.redhat.thermostat.client.ui,
  com.redhat.thermostat.common,
  com.redhat.thermostat.common.appctx,
- com.redhat.thermostat.storage.config,
  com.redhat.thermostat.common.dao,
- com.redhat.thermostat.storage.model,
- com.redhat.thermostat.storage.core,
  com.redhat.thermostat.common.locale,
  com.redhat.thermostat.common.utils,
+ com.redhat.thermostat.host.overview.client.core,
+ com.redhat.thermostat.host.overview.client.locale,
+ com.redhat.thermostat.storage.config,
+ com.redhat.thermostat.storage.core,
+ com.redhat.thermostat.storage.model,
  com.redhat.thermostat.web.client,
  com.redhat.thermostat.web.common
 Export-Package: com.redhat.thermostat.eclipse,
--- a/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/Activator.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/Activator.java	Wed Nov 28 12:28:04 2012 +0100
@@ -44,7 +44,6 @@
 import org.eclipse.ui.plugin.AbstractUIPlugin;
 import org.osgi.framework.BundleContext;
 
-import com.redhat.thermostat.client.core.views.HostOverviewViewProvider;
 import com.redhat.thermostat.common.DbService;
 import com.redhat.thermostat.common.ThreadPoolTimerFactory;
 import com.redhat.thermostat.common.TimerFactory;
@@ -52,6 +51,7 @@
 import com.redhat.thermostat.common.utils.OSGIUtils;
 import com.redhat.thermostat.eclipse.LoggerFacility;
 import com.redhat.thermostat.eclipse.internal.views.SWTHostOverviewViewProvider;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewViewProvider;
 import com.redhat.thermostat.storage.core.ConnectionException;
 
 /**
--- a/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/views/HostOverviewViewPart.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/views/HostOverviewViewPart.java	Wed Nov 28 12:28:04 2012 +0100
@@ -38,14 +38,14 @@
 
 import org.eclipse.swt.widgets.Composite;
 
-import com.redhat.thermostat.client.core.views.HostOverviewViewProvider;
-import com.redhat.thermostat.client.ui.HostOverviewController;
 import com.redhat.thermostat.common.dao.HostInfoDAO;
 import com.redhat.thermostat.common.dao.HostRef;
 import com.redhat.thermostat.common.dao.NetworkInterfaceInfoDAO;
 import com.redhat.thermostat.common.utils.OSGIUtils;
 import com.redhat.thermostat.eclipse.SWTComponent;
 import com.redhat.thermostat.eclipse.views.HostRefViewPart;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewController;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewViewProvider;
 
 public class HostOverviewViewPart extends HostRefViewPart {
 
--- a/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/views/SWTHostOverviewView.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/views/SWTHostOverviewView.java	Wed Nov 28 12:28:04 2012 +0100
@@ -51,8 +51,8 @@
 import org.eclipse.swt.widgets.TableColumn;
 import org.eclipse.ui.PlatformUI;
 
-import com.redhat.thermostat.client.core.views.HostOverviewView;
-import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewView;
+import com.redhat.thermostat.host.overview.client.locale.LocaleResources;
 import com.redhat.thermostat.common.locale.Translate;
 import com.redhat.thermostat.eclipse.SWTComponent;
 import com.redhat.thermostat.eclipse.ThermostatConstants;
--- a/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/views/SWTHostOverviewViewProvider.java	Wed Nov 28 12:24:00 2012 +0100
+++ b/eclipse/com.redhat.thermostat.eclipse/src/com/redhat/thermostat/eclipse/internal/views/SWTHostOverviewViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -36,9 +36,9 @@
 
 package com.redhat.thermostat.eclipse.internal.views;
 
-import com.redhat.thermostat.client.core.views.HostOverviewView;
-import com.redhat.thermostat.client.core.views.HostOverviewViewProvider;
 import com.redhat.thermostat.eclipse.SWTViewProvider;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewView;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewViewProvider;
 
 public class SWTHostOverviewViewProvider extends SWTViewProvider implements HostOverviewViewProvider {
 
--- a/gc/pom.xml	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-<?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</artifactId>
-    <version>0.5.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>thermostat-gc</artifactId>
-  <packaging>pom</packaging>
-
-  <name>Thermostat GC Analysis And Remote GC Plugin</name>
-
-  <dependencies>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-  </dependencies>
-
-  <modules>
-    <module>remote-collector-command</module>
-    <module>remote-collector-client-common</module>
-    <module>remote-collector-client-swing</module>
-    <module>remote-collector-common</module>
-  </modules>
-</project>
-
--- a/gc/remote-collector-client-common/pom.xml	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,133 +0,0 @@
-<?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-gc</artifactId>
-    <version>0.5.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>thermostat-gc-remote-collector-client-common</artifactId>
-  <packaging>bundle</packaging>
-
-  <name>Thermostat GC Plugin Common Client API</name>
-
-  <dependencies>
-    <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>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-common-core</artifactId>
-      <version>${project.version}</version>
-    </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>
-    
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-client-command</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-        
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-agent-command</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-        
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-client-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-gc-remote-collector-common</artifactId>
-      <version>${project.version}</version>
-    </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.gc.remote.client.common</Bundle-SymbolicName>
-            <Bundle-Activator>com.redhat.thermostat.gc.remote.client.common.osgi.GCCommandActivator</Bundle-Activator>
-            <Export-Package>
-                com.redhat.thermostat.gc.remote.client.common,
-                com.redhat.thermostat.gc.remote.common,
-            </Export-Package>
-            <Private-Package>
-                com.redhat.thermostat.gc.remote.client.common.osgi,
-            </Private-Package>            
-            <!-- Do not autogenerate uses clauses in Manifests -->
-            <_nouses>true</_nouses>
-          </instructions>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
-</project>
--- a/gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/IconResources.java	Wed Nov 28 12:24:00 2012 +0100
+++ /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.gc.remote.client.common;
-
-import com.redhat.thermostat.client.ui.IconDescriptor;
-
-public class IconResources {
-
-    private static IconDescriptor gcIconSmall;
-    
-    public synchronized static IconDescriptor getGCIconSmall() {
-        if (gcIconSmall == null) {
-            gcIconSmall = IconDescriptor.loadIcon("com/redhat/thermostat/gc/remote/client/common/gcSmall.png");
-        }
-        return gcIconSmall;
-    }
-}
--- a/gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/LocaleResources.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.gc.remote.client.common;
-
-import com.redhat.thermostat.common.locale.Translate;
-
-public enum LocaleResources {
-
-    PERFORM_GC;
-    
-    static final String RESOURCE_BUNDLE = "com.redhat.thermostat.gc.remote.client.common.strings";
-
-    public static Translate<LocaleResources> createLocalizer() {
-        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
-    }
-}
--- a/gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/RequestGCAction.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +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.gc.remote.client.common;
-
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.ActionNotifier;
-import com.redhat.thermostat.gc.remote.common.command.GCCommand;
-
-public class RequestGCAction {
-    
-    private final ActionNotifier<GCCommand> notifier;
-    
-    public RequestGCAction() {
-        notifier = new ActionNotifier<>(this);
-    }
-    
-    public void addActionListener(ActionListener<GCCommand> listener) {
-        this.notifier.addActionListener(listener);
-    }
-    
-    public void removeActionListener(ActionListener<GCCommand> listener) {
-        this.notifier.removeActionListener(listener);
-    }
-    
-    public void requestGC() {
-        notifier.fireAction(GCCommand.REQUEST_GC);
-    }
-}
--- a/gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/osgi/GCCommandActivator.java	Wed Nov 28 12:24:00 2012 +0100
+++ /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.gc.remote.client.common.osgi;
-
-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.command.RequestQueue;
-import com.redhat.thermostat.gc.remote.common.GCRequest;
-
-@SuppressWarnings({ "rawtypes", "unchecked" })
-public class GCCommandActivator implements BundleActivator {
-
-    private ServiceTracker tracker;
-
-    @Override
-    public void start(final BundleContext context) throws Exception {
-        tracker = new ServiceTracker(context, RequestQueue.class, null) {
-            @Override
-            public Object addingService(ServiceReference reference) {
-                
-                RequestQueue requestqueue = (RequestQueue) context.getService(reference);
-                
-                GCRequest gcRequest = new GCRequest(requestqueue); 
-                context.registerService(GCRequest.class, gcRequest, null);
-                return super.addingService(reference);
-            }
-            
-            @Override
-            public void removedService(ServiceReference reference, Object service) {
-                
-                context.ungetService(reference);
-                super.removedService(reference, service);
-            }
-        };
-        
-        tracker.open();
-    }
-    
-    @Override
-    public void stop(BundleContext context) throws Exception {
-        tracker.close();
-    }
-}
--- a/gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/common/GCRequest.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +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.gc.remote.common;
-
-import java.net.InetSocketAddress;
-
-import com.redhat.thermostat.client.command.RequestQueue;
-import com.redhat.thermostat.common.command.Request;
-import com.redhat.thermostat.common.command.Request.RequestType;
-import com.redhat.thermostat.common.dao.AgentInfoDAO;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.gc.remote.common.command.GCCommand;
-
-public class GCRequest {
-    
-    private RequestQueue queue;
-    public GCRequest(RequestQueue queue) {
-        this.queue = queue;
-    }
-        
-    public void sendGCRequestToAgent(VmRef vm, AgentInfoDAO agentDAO) {
-                
-        HostRef targetHostRef = vm.getAgent();
-
-        String address = agentDAO.getAgentInformation(targetHostRef).getConfigListenAddress();
-        String [] host = address.split(":");
-        
-        InetSocketAddress target = new InetSocketAddress(host[0], Integer.parseInt(host[1]));
-        Request gcRequest = createRequest(target);
-
-        gcRequest.setReceiver(GCCommand.RECEIVER);
-
-        gcRequest.setParameter(GCCommand.class.getName(), GCCommand.REQUEST_GC.name());
-        gcRequest.setParameter(GCCommand.VM_ID, vm.getIdString());
-        
-        queue.putRequest(gcRequest);
-    }
-    
-    // for testing
-    Request createRequest(InetSocketAddress target) {
-        return new Request(RequestType.NO_RESPONSE_EXPECTED, target);
-    }
-}
--- a/gc/remote-collector-client-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/strings.properties	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-PERFORM_GC = Perform GC
\ No newline at end of file
--- a/gc/remote-collector-client-common/src/test/java/com/redhat/thermostat/gc/remote/common/GCRequestTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ /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.gc.remote.common;
-
-import static org.junit.Assert.*;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-import static org.mockito.Mockito.verify;
-
-import java.net.InetSocketAddress;
-
-import org.junit.Before;
-import org.junit.Test;
-
-import com.redhat.thermostat.client.command.RequestQueue;
-import com.redhat.thermostat.common.command.Request;
-import com.redhat.thermostat.common.dao.AgentInfoDAO;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.gc.remote.common.command.GCCommand;
-import com.redhat.thermostat.storage.model.AgentInformation;
-
-public class GCRequestTest {
-
-    private AgentInfoDAO agentDAO;
-    private RequestQueue queue;
-    private VmRef vm;
-
-    private GCRequest gcRequest;
-    private Request request;
-    
-    @Before
-    public void setUp() {
-        agentDAO = mock(AgentInfoDAO.class);
-        vm = mock(VmRef.class);
-
-        request = mock(Request.class);
-        
-        HostRef ref = mock(HostRef.class);        
-        when(vm.getAgent()).thenReturn(ref);
-        when(vm.getIdString()).thenReturn("123456");
-
-        AgentInformation info = mock(AgentInformation.class);
-        when(info.getConfigListenAddress()).thenReturn("0.0.42.42:42");
-        
-        when(agentDAO.getAgentInformation(ref)).thenReturn(info);
-        
-        queue = mock(RequestQueue.class);
-    }
-    
-    @Test
-    public void testSendGCRequestToAgent() {
-        
-        final boolean [] results = new boolean [3];
-        gcRequest = new GCRequest(queue) {
-            @Override
-            Request createRequest(InetSocketAddress target) {
-                results[0] = true;
-                if (target.getHostString().equals("0.0.42.42")) {
-                    results[1] = true;
-                }
-                if (target.getPort() == 42) {
-                    results[2] = true;
-                }
-                
-                return request;
-            }
-        };
-        
-        gcRequest.sendGCRequestToAgent(vm, agentDAO);
-        verify(vm).getAgent();
-        verify(vm).getIdString();
-        
-        assertTrue(results[0]);
-        assertTrue(results[1]);
-        assertTrue(results[2]);
-        
-        verify(request).setReceiver(GCCommand.RECEIVER);
-        verify(request).setParameter(GCCommand.class.getName(), GCCommand.REQUEST_GC.name());
-        verify(request).setParameter(GCCommand.VM_ID, "123456");
-        
-        verify(queue).putRequest(request);
-    }
-}
--- a/gc/remote-collector-client-swing/pom.xml	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,148 +0,0 @@
-<?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-gc</artifactId>
-    <version>0.5.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>thermostat-gc-remote-collector-client-swing</artifactId>
-  <packaging>bundle</packaging>
-
-  <name>Thermostat GC Plugin Swing Client</name>
-
-  <dependencies>
-    <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>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-common-core</artifactId>
-      <version>${project.version}</version>
-    </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>
-    
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-client-core</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-    
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-client-swing</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-gc-remote-collector-client-common</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>
-    
-  </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.gc.remote.client.swing</Bundle-SymbolicName>
-            <Export-Package>
-              com.redhat.thermostat.gc.remote.client.swing,
-            </Export-Package>
-            <!-- Do not autogenerate uses clauses in Manifests -->
-            <_nouses>true</_nouses>
-          </instructions>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
-</project>
--- a/gc/remote-collector-client-swing/src/main/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButton.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +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.gc.remote.client.swing;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-import javax.swing.ImageIcon;
-
-import com.redhat.thermostat.client.swing.components.ActionButton;
-import com.redhat.thermostat.common.locale.Translate;
-
-import com.redhat.thermostat.gc.remote.client.common.IconResources;
-import com.redhat.thermostat.gc.remote.client.common.LocaleResources;
-import com.redhat.thermostat.gc.remote.client.common.RequestGCAction;
-
-@SuppressWarnings("serial")
-public class ToolbarGCButton extends ActionButton {
-
-    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
-    
-    private RequestGCAction action;
-    public ToolbarGCButton(RequestGCAction action) {
-        this(action, translator.localize(LocaleResources.PERFORM_GC));
-    }
-    
-    private ToolbarGCButton(RequestGCAction action, String text) {
-        super(new ImageIcon(IconResources.getGCIconSmall().getData().array()), text);
-        
-        setToolTipText(text);
-        this.action = action;
-        
-        addActionListener(new ToolbarGCButtonActionlistener());
-    }
-    
-    private class ToolbarGCButtonActionlistener implements ActionListener {
-        @Override
-        public void actionPerformed(ActionEvent e) {            
-            Thread actionThread = new Thread(new Runnable() {
-                @Override
-                public void run() {
-                    action.requestGC();
-                }
-            }, "ToolbarGCButton.ToolbarGCButtonActionlistener.RequestGCAction");
-            actionThread.start();
-        }
-    }
-}
--- a/gc/remote-collector-client-swing/src/test/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButtonTest.java	Wed Nov 28 12:24:00 2012 +0100
+++ /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.gc.remote.client.swing;
-
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-
-import java.awt.Dimension;
-import java.util.prefs.BackingStoreException;
-import java.util.prefs.Preferences;
-
-import javax.swing.JFrame;
-import javax.swing.JPanel;
-
-import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner;
-
-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.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import com.redhat.thermostat.client.swing.components.HeaderPanel;
-import com.redhat.thermostat.gc.remote.client.common.RequestGCAction;
-
-@RunWith(CacioFESTRunner.class)
-public class ToolbarGCButtonTest {
-
-    private JFrame frame;
-    private FrameFixture frameFixture;
-    private ToolbarGCButton gcButton;
-        
-    private RequestGCAction action;
-    
-    @BeforeClass
-    public static void setUpOnce() {
-        FailOnThreadViolationRepaintManager.install();
-    }
-    
-    @Before
-    public void setUp() {
-        
-        final Preferences prefs = mock(Preferences.class);
-        
-        action = mock(RequestGCAction.class);
-        
-        GuiActionRunner.execute(new GuiTask() {
-            @Override
-            protected void executeInEDT() throws Throwable {
-                frame = new JFrame();
-                
-                HeaderPanel header = new HeaderPanel(prefs, "Test Panel");
-                header.setName("headerPanel");
-                
-                JPanel content = new JPanel();
-                content.setName("contentPanel");
-                
-                header.setContent(content);
-               
-                gcButton = new ToolbarGCButton(action);
-                gcButton.setName("gcButton");
-                header.addToolBarButton(gcButton);
-                
-                frame.getContentPane().add(header);
-                
-                frame.setMinimumSize(new Dimension(800, 300));
-            }
-        });
-        frameFixture = new FrameFixture(frame);
-    }
-    
-    @After
-    public void tearDown() throws BackingStoreException {
-        frameFixture.cleanUp();
-        frameFixture = null;
-    }
-    
-    @Test
-    public void testEventDelivered() throws InterruptedException {
-        frameFixture.show();
-        
-        JButtonFixture button = frameFixture.button("gcButton");
-        button.requireVisible();
-        
-        button.click();
-        
-        // timing dependent test...
-        Thread.sleep(250);
-        
-        verify(action).requestGC();
-    }
-}
--- a/gc/remote-collector-command/pom.xml	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,120 +0,0 @@
-<?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-gc</artifactId>
-    <version>0.5.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>thermostat-gc-remote-collector-command</artifactId>
-  <packaging>bundle</packaging>
-
-  <name>Thermostat GC Plugin Command Channel</name>
-
-  <dependencies>
-    <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>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-common-core</artifactId>
-      <version>${project.version}</version>
-    </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>
-    
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-gc-remote-collector-common</artifactId>
-      <version>${project.version}</version>      
-    </dependency>
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-agent-core</artifactId>
-      <version>${project.version}</version>      
-    </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.gc.remote.command</Bundle-SymbolicName>
-            <Bundle-Activator>com.redhat.thermostat.gc.remote.command.osgi.GCCommandReceiverActivator</Bundle-Activator>            
-            <Export-Package>
-              com.redhat.thermostat.gc.remote.command,
-            </Export-Package>
-            <Private-Package>
-                com.redhat.thermostat.gc.remote.command.osgi,
-                com.redhat.thermostat.gc.remote.command.internal,
-            </Private-Package>               
-            <!-- Do not autogenerate uses clauses in Manifests -->
-            <_nouses>true</_nouses>
-          </instructions>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
-</project>
--- a/gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/GCCommandReceiver.java	Wed Nov 28 12:24:00 2012 +0100
+++ /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.gc.remote.command;
-
-import com.redhat.thermostat.agent.command.RequestReceiver;
-import com.redhat.thermostat.common.command.Request;
-import com.redhat.thermostat.common.command.Response;
-import com.redhat.thermostat.common.command.Response.ResponseType;
-import com.redhat.thermostat.gc.remote.command.internal.GC;
-import com.redhat.thermostat.gc.remote.common.command.GCCommand;
-import com.redhat.thermostat.utils.management.MXBeanConnector;
-
-public class GCCommandReceiver implements RequestReceiver {
-
-    @Override
-    public Response receive(Request request) {
-        
-        String command = request.getParameter(GCCommand.class.getName());
-        switch (GCCommand.valueOf(command)) {
-        case REQUEST_GC:
-            String vmId = request.getParameter(GCCommand.VM_ID);
-            MXBeanConnector connector = new MXBeanConnector(vmId);
-            new GC(connector).gc();
-            break;
-        
-        default:
-            break;
-        }
-        return new Response(ResponseType.OK);
-    }
-}
--- a/gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/internal/GC.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +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.gc.remote.command.internal;
-
-import java.lang.management.ManagementFactory;
-import java.lang.management.MemoryMXBean;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.redhat.thermostat.utils.management.MXBeanConnection;
-import com.redhat.thermostat.utils.management.MXBeanConnector;
-
-public class GC {
-
-    private static final Logger logger = Logger.getLogger(GC.class.getSimpleName());
-
-    private MXBeanConnector connector;
-    public GC(MXBeanConnector connector) {
-        this.connector = connector;
-    }
-    
-    public void gc() {
-        boolean closeAfter = false;
-        if (!connector.isAttached()) {
-            closeAfter = true; 
-            try {
-                connector.attach();
-
-            } catch (Exception ex) {
-                logger.log(Level.SEVERE, "can't attach", ex);
-                if (closeAfter) {
-                    closeConnection();
-                }
-            }
-        }
-        
-        try (MXBeanConnection connection = connector.connect()) {
-
-            MemoryMXBean bean = connection.createProxy(ManagementFactory.MEMORY_MXBEAN_NAME, MemoryMXBean.class);
-            bean.gc();
-
-        } catch (Exception ex) {
-            logger.log(Level.SEVERE, "can't get MXBeanConnection connection", ex);
-        }
-        
-        if (closeAfter) {
-            closeConnection();
-        }
-    }
-    
-    private void closeConnection() {
-        try {
-            connector.close();
-        } catch (Exception ex) {
-            logger.log(Level.SEVERE, "can't close connection to vm", ex);
-        }
-    }    
-}
--- a/gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/osgi/GCCommandReceiverActivator.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +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.gc.remote.command.osgi;
-
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-import com.redhat.thermostat.agent.command.ReceiverRegistry;
-import com.redhat.thermostat.gc.remote.command.GCCommandReceiver;
-
-public class GCCommandReceiverActivator implements BundleActivator {
-
-    @Override
-    public void start(BundleContext context) throws Exception {
-        ReceiverRegistry registry = new ReceiverRegistry(context);
-        registry.registerReceiver(new GCCommandReceiver());
-    }
-    
-    @Override
-    public void stop(BundleContext context) throws Exception {
-    }
-}
--- a/gc/remote-collector-common/pom.xml	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-<?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-gc</artifactId>
-    <version>0.5.0-SNAPSHOT</version>
-  </parent>
-
-  <artifactId>thermostat-gc-remote-collector-common</artifactId>
-  <packaging>bundle</packaging>
-
-  <name>Thermostat GC Plugin Common Client API</name>
-
-  <dependencies>
-    <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>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-common-core</artifactId>
-      <version>${project.version}</version>
-    </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>
-    
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-client-command</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-        
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-agent-command</artifactId>
-      <version>${project.version}</version>
-    </dependency>
-        
-    <dependency>
-      <groupId>com.redhat.thermostat</groupId>
-      <artifactId>thermostat-client-core</artifactId>
-      <version>${project.version}</version>
-    </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.gc.remote.common.command</Bundle-SymbolicName>
-            <Export-Package>
-                com.redhat.thermostat.gc.remote.common.command
-            </Export-Package>          
-            <!-- Do not autogenerate uses clauses in Manifests -->
-            <_nouses>true</_nouses>
-          </instructions>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
-
-</project>
--- a/gc/remote-collector-common/src/main/java/com/redhat/thermostat/gc/remote/common/command/GCCommand.java	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,45 +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.gc.remote.common.command;
-
-public enum GCCommand {
-
-    REQUEST_GC;
-    
-    public static final String VM_ID = "VM_ID";
-    public static final String RECEIVER = "com.redhat.thermostat.gc.remote.command.GCCommandReceiver";
-}
Binary file gc/remote-collector-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/gcSmall.png has changed
--- a/gc/remote-collector-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/strings.properties	Wed Nov 28 12:24:00 2012 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-PERFORM_GC = Perform GC
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-cpu/client-core/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-host-cpu</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-host-cpu-client-core</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat Host CPU Core Client plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Private-Package></Private-Package>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.host.cpu.client.core</Bundle-SymbolicName>
+            <Export-Package>
+              com.redhat.thermostat.host.cpu.client.core,
+              com.redhat.thermostat.host.cpu.client.locale
+            </Export-Package>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <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.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>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/core/HostCpuController.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,164 @@
+/*
+ * 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.host.cpu.client.core;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import com.redhat.thermostat.client.core.controllers.HostInformationServiceController;
+import com.redhat.thermostat.client.core.views.BasicView.Action;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.NotImplementedException;
+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.dao.CpuStatDAO;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.host.cpu.client.locale.LocaleResources;
+import com.redhat.thermostat.storage.model.CpuStat;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+import com.redhat.thermostat.storage.model.HostInfo;
+
+public class HostCpuController implements HostInformationServiceController {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private final HostCpuView view;
+    private final Timer backgroundUpdateTimer;
+
+    private final HostInfoDAO hostInfoDAO;
+    private final CpuStatDAO cpuStatDAO;
+    private final HostRef ref;
+
+    private int chartsAdded = 0;
+    private long lastSeenTimeStamp = Long.MIN_VALUE;
+
+    public HostCpuController(HostInfoDAO hostInfoDao, CpuStatDAO cpuStatDAO, HostRef ref, HostCpuViewProvider provider) {
+        this.ref = ref;
+        view = provider.createView();
+        view.clearCpuUsageData();
+        this.hostInfoDAO = hostInfoDao;
+        this.cpuStatDAO = cpuStatDAO;
+
+        backgroundUpdateTimer = ApplicationContext.getInstance().getTimerFactory().createTimer();
+        backgroundUpdateTimer.setAction(new Runnable() {
+
+            @Override
+            public void run() {
+                updateView();
+            }
+
+        });
+        backgroundUpdateTimer.setInitialDelay(0);
+        backgroundUpdateTimer.setDelay(5);
+        backgroundUpdateTimer.setTimeUnit(TimeUnit.SECONDS);
+        backgroundUpdateTimer.setSchedulingType(SchedulingType.FIXED_RATE);
+
+        view.addActionListener(new ActionListener<HostCpuView.Action>() {
+            @Override
+            public void actionPerformed(ActionEvent<Action> actionEvent) {
+                switch (actionEvent.getActionId()) {
+                    case VISIBLE:
+                        start();
+                        break;
+                    case HIDDEN:
+                        stop();
+                        break;
+                    default:
+                        throw new NotImplementedException("unhandled action: " + actionEvent.getActionId());
+                }
+            }
+        });
+
+    }
+
+    // TODO: Consider doing this in a background thread (move to view and use SwingWorker or such).
+    private void updateView() {
+        HostInfo hostInfo = hostInfoDAO.getHostInfo(ref);
+
+        view.setCpuCount(String.valueOf(hostInfo.getCpuCount()));
+        view.setCpuModel(hostInfo.getCpuModel());
+
+        doCpuChartUpdate();
+    }
+
+    private void start() {
+        backgroundUpdateTimer.start();
+    }
+
+    private void stop() {
+        backgroundUpdateTimer.stop();
+    }
+
+    private void doCpuChartUpdate() {
+        List<CpuStat> cpuStats = cpuStatDAO.getLatestCpuStats(ref, lastSeenTimeStamp);
+        List<List<DiscreteTimeData<Double>>> results = new ArrayList<>();
+        for (CpuStat stat : cpuStats) {
+            double[] data = stat.getPerProcessorUsage();
+            for (int i = 0 ; i < data.length; i++) {
+                if (results.size() == i) {
+                    results.add(new ArrayList<DiscreteTimeData<Double>>());
+                }
+                results.get(i).add(new DiscreteTimeData<Double>(stat.getTimeStamp(), data[i]));
+                lastSeenTimeStamp = Math.max(lastSeenTimeStamp, stat.getTimeStamp());
+            }
+        }
+
+        for (int i = 0; i < results.size(); i++) {
+            if (i == chartsAdded) {
+                view.addCpuUsageChart(i, translator.localize(LocaleResources.HOST_CPU_ID, String.valueOf(i)));
+                chartsAdded++;
+            }
+            view.addCpuUsageData(i, results.get(i));
+        }
+    }
+
+    public UIComponent getView() {
+        return view;
+    }
+
+    @Override
+    public String getLocalizedName() {
+        return translator.localize(LocaleResources.HOST_INFO_TAB_CPU);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/core/HostCpuService.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.cpu.client.core;
+
+import com.redhat.thermostat.client.core.HostFilter;
+import com.redhat.thermostat.client.core.HostInformationService;
+import com.redhat.thermostat.client.core.controllers.HostInformationServiceController;
+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.utils.OSGIUtils;
+
+public class HostCpuService implements HostInformationService {
+    
+    private static final HostFilter FILTER = new HostFilter() {
+        @Override
+        public boolean matches(HostRef toMatch) {
+            return true;
+        }
+    };
+    
+    private HostInfoDAO hostInfoDAO;
+    private CpuStatDAO cpuStatDAO;
+    
+    public HostCpuService(HostInfoDAO hostInfoDAO, CpuStatDAO cpuStatDAO) {
+        this.hostInfoDAO = hostInfoDAO;
+        this.cpuStatDAO = cpuStatDAO;
+    }
+
+    @Override
+    public HostFilter getFilter() {
+        return FILTER;
+    }
+
+    @Override
+    public HostInformationServiceController getInformationServiceController(
+            HostRef ref) {
+        HostCpuViewProvider provider = OSGIUtils.getInstance().getService(HostCpuViewProvider.class);
+        return new HostCpuController(hostInfoDAO, cpuStatDAO, ref, provider);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/core/HostCpuView.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,57 @@
+/*
+ * 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.host.cpu.client.core;
+
+import java.util.List;
+
+import com.redhat.thermostat.client.core.views.BasicView;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+
+public abstract class HostCpuView extends BasicView implements UIComponent {
+
+    public abstract void setCpuCount(String count);
+
+    public abstract void setCpuModel(String model);
+
+    public abstract void clearCpuUsageData();
+
+    public abstract void addCpuUsageChart(int cpuIndex, String humanReadableName);
+
+    public abstract void addCpuUsageData(int cpuIndex, List<DiscreteTimeData<Double>> data);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/core/HostCpuViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * 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.host.cpu.client.core;
+
+import com.redhat.thermostat.client.core.views.ViewProvider;
+
+public interface HostCpuViewProvider extends ViewProvider {
+
+    @Override
+    HostCpuView createView();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-cpu/client-core/src/main/java/com/redhat/thermostat/host/cpu/client/locale/LocaleResources.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,59 @@
+/*
+ * 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.host.cpu.client.locale;
+
+import com.redhat.thermostat.common.locale.Translate;
+
+public enum LocaleResources {
+    HOST_INFO_TAB_CPU,
+    
+    HOST_INFO_CPU_COUNT,
+    HOST_INFO_CPU_MODEL,
+    
+    HOST_CPU_SECTION_OVERVIEW,
+    HOST_CPU_ID,
+    HOST_CPU_USAGE_CHART_TIME_LABEL,
+    HOST_CPU_USAGE_CHART_VALUE_LABEL,
+    ;
+
+    static final String RESOURCE_BUNDLE =
+            "com.redhat.thermostat.host.cpu.client.locale.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-cpu/client-core/src/main/resources/com/redhat/thermostat/host/cpu/client/locale/strings.properties	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,9 @@
+HOST_INFO_TAB_CPU = Processor
+
+HOST_INFO_CPU_COUNT = Processor Count
+HOST_INFO_CPU_MODEL = Processor Model
+
+HOST_CPU_SECTION_OVERVIEW = Processor
+HOST_CPU_ID = Cpu {0}
+HOST_CPU_USAGE_CHART_TIME_LABEL = Time
+HOST_CPU_USAGE_CHART_VALUE_LABEL = Cpu Usage (%)
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-cpu/client-core/src/test/java/com/redhat/thermostat/host/cpu/client/core/HostCpuControllerTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,166 @@
+/*
+ * 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.host.cpu.client.core;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNotNull;
+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.Arrays;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.Timer;
+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.CpuStatDAO;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuController;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuView;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuViewProvider;
+import com.redhat.thermostat.storage.model.CpuStat;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+import com.redhat.thermostat.storage.model.HostInfo;
+
+public class HostCpuControllerTest {
+
+    @SuppressWarnings("unused")
+    private HostCpuController controller;
+
+    private HostCpuView view;
+
+    private Timer timer;
+
+    private ActionListener<HostCpuView.Action> viewListener;
+    private Runnable timerAction;
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Before
+    public void setUp() {
+        // Setup timer.
+        ApplicationContextUtil.resetApplicationContext();
+        timer = mock(Timer.class);
+        ArgumentCaptor<Runnable> actionCaptor = ArgumentCaptor.forClass(Runnable.class);
+        doNothing().when(timer).setAction(actionCaptor.capture());
+
+        TimerFactory timerFactory = mock(TimerFactory.class);
+        when(timerFactory.createTimer()).thenReturn(timer);
+        ApplicationContext.getInstance().setTimerFactory(timerFactory);
+
+        // Setup DAOs.
+        HostInfo hostInfo = new HostInfo("fluffhost1", "fluffOs1", "fluffKernel1", "fluffCpu1", 12345, 98765);
+        HostInfoDAO hostInfoDAO = mock(HostInfoDAO.class);
+        when(hostInfoDAO.getHostInfo(any(HostRef.class))).thenReturn(hostInfo);
+
+        CpuStat cpuStat1 = new CpuStat(1l, new double[] {10.0, 20.0, 30.0});
+        CpuStat cpuStat2 = new CpuStat(2l, new double[] {15.0, 25.0, 35.0});
+        CpuStatDAO cpuStatDAO = mock(CpuStatDAO.class);
+        when(cpuStatDAO.getLatestCpuStats(any(HostRef.class), anyLong())).thenReturn(Arrays.asList(cpuStat1, cpuStat2));
+
+        // Set up View
+        view = mock(HostCpuView.class);
+        ArgumentCaptor<ActionListener> viewArgumentCaptor = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(view).addActionListener(viewArgumentCaptor.capture());
+        HostCpuViewProvider viewProvider = mock(HostCpuViewProvider.class);
+        when(viewProvider.createView()).thenReturn(view);
+
+        HostRef host = new HostRef("123", "fluffhost");
+        controller = new HostCpuController(hostInfoDAO, cpuStatDAO, host, viewProvider);
+
+        timerAction = actionCaptor.getValue();
+        viewListener = viewArgumentCaptor.getValue();
+    }
+
+    @After
+    public void tearDown() {
+        timerAction = null;
+        controller = null;
+        view = null;
+        timer = null;
+        ApplicationContextUtil.resetApplicationContext();
+    }
+
+    @Test
+    public void testTimer() {
+        viewListener.actionPerformed(new ActionEvent<>(view, HostCpuView.Action.VISIBLE));
+
+        verify(timer).setAction(isNotNull(Runnable.class));
+        verify(timer).setDelay(5);
+        verify(timer).setTimeUnit(TimeUnit.SECONDS);
+        verify(timer).setInitialDelay(0);
+        verify(timer).setSchedulingType(SchedulingType.FIXED_RATE);
+        verify(timer).start();
+
+        viewListener.actionPerformed(new ActionEvent<>(view, HostCpuView.Action.HIDDEN));
+
+        verify(timer).stop();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void testTimerAction() {
+        timerAction.run();
+        verify(view).setCpuModel("fluffCpu1");
+        verify(view).setCpuCount("12345");
+        @SuppressWarnings("rawtypes")
+        ArgumentCaptor<List> captor = ArgumentCaptor.forClass(List.class);
+        verify(view).addCpuUsageChart(eq(0), anyString());
+        verify(view).addCpuUsageData(eq(0), captor.capture());
+        List<DiscreteTimeData<Double>> cpuLoadData = captor.getValue();
+        assertEquals(1, cpuLoadData.get(0).getTimeInMillis());
+        assertEquals(10.0, cpuLoadData.get(0).getData().doubleValue(), 0.0001);
+        assertEquals(2, cpuLoadData.get(1).getTimeInMillis());
+        assertEquals(15.0, cpuLoadData.get(1).getData().doubleValue(), 0.0001);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-cpu/client-swing/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-host-cpu</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-host-cpu-client-swing</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat Host CPU Swing Client plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Private-Package>com.redhat.thermostat.host.cpu.client.swing</Private-Package>
+            <Bundle-Activator>com.redhat.thermostat.host.cpu.client.swing.Activator</Bundle-Activator>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.host.cpu.client.swing</Bundle-SymbolicName>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <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.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>
+    <dependency>
+      <groupId>org.jfree</groupId>
+      <artifactId>jfreechart</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-swing-components</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-cpu-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-cpu/client-swing/src/main/java/com/redhat/thermostat/host/cpu/client/swing/Activator.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.cpu.client.swing;
+
+import java.util.Map;
+import java.util.Objects;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import com.redhat.thermostat.client.core.HostInformationService;
+import com.redhat.thermostat.common.MultipleServiceTracker;
+import com.redhat.thermostat.common.MultipleServiceTracker.Action;
+import com.redhat.thermostat.common.dao.CpuStatDAO;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuService;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuViewProvider;
+
+public class Activator implements BundleActivator {
+    
+    private MultipleServiceTracker tracker;
+    private ServiceRegistration reg;
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+        HostCpuViewProvider viewProvider = new SwingHostCpuViewProvider();
+        context.registerService(HostCpuViewProvider.class.getName(), viewProvider, null);
+
+        Class<?>[] deps = new Class<?>[] {
+            HostInfoDAO.class,
+            CpuStatDAO.class,
+        };
+
+        tracker = new MultipleServiceTracker(context, deps, new Action() {
+
+            @Override
+            public void dependenciesAvailable(Map<String, Object> services) {
+                HostInfoDAO hostInfoDAO = (HostInfoDAO) services.get(HostInfoDAO.class.getName());
+                Objects.requireNonNull(hostInfoDAO);
+                CpuStatDAO cpuStatDAO = (CpuStatDAO) services.get(CpuStatDAO.class.getName());
+                Objects.requireNonNull(cpuStatDAO);
+                HostCpuService service = new HostCpuService(hostInfoDAO, cpuStatDAO);
+                reg = context.registerService(HostInformationService.class.getName(), service, null);
+            }
+
+            @Override
+            public void dependenciesUnavailable() {
+                reg.unregister();
+            }
+
+        });
+        tracker.open();
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        tracker.close();
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-cpu/client-swing/src/main/java/com/redhat/thermostat/host/cpu/client/swing/HostCpuPanel.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.cpu.client.swing;
+
+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.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.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.host.cpu.client.core.HostCpuView;
+import com.redhat.thermostat.host.cpu.client.locale.LocaleResources;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+import com.redhat.thermostat.swing.components.experimental.WrapLayout;
+
+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/host-cpu/client-swing/src/main/java/com/redhat/thermostat/host/cpu/client/swing/SwingHostCpuViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.cpu.client.swing;
+
+import com.redhat.thermostat.host.cpu.client.core.HostCpuView;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuViewProvider;
+
+public class SwingHostCpuViewProvider implements HostCpuViewProvider {
+
+    @Override
+    public HostCpuView createView() {
+        return new HostCpuPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-cpu/client-swing/src/test/java/com/redhat/thermostat/host/cpu/client/swing/ActivatorTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,104 @@
+/*
+ * 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.host.cpu.client.swing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.core.HostInformationService;
+import com.redhat.thermostat.common.dao.CpuStatDAO;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuService;
+import com.redhat.thermostat.host.cpu.client.core.HostCpuViewProvider;
+import com.redhat.thermostat.host.cpu.client.swing.Activator;
+import com.redhat.thermostat.host.cpu.client.swing.SwingHostCpuViewProvider;
+import com.redhat.thermostat.test.StubBundleContext;
+
+public class ActivatorTest {
+    
+    @Test
+    public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        // View provider registers unconditionally
+        assertEquals(1, context.getAllServices().size());
+        assertNotSame(1, context.getServiceListeners().size());
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+    }
+
+    @Test
+    public void verifyActivatorRegistersServices() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+        HostInfoDAO hostInfoDAO = mock(HostInfoDAO.class);
+        CpuStatDAO cpuStatDAO = mock(CpuStatDAO.class);
+
+        context.registerService(HostInfoDAO.class, hostInfoDAO, null);
+        context.registerService(CpuStatDAO.class, cpuStatDAO, null);
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        assertTrue(context.isServiceRegistered(HostInformationService.class.getName(), HostCpuService.class));
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+        assertEquals(3, context.getAllServices().size());
+    }
+
+    @Test
+    public void verifyStartRegistersViewProvider() throws Exception {
+        StubBundleContext ctx = new StubBundleContext();
+        Activator activator = new Activator();
+        activator.start(ctx);
+        assertTrue(ctx.isServiceRegistered(HostCpuViewProvider.class.getName(), SwingHostCpuViewProvider.class));
+        assertEquals(1, ctx.getAllServices().size());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-cpu/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,58 @@
+<?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</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-host-cpu</artifactId>
+  <packaging>pom</packaging>
+
+  <name>Thermostat Host CPU plugin</name>
+
+  <modules>
+    <module>client-core</module>
+    <module>client-swing</module>
+  </modules>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-memory/client-core/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-host-memory</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-host-memory-client-core</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat Host Memory Core Client plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Private-Package></Private-Package>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.host.memory.client.core</Bundle-SymbolicName>
+            <Export-Package>
+              com.redhat.thermostat.host.memory.client.core,
+              com.redhat.thermostat.host.memory.client.locale
+            </Export-Package>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <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.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>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/core/HostMemoryController.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,186 @@
+/*
+ * 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.host.memory.client.core;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import com.redhat.thermostat.client.core.controllers.HostInformationServiceController;
+import com.redhat.thermostat.client.core.views.BasicView.Action;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.NotImplementedException;
+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.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.MemoryStatDAO;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.common.utils.DisplayableValues;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryView.GraphVisibilityChangeListener;
+import com.redhat.thermostat.host.memory.client.locale.LocaleResources;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+import com.redhat.thermostat.storage.model.MemoryStat;
+import com.redhat.thermostat.storage.model.MemoryType;
+
+public class HostMemoryController implements HostInformationServiceController {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private final HostMemoryView view;
+
+    private final HostInfoDAO hostInfoDAO;
+    private final MemoryStatDAO memoryStatDAO;
+    private final HostRef ref;
+
+    private final Timer backgroundUpdateTimer;
+    private final GraphVisibilityChangeListener listener = new ShowHideGraph();
+
+    private long lastSeenTimeStamp = Long.MIN_VALUE;
+
+    public HostMemoryController(HostInfoDAO hostInfoDAO, MemoryStatDAO memoryStatDAO, final HostRef ref, HostMemoryViewProvider provider) {
+        this.ref = ref;
+        this.hostInfoDAO = hostInfoDAO;
+        this.memoryStatDAO = memoryStatDAO;
+
+        view = provider.createView();
+
+        view.addMemoryChart(MemoryType.MEMORY_TOTAL.name(), translator.localize(LocaleResources.HOST_MEMORY_TOTAL));
+        view.addMemoryChart(MemoryType.MEMORY_FREE.name(), translator.localize(LocaleResources.HOST_MEMORY_FREE));
+        view.addMemoryChart(MemoryType.MEMORY_USED.name(), translator.localize(LocaleResources.HOST_MEMORY_USED));
+        view.addMemoryChart(MemoryType.SWAP_TOTAL.name(), translator.localize(LocaleResources.HOST_SWAP_TOTAL));
+        view.addMemoryChart(MemoryType.SWAP_FREE.name(), translator.localize(LocaleResources.HOST_SWAP_FREE));
+        view.addMemoryChart(MemoryType.BUFFERS.name(), translator.localize(LocaleResources.HOST_BUFFERS));
+
+        view.addGraphVisibilityListener(listener);
+        view.addActionListener(new ActionListener<HostMemoryView.Action>() {
+            @Override
+            public void actionPerformed(ActionEvent<Action> actionEvent) {
+                switch (actionEvent.getActionId()) {
+                    case HIDDEN:
+                        stopBackgroundUpdates();
+                        break;
+                    case VISIBLE:
+                        startBackgroundUpdates();
+                        break;
+                    default:
+                        throw new NotImplementedException("action event not handled: " + actionEvent.getActionId());
+                }
+            }
+        });
+
+        backgroundUpdateTimer = ApplicationContext.getInstance().getTimerFactory().createTimer();
+        backgroundUpdateTimer.setAction(new Runnable() {
+            @Override
+            public void run() {
+                long memorySize = HostMemoryController.this.hostInfoDAO.getHostInfo(ref).getTotalMemory();
+                String[] memorySizeParts = DisplayableValues.bytes(memorySize);
+                view.setTotalMemory(translator.localize(LocaleResources.NUMBER_AND_UNIT, memorySizeParts[0], memorySizeParts[1]));
+                doMemoryChartUpdate();
+            }
+        });
+        backgroundUpdateTimer.setSchedulingType(SchedulingType.FIXED_RATE);
+        backgroundUpdateTimer.setTimeUnit(TimeUnit.SECONDS);
+        backgroundUpdateTimer.setInitialDelay(0);
+        backgroundUpdateTimer.setDelay(5);
+    }
+
+    private void startBackgroundUpdates() {
+        for (MemoryType type : MemoryType.values()) {
+            view.showMemoryChart(type.name());
+        }
+
+        backgroundUpdateTimer.start();
+    }
+
+    private void stopBackgroundUpdates() {
+        backgroundUpdateTimer.stop();
+        for (MemoryType type : MemoryType.values()) {
+            view.hideMemoryChart(type.name());
+        }
+    }
+
+    public UIComponent getView() {
+        return view;
+    }
+
+    private void doMemoryChartUpdate() {
+        List<DiscreteTimeData<? extends Number>> memFree = new LinkedList<>();
+        List<DiscreteTimeData<? extends Number>> memTotal = new LinkedList<>();
+        List<DiscreteTimeData<? extends Number>> memUsed = new LinkedList<>();
+        List<DiscreteTimeData<? extends Number>> buf = new LinkedList<>();
+        List<DiscreteTimeData<? extends Number>> swapTotal = new LinkedList<>();
+        List<DiscreteTimeData<? extends Number>> swapFree = new LinkedList<>();
+
+        for (MemoryStat stat : memoryStatDAO.getLatestMemoryStats(ref, lastSeenTimeStamp)) {
+            long timeStamp = stat.getTimeStamp();
+            memFree.add(new DiscreteTimeData<Long>(timeStamp, stat.getFree()));
+            memTotal.add(new DiscreteTimeData<Long>(timeStamp, stat.getTotal()));
+            memUsed.add(new DiscreteTimeData<Long>(timeStamp, stat.getTotal() - stat.getFree()));
+            buf.add(new DiscreteTimeData<Long>(timeStamp, stat.getBuffers()));
+            swapTotal.add(new DiscreteTimeData<Long>(timeStamp, stat.getSwapTotal()));
+            swapFree.add(new DiscreteTimeData<Long>(timeStamp, stat.getSwapFree()));
+            lastSeenTimeStamp = Math.max(lastSeenTimeStamp, stat.getTimeStamp());
+        }
+
+        view.addMemoryData(MemoryType.MEMORY_FREE.name(), memFree);
+        view.addMemoryData(MemoryType.MEMORY_TOTAL.name(), memTotal);
+        view.addMemoryData(MemoryType.MEMORY_USED.name(), memUsed);
+        view.addMemoryData(MemoryType.BUFFERS.name(), buf);
+        view.addMemoryData(MemoryType.SWAP_FREE.name(), swapFree);
+        view.addMemoryData(MemoryType.SWAP_TOTAL.name(), swapTotal);
+    }
+
+    private class ShowHideGraph implements GraphVisibilityChangeListener {
+        @Override
+        public void show(String tag) {
+            view.showMemoryChart(tag);
+        }
+        @Override
+        public void hide(String tag) {
+            view.hideMemoryChart(tag);
+        }
+    }
+
+    @Override
+    public String getLocalizedName() {
+        return translator.localize(LocaleResources.HOST_INFO_TAB_MEMORY);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/core/HostMemoryService.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.memory.client.core;
+
+import com.redhat.thermostat.client.core.HostFilter;
+import com.redhat.thermostat.client.core.HostInformationService;
+import com.redhat.thermostat.client.core.controllers.HostInformationServiceController;
+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.utils.OSGIUtils;
+
+public class HostMemoryService implements HostInformationService {
+    
+    private static final HostFilter FILTER = new HostFilter() {
+        @Override
+        public boolean matches(HostRef toMatch) {
+            return true;
+        }
+    };
+    
+    private HostInfoDAO hostInfoDAO;
+    private MemoryStatDAO memoryStatDAO;
+    
+    public HostMemoryService(HostInfoDAO hostInfoDAO, MemoryStatDAO memoryStatDAO) {
+        this.hostInfoDAO = hostInfoDAO;
+        this.memoryStatDAO = memoryStatDAO;
+    }
+
+    @Override
+    public HostFilter getFilter() {
+        return FILTER;
+    }
+
+    @Override
+    public HostInformationServiceController getInformationServiceController(
+            HostRef ref) {
+        HostMemoryViewProvider provider = OSGIUtils.getInstance().getService(HostMemoryViewProvider.class);
+        return new HostMemoryController(hostInfoDAO, memoryStatDAO, ref, provider);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/core/HostMemoryView.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.memory.client.core;
+
+import java.util.List;
+
+import com.redhat.thermostat.client.core.views.BasicView;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+
+public abstract class HostMemoryView extends BasicView implements UIComponent {
+
+    public interface GraphVisibilityChangeListener {
+        public void show(String tag);
+
+        public void hide(String tag);
+    }
+
+    public abstract void setTotalMemory(String totalMemory);
+
+    public abstract void addMemoryChart(String tag, String humanReadableName);
+
+    public abstract void removeMemoryChart(String tag);
+
+    public abstract void showMemoryChart(String tag);
+
+    public abstract void hideMemoryChart(String tag);
+
+    public abstract void addMemoryData(String tag, List<DiscreteTimeData<? extends Number>> data);
+
+    public abstract void clearMemoryData(String tag);
+
+    public abstract void addGraphVisibilityListener(GraphVisibilityChangeListener listener);
+
+    public abstract void removeGraphVisibilityListener(GraphVisibilityChangeListener listener);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/core/HostMemoryViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * 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.host.memory.client.core;
+
+import com.redhat.thermostat.client.core.views.ViewProvider;
+
+public interface HostMemoryViewProvider extends ViewProvider {
+
+    @Override
+    public HostMemoryView createView();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-memory/client-core/src/main/java/com/redhat/thermostat/host/memory/client/locale/LocaleResources.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.memory.client.locale;
+
+import com.redhat.thermostat.common.locale.Translate;
+
+public enum LocaleResources {
+    NUMBER_AND_UNIT,
+    
+    HOST_INFO_TAB_MEMORY,
+    
+    HOST_INFO_MEMORY_TOTAL,
+    
+    HOST_MEMORY_SECTION_OVERVIEW,
+    HOST_MEMORY_CHART_TITLE,
+    HOST_MEMORY_CHART_TIME_LABEL,
+    HOST_MEMORY_CHART_SIZE_LABEL,
+    
+    HOST_MEMORY_TOTAL,
+    HOST_MEMORY_FREE,
+    HOST_MEMORY_USED,
+    HOST_SWAP_TOTAL,
+    HOST_SWAP_FREE,
+    HOST_BUFFERS,
+    ;
+
+    static final String RESOURCE_BUNDLE =
+            "com.redhat.thermostat.host.memory.client.locale.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-memory/client-core/src/main/resources/com/redhat/thermostat/host/memory/client/locale/strings.properties	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,17 @@
+NUMBER_AND_UNIT = {0} {1}
+
+HOST_INFO_TAB_MEMORY = Memory
+
+HOST_INFO_MEMORY_TOTAL = Total Memory
+
+HOST_MEMORY_SECTION_OVERVIEW = Memory
+HOST_MEMORY_CHART_TITLE = Memory
+HOST_MEMORY_CHART_TIME_LABEL = Time
+HOST_MEMORY_CHART_SIZE_LABEL = Size ({0})
+
+HOST_MEMORY_TOTAL = Total Memory
+HOST_MEMORY_FREE = Free Memory
+HOST_MEMORY_USED = Used Memory
+HOST_SWAP_TOTAL = Total Swap
+HOST_SWAP_FREE = Free Swap
+HOST_BUFFERS = Buffers
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-memory/client-core/src/test/java/com/redhat/thermostat/host/memory/client/core/HostMemoryControllerTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,126 @@
+/*
+ * 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.host.memory.client.core;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.eq;
+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.util.LinkedList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.Timer;
+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.MemoryStatDAO;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryController;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryView;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryViewProvider;
+import com.redhat.thermostat.storage.model.HostInfo;
+import com.redhat.thermostat.storage.model.MemoryStat;
+
+public class HostMemoryControllerTest {
+
+    @Before
+    public void setUp() {
+        ApplicationContextUtil.resetApplicationContext();
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" }) // any(List.class)
+    @Test
+    public void testUpdate() {
+        final long TOTAL_MEMORY = 512;
+        HostInfo hostInfo = new HostInfo("someHost", "someOS", "linux_0.0.1", "lreally_fast_cpu", 2, TOTAL_MEMORY);
+        HostInfoDAO hostInfoDAO = mock(HostInfoDAO.class);
+        when(hostInfoDAO.getHostInfo(any(HostRef.class))).thenReturn(hostInfo);
+
+        MemoryStat memoryStat = new MemoryStat(1, 2, 3, 4, 5, 6, 7, 8);
+        List<MemoryStat> memoryStats = new LinkedList<>();
+        memoryStats.add(memoryStat);
+        MemoryStatDAO memoryStatDAO = mock(MemoryStatDAO.class);
+        when(memoryStatDAO.getLatestMemoryStats(any(HostRef.class), anyLong())).thenReturn(memoryStats);
+
+        Timer timer = mock(Timer.class);
+        ArgumentCaptor<Runnable> timerActionCaptor = ArgumentCaptor.forClass(Runnable.class);
+        doNothing().when(timer).setAction(timerActionCaptor.capture());
+
+        TimerFactory timerFactory = mock(TimerFactory.class);
+        when(timerFactory.createTimer()).thenReturn(timer);
+        ApplicationContext.getInstance().setTimerFactory(timerFactory);
+
+        HostRef ref = mock(HostRef.class);
+
+        HostMemoryView view = mock(HostMemoryView.class);
+        ArgumentCaptor<ActionListener> viewArgumentCaptor = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(view).addActionListener(viewArgumentCaptor.capture());
+
+        HostMemoryViewProvider viewProvider = mock(HostMemoryViewProvider.class);
+        when(viewProvider.createView()).thenReturn(view);
+
+        @SuppressWarnings("unused")
+        HostMemoryController controller = new HostMemoryController(hostInfoDAO, memoryStatDAO, ref, viewProvider);
+
+        ActionListener<HostMemoryView.Action> l = viewArgumentCaptor.getValue();
+
+        l.actionPerformed(new ActionEvent<>(view, HostMemoryView.Action.VISIBLE));
+
+        verify(timer).start();
+        timerActionCaptor.getValue().run();
+
+        verify(view, times(1)).setTotalMemory(eq(TOTAL_MEMORY + " B"));
+        verify(view, times(6)).addMemoryData(any(String.class), any(List.class));
+
+        l.actionPerformed(new ActionEvent<>(view, HostMemoryView.Action.HIDDEN));
+
+        verify(timer).stop();
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-memory/client-swing/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-host-memory</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-host-memory-client-swing</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat Host Memory Swing Client plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Private-Package>com.redhat.thermostat.host.memory.client.swing</Private-Package>
+            <Bundle-Activator>com.redhat.thermostat.host.memory.client.swing.Activator</Bundle-Activator>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.host.memory.client.swing</Bundle-SymbolicName>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <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.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>
+    <dependency>
+      <groupId>org.jfree</groupId>
+      <artifactId>jfreechart</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-swing-components</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-memory-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-memory/client-swing/src/main/java/com/redhat/thermostat/host/memory/client/swing/Activator.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.memory.client.swing;
+
+import java.util.Map;
+import java.util.Objects;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import com.redhat.thermostat.client.core.HostInformationService;
+import com.redhat.thermostat.common.MultipleServiceTracker;
+import com.redhat.thermostat.common.MultipleServiceTracker.Action;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.MemoryStatDAO;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryService;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryViewProvider;
+
+public class Activator implements BundleActivator {
+    
+    private MultipleServiceTracker tracker;
+    private ServiceRegistration reg;
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+        HostMemoryViewProvider viewProvider = new SwingHostMemoryViewProvider();
+        context.registerService(HostMemoryViewProvider.class.getName(), viewProvider, null);
+
+        Class<?>[] deps = new Class<?>[] {
+            HostInfoDAO.class,
+            MemoryStatDAO.class,
+        };
+
+        tracker = new MultipleServiceTracker(context, deps, new Action() {
+
+            @Override
+            public void dependenciesAvailable(Map<String, Object> services) {
+                HostInfoDAO hostInfoDAO = (HostInfoDAO) services.get(HostInfoDAO.class.getName());
+                Objects.requireNonNull(hostInfoDAO);
+                MemoryStatDAO memoryStatDAO = (MemoryStatDAO) services.get(MemoryStatDAO.class.getName());
+                Objects.requireNonNull(memoryStatDAO);
+                HostMemoryService service = new HostMemoryService(hostInfoDAO, memoryStatDAO);
+                reg = context.registerService(HostInformationService.class.getName(), service, null);
+            }
+
+            @Override
+            public void dependenciesUnavailable() {
+                reg.unregister();
+            }
+
+        });
+        tracker.open();
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        tracker.close();
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-memory/client-swing/src/main/java/com/redhat/thermostat/host/memory/client/swing/HostMemoryPanel.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.memory.client.swing;
+
+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.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.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.utils.DisplayableValues;
+import com.redhat.thermostat.common.utils.DisplayableValues.Scale;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryView;
+import com.redhat.thermostat.host.memory.client.locale.LocaleResources;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+import com.redhat.thermostat.swing.components.experimental.WrapLayout;
+
+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/host-memory/client-swing/src/main/java/com/redhat/thermostat/host/memory/client/swing/SwingHostMemoryViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.memory.client.swing;
+
+import com.redhat.thermostat.host.memory.client.core.HostMemoryView;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryViewProvider;
+
+public class SwingHostMemoryViewProvider implements HostMemoryViewProvider {
+
+    @Override
+    public HostMemoryView createView() {
+        return new HostMemoryPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-memory/client-swing/src/test/java/com/redhat/thermostat/host/memory/client/swing/ActivatorTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,104 @@
+/*
+ * 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.host.memory.client.swing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.core.HostInformationService;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.MemoryStatDAO;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryService;
+import com.redhat.thermostat.host.memory.client.core.HostMemoryViewProvider;
+import com.redhat.thermostat.host.memory.client.swing.Activator;
+import com.redhat.thermostat.host.memory.client.swing.SwingHostMemoryViewProvider;
+import com.redhat.thermostat.test.StubBundleContext;
+
+public class ActivatorTest {
+    
+    @Test
+    public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        // View provider registers unconditionally
+        assertEquals(1, context.getAllServices().size());
+        assertNotSame(1, context.getServiceListeners().size());
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+    }
+
+    @Test
+    public void verifyActivatorRegistersServices() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+        HostInfoDAO hostInfoDAO = mock(HostInfoDAO.class);
+        MemoryStatDAO memoryStatDAO = mock(MemoryStatDAO.class);
+
+        context.registerService(HostInfoDAO.class, hostInfoDAO, null);
+        context.registerService(MemoryStatDAO.class, memoryStatDAO, null);
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        assertTrue(context.isServiceRegistered(HostInformationService.class.getName(), HostMemoryService.class));
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+        assertEquals(3, context.getAllServices().size());
+    }
+
+    @Test
+    public void verifyStartRegistersViewProvider() throws Exception {
+        StubBundleContext ctx = new StubBundleContext();
+        Activator activator = new Activator();
+        activator.start(ctx);
+        assertTrue(ctx.isServiceRegistered(HostMemoryViewProvider.class.getName(), SwingHostMemoryViewProvider.class));
+        assertEquals(1, ctx.getAllServices().size());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-memory/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,58 @@
+<?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</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-host-memory</artifactId>
+  <packaging>pom</packaging>
+
+  <name>Thermostat Host Memory plugin</name>
+
+  <modules>
+    <module>client-core</module>
+    <module>client-swing</module>
+  </modules>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-overview/client-core/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-host-overview</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-host-overview-client-core</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat Host Overview Core Client plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Private-Package></Private-Package>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.host.overview.client.core</Bundle-SymbolicName>
+            <Export-Package>
+              com.redhat.thermostat.host.overview.client.core,
+              com.redhat.thermostat.host.overview.client.locale
+            </Export-Package>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <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.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>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-overview/client-core/src/main/java/com/redhat/thermostat/host/overview/client/core/HostOverviewController.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,169 @@
+/*
+ * 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.host.overview.client.core;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+import java.util.concurrent.TimeUnit;
+
+import com.redhat.thermostat.client.core.controllers.HostInformationServiceController;
+import com.redhat.thermostat.client.core.views.BasicView.Action;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.NotImplementedException;
+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.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.NetworkInterfaceInfoDAO;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.common.utils.DisplayableValues;
+import com.redhat.thermostat.host.overview.client.locale.LocaleResources;
+import com.redhat.thermostat.storage.model.HostInfo;
+import com.redhat.thermostat.storage.model.NetworkInterfaceInfo;
+
+public class HostOverviewController implements HostInformationServiceController {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private final HostInfoDAO hostInfoDAO;
+    private final NetworkInterfaceInfoDAO networkInfoDAO;
+
+    private final Timer backgroundUpdateTimer;
+    private final List<String> knownNetworkIfaces = new ArrayList<>();
+
+    private final HostOverviewView view;
+
+    public HostOverviewController(HostInfoDAO hostInfoDAO, NetworkInterfaceInfoDAO networkInfoDAO, final HostRef ref, HostOverviewViewProvider provider) {
+        this.hostInfoDAO = hostInfoDAO;
+        this.networkInfoDAO = networkInfoDAO;
+
+        final Vector<String> networkTableColumnVector;
+        networkTableColumnVector = new Vector<String>();
+        networkTableColumnVector.add(translator.localize(LocaleResources.NETWORK_INTERFACE_COLUMN));
+        networkTableColumnVector.add(translator.localize(LocaleResources.NETWORK_IPV4_COLUMN));
+        networkTableColumnVector.add(translator.localize(LocaleResources.NETWORK_IPV6_COLUMN));
+
+        backgroundUpdateTimer = ApplicationContext.getInstance().getTimerFactory().createTimer();
+        backgroundUpdateTimer.setAction(new Runnable() {
+            @Override
+            public void run() {
+                HostInfo hostInfo = HostOverviewController.this.hostInfoDAO.getHostInfo(ref);
+                view.setHostName(hostInfo.getHostname());
+                view.setOsName(hostInfo.getOsName());
+                view.setOsKernel(hostInfo.getOsKernel());
+                view.setCpuModel(hostInfo.getCpuModel());
+                view.setCpuCount(String.valueOf(hostInfo.getCpuCount()));
+
+                String[] parts = DisplayableValues.bytes(hostInfo.getTotalMemory());
+                String readableTotalMemory = translator.localize(LocaleResources.NUMBER_AND_UNIT, parts[0], parts[1]);
+                view.setTotalMemory(readableTotalMemory);
+
+                List<NetworkInterfaceInfo> networkInfo =
+                        HostOverviewController.this.networkInfoDAO.getNetworkInterfaces(ref);
+
+                boolean firstRun = knownNetworkIfaces.isEmpty();
+                if (firstRun) {
+                    List<Object[]> data = new ArrayList<Object[]>();
+                    for (NetworkInterfaceInfo info: networkInfo) {
+                        String ifaceName = info.getInterfaceName();
+                        String ipv4 = info.getIp4Addr();
+                        String ipv6 = info.getIp6Addr();
+                        data.add(new String[] { ifaceName, ipv4, ipv6 });
+                        knownNetworkIfaces.add(ifaceName);
+                    }
+                    view.setInitialNetworkTableData(data.toArray(new Object[0][0]));
+                } else {
+                    for (NetworkInterfaceInfo info: networkInfo) {
+                        String ifaceName = info.getInterfaceName();
+                        String ipv4 = info.getIp4Addr();
+                        String ipv6 = info.getIp6Addr();
+                        int index = knownNetworkIfaces.indexOf(ifaceName);
+                        int row = index;
+                        view.updateNetworkTableData(index, 0, ifaceName);
+                        view.updateNetworkTableData(row, 1, ipv4);
+                        view.updateNetworkTableData(row, 2, ipv6);
+                    }
+                }
+            }
+        });
+        backgroundUpdateTimer.setSchedulingType(SchedulingType.FIXED_RATE);
+        backgroundUpdateTimer.setTimeUnit(TimeUnit.SECONDS);
+        backgroundUpdateTimer.setInitialDelay(0);
+        backgroundUpdateTimer.setDelay(5);
+
+        view = provider.createView();
+
+        view.setNetworkTableColumns(networkTableColumnVector.toArray());
+
+        view.addActionListener(new ActionListener<Action>() {
+            @Override
+            public void actionPerformed(ActionEvent<Action> actionEvent) {
+                switch (actionEvent.getActionId()) {
+                    case HIDDEN:
+                        stop();
+                        break;
+                    case VISIBLE:
+                        start();
+                        break;
+                    default:
+                        throw new NotImplementedException("unhandled: " + actionEvent.getActionId());
+                }
+            }
+        });
+    }
+
+    private void start() {
+        backgroundUpdateTimer.start();
+    }
+
+    private void stop() {
+        backgroundUpdateTimer.stop();
+    }
+
+    public UIComponent getView() {
+        return view;
+    }
+
+    @Override
+    public String getLocalizedName() {
+        return translator.localize(LocaleResources.HOST_INFO_TAB_OVERVIEW);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-overview/client-core/src/main/java/com/redhat/thermostat/host/overview/client/core/HostOverviewService.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.overview.client.core;
+
+import com.redhat.thermostat.client.core.HostFilter;
+import com.redhat.thermostat.client.core.HostInformationService;
+import com.redhat.thermostat.client.core.controllers.HostInformationServiceController;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.NetworkInterfaceInfoDAO;
+import com.redhat.thermostat.common.utils.OSGIUtils;
+
+public class HostOverviewService implements HostInformationService {
+    
+    private static final HostFilter FILTER = new HostFilter() {
+        @Override
+        public boolean matches(HostRef toMatch) {
+            return true;
+        }
+    };
+    
+    private HostInfoDAO hostInfoDAO;
+    private NetworkInterfaceInfoDAO networkInfoDAO;
+    
+    public HostOverviewService(HostInfoDAO hostInfoDAO, NetworkInterfaceInfoDAO networkInfoDAO) {
+        this.hostInfoDAO = hostInfoDAO;
+        this.networkInfoDAO = networkInfoDAO;
+    }
+
+    @Override
+    public HostFilter getFilter() {
+        return FILTER;
+    }
+
+    @Override
+    public HostInformationServiceController getInformationServiceController(
+            HostRef ref) {
+        HostOverviewViewProvider provider = OSGIUtils.getInstance().getService(HostOverviewViewProvider.class);
+        return new HostOverviewController(hostInfoDAO, networkInfoDAO, ref, provider);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-overview/client-core/src/main/java/com/redhat/thermostat/host/overview/client/core/HostOverviewView.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,62 @@
+/*
+ * 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.host.overview.client.core;
+
+import com.redhat.thermostat.client.core.views.BasicView;
+import com.redhat.thermostat.client.core.views.UIComponent;
+
+
+public abstract class HostOverviewView extends BasicView implements UIComponent {
+
+    public abstract void setHostName(String newHostName);
+
+    public abstract void setCpuModel(String newCpuModel);
+
+    public abstract void setCpuCount(String newCpuCount);
+
+    public abstract void setTotalMemory(String newTotalMemory);
+
+    public abstract void setOsName(String newOsName);
+
+    public abstract void setOsKernel(String newOsKernel);
+
+    public abstract void setNetworkTableColumns(Object[] columns);
+
+    public abstract void setInitialNetworkTableData(Object[][] table);
+
+    public abstract void updateNetworkTableData(int row, int column, String data);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-overview/client-core/src/main/java/com/redhat/thermostat/host/overview/client/core/HostOverviewViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * 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.host.overview.client.core;
+
+import com.redhat.thermostat.client.core.views.ViewProvider;
+
+public interface HostOverviewViewProvider extends ViewProvider {
+
+    @Override
+    public HostOverviewView createView();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-overview/client-core/src/main/java/com/redhat/thermostat/host/overview/client/locale/LocaleResources.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.overview.client.locale;
+
+import com.redhat.thermostat.common.locale.Translate;
+
+public enum LocaleResources {
+    NUMBER_AND_UNIT,
+
+    HOST_INFO_TAB_OVERVIEW,
+    
+    HOST_OVERVIEW_SECTION_BASICS,
+    HOST_OVERVIEW_SECTION_HARDWARE,
+    HOST_OVERVIEW_SECTION_SOFTWARE,
+
+    HOST_INFO_HOSTNAME,
+    HOST_INFO_CPU_COUNT,
+    HOST_INFO_CPU_MODEL,
+    HOST_INFO_OS_NAME,
+    HOST_INFO_OS_KERNEL,
+
+    HOST_INFO_MEMORY_TOTAL,
+    HOST_INFO_NETWORK,
+
+    NETWORK_INTERFACE_COLUMN,
+    NETWORK_IPV4_COLUMN,
+    NETWORK_IPV6_COLUMN,
+    ;
+
+    static final String RESOURCE_BUNDLE =
+            "com.redhat.thermostat.host.overview.client.locale.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-overview/client-core/src/main/resources/com/redhat/thermostat/host/overview/client/locale/strings.properties	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,19 @@
+NUMBER_AND_UNIT = {0} {1}
+
+HOST_INFO_TAB_OVERVIEW = Overview
+
+HOST_OVERVIEW_SECTION_BASICS = Basics
+HOST_OVERVIEW_SECTION_HARDWARE = Hardware
+HOST_OVERVIEW_SECTION_SOFTWARE = Software
+
+HOST_INFO_HOSTNAME = Host
+HOST_INFO_CPU_COUNT = Processor Count
+HOST_INFO_CPU_MODEL = Processor Model
+HOST_INFO_OS_NAME = OS Name
+HOST_INFO_OS_KERNEL = OS Kernel
+HOST_INFO_MEMORY_TOTAL = Total Memory
+HOST_INFO_NETWORK = Network
+
+NETWORK_INTERFACE_COLUMN = Interface
+NETWORK_IPV4_COLUMN = IPv4 Address
+NETWORK_IPV6_COLUMN = IPv6 Address
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-overview/client-core/src/test/java/com/redhat/thermostat/host/overview/client/core/HostOverviewControllerTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,181 @@
+/*
+ * 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.host.overview.client.core;
+
+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.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import com.redhat.thermostat.client.core.views.BasicView.Action;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.Timer;
+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.NetworkInterfaceInfoDAO;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewController;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewView;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewViewProvider;
+import com.redhat.thermostat.storage.model.HostInfo;
+import com.redhat.thermostat.storage.model.NetworkInterfaceInfo;
+
+public class HostOverviewControllerTest {
+
+    private static final String HOST_NAME = "host-name";
+    private static final String OS_NAME = "some os";
+    private static final String KERNEL_NAME = "korn";
+    private static final int CPU_COUNT = 99;
+    private static final String CPU_MODEL = "cpu-model";
+    private static final long TOTAL_MEMORY = 99+99;
+    private static final String NETWORK_INTERFACE = "iface0";
+    private static final String IPV4_ADDR = "0xcafef00d";
+    private static final String IPV6_ADDR = "HOME_SWEET_HOME";
+
+    private Timer timer;
+    private Runnable timerAction;
+    private HostOverviewView view;
+    private ActionListener<HostOverviewView.Action> listener;
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Before
+    public void setUp() {
+        ApplicationContextUtil.resetApplicationContext();
+
+        // Setup timer
+        timer = mock(Timer.class);
+        ArgumentCaptor<Runnable> timerActionCaptor = ArgumentCaptor.forClass(Runnable.class);
+        doNothing().when(timer).setAction(timerActionCaptor.capture());
+
+        TimerFactory timerFactory = mock(TimerFactory.class);
+        when(timerFactory.createTimer()).thenReturn(timer);
+        ApplicationContext.getInstance().setTimerFactory(timerFactory);
+
+        // Setup DAOs
+        HostInfo hostInfo = new HostInfo(HOST_NAME, OS_NAME, KERNEL_NAME, CPU_MODEL, CPU_COUNT, TOTAL_MEMORY);
+
+        List<NetworkInterfaceInfo> networkInfo = new ArrayList<NetworkInterfaceInfo>();
+        NetworkInterfaceInfo ifaceInfo = new NetworkInterfaceInfo(NETWORK_INTERFACE);
+        ifaceInfo.setIp4Addr(IPV4_ADDR);
+        ifaceInfo.setIp6Addr(IPV6_ADDR);
+        networkInfo.add(ifaceInfo);
+
+        HostRef ref = mock(HostRef.class);
+
+        HostInfoDAO hostInfoDao = mock(HostInfoDAO.class);
+        when(hostInfoDao.getHostInfo(any(HostRef.class))).thenReturn(hostInfo);
+
+        NetworkInterfaceInfoDAO networkInfoDao = mock(NetworkInterfaceInfoDAO.class);
+        when(networkInfoDao.getNetworkInterfaces(any(HostRef.class))).thenReturn(networkInfo);
+
+        // Setup View
+        ArgumentCaptor<ActionListener> listenerCaptor = ArgumentCaptor.forClass(ActionListener.class);
+        view = mock(HostOverviewView.class);
+        doNothing().when(view).addActionListener(listenerCaptor.capture());
+        HostOverviewViewProvider viewProvider = mock(HostOverviewViewProvider.class);
+        when(viewProvider.createView()).thenReturn(view);
+
+        @SuppressWarnings("unused")
+        HostOverviewController controller = new HostOverviewController(hostInfoDao, networkInfoDao, ref, viewProvider);
+
+        listener = listenerCaptor.getValue();
+        timerAction = timerActionCaptor.getValue();
+    }
+
+    @After
+    public void tearDown() {
+        ApplicationContextUtil.resetApplicationContext();
+    }
+
+    @Test
+    public void verifyViewIsUpdatedWithData() {
+        timerAction.run();
+
+        verify(view).setCpuCount(eq(String.valueOf(CPU_COUNT)));
+        verify(view).setCpuModel(eq(CPU_MODEL));
+        verify(view).setHostName(eq(HOST_NAME));
+
+        verify(view).setNetworkTableColumns(any(String[][].class));
+        verify(view).setInitialNetworkTableData(eq(new String[][] { new String[] { NETWORK_INTERFACE, IPV4_ADDR, IPV6_ADDR }, }));
+
+        verify(view).setOsKernel(eq(KERNEL_NAME));
+        verify(view).setOsName(eq(OS_NAME));
+
+        final String UNITS = " B";
+        verify(view).setTotalMemory(eq(String.valueOf(TOTAL_MEMORY + UNITS)));
+    }
+
+    @Test
+    public void verifyTimerIsSetUpCorrectly() {
+        assertNotNull(timer);
+
+        verify(timer).setAction(isNotNull(Runnable.class));
+        verify(timer).setDelay(5);
+        verify(timer).setTimeUnit(TimeUnit.SECONDS);
+        verify(timer).setInitialDelay(0);
+        verify(timer).setSchedulingType(SchedulingType.FIXED_RATE);
+    }
+
+    @Test
+    public void verifyTimerRunsWhenNeeded() {
+        listener.actionPerformed(new ActionEvent<>(view, Action.VISIBLE));
+
+        verify(timer).start();
+
+        listener.actionPerformed(new ActionEvent<>(view, Action.HIDDEN));
+
+        verify(timer).stop();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-overview/client-swing/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-host-overview</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-host-overview-client-swing</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat Host Overview Swing Client plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Private-Package>com.redhat.thermostat.host.overview.client.swing</Private-Package>
+            <Bundle-Activator>com.redhat.thermostat.host.overview.client.swing.Activator</Bundle-Activator>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.host.overview.client.swing</Bundle-SymbolicName>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <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.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>
+    <dependency>
+      <groupId>org.jfree</groupId>
+      <artifactId>jfreechart</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-host-overview-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-overview/client-swing/src/main/java/com/redhat/thermostat/host/overview/client/swing/Activator.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,97 @@
+/*
+ * 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.host.overview.client.swing;
+
+import java.util.Map;
+import java.util.Objects;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import com.redhat.thermostat.client.core.HostInformationService;
+import com.redhat.thermostat.common.MultipleServiceTracker;
+import com.redhat.thermostat.common.MultipleServiceTracker.Action;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.NetworkInterfaceInfoDAO;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewService;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewViewProvider;
+
+public class Activator implements BundleActivator {
+    
+    private MultipleServiceTracker tracker;
+    private ServiceRegistration reg;
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+        HostOverviewViewProvider viewProvider = new SwingHostOverviewViewProvider();
+        context.registerService(HostOverviewViewProvider.class.getName(), viewProvider, null);
+
+        Class<?>[] deps = new Class<?>[] {
+            HostInfoDAO.class,
+            NetworkInterfaceInfoDAO.class,
+        };
+
+        tracker = new MultipleServiceTracker(context, deps, new Action() {
+
+            @Override
+            public void dependenciesAvailable(Map<String, Object> services) {
+                HostInfoDAO hostInfoDAO = (HostInfoDAO) services.get(HostInfoDAO.class.getName());
+                Objects.requireNonNull(hostInfoDAO);
+                NetworkInterfaceInfoDAO networkInfoDAO = (NetworkInterfaceInfoDAO) 
+                        services.get(NetworkInterfaceInfoDAO.class.getName());
+                Objects.requireNonNull(networkInfoDAO);
+                HostOverviewService service = new HostOverviewService(hostInfoDAO, networkInfoDAO);
+                reg = context.registerService(HostInformationService.class.getName(), service, null);
+            }
+
+            @Override
+            public void dependenciesUnavailable() {
+                reg.unregister();
+            }
+
+        });
+        tracker.open();
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        tracker.close();
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-overview/client-swing/src/main/java/com/redhat/thermostat/host/overview/client/swing/HostOverviewPanel.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.overview.client.swing;
+
+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.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;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewView;
+import com.redhat.thermostat.host.overview.client.locale.LocaleResources;
+
+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/host-overview/client-swing/src/main/java/com/redhat/thermostat/host/overview/client/swing/SwingHostOverviewViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.host.overview.client.swing;
+
+import com.redhat.thermostat.host.overview.client.core.HostOverviewView;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewViewProvider;
+
+public class SwingHostOverviewViewProvider implements HostOverviewViewProvider {
+
+    @Override
+    public HostOverviewView createView() {
+        return new HostOverviewPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-overview/client-swing/src/test/java/com/redhat/thermostat/host/overview/client/swing/ActivatorTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,104 @@
+/*
+ * 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.host.overview.client.swing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.core.HostInformationService;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.NetworkInterfaceInfoDAO;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewService;
+import com.redhat.thermostat.host.overview.client.core.HostOverviewViewProvider;
+import com.redhat.thermostat.host.overview.client.swing.Activator;
+import com.redhat.thermostat.host.overview.client.swing.SwingHostOverviewViewProvider;
+import com.redhat.thermostat.test.StubBundleContext;
+
+public class ActivatorTest {
+    
+    @Test
+    public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        // View provider registers unconditionally
+        assertEquals(1, context.getAllServices().size());
+        assertNotSame(1, context.getServiceListeners().size());
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+    }
+
+    @Test
+    public void verifyActivatorRegistersServices() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+        HostInfoDAO hostInfoDAO = mock(HostInfoDAO.class);
+        NetworkInterfaceInfoDAO networkInfoDAO = mock(NetworkInterfaceInfoDAO.class);
+
+        context.registerService(HostInfoDAO.class, hostInfoDAO, null);
+        context.registerService(NetworkInterfaceInfoDAO.class, networkInfoDAO, null);
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        assertTrue(context.isServiceRegistered(HostInformationService.class.getName(), HostOverviewService.class));
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+        assertEquals(3, context.getAllServices().size());
+    }
+
+    @Test
+    public void verifyStartRegistersViewProvider() throws Exception {
+        StubBundleContext ctx = new StubBundleContext();
+        Activator activator = new Activator();
+        activator.start(ctx);
+        assertTrue(ctx.isServiceRegistered(HostOverviewViewProvider.class.getName(), SwingHostOverviewViewProvider.class));
+        assertEquals(1, ctx.getAllServices().size());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/host-overview/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,58 @@
+<?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</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-host-overview</artifactId>
+  <packaging>pom</packaging>
+
+  <name>Thermostat Host Overview plugin</name>
+
+  <modules>
+    <module>client-core</module>
+    <module>client-swing</module>
+  </modules>
+
+</project>
--- a/pom.xml	Wed Nov 28 12:24:00 2012 +0100
+++ b/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -129,8 +129,13 @@
     <module>killvm</module>
     <module>web</module>
     <module>system-backend</module>
-    <module>gc</module>
     <module>storage</module>
+    <module>host-overview</module>
+    <module>host-cpu</module>
+    <module>host-memory</module>
+    <module>vm-overview</module>
+    <module>vm-cpu</module>
+    <module>vm-gc</module>
     <!-- development related modules -->
     <module>dev</module>
   </modules>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-cpu/client-core/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-vm-cpu</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-vm-cpu-client-core</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat VM CPU Core Client plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Private-Package></Private-Package>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.vm.cpu.client.core</Bundle-SymbolicName>
+            <Export-Package>
+              com.redhat.thermostat.vm.cpu.client.core,
+              com.redhat.thermostat.vm.cpu.client.locale
+            </Export-Package>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <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.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>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/core/VmCpuController.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,134 @@
+/*
+ * 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.vm.cpu.client.core;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import com.redhat.thermostat.client.core.controllers.VmInformationServiceController;
+import com.redhat.thermostat.client.core.views.BasicView.Action;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.NotImplementedException;
+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.dao.VmCpuStatDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+import com.redhat.thermostat.storage.model.VmCpuStat;
+import com.redhat.thermostat.vm.cpu.client.locale.LocaleResources;
+
+public class VmCpuController implements VmInformationServiceController {
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private final VmRef ref;
+    private final VmCpuStatDAO dao;
+    private final VmCpuView view;
+
+    private final Timer timer;
+
+    private long lastSeenTimeStamp = Long.MIN_VALUE;
+
+    public VmCpuController(VmCpuStatDAO vmCpuStatDao, VmRef ref, VmCpuViewProvider provider) {
+        this.ref = ref;
+        dao = vmCpuStatDao;
+        timer = ApplicationContext.getInstance().getTimerFactory().createTimer();
+
+        timer.setAction(new Runnable() {
+            @Override
+            public void run() {
+                doUpdateVmCpuCharts();
+            }
+        });
+        timer.setTimeUnit(TimeUnit.SECONDS);
+        timer.setDelay(5);
+        timer.setInitialDelay(0);
+        timer.setSchedulingType(SchedulingType.FIXED_RATE);
+
+        view = provider.createView();
+
+        view.addActionListener(new ActionListener<VmCpuView.Action>() {
+            @Override
+            public void actionPerformed(ActionEvent<Action> actionEvent) {
+                switch (actionEvent.getActionId()) {
+                    case HIDDEN:
+                        stop();
+                        break;
+                    case VISIBLE:
+                        start();
+                        break;
+                    default:
+                        throw new NotImplementedException("unknown event : " + actionEvent.getActionId());
+                }
+            }
+        });
+    }
+
+    private void start() {
+        timer.start();
+    }
+
+    private void doUpdateVmCpuCharts() {
+        List<VmCpuStat> stats = dao.getLatestVmCpuStats(ref, lastSeenTimeStamp);
+        List<DiscreteTimeData<? extends Number>> toDisplay = new ArrayList<>(stats.size());
+        for (VmCpuStat stat: stats) {
+            DiscreteTimeData<? extends Number> data =
+                    new DiscreteTimeData<Number>(stat.getTimeStamp(), stat.getCpuLoad());
+            toDisplay.add(data);
+            lastSeenTimeStamp = Math.max(lastSeenTimeStamp, stat.getTimeStamp());
+        }
+
+        view.addData(toDisplay);
+    }
+
+    private void stop() {
+        timer.stop();
+    }
+
+    public UIComponent getView() {
+        return (UIComponent) view;
+    }
+
+    @Override
+    public String getLocalizedName() {
+        return translator.localize(LocaleResources.VM_INFO_TAB_CPU);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/core/VmCpuService.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.cpu.client.core;
+
+import com.redhat.thermostat.client.core.VmFilter;
+import com.redhat.thermostat.client.core.VmInformationService;
+import com.redhat.thermostat.client.core.controllers.VmInformationServiceController;
+import com.redhat.thermostat.client.osgi.service.AlwaysMatchFilter;
+import com.redhat.thermostat.common.dao.VmCpuStatDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.utils.OSGIUtils;
+
+public class VmCpuService implements VmInformationService {
+    
+    private static final VmFilter FILTER = new AlwaysMatchFilter();
+    
+    private VmCpuStatDAO vmCpuStatDAO;
+    
+    public VmCpuService(VmCpuStatDAO vmCpuStatDAO) {
+        this.vmCpuStatDAO = vmCpuStatDAO;
+    }
+
+    @Override
+    public VmInformationServiceController getInformationServiceController(
+            VmRef ref) {
+        VmCpuViewProvider provider = OSGIUtils.getInstance().getService(VmCpuViewProvider.class);
+        return new VmCpuController(vmCpuStatDAO, ref, provider);
+    }
+
+    @Override
+    public VmFilter getFilter() {
+        return FILTER;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/core/VmCpuView.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * 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.vm.cpu.client.core;
+
+import java.util.List;
+
+import com.redhat.thermostat.client.core.views.BasicView;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.storage.model.DiscreteTimeData;
+
+public abstract class VmCpuView extends BasicView implements UIComponent {
+
+    public abstract void addData(List<DiscreteTimeData<? extends Number>> data);
+
+    public abstract void clearData();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/core/VmCpuViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * 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.vm.cpu.client.core;
+
+import com.redhat.thermostat.client.core.views.ViewProvider;
+
+public interface VmCpuViewProvider extends ViewProvider {
+
+    @Override
+    public VmCpuView createView();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-cpu/client-core/src/main/java/com/redhat/thermostat/vm/cpu/client/locale/LocaleResources.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * 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.vm.cpu.client.locale;
+
+import com.redhat.thermostat.common.locale.Translate;
+
+public enum LocaleResources {
+    
+    VM_INFO_TAB_CPU,
+    
+    VM_CPU_TITLE,
+    VM_CPU_CHART_LOAD_LABEL,
+    VM_CPU_CHART_TIME_LABEL,
+    ;
+
+    static final String RESOURCE_BUNDLE =
+            "com.redhat.thermostat.vm.cpu.client.locale.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-cpu/client-core/src/main/resources/com/redhat/thermostat/vm/cpu/client/locale/strings.properties	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,5 @@
+VM_INFO_TAB_CPU = CPU
+
+VM_CPU_TITLE = Cpu Usage by Virtual Machine
+VM_CPU_CHART_LOAD_LABEL = % CPU
+VM_CPU_CHART_TIME_LABEL = Time
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-cpu/client-core/src/test/java/com/redhat/thermostat/vm/cpu/client/core/VmCpuControllerTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.cpu.client.core;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+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.ArrayList;
+import java.util.List;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.Timer;
+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.VmCpuStatDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.storage.model.VmCpuStat;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuController;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuView;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuViewProvider;
+
+
+public class VmCpuControllerTest {
+
+    @Before
+    public void setUp() {
+        ApplicationContextUtil.resetApplicationContext();
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" }) // any(List.class)
+    @Test
+    public void testChartUpdate() {
+
+        VmCpuStat stat1 = new VmCpuStat(123, 12345, 50.5);
+        List<VmCpuStat> stats = new ArrayList<VmCpuStat>();
+        stats.add(stat1);
+
+        VmCpuStatDAO vmCpuStatDAO = mock(VmCpuStatDAO.class);
+        when(vmCpuStatDAO.getLatestVmCpuStats(any(VmRef.class), eq(Long.MIN_VALUE))).thenReturn(stats).thenReturn(new ArrayList<VmCpuStat>());
+
+        VmRef ref = mock(VmRef.class);
+
+        Timer timer = mock(Timer.class);
+        ArgumentCaptor<Runnable> timerActionCaptor = ArgumentCaptor.forClass(Runnable.class);
+        doNothing().when(timer).setAction(timerActionCaptor.capture());
+
+        TimerFactory timerFactory = mock(TimerFactory.class);
+        when(timerFactory.createTimer()).thenReturn(timer);
+        ApplicationContext.getInstance().setTimerFactory(timerFactory);
+
+        final VmCpuView view = mock(VmCpuView.class);
+        ArgumentCaptor<ActionListener> viewArgumentCaptor = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(view).addActionListener(viewArgumentCaptor.capture());
+        
+        VmCpuViewProvider viewProvider = mock(VmCpuViewProvider.class);
+        when(viewProvider.createView()).thenReturn(view);
+
+        @SuppressWarnings("unused")
+        VmCpuController controller = new VmCpuController(vmCpuStatDAO, ref, viewProvider);
+
+        ActionListener<VmCpuView.Action> l = viewArgumentCaptor.getValue();
+
+        l.actionPerformed(new ActionEvent<>(view, VmCpuView.Action.VISIBLE));
+
+        verify(timer).start();
+
+        timerActionCaptor.getValue().run();
+
+        l.actionPerformed(new ActionEvent<>(view, VmCpuView.Action.HIDDEN));
+
+        verify(timer).stop();
+
+        verify(view).addData(any(List.class));
+        // We don't verify atMost() since we might increase the update rate in the future.
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-cpu/client-swing/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-vm-cpu</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-vm-cpu-client-swing</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat VM CPU Swing Client plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Private-Package>com.redhat.thermostat.vm.cpu.client.swing</Private-Package>
+            <Bundle-Activator>com.redhat.thermostat.vm.cpu.client.swing.Activator</Bundle-Activator>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.vm.cpu.client.swing</Bundle-SymbolicName>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <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.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>
+    <dependency>
+      <groupId>org.jfree</groupId>
+      <artifactId>jfreechart</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-cpu-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-cpu/client-swing/src/main/java/com/redhat/thermostat/vm/cpu/client/swing/Activator.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.cpu.client.swing;
+
+import java.util.Objects;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+
+import com.redhat.thermostat.client.core.VmInformationService;
+import com.redhat.thermostat.common.dao.VmCpuStatDAO;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuService;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuViewProvider;
+
+public class Activator implements BundleActivator {
+    
+    private ServiceTracker tracker;
+    private ServiceRegistration reg;
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+        VmCpuViewProvider viewProvider = new SwingVmCpuViewProvider();
+        context.registerService(VmCpuViewProvider.class.getName(), viewProvider, null);
+
+        tracker = new ServiceTracker(context, VmCpuStatDAO.class.getName(), null) {
+            
+            @Override
+            public Object addingService(ServiceReference reference) {
+                VmCpuStatDAO vmCpuStatDAO = (VmCpuStatDAO) context.getService(reference);
+                Objects.requireNonNull(vmCpuStatDAO);
+                VmCpuService service = new VmCpuService(vmCpuStatDAO);
+                reg = context.registerService(VmInformationService.class.getName(), service, null);
+                
+                return super.addingService(reference);
+            }
+
+            @Override
+            public void removedService(ServiceReference reference, Object service) {
+                context.ungetService(reference);
+                reg.unregister();
+            }
+        };
+        tracker.open();
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        tracker.close();
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-cpu/client-swing/src/main/java/com/redhat/thermostat/vm/cpu/client/swing/SwingVmCpuViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.cpu.client.swing;
+
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuView;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuViewProvider;
+
+public class SwingVmCpuViewProvider implements VmCpuViewProvider {
+
+    @Override
+    public VmCpuView createView() {
+        return new VmCpuPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-cpu/client-swing/src/main/java/com/redhat/thermostat/vm/cpu/client/swing/VmCpuPanel.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.cpu.client.swing;
+
+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.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.storage.model.DiscreteTimeData;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuView;
+import com.redhat.thermostat.vm.cpu.client.locale.LocaleResources;
+
+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/vm-cpu/client-swing/src/test/java/com/redhat/thermostat/vm/cpu/client/swing/ActivatorTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.cpu.client.swing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.core.VmInformationService;
+import com.redhat.thermostat.common.dao.VmCpuStatDAO;
+import com.redhat.thermostat.test.StubBundleContext;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuService;
+import com.redhat.thermostat.vm.cpu.client.core.VmCpuViewProvider;
+
+public class ActivatorTest {
+    
+    @Test
+    public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        // View provider registers unconditionally
+        assertEquals(1, context.getAllServices().size());
+        assertEquals(1, context.getServiceListeners().size());
+        
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+    }
+
+    @Test
+    public void verifyActivatorRegistersServices() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+        VmCpuStatDAO vmCpuStatDAO = mock(VmCpuStatDAO.class);
+
+        context.registerService(VmCpuStatDAO.class, vmCpuStatDAO, null);
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        assertTrue(context.isServiceRegistered(VmInformationService.class.getName(), VmCpuService.class));
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+        assertEquals(2, context.getAllServices().size());
+    }
+
+    @Test
+    public void verifyStartRegistersViewProvider() throws Exception {
+        StubBundleContext ctx = new StubBundleContext();
+        Activator activator = new Activator();
+        activator.start(ctx);
+        assertTrue(ctx.isServiceRegistered(VmCpuViewProvider.class.getName(), SwingVmCpuViewProvider.class));
+        assertEquals(1, ctx.getAllServices().size());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-cpu/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,58 @@
+<?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</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-vm-cpu</artifactId>
+  <packaging>pom</packaging>
+
+  <name>Thermostat VM CPU plugin</name>
+
+  <modules>
+    <module>client-core</module>
+    <module>client-swing</module>
+  </modules>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/client-core/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-vm-gc</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-vm-gc-client-core</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat VM GC Core Client plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Private-Package></Private-Package>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.vm.gc.client.core</Bundle-SymbolicName>
+            <Export-Package>
+              com.redhat.thermostat.vm.gc.client.core,
+              com.redhat.thermostat.vm.gc.client.locale
+            </Export-Package>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <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.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>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/VmGcController.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,201 @@
+/*
+ * 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.vm.gc.client.core;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.concurrent.TimeUnit;
+
+import com.redhat.thermostat.client.core.controllers.VmInformationServiceController;
+import com.redhat.thermostat.client.core.views.BasicView.Action;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.NotImplementedException;
+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.dao.VmGcStatDAO;
+import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.storage.model.IntervalTimeData;
+import com.redhat.thermostat.storage.model.TimeStampedPojoComparator;
+import com.redhat.thermostat.storage.model.VmGcStat;
+import com.redhat.thermostat.storage.model.VmMemoryStat;
+import com.redhat.thermostat.storage.model.VmMemoryStat.Generation;
+import com.redhat.thermostat.vm.gc.client.locale.LocaleResources;
+
+public class VmGcController implements VmInformationServiceController {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private final VmRef ref;
+    private final VmGcView view;
+
+    private final VmGcStatDAO gcDao;
+    private final VmMemoryStatDAO memDao;
+
+    private final Set<String> addedCollectors = new TreeSet<>();
+    // the last value seen for each collector
+    private final Map<String, VmGcStat> lastValueSeen = new TreeMap<>();
+
+    private final Timer timer;
+
+    private long lastSeenTimeStamp = Long.MIN_VALUE;
+
+    public VmGcController(VmMemoryStatDAO vmMemoryStatDao, VmGcStatDAO vmGcStatDao, VmRef ref, VmGcViewProvider provider) {
+        this.ref = ref;
+        this.view = provider.createView();
+        this.timer = ApplicationContext.getInstance().getTimerFactory().createTimer();
+
+        gcDao = vmGcStatDao;
+        memDao = vmMemoryStatDao;
+
+        view.addActionListener(new ActionListener<VmGcView.Action>() {
+            @Override
+            public void actionPerformed(ActionEvent<Action> actionEvent) {
+                switch (actionEvent.getActionId()) {
+                    case HIDDEN:
+                        stop();
+                        break;
+                    case VISIBLE:
+                        start();
+                        break;
+                    default:
+                        throw new NotImplementedException("unkonwn action: " + actionEvent.getActionId());
+                }
+            }
+        });
+
+        timer.setAction(new Runnable() {
+            @Override
+            public void run() {
+                try {
+                    doUpdateCollectorData();
+                } catch (Throwable t) {
+                    t.printStackTrace();
+                    throw t;
+                }
+            }
+        });
+        timer.setSchedulingType(SchedulingType.FIXED_RATE);
+        timer.setInitialDelay(0);
+        timer.setDelay(5);
+        timer.setTimeUnit(TimeUnit.SECONDS);
+    }
+
+    private void start() {
+        timer.start();
+    }
+
+    private void stop() {
+         timer.stop();
+    }
+
+    // FIXME
+    private String chartName(String collectorName, String generationName) {
+        return translator.localize(LocaleResources.VM_GC_COLLECTOR_OVER_GENERATION,
+                collectorName, generationName);
+    }
+
+    private void doUpdateCollectorData() {
+        Map<String, List<IntervalTimeData<Double>>> dataToAdd = new HashMap<>();
+        List<VmGcStat> sortedList = gcDao.getLatestVmGcStats(ref, lastSeenTimeStamp);
+        Collections.sort(sortedList, new TimeStampedPojoComparator<>());
+
+        for (VmGcStat stat : sortedList) {
+            String collector = stat.getCollectorName();
+            List<IntervalTimeData<Double>> data = dataToAdd.get(collector);
+            if (data == null) {
+                data = new ArrayList<>();
+                dataToAdd.put(collector, data);
+            }
+            if (lastValueSeen.containsKey(collector)) {
+                if (stat.getTimeStamp() <= lastValueSeen.get(collector).getTimeStamp()) {
+                    System.out.println("new gc collector value is older than previous value");
+                }
+                VmGcStat last = lastValueSeen.get(collector);
+                lastSeenTimeStamp = Math.max(lastSeenTimeStamp, stat.getTimeStamp());
+                long diffInMicro = (stat.getWallTime() - last.getWallTime());
+                double diffInMillis = diffInMicro / 1000.0;
+                // TODO there is not much point in adding data when diff is 0,
+                // but we need to make the chart scroll automatically based on
+                // the current time when we do that
+                //  if (diff != 0) {
+                data.add(new IntervalTimeData<>(last.getTimeStamp(), stat.getTimeStamp(), diffInMillis));
+                // }
+            }
+            lastValueSeen.put(collector, stat);
+        }
+        for (Map.Entry<String, List<IntervalTimeData<Double>>> entry : dataToAdd.entrySet()) {
+            String name = entry.getKey();
+            if (!addedCollectors.contains(name)) {
+                view.addChart(name, chartName(name, getCollectorGeneration(name)), "ms");
+                addedCollectors.add(name);
+            }
+            view.addData(entry.getKey(), entry.getValue());
+        }
+    }
+
+    public String getCollectorGeneration(String collectorName) {
+        VmMemoryStat info = memDao.getLatestMemoryStat(ref);
+
+        for (Generation g: info.getGenerations()) {
+            if (g.getCollector().equals(collectorName)) {
+                return g.getName();
+            }
+        }
+        return translator.localize(LocaleResources.UNKNOWN_GEN);
+    }
+
+    public UIComponent getView() {
+        return (UIComponent) view;
+    }
+
+    @Override
+    public String getLocalizedName() {
+        return translator.localize(LocaleResources.VM_INFO_TAB_GC);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/VmGcService.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.gc.client.core;
+
+import com.redhat.thermostat.client.core.VmFilter;
+import com.redhat.thermostat.client.core.VmInformationService;
+import com.redhat.thermostat.client.core.controllers.VmInformationServiceController;
+import com.redhat.thermostat.client.osgi.service.AlwaysMatchFilter;
+import com.redhat.thermostat.common.dao.VmGcStatDAO;
+import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.utils.OSGIUtils;
+
+public class VmGcService implements VmInformationService {
+    
+    private static final VmFilter FILTER = new AlwaysMatchFilter();
+    
+    private VmMemoryStatDAO vmMemoryStatDAO;
+    private VmGcStatDAO vmGcStatDAO;
+    
+    public VmGcService(VmMemoryStatDAO vmMemoryStatDAO, VmGcStatDAO vmGcStatDAO) {
+        this.vmMemoryStatDAO = vmMemoryStatDAO;
+        this.vmGcStatDAO = vmGcStatDAO;
+    }
+
+    @Override
+    public VmInformationServiceController getInformationServiceController(
+            VmRef ref) {
+        VmGcViewProvider provider = OSGIUtils.getInstance().getService(VmGcViewProvider.class);
+        return new VmGcController(vmMemoryStatDAO, vmGcStatDAO, ref, provider);
+    }
+
+    @Override
+    public VmFilter getFilter() {
+        return FILTER;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/VmGcView.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,55 @@
+/*
+ * 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.vm.gc.client.core;
+
+import java.util.List;
+
+import com.redhat.thermostat.client.core.views.BasicView;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.storage.model.IntervalTimeData;
+
+public abstract class VmGcView extends BasicView implements UIComponent {
+
+    public abstract void addChart(String tag, String title, String valueUnit);
+
+    public abstract void removeChart(String tag);
+
+    public abstract void addData(String tag, List<IntervalTimeData<Double>> data);
+
+    public abstract void clearData(String tag);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/core/VmGcViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * 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.vm.gc.client.core;
+
+import com.redhat.thermostat.client.core.views.ViewProvider;
+
+public interface VmGcViewProvider extends ViewProvider {
+
+    @Override
+    public VmGcView createView();
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/client-core/src/main/java/com/redhat/thermostat/vm/gc/client/locale/LocaleResources.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,66 @@
+/*
+ * 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.vm.gc.client.locale;
+
+import com.redhat.thermostat.common.locale.Translate;
+
+public enum LocaleResources {
+    GARBAGE_COLLECTION,
+    YOUNG_GEN,
+    EDEN_GEN,
+    S0_GEN,
+    S1_GEN,
+    OLD_GEN,
+    PERM_GEN,
+    UNKNOWN_GEN,
+    SOME_GENERATION,
+    
+    VM_INFO_TAB_GC,
+    
+    VM_GC_TITLE,
+    VM_GC_COLLECTOR_OVER_GENERATION,
+    VM_GC_COLLECTOR_CHART_REAL_TIME_LABEL,
+    VM_GC_COLLECTOR_CHART_GC_TIME_LABEL,
+    ;
+
+    static final String RESOURCE_BUNDLE =
+            "com.redhat.thermostat.vm.gc.client.locale.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/client-core/src/main/resources/com/redhat/thermostat/vm/gc/client/locale/strings.properties	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,16 @@
+GARBAGE_COLLECTION = Garbage Collection
+YOUNG_GEN = Young
+EDEN_GEN = Eden
+S0_GEN = Survivor 0
+S1_GEN = Survivor 1
+OLD_GEN = Tenured
+PERM_GEN = Permanent
+UNKNOWN_GEN = Unknown
+SOME_GENERATION = {0} Generation
+
+VM_INFO_TAB_GC = GC
+
+VM_GC_TITLE = Garbage Collection in the VM
+VM_GC_COLLECTOR_OVER_GENERATION = Collector {0} running on {1}
+VM_GC_COLLECTOR_CHART_REAL_TIME_LABEL = Time
+VM_GC_COLLECTOR_CHART_GC_TIME_LABEL = GC Time ({0})
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/client-core/src/test/java/com/redhat/thermostat/vm/gc/client/core/VmGcControllerTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,166 @@
+/*
+ * 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.vm.gc.client.core;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isA;
+import static org.mockito.Matchers.isNotNull;
+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.ArrayList;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.Timer;
+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.VmGcStatDAO;
+import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.storage.model.VmGcStat;
+import com.redhat.thermostat.storage.model.VmMemoryStat;
+import com.redhat.thermostat.storage.model.VmMemoryStat.Generation;
+import com.redhat.thermostat.vm.gc.client.core.VmGcController;
+import com.redhat.thermostat.vm.gc.client.core.VmGcView;
+import com.redhat.thermostat.vm.gc.client.core.VmGcViewProvider;
+
+public class VmGcControllerTest {
+
+    private Timer timer;
+    private Runnable timerAction;
+    private VmGcView view;
+    private ActionListener<VmGcView.Action> viewListener;
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Before
+    public void setUp() {
+        ApplicationContextUtil.resetApplicationContext();
+
+        // Setup Timer
+        timer = mock(Timer.class);
+        ArgumentCaptor<Runnable> timerActionCaptor = ArgumentCaptor.forClass(Runnable.class);
+        doNothing().when(timer).setAction(timerActionCaptor.capture());
+
+        TimerFactory timerFactory = mock(TimerFactory.class);
+        when(timerFactory.createTimer()).thenReturn(timer);
+        ApplicationContext.getInstance().setTimerFactory(timerFactory);
+
+        // Set up fake data
+        List<VmGcStat> stats = new ArrayList<>();
+        VmGcStat stat1 = new VmGcStat(42, 1, "collector1", 1, 10);
+        VmGcStat stat2 = new VmGcStat(42, 2, "collector1", 5, 20);
+        stats.add(stat1);
+        stats.add(stat2);
+
+        Generation gen;
+        gen = new Generation();
+        gen.setName("generation 1");
+        gen.setCollector("collector1");
+        VmMemoryStat memoryStat = new VmMemoryStat(1, 42, new Generation[] { gen });
+
+        // Setup DAO
+        VmGcStatDAO vmGcStatDAO = mock(VmGcStatDAO.class);
+        when(vmGcStatDAO.getLatestVmGcStats(isA(VmRef.class), eq(Long.MIN_VALUE))).thenReturn(stats);
+        VmMemoryStatDAO vmMemoryStatDAO = mock(VmMemoryStatDAO.class);
+        when(vmMemoryStatDAO.getLatestMemoryStat(isA(VmRef.class))).thenReturn(memoryStat);
+
+        // Setup View
+        view = mock(VmGcView.class);
+        ArgumentCaptor<ActionListener> viewArgumentCaptor = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(view).addActionListener(viewArgumentCaptor.capture());
+
+        VmGcViewProvider viewProvider = mock(VmGcViewProvider.class);
+        when(viewProvider.createView()).thenReturn(view);
+
+        // Now start the controller
+        VmRef ref = mock(VmRef.class);
+
+        new VmGcController(vmMemoryStatDAO, vmGcStatDAO, ref, viewProvider);
+
+        // Extract relevant objects
+        viewListener = viewArgumentCaptor.getValue();
+        timerAction = timerActionCaptor.getValue();
+    }
+
+    @After
+    public void tearDown() {
+        ApplicationContextUtil.resetApplicationContext();
+    }
+
+    @Test
+    public void verifyTimer() {
+        verify(timer).setAction(isNotNull(Runnable.class));
+        verify(timer).setAction(isA(Runnable.class));
+        verify(timer).setDelay(5);
+        verify(timer).setInitialDelay(0);
+        verify(timer).setTimeUnit(TimeUnit.SECONDS);
+        verify(timer).setSchedulingType(SchedulingType.FIXED_RATE);
+
+    }
+
+    @Test
+    public void verifyStartAndStop() {
+        viewListener.actionPerformed(new ActionEvent<>(view, VmGcView.Action.VISIBLE));
+
+        verify(timer).start();
+
+        viewListener.actionPerformed(new ActionEvent<>(view, VmGcView.Action.HIDDEN));
+
+        verify(timer).stop();
+    }
+
+    @SuppressWarnings("unchecked")
+    @Test
+    public void verifyAction() {
+        timerAction.run();
+
+        verify(view).addData(isA(String.class), isA(List.class));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/client-swing/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-vm-gc</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-vm-gc-client-swing</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat VM GC Swing Client plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Private-Package>com.redhat.thermostat.vm.gc.client.swing</Private-Package>
+            <Bundle-Activator>com.redhat.thermostat.vm.gc.client.swing.Activator</Bundle-Activator>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.vm.gc.client.swing</Bundle-SymbolicName>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <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.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>
+    <dependency>
+      <groupId>org.jfree</groupId>
+      <artifactId>jfreechart</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-gc-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/client-swing/src/main/java/com/redhat/thermostat/vm/gc/client/swing/Activator.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.gc.client.swing;
+
+import java.util.Map;
+import java.util.Objects;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+
+import com.redhat.thermostat.client.core.VmInformationService;
+import com.redhat.thermostat.common.MultipleServiceTracker;
+import com.redhat.thermostat.common.MultipleServiceTracker.Action;
+import com.redhat.thermostat.common.dao.VmGcStatDAO;
+import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
+import com.redhat.thermostat.vm.gc.client.core.VmGcService;
+import com.redhat.thermostat.vm.gc.client.core.VmGcViewProvider;
+
+public class Activator implements BundleActivator {
+    
+    private MultipleServiceTracker tracker;
+    private ServiceRegistration reg;
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+        VmGcViewProvider viewProvider = new SwingVmGcViewProvider();
+        context.registerService(VmGcViewProvider.class.getName(), viewProvider, null);
+
+        Class<?>[] deps = new Class<?>[] {
+            VmMemoryStatDAO.class,
+            VmGcStatDAO.class,
+        };
+
+        tracker = new MultipleServiceTracker(context, deps, new Action() {
+
+            @Override
+            public void dependenciesAvailable(Map<String, Object> services) {
+                VmMemoryStatDAO vmMemoryStatDAO = (VmMemoryStatDAO) services.get(VmMemoryStatDAO.class.getName());
+                Objects.requireNonNull(vmMemoryStatDAO);
+                VmGcStatDAO vmGcStatDAO = (VmGcStatDAO) services.get(VmGcStatDAO.class.getName());
+                Objects.requireNonNull(vmGcStatDAO);
+                VmGcService service = new VmGcService(vmMemoryStatDAO, vmGcStatDAO);
+                reg = context.registerService(VmInformationService.class.getName(), service, null);
+            }
+
+            @Override
+            public void dependenciesUnavailable() {
+                reg.unregister();
+            }
+
+        });
+        tracker.open();
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        tracker.close();
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/client-swing/src/main/java/com/redhat/thermostat/vm/gc/client/swing/SwingVmGcViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.gc.client.swing;
+
+import com.redhat.thermostat.vm.gc.client.core.VmGcView;
+import com.redhat.thermostat.vm.gc.client.core.VmGcViewProvider;
+
+public class SwingVmGcViewProvider implements VmGcViewProvider {
+
+    @Override
+    public VmGcView createView() {
+        return new VmGcPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/client-swing/src/main/java/com/redhat/thermostat/vm/gc/client/swing/VmGcPanel.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.gc.client.swing;
+
+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.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.storage.model.IntervalTimeData;
+import com.redhat.thermostat.vm.gc.client.core.VmGcView;
+import com.redhat.thermostat.vm.gc.client.locale.LocaleResources;
+
+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/vm-gc/client-swing/src/test/java/com/redhat/thermostat/vm/gc/client/swing/ActivatorTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.gc.client.swing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.core.VmInformationService;
+import com.redhat.thermostat.common.dao.VmGcStatDAO;
+import com.redhat.thermostat.common.dao.VmMemoryStatDAO;
+import com.redhat.thermostat.test.StubBundleContext;
+import com.redhat.thermostat.vm.gc.client.core.VmGcService;
+import com.redhat.thermostat.vm.gc.client.core.VmGcViewProvider;
+
+public class ActivatorTest {
+    
+    @Test
+    public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        // View provider registers unconditionally
+        assertEquals(1, context.getAllServices().size());
+        assertNotSame(1, context.getServiceListeners().size());
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+    }
+
+    @Test
+    public void verifyActivatorRegistersServices() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+        VmMemoryStatDAO vmMemoryStatDAO = mock(VmMemoryStatDAO.class);
+        VmGcStatDAO vmGcStatDAO = mock(VmGcStatDAO.class);
+
+        context.registerService(VmMemoryStatDAO.class, vmMemoryStatDAO, null);
+        context.registerService(VmGcStatDAO.class, vmGcStatDAO, null);
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        assertTrue(context.isServiceRegistered(VmInformationService.class.getName(), VmGcService.class));
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+        assertEquals(3, context.getAllServices().size());
+    }
+
+    @Test
+    public void verifyStartRegistersViewProvider() throws Exception {
+        StubBundleContext ctx = new StubBundleContext();
+        Activator activator = new Activator();
+        activator.start(ctx);
+        assertTrue(ctx.isServiceRegistered(VmGcViewProvider.class.getName(), SwingVmGcViewProvider.class));
+        assertEquals(1, ctx.getAllServices().size());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,62 @@
+<?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</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-vm-gc</artifactId>
+  <packaging>pom</packaging>
+
+  <name>Thermostat VM GC plugin</name>
+
+  <modules>
+    <module>client-core</module>
+    <module>client-swing</module>
+    <module>remote-collector-command</module>
+    <module>remote-collector-client-common</module>
+    <module>remote-collector-client-swing</module>
+    <module>remote-collector-common</module>
+  </modules>
+
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-client-common/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,133 @@
+<?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-vm-gc</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-gc-remote-collector-client-common</artifactId>
+  <packaging>bundle</packaging>
+
+  <name>Thermostat GC Plugin Common Client API</name>
+
+  <dependencies>
+    <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>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </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>
+    
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-command</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+        
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-agent-command</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+        
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-gc-remote-collector-common</artifactId>
+      <version>${project.version}</version>
+    </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.gc.remote.client.common</Bundle-SymbolicName>
+            <Bundle-Activator>com.redhat.thermostat.gc.remote.client.common.osgi.GCCommandActivator</Bundle-Activator>
+            <Export-Package>
+                com.redhat.thermostat.gc.remote.client.common,
+                com.redhat.thermostat.gc.remote.common,
+            </Export-Package>
+            <Private-Package>
+                com.redhat.thermostat.gc.remote.client.common.osgi,
+            </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/vm-gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/IconResources.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,51 @@
+/*
+ * 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.gc.remote.client.common;
+
+import com.redhat.thermostat.client.ui.IconDescriptor;
+
+public class IconResources {
+
+    private static IconDescriptor gcIconSmall;
+    
+    public synchronized static IconDescriptor getGCIconSmall() {
+        if (gcIconSmall == null) {
+            gcIconSmall = IconDescriptor.loadIcon("com/redhat/thermostat/gc/remote/client/common/gcSmall.png");
+        }
+        return gcIconSmall;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/LocaleResources.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.gc.remote.client.common;
+
+import com.redhat.thermostat.common.locale.Translate;
+
+public enum LocaleResources {
+
+    PERFORM_GC;
+    
+    static final String RESOURCE_BUNDLE = "com.redhat.thermostat.gc.remote.client.common.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/RequestGCAction.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,62 @@
+/*
+ * 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.gc.remote.client.common;
+
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.ActionNotifier;
+import com.redhat.thermostat.gc.remote.common.command.GCCommand;
+
+public class RequestGCAction {
+    
+    private final ActionNotifier<GCCommand> notifier;
+    
+    public RequestGCAction() {
+        notifier = new ActionNotifier<>(this);
+    }
+    
+    public void addActionListener(ActionListener<GCCommand> listener) {
+        this.notifier.addActionListener(listener);
+    }
+    
+    public void removeActionListener(ActionListener<GCCommand> listener) {
+        this.notifier.removeActionListener(listener);
+    }
+    
+    public void requestGC() {
+        notifier.fireAction(GCCommand.REQUEST_GC);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/client/common/osgi/GCCommandActivator.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.gc.remote.client.common.osgi;
+
+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.command.RequestQueue;
+import com.redhat.thermostat.gc.remote.common.GCRequest;
+
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public class GCCommandActivator implements BundleActivator {
+
+    private ServiceTracker tracker;
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+        tracker = new ServiceTracker(context, RequestQueue.class, null) {
+            @Override
+            public Object addingService(ServiceReference reference) {
+                
+                RequestQueue requestqueue = (RequestQueue) context.getService(reference);
+                
+                GCRequest gcRequest = new GCRequest(requestqueue); 
+                context.registerService(GCRequest.class, gcRequest, null);
+                return super.addingService(reference);
+            }
+            
+            @Override
+            public void removedService(ServiceReference reference, Object service) {
+                
+                context.ungetService(reference);
+                super.removedService(reference, service);
+            }
+        };
+        
+        tracker.open();
+    }
+    
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        tracker.close();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-client-common/src/main/java/com/redhat/thermostat/gc/remote/common/GCRequest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,78 @@
+/*
+ * 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.gc.remote.common;
+
+import java.net.InetSocketAddress;
+
+import com.redhat.thermostat.client.command.RequestQueue;
+import com.redhat.thermostat.common.command.Request;
+import com.redhat.thermostat.common.command.Request.RequestType;
+import com.redhat.thermostat.common.dao.AgentInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.gc.remote.common.command.GCCommand;
+
+public class GCRequest {
+    
+    private RequestQueue queue;
+    public GCRequest(RequestQueue queue) {
+        this.queue = queue;
+    }
+        
+    public void sendGCRequestToAgent(VmRef vm, AgentInfoDAO agentDAO) {
+                
+        HostRef targetHostRef = vm.getAgent();
+
+        String address = agentDAO.getAgentInformation(targetHostRef).getConfigListenAddress();
+        String [] host = address.split(":");
+        
+        InetSocketAddress target = new InetSocketAddress(host[0], Integer.parseInt(host[1]));
+        Request gcRequest = createRequest(target);
+
+        gcRequest.setReceiver(GCCommand.RECEIVER);
+
+        gcRequest.setParameter(GCCommand.class.getName(), GCCommand.REQUEST_GC.name());
+        gcRequest.setParameter(GCCommand.VM_ID, vm.getIdString());
+        
+        queue.putRequest(gcRequest);
+    }
+    
+    // for testing
+    Request createRequest(InetSocketAddress target) {
+        return new Request(RequestType.NO_RESPONSE_EXPECTED, target);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-client-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/strings.properties	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,1 @@
+PERFORM_GC = Perform GC
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-client-common/src/test/java/com/redhat/thermostat/gc/remote/common/GCRequestTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.gc.remote.common;
+
+import static org.junit.Assert.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.verify;
+
+import java.net.InetSocketAddress;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.redhat.thermostat.client.command.RequestQueue;
+import com.redhat.thermostat.common.command.Request;
+import com.redhat.thermostat.common.dao.AgentInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.gc.remote.common.command.GCCommand;
+import com.redhat.thermostat.storage.model.AgentInformation;
+
+public class GCRequestTest {
+
+    private AgentInfoDAO agentDAO;
+    private RequestQueue queue;
+    private VmRef vm;
+
+    private GCRequest gcRequest;
+    private Request request;
+    
+    @Before
+    public void setUp() {
+        agentDAO = mock(AgentInfoDAO.class);
+        vm = mock(VmRef.class);
+
+        request = mock(Request.class);
+        
+        HostRef ref = mock(HostRef.class);        
+        when(vm.getAgent()).thenReturn(ref);
+        when(vm.getIdString()).thenReturn("123456");
+
+        AgentInformation info = mock(AgentInformation.class);
+        when(info.getConfigListenAddress()).thenReturn("0.0.42.42:42");
+        
+        when(agentDAO.getAgentInformation(ref)).thenReturn(info);
+        
+        queue = mock(RequestQueue.class);
+    }
+    
+    @Test
+    public void testSendGCRequestToAgent() {
+        
+        final boolean [] results = new boolean [3];
+        gcRequest = new GCRequest(queue) {
+            @Override
+            Request createRequest(InetSocketAddress target) {
+                results[0] = true;
+                if (target.getHostString().equals("0.0.42.42")) {
+                    results[1] = true;
+                }
+                if (target.getPort() == 42) {
+                    results[2] = true;
+                }
+                
+                return request;
+            }
+        };
+        
+        gcRequest.sendGCRequestToAgent(vm, agentDAO);
+        verify(vm).getAgent();
+        verify(vm).getIdString();
+        
+        assertTrue(results[0]);
+        assertTrue(results[1]);
+        assertTrue(results[2]);
+        
+        verify(request).setReceiver(GCCommand.RECEIVER);
+        verify(request).setParameter(GCCommand.class.getName(), GCCommand.REQUEST_GC.name());
+        verify(request).setParameter(GCCommand.VM_ID, "123456");
+        
+        verify(queue).putRequest(request);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-client-swing/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,148 @@
+<?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-vm-gc</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-gc-remote-collector-client-swing</artifactId>
+  <packaging>bundle</packaging>
+
+  <name>Thermostat GC Plugin Swing Client</name>
+
+  <dependencies>
+    <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>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </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>
+    
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-gc-remote-collector-client-common</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>
+    
+  </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.gc.remote.client.swing</Bundle-SymbolicName>
+            <Export-Package>
+              com.redhat.thermostat.gc.remote.client.swing,
+            </Export-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/vm-gc/remote-collector-client-swing/src/main/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButton.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,82 @@
+/*
+ * 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.gc.remote.client.swing;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.ImageIcon;
+
+import com.redhat.thermostat.client.swing.components.ActionButton;
+import com.redhat.thermostat.common.locale.Translate;
+
+import com.redhat.thermostat.gc.remote.client.common.IconResources;
+import com.redhat.thermostat.gc.remote.client.common.LocaleResources;
+import com.redhat.thermostat.gc.remote.client.common.RequestGCAction;
+
+@SuppressWarnings("serial")
+public class ToolbarGCButton extends ActionButton {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+    
+    private RequestGCAction action;
+    public ToolbarGCButton(RequestGCAction action) {
+        this(action, translator.localize(LocaleResources.PERFORM_GC));
+    }
+    
+    private ToolbarGCButton(RequestGCAction action, String text) {
+        super(new ImageIcon(IconResources.getGCIconSmall().getData().array()), text);
+        
+        setToolTipText(text);
+        this.action = action;
+        
+        addActionListener(new ToolbarGCButtonActionlistener());
+    }
+    
+    private class ToolbarGCButtonActionlistener implements ActionListener {
+        @Override
+        public void actionPerformed(ActionEvent e) {            
+            Thread actionThread = new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    action.requestGC();
+                }
+            }, "ToolbarGCButton.ToolbarGCButtonActionlistener.RequestGCAction");
+            actionThread.start();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-client-swing/src/test/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButtonTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.gc.remote.client.swing;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import java.awt.Dimension;
+import java.util.prefs.BackingStoreException;
+import java.util.prefs.Preferences;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner;
+
+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.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.redhat.thermostat.client.swing.components.HeaderPanel;
+import com.redhat.thermostat.gc.remote.client.common.RequestGCAction;
+
+@RunWith(CacioFESTRunner.class)
+public class ToolbarGCButtonTest {
+
+    private JFrame frame;
+    private FrameFixture frameFixture;
+    private ToolbarGCButton gcButton;
+        
+    private RequestGCAction action;
+    
+    @BeforeClass
+    public static void setUpOnce() {
+        FailOnThreadViolationRepaintManager.install();
+    }
+    
+    @Before
+    public void setUp() {
+        
+        final Preferences prefs = mock(Preferences.class);
+        
+        action = mock(RequestGCAction.class);
+        
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                frame = new JFrame();
+                
+                HeaderPanel header = new HeaderPanel(prefs, "Test Panel");
+                header.setName("headerPanel");
+                
+                JPanel content = new JPanel();
+                content.setName("contentPanel");
+                
+                header.setContent(content);
+               
+                gcButton = new ToolbarGCButton(action);
+                gcButton.setName("gcButton");
+                header.addToolBarButton(gcButton);
+                
+                frame.getContentPane().add(header);
+                
+                frame.setMinimumSize(new Dimension(800, 300));
+            }
+        });
+        frameFixture = new FrameFixture(frame);
+    }
+    
+    @After
+    public void tearDown() throws BackingStoreException {
+        frameFixture.cleanUp();
+        frameFixture = null;
+    }
+    
+    @Test
+    public void testEventDelivered() throws InterruptedException {
+        frameFixture.show();
+        
+        JButtonFixture button = frameFixture.button("gcButton");
+        button.requireVisible();
+        
+        button.click();
+        
+        // timing dependent test...
+        Thread.sleep(250);
+        
+        verify(action).requestGC();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-command/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,120 @@
+<?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-vm-gc</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-gc-remote-collector-command</artifactId>
+  <packaging>bundle</packaging>
+
+  <name>Thermostat GC Plugin Command Channel</name>
+
+  <dependencies>
+    <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>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </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>
+    
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-gc-remote-collector-common</artifactId>
+      <version>${project.version}</version>      
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-agent-core</artifactId>
+      <version>${project.version}</version>      
+    </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.gc.remote.command</Bundle-SymbolicName>
+            <Bundle-Activator>com.redhat.thermostat.gc.remote.command.osgi.GCCommandReceiverActivator</Bundle-Activator>            
+            <Export-Package>
+              com.redhat.thermostat.gc.remote.command,
+            </Export-Package>
+            <Private-Package>
+                com.redhat.thermostat.gc.remote.command.osgi,
+                com.redhat.thermostat.gc.remote.command.internal,
+            </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/vm-gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/GCCommandReceiver.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.gc.remote.command;
+
+import com.redhat.thermostat.agent.command.RequestReceiver;
+import com.redhat.thermostat.common.command.Request;
+import com.redhat.thermostat.common.command.Response;
+import com.redhat.thermostat.common.command.Response.ResponseType;
+import com.redhat.thermostat.gc.remote.command.internal.GC;
+import com.redhat.thermostat.gc.remote.common.command.GCCommand;
+import com.redhat.thermostat.utils.management.MXBeanConnector;
+
+public class GCCommandReceiver implements RequestReceiver {
+
+    @Override
+    public Response receive(Request request) {
+        
+        String command = request.getParameter(GCCommand.class.getName());
+        switch (GCCommand.valueOf(command)) {
+        case REQUEST_GC:
+            String vmId = request.getParameter(GCCommand.VM_ID);
+            MXBeanConnector connector = new MXBeanConnector(vmId);
+            new GC(connector).gc();
+            break;
+        
+        default:
+            break;
+        }
+        return new Response(ResponseType.OK);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/internal/GC.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,92 @@
+/*
+ * 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.gc.remote.command.internal;
+
+import java.lang.management.ManagementFactory;
+import java.lang.management.MemoryMXBean;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.redhat.thermostat.utils.management.MXBeanConnection;
+import com.redhat.thermostat.utils.management.MXBeanConnector;
+
+public class GC {
+
+    private static final Logger logger = Logger.getLogger(GC.class.getSimpleName());
+
+    private MXBeanConnector connector;
+    public GC(MXBeanConnector connector) {
+        this.connector = connector;
+    }
+    
+    public void gc() {
+        boolean closeAfter = false;
+        if (!connector.isAttached()) {
+            closeAfter = true; 
+            try {
+                connector.attach();
+
+            } catch (Exception ex) {
+                logger.log(Level.SEVERE, "can't attach", ex);
+                if (closeAfter) {
+                    closeConnection();
+                }
+            }
+        }
+        
+        try (MXBeanConnection connection = connector.connect()) {
+
+            MemoryMXBean bean = connection.createProxy(ManagementFactory.MEMORY_MXBEAN_NAME, MemoryMXBean.class);
+            bean.gc();
+
+        } catch (Exception ex) {
+            logger.log(Level.SEVERE, "can't get MXBeanConnection connection", ex);
+        }
+        
+        if (closeAfter) {
+            closeConnection();
+        }
+    }
+    
+    private void closeConnection() {
+        try {
+            connector.close();
+        } catch (Exception ex) {
+            logger.log(Level.SEVERE, "can't close connection to vm", ex);
+        }
+    }    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-command/src/main/java/com/redhat/thermostat/gc/remote/command/osgi/GCCommandReceiverActivator.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,56 @@
+/*
+ * 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.gc.remote.command.osgi;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+import com.redhat.thermostat.agent.command.ReceiverRegistry;
+import com.redhat.thermostat.gc.remote.command.GCCommandReceiver;
+
+public class GCCommandReceiverActivator implements BundleActivator {
+
+    @Override
+    public void start(BundleContext context) throws Exception {
+        ReceiverRegistry registry = new ReceiverRegistry(context);
+        registry.registerReceiver(new GCCommandReceiver());
+    }
+    
+    @Override
+    public void stop(BundleContext context) throws Exception {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-common/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,122 @@
+<?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-vm-gc</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-gc-remote-collector-common</artifactId>
+  <packaging>bundle</packaging>
+
+  <name>Thermostat Remote GC Plugin Common Client API</name>
+
+  <dependencies>
+    <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>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </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>
+    
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-command</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+        
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-agent-command</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+        
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-core</artifactId>
+      <version>${project.version}</version>
+    </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.gc.remote.common.command</Bundle-SymbolicName>
+            <Export-Package>
+                com.redhat.thermostat.gc.remote.common.command
+            </Export-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/vm-gc/remote-collector-common/src/main/java/com/redhat/thermostat/gc/remote/common/command/GCCommand.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,45 @@
+/*
+ * 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.gc.remote.common.command;
+
+public enum GCCommand {
+
+    REQUEST_GC;
+    
+    public static final String VM_ID = "VM_ID";
+    public static final String RECEIVER = "com.redhat.thermostat.gc.remote.command.GCCommandReceiver";
+}
Binary file vm-gc/remote-collector-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/gcSmall.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-gc/remote-collector-common/src/main/resources/com/redhat/thermostat/gc/remote/client/common/strings.properties	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,1 @@
+PERFORM_GC = Perform GC
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/client-core/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-vm-overview</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-vm-overview-client-core</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat VM Overview Core Client plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Private-Package></Private-Package>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.vm.overview.client.core</Bundle-SymbolicName>
+            <Export-Package>
+              com.redhat.thermostat.vm.overview.client.core,
+              com.redhat.thermostat.vm.overview.client.locale
+            </Export-Package>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <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.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>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/client-core/src/main/java/com/redhat/thermostat/vm/overview/client/core/VmOverviewController.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.overview.client.core;
+
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.concurrent.TimeUnit;
+
+import com.redhat.thermostat.client.core.controllers.VmInformationServiceController;
+import com.redhat.thermostat.client.core.views.BasicView.Action;
+import com.redhat.thermostat.client.core.views.UIComponent;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.NotImplementedException;
+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.dao.VmInfoDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.storage.model.VmInfo;
+import com.redhat.thermostat.vm.overview.client.locale.LocaleResources;
+
+public class VmOverviewController implements VmInformationServiceController {
+
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+
+    private final VmRef ref;
+    private final VmInfoDAO dao;
+    private final DateFormat vmRunningTimeFormat;
+
+    private final Timer timer;
+
+    private final VmOverviewView view;
+
+    public VmOverviewController(VmInfoDAO vmDao, VmRef vmRef, VmOverviewViewProvider provider) {
+        this.ref = vmRef;
+        this.view = provider.createView();
+
+        dao = vmDao;
+        timer = ApplicationContext.getInstance().getTimerFactory().createTimer();
+
+        vmRunningTimeFormat = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.FULL);
+
+        view.addActionListener(new ActionListener<Action>() {
+            @Override
+            public void actionPerformed(ActionEvent<Action> actionEvent) {
+                switch(actionEvent.getActionId()) {
+                    case HIDDEN:
+                        stop();
+                        break;
+                    case VISIBLE:
+                        start();
+                        break;
+                    default:
+                        throw new NotImplementedException("unknown event: " + actionEvent.getActionId());
+                }
+            }
+        });
+
+        timer.setAction(new Runnable() {
+
+            @Override
+            public void run() {
+                VmInfo info = dao.getVmInfo(ref);
+                view.setVmPid(((Integer) info.getVmPid()).toString());
+                long actualStartTime = info.getStartTimeStamp();
+                view.setVmStartTimeStamp(vmRunningTimeFormat.format(new Date(actualStartTime)));
+                long actualStopTime = info.getStopTimeStamp();
+                if (actualStopTime >= actualStartTime) {
+                    // Only show a stop time if we have actually stopped.
+                    view.setVmStopTimeStamp(vmRunningTimeFormat.format(new Date(actualStopTime)));
+                } else {
+                    view.setVmStopTimeStamp(translator.localize(LocaleResources.VM_INFO_RUNNING));
+                }
+                view.setJavaVersion(info.getJavaVersion());
+                view.setJavaHome(info.getJavaHome());
+                view.setMainClass(info.getMainClass());
+                view.setJavaCommandLine(info.getJavaCommandLine());
+                String actualVmName = info.getVmName();
+                String actualVmVersion = info.getVmVersion();
+                String actualVmInfo = info.getVmInfo();
+                view.setVmNameAndVersion(translator.localize(LocaleResources.VM_INFO_VM_NAME_AND_VERSION,
+                        actualVmName, actualVmVersion, actualVmInfo));
+                view.setVmArguments(info.getVmArguments());
+            }
+        });
+        timer.setInitialDelay(0);
+        timer.setDelay(5);
+        timer.setTimeUnit(TimeUnit.SECONDS);
+        timer.setSchedulingType(SchedulingType.FIXED_RATE);
+    }
+
+    private void start() {
+        timer.start();
+    }
+
+    private void stop() {
+        timer.stop();
+    }
+
+    public UIComponent getView() {
+        return (UIComponent) view;
+    }
+
+    @Override
+    public String getLocalizedName() {
+        return translator.localize(LocaleResources.VM_INFO_TAB_OVERVIEW);
+    }
+    
+    /*
+     * For testing purposes only.
+     */
+    DateFormat getDateFormat() {
+        return vmRunningTimeFormat;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/client-core/src/main/java/com/redhat/thermostat/vm/overview/client/core/VmOverviewService.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.overview.client.core;
+
+import com.redhat.thermostat.client.core.VmFilter;
+import com.redhat.thermostat.client.core.VmInformationService;
+import com.redhat.thermostat.client.core.controllers.VmInformationServiceController;
+import com.redhat.thermostat.client.osgi.service.AlwaysMatchFilter;
+import com.redhat.thermostat.common.dao.VmInfoDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.utils.OSGIUtils;
+
+public class VmOverviewService implements VmInformationService {
+    
+    private static final VmFilter FILTER = new AlwaysMatchFilter();
+    
+    private VmInfoDAO vmInfoDAO;
+    
+    public VmOverviewService(VmInfoDAO vmInfoDAO) {
+        this.vmInfoDAO = vmInfoDAO;
+    }
+
+    @Override
+    public VmInformationServiceController getInformationServiceController(
+            VmRef ref) {
+        VmOverviewViewProvider provider = OSGIUtils.getInstance().getService(VmOverviewViewProvider.class);
+        return new VmOverviewController(vmInfoDAO, ref, provider);
+    }
+
+    @Override
+    public VmFilter getFilter() {
+        return FILTER;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/client-core/src/main/java/com/redhat/thermostat/vm/overview/client/core/VmOverviewView.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,63 @@
+/*
+ * 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.vm.overview.client.core;
+
+import com.redhat.thermostat.client.core.views.BasicView;
+import com.redhat.thermostat.client.core.views.UIComponent;
+
+
+public abstract class VmOverviewView extends BasicView implements UIComponent {
+
+    public abstract void setVmPid(String pid);
+
+    public abstract void setVmStartTimeStamp(String timestamp);
+
+    public abstract void setVmStopTimeStamp(String timeStamp);
+
+    public abstract void setMainClass(String mainClass);
+
+    public abstract void setJavaCommandLine(String javaCommandLine);
+
+    public abstract void setJavaHome(String string);
+
+    public abstract void setJavaVersion(String javaVersion);
+
+    public abstract void setVmNameAndVersion(String vmNameAndVersion);
+
+    public abstract void setVmArguments(String vmArguments);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/client-core/src/main/java/com/redhat/thermostat/vm/overview/client/core/VmOverviewViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,46 @@
+/*
+ * 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.vm.overview.client.core;
+
+import com.redhat.thermostat.client.core.views.ViewProvider;
+
+public interface VmOverviewViewProvider extends ViewProvider {
+
+    @Override
+    public VmOverviewView createView();
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/client-core/src/main/java/com/redhat/thermostat/vm/overview/client/locale/LocaleResources.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.overview.client.locale;
+
+import com.redhat.thermostat.common.locale.Translate;
+
+public enum LocaleResources {
+    VM_INFO_TAB_OVERVIEW,
+    
+    VM_INFO_TITLE,
+    VM_INFO_SECTION_PROCESS,
+    VM_INFO_SECTION_JAVA,
+
+    VM_INFO_PROCESS_ID,
+    VM_INFO_START_TIME,
+    VM_INFO_STOP_TIME,
+    VM_INFO_RUNNING,
+    VM_INFO_MAIN_CLASS,
+    VM_INFO_COMMAND_LINE,
+    VM_INFO_JAVA_VERSION,
+    VM_INFO_VM,
+    VM_INFO_VM_ARGUMENTS,
+    VM_INFO_VM_NAME_AND_VERSION,
+    VM_INFO_PROPERTIES,
+    VM_INFO_ENVIRONMENT,
+    VM_INFO_LIBRARIES,
+    ;
+
+    static final String RESOURCE_BUNDLE =
+            "com.redhat.thermostat.vm.overview.client.locale.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/client-core/src/main/resources/com/redhat/thermostat/vm/overview/client/locale/strings.properties	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,19 @@
+VM_INFO_TAB_OVERVIEW = Overview
+
+VM_INFO_TITLE = Virtual Machine Overview
+VM_INFO_SECTION_PROCESS = Process Information
+VM_INFO_SECTION_JAVA = Java Information
+
+VM_INFO_PROCESS_ID = Process Id
+VM_INFO_START_TIME = Start time
+VM_INFO_STOP_TIME = Stop time
+VM_INFO_RUNNING = Running
+VM_INFO_MAIN_CLASS = Main Class
+VM_INFO_COMMAND_LINE = Command Line
+VM_INFO_JAVA_VERSION = Java Version
+VM_INFO_VM = Virtual Machine
+VM_INFO_VM_ARGUMENTS = VM arguments
+VM_INFO_VM_NAME_AND_VERSION = {0} version {1}
+VM_INFO_PROPERTIES = Properties
+VM_INFO_ENVIRONMENT = Environment
+VM_INFO_LIBRARIES = Native Libraries
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/client-core/src/test/java/com/redhat/thermostat/vm/overview/client/core/VmOverviewControllerTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,181 @@
+/*
+ * 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.vm.overview.client.core;
+
+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.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.text.DateFormat;
+import java.util.Collections;
+import java.util.Date;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import com.redhat.thermostat.client.core.views.BasicView.Action;
+import com.redhat.thermostat.common.ActionEvent;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.Timer;
+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.VmInfoDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.storage.model.VmInfo;
+import com.redhat.thermostat.vm.overview.client.locale.LocaleResources;
+
+public class VmOverviewControllerTest {
+    private static final Translate<LocaleResources> translator = LocaleResources.createLocalizer();
+    
+    private static final int VM_PID = 1337;
+    private static final long START_TIME = 10000;
+    private static final long STOP_TIME = 20000;
+    private static final String JAVA_VERSION = "1.2000.1";
+    private static final String JAVA_HOME = "/path/to/java";
+    private static final String MAIN_CLASS = "Main";
+    private static final String COMMAND_LINE = "java Main command line args";
+    private static final String VM_NAME = "MyCoolJVM";
+    private static final String VM_INFO = "Info about MyCoolJVM";
+    private static final String VM_VERSION = "1.0";
+    private static final String VM_ARGS = "-Dvar=arg -DotherVar=otherArg";
+    private static final Map<String, String> PROPS = Collections.emptyMap();
+    private static final Map<String, String> ENV = Collections.emptyMap();
+    private static final String[] LIBS = new String[0];
+
+    private Timer timer;
+    private Runnable timerAction;
+    private VmOverviewView view;
+    private ActionListener<VmOverviewView.Action> listener;
+    private VmOverviewController controller;
+
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    @Before
+    public void setUp() {
+        ApplicationContextUtil.resetApplicationContext();
+
+        // Setup timer
+        timer = mock(Timer.class);
+        ArgumentCaptor<Runnable> timerActionCaptor = ArgumentCaptor
+                .forClass(Runnable.class);
+        doNothing().when(timer).setAction(timerActionCaptor.capture());
+
+        TimerFactory timerFactory = mock(TimerFactory.class);
+        when(timerFactory.createTimer()).thenReturn(timer);
+        ApplicationContext.getInstance().setTimerFactory(timerFactory);
+
+        // Setup DAOs
+        VmInfo vmInfo = new VmInfo(VM_PID, START_TIME, STOP_TIME, JAVA_VERSION,
+                JAVA_HOME, MAIN_CLASS, COMMAND_LINE, VM_NAME, VM_INFO,
+                VM_VERSION, VM_ARGS, PROPS, ENV, LIBS);
+
+        VmRef ref = mock(VmRef.class);
+
+        VmInfoDAO vmInfoDao = mock(VmInfoDAO.class);
+        when(vmInfoDao.getVmInfo(any(VmRef.class))).thenReturn(vmInfo);
+
+        // Setup View
+        ArgumentCaptor<ActionListener> listenerCaptor = ArgumentCaptor
+                .forClass(ActionListener.class);
+        view = mock(VmOverviewView.class);
+        doNothing().when(view).addActionListener(listenerCaptor.capture());
+        VmOverviewViewProvider viewProvider = mock(VmOverviewViewProvider.class);
+        when(viewProvider.createView()).thenReturn(view);
+
+        controller = new VmOverviewController(vmInfoDao, ref, viewProvider);
+
+        listener = listenerCaptor.getValue();
+        timerAction = timerActionCaptor.getValue();
+    }
+
+    @After
+    public void tearDown() {
+        ApplicationContextUtil.resetApplicationContext();
+    }
+
+    @Test
+    public void verifyViewIsUpdatedWithData() {
+        timerAction.run();
+
+        DateFormat timestampFormat = controller.getDateFormat();
+        verify(view).setVmPid(eq(String.valueOf(VM_PID)));
+        verify(view).setVmStartTimeStamp(eq(timestampFormat.format(new Date(START_TIME))));
+        verify(view).setVmStopTimeStamp(eq(timestampFormat.format(new Date(STOP_TIME))));
+        verify(view).setJavaVersion(eq(JAVA_VERSION));
+        verify(view).setJavaHome(eq(JAVA_HOME));
+        verify(view).setMainClass(eq(MAIN_CLASS));
+        verify(view).setJavaCommandLine(eq(COMMAND_LINE));
+        
+        verify(view).setVmNameAndVersion(eq(translator.localize(LocaleResources.VM_INFO_VM_NAME_AND_VERSION,
+                        VM_NAME, VM_VERSION, VM_INFO)));
+        verify(view).setVmArguments(eq(VM_ARGS));
+    }
+
+    @Test
+    public void verifyTimerIsSetUpCorrectly() {
+        assertNotNull(timer);
+
+        verify(timer).setAction(isNotNull(Runnable.class));
+        verify(timer).setDelay(5);
+        verify(timer).setTimeUnit(TimeUnit.SECONDS);
+        verify(timer).setInitialDelay(0);
+        verify(timer).setSchedulingType(SchedulingType.FIXED_RATE);
+    }
+
+    @Test
+    public void verifyTimerRunsWhenNeeded() {
+        listener.actionPerformed(new ActionEvent<>(view, Action.VISIBLE));
+
+        verify(timer).start();
+
+        listener.actionPerformed(new ActionEvent<>(view, Action.HIDDEN));
+
+        verify(timer).stop();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/client-swing/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<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-vm-overview</artifactId>
+    <groupId>com.redhat.thermostat</groupId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+  <artifactId>thermostat-vm-overview-client-swing</artifactId>
+  <packaging>bundle</packaging>
+  <name>Thermostat VM Overview Swing Client plugin</name>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix</groupId>
+        <artifactId>maven-bundle-plugin</artifactId>
+        <extensions>true</extensions>
+        <configuration>
+          <instructions>
+            <Private-Package>com.redhat.thermostat.vm.overview.client.swing</Private-Package>
+            <Bundle-Activator>com.redhat.thermostat.vm.overview.client.swing.Activator</Bundle-Activator>
+            <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
+            <Bundle-SymbolicName>com.redhat.thermostat.vm.overview.client.swing</Bundle-SymbolicName>
+            <!-- Do not autogenerate uses clauses in Manifests -->
+            <_nouses>true</_nouses>
+          </instructions>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+  <dependencies>
+    <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.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>
+    <dependency>
+      <groupId>org.jfree</groupId>
+      <artifactId>jfreechart</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-common-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-client-swing</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>com.redhat.thermostat</groupId>
+      <artifactId>thermostat-vm-overview-client-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+  </dependencies>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/client-swing/src/main/java/com/redhat/thermostat/vm/overview/client/swing/Activator.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.overview.client.swing;
+
+import java.util.Objects;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.util.tracker.ServiceTracker;
+
+import com.redhat.thermostat.client.core.VmInformationService;
+import com.redhat.thermostat.common.dao.VmInfoDAO;
+import com.redhat.thermostat.vm.overview.client.core.VmOverviewService;
+import com.redhat.thermostat.vm.overview.client.core.VmOverviewViewProvider;
+
+public class Activator implements BundleActivator {
+    
+    private ServiceTracker tracker;
+    private ServiceRegistration reg;
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+        VmOverviewViewProvider viewProvider = new SwingVmOverviewViewProvider();
+        context.registerService(VmOverviewViewProvider.class.getName(), viewProvider, null);
+
+        tracker = new ServiceTracker(context, VmInfoDAO.class.getName(), null) {
+            
+            @Override
+            public Object addingService(ServiceReference reference) {
+                VmInfoDAO vmInfoDAO = (VmInfoDAO) context.getService(reference);
+                Objects.requireNonNull(vmInfoDAO);
+                VmOverviewService service = new VmOverviewService(vmInfoDAO);
+                reg = context.registerService(VmInformationService.class.getName(), service, null);
+                
+                return super.addingService(reference);
+            }
+
+            @Override
+            public void removedService(ServiceReference reference, Object service) {
+                context.ungetService(reference);
+                reg.unregister();
+            }
+        };
+        tracker.open();
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        tracker.close();
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/client-swing/src/main/java/com/redhat/thermostat/vm/overview/client/swing/ChangeableText.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.overview.client.swing;
+
+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/vm-overview/client-swing/src/main/java/com/redhat/thermostat/vm/overview/client/swing/SimpleTable.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,291 @@
+/*
+ * 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.vm.overview.client.swing;
+
+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.components.Components;
+import com.redhat.thermostat.client.swing.components.ValueField;
+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/vm-overview/client-swing/src/main/java/com/redhat/thermostat/vm/overview/client/swing/SwingVmOverviewViewProvider.java	Wed Nov 28 12:28:04 2012 +0100
@@ -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.vm.overview.client.swing;
+
+import com.redhat.thermostat.vm.overview.client.core.VmOverviewView;
+import com.redhat.thermostat.vm.overview.client.core.VmOverviewViewProvider;
+
+public class SwingVmOverviewViewProvider implements VmOverviewViewProvider {
+
+    @Override
+    public VmOverviewView createView() {
+        return new VmOverviewPanel();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/client-swing/src/main/java/com/redhat/thermostat/vm/overview/client/swing/VmOverviewPanel.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,186 @@
+/*
+ * 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.vm.overview.client.swing;
+
+import java.awt.Component;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JPanel;
+
+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.ui.ComponentVisibleListener;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.locale.Translate;
+import com.redhat.thermostat.vm.overview.client.core.VmOverviewView;
+import com.redhat.thermostat.vm.overview.client.locale.LocaleResources;
+import com.redhat.thermostat.vm.overview.client.swing.SimpleTable.Section;
+import com.redhat.thermostat.vm.overview.client.swing.SimpleTable.TableEntry;
+
+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 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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/client-swing/src/test/java/com/redhat/thermostat/vm/overview/client/swing/ActivatorTest.java	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,100 @@
+/*
+ * 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.vm.overview.client.swing;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.core.VmInformationService;
+import com.redhat.thermostat.common.dao.VmInfoDAO;
+import com.redhat.thermostat.test.StubBundleContext;
+import com.redhat.thermostat.vm.overview.client.core.VmOverviewService;
+import com.redhat.thermostat.vm.overview.client.core.VmOverviewViewProvider;
+import com.redhat.thermostat.vm.overview.client.swing.Activator;
+import com.redhat.thermostat.vm.overview.client.swing.SwingVmOverviewViewProvider;
+
+public class ActivatorTest {
+    
+    @Test
+    public void verifyActivatorDoesNotRegisterServiceOnMissingDeps() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        // View provider registers unconditionally
+        assertEquals(1, context.getAllServices().size());
+        assertEquals(1, context.getServiceListeners().size());
+        
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+    }
+
+    @Test
+    public void verifyActivatorRegistersServices() throws Exception {
+        StubBundleContext context = new StubBundleContext();
+        VmInfoDAO vmInfoDAO = mock(VmInfoDAO.class);
+
+        context.registerService(VmInfoDAO.class, vmInfoDAO, null);
+
+        Activator activator = new Activator();
+
+        activator.start(context);
+
+        assertTrue(context.isServiceRegistered(VmInformationService.class.getName(), VmOverviewService.class));
+
+        activator.stop(context);
+
+        assertEquals(0, context.getServiceListeners().size());
+        assertEquals(2, context.getAllServices().size());
+    }
+
+    @Test
+    public void verifyStartRegistersViewProvider() throws Exception {
+        StubBundleContext ctx = new StubBundleContext();
+        Activator activator = new Activator();
+        activator.start(ctx);
+        assertTrue(ctx.isServiceRegistered(VmOverviewViewProvider.class.getName(), SwingVmOverviewViewProvider.class));
+        assertEquals(1, ctx.getAllServices().size());
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-overview/pom.xml	Wed Nov 28 12:28:04 2012 +0100
@@ -0,0 +1,58 @@
+<?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</artifactId>
+    <version>0.5.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>thermostat-vm-overview</artifactId>
+  <packaging>pom</packaging>
+
+  <name>Thermostat VM Overview plugin</name>
+
+  <modules>
+    <module>client-core</module>
+    <module>client-swing</module>
+  </modules>
+
+</project>