changeset 512:38c91eea3852

Make search work for hosts When deciding to show a host or VM in the tree, we require one of two possible conditions to succeed: either the node matches all the filters, or a child node needs to be displayed. For a search term which just matches the host name, all the filters need to be matched. There are currently two filters: the search text filter and the LivingVmFilter. The LivingVMFilter does not match hosts, of course. The result is that if no VMs are selected by the search query, the host is not shown either. Fix this by using separate filters for different parts of the tree: HostFilter and VmFilter (and matching HostDecorator and VmDecorator). The searchFilter is now used as both a host and vm filter, but other filters are for host or vms only. Reviewed-by: jerboaa, neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2012-July/002532.html
author Omair Majid <omajid@redhat.com>
date Wed, 01 Aug 2012 16:45:50 -0400
parents ce4dcf5ae06f
children c36dd2bd7280
files client/core/src/main/java/com/redhat/thermostat/client/internal/HostFilterRegistry.java client/core/src/main/java/com/redhat/thermostat/client/internal/MainView.java client/core/src/main/java/com/redhat/thermostat/client/internal/MainWindowControllerImpl.java client/core/src/main/java/com/redhat/thermostat/client/internal/RegistryFactory.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/VmFilterRegistry.java client/core/src/main/java/com/redhat/thermostat/client/osgi/service/Filter.java client/core/src/main/java/com/redhat/thermostat/client/osgi/service/HostDecorator.java client/core/src/main/java/com/redhat/thermostat/client/osgi/service/HostFilter.java client/core/src/main/java/com/redhat/thermostat/client/osgi/service/ReferenceDecorator.java client/core/src/main/java/com/redhat/thermostat/client/osgi/service/VMContextAction.java client/core/src/main/java/com/redhat/thermostat/client/osgi/service/VmDecorator.java client/core/src/main/java/com/redhat/thermostat/client/osgi/service/VmFilter.java client/core/src/main/java/com/redhat/thermostat/client/ui/DecoratedDefaultMutableTreeNode.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostVmFilter.java client/core/src/main/java/com/redhat/thermostat/client/ui/MainWindow.java client/core/src/test/java/com/redhat/thermostat/client/internal/MainWindowControllerImplTest.java client/core/src/test/java/com/redhat/thermostat/client/ui/MainWindowTest.java client/killvm/src/main/java/com/redhat/thermostat/client/killvm/KillVMAction.java client/living-vm-filter/src/main/java/com/redhat/thermostat/client/filter/vm/DeadVMDecorator.java client/living-vm-filter/src/main/java/com/redhat/thermostat/client/filter/vm/LivingVMFilter.java client/living-vm-filter/src/main/java/com/redhat/thermostat/client/filter/vm/VMDecorator.java client/living-vm-filter/src/main/java/com/redhat/thermostat/client/filter/vm/VMFilterActivator.java
diffstat 24 files changed, 588 insertions(+), 309 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/HostFilterRegistry.java	Wed Aug 01 16:45:50 2012 -0400
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.osgi.service.HostFilter;
+
+class HostFilterRegistry extends ThermostatExtensionRegistry<HostFilter> {
+
+    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + HostFilter.class.getName() + ")";
+
+    public HostFilterRegistry(BundleContext context) throws InvalidSyntaxException {
+        super(context, FILTER, HostFilter.class);
+    }
+}
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/MainView.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/MainView.java	Wed Aug 01 16:45:50 2012 -0400
@@ -39,10 +39,12 @@
 import java.awt.event.MouseEvent;
 import java.util.List;
 
-import com.redhat.thermostat.client.osgi.service.Filter;
+import com.redhat.thermostat.client.osgi.service.HostDecorator;
+import com.redhat.thermostat.client.osgi.service.HostFilter;
 import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
+import com.redhat.thermostat.client.osgi.service.VmDecorator;
 import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.osgi.service.VmFilter;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.BasicView;
 import com.redhat.thermostat.common.HostsVMsLoader;
@@ -66,7 +68,10 @@
 
     void addActionListener(ActionListener<Action> capture);
 
-    void updateTree(List<Filter> filter, List<ReferenceDecorator> decorators, HostsVMsLoader any);
+    void updateTree(List<HostFilter> hostFilters, List<VmFilter> vmFilters,
+            List<HostDecorator> hostDecorators, List<VmDecorator> vmDecorators,
+            HostsVMsLoader any);
+
     String getHostVmTreeFilterText();
     
     void setWindowTitle(String title);
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/MainWindowControllerImpl.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/MainWindowControllerImpl.java	Wed Aug 01 16:45:50 2012 -0400
@@ -38,6 +38,7 @@
 
 import java.awt.event.MouseEvent;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
@@ -50,10 +51,12 @@
 
 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.HostDecorator;
+import com.redhat.thermostat.client.osgi.service.HostFilter;
 import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
+import com.redhat.thermostat.client.osgi.service.VmDecorator;
 import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.osgi.service.VmFilter;
 import com.redhat.thermostat.client.ui.AgentConfigurationController;
 import com.redhat.thermostat.client.ui.AgentConfigurationModel;
 import com.redhat.thermostat.client.ui.AgentConfigurationView;
@@ -85,9 +88,11 @@
 
     private static final Logger logger = LoggingUtils.getLogger(MainWindowControllerImpl.class);
     
-    private List<Filter> vmTreefilters;
-    private List<ReferenceDecorator> vmTreeDecorators;
+    private List<HostFilter> hostFilters;
+    private List<VmFilter> vmFilters;
     
+    private List<VmDecorator> vmTreeDecorators;
+
     private Timer backgroundUpdater;
 
     private MainView view;
@@ -127,25 +132,55 @@
         }
     };
 
-    private HostVmFilter treeFilter;
-    private VMTreeFilterRegistry filterRegistry;
-    private ActionListener<ThermostatExtensionRegistry.Action> filterListener =
+    private HostVmFilter searchFilter;
+    private VmFilterRegistry vmFilterRegistry;
+    private HostFilterRegistry hostFilterRegistry;
+
+    private ActionListener<ThermostatExtensionRegistry.Action> hostFilterListener =
             new ActionListener<ThermostatExtensionRegistry.Action>()
     {
         @Override
         public void actionPerformed(ActionEvent<com.redhat.thermostat.client.internal.ThermostatExtensionRegistry.Action>
                                     actionEvent)
         {
-            Filter filter = (Filter) actionEvent.getPayload();
+            HostFilter filter = (HostFilter) actionEvent.getPayload();
+
+            switch (actionEvent.getActionId()) {
+            case SERVICE_ADDED:
+                hostFilters.add(filter);
+                doUpdateTreeAsync();
+                break;
+
+            case SERVICE_REMOVED:
+                hostFilters.remove(filter);
+                doUpdateTreeAsync();
+                break;
+
+            default:
+                logger.log(Level.WARNING, "received unknown event from VMTreeFilterRegistry: " +
+                                           actionEvent.getActionId());
+                break;
+            }
+        }
+    };
+
+    private ActionListener<ThermostatExtensionRegistry.Action> vmFilterListener =
+            new ActionListener<ThermostatExtensionRegistry.Action>()
+    {
+        @Override
+        public void actionPerformed(ActionEvent<com.redhat.thermostat.client.internal.ThermostatExtensionRegistry.Action>
+                                    actionEvent)
+        {
+            VmFilter filter = (VmFilter) actionEvent.getPayload();
             
             switch (actionEvent.getActionId()) {
             case SERVICE_ADDED:
-                vmTreefilters.add(filter);
+                vmFilters.add(filter);
                 doUpdateTreeAsync();
                 break;
             
             case SERVICE_REMOVED:
-                vmTreefilters.remove(filter);
+                vmFilters.remove(filter);
                 doUpdateTreeAsync();
                 break;
                 
@@ -164,7 +199,7 @@
         public void actionPerformed(com.redhat.thermostat.common.ActionEvent<ThermostatExtensionRegistry.Action>
                                     actionEvent)
         {
-            ReferenceDecorator decorator = (ReferenceDecorator) actionEvent.getPayload();
+            VmDecorator decorator = (VmDecorator) actionEvent.getPayload();
             switch (actionEvent.getActionId()) {
             case SERVICE_ADDED:
                 vmTreeDecorators.add(decorator);
@@ -202,7 +237,8 @@
     public MainWindowControllerImpl(UiFacadeFactory facadeFactory, MainView view, RegistryFactory registryFactory)
     {
         try {
-            filterRegistry = registryFactory.createVMTreeFilterRegistry();
+            vmFilterRegistry = registryFactory.createVmFilterRegistry();
+            hostFilterRegistry = registryFactory.createHostFilterRegistry();
             decoratorRegistry = registryFactory.createVMTreeDecoratorRegistry();
             menuRegistry = registryFactory.createMenuRegistry();
             vmInfoRegistry = registryFactory.createVMInformationRegistry();
@@ -213,9 +249,11 @@
 
         vmTreeDecorators = new CopyOnWriteArrayList<>();
         
-        vmTreefilters = new CopyOnWriteArrayList<>();
-        treeFilter = new HostVmFilter();
-        vmTreefilters.add(treeFilter);
+        hostFilters = new CopyOnWriteArrayList<>();
+        vmFilters = new CopyOnWriteArrayList<>();
+        searchFilter = new HostVmFilter();
+        hostFilters.add(searchFilter);
+        vmFilters.add(searchFilter);
         
         this.facadeFactory = facadeFactory;
 
@@ -236,10 +274,13 @@
 
         menuRegistry.addActionListener(menuListener);
         menuRegistry.start();
-        
-        filterRegistry.addActionListener(filterListener);
-        filterRegistry.start();
-        
+
+        hostFilterRegistry.addActionListener(hostFilterListener);
+        hostFilterRegistry.start();
+
+        vmFilterRegistry.addActionListener(vmFilterListener);
+        vmFilterRegistry.start();
+
         decoratorRegistry.addActionListener(decoratorListener);
         decoratorRegistry.start();
         
@@ -250,14 +291,14 @@
     /**
      * This method is for testing purposes only
      */
-    Filter getTreeFilter() {
-        return treeFilter;
+    HostVmFilter getSearchFilter() {
+        return searchFilter;
     }
     
     /**
      * This method is for testing purposes only
      */ 
-    List<ReferenceDecorator> getVmTreeDecorators() {
+    List<VmDecorator> getVmTreeDecorators() {
         return vmTreeDecorators;
     }
     
@@ -293,13 +334,13 @@
 
     @Override
     public void setHostVmTreeFilter(String filter) {
-        this.treeFilter.setFilter(filter);
+        this.searchFilter.setFilter(filter);
         doUpdateTreeAsync();
     }
 
     public void doUpdateTreeAsync() {
         HostsVMsLoader loader = new DefaultHostsVMsLoader(hostsDAO, vmsDAO, !showHistory);
-        view.updateTree(vmTreefilters, vmTreeDecorators, loader);
+        view.updateTree(hostFilters, vmFilters, Collections.<HostDecorator>emptyList(), vmTreeDecorators, loader);
     }
 
     private void initView(MainView mainView) {
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/RegistryFactory.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/RegistryFactory.java	Wed Aug 01 16:45:50 2012 -0400
@@ -50,8 +50,12 @@
         return new VMTreeDecoratorRegistry(context);
     }
     
-    VMTreeFilterRegistry createVMTreeFilterRegistry() throws InvalidSyntaxException {
-        return new VMTreeFilterRegistry(context);
+    HostFilterRegistry createHostFilterRegistry() throws InvalidSyntaxException {
+        return new HostFilterRegistry(context);
+    }
+
+    VmFilterRegistry createVmFilterRegistry() throws InvalidSyntaxException {
+        return new VmFilterRegistry(context);
     }
     
     MenuRegistry createMenuRegistry() throws InvalidSyntaxException {
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/VMTreeDecoratorRegistry.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/core/src/main/java/com/redhat/thermostat/client/internal/VMTreeDecoratorRegistry.java	Wed Aug 01 16:45:50 2012 -0400
@@ -40,13 +40,13 @@
 import org.osgi.framework.Constants;
 import org.osgi.framework.InvalidSyntaxException;
 
-import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
+import com.redhat.thermostat.client.osgi.service.VmDecorator;
 
-class VMTreeDecoratorRegistry extends ThermostatExtensionRegistry<ReferenceDecorator> {
+class VMTreeDecoratorRegistry extends ThermostatExtensionRegistry<VmDecorator> {
 
-    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + ReferenceDecorator.class.getName() + ")";
+    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + VmDecorator.class.getName() + ")";
     
     public VMTreeDecoratorRegistry(BundleContext context) throws InvalidSyntaxException {
-        super(context, FILTER, ReferenceDecorator.class);
+        super(context, FILTER, VmDecorator.class);
     }
 }
--- a/client/core/src/main/java/com/redhat/thermostat/client/internal/VMTreeFilterRegistry.java	Mon Jul 23 16:25:07 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.internal;
-
-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/VmFilterRegistry.java	Wed Aug 01 16:45:50 2012 -0400
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.internal;
+
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.InvalidSyntaxException;
+
+import com.redhat.thermostat.client.osgi.service.VmFilter;
+
+class VmFilterRegistry extends ThermostatExtensionRegistry<VmFilter> {
+
+    private static final String FILTER = "(" + Constants.OBJECTCLASS + "=" + VmFilter.class.getName() + ")";
+
+    public VmFilterRegistry(BundleContext context) throws InvalidSyntaxException {
+        super(context, FILTER, VmFilter.class);
+    }
+}
--- a/client/core/src/main/java/com/redhat/thermostat/client/osgi/service/Filter.java	Mon Jul 23 16:25:07 2012 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-/*
- * Copyright 2012 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.osgi.service;
-
-import com.redhat.thermostat.common.dao.Ref;
-
-public interface Filter {
-
-    boolean matches(Ref ref);
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/osgi/service/HostDecorator.java	Wed Aug 01 16:45:50 2012 -0400
@@ -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.osgi.service;
+
+import com.redhat.thermostat.client.ui.Decorator;
+
+/**
+ * This interface allows plugins to install a custom {@link Decorator} into
+ * the Reference List view.
+ * 
+ * <br /><br />
+ * 
+ * Active {@link HostDecorator}s are first queried against their filters
+ * and then installed into the view if the filter passes. 
+ */
+public interface HostDecorator {
+
+    Decorator getDecorator();
+    HostFilter getFilter();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/osgi/service/HostFilter.java	Wed Aug 01 16:45:50 2012 -0400
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not 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.service;
+
+import com.redhat.thermostat.common.dao.HostRef;
+
+public interface HostFilter {
+
+    boolean matches(HostRef toMatch);
+}
--- a/client/core/src/main/java/com/redhat/thermostat/client/osgi/service/ReferenceDecorator.java	Mon Jul 23 16:25:07 2012 +0200
+++ /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.osgi.service;
-
-import com.redhat.thermostat.client.ui.Decorator;
-
-/**
- * This interface allows plugins to install a custom {@link Decorator} into
- * the Reference List view.
- * 
- * <br /><br />
- * 
- * Active {@link ReferenceDecorator}s are first queried against their filters
- * and then installed into the view if the filter passes. 
- */
-public interface ReferenceDecorator {
-
-    Decorator getDecorator();
-    Filter getFilter();
-}
--- a/client/core/src/main/java/com/redhat/thermostat/client/osgi/service/VMContextAction.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/core/src/main/java/com/redhat/thermostat/client/osgi/service/VMContextAction.java	Wed Aug 01 16:45:50 2012 -0400
@@ -45,5 +45,5 @@
 
     void execute(VmRef referece);
 
-    Filter getFilter();
+    VmFilter getFilter();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/osgi/service/VmDecorator.java	Wed Aug 01 16:45:50 2012 -0400
@@ -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.osgi.service;
+
+import com.redhat.thermostat.client.ui.Decorator;
+
+/**
+ * This interface allows plugins to install a custom {@link Decorator} into
+ * the Reference List view.
+ * 
+ * <br /><br />
+ * 
+ * Active {@link VmDecorator}s are first queried against their filters
+ * and then installed into the view if the filter passes. 
+ */
+public interface VmDecorator {
+
+    Decorator getDecorator();
+    VmFilter getFilter();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/core/src/main/java/com/redhat/thermostat/client/osgi/service/VmFilter.java	Wed Aug 01 16:45:50 2012 -0400
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not 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.service;
+
+import com.redhat.thermostat.common.dao.VmRef;
+
+public interface VmFilter {
+
+    boolean matches(VmRef toMatch);
+
+}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/DecoratedDefaultMutableTreeNode.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/DecoratedDefaultMutableTreeNode.java	Wed Aug 01 16:45:50 2012 -0400
@@ -41,27 +41,27 @@
 
 import javax.swing.tree.DefaultMutableTreeNode;
 
-import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
+import com.redhat.thermostat.client.osgi.service.VmDecorator;
 import com.redhat.thermostat.common.dao.Ref;
 
 class DecoratedDefaultMutableTreeNode  extends DefaultMutableTreeNode {
     
-    private List<ReferenceDecorator> decorators;
+    private List<Decorator> decorators;
     
     DecoratedDefaultMutableTreeNode(Ref ref) {
         super(ref);
         decorators = new ArrayList<>();
     }
     
-    public void addDecorator(ReferenceDecorator decorator) {
+    public void addDecorator(Decorator decorator) {
         decorators.add(decorator);
     }
     
-    public void setDecorators(List<ReferenceDecorator> decorators) {
+    public void setDecorators(List<Decorator> decorators) {
         this.decorators = decorators;
     }
     
-    public List<ReferenceDecorator> getDecorators() {
+    public List<Decorator> getDecorators() {
         return decorators;
     }
-}
\ No newline at end of file
+}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostVmFilter.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/HostVmFilter.java	Wed Aug 01 16:45:50 2012 -0400
@@ -1,9 +1,48 @@
+/*
+ * Copyright 2012 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
 package com.redhat.thermostat.client.ui;
 
-import com.redhat.thermostat.client.osgi.service.Filter;
+import com.redhat.thermostat.client.osgi.service.HostFilter;
+import com.redhat.thermostat.client.osgi.service.VmFilter;
+import com.redhat.thermostat.common.dao.HostRef;
 import com.redhat.thermostat.common.dao.Ref;
+import com.redhat.thermostat.common.dao.VmRef;
 
-public class HostVmFilter implements Filter {
+public class HostVmFilter implements HostFilter, VmFilter {
     
     private String filter;
 
@@ -15,16 +54,25 @@
     }
 
     @Override
-    public boolean matches(Ref ref) {
+    public boolean matches(HostRef toMatch) {
+        return matchesRef(toMatch);
+    }
+
+    @Override
+    public boolean matches(VmRef toMatch) {
+        return matchesRef(toMatch);
+    }
+
+    public boolean matchesRef(Ref ref) {
         if (filter == null || filter.isEmpty()) {
             return true;
             
         } else {
-            return matches(ref, filter);                
+            return matchesRef(ref, filter);
         }
     }
 
-    public boolean matches(Ref ref, String filter) {
+    public boolean matchesRef(Ref ref, String filter) {
       return ref.getName().contains(filter) || ref.getStringID().contains(filter);
     }
-}
\ No newline at end of file
+}
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/MainWindow.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/MainWindow.java	Wed Aug 01 16:45:50 2012 -0400
@@ -93,10 +93,12 @@
 
 import com.redhat.thermostat.client.internal.MainView;
 import com.redhat.thermostat.client.locale.LocaleResources;
-import com.redhat.thermostat.client.osgi.service.Filter;
+import com.redhat.thermostat.client.osgi.service.HostDecorator;
+import com.redhat.thermostat.client.osgi.service.HostFilter;
 import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
+import com.redhat.thermostat.client.osgi.service.VmDecorator;
 import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.osgi.service.VmFilter;
 import com.redhat.thermostat.client.ui.SearchFieldView.SearchAction;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
@@ -121,20 +123,27 @@
         private final DefaultTreeModel treeModel;
         private DefaultMutableTreeNode treeRoot;
         
-        private List<Filter> filters;
-        private List<ReferenceDecorator> decorators;
+        private List<HostFilter> hostFilters;
+        private List<VmFilter> vmFilters;
+        private List<HostDecorator> hostDecorators;
+        private List<VmDecorator> vmDecorators;
         
         private HostsVMsLoader hostsVMsLoader;
 
         public BackgroundTreeModelWorker(DefaultTreeModel model, DefaultMutableTreeNode root,
-                                         List<Filter> filters, List<ReferenceDecorator> decorators,
+                                         List<HostFilter> hostFilters, List<VmFilter> vmFilters,
+                                         List<HostDecorator> hostDecorators, List<VmDecorator> vmDecorators,
                                          HostsVMsLoader hostsVMsLoader, JTree tree)
         {
-            this.filters = filters;
+            this.hostFilters = hostFilters;
+            this.vmFilters = vmFilters;
+
+            this.vmDecorators = vmDecorators;
+            this.hostDecorators = hostDecorators;
+
             this.treeModel = model;
             this.treeRoot = root;
             this.hostsVMsLoader = hostsVMsLoader;
-            this.decorators = decorators;
             this.tree = tree;
         }
 
@@ -143,22 +152,22 @@
             DefaultMutableTreeNode root = new DefaultMutableTreeNode();
             
             Collection<HostRef> hostsInRemoteModel = hostsVMsLoader.getHosts();
-            buildSubTree(root, hostsInRemoteModel);
+            buildHostSubTree(root, hostsInRemoteModel);
             return root;
         }
 
-        private boolean buildSubTree(DefaultMutableTreeNode parent, Collection<? extends Ref> objectsInRemoteModel) {
+        private boolean buildHostSubTree(DefaultMutableTreeNode parent, Collection<HostRef> objectsInRemoteModel) {
             boolean subTreeMatches = false;
-            for (Ref inRemoteModel : objectsInRemoteModel) {
+            for (HostRef inRemoteModel : objectsInRemoteModel) {
                 DecoratedDefaultMutableTreeNode inTreeNode =
                         new DecoratedDefaultMutableTreeNode(inRemoteModel);
 
                 boolean shouldInsert = false;
-                if (filters == null) {
+                if (hostFilters == null) {
                     shouldInsert = true;
                 } else {
                     shouldInsert = true;
-                    for (Filter filter : filters) {
+                    for (HostFilter filter : hostFilters) {
                         if (!filter.matches(inRemoteModel)) {
                             shouldInsert = false;
                             break;
@@ -166,17 +175,17 @@
                     }
                 }
                 
-                Collection<? extends Ref> children = getChildren(inRemoteModel);
-                boolean subtreeResult = buildSubTree(inTreeNode, children);
+                Collection<VmRef> children = hostsVMsLoader.getVMs(inRemoteModel);
+                boolean subtreeResult = buildVmSubTree(inTreeNode, children);
                 if (subtreeResult) {
                     shouldInsert = true;
                 }
 
                 if (shouldInsert) {
-                    for (ReferenceDecorator decorator : decorators) {
-                        Filter filter = decorator.getFilter();
+                    for (HostDecorator decorator : hostDecorators) {
+                        HostFilter filter = decorator.getFilter();
                         if (filter != null && filter.matches(inRemoteModel)) {
-                            inTreeNode.addDecorator(decorator);
+                            inTreeNode.addDecorator(decorator.getDecorator());
                         }
                     }
                     
@@ -188,6 +197,41 @@
             return subTreeMatches;
         }
 
+        private boolean buildVmSubTree(DefaultMutableTreeNode parent, Collection<VmRef> objectsInRemoteModel) {
+            boolean subTreeMatches = false;
+            for (VmRef inRemoteModel : objectsInRemoteModel) {
+                DecoratedDefaultMutableTreeNode inTreeNode =
+                        new DecoratedDefaultMutableTreeNode(inRemoteModel);
+
+                boolean shouldInsert = false;
+                if (vmFilters == null) {
+                    shouldInsert = true;
+                } else {
+                    shouldInsert = true;
+                    for (VmFilter filter : vmFilters) {
+                        if (!filter.matches(inRemoteModel)) {
+                            shouldInsert = false;
+                            break;
+                        }
+                    }
+                }
+
+                if (shouldInsert) {
+                    for (VmDecorator decorator : vmDecorators) {
+                        VmFilter filter = decorator.getFilter();
+                        if (filter != null && filter.matches(inRemoteModel)) {
+                            inTreeNode.addDecorator(decorator.getDecorator());
+                        }
+                    }
+
+                    parent.add(inTreeNode);
+                    subTreeMatches = true;
+                }
+            }
+
+            return subTreeMatches;
+        }
+
         @Override
         protected void done() {
             DefaultMutableTreeNode sourceRoot;
@@ -201,16 +245,6 @@
             }
         }
 
-        private Collection<? extends Ref> getChildren(Ref parent) {
-            if (parent == null) {
-                return hostsVMsLoader.getHosts();
-            } else if (parent instanceof HostRef) {
-                HostRef host = (HostRef) parent;
-                return hostsVMsLoader.getVMs(host);
-            }
-            return Collections.emptyList();
-        }
-
         private void syncTree(DefaultMutableTreeNode sourceRoot, DefaultTreeModel targetModel, DefaultMutableTreeNode targetNode) {
             
             @SuppressWarnings("unchecked") // We know what we put into these trees.
@@ -534,9 +568,8 @@
         private Map<Decorator, ImageIcon> decoratorsCache = new HashMap<>();
         private void setAnnotation(DecoratedDefaultMutableTreeNode treeNode, Object value, Component component) {
 
-            List<ReferenceDecorator> decorators = treeNode.getDecorators();
-            for (ReferenceDecorator decorator : decorators) {
-                Decorator dec = decorator.getDecorator();
+            List<Decorator> decorators = treeNode.getDecorators();
+            for (Decorator dec : decorators) {
                 String newText = dec.getLabel(getText());
                 setText(newText);
                 setLabelFor(component);
@@ -630,10 +663,13 @@
     }
     
     @Override
-    public void updateTree(List<Filter> filters, List<ReferenceDecorator> decorators, HostsVMsLoader hostsVMsLoader) {
+    public void updateTree(List<HostFilter> hostFilters, List<VmFilter> vmFilters,
+            List<HostDecorator> hostDecorators, List<VmDecorator> vmDecorators,
+            HostsVMsLoader hostsVMsLoader)
+    {
         BackgroundTreeModelWorker worker =
                 new BackgroundTreeModelWorker(publishedTreeModel, publishedRoot,
-                                              filters, decorators, hostsVMsLoader, agentVmTree);
+                                              hostFilters, vmFilters, hostDecorators, vmDecorators, hostsVMsLoader, agentVmTree);
         worker.execute();
     }
 
--- a/client/core/src/test/java/com/redhat/thermostat/client/internal/MainWindowControllerImplTest.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/core/src/test/java/com/redhat/thermostat/client/internal/MainWindowControllerImplTest.java	Wed Aug 01 16:45:50 2012 -0400
@@ -65,10 +65,11 @@
 import org.osgi.framework.BundleException;
 
 import com.redhat.thermostat.client.internal.ThermostatExtensionRegistry.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.VmDecorator;
 import com.redhat.thermostat.client.osgi.service.VMContextAction;
+import com.redhat.thermostat.client.osgi.service.VmFilter;
+import com.redhat.thermostat.client.ui.HostVmFilter;
 import com.redhat.thermostat.client.ui.SummaryController;
 import com.redhat.thermostat.client.ui.SummaryView;
 import com.redhat.thermostat.client.ui.VmInformationController;
@@ -108,12 +109,14 @@
     private VMContextAction action1;
     private VMContextAction action2;
 
-    private VMTreeFilterRegistry filters;
+    private HostFilterRegistry hostFilterRegistry;
+    private VmFilterRegistry vmFilterRegistry;
     private VMTreeDecoratorRegistry decorators;
     private VMInformationRegistry vmInfoRegistry;
     private MenuRegistry menus;
     
-    private ActionListener<ThermostatExtensionRegistry.Action> filtersListener;
+    private ActionListener<ThermostatExtensionRegistry.Action> hostFiltersListener;
+    private ActionListener<ThermostatExtensionRegistry.Action> vmFiltersListener;
     private ActionListener<ThermostatExtensionRegistry.Action> decoratorsListener;
     
     @BeforeClass
@@ -146,18 +149,23 @@
         doNothing().when(view).addActionListener(grabListener.capture());
         
         RegistryFactory registryFactory = mock(RegistryFactory.class);
-        filters = mock(VMTreeFilterRegistry.class);
+        hostFilterRegistry = mock(HostFilterRegistry.class);
+        vmFilterRegistry = mock(VmFilterRegistry.class);
         decorators = mock(VMTreeDecoratorRegistry.class);
         vmInfoRegistry = mock(VMInformationRegistry.class);
         menus = mock(MenuRegistry.class);
 
         when(registryFactory.createMenuRegistry()).thenReturn(menus);
         when(registryFactory.createVMTreeDecoratorRegistry()).thenReturn(decorators);
-        when(registryFactory.createVMTreeFilterRegistry()).thenReturn(filters);
+        when(registryFactory.createHostFilterRegistry()).thenReturn(hostFilterRegistry);
+        when(registryFactory.createVmFilterRegistry()).thenReturn(vmFilterRegistry);
         when(registryFactory.createVMInformationRegistry()).thenReturn(vmInfoRegistry);
         
-        ArgumentCaptor<ActionListener> grabFiltersListener = ArgumentCaptor.forClass(ActionListener.class);
-        doNothing().when(filters).addActionListener(grabFiltersListener.capture());
+        ArgumentCaptor<ActionListener> grabHostFiltersListener = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(hostFilterRegistry).addActionListener(grabHostFiltersListener.capture());
+
+        ArgumentCaptor<ActionListener> grabVmFiltersListener = ArgumentCaptor.forClass(ActionListener.class);
+        doNothing().when(vmFilterRegistry).addActionListener(grabVmFiltersListener.capture());
 
         ArgumentCaptor<ActionListener> grabDecoratorsListener = ArgumentCaptor.forClass(ActionListener.class);
         doNothing().when(decorators).addActionListener(grabDecoratorsListener.capture());
@@ -176,13 +184,14 @@
         controller = new MainWindowControllerImpl(uiFacadeFactory, view, registryFactory);
         l = grabListener.getValue();
         
-        filtersListener = grabFiltersListener.getValue();
+        hostFiltersListener = grabHostFiltersListener.getValue();
+        vmFiltersListener = grabVmFiltersListener.getValue();
         decoratorsListener = grabDecoratorsListener.getValue();
     }
 
     private void setUpVMContextActions() {
         action1 = mock(VMContextAction.class);
-        Filter action1Filter = mock(Filter.class);
+        VmFilter action1Filter = mock(VmFilter.class);
         when(action1Filter.matches(isA(VmRef.class))).thenReturn(true);
 
         when(action1.getName()).thenReturn("action1");
@@ -190,7 +199,7 @@
         when(action1.getFilter()).thenReturn(action1Filter);
         
         action2 = mock(VMContextAction.class);
-        Filter action2Filter = mock(Filter.class);
+        VmFilter action2Filter = mock(VmFilter.class);
         when(action2Filter.matches(isA(VmRef.class))).thenReturn(false);
 
         when(action2.getName()).thenReturn("action2");
@@ -228,14 +237,14 @@
     @Test
     public void verifyDecoratorsAdded() {
 
-        List<ReferenceDecorator> currentDecoratros = controller.getVmTreeDecorators();
+        List<VmDecorator> 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);
+        VmDecorator payload = mock(VmDecorator.class);
         event.setPayload(payload);
         
         decoratorsListener.actionPerformed(event);
@@ -244,7 +253,7 @@
         assertEquals(1, currentDecoratros.size());
         assertEquals(payload, currentDecoratros.get(0));
         
-        verify(view).updateTree(any(List.class), any(List.class), any(HostsVMsLoader.class));
+        verify(view).updateTree(any(List.class), isA(List.class), isA(List.class), any(List.class), any(HostsVMsLoader.class));
     }
     
     @Test
@@ -262,7 +271,7 @@
 
         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));
+        verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), isA(HostsVMsLoader.class));
     }
     
     @Test
@@ -298,7 +307,7 @@
         controller.doUpdateTreeAsync();
 
         ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
-        verify(view).updateTree(any(List.class), any(List.class), arg.capture());
+        verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), arg.capture());
         HostsVMsLoader loader = arg.getValue();
 
         Collection<HostRef> actualHosts = loader.getHosts();
@@ -322,7 +331,7 @@
         controller.doUpdateTreeAsync();
 
         ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
-        verify(view).updateTree(any(List.class), any(List.class), arg.capture());
+        verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), arg.capture());
         HostsVMsLoader loader = arg.getValue();
 
         Collection<HostRef> actualHosts = loader.getHosts();
@@ -331,7 +340,7 @@
         l.actionPerformed(new ActionEvent<MainView.Action>(view, MainView.Action.SWITCH_HISTORY_MODE));
         ArgumentCaptor<HostsVMsLoader> argCaptor = ArgumentCaptor.forClass(HostsVMsLoader.class);
         // actionPerformed triggers updateTree
-        verify(view, times(2)).updateTree(any(List.class), any(List.class), argCaptor.capture());
+        verify(view, times(2)).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), argCaptor.capture());
         loader = argCaptor.getValue();
 
         actualHosts = loader.getHosts();
@@ -351,7 +360,7 @@
         controller.doUpdateTreeAsync();
 
         ArgumentCaptor<HostsVMsLoader> arg = ArgumentCaptor.forClass(HostsVMsLoader.class);
-        verify(view).updateTree(any(List.class), any(List.class), arg.capture());
+        verify(view).updateTree(isA(List.class), isA(List.class), isA(List.class), isA(List.class), arg.capture());
         HostsVMsLoader loader = arg.getValue();
 
         Collection<VmRef> actualVMs = loader.getVMs(host);
@@ -371,7 +380,7 @@
         
         controller.setHostVmTreeFilter("test1");
                 
-        Filter filter = controller.getTreeFilter();
+        HostVmFilter filter = controller.getSearchFilter();
         assertTrue(filter.matches(ref1));
         assertFalse(filter.matches(ref2));
     }
--- a/client/core/src/test/java/com/redhat/thermostat/client/ui/MainWindowTest.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/core/src/test/java/com/redhat/thermostat/client/ui/MainWindowTest.java	Wed Aug 01 16:45:50 2012 -0400
@@ -46,6 +46,7 @@
 import static org.mockito.Mockito.any;
 import static org.mockito.Mockito.anyString;
 import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.isA;
 
 import java.util.ArrayList;
 import java.util.Collection;
@@ -73,9 +74,11 @@
 import org.junit.runner.RunWith;
 
 import com.redhat.thermostat.client.internal.MainView;
-import com.redhat.thermostat.client.osgi.service.Filter;
+import com.redhat.thermostat.client.osgi.service.HostDecorator;
+import com.redhat.thermostat.client.osgi.service.HostFilter;
 import com.redhat.thermostat.client.osgi.service.MenuAction;
-import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
+import com.redhat.thermostat.client.osgi.service.VmDecorator;
+import com.redhat.thermostat.client.osgi.service.VmFilter;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.HostsVMsLoader;
@@ -133,15 +136,15 @@
     @Test
     public void testHostVmDecoratorsAdded() throws InterruptedException {
         
-        List<ReferenceDecorator> decorators = new ArrayList<>();
-        ReferenceDecorator refDecorator = mock(ReferenceDecorator.class);
+        List<HostDecorator> decorators = new ArrayList<>();
+        HostDecorator refDecorator = mock(HostDecorator.class);
         final Decorator decorator = mock(Decorator.class);
         when(decorator.getLabel(anyString())).thenReturn("fluff");
         
         when(refDecorator.getDecorator()).thenReturn(decorator);
         
-        Filter filter = mock(Filter.class);
-        when(filter.matches(any(Ref.class))).thenReturn(false).thenReturn(true);
+        HostFilter filter = mock(HostFilter.class);
+        when(filter.matches(isA(HostRef.class))).thenReturn(false).thenReturn(true);
 
         when(refDecorator.getFilter()).thenReturn(filter);
         
@@ -154,7 +157,7 @@
         
         when(hostsVMsLoader.getHosts()).thenReturn(expectedHosts);
         
-        window.updateTree(null, decorators, hostsVMsLoader);
+        window.updateTree(null, null, decorators, null, hostsVMsLoader);
 
         Thread.sleep(50);
         
--- a/client/killvm/src/main/java/com/redhat/thermostat/client/killvm/KillVMAction.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/killvm/src/main/java/com/redhat/thermostat/client/killvm/KillVMAction.java	Wed Aug 01 16:45:50 2012 -0400
@@ -37,9 +37,8 @@
 package com.redhat.thermostat.client.killvm;
 
 import com.redhat.thermostat.client.osgi.service.VMContextAction;
-import com.redhat.thermostat.client.osgi.service.Filter;
+import com.redhat.thermostat.client.osgi.service.VmFilter;
 import com.redhat.thermostat.common.dao.DAOFactory;
-import com.redhat.thermostat.common.dao.Ref;
 import com.redhat.thermostat.common.dao.VmRef;
 import com.redhat.thermostat.common.model.VmInfo;
 import com.redhat.thermostat.service.process.UNIXProcessHandler;
@@ -76,22 +75,19 @@
     }
 
     @Override
-    public Filter getFilter() {
+    public VmFilter getFilter() {
         return new LocalAndAliveFilter();
     }
 
-    private class LocalAndAliveFilter implements Filter {
+    private class LocalAndAliveFilter implements VmFilter {
 
         @Override
-        public boolean matches(Ref ref) {
-            if (ref instanceof VmRef) {
-                VmRef vm = (VmRef) ref;
-                
-                // TODO implement local checking too
-                VmInfo vmInfo = dao.getVmInfoDAO().getVmInfo(vm);
-                return vmInfo.isAlive();
-            }
-            return false;
+        public boolean matches(VmRef ref) {
+            VmRef vm = ref;
+
+            // TODO implement local checking too
+            VmInfo vmInfo = dao.getVmInfoDAO().getVmInfo(vm);
+            return vmInfo.isAlive();
         }
 
     }
--- a/client/living-vm-filter/src/main/java/com/redhat/thermostat/client/filter/vm/DeadVMDecorator.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/living-vm-filter/src/main/java/com/redhat/thermostat/client/filter/vm/DeadVMDecorator.java	Wed Aug 01 16:45:50 2012 -0400
@@ -38,17 +38,16 @@
 
 import java.io.IOException;
 
-import com.redhat.thermostat.client.osgi.service.Filter;
-import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
+import com.redhat.thermostat.client.osgi.service.VmDecorator;
+import com.redhat.thermostat.client.osgi.service.VmFilter;
 import com.redhat.thermostat.client.ui.Decorator;
 import com.redhat.thermostat.client.ui.IconDescriptor;
 import com.redhat.thermostat.common.dao.DAOFactory;
-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.model.VmInfo;
 
-public class DeadVMDecorator implements ReferenceDecorator {
+public class DeadVMDecorator implements VmDecorator {
     
     private class VMDecorator implements Decorator {
         @Override
@@ -72,23 +71,18 @@
         }
     }
 
-    private Filter decoratorFilter;
+    private VmFilter decoratorFilter;
     private VMDecorator decorator;
     
     public DeadVMDecorator(final DAOFactory dao) {
         decorator = new VMDecorator();
-        decoratorFilter = new Filter() {            
+        decoratorFilter = new VmFilter() {
             @Override
-            public boolean matches(Ref ref) {
-                if (ref instanceof VmRef) {
-                    VmRef vm = (VmRef) ref;
-                    
-                    VmInfoDAO info = dao.getVmInfoDAO();
-                    VmInfo vmInfo = info.getVmInfo(vm);
-                    
-                    return !vmInfo.isAlive();
-                }
-                return false;
+            public boolean matches(VmRef vm) {
+                VmInfoDAO info = dao.getVmInfoDAO();
+                VmInfo vmInfo = info.getVmInfo(vm);
+
+                return !vmInfo.isAlive();
             }
         };
     }
@@ -99,7 +93,7 @@
     }
     
     @Override
-    public Filter getFilter() {
+    public VmFilter getFilter() {
         return decoratorFilter;
     }
-}
\ No newline at end of file
+}
--- a/client/living-vm-filter/src/main/java/com/redhat/thermostat/client/filter/vm/LivingVMFilter.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/living-vm-filter/src/main/java/com/redhat/thermostat/client/filter/vm/LivingVMFilter.java	Wed Aug 01 16:45:50 2012 -0400
@@ -36,14 +36,13 @@
 
 package com.redhat.thermostat.client.filter.vm;
 
-import com.redhat.thermostat.client.osgi.service.Filter;
+import com.redhat.thermostat.client.osgi.service.VmFilter;
 import com.redhat.thermostat.common.dao.DAOFactory;
-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.model.VmInfo;
 
-public class LivingVMFilter implements Filter {
+public class LivingVMFilter implements VmFilter {
 
     volatile boolean filterActive = true;
     
@@ -54,18 +53,12 @@
     }
     
     @Override
-    public boolean matches(Ref ref) {
+    public boolean matches(VmRef ref) {
         if (!filterActive)
             return true;
-        
-        if (ref instanceof VmRef) {
-            VmRef vm = (VmRef) ref;
-            
-            VmInfoDAO info = dao.getVmInfoDAO();
-            VmInfo vmInfo = info.getVmInfo(vm);
-            return vmInfo.isAlive();
-        }
-        
-        return false;
+
+        VmInfoDAO info = dao.getVmInfoDAO();
+        VmInfo vmInfo = info.getVmInfo(ref);
+        return vmInfo.isAlive();
     }
 }
--- a/client/living-vm-filter/src/main/java/com/redhat/thermostat/client/filter/vm/VMDecorator.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/living-vm-filter/src/main/java/com/redhat/thermostat/client/filter/vm/VMDecorator.java	Wed Aug 01 16:45:50 2012 -0400
@@ -38,14 +38,14 @@
 
 import java.io.IOException;
 
-import com.redhat.thermostat.client.osgi.service.Filter;
-import com.redhat.thermostat.client.osgi.service.ReferenceDecorator;
+import com.redhat.thermostat.client.osgi.service.VmDecorator;
+import com.redhat.thermostat.client.osgi.service.VmFilter;
 import com.redhat.thermostat.client.ui.Decorator;
 import com.redhat.thermostat.client.ui.IconDescriptor;
 import com.redhat.thermostat.client.ui.IconResource;
 import com.redhat.thermostat.common.dao.DAOFactory;
 
-public class VMDecorator implements ReferenceDecorator {
+public class VMDecorator implements VmDecorator {
     
     private class LivingVMDecorator implements Decorator {
         @Override
@@ -83,7 +83,7 @@
     }
     
     @Override
-    public Filter getFilter() {
+    public VmFilter getFilter() {
         return decoratorFilter;
     }
 }
--- a/client/living-vm-filter/src/main/java/com/redhat/thermostat/client/filter/vm/VMFilterActivator.java	Mon Jul 23 16:25:07 2012 +0200
+++ b/client/living-vm-filter/src/main/java/com/redhat/thermostat/client/filter/vm/VMFilterActivator.java	Wed Aug 01 16:45:50 2012 -0400
@@ -44,9 +44,9 @@
 import org.osgi.util.tracker.ServiceTracker;
 
 import com.redhat.thermostat.client.osgi.service.ApplicationService;
-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.VmDecorator;
+import com.redhat.thermostat.client.osgi.service.VmFilter;
 
 public class VMFilterActivator implements BundleActivator {
     
@@ -64,10 +64,10 @@
                 
                 LivingVMFilterMenuAction menu = new LivingVMFilterMenuAction(filter);
                 
-                context.registerService(ReferenceDecorator.class.getName(), deadDecorator, null);
-                context.registerService(ReferenceDecorator.class.getName(), decorator, null);
+                context.registerService(VmDecorator.class.getName(), deadDecorator, null);
+                context.registerService(VmDecorator.class.getName(), decorator, null);
                 
-                context.registerService(Filter.class.getName(), filter, null);
+                context.registerService(VmFilter.class.getName(), filter, null);
                 context.registerService(MenuAction.class.getName(), menu, null);
                 
                 return super.addingService(reference);