changeset 367:5b8da5a49f21

Cleanup client-core directories reviewed-by: vanaltj review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-June/001806.html
author Mario Torre <neugens.limasoftware@gmail.com>
date Tue, 12 Jun 2012 21:26:04 +0200
parents 7c12420ae95a
children 48431d04e664
files client/core/pom.xml client/core/src/main/java/com/redhat/thermostat/client/AgentConfigurationSource.java client/core/src/main/java/com/redhat/thermostat/client/ApplicationInfo.java client/core/src/main/java/com/redhat/thermostat/client/ChangeableText.java client/core/src/main/java/com/redhat/thermostat/client/ClientArgs.java client/core/src/main/java/com/redhat/thermostat/client/DefaultViewFactory.java client/core/src/main/java/com/redhat/thermostat/client/GUIClientCommand.java client/core/src/main/java/com/redhat/thermostat/client/HostPanelFacade.java client/core/src/main/java/com/redhat/thermostat/client/HostPanelFacadeImpl.java client/core/src/main/java/com/redhat/thermostat/client/HostsVMsLoader.java client/core/src/main/java/com/redhat/thermostat/client/Main.java client/core/src/main/java/com/redhat/thermostat/client/MainView.java client/core/src/main/java/com/redhat/thermostat/client/MainWindowController.java client/core/src/main/java/com/redhat/thermostat/client/MainWindowControllerImpl.java client/core/src/main/java/com/redhat/thermostat/client/MenuRegistry.java client/core/src/main/java/com/redhat/thermostat/client/RegistryFactory.java client/core/src/main/java/com/redhat/thermostat/client/SwingViewFactory.java client/core/src/main/java/com/redhat/thermostat/client/ThermostatExtensionRegistry.java client/core/src/main/java/com/redhat/thermostat/client/UiFacadeFactory.java client/core/src/main/java/com/redhat/thermostat/client/UiFacadeFactoryImpl.java client/core/src/main/java/com/redhat/thermostat/client/VMTreeDecoratorRegistry.java client/core/src/main/java/com/redhat/thermostat/client/VMTreeFilterRegistry.java client/core/src/main/java/com/redhat/thermostat/client/config/ConnectionConfiguration.java client/core/src/main/java/com/redhat/thermostat/client/internal/AgentConfigurationSource.java client/core/src/main/java/com/redhat/thermostat/client/internal/ApplicationInfo.java client/core/src/main/java/com/redhat/thermostat/client/internal/ChangeableText.java client/core/src/main/java/com/redhat/thermostat/client/internal/ClientArgs.java client/core/src/main/java/com/redhat/thermostat/client/internal/DefaultViewFactory.java client/core/src/main/java/com/redhat/thermostat/client/internal/GUIClientCommand.java client/core/src/main/java/com/redhat/thermostat/client/internal/HostPanelFacade.java client/core/src/main/java/com/redhat/thermostat/client/internal/HostPanelFacadeImpl.java client/core/src/main/java/com/redhat/thermostat/client/internal/HostsVMsLoader.java client/core/src/main/java/com/redhat/thermostat/client/internal/Main.java client/core/src/main/java/com/redhat/thermostat/client/internal/MainView.java client/core/src/main/java/com/redhat/thermostat/client/internal/MainWindowController.java client/core/src/main/java/com/redhat/thermostat/client/internal/MainWindowControllerImpl.java client/core/src/main/java/com/redhat/thermostat/client/internal/MenuRegistry.java client/core/src/main/java/com/redhat/thermostat/client/internal/RegistryFactory.java client/core/src/main/java/com/redhat/thermostat/client/internal/SwingViewFactory.java client/core/src/main/java/com/redhat/thermostat/client/internal/ThermostatExtensionRegistry.java client/core/src/main/java/com/redhat/thermostat/client/internal/UiFacadeFactory.java client/core/src/main/java/com/redhat/thermostat/client/internal/UiFacadeFactoryImpl.java client/core/src/main/java/com/redhat/thermostat/client/internal/VMTreeDecoratorRegistry.java client/core/src/main/java/com/redhat/thermostat/client/internal/VMTreeFilterRegistry.java client/core/src/main/java/com/redhat/thermostat/client/internal/config/ConnectionConfiguration.java client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ApplicationServiceProvider.java client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ContextActionServiceProvider.java client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ThermostatActivator.java client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/VMContextActionServiceTracker.java client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/VmInformationServiceTracker.java client/core/src/main/java/com/redhat/thermostat/client/internal/ui/swing/AboutDialog.java client/core/src/main/java/com/redhat/thermostat/client/internal/ui/swing/WrapLayout.java client/core/src/main/java/com/redhat/thermostat/client/osgi/ApplicationServiceProvider.java client/core/src/main/java/com/redhat/thermostat/client/osgi/ContextActionServiceProvider.java client/core/src/main/java/com/redhat/thermostat/client/osgi/ThermostatActivator.java client/core/src/main/java/com/redhat/thermostat/client/osgi/VMContextActionServiceTracker.java client/core/src/main/java/com/redhat/thermostat/client/osgi/VmInformationServiceTracker.java client/core/src/main/java/com/redhat/thermostat/client/ui/AboutDialog.java client/core/src/main/java/com/redhat/thermostat/client/ui/AgentConfigurationModel.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostMemoryPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostOverviewPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/MainWindow.java client/core/src/main/java/com/redhat/thermostat/client/ui/SimpleTable.java client/core/src/main/java/com/redhat/thermostat/client/ui/VmInformationController.java client/core/src/main/java/com/redhat/thermostat/client/ui/VmOverviewPanel.java client/core/src/main/java/com/redhat/thermostat/client/ui/WrapLayout.java client/core/src/test/java/com/redhat/thermostat/client/DefaultViewFactoryTest.java client/core/src/test/java/com/redhat/thermostat/client/GUIClientCommandTest.java client/core/src/test/java/com/redhat/thermostat/client/MainWindowControllerImplTest.java client/core/src/test/java/com/redhat/thermostat/client/MenuRegistryTest.java client/core/src/test/java/com/redhat/thermostat/client/SwingViewFactoryTest.java client/core/src/test/java/com/redhat/thermostat/client/internal/DefaultViewFactoryTest.java client/core/src/test/java/com/redhat/thermostat/client/internal/GUIClientCommandTest.java client/core/src/test/java/com/redhat/thermostat/client/internal/MainWindowControllerImplTest.java client/core/src/test/java/com/redhat/thermostat/client/internal/MenuRegistryTest.java client/core/src/test/java/com/redhat/thermostat/client/internal/SwingViewFactoryTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/MainWindowTest.java
diffstat 78 files changed, 3901 insertions(+), 3882 deletions(-) [+]
line wrap: on
line diff
--- a/client/core/pom.xml	Tue Jun 12 14:02:16 2012 -0400
+++ b/client/core/pom.xml	Tue Jun 12 21:26:04 2012 +0200
@@ -142,16 +142,18 @@
         <configuration>
           <instructions>
             <Bundle-Vendor>Red Hat, Inc.</Bundle-Vendor>
-            <Bundle-Activator>com.redhat.thermostat.client.osgi.ThermostatActivator</Bundle-Activator>
+            <Bundle-Activator>com.redhat.thermostat.client.internal.osgi.ThermostatActivator</Bundle-Activator>
             <Export-Package>
               com.redhat.thermostat.client.osgi.service,
               com.redhat.thermostat.client.ui,
               com.redhat.thermostat.client.locale
             </Export-Package>
             <Private-Package>
-              com.redhat.thermostat.client,
-              com.redhat.thermostat.client.config,
-              com.redhat.thermostat.client.osgi,
+              com.redhat.thermostat.client.internal,
+              com.redhat.thermostat.client.internal.config,
+              com.redhat.thermostat.client.internal.osgi,
+              com.redhat.thermostat.client.internal.ui,
+              com.redhat.thermostat.client.internal.ui.swing
             </Private-Package>
           </instructions>
         </configuration>
--- a/client/core/src/main/java/com/redhat/thermostat/client/AgentConfigurationSource.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class AgentConfigurationSource {
-
-    // FIXME fix this properly
-
-    public List<String> getKnownAgents() {
-        return Arrays.asList(new String[] { "Agent Smith", "Agent Jones", "Agent Brown" });
-    }
-
-    public Map<String, Boolean> getAgentBackends(String agentName) {
-        Map<String, Boolean> fake = new HashMap<>();
-        fake.put("Monitor New JVMs", true);
-        fake.put("Use up all my CPU Cycles", false);
-        return fake;
-    }
-
-    public void updateAgentConfig(String agentName, Map<String, Boolean> newBackendStatus) {
-        // TODO Auto-generated method stub
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ApplicationInfo.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +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;
-
-import static com.redhat.thermostat.client.locale.Translate.localize;
-
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Properties;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.Icon;
-
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.client.ui.IconResource;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-
-public class ApplicationInfo {
-
-    private static final Logger logger = LoggingUtils.getLogger(ApplicationInfo.class);
-
-    private Properties appInfo;
-
-    public ApplicationInfo() {
-        appInfo = new Properties();
-        // the properties file should be in the same package as this class
-        InputStream res = getClass().getResourceAsStream("app-info.properties");
-        if (res != null) {
-            try {
-                appInfo.load(res);
-            } catch (IOException e) {
-                logger.log(Level.WARNING, "error loading application information", e);
-            }
-        }
-    }
-
-    public String getName() {
-        return appInfo.getProperty("APP_NAME", localize(LocaleResources.MISSING_INFO));
-    }
-
-    public String getVersion() {
-        return appInfo.getProperty("APP_VERSION", localize(LocaleResources.MISSING_INFO));
-    }
-
-    public String getDescription() {
-        return localize(LocaleResources.APPLICATION_INFO_DESCRIPTION);
-    }
-
-    public Icon getIcon() {
-        String path = appInfo.getProperty("APP_ICON");
-        if (new File(path).exists()) {
-            return IconResource.fromPath(path).getIcon();
-        }
-        return IconResource.QUESTION.getIcon();
-    }
-
-    public String getReleaseDate() {
-        return appInfo.getProperty("APP_RELEASE_DATE", localize(LocaleResources.MISSING_INFO));
-    }
-
-    public String getCopyright() {
-        return appInfo.getProperty("APP_COPYRIGHT", localize(LocaleResources.MISSING_INFO));
-    }
-
-    public String getLicenseSummary() {
-        return localize(LocaleResources.APPLICATION_INFO_LICENSE);
-    }
-
-    public String getEmail() {
-        return appInfo.getProperty("APP_EMAIL", localize(LocaleResources.MISSING_INFO));
-    }
-
-    public String getWebsite() {
-        return appInfo.getProperty("APP_WEBSITE", localize(LocaleResources.MISSING_INFO));
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ChangeableText.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import java.util.HashSet;
-import java.util.Set;
-
-public class ChangeableText {
-
-    private final Set<TextListener> listeners = new HashSet<TextListener>();
-    private String text;
-
-    public static interface TextListener {
-        public void textChanged(ChangeableText text);
-    }
-
-    public ChangeableText(String text) {
-        this.text = text;
-    }
-
-    public synchronized void setText(String text) {
-        if (this.text.equals(text)) {
-            return;
-        }
-        this.text = text;
-        fireChanged();
-    }
-
-    public synchronized String getText() {
-        return text;
-    }
-
-    public synchronized void addListener(TextListener listener) {
-        this.listeners.add(listener);
-    }
-
-    public synchronized void removeListener(TextListener listener) {
-        this.listeners.remove(listener);
-    }
-
-    private void fireChanged() {
-        for (TextListener listener: listeners) {
-            listener.textChanged(this);
-        }
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ClientArgs.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,57 +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;
-
-public class ClientArgs {
-
-    private boolean isDebugLayout = Boolean.getBoolean("thermostat.debug-layout");
-
-    public ClientArgs(String[] args) {
-        for (int i=0; i < args.length; i++) {
-            if (args[i].equals("--debug-layout")) {
-                isDebugLayout = true;
-            }
-        }
-        // TODO what other arguments do we care about?
-        // perhaps skipping the mode selection?
-    }
-
-    public boolean isDebugLayout() {
-        return isDebugLayout;
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/DefaultViewFactory.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.redhat.thermostat.common.View;
-import com.redhat.thermostat.common.ViewFactory;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-
-public class DefaultViewFactory implements ViewFactory {
-
-    private static final Logger logger = LoggingUtils.getLogger(SwingViewFactory.class);
-    private final Map<Class<?>, Class<?>> lookupTable = Collections.synchronizedMap(new HashMap<Class<?>, Class<?>>());
-
-    @Override
-    public <T extends View> T getView(Class<T> viewClass) {
-        Class<? extends T> klass = getViewClass(viewClass);
-        if (klass == null) {
-            logger.log(Level.WARNING, "no view class registered for " + viewClass.toString());
-            return null;
-        }
-
-        try {
-            return klass.newInstance();
-        } catch (InstantiationException | IllegalAccessException e) {
-            logger.log(Level.WARNING, "error instantiaitng" + klass);
-            return null;
-        }
-    }
-
-    @Override
-    public <T extends View> Class<? extends T> getViewClass(Class<T> viewClass) {
-        // the cast is safe because the only way to insert an entry into the table is through
-        // a method that enforces this constraint
-        @SuppressWarnings("unchecked")
-        Class<? extends T> result = (Class<? extends T>) lookupTable.get(viewClass);
-        return result;
-    }
-
-    @Override
-    public <T extends View> void setViewClass(Class<T> viewClass, Class<? extends T> implClass) {
-        lookupTable.put(viewClass, implClass);
-    }
-
-}
\ No newline at end of file
--- a/client/core/src/main/java/com/redhat/thermostat/client/GUIClientCommand.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +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;
-
-import java.util.Collection;
-import java.util.Collections;
-
-import org.osgi.framework.BundleContext;
-
-import com.redhat.thermostat.client.osgi.ApplicationServiceProvider;
-import com.redhat.thermostat.client.osgi.ContextActionServiceProvider;
-import com.redhat.thermostat.client.osgi.service.ApplicationService;
-import com.redhat.thermostat.client.osgi.service.ContextAction;
-import com.redhat.thermostat.common.cli.ArgumentSpec;
-import com.redhat.thermostat.common.cli.Command;
-import com.redhat.thermostat.common.cli.CommandContext;
-import com.redhat.thermostat.common.cli.CommandException;
-
-public class GUIClientCommand implements Command {
-
-    private Main clientMain;
-
-    public GUIClientCommand(Main clientMain) {
-        this.clientMain = clientMain;
-    }
-
-    @Override
-    public void run(CommandContext ctx) throws CommandException {
-        BundleContext context = ctx.getCommandContextFactory().getBundleContext();
-        context.registerService(ApplicationService.class.getName(), new ApplicationServiceProvider(), null);
-        context.registerService(ContextAction.class.getName(), new ContextActionServiceProvider(), null);
-        
-        // this blocks, everything else needs to be done before
-        clientMain.run();
-    }
-
-    @Override
-    public void disable() {
-        // TODO clientMain.shutdown();
-    }
-
-    @Override
-    public String getName() {
-        return "gui";
-    }
-
-    @Override
-    public String getDescription() {
-        return "launches the GUI client";
-    }
-
-    @Override
-    public String getUsage() {
-        return getDescription();
-    }
-
-    @Override
-    public Collection<ArgumentSpec> getAcceptedArguments() {
-        return Collections.emptyList();
-    }
-
-    @Override
-    public boolean isStorageRequired() {
-        return false;
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/HostPanelFacade.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import com.redhat.thermostat.client.ui.HostCpuController;
-import com.redhat.thermostat.client.ui.HostMemoryController;
-import com.redhat.thermostat.client.ui.HostOverviewController;
-
-public interface HostPanelFacade  {
-
-    public HostOverviewController getOverviewController();
-
-    public HostCpuController getCpuController();
-
-    public HostMemoryController getMemoryController();
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/HostPanelFacadeImpl.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import com.redhat.thermostat.client.ui.HostCpuController;
-import com.redhat.thermostat.client.ui.HostMemoryController;
-import com.redhat.thermostat.client.ui.HostOverviewController;
-import com.redhat.thermostat.common.dao.HostRef;
-
-public class HostPanelFacadeImpl implements HostPanelFacade {
-
-    private final HostOverviewController overviewController;
-    private final HostCpuController cpuController;
-    private final HostMemoryController memoryController;
-
-    public HostPanelFacadeImpl(HostRef ref) {
-        overviewController = new HostOverviewController(ref);
-        cpuController = new HostCpuController(ref);
-        memoryController = new HostMemoryController(ref);
-    }
-
-    @Override
-    public HostOverviewController getOverviewController() {
-        return overviewController;
-    }
-
-    @Override
-    public HostCpuController getCpuController() {
-        return cpuController;
-    }
-
-    @Override
-    public HostMemoryController getMemoryController() {
-        return memoryController;
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/HostsVMsLoader.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,51 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import java.util.Collection;
-
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.VmRef;
-
-/**
- * Provides a way to load the current hosts and VMs.
- */
-public interface HostsVMsLoader {
-
-    Collection<HostRef> getHosts();
-    Collection<VmRef> getVMs(HostRef host);
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/Main.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,187 +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;
-
-import static com.redhat.thermostat.client.locale.Translate.localize;
-
-import java.awt.EventQueue;
-import java.awt.Window;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.JFrame;
-import javax.swing.JOptionPane;
-import javax.swing.JPopupMenu;
-import javax.swing.UIManager;
-import javax.swing.UnsupportedLookAndFeelException;
-
-import com.redhat.swing.laf.dolphin.DolphinLookAndFeel;
-import com.redhat.thermostat.client.config.ConnectionConfiguration;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.client.ui.ConnectionSelectionDialog;
-import com.redhat.thermostat.client.ui.LayoutDebugHelper;
-import com.redhat.thermostat.common.Constants;
-import com.redhat.thermostat.common.ThreadPoolTimerFactory;
-import com.redhat.thermostat.common.TimerFactory;
-import com.redhat.thermostat.common.appctx.ApplicationContext;
-import com.redhat.thermostat.common.config.ClientPreferences;
-import com.redhat.thermostat.common.config.StartupConfiguration;
-import com.redhat.thermostat.common.dao.DAOFactory;
-import com.redhat.thermostat.common.dao.MongoDAOFactory;
-import com.redhat.thermostat.common.storage.Connection;
-import com.redhat.thermostat.common.storage.Connection.ConnectionListener;
-import com.redhat.thermostat.common.storage.Connection.ConnectionStatus;
-import com.redhat.thermostat.common.storage.MongoStorageProvider;
-import com.redhat.thermostat.common.storage.StorageProvider;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-
-public class Main {
-
-    private static final Logger logger = LoggingUtils.getLogger(Main.class);
-
-    private ClientArgs arguments;
-    private UiFacadeFactory uiFacadeFactory;
-
-    public Main(UiFacadeFactory uiFacadeFactory, String[] args) {
-        this.uiFacadeFactory = uiFacadeFactory;
-        try {
-            this.arguments = new ClientArgs(args);
-        } catch (IllegalArgumentException ex) {
-            logger.log(Level.SEVERE, "Bad arguments to Thermostat client.", ex);
-            System.exit(-1);
-        }
-
-        ClientPreferences prefs = new ClientPreferences();
-        StartupConfiguration config = new ConnectionConfiguration(prefs);
-
-        StorageProvider connProv = new MongoStorageProvider(config);
-        DAOFactory daoFactory = new MongoDAOFactory(connProv);
-        ApplicationContext.getInstance().setDAOFactory(daoFactory);
-        TimerFactory timerFactory = new ThreadPoolTimerFactory(1);
-        ApplicationContext.getInstance().setTimerFactory(timerFactory);
-        SwingViewFactory viewFactory = new SwingViewFactory();
-        ApplicationContext.getInstance().setViewFactory(viewFactory);
-    }
-
-    void run() {
-        EventQueue.invokeLater(new Runnable() {
-
-            @Override
-            public void run() {
-                
-                try {
-                    UIManager.setLookAndFeel(new DolphinLookAndFeel());
-                } catch (UnsupportedLookAndFeelException e) {
-                    logger.log(Level.WARNING, "cannot use DolphinLookAndFeel");
-                }
-                
-                showGui();
-            }
-            
-        });
-        
-        try {
-            uiFacadeFactory.awaitShutdown();
-        } catch (InterruptedException e) {
-            Thread.currentThread().interrupt();
-        }
-    }
-
-    private void showGui() {
-        
-        JPopupMenu.setDefaultLightWeightPopupEnabled(false);
-
-        Connection connection = ApplicationContext.getInstance().getDAOFactory().getConnection();
-        ConnectionSelectionDialog dialog = new ConnectionSelectionDialog((JFrame) null, connection);
-        dialog.pack();
-        dialog.setModal(true);
-        dialog.setVisible(true);
-
-        if (dialog.isCancelled()) {
-            return;
-        }
-
-        ConnectionListener connectionListener = new ConnectionListener() {
-            @Override
-            public void changed(ConnectionStatus newStatus) {
-                if (newStatus == ConnectionStatus.FAILED_TO_CONNECT) {
-                    JOptionPane.showMessageDialog(
-                            null,
-                            localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_DESCRIPTION),
-                            localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_TITLE),
-                            JOptionPane.ERROR_MESSAGE);
-                    System.exit(Constants.EXIT_UNABLE_TO_CONNECT_TO_DATABASE);
-                }
-            }
-        };
-
-        connection.addListener(connectionListener);
-        connection.connect();
-        connection.removeListener(connectionListener);
-
-        MainWindowController mainController = uiFacadeFactory.getMainWindow();
-        mainController.showMainMainWindow();
-
-        if (arguments.isDebugLayout()) {
-            Thread layoutDebugger = new Thread(new Runnable() {
-                @Override
-                public void run() {
-                    LayoutDebugHelper helper = new LayoutDebugHelper();
-                    try {
-                        while (true) {
-                            Thread.sleep(5000);
-                            Window[] windows = Window.getWindows();
-                            for (Window w : windows) {
-                                helper.debugLayout(w);
-                                w.invalidate();
-                                w.repaint();
-                            }
-                        }
-                    } catch (InterruptedException ie) {
-                        logger.log(Level.INFO, "layout debug helper interrupted; exiting", ie);
-                        // mark thread as interrupted
-                        Thread.currentThread().interrupt();
-                    }
-                }
-            });
-            layoutDebugger.setDaemon(true);
-            layoutDebugger.start();
-        }
-
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/MainView.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +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;
-
-import java.awt.Component;
-import java.awt.event.MouseEvent;
-import java.util.List;
-
-import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
-import com.redhat.thermostat.client.osgi.service.VMContextAction;
-import com.redhat.thermostat.client.osgi.service.Filter;
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.dao.Ref;
-
-public interface MainView {
-
-    enum Action {
-        VISIBLE,
-        HIDDEN,
-        HOST_VM_TREE_FILTER,
-        HOST_VM_SELECTION_CHANGED,
-        SHOW_AGENT_CONFIG,
-        SHOW_CLIENT_CONFIG,
-        SWITCH_HISTORY_MODE,
-        SHOW_ABOUT_DIALOG,
-        SHUTDOWN,
-        SHOW_VM_CONTEXT_MENU,
-        VM_CONTEXT_ACTION,
-    }
-
-    void addActionListener(ActionListener<Action> capture);
-
-    void updateTree(List<Filter> filter, List<ReferenceDecorator> decorators, HostsVMsLoader any);
-    String getHostVmTreeFilterText();
-    
-    void setWindowTitle(String title);
-
-    void showMainWindow();
-
-    void hideMainWindow();
-
-    Ref getSelectedHostOrVm();
-
-    void setSubView(Component view);
-
-    void addMenu(String parentMenuName, MenuAction action);
-
-    void removeMenu(String parentMenuName, MenuAction action);
-
-    void showVMContextActions(List<VMContextAction> actions, MouseEvent e);
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/MainWindowController.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,46 +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;
-
-
-public interface MainWindowController {
-
-    public void setHostVmTreeFilter(String filter);
-
-    public void showMainMainWindow();
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/MainWindowControllerImpl.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,467 +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;
-
-import java.awt.event.MouseEvent;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.TimeUnit;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-
-import com.redhat.thermostat.client.MainView.Action;
-import com.redhat.thermostat.client.osgi.service.Filter;
-import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
-import com.redhat.thermostat.client.osgi.service.VMContextAction;
-import com.redhat.thermostat.client.ui.AboutDialog;
-import com.redhat.thermostat.client.ui.AgentConfigurationController;
-import com.redhat.thermostat.client.ui.AgentConfigurationModel;
-import com.redhat.thermostat.client.ui.AgentConfigurationView;
-import com.redhat.thermostat.client.ui.ClientConfigurationController;
-import com.redhat.thermostat.client.ui.ClientConfigurationView;
-import com.redhat.thermostat.client.ui.HostInformationController;
-import com.redhat.thermostat.client.ui.SummaryController;
-import com.redhat.thermostat.client.ui.VmInformationController;
-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.appctx.ApplicationContext;
-import com.redhat.thermostat.common.config.ClientPreferences;
-import com.redhat.thermostat.common.dao.DAOFactory;
-import com.redhat.thermostat.common.dao.HostInfoDAO;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.Ref;
-import com.redhat.thermostat.common.dao.VmInfoDAO;
-import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-
-public class MainWindowControllerImpl implements MainWindowController {
-
-    private static final Logger logger = LoggingUtils.getLogger(MainWindowControllerImpl.class);
-    
-    private List<Filter> vmTreefilters;
-    private List<ReferenceDecorator> vmTreeDecorators;
-    
-    private Timer backgroundUpdater;
-
-    private MainView view;
-
-    private String filter;
-
-    private final HostInfoDAO hostsDAO;
-    private final VmInfoDAO vmsDAO;
-
-    private ApplicationInfo appInfo;
-
-    private UiFacadeFactory facadeFactory;
-    private MenuRegistry menuRegistry;
-    private MenuRegistry.MenuListener menuListener = new MenuRegistry.MenuListener() {
-
-        @Override
-        public void removed(String parentMenuName, MenuAction action) {
-            view.removeMenu(parentMenuName, action);
-        }
-
-        @Override
-        public void added(String parentMenuName, MenuAction action) {
-            view.addMenu(parentMenuName, action);
-        }
-    };
-
-    // FIXME: sort out the code duplication in the registry listeners
-    
-    private TreeViewFilter treeFilter;
-    private VMTreeFilterRegistry filterRegistry;
-    private ActionListener<ThermostatExtensionRegistry.Action> filterListener =
-            new ActionListener<ThermostatExtensionRegistry.Action>()
-    {
-        @Override
-        public void actionPerformed(ActionEvent<com.redhat.thermostat.client.ThermostatExtensionRegistry.Action>
-                                    actionEvent)
-        {
-            Filter filter = (Filter) actionEvent.getPayload();
-            
-            switch (actionEvent.getActionId()) {
-            case SERVICE_ADDED:
-                vmTreefilters.add(filter);
-                doUpdateTreeAsync();
-                break;
-            
-            case SERVICE_REMOVED:
-                vmTreefilters.remove(filter);
-                doUpdateTreeAsync();
-                break;
-                
-            default:
-                logger.log(Level.WARNING, "received unknown event from VMTreeFilterRegistry: " +
-                                           actionEvent.getActionId());
-                break;
-            }
-        }
-    };
-    
-    private VMTreeDecoratorRegistry decoratorRegistry;
-    private ActionListener<ThermostatExtensionRegistry.Action> decoratorListener =
-            new ActionListener<ThermostatExtensionRegistry.Action> ()
-    {
-        public void actionPerformed(com.redhat.thermostat.common.ActionEvent<ThermostatExtensionRegistry.Action>
-                                    actionEvent)
-        {
-            ReferenceDecorator decorator = (ReferenceDecorator) actionEvent.getPayload();
-            switch (actionEvent.getActionId()) {
-            case SERVICE_ADDED:
-                vmTreeDecorators.add(decorator);
-                doUpdateTreeAsync();
-                break;
-            
-            case SERVICE_REMOVED:
-                vmTreeDecorators.remove(decorator);
-                doUpdateTreeAsync();
-                break;
-                
-            default:
-                logger.log(Level.WARNING, "received unknown event from ReferenceDecorator: " +
-                                           actionEvent.getActionId());
-                break;
-            }
-        };
-    };
-    
-    private boolean showHistory;
-
-    private VmInformationControllerProvider vmInfoControllerProvider;
-
-    public MainWindowControllerImpl(UiFacadeFactory facadeFactory, MainView view, RegistryFactory registryFactory)
-    {
-        try {
-            filterRegistry = registryFactory.createVMTreeFilterRegistry();
-            decoratorRegistry = registryFactory.createVMTreeDecoratorRegistry();
-            menuRegistry = registryFactory.createMenuRegistry();
-            
-        } catch (InvalidSyntaxException e) {
-            throw new RuntimeException(e);
-        }
-
-        vmTreeDecorators = new CopyOnWriteArrayList<>();
-        
-        vmTreefilters = new CopyOnWriteArrayList<>();
-        treeFilter = new TreeViewFilter();
-        vmTreefilters.add(treeFilter);
-        
-        this.facadeFactory = facadeFactory;
-
-        ApplicationContext ctx = ApplicationContext.getInstance();
-        DAOFactory daoFactory = ctx.getDAOFactory();
-        hostsDAO = daoFactory.getHostInfoDAO();
-        vmsDAO = daoFactory.getVmInfoDAO();
-
-        initView(view);
-
-        vmInfoControllerProvider = new VmInformationControllerProvider();
-
-        appInfo = new ApplicationInfo();
-        view.setWindowTitle(appInfo.getName());
-        initializeTimer();
-
-        updateView();
-
-        menuRegistry.addMenuListener(menuListener);
-        menuRegistry.start();
-        
-        filterRegistry.addActionListener(filterListener);
-        filterRegistry.start();
-        
-        decoratorRegistry.addActionListener(decoratorListener);
-        decoratorRegistry.start();
-    }
-
-    private class HostsVMsLoaderImpl implements HostsVMsLoader {
-
-        @Override
-        public Collection<HostRef> getHosts() {
-            if (showHistory) {
-                return hostsDAO.getHosts();
-            } else {
-                return hostsDAO.getAliveHosts();
-            }
-        }
-
-        @Override
-        public Collection<VmRef> getVMs(HostRef host) {
-            return vmsDAO.getVMs(host);
-        }
-
-    }
-
-    /**
-     * This method is for testing purpouse only
-     */
-    Filter getTreeFilter() {
-        return treeFilter;
-    }
-    
-    /**
-     * This method is for testing purpouse only
-     */ 
-    List<ReferenceDecorator> getVmTreeDecorators() {
-        return vmTreeDecorators;
-    }
-    
-    /**
-     * This method is for testing purpouse only
-     */
-    MenuRegistry.MenuListener getMenuListener() {
-        return menuListener;
-    }
-    
-    private void initializeTimer() {
-        ApplicationContext ctx = ApplicationContext.getInstance();
-        backgroundUpdater = ctx.getTimerFactory().createTimer();
-        backgroundUpdater.setAction(new Runnable() {
-            @Override
-            public void run() {
-                doUpdateTreeAsync();
-            }
-        });
-        backgroundUpdater.setInitialDelay(0);
-        backgroundUpdater.setDelay(3);
-        backgroundUpdater.setTimeUnit(TimeUnit.SECONDS);
-        backgroundUpdater.setSchedulingType(SchedulingType.FIXED_RATE);
-    }
-
-    private void startBackgroundUpdates() {
-        backgroundUpdater.start();
-    }
-
-    public void stopBackgroundUpdates() {
-        backgroundUpdater.stop();
-    }
-
-    private class TreeViewFilter implements Filter {
-        @Override
-        public boolean matches(Ref ref) {
-            if (filter == null || filter.isEmpty()) {
-                return true;
-                
-            } else {
-                return matches(ref, filter);                
-            }
-        }
-      
-        public boolean matches(Ref ref, String filter) {
-          return ref.getName().contains(filter) || ref.getStringID().contains(filter);
-        }
-    }
-    
-    @Override
-    public void setHostVmTreeFilter(String filter) {
-        this.filter = filter;
-        doUpdateTreeAsync();
-    }
-
-    public void doUpdateTreeAsync() {
-        HostsVMsLoader loader = new HostsVMsLoaderImpl();
-        view.updateTree(vmTreefilters, vmTreeDecorators, loader);
-    }
-
-    private void initView(MainView mainView) {
-        this.view = mainView;
-        mainView.addActionListener(new ActionListener<MainView.Action>() {
-
-            @Override
-            public void actionPerformed(ActionEvent<MainView.Action> evt) {
-                MainView.Action action = evt.getActionId();
-                switch (action) {
-                case VISIBLE:
-                    startBackgroundUpdates();
-                    break;
-                case HIDDEN:
-                    stopBackgroundUpdates();
-                    break;
-                case HOST_VM_SELECTION_CHANGED:
-                    updateView();
-                    break;
-                case HOST_VM_TREE_FILTER:
-                    String filter = view.getHostVmTreeFilterText();
-                    setHostVmTreeFilter(filter);
-                    break;
-                case SHOW_AGENT_CONFIG:
-                    showAgentConfiguration();
-                    break;
-                case SHOW_CLIENT_CONFIG:
-                    showConfigureClientPreferences();
-                    break;
-                case SWITCH_HISTORY_MODE:
-                    switchHistoryMode();
-                    break;
-                case SHOW_ABOUT_DIALOG:
-                    showAboutDialog();
-                    break;
-                case SHOW_VM_CONTEXT_MENU:
-                    showContextMenu(evt);
-                    break;
-                case VM_CONTEXT_ACTION:
-                    handleVMHooks(evt);
-                    break;
-                case SHUTDOWN:
-                    shutdownApplication();
-                    break;
-                default:
-                    throw new IllegalStateException("unhandled action");
-                }
-            }
-
-        });
-    }
-
-    private void shutdownApplication() {
-        menuRegistry.removeMenuListener(menuListener);
-        menuListener = null;
-        menuRegistry.stop();
-
-        view.hideMainWindow();
-        ApplicationContext.getInstance().getTimerFactory().shutdown();
-        shutdownOSGiFramework();
-    }
-
-    private void shutdownOSGiFramework() {
-        facadeFactory.shutdown();
-    }
-
-    private void showContextMenu(ActionEvent<Action> evt) {
-        List<VMContextAction> toShow = new ArrayList<>();
-        VmRef vm = (VmRef) view.getSelectedHostOrVm();
-
-        logger.log(Level.INFO, "registering applicable VMContextActions actions to show");
-
-        for (VMContextAction action : facadeFactory.getVMContextActions()) {
-            if (action.getFilter().matches(vm)) {
-                toShow.add(action);
-            }
-        }
-
-        view.showVMContextActions(toShow, (MouseEvent)evt.getPayload());
-    }
-
-    private void handleVMHooks(ActionEvent<MainView.Action> event) {
-        Object payload = event.getPayload();
-        if (payload instanceof VMContextAction) { 
-            try {
-                VMContextAction action = (VMContextAction) payload;
-                action.execute((VmRef) view.getSelectedHostOrVm());
-            } catch (Throwable error) {
-                logger.log(Level.SEVERE, "");
-            }
-        }
-    }
-    
-    @Override
-    public void showMainMainWindow() {
-        view.showMainWindow();
-    }
-
-    private void showAboutDialog() {
-        AboutDialog aboutDialog = new AboutDialog(appInfo);
-        aboutDialog.setModal(true);
-        aboutDialog.pack();
-        aboutDialog.setVisible(true);
-    }
-
-    private void showAgentConfiguration() {
-        AgentConfigurationSource agentPrefs = new AgentConfigurationSource();
-        AgentConfigurationModel model = new AgentConfigurationModel(agentPrefs);
-        AgentConfigurationView view = ApplicationContext.getInstance().getViewFactory().getView(AgentConfigurationView.class);
-        AgentConfigurationController controller = new AgentConfigurationController(model, view);
-        controller.showView();
-    }
-
-    private void showConfigureClientPreferences() {
-        ClientPreferences prefs = new ClientPreferences();
-        ClientConfigurationView view = ApplicationContext.getInstance().getViewFactory().getView(ClientConfigurationView.class);
-        ClientConfigurationController controller = new ClientConfigurationController(prefs, view);
-        controller.showDialog();
-    }
-
-    private void switchHistoryMode() {
-        showHistory = !showHistory;
-        doUpdateTreeAsync();
-    }
-
-    private void updateView() {
-        // this is quite an ugly method. there must be a cleaner way to do this
-        Ref ref = view.getSelectedHostOrVm();
-
-        if (ref == null) {
-            SummaryController controller = new SummaryController();
-            view.setSubView(controller.getComponent());
-        } else if (ref instanceof HostRef) {
-            HostRef hostRef = (HostRef) ref;
-            HostInformationController hostController = facadeFactory.getHostController(hostRef);
-            view.setSubView(hostController.getComponent());
-        } else if (ref instanceof VmRef) {
-            VmRef vmRef = (VmRef) ref;
-            VmInformationController vmInformation =
-                    vmInfoControllerProvider.getVmInfoController(vmRef);
-            view.setSubView(vmInformation.getComponent());
-        } else {
-            throw new IllegalArgumentException("unknown type of ref");
-        }
-    }
-
-    private class VmInformationControllerProvider {
-        private VmInformationController lastSelectedVM;
-
-        VmInformationController getVmInfoController(VmRef vmRef) {
-            int id = 0;
-            if (lastSelectedVM != null) {
-                id = lastSelectedVM.getSelectedChildID();
-            }
-            lastSelectedVM = facadeFactory.getVmController(vmRef);
-            lastSelectedVM.selectChildID(id);
-
-            return lastSelectedVM;
-        }
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/MenuRegistry.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,142 +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;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.concurrent.CopyOnWriteArrayList;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-
-import com.redhat.thermostat.client.osgi.service.MenuAction;
-
-public class MenuRegistry {
-
-    public static interface MenuListener {
-
-        public void added(String parentMenuName, MenuAction action);
-
-        public void removed(String parentMenuName, MenuAction action);
-    }
-
-    public static final String PARENT_MENU = "parentMenu";
-
-    private static final String FILTER = "(&(" + Constants.OBJECTCLASS + "=" + MenuAction.class.getName() + ")(" + PARENT_MENU + "=*))";
-
-    private ServiceTracker menuTracker;
-
-    private Map<String,List<MenuAction>> menus = new HashMap<>();
-    private List<MenuListener> listeners = new CopyOnWriteArrayList<>();
-
-    public MenuRegistry(BundleContext context) throws InvalidSyntaxException {
-        menuTracker = new ServiceTracker(context, FrameworkUtil.createFilter(FILTER), null) {
-            @Override
-            public Object addingService(ServiceReference reference) {
-                MenuAction action = (MenuAction) super.addingService(reference);
-                String parentMenuName = (String) reference.getProperty(PARENT_MENU);
-                menuAdded(parentMenuName, action);
-                return action;
-            }
-
-            @Override
-            public void removedService(ServiceReference reference, Object service) {
-                if (!(service instanceof MenuAction)) {
-                    throw new AssertionError("removing a non-MenuAction service");
-                }
-                String parentMenuName = (String) reference.getProperty(PARENT_MENU);
-                menuRemoved(parentMenuName, (MenuAction)service);
-                super.removedService(reference, service);
-            }
-        };
-    }
-
-    public void start() {
-        menuTracker.open();
-    }
-
-    public void stop() {
-        menuTracker.close();
-    }
-
-    public void addMenuListener(MenuListener listener) {
-        listeners.add(listener);
-
-        for (Entry<String,List<MenuAction>> entry: menus.entrySet()) {
-            for (MenuAction action: entry.getValue()) {
-                listener.added(entry.getKey(), action);
-            }
-        }
-    }
-
-    public void removeMenuListener(MenuListener listener) {
-        listeners.remove(listener);
-    }
-
-    private void menuAdded(String parentMenuName, MenuAction action) {
-        if (!menus.containsKey(parentMenuName)) {
-            menus.put(parentMenuName, new ArrayList<MenuAction>());
-        }
-        List<MenuAction> list = menus.get(parentMenuName);
-        list.add(action);
-        for (MenuListener listener: listeners) {
-            listener.added(parentMenuName, action);
-        }
-    }
-
-    private void menuRemoved(String parentMenuName, MenuAction action) {
-        if (!menus.containsKey(parentMenuName)) {
-            throw new IllegalArgumentException("unknown parent menu name");
-        }
-        List<MenuAction> list = menus.get(parentMenuName);
-        if (!list.contains(action)) {
-            throw new IllegalArgumentException("unknown menu action");
-        }
-
-        list.remove(action);
-        for (MenuListener listener: listeners) {
-            listener.removed(parentMenuName, action);
-        }
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/RegistryFactory.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-
-class RegistryFactory {
-
-    private BundleContext context;
-    RegistryFactory(BundleContext context) {
-        this.context = context;
-    }
-    
-    VMTreeDecoratorRegistry createVMTreeDecoratorRegistry() throws InvalidSyntaxException {
-        return new VMTreeDecoratorRegistry(context);
-    }
-    
-    VMTreeFilterRegistry createVMTreeFilterRegistry() throws InvalidSyntaxException {
-        return new VMTreeFilterRegistry(context);
-    }
-    
-    MenuRegistry createMenuRegistry() throws InvalidSyntaxException {
-        return new MenuRegistry(context);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/SwingViewFactory.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,112 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.concurrent.Callable;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import com.redhat.thermostat.client.ui.AgentConfigurationFrame;
-import com.redhat.thermostat.client.ui.AgentConfigurationView;
-import com.redhat.thermostat.client.ui.ClientConfigurationFrame;
-import com.redhat.thermostat.client.ui.ClientConfigurationView;
-import com.redhat.thermostat.client.ui.EdtHelper;
-import com.redhat.thermostat.client.ui.HostCpuPanel;
-import com.redhat.thermostat.client.ui.HostCpuView;
-import com.redhat.thermostat.client.ui.HostInformationPanel;
-import com.redhat.thermostat.client.ui.HostInformationView;
-import com.redhat.thermostat.client.ui.HostMemoryPanel;
-import com.redhat.thermostat.client.ui.HostMemoryView;
-import com.redhat.thermostat.client.ui.HostOverviewPanel;
-import com.redhat.thermostat.client.ui.HostOverviewView;
-import com.redhat.thermostat.client.ui.SummaryPanel;
-import com.redhat.thermostat.client.ui.SummaryView;
-import com.redhat.thermostat.client.ui.VmCpuPanel;
-import com.redhat.thermostat.client.ui.VmCpuView;
-import com.redhat.thermostat.client.ui.VmGcPanel;
-import com.redhat.thermostat.client.ui.VmGcView;
-import com.redhat.thermostat.client.ui.VmInformationPanel;
-import com.redhat.thermostat.client.ui.VmInformationView;
-import com.redhat.thermostat.client.ui.VmOverviewPanel;
-import com.redhat.thermostat.client.ui.VmOverviewView;
-import com.redhat.thermostat.common.View;
-import com.redhat.thermostat.common.ViewFactory;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-
-public class SwingViewFactory extends DefaultViewFactory implements ViewFactory {
-
-    private static final Logger logger = LoggingUtils.getLogger(SwingViewFactory.class);
-
-    public SwingViewFactory() {
-        setViewClass(AgentConfigurationView.class, AgentConfigurationFrame.class);
-        setViewClass(ClientConfigurationView.class, ClientConfigurationFrame.class);
-
-        setViewClass(SummaryView.class, SummaryPanel.class);
-
-        setViewClass(HostInformationView.class, HostInformationPanel.class);
-        setViewClass(VmInformationView.class, VmInformationPanel.class);
-
-        setViewClass(HostCpuView.class, HostCpuPanel.class);
-        setViewClass(HostMemoryView.class, HostMemoryPanel.class);
-        setViewClass(HostOverviewView.class, HostOverviewPanel.class);
-
-        setViewClass(VmCpuView.class, VmCpuPanel.class);
-        setViewClass(VmGcView.class, VmGcPanel.class);
-        setViewClass(VmOverviewView.class, VmOverviewPanel.class);
-    }
-
-    @Override
-    public <T extends View> T getView(final Class<T> viewClass) {
-        try {
-            return new EdtHelper().callAndWait(new Callable<T>() {
-                @Override
-                public T call() throws Exception {
-                    return createViewOnEdt(viewClass);
-                }
-            });
-        } catch (InvocationTargetException | InterruptedException e) {
-            logger.log(Level.WARNING, "error trying to create swing component on the EDT", e);
-        }
-        return null;
-    }
-
-    private <T extends View> T createViewOnEdt(Class<T> viewClass) {
-        return super.getView(viewClass);
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ThermostatExtensionRegistry.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-
-import com.redhat.thermostat.common.ActionListener;
-import com.redhat.thermostat.common.ActionNotifier;
-
-public class ThermostatExtensionRegistry<E> {
-
-    public enum Action {
-        SERVICE_ADDED,
-        SERVICE_REMOVED
-    }
-    
-    private ActionNotifier<Action> actionNotifier = new ActionNotifier<>(this);
-    
-    private ServiceTracker tracker;
-    
-    public ThermostatExtensionRegistry(BundleContext context, String filter, final Class<E> classType) throws InvalidSyntaxException {
-                
-        tracker = new ServiceTracker(context, FrameworkUtil.createFilter(filter), null) {
-            
-            @Override
-            public Object addingService(ServiceReference reference) {
-                @SuppressWarnings("unchecked")
-                E service = (E) super.addingService(reference);
-                
-                actionNotifier.fireAction(Action.SERVICE_ADDED, service);
-                return service;
-            }
-            
-            @Override
-            public void removedService(ServiceReference reference, Object service) {
-                if (!classType.isAssignableFrom(service.getClass())) {
-                    throw new AssertionError("removing a non-Filter service");
-                }
-                
-                actionNotifier.fireAction(Action.SERVICE_REMOVED, service);
-                super.removedService(reference, service);
-            }
-        };
-    }
-    
-    public void start() {
-        tracker.open();
-    }
-
-    public void stop() {
-        tracker.close();
-    }
-    
-    public void addActionListener(ActionListener<Action> l) {
-        actionNotifier.addActionListener(l);
-    }
-
-    public void removeViewActionListener(ActionListener<Action> l) {
-        actionNotifier.removeActionListener(l);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/UiFacadeFactory.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import java.util.Collection;
-
-import com.redhat.thermostat.client.osgi.service.VMContextAction;
-import com.redhat.thermostat.client.osgi.service.VmInformationService;
-import com.redhat.thermostat.client.ui.HostInformationController;
-import com.redhat.thermostat.client.ui.SummaryController;
-import com.redhat.thermostat.client.ui.VmInformationController;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.VmRef;
-
-public interface UiFacadeFactory {
-
-    public MainWindowController getMainWindow();
-
-    public SummaryController getSummary();
-
-    public HostInformationController getHostController(HostRef ref);
-
-    public VmInformationController getVmController(VmRef ref);
-
-    Collection<VmInformationService> getVmInformationServices();
-
-    void addVmInformationService(VmInformationService vmInfoService);
-
-    Collection<VMContextAction> getVMContextActions();
-    void addVMContextAction(VMContextAction service);
-
-    public void shutdown();
-
-    public void awaitShutdown() throws InterruptedException;
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/UiFacadeFactoryImpl.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +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;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.concurrent.CountDownLatch;
-
-import org.osgi.framework.BundleContext;
-
-import com.redhat.thermostat.client.osgi.service.VMContextAction;
-import com.redhat.thermostat.client.osgi.service.VmInformationService;
-import com.redhat.thermostat.client.ui.HostInformationController;
-import com.redhat.thermostat.client.ui.MainWindow;
-import com.redhat.thermostat.client.ui.SummaryController;
-import com.redhat.thermostat.client.ui.VmInformationController;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.VmRef;
-
-public class UiFacadeFactoryImpl implements UiFacadeFactory {
-
-    private CountDownLatch shutdown = new CountDownLatch(1);
-
-    private Collection<VmInformationService> vmInformationServices = new ArrayList<>();
-    private Collection<VMContextAction> contextAction = new ArrayList<>();
-
-    private BundleContext context;
-
-    public UiFacadeFactoryImpl(BundleContext context) {
-        this.context = context;
-    }
-
-    @Override
-    public MainWindowController getMainWindow() {
-        MainView mainView = new MainWindow();
-        RegistryFactory registryFactory = new RegistryFactory(context);
-        return new MainWindowControllerImpl(this, mainView, registryFactory);
-    }
-
-    @Override
-    public SummaryController getSummary() {
-        return new SummaryController();
-
-    }
-
-    @Override
-    public HostInformationController getHostController(HostRef ref) {
-        return new HostInformationController(ref);
-
-    }
-
-    @Override
-    public VmInformationController getVmController(VmRef ref) {
-        return new VmInformationController(this, ref);
-
-    }
-
-    @Override
-    public Collection<VmInformationService> getVmInformationServices() {
-        return vmInformationServices;
-    }
-
-    @Override
-    public void addVmInformationService(VmInformationService vmInfoService) {
-        vmInformationServices.add(vmInfoService);
-    }
-
-    @Override
-    public Collection<VMContextAction> getVMContextActions() {
-        return contextAction;
-    }
-
-    @Override
-    public void addVMContextAction(VMContextAction service) {
-        contextAction.add(service);
-    }
-
-    @Override
-    public void shutdown() {
-        shutdown.countDown();
-    }
-
-    @Override
-    public void awaitShutdown() throws InterruptedException {
-        shutdown.await();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/VMTreeDecoratorRegistry.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-
-import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
-
-class VMTreeDecoratorRegistry extends ThermostatExtensionRegistry<ReferenceDecorator> {
-
-    private static final String FILTER = "(&(" + Constants.OBJECTCLASS + "=" + ReferenceDecorator.class.getName() + "))";
-    
-    public VMTreeDecoratorRegistry(BundleContext context) throws InvalidSyntaxException {
-        super(context, FILTER, ReferenceDecorator.class);
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/VMTreeFilterRegistry.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.Constants;
-import org.osgi.framework.InvalidSyntaxException;
-
-import com.redhat.thermostat.client.osgi.service.Filter;
-
-class VMTreeFilterRegistry extends ThermostatExtensionRegistry<Filter> {
-    
-    private static final String FILTER = "(&(" + Constants.OBJECTCLASS + "=" + Filter.class.getName() + "))";
-    
-    public VMTreeFilterRegistry(BundleContext context) throws InvalidSyntaxException {
-        super(context, FILTER, Filter.class);
-    }    
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/config/ConnectionConfiguration.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,54 +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.config;
-
-import com.redhat.thermostat.common.config.ClientPreferences;
-import com.redhat.thermostat.common.config.StartupConfiguration;
-
-public class ConnectionConfiguration implements StartupConfiguration {
-
-    private final ClientPreferences clientPrefs;
-
-    public ConnectionConfiguration(ClientPreferences clientPrefs) {
-        this.clientPrefs = clientPrefs;
-    }
-
-    @Override
-    public String getDBConnectionString() {
-        return clientPrefs.getConnectionUrl();
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/AgentConfigurationSource.java	Tue Jun 12 21:26:04 2012 +0200
@@ -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.client.internal;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class AgentConfigurationSource {
+
+    // FIXME fix this properly
+
+    public List<String> getKnownAgents() {
+        return Arrays.asList(new String[] { "Agent Smith", "Agent Jones", "Agent Brown" });
+    }
+
+    public Map<String, Boolean> getAgentBackends(String agentName) {
+        Map<String, Boolean> fake = new HashMap<>();
+        fake.put("Monitor New JVMs", true);
+        fake.put("Use up all my CPU Cycles", false);
+        return fake;
+    }
+
+    public void updateAgentConfig(String agentName, Map<String, Boolean> newBackendStatus) {
+        // TODO Auto-generated method stub
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/ApplicationInfo.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import static com.redhat.thermostat.client.locale.Translate.localize;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.Icon;
+
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.ui.IconResource;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+
+public class ApplicationInfo {
+
+    private static final Logger logger = LoggingUtils.getLogger(ApplicationInfo.class);
+
+    private Properties appInfo;
+
+    public ApplicationInfo() {
+        appInfo = new Properties();
+        // the properties file should be in the same package as this class
+        InputStream res = getClass().getResourceAsStream("app-info.properties");
+        if (res != null) {
+            try {
+                appInfo.load(res);
+            } catch (IOException e) {
+                logger.log(Level.WARNING, "error loading application information", e);
+            }
+        }
+    }
+
+    public String getName() {
+        return appInfo.getProperty("APP_NAME", localize(LocaleResources.MISSING_INFO));
+    }
+
+    public String getVersion() {
+        return appInfo.getProperty("APP_VERSION", localize(LocaleResources.MISSING_INFO));
+    }
+
+    public String getDescription() {
+        return localize(LocaleResources.APPLICATION_INFO_DESCRIPTION);
+    }
+
+    public Icon getIcon() {
+        String path = appInfo.getProperty("APP_ICON");
+        if (new File(path).exists()) {
+            return IconResource.fromPath(path).getIcon();
+        }
+        return IconResource.QUESTION.getIcon();
+    }
+
+    public String getReleaseDate() {
+        return appInfo.getProperty("APP_RELEASE_DATE", localize(LocaleResources.MISSING_INFO));
+    }
+
+    public String getCopyright() {
+        return appInfo.getProperty("APP_COPYRIGHT", localize(LocaleResources.MISSING_INFO));
+    }
+
+    public String getLicenseSummary() {
+        return localize(LocaleResources.APPLICATION_INFO_LICENSE);
+    }
+
+    public String getEmail() {
+        return appInfo.getProperty("APP_EMAIL", localize(LocaleResources.MISSING_INFO));
+    }
+
+    public String getWebsite() {
+        return appInfo.getProperty("APP_WEBSITE", localize(LocaleResources.MISSING_INFO));
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/ChangeableText.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class ChangeableText {
+
+    private final Set<TextListener> listeners = new HashSet<TextListener>();
+    private String text;
+
+    public static interface TextListener {
+        public void textChanged(ChangeableText text);
+    }
+
+    public ChangeableText(String text) {
+        this.text = text;
+    }
+
+    public synchronized void setText(String text) {
+        if (this.text.equals(text)) {
+            return;
+        }
+        this.text = text;
+        fireChanged();
+    }
+
+    public synchronized String getText() {
+        return text;
+    }
+
+    public synchronized void addListener(TextListener listener) {
+        this.listeners.add(listener);
+    }
+
+    public synchronized void removeListener(TextListener listener) {
+        this.listeners.remove(listener);
+    }
+
+    private void fireChanged() {
+        for (TextListener listener: listeners) {
+            listener.textChanged(this);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/ClientArgs.java	Tue Jun 12 21:26:04 2012 +0200
@@ -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.client.internal;
+
+public class ClientArgs {
+
+    private boolean isDebugLayout = Boolean.getBoolean("thermostat.debug-layout");
+
+    public ClientArgs(String[] args) {
+        for (int i=0; i < args.length; i++) {
+            if (args[i].equals("--debug-layout")) {
+                isDebugLayout = true;
+            }
+        }
+        // TODO what other arguments do we care about?
+        // perhaps skipping the mode selection?
+    }
+
+    public boolean isDebugLayout() {
+        return isDebugLayout;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/DefaultViewFactory.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.redhat.thermostat.common.View;
+import com.redhat.thermostat.common.ViewFactory;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+
+public class DefaultViewFactory implements ViewFactory {
+
+    private static final Logger logger = LoggingUtils.getLogger(SwingViewFactory.class);
+    private final Map<Class<?>, Class<?>> lookupTable = Collections.synchronizedMap(new HashMap<Class<?>, Class<?>>());
+
+    @Override
+    public <T extends View> T getView(Class<T> viewClass) {
+        Class<? extends T> klass = getViewClass(viewClass);
+        if (klass == null) {
+            logger.log(Level.WARNING, "no view class registered for " + viewClass.toString());
+            return null;
+        }
+
+        try {
+            return klass.newInstance();
+        } catch (InstantiationException | IllegalAccessException e) {
+            logger.log(Level.WARNING, "error instantiaitng" + klass);
+            return null;
+        }
+    }
+
+    @Override
+    public <T extends View> Class<? extends T> getViewClass(Class<T> viewClass) {
+        // the cast is safe because the only way to insert an entry into the table is through
+        // a method that enforces this constraint
+        @SuppressWarnings("unchecked")
+        Class<? extends T> result = (Class<? extends T>) lookupTable.get(viewClass);
+        return result;
+    }
+
+    @Override
+    public <T extends View> void setViewClass(Class<T> viewClass, Class<? extends T> implClass) {
+        lookupTable.put(viewClass, implClass);
+    }
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/GUIClientCommand.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import java.util.Collection;
+import java.util.Collections;
+
+import org.osgi.framework.BundleContext;
+
+import com.redhat.thermostat.client.internal.osgi.ApplicationServiceProvider;
+import com.redhat.thermostat.client.internal.osgi.ContextActionServiceProvider;
+import com.redhat.thermostat.client.osgi.service.ApplicationService;
+import com.redhat.thermostat.client.osgi.service.ContextAction;
+import com.redhat.thermostat.common.cli.ArgumentSpec;
+import com.redhat.thermostat.common.cli.Command;
+import com.redhat.thermostat.common.cli.CommandContext;
+import com.redhat.thermostat.common.cli.CommandException;
+
+public class GUIClientCommand implements Command {
+
+    private Main clientMain;
+
+    public GUIClientCommand(Main clientMain) {
+        this.clientMain = clientMain;
+    }
+
+    @Override
+    public void run(CommandContext ctx) throws CommandException {
+        BundleContext context = ctx.getCommandContextFactory().getBundleContext();
+        context.registerService(ApplicationService.class.getName(), new ApplicationServiceProvider(), null);
+        context.registerService(ContextAction.class.getName(), new ContextActionServiceProvider(), null);
+        
+        // this blocks, everything else needs to be done before
+        clientMain.run();
+    }
+
+    @Override
+    public void disable() {
+        // TODO clientMain.shutdown();
+    }
+
+    @Override
+    public String getName() {
+        return "gui";
+    }
+
+    @Override
+    public String getDescription() {
+        return "launches the GUI client";
+    }
+
+    @Override
+    public String getUsage() {
+        return getDescription();
+    }
+
+    @Override
+    public Collection<ArgumentSpec> getAcceptedArguments() {
+        return Collections.emptyList();
+    }
+
+    @Override
+    public boolean isStorageRequired() {
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/HostPanelFacade.java	Tue Jun 12 21:26:04 2012 +0200
@@ -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.client.internal;
+
+import com.redhat.thermostat.client.ui.HostCpuController;
+import com.redhat.thermostat.client.ui.HostMemoryController;
+import com.redhat.thermostat.client.ui.HostOverviewController;
+
+public interface HostPanelFacade  {
+
+    public HostOverviewController getOverviewController();
+
+    public HostCpuController getCpuController();
+
+    public HostMemoryController getMemoryController();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/HostPanelFacadeImpl.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import com.redhat.thermostat.client.ui.HostCpuController;
+import com.redhat.thermostat.client.ui.HostMemoryController;
+import com.redhat.thermostat.client.ui.HostOverviewController;
+import com.redhat.thermostat.common.dao.HostRef;
+
+public class HostPanelFacadeImpl implements HostPanelFacade {
+
+    private final HostOverviewController overviewController;
+    private final HostCpuController cpuController;
+    private final HostMemoryController memoryController;
+
+    public HostPanelFacadeImpl(HostRef ref) {
+        overviewController = new HostOverviewController(ref);
+        cpuController = new HostCpuController(ref);
+        memoryController = new HostMemoryController(ref);
+    }
+
+    @Override
+    public HostOverviewController getOverviewController() {
+        return overviewController;
+    }
+
+    @Override
+    public HostCpuController getCpuController() {
+        return cpuController;
+    }
+
+    @Override
+    public HostMemoryController getMemoryController() {
+        return memoryController;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/HostsVMsLoader.java	Tue Jun 12 21:26:04 2012 +0200
@@ -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.client.internal;
+
+import java.util.Collection;
+
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.VmRef;
+
+/**
+ * Provides a way to load the current hosts and VMs.
+ */
+public interface HostsVMsLoader {
+
+    Collection<HostRef> getHosts();
+    Collection<VmRef> getVMs(HostRef host);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/Main.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import static com.redhat.thermostat.client.locale.Translate.localize;
+
+import java.awt.EventQueue;
+import java.awt.Window;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.JPopupMenu;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+import com.redhat.swing.laf.dolphin.DolphinLookAndFeel;
+import com.redhat.thermostat.client.internal.config.ConnectionConfiguration;
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.ui.ConnectionSelectionDialog;
+import com.redhat.thermostat.client.ui.LayoutDebugHelper;
+import com.redhat.thermostat.common.Constants;
+import com.redhat.thermostat.common.ThreadPoolTimerFactory;
+import com.redhat.thermostat.common.TimerFactory;
+import com.redhat.thermostat.common.appctx.ApplicationContext;
+import com.redhat.thermostat.common.config.ClientPreferences;
+import com.redhat.thermostat.common.config.StartupConfiguration;
+import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.dao.MongoDAOFactory;
+import com.redhat.thermostat.common.storage.Connection;
+import com.redhat.thermostat.common.storage.Connection.ConnectionListener;
+import com.redhat.thermostat.common.storage.Connection.ConnectionStatus;
+import com.redhat.thermostat.common.storage.MongoStorageProvider;
+import com.redhat.thermostat.common.storage.StorageProvider;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+
+public class Main {
+
+    private static final Logger logger = LoggingUtils.getLogger(Main.class);
+
+    private ClientArgs arguments;
+    private UiFacadeFactory uiFacadeFactory;
+
+    public Main(UiFacadeFactory uiFacadeFactory, String[] args) {
+        this.uiFacadeFactory = uiFacadeFactory;
+        try {
+            this.arguments = new ClientArgs(args);
+        } catch (IllegalArgumentException ex) {
+            logger.log(Level.SEVERE, "Bad arguments to Thermostat client.", ex);
+            System.exit(-1);
+        }
+
+        ClientPreferences prefs = new ClientPreferences();
+        StartupConfiguration config = new ConnectionConfiguration(prefs);
+
+        StorageProvider connProv = new MongoStorageProvider(config);
+        DAOFactory daoFactory = new MongoDAOFactory(connProv);
+        ApplicationContext.getInstance().setDAOFactory(daoFactory);
+        TimerFactory timerFactory = new ThreadPoolTimerFactory(1);
+        ApplicationContext.getInstance().setTimerFactory(timerFactory);
+        SwingViewFactory viewFactory = new SwingViewFactory();
+        ApplicationContext.getInstance().setViewFactory(viewFactory);
+    }
+
+    void run() {
+        EventQueue.invokeLater(new Runnable() {
+
+            @Override
+            public void run() {
+                
+                try {
+                    UIManager.setLookAndFeel(new DolphinLookAndFeel());
+                } catch (UnsupportedLookAndFeelException e) {
+                    logger.log(Level.WARNING, "cannot use DolphinLookAndFeel");
+                }
+                
+                showGui();
+            }
+            
+        });
+        
+        try {
+            uiFacadeFactory.awaitShutdown();
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+        }
+    }
+
+    private void showGui() {
+        
+        JPopupMenu.setDefaultLightWeightPopupEnabled(false);
+
+        Connection connection = ApplicationContext.getInstance().getDAOFactory().getConnection();
+        ConnectionSelectionDialog dialog = new ConnectionSelectionDialog((JFrame) null, connection);
+        dialog.pack();
+        dialog.setModal(true);
+        dialog.setVisible(true);
+
+        if (dialog.isCancelled()) {
+            return;
+        }
+
+        ConnectionListener connectionListener = new ConnectionListener() {
+            @Override
+            public void changed(ConnectionStatus newStatus) {
+                if (newStatus == ConnectionStatus.FAILED_TO_CONNECT) {
+                    JOptionPane.showMessageDialog(
+                            null,
+                            localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_DESCRIPTION),
+                            localize(LocaleResources.CONNECTION_FAILED_TO_CONNECT_TITLE),
+                            JOptionPane.ERROR_MESSAGE);
+                    System.exit(Constants.EXIT_UNABLE_TO_CONNECT_TO_DATABASE);
+                }
+            }
+        };
+
+        connection.addListener(connectionListener);
+        connection.connect();
+        connection.removeListener(connectionListener);
+
+        MainWindowController mainController = uiFacadeFactory.getMainWindow();
+        mainController.showMainMainWindow();
+
+        if (arguments.isDebugLayout()) {
+            Thread layoutDebugger = new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    LayoutDebugHelper helper = new LayoutDebugHelper();
+                    try {
+                        while (true) {
+                            Thread.sleep(5000);
+                            Window[] windows = Window.getWindows();
+                            for (Window w : windows) {
+                                helper.debugLayout(w);
+                                w.invalidate();
+                                w.repaint();
+                            }
+                        }
+                    } catch (InterruptedException ie) {
+                        logger.log(Level.INFO, "layout debug helper interrupted; exiting", ie);
+                        // mark thread as interrupted
+                        Thread.currentThread().interrupt();
+                    }
+                }
+            });
+            layoutDebugger.setDaemon(true);
+            layoutDebugger.start();
+        }
+
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/MainView.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import java.awt.Component;
+import java.awt.event.MouseEvent;
+import java.util.List;
+
+import com.redhat.thermostat.client.osgi.service.MenuAction;
+import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
+import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.osgi.service.Filter;
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.dao.Ref;
+
+public interface MainView {
+
+    enum Action {
+        VISIBLE,
+        HIDDEN,
+        HOST_VM_TREE_FILTER,
+        HOST_VM_SELECTION_CHANGED,
+        SHOW_AGENT_CONFIG,
+        SHOW_CLIENT_CONFIG,
+        SWITCH_HISTORY_MODE,
+        SHOW_ABOUT_DIALOG,
+        SHUTDOWN,
+        SHOW_VM_CONTEXT_MENU,
+        VM_CONTEXT_ACTION,
+    }
+
+    void addActionListener(ActionListener<Action> capture);
+
+    void updateTree(List<Filter> filter, List<ReferenceDecorator> decorators, HostsVMsLoader any);
+    String getHostVmTreeFilterText();
+    
+    void setWindowTitle(String title);
+
+    void showMainWindow();
+
+    void hideMainWindow();
+
+    Ref getSelectedHostOrVm();
+
+    void setSubView(Component view);
+
+    void addMenu(String parentMenuName, MenuAction action);
+
+    void removeMenu(String parentMenuName, MenuAction action);
+
+    void showVMContextActions(List<VMContextAction> actions, MouseEvent e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/MainWindowController.java	Tue Jun 12 21:26:04 2012 +0200
@@ -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.client.internal;
+
+
+public interface MainWindowController {
+
+    public void setHostVmTreeFilter(String filter);
+
+    public void showMainMainWindow();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/MainWindowControllerImpl.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,467 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import java.awt.event.MouseEvent;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.internal.MainView.Action;
+import com.redhat.thermostat.client.internal.ui.swing.AboutDialog;
+import com.redhat.thermostat.client.osgi.service.Filter;
+import com.redhat.thermostat.client.osgi.service.MenuAction;
+import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
+import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.ui.AgentConfigurationController;
+import com.redhat.thermostat.client.ui.AgentConfigurationModel;
+import com.redhat.thermostat.client.ui.AgentConfigurationView;
+import com.redhat.thermostat.client.ui.ClientConfigurationController;
+import com.redhat.thermostat.client.ui.ClientConfigurationView;
+import com.redhat.thermostat.client.ui.HostInformationController;
+import com.redhat.thermostat.client.ui.SummaryController;
+import com.redhat.thermostat.client.ui.VmInformationController;
+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.appctx.ApplicationContext;
+import com.redhat.thermostat.common.config.ClientPreferences;
+import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.Ref;
+import com.redhat.thermostat.common.dao.VmInfoDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+
+public class MainWindowControllerImpl implements MainWindowController {
+
+    private static final Logger logger = LoggingUtils.getLogger(MainWindowControllerImpl.class);
+    
+    private List<Filter> vmTreefilters;
+    private List<ReferenceDecorator> vmTreeDecorators;
+    
+    private Timer backgroundUpdater;
+
+    private MainView view;
+
+    private String filter;
+
+    private final HostInfoDAO hostsDAO;
+    private final VmInfoDAO vmsDAO;
+
+    private ApplicationInfo appInfo;
+
+    private UiFacadeFactory facadeFactory;
+    private MenuRegistry menuRegistry;
+    private MenuRegistry.MenuListener menuListener = new MenuRegistry.MenuListener() {
+
+        @Override
+        public void removed(String parentMenuName, MenuAction action) {
+            view.removeMenu(parentMenuName, action);
+        }
+
+        @Override
+        public void added(String parentMenuName, MenuAction action) {
+            view.addMenu(parentMenuName, action);
+        }
+    };
+
+    // FIXME: sort out the code duplication in the registry listeners
+    
+    private TreeViewFilter treeFilter;
+    private VMTreeFilterRegistry filterRegistry;
+    private ActionListener<ThermostatExtensionRegistry.Action> filterListener =
+            new ActionListener<ThermostatExtensionRegistry.Action>()
+    {
+        @Override
+        public void actionPerformed(ActionEvent<com.redhat.thermostat.client.internal.ThermostatExtensionRegistry.Action>
+                                    actionEvent)
+        {
+            Filter filter = (Filter) actionEvent.getPayload();
+            
+            switch (actionEvent.getActionId()) {
+            case SERVICE_ADDED:
+                vmTreefilters.add(filter);
+                doUpdateTreeAsync();
+                break;
+            
+            case SERVICE_REMOVED:
+                vmTreefilters.remove(filter);
+                doUpdateTreeAsync();
+                break;
+                
+            default:
+                logger.log(Level.WARNING, "received unknown event from VMTreeFilterRegistry: " +
+                                           actionEvent.getActionId());
+                break;
+            }
+        }
+    };
+    
+    private VMTreeDecoratorRegistry decoratorRegistry;
+    private ActionListener<ThermostatExtensionRegistry.Action> decoratorListener =
+            new ActionListener<ThermostatExtensionRegistry.Action> ()
+    {
+        public void actionPerformed(com.redhat.thermostat.common.ActionEvent<ThermostatExtensionRegistry.Action>
+                                    actionEvent)
+        {
+            ReferenceDecorator decorator = (ReferenceDecorator) actionEvent.getPayload();
+            switch (actionEvent.getActionId()) {
+            case SERVICE_ADDED:
+                vmTreeDecorators.add(decorator);
+                doUpdateTreeAsync();
+                break;
+            
+            case SERVICE_REMOVED:
+                vmTreeDecorators.remove(decorator);
+                doUpdateTreeAsync();
+                break;
+                
+            default:
+                logger.log(Level.WARNING, "received unknown event from ReferenceDecorator: " +
+                                           actionEvent.getActionId());
+                break;
+            }
+        };
+    };
+    
+    private boolean showHistory;
+
+    private VmInformationControllerProvider vmInfoControllerProvider;
+
+    public MainWindowControllerImpl(UiFacadeFactory facadeFactory, MainView view, RegistryFactory registryFactory)
+    {
+        try {
+            filterRegistry = registryFactory.createVMTreeFilterRegistry();
+            decoratorRegistry = registryFactory.createVMTreeDecoratorRegistry();
+            menuRegistry = registryFactory.createMenuRegistry();
+            
+        } catch (InvalidSyntaxException e) {
+            throw new RuntimeException(e);
+        }
+
+        vmTreeDecorators = new CopyOnWriteArrayList<>();
+        
+        vmTreefilters = new CopyOnWriteArrayList<>();
+        treeFilter = new TreeViewFilter();
+        vmTreefilters.add(treeFilter);
+        
+        this.facadeFactory = facadeFactory;
+
+        ApplicationContext ctx = ApplicationContext.getInstance();
+        DAOFactory daoFactory = ctx.getDAOFactory();
+        hostsDAO = daoFactory.getHostInfoDAO();
+        vmsDAO = daoFactory.getVmInfoDAO();
+
+        initView(view);
+
+        vmInfoControllerProvider = new VmInformationControllerProvider();
+
+        appInfo = new ApplicationInfo();
+        view.setWindowTitle(appInfo.getName());
+        initializeTimer();
+
+        updateView();
+
+        menuRegistry.addMenuListener(menuListener);
+        menuRegistry.start();
+        
+        filterRegistry.addActionListener(filterListener);
+        filterRegistry.start();
+        
+        decoratorRegistry.addActionListener(decoratorListener);
+        decoratorRegistry.start();
+    }
+
+    private class HostsVMsLoaderImpl implements HostsVMsLoader {
+
+        @Override
+        public Collection<HostRef> getHosts() {
+            if (showHistory) {
+                return hostsDAO.getHosts();
+            } else {
+                return hostsDAO.getAliveHosts();
+            }
+        }
+
+        @Override
+        public Collection<VmRef> getVMs(HostRef host) {
+            return vmsDAO.getVMs(host);
+        }
+
+    }
+
+    /**
+     * This method is for testing purpouse only
+     */
+    Filter getTreeFilter() {
+        return treeFilter;
+    }
+    
+    /**
+     * This method is for testing purpouse only
+     */ 
+    List<ReferenceDecorator> getVmTreeDecorators() {
+        return vmTreeDecorators;
+    }
+    
+    /**
+     * This method is for testing purpouse only
+     */
+    MenuRegistry.MenuListener getMenuListener() {
+        return menuListener;
+    }
+    
+    private void initializeTimer() {
+        ApplicationContext ctx = ApplicationContext.getInstance();
+        backgroundUpdater = ctx.getTimerFactory().createTimer();
+        backgroundUpdater.setAction(new Runnable() {
+            @Override
+            public void run() {
+                doUpdateTreeAsync();
+            }
+        });
+        backgroundUpdater.setInitialDelay(0);
+        backgroundUpdater.setDelay(3);
+        backgroundUpdater.setTimeUnit(TimeUnit.SECONDS);
+        backgroundUpdater.setSchedulingType(SchedulingType.FIXED_RATE);
+    }
+
+    private void startBackgroundUpdates() {
+        backgroundUpdater.start();
+    }
+
+    public void stopBackgroundUpdates() {
+        backgroundUpdater.stop();
+    }
+
+    private class TreeViewFilter implements Filter {
+        @Override
+        public boolean matches(Ref ref) {
+            if (filter == null || filter.isEmpty()) {
+                return true;
+                
+            } else {
+                return matches(ref, filter);                
+            }
+        }
+      
+        public boolean matches(Ref ref, String filter) {
+          return ref.getName().contains(filter) || ref.getStringID().contains(filter);
+        }
+    }
+    
+    @Override
+    public void setHostVmTreeFilter(String filter) {
+        this.filter = filter;
+        doUpdateTreeAsync();
+    }
+
+    public void doUpdateTreeAsync() {
+        HostsVMsLoader loader = new HostsVMsLoaderImpl();
+        view.updateTree(vmTreefilters, vmTreeDecorators, loader);
+    }
+
+    private void initView(MainView mainView) {
+        this.view = mainView;
+        mainView.addActionListener(new ActionListener<MainView.Action>() {
+
+            @Override
+            public void actionPerformed(ActionEvent<MainView.Action> evt) {
+                MainView.Action action = evt.getActionId();
+                switch (action) {
+                case VISIBLE:
+                    startBackgroundUpdates();
+                    break;
+                case HIDDEN:
+                    stopBackgroundUpdates();
+                    break;
+                case HOST_VM_SELECTION_CHANGED:
+                    updateView();
+                    break;
+                case HOST_VM_TREE_FILTER:
+                    String filter = view.getHostVmTreeFilterText();
+                    setHostVmTreeFilter(filter);
+                    break;
+                case SHOW_AGENT_CONFIG:
+                    showAgentConfiguration();
+                    break;
+                case SHOW_CLIENT_CONFIG:
+                    showConfigureClientPreferences();
+                    break;
+                case SWITCH_HISTORY_MODE:
+                    switchHistoryMode();
+                    break;
+                case SHOW_ABOUT_DIALOG:
+                    showAboutDialog();
+                    break;
+                case SHOW_VM_CONTEXT_MENU:
+                    showContextMenu(evt);
+                    break;
+                case VM_CONTEXT_ACTION:
+                    handleVMHooks(evt);
+                    break;
+                case SHUTDOWN:
+                    shutdownApplication();
+                    break;
+                default:
+                    throw new IllegalStateException("unhandled action");
+                }
+            }
+
+        });
+    }
+
+    private void shutdownApplication() {
+        menuRegistry.removeMenuListener(menuListener);
+        menuListener = null;
+        menuRegistry.stop();
+
+        view.hideMainWindow();
+        ApplicationContext.getInstance().getTimerFactory().shutdown();
+        shutdownOSGiFramework();
+    }
+
+    private void shutdownOSGiFramework() {
+        facadeFactory.shutdown();
+    }
+
+    private void showContextMenu(ActionEvent<Action> evt) {
+        List<VMContextAction> toShow = new ArrayList<>();
+        VmRef vm = (VmRef) view.getSelectedHostOrVm();
+
+        logger.log(Level.INFO, "registering applicable VMContextActions actions to show");
+
+        for (VMContextAction action : facadeFactory.getVMContextActions()) {
+            if (action.getFilter().matches(vm)) {
+                toShow.add(action);
+            }
+        }
+
+        view.showVMContextActions(toShow, (MouseEvent)evt.getPayload());
+    }
+
+    private void handleVMHooks(ActionEvent<MainView.Action> event) {
+        Object payload = event.getPayload();
+        if (payload instanceof VMContextAction) { 
+            try {
+                VMContextAction action = (VMContextAction) payload;
+                action.execute((VmRef) view.getSelectedHostOrVm());
+            } catch (Throwable error) {
+                logger.log(Level.SEVERE, "");
+            }
+        }
+    }
+    
+    @Override
+    public void showMainMainWindow() {
+        view.showMainWindow();
+    }
+
+    private void showAboutDialog() {
+        AboutDialog aboutDialog = new AboutDialog(appInfo);
+        aboutDialog.setModal(true);
+        aboutDialog.pack();
+        aboutDialog.setVisible(true);
+    }
+
+    private void showAgentConfiguration() {
+        AgentConfigurationSource agentPrefs = new AgentConfigurationSource();
+        AgentConfigurationModel model = new AgentConfigurationModel(agentPrefs);
+        AgentConfigurationView view = ApplicationContext.getInstance().getViewFactory().getView(AgentConfigurationView.class);
+        AgentConfigurationController controller = new AgentConfigurationController(model, view);
+        controller.showView();
+    }
+
+    private void showConfigureClientPreferences() {
+        ClientPreferences prefs = new ClientPreferences();
+        ClientConfigurationView view = ApplicationContext.getInstance().getViewFactory().getView(ClientConfigurationView.class);
+        ClientConfigurationController controller = new ClientConfigurationController(prefs, view);
+        controller.showDialog();
+    }
+
+    private void switchHistoryMode() {
+        showHistory = !showHistory;
+        doUpdateTreeAsync();
+    }
+
+    private void updateView() {
+        // this is quite an ugly method. there must be a cleaner way to do this
+        Ref ref = view.getSelectedHostOrVm();
+
+        if (ref == null) {
+            SummaryController controller = new SummaryController();
+            view.setSubView(controller.getComponent());
+        } else if (ref instanceof HostRef) {
+            HostRef hostRef = (HostRef) ref;
+            HostInformationController hostController = facadeFactory.getHostController(hostRef);
+            view.setSubView(hostController.getComponent());
+        } else if (ref instanceof VmRef) {
+            VmRef vmRef = (VmRef) ref;
+            VmInformationController vmInformation =
+                    vmInfoControllerProvider.getVmInfoController(vmRef);
+            view.setSubView(vmInformation.getComponent());
+        } else {
+            throw new IllegalArgumentException("unknown type of ref");
+        }
+    }
+
+    private class VmInformationControllerProvider {
+        private VmInformationController lastSelectedVM;
+
+        VmInformationController getVmInfoController(VmRef vmRef) {
+            int id = 0;
+            if (lastSelectedVM != null) {
+                id = lastSelectedVM.getSelectedChildID();
+            }
+            lastSelectedVM = facadeFactory.getVmController(vmRef);
+            lastSelectedVM.selectChildID(id);
+
+            return lastSelectedVM;
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/MenuRegistry.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+package com.redhat.thermostat.client.internal;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+import com.redhat.thermostat.client.osgi.service.MenuAction;
+
+public class MenuRegistry {
+
+    public static interface MenuListener {
+
+        public void added(String parentMenuName, MenuAction action);
+
+        public void removed(String parentMenuName, MenuAction action);
+    }
+
+    public static final String PARENT_MENU = "parentMenu";
+
+    private static final String FILTER = "(&(" + Constants.OBJECTCLASS + "=" + MenuAction.class.getName() + ")(" + PARENT_MENU + "=*))";
+
+    private ServiceTracker menuTracker;
+
+    private Map<String,List<MenuAction>> menus = new HashMap<>();
+    private List<MenuListener> listeners = new CopyOnWriteArrayList<>();
+
+    public MenuRegistry(BundleContext context) throws InvalidSyntaxException {
+        menuTracker = new ServiceTracker(context, FrameworkUtil.createFilter(FILTER), null) {
+            @Override
+            public Object addingService(ServiceReference reference) {
+                MenuAction action = (MenuAction) super.addingService(reference);
+                String parentMenuName = (String) reference.getProperty(PARENT_MENU);
+                menuAdded(parentMenuName, action);
+                return action;
+            }
+
+            @Override
+            public void removedService(ServiceReference reference, Object service) {
+                if (!(service instanceof MenuAction)) {
+                    throw new AssertionError("removing a non-MenuAction service");
+                }
+                String parentMenuName = (String) reference.getProperty(PARENT_MENU);
+                menuRemoved(parentMenuName, (MenuAction)service);
+                super.removedService(reference, service);
+            }
+        };
+    }
+
+    public void start() {
+        menuTracker.open();
+    }
+
+    public void stop() {
+        menuTracker.close();
+    }
+
+    public void addMenuListener(MenuListener listener) {
+        listeners.add(listener);
+
+        for (Entry<String,List<MenuAction>> entry: menus.entrySet()) {
+            for (MenuAction action: entry.getValue()) {
+                listener.added(entry.getKey(), action);
+            }
+        }
+    }
+
+    public void removeMenuListener(MenuListener listener) {
+        listeners.remove(listener);
+    }
+
+    private void menuAdded(String parentMenuName, MenuAction action) {
+        if (!menus.containsKey(parentMenuName)) {
+            menus.put(parentMenuName, new ArrayList<MenuAction>());
+        }
+        List<MenuAction> list = menus.get(parentMenuName);
+        list.add(action);
+        for (MenuListener listener: listeners) {
+            listener.added(parentMenuName, action);
+        }
+    }
+
+    private void menuRemoved(String parentMenuName, MenuAction action) {
+        if (!menus.containsKey(parentMenuName)) {
+            throw new IllegalArgumentException("unknown parent menu name");
+        }
+        List<MenuAction> list = menus.get(parentMenuName);
+        if (!list.contains(action)) {
+            throw new IllegalArgumentException("unknown menu action");
+        }
+
+        list.remove(action);
+        for (MenuListener listener: listeners) {
+            listener.removed(parentMenuName, action);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/RegistryFactory.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+
+class RegistryFactory {
+
+    private BundleContext context;
+    RegistryFactory(BundleContext context) {
+        this.context = context;
+    }
+    
+    VMTreeDecoratorRegistry createVMTreeDecoratorRegistry() throws InvalidSyntaxException {
+        return new VMTreeDecoratorRegistry(context);
+    }
+    
+    VMTreeFilterRegistry createVMTreeFilterRegistry() throws InvalidSyntaxException {
+        return new VMTreeFilterRegistry(context);
+    }
+    
+    MenuRegistry createMenuRegistry() throws InvalidSyntaxException {
+        return new MenuRegistry(context);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/SwingViewFactory.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.concurrent.Callable;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import com.redhat.thermostat.client.ui.AgentConfigurationFrame;
+import com.redhat.thermostat.client.ui.AgentConfigurationView;
+import com.redhat.thermostat.client.ui.ClientConfigurationFrame;
+import com.redhat.thermostat.client.ui.ClientConfigurationView;
+import com.redhat.thermostat.client.ui.EdtHelper;
+import com.redhat.thermostat.client.ui.HostCpuPanel;
+import com.redhat.thermostat.client.ui.HostCpuView;
+import com.redhat.thermostat.client.ui.HostInformationPanel;
+import com.redhat.thermostat.client.ui.HostInformationView;
+import com.redhat.thermostat.client.ui.HostMemoryPanel;
+import com.redhat.thermostat.client.ui.HostMemoryView;
+import com.redhat.thermostat.client.ui.HostOverviewPanel;
+import com.redhat.thermostat.client.ui.HostOverviewView;
+import com.redhat.thermostat.client.ui.SummaryPanel;
+import com.redhat.thermostat.client.ui.SummaryView;
+import com.redhat.thermostat.client.ui.VmCpuPanel;
+import com.redhat.thermostat.client.ui.VmCpuView;
+import com.redhat.thermostat.client.ui.VmGcPanel;
+import com.redhat.thermostat.client.ui.VmGcView;
+import com.redhat.thermostat.client.ui.VmInformationPanel;
+import com.redhat.thermostat.client.ui.VmInformationView;
+import com.redhat.thermostat.client.ui.VmOverviewPanel;
+import com.redhat.thermostat.client.ui.VmOverviewView;
+import com.redhat.thermostat.common.View;
+import com.redhat.thermostat.common.ViewFactory;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+
+public class SwingViewFactory extends DefaultViewFactory implements ViewFactory {
+
+    private static final Logger logger = LoggingUtils.getLogger(SwingViewFactory.class);
+
+    public SwingViewFactory() {
+        setViewClass(AgentConfigurationView.class, AgentConfigurationFrame.class);
+        setViewClass(ClientConfigurationView.class, ClientConfigurationFrame.class);
+
+        setViewClass(SummaryView.class, SummaryPanel.class);
+
+        setViewClass(HostInformationView.class, HostInformationPanel.class);
+        setViewClass(VmInformationView.class, VmInformationPanel.class);
+
+        setViewClass(HostCpuView.class, HostCpuPanel.class);
+        setViewClass(HostMemoryView.class, HostMemoryPanel.class);
+        setViewClass(HostOverviewView.class, HostOverviewPanel.class);
+
+        setViewClass(VmCpuView.class, VmCpuPanel.class);
+        setViewClass(VmGcView.class, VmGcPanel.class);
+        setViewClass(VmOverviewView.class, VmOverviewPanel.class);
+    }
+
+    @Override
+    public <T extends View> T getView(final Class<T> viewClass) {
+        try {
+            return new EdtHelper().callAndWait(new Callable<T>() {
+                @Override
+                public T call() throws Exception {
+                    return createViewOnEdt(viewClass);
+                }
+            });
+        } catch (InvocationTargetException | InterruptedException e) {
+            logger.log(Level.WARNING, "error trying to create swing component on the EDT", e);
+        }
+        return null;
+    }
+
+    private <T extends View> T createViewOnEdt(Class<T> viewClass) {
+        return super.getView(viewClass);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/ThermostatExtensionRegistry.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.common.ActionNotifier;
+
+public class ThermostatExtensionRegistry<E> {
+
+    public enum Action {
+        SERVICE_ADDED,
+        SERVICE_REMOVED
+    }
+    
+    private ActionNotifier<Action> actionNotifier = new ActionNotifier<>(this);
+    
+    private ServiceTracker tracker;
+    
+    public ThermostatExtensionRegistry(BundleContext context, String filter, final Class<E> classType) throws InvalidSyntaxException {
+                
+        tracker = new ServiceTracker(context, FrameworkUtil.createFilter(filter), null) {
+            
+            @Override
+            public Object addingService(ServiceReference reference) {
+                @SuppressWarnings("unchecked")
+                E service = (E) super.addingService(reference);
+                
+                actionNotifier.fireAction(Action.SERVICE_ADDED, service);
+                return service;
+            }
+            
+            @Override
+            public void removedService(ServiceReference reference, Object service) {
+                if (!classType.isAssignableFrom(service.getClass())) {
+                    throw new AssertionError("removing a non-Filter service");
+                }
+                
+                actionNotifier.fireAction(Action.SERVICE_REMOVED, service);
+                super.removedService(reference, service);
+            }
+        };
+    }
+    
+    public void start() {
+        tracker.open();
+    }
+
+    public void stop() {
+        tracker.close();
+    }
+    
+    public void addActionListener(ActionListener<Action> l) {
+        actionNotifier.addActionListener(l);
+    }
+
+    public void removeViewActionListener(ActionListener<Action> l) {
+        actionNotifier.removeActionListener(l);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/UiFacadeFactory.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import java.util.Collection;
+
+import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.osgi.service.VmInformationService;
+import com.redhat.thermostat.client.ui.HostInformationController;
+import com.redhat.thermostat.client.ui.SummaryController;
+import com.redhat.thermostat.client.ui.VmInformationController;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.VmRef;
+
+public interface UiFacadeFactory {
+
+    public MainWindowController getMainWindow();
+
+    public SummaryController getSummary();
+
+    public HostInformationController getHostController(HostRef ref);
+
+    public VmInformationController getVmController(VmRef ref);
+
+    Collection<VmInformationService> getVmInformationServices();
+
+    void addVmInformationService(VmInformationService vmInfoService);
+
+    Collection<VMContextAction> getVMContextActions();
+    void addVMContextAction(VMContextAction service);
+
+    public void shutdown();
+
+    public void awaitShutdown() throws InterruptedException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/UiFacadeFactoryImpl.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.concurrent.CountDownLatch;
+
+import org.osgi.framework.BundleContext;
+
+import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.osgi.service.VmInformationService;
+import com.redhat.thermostat.client.ui.HostInformationController;
+import com.redhat.thermostat.client.ui.MainWindow;
+import com.redhat.thermostat.client.ui.SummaryController;
+import com.redhat.thermostat.client.ui.VmInformationController;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.VmRef;
+
+public class UiFacadeFactoryImpl implements UiFacadeFactory {
+
+    private CountDownLatch shutdown = new CountDownLatch(1);
+
+    private Collection<VmInformationService> vmInformationServices = new ArrayList<>();
+    private Collection<VMContextAction> contextAction = new ArrayList<>();
+
+    private BundleContext context;
+
+    public UiFacadeFactoryImpl(BundleContext context) {
+        this.context = context;
+    }
+
+    @Override
+    public MainWindowController getMainWindow() {
+        MainView mainView = new MainWindow();
+        RegistryFactory registryFactory = new RegistryFactory(context);
+        return new MainWindowControllerImpl(this, mainView, registryFactory);
+    }
+
+    @Override
+    public SummaryController getSummary() {
+        return new SummaryController();
+
+    }
+
+    @Override
+    public HostInformationController getHostController(HostRef ref) {
+        return new HostInformationController(ref);
+
+    }
+
+    @Override
+    public VmInformationController getVmController(VmRef ref) {
+        return new VmInformationController(this, ref);
+
+    }
+
+    @Override
+    public Collection<VmInformationService> getVmInformationServices() {
+        return vmInformationServices;
+    }
+
+    @Override
+    public void addVmInformationService(VmInformationService vmInfoService) {
+        vmInformationServices.add(vmInfoService);
+    }
+
+    @Override
+    public Collection<VMContextAction> getVMContextActions() {
+        return contextAction;
+    }
+
+    @Override
+    public void addVMContextAction(VMContextAction service) {
+        contextAction.add(service);
+    }
+
+    @Override
+    public void shutdown() {
+        shutdown.countDown();
+    }
+
+    @Override
+    public void awaitShutdown() throws InterruptedException {
+        shutdown.await();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/VMTreeDecoratorRegistry.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
+
+class VMTreeDecoratorRegistry extends ThermostatExtensionRegistry<ReferenceDecorator> {
+
+    private static final String FILTER = "(&(" + Constants.OBJECTCLASS + "=" + ReferenceDecorator.class.getName() + "))";
+    
+    public VMTreeDecoratorRegistry(BundleContext context) throws InvalidSyntaxException {
+        super(context, FILTER, ReferenceDecorator.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/VMTreeFilterRegistry.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.osgi.service.Filter;
+
+class VMTreeFilterRegistry extends ThermostatExtensionRegistry<Filter> {
+    
+    private static final String FILTER = "(&(" + Constants.OBJECTCLASS + "=" + Filter.class.getName() + "))";
+    
+    public VMTreeFilterRegistry(BundleContext context) throws InvalidSyntaxException {
+        super(context, FILTER, Filter.class);
+    }    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/config/ConnectionConfiguration.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal.config;
+
+import com.redhat.thermostat.common.config.ClientPreferences;
+import com.redhat.thermostat.common.config.StartupConfiguration;
+
+public class ConnectionConfiguration implements StartupConfiguration {
+
+    private final ClientPreferences clientPrefs;
+
+    public ConnectionConfiguration(ClientPreferences clientPrefs) {
+        this.clientPrefs = clientPrefs;
+    }
+
+    @Override
+    public String getDBConnectionString() {
+        return clientPrefs.getConnectionUrl();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ApplicationServiceProvider.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal.osgi;
+
+import com.redhat.thermostat.client.osgi.service.ApplicationService;
+import com.redhat.thermostat.common.appctx.ApplicationContext;
+import com.redhat.thermostat.common.dao.DAOFactory;
+
+
+public class ApplicationServiceProvider implements ApplicationService {
+
+    @Override
+    public DAOFactory getDAOFactory() {
+        // TODO: Eventually we will no longer need a singleton for ApplicationContext!
+        return ApplicationContext.getInstance().getDAOFactory();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ContextActionServiceProvider.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal.osgi;
+
+import com.redhat.thermostat.client.osgi.service.ContextAction;
+
+public class ContextActionServiceProvider implements ContextAction {
+  
+    @Override
+    public String getName() {
+        return "system context";
+    }
+
+    @Override
+    public String getDescription() {
+        return "system context";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/ThermostatActivator.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal.osgi;
+
+import java.util.Arrays;
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+import com.redhat.thermostat.client.internal.GUIClientCommand;
+import com.redhat.thermostat.client.internal.Main;
+import com.redhat.thermostat.client.internal.UiFacadeFactory;
+import com.redhat.thermostat.client.internal.UiFacadeFactoryImpl;
+import com.redhat.thermostat.common.cli.CommandRegistry;
+import com.redhat.thermostat.common.cli.CommandRegistryImpl;
+
+public class ThermostatActivator implements BundleActivator {
+
+    private VmInformationServiceTracker vmInfoServiceTracker;
+    private VMContextActionServiceTracker contextActionTracker;
+
+    private CommandRegistry cmdReg;
+
+    @Override
+    public void start(final BundleContext context) throws Exception {
+        UiFacadeFactory uiFacadeFactory = new UiFacadeFactoryImpl(context);
+
+        vmInfoServiceTracker = new VmInformationServiceTracker(context, uiFacadeFactory);
+        vmInfoServiceTracker.open();
+
+        contextActionTracker =
+                new VMContextActionServiceTracker(context, uiFacadeFactory);
+        contextActionTracker.open();
+
+        cmdReg = new CommandRegistryImpl(context);
+        Main main = new Main(uiFacadeFactory, new String[0]);
+        cmdReg.registerCommands(Arrays.asList(new GUIClientCommand(main)));
+    }
+
+    @Override
+    public void stop(BundleContext context) throws Exception {
+        vmInfoServiceTracker.close(); //context.removeServiceListener(vmInfoServiceTracker);
+        contextActionTracker.close();
+        cmdReg.unregisterCommands();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/VMContextActionServiceTracker.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal.osgi;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+import com.redhat.thermostat.client.internal.UiFacadeFactory;
+import com.redhat.thermostat.client.osgi.service.VMContextAction;
+
+@SuppressWarnings("rawtypes")
+class VMContextActionServiceTracker extends ServiceTracker {
+
+    private UiFacadeFactory uiFacadeFactory;
+
+    private BundleContext context;
+
+    @SuppressWarnings("unchecked")
+    VMContextActionServiceTracker(BundleContext context, UiFacadeFactory uiFacadeFactory) {
+        super(context, VMContextAction.class.getName(), null);
+        this.context = context;
+        this.uiFacadeFactory = uiFacadeFactory;
+    }
+
+    @Override
+    public Object addingService(ServiceReference reference) {
+        @SuppressWarnings("unchecked")
+        VMContextAction service = (VMContextAction) context.getService(reference);
+        uiFacadeFactory.addVMContextAction(service);
+        return service;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/osgi/VmInformationServiceTracker.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal.osgi;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceReference;
+import org.osgi.util.tracker.ServiceTracker;
+
+import com.redhat.thermostat.client.internal.UiFacadeFactory;
+import com.redhat.thermostat.client.osgi.service.VmInformationService;
+
+class VmInformationServiceTracker extends ServiceTracker {
+
+    private UiFacadeFactory uiFacadeFactory;
+
+    private BundleContext context;
+
+    VmInformationServiceTracker(BundleContext context, UiFacadeFactory uiFacadeFactory) {
+        super(context, VmInformationService.class.getName(), null);
+        this.context = context;
+        this.uiFacadeFactory = uiFacadeFactory;
+    }
+
+    @Override
+    public Object addingService(ServiceReference reference) {
+        VmInformationService service = (VmInformationService) context.getService(reference);
+        uiFacadeFactory.addVmInformationService(service);
+        return service;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/ui/swing/AboutDialog.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal.ui.swing;
+
+import static com.redhat.thermostat.client.locale.Translate.localize;
+
+import java.awt.Cursor;
+import java.awt.Desktop;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.net.URI;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.swing.GroupLayout;
+import javax.swing.GroupLayout.Alignment;
+import javax.swing.Icon;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.LayoutStyle.ComponentPlacement;
+import javax.swing.SwingConstants;
+import javax.swing.SwingWorker;
+
+import javax.swing.border.TitledBorder;
+
+import com.redhat.thermostat.client.internal.ApplicationInfo;
+import com.redhat.thermostat.client.locale.LocaleResources;
+import com.redhat.thermostat.client.ui.IconResource;
+import com.redhat.thermostat.client.ui.UIResources;
+import com.redhat.thermostat.common.utils.LoggingUtils;
+
+public class AboutDialog extends JDialog {
+
+    private static final long serialVersionUID = -7611616871710076514L;
+
+    private static final Logger logger = LoggingUtils.getLogger(AboutDialog.class);
+
+    private String name;
+    private String description;
+    private String version;
+    private Icon icon;
+    private String copyright;
+    private String license;
+    private String website;
+    private String email;
+    
+    /**
+     * Create the dialog.
+     * @param applicationInfo 
+     */
+    public AboutDialog(ApplicationInfo appInfo) {
+        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+        setResizable(false);
+        
+        name = appInfo.getName();
+        description = appInfo.getDescription();
+        version = appInfo.getVersion();
+        icon = IconResource.QUESTION.getIcon(); // TODO appInfo.getIcon();
+        copyright = appInfo.getCopyright();
+        license = appInfo.getLicenseSummary();
+        website = appInfo.getWebsite();
+        email = appInfo.getEmail();
+        
+        initComponents();
+    }
+    
+    private void initComponents() {
+        setBounds(100, 100, 450, 338);
+        
+        UIResources res = UIResources.getInstance();
+        
+        JPanel panel = new JPanel();
+        panel.setBorder(new TitledBorder(""));
+        
+        JButton closeButton = new JButton(localize(LocaleResources.BUTTON_CLOSE));
+        closeButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                AboutDialog.this.setVisible(false);
+                AboutDialog.this.dispose();  
+            }
+        });
+        
+        GroupLayout groupLayout = new GroupLayout(getContentPane());
+        groupLayout.setHorizontalGroup(
+            groupLayout.createParallelGroup(Alignment.TRAILING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
+                        .addComponent(closeButton, GroupLayout.PREFERRED_SIZE, 92, GroupLayout.PREFERRED_SIZE)
+                        .addComponent(panel, GroupLayout.DEFAULT_SIZE, 424, Short.MAX_VALUE))
+                    .addContainerGap())
+        );
+        groupLayout.setVerticalGroup(
+            groupLayout.createParallelGroup(Alignment.LEADING)
+                .addGroup(groupLayout.createSequentialGroup()
+                    .addContainerGap()
+                    .addComponent(panel, GroupLayout.DEFAULT_SIZE, 245, Short.MAX_VALUE)
+                    .addGap(18)
+                    .addComponent(closeButton)
+                    .addGap(9))
+        );
+        
+        JLabel iconLabel = new JLabel("");
+        iconLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        
+        iconLabel.setIcon(icon);
+        
+        JLabel versionLabel = new JLabel(version);
+        versionLabel.setFont(res.footerFont());
+        versionLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        
+        JLabel nameLabel = new JLabel(name);
+        nameLabel.setFont(res.headerFont());
+        nameLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        
+        JLabel descriptionLabel = new JLabel(description);
+        descriptionLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        descriptionLabel.setFont(res.standardFont());
+        
+        JLabel homePageLabel = new JLabel(website);
+        homePageLabel.setForeground(res.hyperlinkColor());
+        homePageLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        homePageLabel.setFont(res.footerFont());        
+        homePageLabel.addMouseListener(new Browse(homePageLabel));
+
+        JLabel copyrightLabel = new JLabel(copyright);
+        copyrightLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        copyrightLabel.setFont(res.footerFont());
+        
+        JLabel licenseString = new JLabel(license);
+        licenseString.setHorizontalAlignment(SwingConstants.CENTER);
+        licenseString.setFont(res.footerFont());
+        
+        JLabel emailLabel = new JLabel(email);
+        emailLabel.setHorizontalAlignment(SwingConstants.CENTER);
+        emailLabel.setForeground(res.hyperlinkColor());
+        emailLabel.setFont(res.footerFont());
+        emailLabel.addMouseListener(new Mailer(emailLabel));
+        
+        GroupLayout gl_panel = new GroupLayout(panel);
+        gl_panel.setHorizontalGroup(
+            gl_panel.createParallelGroup(Alignment.TRAILING)
+                .addGroup(gl_panel.createSequentialGroup()
+                    .addContainerGap()
+                    .addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
+                        .addComponent(iconLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(nameLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(versionLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(descriptionLabel, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(copyrightLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(licenseString, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(emailLabel, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
+                        .addComponent(homePageLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE))
+                    .addContainerGap())
+        );
+        gl_panel.setVerticalGroup(
+            gl_panel.createParallelGroup(Alignment.LEADING)
+                .addGroup(gl_panel.createSequentialGroup()
+                    .addContainerGap()
+                    .addComponent(iconLabel)
+                    .addGap(4)
+                    .addComponent(nameLabel, GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addComponent(versionLabel, GroupLayout.DEFAULT_SIZE, 13, Short.MAX_VALUE)
+                    .addPreferredGap(ComponentPlacement.UNRELATED)
+                    .addComponent(descriptionLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .addGap(12)
+                    .addComponent(homePageLabel, GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE)
+                    .addGap(3)
+                    .addComponent(emailLabel, GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addComponent(copyrightLabel, GroupLayout.DEFAULT_SIZE, 13, Short.MAX_VALUE)
+                    .addPreferredGap(ComponentPlacement.RELATED)
+                    .addComponent(licenseString, GroupLayout.DEFAULT_SIZE, 13, Short.MAX_VALUE)
+                    .addContainerGap())
+        );
+        panel.setLayout(gl_panel);
+        getContentPane().setLayout(groupLayout);
+    }
+    
+    private abstract class HyperLinkAction extends MouseAdapter {
+        
+        private JLabel hyperLinkLabel;
+        public HyperLinkAction(JLabel hyperLinkLabel) {
+            this.hyperLinkLabel = hyperLinkLabel;
+        }
+        
+        @Override
+        public void mouseEntered(MouseEvent e) {
+            hyperLinkLabel.setForeground(UIResources.getInstance().hyperlinkActiveColor());
+            Cursor cursor = new Cursor(Cursor.HAND_CURSOR);
+            setCursor(cursor);
+        }
+        @Override
+        public void mouseExited(MouseEvent e) {
+            hyperLinkLabel.setForeground(UIResources.getInstance().hyperlinkColor());
+            Cursor cursor = new Cursor(Cursor.DEFAULT_CURSOR);
+            setCursor(cursor);
+        }
+        
+        @Override
+        public void mouseClicked(MouseEvent e) {
+            if (Desktop.isDesktopSupported()) {
+                new SwingWorker<Void, Void>() {
+                    @Override
+                    protected Void doInBackground() throws Exception {
+                        doAction();
+                        return null;
+                    }
+                    @Override
+                    protected void done() {
+                        hyperLinkLabel.setForeground(UIResources.getInstance().hyperlinkColor());
+                    }
+                }.execute();
+            }
+        }
+        
+        protected abstract void doAction();
+    }
+    
+    private class Mailer extends HyperLinkAction {
+        public Mailer(JLabel hyperLinkLabel) {
+            super(hyperLinkLabel);
+        }
+
+        @Override
+        protected void doAction() {
+            try {
+                Desktop.getDesktop().mail(new URI("mailto:" + email));
+            } catch (Exception ex) {
+                logger.log(Level.WARNING, "Cannot send mail to Thermosat mail", ex);
+            }
+        }
+    }
+    
+    private class Browse extends HyperLinkAction {
+        public Browse(JLabel hyperLinkLabel) {
+            super(hyperLinkLabel);
+        }
+        
+        @Override
+        protected void doAction() {
+            try {
+                Desktop.getDesktop().browse(new URI(website));
+            } catch (Exception ex) {
+                logger.log(Level.WARNING, "Cannot open Thermostat website URL", ex);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/ui/swing/WrapLayout.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2008 Rob Camick, 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+/*
+ * Taken from http://tips4java.wordpress.com/2008/11/06/wrap-layout/
+ *
+ * The about page (http://tips4java.wordpress.com/about/) says this:
+ * "You are free to use and/or modify any or all code posted on the Java Tips
+ * Weblog without restriction. A credit in the code comments would be nice,
+ * but not in any way mandatory."
+ */
+
+package com.redhat.thermostat.client.internal.ui.swing;
+
+import java.awt.*;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+
+/**
+ *  FlowLayout subclass that fully supports wrapping of components.
+ */
+public class WrapLayout extends FlowLayout {
+
+    private static final long serialVersionUID = -9169664895883997422L;
+
+    /**
+	* Constructs a new <code>WrapLayout</code> with a left
+	* alignment and a default 5-unit horizontal and vertical gap.
+	*/
+	public WrapLayout()
+	{
+		super();
+	}
+
+	/**
+	* Constructs a new <code>FlowLayout</code> with the specified
+	* alignment and a default 5-unit horizontal and vertical gap.
+	* The value of the alignment argument must be one of
+	* <code>WrapLayout</code>, <code>WrapLayout</code>,
+	* or <code>WrapLayout</code>.
+	* @param align the alignment value
+	*/
+	public WrapLayout(int align)
+	{
+		super(align);
+	}
+
+	/**
+	* Creates a new flow layout manager with the indicated alignment
+	* and the indicated horizontal and vertical gaps.
+	* <p>
+	* The value of the alignment argument must be one of
+	* <code>WrapLayout</code>, <code>WrapLayout</code>,
+	* or <code>WrapLayout</code>.
+	* @param align the alignment value
+	* @param hgap the horizontal gap between components
+	* @param vgap the vertical gap between components
+	*/
+	public WrapLayout(int align, int hgap, int vgap)
+	{
+		super(align, hgap, vgap);
+	}
+
+	/**
+	* Returns the preferred dimensions for this layout given the
+	* <i>visible</i> components in the specified target container.
+	* @param target the component which needs to be laid out
+	* @return the preferred dimensions to lay out the
+	* subcomponents of the specified container
+	*/
+	@Override
+	public Dimension preferredLayoutSize(Container target)
+	{
+		return layoutSize(target, true);
+	}
+
+	/**
+	* Returns the minimum dimensions needed to layout the <i>visible</i>
+	* components contained in the specified target container.
+	* @param target the component which needs to be laid out
+	* @return the minimum dimensions to lay out the
+	* subcomponents of the specified container
+	*/
+	@Override
+	public Dimension minimumLayoutSize(Container target)
+	{
+		Dimension minimum = layoutSize(target, false);
+		minimum.width -= (getHgap() + 1);
+		return minimum;
+	}
+
+	/**
+	* Returns the minimum or preferred dimension needed to layout the target
+	* container.
+	*
+	* @param target target to get layout size for
+	* @param preferred should preferred size be calculated
+	* @return the dimension to layout the target container
+	*/
+	private Dimension layoutSize(Container target, boolean preferred)
+	{
+	synchronized (target.getTreeLock())
+	{
+		//  Each row must fit with the width allocated to the containter.
+		//  When the container width = 0, the preferred width of the container
+		//  has not yet been calculated so lets ask for the maximum.
+
+		int targetWidth = target.getSize().width;
+
+		if (targetWidth == 0)
+			targetWidth = Integer.MAX_VALUE;
+
+		int hgap = getHgap();
+		int vgap = getVgap();
+		Insets insets = target.getInsets();
+		int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
+		int maxWidth = targetWidth - horizontalInsetsAndGap;
+
+		//  Fit components into the allowed width
+
+		Dimension dim = new Dimension(0, 0);
+		int rowWidth = 0;
+		int rowHeight = 0;
+
+		int nmembers = target.getComponentCount();
+
+		for (int i = 0; i < nmembers; i++)
+		{
+			Component m = target.getComponent(i);
+
+			if (m.isVisible())
+			{
+				Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
+
+				//  Can't add the component to current row. Start a new row.
+
+				if (rowWidth + d.width > maxWidth)
+				{
+					addRow(dim, rowWidth, rowHeight);
+					rowWidth = 0;
+					rowHeight = 0;
+				}
+
+				//  Add a horizontal gap for all components after the first
+
+				if (rowWidth != 0)
+				{
+					rowWidth += hgap;
+				}
+
+				rowWidth += d.width;
+				rowHeight = Math.max(rowHeight, d.height);
+			}
+		}
+
+		addRow(dim, rowWidth, rowHeight);
+
+		dim.width += horizontalInsetsAndGap;
+		dim.height += insets.top + insets.bottom + vgap * 2;
+
+		//	When using a scroll pane or the DecoratedLookAndFeel we need to
+		//  make sure the preferred size is less than the size of the
+		//  target containter so shrinking the container size works
+		//  correctly. Removing the horizontal gap is an easy way to do this.
+
+		Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);
+
+		if (scrollPane != null)
+		{
+			dim.width -= (hgap + 1);
+		}
+
+		return dim;
+	}
+	}
+
+	/*
+	 *  A new row has been completed. Use the dimensions of this row
+	 *  to update the preferred size for the container.
+	 *
+	 *  @param dim update the width and height when appropriate
+	 *  @param rowWidth the width of the row to add
+	 *  @param rowHeight the height of the row to add
+	 */
+	private void addRow(Dimension dim, int rowWidth, int rowHeight)
+	{
+		dim.width = Math.max(dim.width, rowWidth);
+
+		if (dim.height > 0)
+		{
+			dim.height += getVgap();
+		}
+
+		dim.height += rowHeight;
+	}
+}
--- a/client/core/src/main/java/com/redhat/thermostat/client/osgi/ApplicationServiceProvider.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.osgi;
-
-import com.redhat.thermostat.client.osgi.service.ApplicationService;
-import com.redhat.thermostat.common.appctx.ApplicationContext;
-import com.redhat.thermostat.common.dao.DAOFactory;
-
-
-public class ApplicationServiceProvider implements ApplicationService {
-
-    @Override
-    public DAOFactory getDAOFactory() {
-        // TODO: Eventually we will no longer need a singleton for ApplicationContext!
-        return ApplicationContext.getInstance().getDAOFactory();
-    }
-
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/osgi/ContextActionServiceProvider.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.osgi;
-
-import com.redhat.thermostat.client.osgi.service.ContextAction;
-
-public class ContextActionServiceProvider implements ContextAction {
-  
-    @Override
-    public String getName() {
-        return "system context";
-    }
-
-    @Override
-    public String getDescription() {
-        return "system context";
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/osgi/ThermostatActivator.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.osgi;
-
-import java.util.Arrays;
-
-import org.osgi.framework.BundleActivator;
-import org.osgi.framework.BundleContext;
-
-import com.redhat.thermostat.client.GUIClientCommand;
-import com.redhat.thermostat.client.Main;
-import com.redhat.thermostat.client.UiFacadeFactory;
-import com.redhat.thermostat.client.UiFacadeFactoryImpl;
-import com.redhat.thermostat.common.cli.CommandRegistry;
-import com.redhat.thermostat.common.cli.CommandRegistryImpl;
-
-public class ThermostatActivator implements BundleActivator {
-
-    private VmInformationServiceTracker vmInfoServiceTracker;
-    private VMContextActionServiceTracker contextActionTracker;
-
-    private CommandRegistry cmdReg;
-
-    @Override
-    public void start(final BundleContext context) throws Exception {
-        UiFacadeFactory uiFacadeFactory = new UiFacadeFactoryImpl(context);
-
-        vmInfoServiceTracker = new VmInformationServiceTracker(context, uiFacadeFactory);
-        vmInfoServiceTracker.open();
-
-        contextActionTracker =
-                new VMContextActionServiceTracker(context, uiFacadeFactory);
-        contextActionTracker.open();
-
-        cmdReg = new CommandRegistryImpl(context);
-        Main main = new Main(uiFacadeFactory, new String[0]);
-        cmdReg.registerCommands(Arrays.asList(new GUIClientCommand(main)));
-    }
-
-    @Override
-    public void stop(BundleContext context) throws Exception {
-        vmInfoServiceTracker.close(); //context.removeServiceListener(vmInfoServiceTracker);
-        contextActionTracker.close();
-        cmdReg.unregisterCommands();
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/osgi/VMContextActionServiceTracker.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,67 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.osgi;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-
-import com.redhat.thermostat.client.UiFacadeFactory;
-import com.redhat.thermostat.client.osgi.service.VMContextAction;
-
-@SuppressWarnings("rawtypes")
-class VMContextActionServiceTracker extends ServiceTracker {
-
-    private UiFacadeFactory uiFacadeFactory;
-
-    private BundleContext context;
-
-    @SuppressWarnings("unchecked")
-    VMContextActionServiceTracker(BundleContext context, UiFacadeFactory uiFacadeFactory) {
-        super(context, VMContextAction.class.getName(), null);
-        this.context = context;
-        this.uiFacadeFactory = uiFacadeFactory;
-    }
-
-    @Override
-    public Object addingService(ServiceReference reference) {
-        @SuppressWarnings("unchecked")
-        VMContextAction service = (VMContextAction) context.getService(reference);
-        uiFacadeFactory.addVMContextAction(service);
-        return service;
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/osgi/VmInformationServiceTracker.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,65 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.osgi;
-
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceReference;
-import org.osgi.util.tracker.ServiceTracker;
-
-import com.redhat.thermostat.client.UiFacadeFactory;
-import com.redhat.thermostat.client.osgi.service.VmInformationService;
-
-class VmInformationServiceTracker extends ServiceTracker {
-
-    private UiFacadeFactory uiFacadeFactory;
-
-    private BundleContext context;
-
-    VmInformationServiceTracker(BundleContext context, UiFacadeFactory uiFacadeFactory) {
-        super(context, VmInformationService.class.getName(), null);
-        this.context = context;
-        this.uiFacadeFactory = uiFacadeFactory;
-    }
-
-    @Override
-    public Object addingService(ServiceReference reference) {
-        VmInformationService service = (VmInformationService) context.getService(reference);
-        uiFacadeFactory.addVmInformationService(service);
-        return service;
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/AboutDialog.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,286 +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 com.redhat.thermostat.client.locale.Translate.localize;
-
-import java.awt.Cursor;
-import java.awt.Desktop;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.net.URI;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.swing.GroupLayout;
-import javax.swing.GroupLayout.Alignment;
-import javax.swing.Icon;
-import javax.swing.JButton;
-import javax.swing.JDialog;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.LayoutStyle.ComponentPlacement;
-import javax.swing.SwingConstants;
-import javax.swing.SwingWorker;
-
-import javax.swing.border.TitledBorder;
-
-import com.redhat.thermostat.client.ApplicationInfo;
-import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.common.utils.LoggingUtils;
-
-public class AboutDialog extends JDialog {
-
-    private static final long serialVersionUID = -7611616871710076514L;
-
-    private static final Logger logger = LoggingUtils.getLogger(AboutDialog.class);
-
-    private String name;
-    private String description;
-    private String version;
-    private Icon icon;
-    private String copyright;
-    private String license;
-    private String website;
-    private String email;
-    
-    /**
-     * Create the dialog.
-     * @param applicationInfo 
-     */
-    public AboutDialog(ApplicationInfo appInfo) {
-        setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
-        setResizable(false);
-        
-        name = appInfo.getName();
-        description = appInfo.getDescription();
-        version = appInfo.getVersion();
-        icon = IconResource.QUESTION.getIcon(); // TODO appInfo.getIcon();
-        copyright = appInfo.getCopyright();
-        license = appInfo.getLicenseSummary();
-        website = appInfo.getWebsite();
-        email = appInfo.getEmail();
-        
-        initComponents();
-    }
-    
-    private void initComponents() {
-        setBounds(100, 100, 450, 338);
-        
-        UIResources res = UIResources.getInstance();
-        
-        JPanel panel = new JPanel();
-        panel.setBorder(new TitledBorder(""));
-        
-        JButton closeButton = new JButton(localize(LocaleResources.BUTTON_CLOSE));
-        closeButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                AboutDialog.this.setVisible(false);
-                AboutDialog.this.dispose();  
-            }
-        });
-        
-        GroupLayout groupLayout = new GroupLayout(getContentPane());
-        groupLayout.setHorizontalGroup(
-            groupLayout.createParallelGroup(Alignment.TRAILING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addGroup(groupLayout.createParallelGroup(Alignment.TRAILING)
-                        .addComponent(closeButton, GroupLayout.PREFERRED_SIZE, 92, GroupLayout.PREFERRED_SIZE)
-                        .addComponent(panel, GroupLayout.DEFAULT_SIZE, 424, Short.MAX_VALUE))
-                    .addContainerGap())
-        );
-        groupLayout.setVerticalGroup(
-            groupLayout.createParallelGroup(Alignment.LEADING)
-                .addGroup(groupLayout.createSequentialGroup()
-                    .addContainerGap()
-                    .addComponent(panel, GroupLayout.DEFAULT_SIZE, 245, Short.MAX_VALUE)
-                    .addGap(18)
-                    .addComponent(closeButton)
-                    .addGap(9))
-        );
-        
-        JLabel iconLabel = new JLabel("");
-        iconLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        
-        iconLabel.setIcon(icon);
-        
-        JLabel versionLabel = new JLabel(version);
-        versionLabel.setFont(res.footerFont());
-        versionLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        
-        JLabel nameLabel = new JLabel(name);
-        nameLabel.setFont(res.headerFont());
-        nameLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        
-        JLabel descriptionLabel = new JLabel(description);
-        descriptionLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        descriptionLabel.setFont(res.standardFont());
-        
-        JLabel homePageLabel = new JLabel(website);
-        homePageLabel.setForeground(res.hyperlinkColor());
-        homePageLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        homePageLabel.setFont(res.footerFont());        
-        homePageLabel.addMouseListener(new Browse(homePageLabel));
-
-        JLabel copyrightLabel = new JLabel(copyright);
-        copyrightLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        copyrightLabel.setFont(res.footerFont());
-        
-        JLabel licenseString = new JLabel(license);
-        licenseString.setHorizontalAlignment(SwingConstants.CENTER);
-        licenseString.setFont(res.footerFont());
-        
-        JLabel emailLabel = new JLabel(email);
-        emailLabel.setHorizontalAlignment(SwingConstants.CENTER);
-        emailLabel.setForeground(res.hyperlinkColor());
-        emailLabel.setFont(res.footerFont());
-        emailLabel.addMouseListener(new Mailer(emailLabel));
-        
-        GroupLayout gl_panel = new GroupLayout(panel);
-        gl_panel.setHorizontalGroup(
-            gl_panel.createParallelGroup(Alignment.TRAILING)
-                .addGroup(gl_panel.createSequentialGroup()
-                    .addContainerGap()
-                    .addGroup(gl_panel.createParallelGroup(Alignment.LEADING)
-                        .addComponent(iconLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(nameLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(versionLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(descriptionLabel, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(copyrightLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(licenseString, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(emailLabel, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE)
-                        .addComponent(homePageLabel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 398, Short.MAX_VALUE))
-                    .addContainerGap())
-        );
-        gl_panel.setVerticalGroup(
-            gl_panel.createParallelGroup(Alignment.LEADING)
-                .addGroup(gl_panel.createSequentialGroup()
-                    .addContainerGap()
-                    .addComponent(iconLabel)
-                    .addGap(4)
-                    .addComponent(nameLabel, GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addComponent(versionLabel, GroupLayout.DEFAULT_SIZE, 13, Short.MAX_VALUE)
-                    .addPreferredGap(ComponentPlacement.UNRELATED)
-                    .addComponent(descriptionLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
-                    .addGap(12)
-                    .addComponent(homePageLabel, GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE)
-                    .addGap(3)
-                    .addComponent(emailLabel, GroupLayout.DEFAULT_SIZE, 19, Short.MAX_VALUE)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addComponent(copyrightLabel, GroupLayout.DEFAULT_SIZE, 13, Short.MAX_VALUE)
-                    .addPreferredGap(ComponentPlacement.RELATED)
-                    .addComponent(licenseString, GroupLayout.DEFAULT_SIZE, 13, Short.MAX_VALUE)
-                    .addContainerGap())
-        );
-        panel.setLayout(gl_panel);
-        getContentPane().setLayout(groupLayout);
-    }
-    
-    private abstract class HyperLinkAction extends MouseAdapter {
-        
-        private JLabel hyperLinkLabel;
-        public HyperLinkAction(JLabel hyperLinkLabel) {
-            this.hyperLinkLabel = hyperLinkLabel;
-        }
-        
-        @Override
-        public void mouseEntered(MouseEvent e) {
-            hyperLinkLabel.setForeground(UIResources.getInstance().hyperlinkActiveColor());
-            Cursor cursor = new Cursor(Cursor.HAND_CURSOR);
-            setCursor(cursor);
-        }
-        @Override
-        public void mouseExited(MouseEvent e) {
-            hyperLinkLabel.setForeground(UIResources.getInstance().hyperlinkColor());
-            Cursor cursor = new Cursor(Cursor.DEFAULT_CURSOR);
-            setCursor(cursor);
-        }
-        
-        @Override
-        public void mouseClicked(MouseEvent e) {
-            if (Desktop.isDesktopSupported()) {
-                new SwingWorker<Void, Void>() {
-                    @Override
-                    protected Void doInBackground() throws Exception {
-                        doAction();
-                        return null;
-                    }
-                    @Override
-                    protected void done() {
-                        hyperLinkLabel.setForeground(UIResources.getInstance().hyperlinkColor());
-                    }
-                }.execute();
-            }
-        }
-        
-        protected abstract void doAction();
-    }
-    
-    private class Mailer extends HyperLinkAction {
-        public Mailer(JLabel hyperLinkLabel) {
-            super(hyperLinkLabel);
-        }
-
-        @Override
-        protected void doAction() {
-            try {
-                Desktop.getDesktop().mail(new URI("mailto:" + email));
-            } catch (Exception ex) {
-                logger.log(Level.WARNING, "Cannot send mail to Thermosat mail", ex);
-            }
-        }
-    }
-    
-    private class Browse extends HyperLinkAction {
-        public Browse(JLabel hyperLinkLabel) {
-            super(hyperLinkLabel);
-        }
-        
-        @Override
-        protected void doAction() {
-            try {
-                Desktop.getDesktop().browse(new URI(website));
-            } catch (Exception ex) {
-                logger.log(Level.WARNING, "Cannot open Thermostat website URL", ex);
-            }
-        }
-    }
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/AgentConfigurationModel.java	Tue Jun 12 14:02:16 2012 -0400
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/AgentConfigurationModel.java	Tue Jun 12 21:26:04 2012 +0200
@@ -44,7 +44,7 @@
 import java.util.Map;
 import java.util.Map.Entry;
 
-import com.redhat.thermostat.client.AgentConfigurationSource;
+import com.redhat.thermostat.client.internal.AgentConfigurationSource;
 
 /**
  * This model sits between the current view and the remote model, and allows
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostMemoryPanel.java	Tue Jun 12 14:02:16 2012 -0400
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/HostMemoryPanel.java	Tue Jun 12 21:26:04 2012 +0200
@@ -61,6 +61,7 @@
 import org.jfree.data.time.TimeSeries;
 import org.jfree.data.time.TimeSeriesCollection;
 
+import com.redhat.thermostat.client.internal.ui.swing.WrapLayout;
 import com.redhat.thermostat.client.locale.LocaleResources;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.ActionNotifier;
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostOverviewPanel.java	Tue Jun 12 14:02:16 2012 -0400
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/HostOverviewPanel.java	Tue Jun 12 21:26:04 2012 +0200
@@ -48,7 +48,7 @@
 import javax.swing.JTable;
 import javax.swing.table.DefaultTableModel;
 
-import com.redhat.thermostat.client.ChangeableText;
+import com.redhat.thermostat.client.internal.ChangeableText;
 import com.redhat.thermostat.client.locale.LocaleResources;
 import com.redhat.thermostat.client.ui.SimpleTable.Key;
 import com.redhat.thermostat.client.ui.SimpleTable.Section;
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostPanel.java	Tue Jun 12 14:02:16 2012 -0400
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/HostPanel.java	Tue Jun 12 21:26:04 2012 +0200
@@ -43,7 +43,7 @@
 import javax.swing.JPanel;
 import javax.swing.JTabbedPane;
 
-import com.redhat.thermostat.client.HostPanelFacade;
+import com.redhat.thermostat.client.internal.HostPanelFacade;
 import com.redhat.thermostat.client.locale.LocaleResources;
 
 public class HostPanel extends JPanel {
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/MainWindow.java	Tue Jun 12 14:02:16 2012 -0400
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/MainWindow.java	Tue Jun 12 21:26:04 2012 +0200
@@ -101,8 +101,8 @@
 import javax.swing.tree.TreePath;
 import javax.swing.tree.TreeSelectionModel;
 
-import com.redhat.thermostat.client.HostsVMsLoader;
-import com.redhat.thermostat.client.MainView;
+import com.redhat.thermostat.client.internal.HostsVMsLoader;
+import com.redhat.thermostat.client.internal.MainView;
 import com.redhat.thermostat.client.locale.LocaleResources;
 import com.redhat.thermostat.client.osgi.service.MenuAction;
 import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/SimpleTable.java	Tue Jun 12 14:02:16 2012 -0400
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/SimpleTable.java	Tue Jun 12 21:26:04 2012 +0200
@@ -57,7 +57,7 @@
 import javax.swing.JTextField;
 import javax.swing.SwingUtilities;
 
-import com.redhat.thermostat.client.ChangeableText;
+import com.redhat.thermostat.client.internal.ChangeableText;
 
 public class SimpleTable implements ChangeableText.TextListener {
 
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/VmInformationController.java	Tue Jun 12 14:02:16 2012 -0400
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/VmInformationController.java	Tue Jun 12 21:26:04 2012 +0200
@@ -41,7 +41,7 @@
 import java.awt.Component;
 import java.util.Collection;
 
-import com.redhat.thermostat.client.UiFacadeFactory;
+import com.redhat.thermostat.client.internal.UiFacadeFactory;
 import com.redhat.thermostat.client.locale.LocaleResources;
 import com.redhat.thermostat.client.osgi.service.VmInformationService;
 import com.redhat.thermostat.client.osgi.service.VmInformationServiceController;
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/VmOverviewPanel.java	Tue Jun 12 14:02:16 2012 -0400
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/VmOverviewPanel.java	Tue Jun 12 21:26:04 2012 +0200
@@ -45,7 +45,7 @@
 
 import javax.swing.JPanel;
 
-import com.redhat.thermostat.client.ChangeableText;
+import com.redhat.thermostat.client.internal.ChangeableText;
 import com.redhat.thermostat.client.locale.LocaleResources;
 import com.redhat.thermostat.client.ui.SimpleTable.Section;
 import com.redhat.thermostat.client.ui.SimpleTable.TableEntry;
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/WrapLayout.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,229 +0,0 @@
-/*
- * Copyright 2008 Rob Camick, 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-/*
- * Taken from http://tips4java.wordpress.com/2008/11/06/wrap-layout/
- *
- * The about page (http://tips4java.wordpress.com/about/) says this:
- * "You are free to use and/or modify any or all code posted on the Java Tips
- * Weblog without restriction. A credit in the code comments would be nice,
- * but not in any way mandatory."
- */
-
-package com.redhat.thermostat.client.ui;
-
-import java.awt.*;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-
-/**
- *  FlowLayout subclass that fully supports wrapping of components.
- */
-public class WrapLayout extends FlowLayout {
-
-    private static final long serialVersionUID = -9169664895883997422L;
-
-    /**
-	* Constructs a new <code>WrapLayout</code> with a left
-	* alignment and a default 5-unit horizontal and vertical gap.
-	*/
-	public WrapLayout()
-	{
-		super();
-	}
-
-	/**
-	* Constructs a new <code>FlowLayout</code> with the specified
-	* alignment and a default 5-unit horizontal and vertical gap.
-	* The value of the alignment argument must be one of
-	* <code>WrapLayout</code>, <code>WrapLayout</code>,
-	* or <code>WrapLayout</code>.
-	* @param align the alignment value
-	*/
-	public WrapLayout(int align)
-	{
-		super(align);
-	}
-
-	/**
-	* Creates a new flow layout manager with the indicated alignment
-	* and the indicated horizontal and vertical gaps.
-	* <p>
-	* The value of the alignment argument must be one of
-	* <code>WrapLayout</code>, <code>WrapLayout</code>,
-	* or <code>WrapLayout</code>.
-	* @param align the alignment value
-	* @param hgap the horizontal gap between components
-	* @param vgap the vertical gap between components
-	*/
-	public WrapLayout(int align, int hgap, int vgap)
-	{
-		super(align, hgap, vgap);
-	}
-
-	/**
-	* Returns the preferred dimensions for this layout given the
-	* <i>visible</i> components in the specified target container.
-	* @param target the component which needs to be laid out
-	* @return the preferred dimensions to lay out the
-	* subcomponents of the specified container
-	*/
-	@Override
-	public Dimension preferredLayoutSize(Container target)
-	{
-		return layoutSize(target, true);
-	}
-
-	/**
-	* Returns the minimum dimensions needed to layout the <i>visible</i>
-	* components contained in the specified target container.
-	* @param target the component which needs to be laid out
-	* @return the minimum dimensions to lay out the
-	* subcomponents of the specified container
-	*/
-	@Override
-	public Dimension minimumLayoutSize(Container target)
-	{
-		Dimension minimum = layoutSize(target, false);
-		minimum.width -= (getHgap() + 1);
-		return minimum;
-	}
-
-	/**
-	* Returns the minimum or preferred dimension needed to layout the target
-	* container.
-	*
-	* @param target target to get layout size for
-	* @param preferred should preferred size be calculated
-	* @return the dimension to layout the target container
-	*/
-	private Dimension layoutSize(Container target, boolean preferred)
-	{
-	synchronized (target.getTreeLock())
-	{
-		//  Each row must fit with the width allocated to the containter.
-		//  When the container width = 0, the preferred width of the container
-		//  has not yet been calculated so lets ask for the maximum.
-
-		int targetWidth = target.getSize().width;
-
-		if (targetWidth == 0)
-			targetWidth = Integer.MAX_VALUE;
-
-		int hgap = getHgap();
-		int vgap = getVgap();
-		Insets insets = target.getInsets();
-		int horizontalInsetsAndGap = insets.left + insets.right + (hgap * 2);
-		int maxWidth = targetWidth - horizontalInsetsAndGap;
-
-		//  Fit components into the allowed width
-
-		Dimension dim = new Dimension(0, 0);
-		int rowWidth = 0;
-		int rowHeight = 0;
-
-		int nmembers = target.getComponentCount();
-
-		for (int i = 0; i < nmembers; i++)
-		{
-			Component m = target.getComponent(i);
-
-			if (m.isVisible())
-			{
-				Dimension d = preferred ? m.getPreferredSize() : m.getMinimumSize();
-
-				//  Can't add the component to current row. Start a new row.
-
-				if (rowWidth + d.width > maxWidth)
-				{
-					addRow(dim, rowWidth, rowHeight);
-					rowWidth = 0;
-					rowHeight = 0;
-				}
-
-				//  Add a horizontal gap for all components after the first
-
-				if (rowWidth != 0)
-				{
-					rowWidth += hgap;
-				}
-
-				rowWidth += d.width;
-				rowHeight = Math.max(rowHeight, d.height);
-			}
-		}
-
-		addRow(dim, rowWidth, rowHeight);
-
-		dim.width += horizontalInsetsAndGap;
-		dim.height += insets.top + insets.bottom + vgap * 2;
-
-		//	When using a scroll pane or the DecoratedLookAndFeel we need to
-		//  make sure the preferred size is less than the size of the
-		//  target containter so shrinking the container size works
-		//  correctly. Removing the horizontal gap is an easy way to do this.
-
-		Container scrollPane = SwingUtilities.getAncestorOfClass(JScrollPane.class, target);
-
-		if (scrollPane != null)
-		{
-			dim.width -= (hgap + 1);
-		}
-
-		return dim;
-	}
-	}
-
-	/*
-	 *  A new row has been completed. Use the dimensions of this row
-	 *  to update the preferred size for the container.
-	 *
-	 *  @param dim update the width and height when appropriate
-	 *  @param rowWidth the width of the row to add
-	 *  @param rowHeight the height of the row to add
-	 */
-	private void addRow(Dimension dim, int rowWidth, int rowHeight)
-	{
-		dim.width = Math.max(dim.width, rowWidth);
-
-		if (dim.height > 0)
-		{
-			dim.height += getVgap();
-		}
-
-		dim.height += rowHeight;
-	}
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/DefaultViewFactoryTest.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.common.View;
-
-public class DefaultViewFactoryTest {
-
-    public static class MockView implements View {}
-
-    @Test
-    public void testGetUnknownClasses() {
-        DefaultViewFactory factory = new DefaultViewFactory();
-        assertEquals(null, factory.getView(MockView.class));
-    }
-
-    @Test
-    public void testSetAndGet() {
-        DefaultViewFactory factory = new DefaultViewFactory();
-        factory.setViewClass(MockView.class, MockView.class);
-        assertEquals(MockView.class, factory.getViewClass(MockView.class));
-    }
-
-    @Test
-    public void testInstantiation() {
-        DefaultViewFactory factory = new DefaultViewFactory();
-        factory.setViewClass(MockView.class, MockView.class);
-        MockView view = factory.getView(MockView.class);
-        assertNotNull(view);
-        assertEquals(MockView.class.getName(), view.getClass().getName());
-    }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/GUIClientCommandTest.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,117 +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;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isNotNull;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.util.Dictionary;
-
-import org.junit.After;
-import org.junit.Before;
-import org.junit.Test;
-import org.osgi.framework.BundleContext;
-
-import com.redhat.thermostat.client.osgi.service.ApplicationService;
-import com.redhat.thermostat.client.osgi.service.ContextAction;
-import com.redhat.thermostat.common.cli.CommandContext;
-import com.redhat.thermostat.common.cli.CommandContextFactory;
-import com.redhat.thermostat.common.cli.CommandException;
-
-public class GUIClientCommandTest {
-
-    private GUIClientCommand cmd;
-    private Main clientMain;
-
-    @Before
-    public void setUp() {
-        clientMain = mock(Main.class);
-        cmd = new GUIClientCommand(clientMain);
-    }
-
-    @After
-    public void tearDown() {
-        cmd = null;
-        clientMain = null;
-    }
-
-    @Test
-    public void testRun() throws CommandException {
-        BundleContext bCtx = mock(BundleContext.class);
-        CommandContextFactory cmdCtxFactory = mock(CommandContextFactory.class);
-        when(cmdCtxFactory.getBundleContext()).thenReturn(bCtx);
-        CommandContext cmdCtx = mock(CommandContext.class);
-        when(cmdCtx.getCommandContextFactory()).thenReturn(cmdCtxFactory);
-
-        cmd.run(cmdCtx);
-
-        verify(clientMain).run();
-        verify(bCtx).registerService(eq(ApplicationService.class.getName()), isNotNull(), any(Dictionary.class));
-        verify(bCtx).registerService(eq(ContextAction.class.getName()), isNotNull(), any(Dictionary.class));
-    }
-
-    @Test
-    public void testName() {
-        assertEquals("gui", cmd.getName());
-    }
-
-    @Test
-    public void testDescription() {
-        assertEquals("launches the GUI client", cmd.getDescription());
-    }
-
-    @Test
-    public void testUsage() {
-        assertEquals("launches the GUI client", cmd.getUsage());
-    }
-
-    @Test
-    public void testAcceptedArguments() {
-        assertEquals(0, cmd.getAcceptedArguments().size());
-    }
-
-    @Test
-    public void testRequiresStorage() {
-        assertFalse(cmd.isStorageRequired());
-    }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/MainWindowControllerImplTest.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,459 +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;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.isA;
-import static org.mockito.Mockito.doNothing;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import java.awt.Component;
-import java.awt.event.MouseEvent;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.List;
-import java.util.concurrent.TimeUnit;
-
-import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.BundleException;
-import org.osgi.util.tracker.ServiceTracker;
-
-import com.redhat.thermostat.client.osgi.service.Filter;
-import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
-import com.redhat.thermostat.client.osgi.service.VMContextAction;
-import com.redhat.thermostat.client.ui.SummaryController;
-import com.redhat.thermostat.client.ui.SummaryView;
-import com.redhat.thermostat.client.ui.VmInformationController;
-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.ViewFactory;
-import com.redhat.thermostat.common.appctx.ApplicationContext;
-import com.redhat.thermostat.common.appctx.ApplicationContextUtil;
-import com.redhat.thermostat.common.dao.DAOFactory;
-import com.redhat.thermostat.common.dao.HostInfoDAO;
-import com.redhat.thermostat.common.dao.HostRef;
-import com.redhat.thermostat.common.dao.VmInfoDAO;
-import com.redhat.thermostat.common.dao.VmRef;
-import com.redhat.thermostat.common.model.VmInfo;
-import com.redhat.thermostat.test.Bug;
-
-public class MainWindowControllerImplTest {
-
-    private ActionListener<MainView.Action> l;
-
-    private MainWindowControllerImpl controller;
-
-    private UiFacadeFactory uiFacadeFactory;
-
-    private MainView view;
-
-    private Timer mainWindowTimer;
-
-    private HostInfoDAO mockHostsDAO;
-    private VmInfoDAO mockVmsDAO;
-
-    private VMContextAction action1;
-    private VMContextAction action2;
-
-    private VMTreeFilterRegistry filters;
-    private VMTreeDecoratorRegistry decorators;
-    private MenuRegistry menues;
-    
-    private ActionListener<ThermostatExtensionRegistry.Action> filtersListener;
-    private ActionListener<ThermostatExtensionRegistry.Action> decoratorsListener;
-    
-    @BeforeClass
-    public static void setUpOnce() {
-        // TODO remove when controller uses mocked objects rather than real swing objects
-        FailOnThreadViolationRepaintManager.install();
-    }
-
-    @SuppressWarnings({ "unchecked", "rawtypes" }) // ActionListener fluff
-    @Before
-    public void setUp() throws Exception {
-        ApplicationContextUtil.resetApplicationContext();
-
-        // Setup timers
-        mainWindowTimer = mock(Timer.class);
-        Timer otherTimer = mock(Timer.class); // FIXME needed for SummaryView; remove later
-        TimerFactory timerFactory = mock(TimerFactory.class);
-        when(timerFactory.createTimer()).thenReturn(mainWindowTimer).thenReturn(otherTimer);
-        ApplicationContext.getInstance().setTimerFactory(timerFactory);
-
-        SummaryController summaryController = mock(SummaryController.class);
-
-        uiFacadeFactory = mock(UiFacadeFactory.class);
-        when(uiFacadeFactory.getSummary()).thenReturn(summaryController);
-        setupDAOs();
-
-        // Setup View
-        view = mock(MainView.class);
-        ArgumentCaptor<ActionListener> grabListener = ArgumentCaptor.forClass(ActionListener.class);
-        doNothing().when(view).addActionListener(grabListener.capture());
-        
-        RegistryFactory registryFactory = mock(RegistryFactory.class);
-        filters = mock(VMTreeFilterRegistry.class);
-        decorators = mock(VMTreeDecoratorRegistry.class);
-        menues = mock(MenuRegistry.class);
-
-        when(registryFactory.createMenuRegistry()).thenReturn(menues);
-        when(registryFactory.createVMTreeDecoratorRegistry()).thenReturn(decorators);
-        when(registryFactory.createVMTreeFilterRegistry()).thenReturn(filters);
-        
-        ArgumentCaptor<ActionListener> grabFiltersListener = ArgumentCaptor.forClass(ActionListener.class);
-        doNothing().when(filters).addActionListener(grabFiltersListener.capture());
-
-        ArgumentCaptor<ActionListener> grabDecoratorsListener = ArgumentCaptor.forClass(ActionListener.class);
-        doNothing().when(decorators).addActionListener(grabDecoratorsListener.capture());
-        
-        // TODO remove this asap. the main window has a hard dependency on summary controller/view
-        ViewFactory viewFactory = mock(ViewFactory.class);
-        SummaryView summaryView = mock(SummaryView.class);
-        when(viewFactory.getView(SummaryView.class)).thenReturn(summaryView);
-        ApplicationContext.getInstance().setViewFactory(viewFactory);
-
-        setUpVMContextActions();
-
-        controller = new MainWindowControllerImpl(uiFacadeFactory, view, registryFactory);
-        l = grabListener.getValue();
-        
-        filtersListener = grabFiltersListener.getValue();
-        decoratorsListener = grabDecoratorsListener.getValue();
-    }
-
-    private void setUpVMContextActions() {
-        action1 = mock(VMContextAction.class);
-        Filter action1Filter = mock(Filter.class);
-        when(action1Filter.matches(isA(VmRef.class))).thenReturn(true);
-
-        when(action1.getName()).thenReturn("action1");
-        when(action1.getDescription()).thenReturn("action1desc");
-        when(action1.getFilter()).thenReturn(action1Filter);
-        
-        action2 = mock(VMContextAction.class);
-        Filter action2Filter = mock(Filter.class);
-        when(action2Filter.matches(isA(VmRef.class))).thenReturn(false);
-
-        when(action2.getName()).thenReturn("action2");
-        when(action2.getDescription()).thenReturn("action2desc");
-        when(action2.getFilter()).thenReturn(action2Filter);
-        
-        Collection<VMContextAction> actions = new ArrayList<>();
-        actions.add(action1);
-        actions.add(action2);
-        
-        when(uiFacadeFactory.getVMContextActions()).thenReturn(actions);
-    }
-    
-    private void setupDAOs() {
-        mockHostsDAO = mock(HostInfoDAO.class);
-        mockVmsDAO = mock(VmInfoDAO.class);
-
-        DAOFactory daoFactory = mock(DAOFactory.class);
-        when(daoFactory.getHostInfoDAO()).thenReturn(mockHostsDAO);
-        when(daoFactory.getVmInfoDAO()).thenReturn(mockVmsDAO);
-        ApplicationContext.getInstance().setDAOFactory(daoFactory);
-
-    }
-
-    @After
-    public void tearDown() {
-        view = null;
-        controller = null;
-        mockHostsDAO = null;
-        mockVmsDAO = null;
-        l = null;
-        ApplicationContextUtil.resetApplicationContext();
-    }
-
-    @Test
-    public void verifyDecoratorsAdded() {
-
-        List<ReferenceDecorator> currentDecoratros = controller.getVmTreeDecorators();
-        assertEquals(0, currentDecoratros.size());
-        
-        ActionEvent<ThermostatExtensionRegistry.Action> event =
-                new ActionEvent<ThermostatExtensionRegistry.Action>(decorators,
-                        ThermostatExtensionRegistry.Action.SERVICE_ADDED);
-        
-        ReferenceDecorator payload = mock(ReferenceDecorator.class);
-        event.setPayload(payload);
-        
-        decoratorsListener.actionPerformed(event);
-
-        currentDecoratros = controller.getVmTreeDecorators();
-        assertEquals(1, currentDecoratros.size());
-        assertEquals(payload, currentDecoratros.get(0));
-        
-        verify(view).updateTree(any(List.class), any(List.class), any(HostsVMsLoader.class));
-    }
-    
-    @Test
-    public void verifyThatHiddenEventStopsController() {
-
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HIDDEN));
-
-        verify(mainWindowTimer).stop();
-    }
-
-    @Test
-    public void verifyThatHostsVmsFilterChangeUpdatesTree() {
-
-        when(view.getHostVmTreeFilterText()).thenReturn("test");
-
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_TREE_FILTER));
-
-        verify(view).updateTree(any(List.class), any(List.class), any(HostsVMsLoader.class));
-    }
-    
-    @Test
-    public void verifyTimerGetsStartedOnBecomingVisible() {
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.VISIBLE));
-
-        verify(mainWindowTimer).setDelay(3);
-        verify(mainWindowTimer).setTimeUnit(TimeUnit.SECONDS);
-        verify(mainWindowTimer).setSchedulingType(SchedulingType.FIXED_RATE);
-        verify(mainWindowTimer).start();
-    }
-
-    @Test
-    public void verifyShowMainWindowActuallyCallsView() {
-        controller.showMainMainWindow();
-        verify(view).showMainWindow();
-    }
-
-    @Test
-    public void verifySubViewIsSetByDefault() throws InvocationTargetException, InterruptedException {
-        verify(view).setSubView(any(Component.class));
-    }
-
-    @Test
-    public void verifyUpdateHostsVMsLoadsCorrectHosts() {
-
-        Collection<HostRef> expectedHosts = new ArrayList<>();
-        expectedHosts.add(new HostRef("123", "fluffhost1"));
-        expectedHosts.add(new HostRef("456", "fluffhost2"));
-
-        when(mockHostsDAO.getAliveHosts()).thenReturn(expectedHosts);
-
-        controller.doUpdateTreeAsync();
-
-        ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
-        verify(view).updateTree(any(List.class), any(List.class), arg.capture());
-        HostsVMsLoader loader = arg.getValue();
-
-        Collection<HostRef> actualHosts = loader.getHosts();
-        assertEqualCollection(expectedHosts, actualHosts);
-    }
-    
-    @Test
-    public void verifyHistoryModeUpdateHostsVMCorrectly() {
-
-        Collection<HostRef> liveHost = new ArrayList<>();
-        liveHost.add(new HostRef("123", "fluffhost1"));
-        liveHost.add(new HostRef("456", "fluffhost2"));
-
-        Collection<HostRef> allHosts = new ArrayList<>();
-        allHosts.addAll(liveHost);
-        allHosts.add(new HostRef("789", "fluffhost3"));
-
-        when(mockHostsDAO.getAliveHosts()).thenReturn(liveHost);
-        when(mockHostsDAO.getHosts()).thenReturn(allHosts);
-
-        controller.doUpdateTreeAsync();
-
-        ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
-        verify(view).updateTree(any(List.class), any(List.class), arg.capture());
-        HostsVMsLoader loader = arg.getValue();
-
-        Collection<HostRef> actualHosts = loader.getHosts();
-        assertEqualCollection(liveHost, actualHosts);
-
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.SWITCH_HISTORY_MODE));
-
-        actualHosts = loader.getHosts();
-        assertEqualCollection(allHosts, actualHosts);
-    }
-
-    @Test
-    public void verifyUpdateHostsVMsLoadsCorrectVMs() {
-
-        Collection<VmRef> expectedVMs = new ArrayList<>();
-        HostRef host = new HostRef("123", "fluffhost1");
-        expectedVMs.add(new VmRef(host, 123, "vm1"));
-        expectedVMs.add(new VmRef(host, 456, "vm2"));
-
-        when(mockVmsDAO.getVMs(any(HostRef.class))).thenReturn(expectedVMs);
-
-        controller.doUpdateTreeAsync();
-
-        ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
-        verify(view).updateTree(any(List.class), any(List.class), arg.capture());
-        HostsVMsLoader loader = arg.getValue();
-
-        Collection<VmRef> actualVMs = loader.getVMs(host);
-        assertEqualCollection(expectedVMs, actualVMs);
-    }
-
-    @Test
-    public void verifyUpdateHostsVMsLoadsCorrectVMWithFilter() {
-
-        VmRef ref1 = mock(VmRef.class);
-        when(ref1.getStringID()).thenReturn("test1");
-        when(ref1.getName()).thenReturn("test1");
-        
-        VmRef ref2 = mock(VmRef.class);
-        when(ref2.getStringID()).thenReturn("test2");
-        when(ref2.getName()).thenReturn("test2");
-        
-        controller.setHostVmTreeFilter("test1");
-                
-        Filter filter = controller.getTreeFilter();
-        assertTrue(filter.matches(ref1));
-        assertFalse(filter.matches(ref2));
-    }
-    
-    private void assertEqualCollection(Collection<?> expected, Collection<?> actual) {
-        assertEquals(expected.size(), actual.size());
-        assertTrue(expected.containsAll(actual));
-    }
-
-    @Test
-    @Bug(id="954",
-         summary="Thermostat GUI client should remember my last panel selected",
-         url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=954")
-    public void verifyOpenSameHostVMTab() {
-
-        VmRef vmRef = mock(VmRef.class);
-        when(view.getSelectedHostOrVm()).thenReturn(vmRef);
-
-        VmInformationController vmInformationController = mock(VmInformationController.class);
-        when(vmInformationController.getSelectedChildID()).thenReturn(3);
-        when(uiFacadeFactory.getVmController(any(VmRef.class))).thenReturn(vmInformationController);
-
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
-
-        ArgumentCaptor<Integer> arg = ArgumentCaptor.forClass(Integer.class);
-        verify(vmInformationController).selectChildID(arg.capture());
-        verify(vmInformationController, times(0)).getSelectedChildID();
-
-        int id = arg.getValue();
-
-        assertEquals(0, id);
-
-        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
-
-        arg = ArgumentCaptor.forClass(Integer.class);
-        verify(vmInformationController, times(1)).getSelectedChildID();
-        verify(vmInformationController, times(2)).selectChildID(arg.capture());
-        id = arg.getValue();
-
-        assertEquals(3, id);
-    }
-
-    @Test
-    public void verityVMActionsAreShown() {
-        VmInfo vmInfo = new VmInfo(0, 1, 2, null, null, null, null, null, null, null, null, null, null, null);
-        when(mockVmsDAO.getVmInfo(isA(VmRef.class))).thenReturn(vmInfo);
-
-        VmRef ref = mock(VmRef.class);
-        when(view.getSelectedHostOrVm()).thenReturn(ref);
-
-        MouseEvent uiEvent = mock(MouseEvent.class);
-        ActionEvent<MainView.Action> viewEvent = new ActionEvent<>(view, MainView.Action.SHOW_VM_CONTEXT_MENU);
-        viewEvent.setPayload(uiEvent);
-
-        l.actionPerformed(viewEvent);
-
-        verify(view).showVMContextActions(Arrays.asList(action1), uiEvent);
-    }
-    
-    @Test
-    public void verityVMActionsAreExecuted() {
-
-        VmRef vmRef = mock(VmRef.class);
-        when(view.getSelectedHostOrVm()).thenReturn(vmRef);
-
-        ActionEvent<MainView.Action> event = new ActionEvent<>(view, MainView.Action.VM_CONTEXT_ACTION);
-        event.setPayload(action1);
-        l.actionPerformed(event);
-        
-        verify(action1, times(1)).execute(any(VmRef.class));
-        verify(action2, times(0)).execute(any(VmRef.class));
-    }
-
-    @Test
-    public void verifyMenuItems() {
-        
-        MenuRegistry.MenuListener menuListener = controller.getMenuListener();
-
-        MenuAction action = mock(MenuAction.class);
-        when(action.getName()).thenReturn("Test1");
-
-        menuListener.added("File", action);
-        verify(view).addMenu("File", action);
-
-        menuListener.removed("File", action);
-        verify(view).removeMenu("File", action);
-    }
-
-   @Test
-   public void testOSGiFrameworkShutdown() throws BundleException {
-
-       l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.SHUTDOWN));
-
-       verify(uiFacadeFactory).shutdown();
-   }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/MenuRegistryTest.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,90 +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;
-
-import static org.mockito.Matchers.eq;
-import static org.mockito.Matchers.isA;
-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 org.junit.Test;
-import org.mockito.ArgumentCaptor;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.InvalidSyntaxException;
-import org.osgi.framework.ServiceEvent;
-import org.osgi.framework.ServiceListener;
-import org.osgi.framework.ServiceReference;
-
-import com.redhat.thermostat.client.MenuRegistry.MenuListener;
-import com.redhat.thermostat.client.osgi.service.MenuAction;
-
-public class MenuRegistryTest {
-
-    @Test
-    public void verifyMenuRegistryReactsToMenuActions() throws InvalidSyntaxException {
-        ArgumentCaptor<ServiceListener> serviceListenerCaptor = ArgumentCaptor.forClass(ServiceListener.class);
-        ArgumentCaptor<String> filterCaptor = ArgumentCaptor.forClass(String.class);
-
-        MenuListener menuListener = mock(MenuListener.class);
-        MenuAction menuAction = mock(MenuAction.class);
-
-        BundleContext context = mock(BundleContext.class);
-        doNothing().when(context).addServiceListener(serviceListenerCaptor.capture(), filterCaptor.capture());
-
-        ServiceReference ref = mock(ServiceReference.class);
-        when(ref.getProperty("objectClass")).thenReturn(MenuAction.class.getName());
-        when(ref.getProperty(MenuRegistry.PARENT_MENU)).thenReturn("Test");
-
-        when(context.getService(ref)).thenReturn(menuAction);
-
-        MenuRegistry registry = new MenuRegistry(context);
-        registry.addMenuListener(menuListener);
-        registry.start();
-
-        ServiceListener serviceListener = serviceListenerCaptor.getValue();
-        serviceListener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, ref));
-
-        verify(menuListener).added(eq("Test"), isA(MenuAction.class));
-
-        serviceListener.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, ref));
-
-        verify(menuListener).removed(eq("Test"), isA(MenuAction.class));
-
-    }
-}
--- a/client/core/src/test/java/com/redhat/thermostat/client/SwingViewFactoryTest.java	Tue Jun 12 14:02:16 2012 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,80 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client;
-
-import static org.junit.Assert.assertNotNull;
-
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.junit.Test;
-
-import com.redhat.thermostat.client.ui.AgentConfigurationView;
-import com.redhat.thermostat.client.ui.ClientConfigurationView;
-import com.redhat.thermostat.client.ui.HostCpuView;
-import com.redhat.thermostat.client.ui.HostMemoryView;
-import com.redhat.thermostat.client.ui.HostOverviewView;
-import com.redhat.thermostat.client.ui.VmCpuView;
-import com.redhat.thermostat.client.ui.VmGcView;
-import com.redhat.thermostat.client.ui.VmOverviewView;
-import com.redhat.thermostat.common.View;
-
-public class SwingViewFactoryTest {
-
-    @Test
-    public void test() throws InvocationTargetException, InterruptedException {
-        SwingViewFactory factory = new SwingViewFactory();
-
-        List<Class<? extends View>> knownViewClasses = new ArrayList<>();
-
-        knownViewClasses.add(AgentConfigurationView.class);
-        knownViewClasses.add(ClientConfigurationView.class);
-        knownViewClasses.add(HostCpuView.class);
-        knownViewClasses.add(HostMemoryView.class);
-        knownViewClasses.add(HostOverviewView.class);
-        knownViewClasses.add(VmCpuView.class);
-        knownViewClasses.add(VmGcView.class);
-        knownViewClasses.add(VmOverviewView.class);
-
-        for (Class<? extends View> klass: knownViewClasses) {
-            assertNotNull(factory.getViewClass(klass));
-            assertNotNull(factory.getView(klass));
-        }
-
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/test/java/com/redhat/thermostat/client/internal/DefaultViewFactoryTest.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.internal.DefaultViewFactory;
+import com.redhat.thermostat.common.View;
+
+public class DefaultViewFactoryTest {
+
+    public static class MockView implements View {}
+
+    @Test
+    public void testGetUnknownClasses() {
+        DefaultViewFactory factory = new DefaultViewFactory();
+        assertEquals(null, factory.getView(MockView.class));
+    }
+
+    @Test
+    public void testSetAndGet() {
+        DefaultViewFactory factory = new DefaultViewFactory();
+        factory.setViewClass(MockView.class, MockView.class);
+        assertEquals(MockView.class, factory.getViewClass(MockView.class));
+    }
+
+    @Test
+    public void testInstantiation() {
+        DefaultViewFactory factory = new DefaultViewFactory();
+        factory.setViewClass(MockView.class, MockView.class);
+        MockView view = factory.getView(MockView.class);
+        assertNotNull(view);
+        assertEquals(MockView.class.getName(), view.getClass().getName());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/test/java/com/redhat/thermostat/client/internal/GUIClientCommandTest.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isNotNull;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.util.Dictionary;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+
+import com.redhat.thermostat.client.internal.GUIClientCommand;
+import com.redhat.thermostat.client.internal.Main;
+import com.redhat.thermostat.client.osgi.service.ApplicationService;
+import com.redhat.thermostat.client.osgi.service.ContextAction;
+import com.redhat.thermostat.common.cli.CommandContext;
+import com.redhat.thermostat.common.cli.CommandContextFactory;
+import com.redhat.thermostat.common.cli.CommandException;
+
+public class GUIClientCommandTest {
+
+    private GUIClientCommand cmd;
+    private Main clientMain;
+
+    @Before
+    public void setUp() {
+        clientMain = mock(Main.class);
+        cmd = new GUIClientCommand(clientMain);
+    }
+
+    @After
+    public void tearDown() {
+        cmd = null;
+        clientMain = null;
+    }
+
+    @Test
+    public void testRun() throws CommandException {
+        BundleContext bCtx = mock(BundleContext.class);
+        CommandContextFactory cmdCtxFactory = mock(CommandContextFactory.class);
+        when(cmdCtxFactory.getBundleContext()).thenReturn(bCtx);
+        CommandContext cmdCtx = mock(CommandContext.class);
+        when(cmdCtx.getCommandContextFactory()).thenReturn(cmdCtxFactory);
+
+        cmd.run(cmdCtx);
+
+        verify(clientMain).run();
+        verify(bCtx).registerService(eq(ApplicationService.class.getName()), isNotNull(), any(Dictionary.class));
+        verify(bCtx).registerService(eq(ContextAction.class.getName()), isNotNull(), any(Dictionary.class));
+    }
+
+    @Test
+    public void testName() {
+        assertEquals("gui", cmd.getName());
+    }
+
+    @Test
+    public void testDescription() {
+        assertEquals("launches the GUI client", cmd.getDescription());
+    }
+
+    @Test
+    public void testUsage() {
+        assertEquals("launches the GUI client", cmd.getUsage());
+    }
+
+    @Test
+    public void testAcceptedArguments() {
+        assertEquals(0, cmd.getAcceptedArguments().size());
+    }
+
+    @Test
+    public void testRequiresStorage() {
+        assertFalse(cmd.isStorageRequired());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/test/java/com/redhat/thermostat/client/internal/MainWindowControllerImplTest.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,468 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.isA;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.awt.Component;
+import java.awt.event.MouseEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.BundleException;
+import org.osgi.util.tracker.ServiceTracker;
+
+import com.redhat.thermostat.client.internal.HostsVMsLoader;
+import com.redhat.thermostat.client.internal.MainView;
+import com.redhat.thermostat.client.internal.MainWindowControllerImpl;
+import com.redhat.thermostat.client.internal.MenuRegistry;
+import com.redhat.thermostat.client.internal.RegistryFactory;
+import com.redhat.thermostat.client.internal.ThermostatExtensionRegistry;
+import com.redhat.thermostat.client.internal.UiFacadeFactory;
+import com.redhat.thermostat.client.internal.VMTreeDecoratorRegistry;
+import com.redhat.thermostat.client.internal.VMTreeFilterRegistry;
+import com.redhat.thermostat.client.osgi.service.Filter;
+import com.redhat.thermostat.client.osgi.service.MenuAction;
+import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
+import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.ui.SummaryController;
+import com.redhat.thermostat.client.ui.SummaryView;
+import com.redhat.thermostat.client.ui.VmInformationController;
+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.ViewFactory;
+import com.redhat.thermostat.common.appctx.ApplicationContext;
+import com.redhat.thermostat.common.appctx.ApplicationContextUtil;
+import com.redhat.thermostat.common.dao.DAOFactory;
+import com.redhat.thermostat.common.dao.HostInfoDAO;
+import com.redhat.thermostat.common.dao.HostRef;
+import com.redhat.thermostat.common.dao.VmInfoDAO;
+import com.redhat.thermostat.common.dao.VmRef;
+import com.redhat.thermostat.common.model.VmInfo;
+import com.redhat.thermostat.test.Bug;
+
+public class MainWindowControllerImplTest {
+
+    private ActionListener<MainView.Action> l;
+
+    private MainWindowControllerImpl controller;
+
+    private UiFacadeFactory uiFacadeFactory;
+
+    private MainView view;
+
+    private Timer mainWindowTimer;
+
+    private HostInfoDAO mockHostsDAO;
+    private VmInfoDAO mockVmsDAO;
+
+    private VMContextAction action1;
+    private VMContextAction action2;
+
+    private VMTreeFilterRegistry filters;
+    private VMTreeDecoratorRegistry decorators;
+    private MenuRegistry menues;
+    
+    private ActionListener<ThermostatExtensionRegistry.Action> filtersListener;
+    private ActionListener<ThermostatExtensionRegistry.Action> decoratorsListener;
+    
+    @BeforeClass
+    public static void setUpOnce() {
+        // TODO remove when controller uses mocked objects rather than real swing objects
+        FailOnThreadViolationRepaintManager.install();
+    }
+
+    @SuppressWarnings({ "unchecked", "rawtypes" }) // ActionListener fluff
+    @Before
+    public void setUp() throws Exception {
+        ApplicationContextUtil.resetApplicationContext();
+
+        // Setup timers
+        mainWindowTimer = mock(Timer.class);
+        Timer otherTimer = mock(Timer.class); // FIXME needed for SummaryView; remove later
+        TimerFactory timerFactory = mock(TimerFactory.class);
+        when(timerFactory.createTimer()).thenReturn(mainWindowTimer).thenReturn(otherTimer);
+        ApplicationContext.getInstance().setTimerFactory(timerFactory);
+
+        SummaryController summaryController = mock(SummaryController.class);
+
+        uiFacadeFactory = mock(UiFacadeFactory.class);
+        when(uiFacadeFactory.getSummary()).thenReturn(summaryController);
+        setupDAOs();
+
+        // Setup View
+        view = mock(MainView.class);
+        ArgumentCaptor<ActionListener> grabListener = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(view).addActionListener(grabListener.capture());
+        
+        RegistryFactory registryFactory = mock(RegistryFactory.class);
+        filters = mock(VMTreeFilterRegistry.class);
+        decorators = mock(VMTreeDecoratorRegistry.class);
+        menues = mock(MenuRegistry.class);
+
+        when(registryFactory.createMenuRegistry()).thenReturn(menues);
+        when(registryFactory.createVMTreeDecoratorRegistry()).thenReturn(decorators);
+        when(registryFactory.createVMTreeFilterRegistry()).thenReturn(filters);
+        
+        ArgumentCaptor<ActionListener> grabFiltersListener = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(filters).addActionListener(grabFiltersListener.capture());
+
+        ArgumentCaptor<ActionListener> grabDecoratorsListener = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(decorators).addActionListener(grabDecoratorsListener.capture());
+        
+        // TODO remove this asap. the main window has a hard dependency on summary controller/view
+        ViewFactory viewFactory = mock(ViewFactory.class);
+        SummaryView summaryView = mock(SummaryView.class);
+        when(viewFactory.getView(SummaryView.class)).thenReturn(summaryView);
+        ApplicationContext.getInstance().setViewFactory(viewFactory);
+
+        setUpVMContextActions();
+
+        controller = new MainWindowControllerImpl(uiFacadeFactory, view, registryFactory);
+        l = grabListener.getValue();
+        
+        filtersListener = grabFiltersListener.getValue();
+        decoratorsListener = grabDecoratorsListener.getValue();
+    }
+
+    private void setUpVMContextActions() {
+        action1 = mock(VMContextAction.class);
+        Filter action1Filter = mock(Filter.class);
+        when(action1Filter.matches(isA(VmRef.class))).thenReturn(true);
+
+        when(action1.getName()).thenReturn("action1");
+        when(action1.getDescription()).thenReturn("action1desc");
+        when(action1.getFilter()).thenReturn(action1Filter);
+        
+        action2 = mock(VMContextAction.class);
+        Filter action2Filter = mock(Filter.class);
+        when(action2Filter.matches(isA(VmRef.class))).thenReturn(false);
+
+        when(action2.getName()).thenReturn("action2");
+        when(action2.getDescription()).thenReturn("action2desc");
+        when(action2.getFilter()).thenReturn(action2Filter);
+        
+        Collection<VMContextAction> actions = new ArrayList<>();
+        actions.add(action1);
+        actions.add(action2);
+        
+        when(uiFacadeFactory.getVMContextActions()).thenReturn(actions);
+    }
+    
+    private void setupDAOs() {
+        mockHostsDAO = mock(HostInfoDAO.class);
+        mockVmsDAO = mock(VmInfoDAO.class);
+
+        DAOFactory daoFactory = mock(DAOFactory.class);
+        when(daoFactory.getHostInfoDAO()).thenReturn(mockHostsDAO);
+        when(daoFactory.getVmInfoDAO()).thenReturn(mockVmsDAO);
+        ApplicationContext.getInstance().setDAOFactory(daoFactory);
+
+    }
+
+    @After
+    public void tearDown() {
+        view = null;
+        controller = null;
+        mockHostsDAO = null;
+        mockVmsDAO = null;
+        l = null;
+        ApplicationContextUtil.resetApplicationContext();
+    }
+
+    @Test
+    public void verifyDecoratorsAdded() {
+
+        List<ReferenceDecorator> currentDecoratros = controller.getVmTreeDecorators();
+        assertEquals(0, currentDecoratros.size());
+        
+        ActionEvent<ThermostatExtensionRegistry.Action> event =
+                new ActionEvent<ThermostatExtensionRegistry.Action>(decorators,
+                        ThermostatExtensionRegistry.Action.SERVICE_ADDED);
+        
+        ReferenceDecorator payload = mock(ReferenceDecorator.class);
+        event.setPayload(payload);
+        
+        decoratorsListener.actionPerformed(event);
+
+        currentDecoratros = controller.getVmTreeDecorators();
+        assertEquals(1, currentDecoratros.size());
+        assertEquals(payload, currentDecoratros.get(0));
+        
+        verify(view).updateTree(any(List.class), any(List.class), any(HostsVMsLoader.class));
+    }
+    
+    @Test
+    public void verifyThatHiddenEventStopsController() {
+
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HIDDEN));
+
+        verify(mainWindowTimer).stop();
+    }
+
+    @Test
+    public void verifyThatHostsVmsFilterChangeUpdatesTree() {
+
+        when(view.getHostVmTreeFilterText()).thenReturn("test");
+
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_TREE_FILTER));
+
+        verify(view).updateTree(any(List.class), any(List.class), any(HostsVMsLoader.class));
+    }
+    
+    @Test
+    public void verifyTimerGetsStartedOnBecomingVisible() {
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.VISIBLE));
+
+        verify(mainWindowTimer).setDelay(3);
+        verify(mainWindowTimer).setTimeUnit(TimeUnit.SECONDS);
+        verify(mainWindowTimer).setSchedulingType(SchedulingType.FIXED_RATE);
+        verify(mainWindowTimer).start();
+    }
+
+    @Test
+    public void verifyShowMainWindowActuallyCallsView() {
+        controller.showMainMainWindow();
+        verify(view).showMainWindow();
+    }
+
+    @Test
+    public void verifySubViewIsSetByDefault() throws InvocationTargetException, InterruptedException {
+        verify(view).setSubView(any(Component.class));
+    }
+
+    @Test
+    public void verifyUpdateHostsVMsLoadsCorrectHosts() {
+
+        Collection<HostRef> expectedHosts = new ArrayList<>();
+        expectedHosts.add(new HostRef("123", "fluffhost1"));
+        expectedHosts.add(new HostRef("456", "fluffhost2"));
+
+        when(mockHostsDAO.getAliveHosts()).thenReturn(expectedHosts);
+
+        controller.doUpdateTreeAsync();
+
+        ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
+        verify(view).updateTree(any(List.class), any(List.class), arg.capture());
+        HostsVMsLoader loader = arg.getValue();
+
+        Collection<HostRef> actualHosts = loader.getHosts();
+        assertEqualCollection(expectedHosts, actualHosts);
+    }
+    
+    @Test
+    public void verifyHistoryModeUpdateHostsVMCorrectly() {
+
+        Collection<HostRef> liveHost = new ArrayList<>();
+        liveHost.add(new HostRef("123", "fluffhost1"));
+        liveHost.add(new HostRef("456", "fluffhost2"));
+
+        Collection<HostRef> allHosts = new ArrayList<>();
+        allHosts.addAll(liveHost);
+        allHosts.add(new HostRef("789", "fluffhost3"));
+
+        when(mockHostsDAO.getAliveHosts()).thenReturn(liveHost);
+        when(mockHostsDAO.getHosts()).thenReturn(allHosts);
+
+        controller.doUpdateTreeAsync();
+
+        ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
+        verify(view).updateTree(any(List.class), any(List.class), arg.capture());
+        HostsVMsLoader loader = arg.getValue();
+
+        Collection<HostRef> actualHosts = loader.getHosts();
+        assertEqualCollection(liveHost, actualHosts);
+
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.SWITCH_HISTORY_MODE));
+
+        actualHosts = loader.getHosts();
+        assertEqualCollection(allHosts, actualHosts);
+    }
+
+    @Test
+    public void verifyUpdateHostsVMsLoadsCorrectVMs() {
+
+        Collection<VmRef> expectedVMs = new ArrayList<>();
+        HostRef host = new HostRef("123", "fluffhost1");
+        expectedVMs.add(new VmRef(host, 123, "vm1"));
+        expectedVMs.add(new VmRef(host, 456, "vm2"));
+
+        when(mockVmsDAO.getVMs(any(HostRef.class))).thenReturn(expectedVMs);
+
+        controller.doUpdateTreeAsync();
+
+        ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
+        verify(view).updateTree(any(List.class), any(List.class), arg.capture());
+        HostsVMsLoader loader = arg.getValue();
+
+        Collection<VmRef> actualVMs = loader.getVMs(host);
+        assertEqualCollection(expectedVMs, actualVMs);
+    }
+
+    @Test
+    public void verifyUpdateHostsVMsLoadsCorrectVMWithFilter() {
+
+        VmRef ref1 = mock(VmRef.class);
+        when(ref1.getStringID()).thenReturn("test1");
+        when(ref1.getName()).thenReturn("test1");
+        
+        VmRef ref2 = mock(VmRef.class);
+        when(ref2.getStringID()).thenReturn("test2");
+        when(ref2.getName()).thenReturn("test2");
+        
+        controller.setHostVmTreeFilter("test1");
+                
+        Filter filter = controller.getTreeFilter();
+        assertTrue(filter.matches(ref1));
+        assertFalse(filter.matches(ref2));
+    }
+    
+    private void assertEqualCollection(Collection<?> expected, Collection<?> actual) {
+        assertEquals(expected.size(), actual.size());
+        assertTrue(expected.containsAll(actual));
+    }
+
+    @Test
+    @Bug(id="954",
+         summary="Thermostat GUI client should remember my last panel selected",
+         url="http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=954")
+    public void verifyOpenSameHostVMTab() {
+
+        VmRef vmRef = mock(VmRef.class);
+        when(view.getSelectedHostOrVm()).thenReturn(vmRef);
+
+        VmInformationController vmInformationController = mock(VmInformationController.class);
+        when(vmInformationController.getSelectedChildID()).thenReturn(3);
+        when(uiFacadeFactory.getVmController(any(VmRef.class))).thenReturn(vmInformationController);
+
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
+
+        ArgumentCaptor<Integer> arg = ArgumentCaptor.forClass(Integer.class);
+        verify(vmInformationController).selectChildID(arg.capture());
+        verify(vmInformationController, times(0)).getSelectedChildID();
+
+        int id = arg.getValue();
+
+        assertEquals(0, id);
+
+        l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.HOST_VM_SELECTION_CHANGED));
+
+        arg = ArgumentCaptor.forClass(Integer.class);
+        verify(vmInformationController, times(1)).getSelectedChildID();
+        verify(vmInformationController, times(2)).selectChildID(arg.capture());
+        id = arg.getValue();
+
+        assertEquals(3, id);
+    }
+
+    @Test
+    public void verityVMActionsAreShown() {
+        VmInfo vmInfo = new VmInfo(0, 1, 2, null, null, null, null, null, null, null, null, null, null, null);
+        when(mockVmsDAO.getVmInfo(isA(VmRef.class))).thenReturn(vmInfo);
+
+        VmRef ref = mock(VmRef.class);
+        when(view.getSelectedHostOrVm()).thenReturn(ref);
+
+        MouseEvent uiEvent = mock(MouseEvent.class);
+        ActionEvent<MainView.Action> viewEvent = new ActionEvent<>(view, MainView.Action.SHOW_VM_CONTEXT_MENU);
+        viewEvent.setPayload(uiEvent);
+
+        l.actionPerformed(viewEvent);
+
+        verify(view).showVMContextActions(Arrays.asList(action1), uiEvent);
+    }
+    
+    @Test
+    public void verityVMActionsAreExecuted() {
+
+        VmRef vmRef = mock(VmRef.class);
+        when(view.getSelectedHostOrVm()).thenReturn(vmRef);
+
+        ActionEvent<MainView.Action> event = new ActionEvent<>(view, MainView.Action.VM_CONTEXT_ACTION);
+        event.setPayload(action1);
+        l.actionPerformed(event);
+        
+        verify(action1, times(1)).execute(any(VmRef.class));
+        verify(action2, times(0)).execute(any(VmRef.class));
+    }
+
+    @Test
+    public void verifyMenuItems() {
+        
+        MenuRegistry.MenuListener menuListener = controller.getMenuListener();
+
+        MenuAction action = mock(MenuAction.class);
+        when(action.getName()).thenReturn("Test1");
+
+        menuListener.added("File", action);
+        verify(view).addMenu("File", action);
+
+        menuListener.removed("File", action);
+        verify(view).removeMenu("File", action);
+    }
+
+   @Test
+   public void testOSGiFrameworkShutdown() throws BundleException {
+
+       l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.SHUTDOWN));
+
+       verify(uiFacadeFactory).shutdown();
+   }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/test/java/com/redhat/thermostat/client/internal/MenuRegistryTest.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Matchers.isA;
+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 org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.InvalidSyntaxException;
+import org.osgi.framework.ServiceEvent;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
+
+import com.redhat.thermostat.client.internal.MenuRegistry;
+import com.redhat.thermostat.client.internal.MenuRegistry.MenuListener;
+import com.redhat.thermostat.client.osgi.service.MenuAction;
+
+public class MenuRegistryTest {
+
+    @Test
+    public void verifyMenuRegistryReactsToMenuActions() throws InvalidSyntaxException {
+        ArgumentCaptor<ServiceListener> serviceListenerCaptor = ArgumentCaptor.forClass(ServiceListener.class);
+        ArgumentCaptor<String> filterCaptor = ArgumentCaptor.forClass(String.class);
+
+        MenuListener menuListener = mock(MenuListener.class);
+        MenuAction menuAction = mock(MenuAction.class);
+
+        BundleContext context = mock(BundleContext.class);
+        doNothing().when(context).addServiceListener(serviceListenerCaptor.capture(), filterCaptor.capture());
+
+        ServiceReference ref = mock(ServiceReference.class);
+        when(ref.getProperty("objectClass")).thenReturn(MenuAction.class.getName());
+        when(ref.getProperty(MenuRegistry.PARENT_MENU)).thenReturn("Test");
+
+        when(context.getService(ref)).thenReturn(menuAction);
+
+        MenuRegistry registry = new MenuRegistry(context);
+        registry.addMenuListener(menuListener);
+        registry.start();
+
+        ServiceListener serviceListener = serviceListenerCaptor.getValue();
+        serviceListener.serviceChanged(new ServiceEvent(ServiceEvent.REGISTERED, ref));
+
+        verify(menuListener).added(eq("Test"), isA(MenuAction.class));
+
+        serviceListener.serviceChanged(new ServiceEvent(ServiceEvent.UNREGISTERING, ref));
+
+        verify(menuListener).removed(eq("Test"), isA(MenuAction.class));
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/test/java/com/redhat/thermostat/client/internal/SwingViewFactoryTest.java	Tue Jun 12 21:26:04 2012 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+
+import com.redhat.thermostat.client.internal.SwingViewFactory;
+import com.redhat.thermostat.client.ui.AgentConfigurationView;
+import com.redhat.thermostat.client.ui.ClientConfigurationView;
+import com.redhat.thermostat.client.ui.HostCpuView;
+import com.redhat.thermostat.client.ui.HostMemoryView;
+import com.redhat.thermostat.client.ui.HostOverviewView;
+import com.redhat.thermostat.client.ui.VmCpuView;
+import com.redhat.thermostat.client.ui.VmGcView;
+import com.redhat.thermostat.client.ui.VmOverviewView;
+import com.redhat.thermostat.common.View;
+
+public class SwingViewFactoryTest {
+
+    @Test
+    public void test() throws InvocationTargetException, InterruptedException {
+        SwingViewFactory factory = new SwingViewFactory();
+
+        List<Class<? extends View>> knownViewClasses = new ArrayList<>();
+
+        knownViewClasses.add(AgentConfigurationView.class);
+        knownViewClasses.add(ClientConfigurationView.class);
+        knownViewClasses.add(HostCpuView.class);
+        knownViewClasses.add(HostMemoryView.class);
+        knownViewClasses.add(HostOverviewView.class);
+        knownViewClasses.add(VmCpuView.class);
+        knownViewClasses.add(VmGcView.class);
+        knownViewClasses.add(VmOverviewView.class);
+
+        for (Class<? extends View> klass: knownViewClasses) {
+            assertNotNull(factory.getViewClass(klass));
+            assertNotNull(factory.getView(klass));
+        }
+
+    }
+}
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/MainWindowTest.java	Tue Jun 12 14:02:16 2012 -0400
+++ b/client/core/src/test/java/com/redhat/thermostat/client/ui/MainWindowTest.java	Tue Jun 12 21:26:04 2012 +0200
@@ -72,8 +72,8 @@
 import org.junit.experimental.categories.Category;
 import org.junit.runner.RunWith;
 
-import com.redhat.thermostat.client.HostsVMsLoader;
-import com.redhat.thermostat.client.MainView;
+import com.redhat.thermostat.client.internal.HostsVMsLoader;
+import com.redhat.thermostat.client.internal.MainView;
 import com.redhat.thermostat.client.osgi.service.Filter;
 import com.redhat.thermostat.client.osgi.service.MenuAction;
 import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;