changeset 1965:180cf94d4b41

Refactor find-vm implementation to add MatchContext class Reviewed-by: jerboaa, jkang Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2015-August/015298.html Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2016-June/019718.html PR3040
author Andrew Azores <aazores@redhat.com>
date Tue, 18 Aug 2015 11:15:33 -0400
parents cc1a683958ca
children f3f9cc19b17c
files vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/AbstractMatcher.java vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/CriterionMatcher.java vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/FindVmCommand.java vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/HostCriterion.java vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/HostMatcher.java vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/MatchContext.java vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/Matcher.java vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/ResultsRenderer.java vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/VmCriterion.java vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/VmMatcher.java vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/AbstractMatcherTest.java vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/FindVmCommandTest.java vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/HostCriterionTest.java vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/HostMatcherTest.java vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/MatchContextTest.java vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/ResultsRendererTest.java vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/VmCriterionTest.java vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/VmMatcherTest.java
diffstat 18 files changed, 528 insertions(+), 234 deletions(-) [+]
line wrap: on
line diff
--- a/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/AbstractMatcher.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/AbstractMatcher.java	Tue Aug 18 11:15:33 2015 -0400
@@ -36,19 +36,17 @@
 
 package com.redhat.thermostat.vm.find.command.internal;
 
-import com.redhat.thermostat.storage.model.Pojo;
-
 import java.util.HashMap;
 import java.util.Map;
 
-abstract class AbstractMatcher<T extends Pojo> implements Matcher<T> {
+abstract class AbstractMatcher implements Matcher {
 
-    protected final Map<CriterionMatcher<T, String>, String> criteriaMap = new HashMap<>();
+    protected final Map<CriterionMatcher, String> criteriaMap = new HashMap<>();
 
     @Override
-    public boolean match(T t) {
-        for (Map.Entry<? extends CriterionMatcher<T, String>, String> entry : criteriaMap.entrySet()) {
-            boolean match = entry.getKey().match(t, entry.getValue());
+    public boolean match(MatchContext matchContext) {
+        for (Map.Entry<? extends CriterionMatcher, String> entry : criteriaMap.entrySet()) {
+            boolean match = entry.getKey().match(matchContext, entry.getValue());
             if (!match) {
                 return false;
             }
--- a/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/CriterionMatcher.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/CriterionMatcher.java	Tue Aug 18 11:15:33 2015 -0400
@@ -36,10 +36,8 @@
 
 package com.redhat.thermostat.vm.find.command.internal;
 
-import com.redhat.thermostat.storage.model.Pojo;
+interface CriterionMatcher {
 
-interface CriterionMatcher<T extends Pojo, U> {
-
-    boolean match(T t, U u);
+    boolean match(MatchContext matchContext, String string);
 
 }
--- a/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/FindVmCommand.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/FindVmCommand.java	Tue Aug 18 11:15:33 2015 -0400
@@ -36,7 +36,6 @@
 
 package com.redhat.thermostat.vm.find.command.internal;
 
-import com.redhat.thermostat.common.Pair;
 import com.redhat.thermostat.common.cli.AbstractCommand;
 import com.redhat.thermostat.common.cli.Arguments;
 import com.redhat.thermostat.common.cli.CommandContext;
@@ -96,7 +95,8 @@
         HostMatcher hostMatcher = new HostMatcher(hostCriteria);
         VmMatcher vmMatcher = new VmMatcher(vmCriteria);
 
-        List<Pair<HostInfo, VmInfo>> results = performSearch(agentsToSearch, hostMatcher, vmMatcher);
+        List<MatchContext> results = performSearch(hostInfoDAO, vmInfoDAO,
+                agentsToSearch, hostMatcher, vmMatcher);
 
         ResultsRenderer resultsRenderer = new ResultsRenderer(arguments);
         resultsRenderer.print(ctx.getConsole().getOutput(), results);
@@ -151,38 +151,54 @@
         return vmCriteria;
     }
 
-    List<Pair<HostInfo, VmInfo>> performSearch(Iterable<AgentInformation> agents, HostMatcher hostMatcher, VmMatcher vmMatcher) {
-        List<Pair<HostInfo, VmInfo>> pairs = new ArrayList<>();
-        for (AgentInformation agentInformation : filterAgents(agents, hostMatcher)) {
-            HostInfo hostInfo = getHostInfo(agentInformation);
-            List<VmInfo> matchingVms = getMatchingVms(agentInformation, vmMatcher);
+    static List<MatchContext> performSearch(HostInfoDAO hostInfoDAO, VmInfoDAO vmInfoDAO,
+             Iterable<AgentInformation> agents, HostMatcher hostMatcher, VmMatcher vmMatcher) {
+        List<MatchContext> matchContexts = new ArrayList<>();
+        for (AgentInformation agentInformation : filterAgents(hostInfoDAO, agents, hostMatcher)) {
+            HostInfo hostInfo = getHostInfo(hostInfoDAO, agentInformation);
+            List<VmInfo> matchingVms = getMatchingVms(hostInfoDAO, vmInfoDAO, agentInformation, hostInfo, vmMatcher);
             for (VmInfo vm : matchingVms) {
-                pairs.add(new Pair<>(hostInfo, vm));
+                MatchContext context = MatchContext.builder()
+                        .agentInfo(agentInformation)
+                        .hostInfo(hostInfo)
+                        .vmInfo(vm)
+                        .build();
+                matchContexts.add(context);
             }
         }
-        return pairs;
+        return matchContexts;
     }
 
-    List<AgentInformation> filterAgents(Iterable<AgentInformation> agents, HostMatcher hostMatcher) {
+    static List<AgentInformation> filterAgents(HostInfoDAO hostInfoDAO, Iterable<AgentInformation> agents, HostMatcher hostMatcher) {
         List<AgentInformation> list = new ArrayList<>();
         for (AgentInformation agent : agents) {
             HostInfo hostInfo = hostInfoDAO.getHostInfo(new HostRef(agent.getAgentId(), "dummy"));
-            if (hostMatcher.match(hostInfo)) {
+            MatchContext context = MatchContext.builder()
+                    .agentInfo(agent)
+                    .hostInfo(hostInfo)
+                    .build();
+            if (hostMatcher.match(context)) {
                 list.add(agent);
             }
         }
         return list;
     }
 
-    HostInfo getHostInfo(AgentInformation agentInformation) {
+    static HostInfo getHostInfo(HostInfoDAO hostInfoDAO, AgentInformation agentInformation) {
         return hostInfoDAO.getHostInfo(new HostRef(agentInformation.getAgentId(), "dummy"));
     }
 
-    List<VmInfo> getMatchingVms(AgentInformation agent, VmMatcher vmMatcher) {
+    static List<VmInfo> getMatchingVms(HostInfoDAO hostInfoDAO, VmInfoDAO vmInfoDAO,
+                                AgentInformation agent, HostInfo hostInfo, VmMatcher vmMatcher) {
         List<VmInfo> list = new ArrayList<>();
         for (VmRef vmRef : vmInfoDAO.getVMs(new HostRef(agent.getAgentId(), "dummy"))) {
             VmInfo vmInfo = vmInfoDAO.getVmInfo(vmRef);
-            if (vmMatcher.match(vmInfo)) {
+            MatchContext context = MatchContext.builder()
+                    .agentInfo(agent)
+                    .hostInfo(hostInfo)
+                    .vmInfo(vmInfo)
+                    .build();
+            if (vmMatcher.match(context)) {
                 list.add(vmInfo);
             }
         }
--- a/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/HostCriterion.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/HostCriterion.java	Tue Aug 18 11:15:33 2015 -0400
@@ -36,25 +36,23 @@
 
 package com.redhat.thermostat.vm.find.command.internal;
 
-import com.redhat.thermostat.storage.model.HostInfo;
-
-enum HostCriterion implements CriterionMatcher<HostInfo, String> {
+enum HostCriterion implements CriterionMatcher {
     HOSTNAME("hostname", new HostnameMatcher()),
     OS_KERNEL("oskernel", new OsKernelMatcher()),
     OS_NAME("osname", new OsNameMatcher()),
     ;
 
     private final String cliSwitch;
-    private final CriterionMatcher<HostInfo, String> criterionMatcher;
+    private final CriterionMatcher criterionMatcher;
 
-    HostCriterion(String cliSwitch, CriterionMatcher<HostInfo, String> criterionMatcher) {
+    HostCriterion(String cliSwitch, CriterionMatcher criterionMatcher) {
         this.cliSwitch = cliSwitch;
         this.criterionMatcher = criterionMatcher;
     }
 
     @Override
-    public boolean match(HostInfo hostInfo, String value) {
-        return this.criterionMatcher.match(hostInfo, value);
+    public boolean match(MatchContext matchContext, String value) {
+        return this.criterionMatcher.match(matchContext, value);
     }
 
     String getCliSwitch() {
@@ -70,24 +68,26 @@
         throw new IllegalArgumentException(string + " is not a legal HostCriterion");
     }
 
-    static class HostnameMatcher implements CriterionMatcher<HostInfo, String> {
+    static class HostnameMatcher implements CriterionMatcher {
         @Override
-        public boolean match(HostInfo hostInfo, String s) {
-            return hostInfo.getHostname().equals(s);
+        public boolean match(MatchContext matchContext, String s) {
+            return matchContext.getHostInfo().getHostname().equals(s);
         }
     }
 
-    static class OsKernelMatcher implements CriterionMatcher<HostInfo, String> {
+    static class OsKernelMatcher implements CriterionMatcher {
         @Override
-        public boolean match(HostInfo hostInfo, String s) {
-            return hostInfo.getOsKernel().equals(s) || hostInfo.getOsKernel().contains(s);
+        public boolean match(MatchContext matchContext, String s) {
+            String osKernel = matchContext.getHostInfo().getOsKernel();
+            return osKernel.equals(s) || osKernel.contains(s);
         }
     }
 
-    static class OsNameMatcher implements CriterionMatcher<HostInfo, String> {
+    static class OsNameMatcher implements CriterionMatcher {
         @Override
-        public boolean match(HostInfo hostInfo, String s) {
-            return hostInfo.getOsName().equals(s) || hostInfo.getOsName().contains(s);
+        public boolean match(MatchContext matchContext, String s) {
+            String osName = matchContext.getHostInfo().getOsName();
+            return osName.equals(s) || osName.contains(s);
         }
     }
 
--- a/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/HostMatcher.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/HostMatcher.java	Tue Aug 18 11:15:33 2015 -0400
@@ -36,11 +36,9 @@
 
 package com.redhat.thermostat.vm.find.command.internal;
 
-import com.redhat.thermostat.storage.model.HostInfo;
-
 import java.util.Map;
 
-class HostMatcher extends AbstractMatcher<HostInfo> {
+class HostMatcher extends AbstractMatcher {
 
     HostMatcher(Map<String, String> criteriaMap) {
         for (Map.Entry<String, String> entry : criteriaMap.entrySet()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/MatchContext.java	Tue Aug 18 11:15:33 2015 -0400
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.find.command.internal;
+
+import com.redhat.thermostat.storage.model.AgentInformation;
+import com.redhat.thermostat.storage.model.HostInfo;
+import com.redhat.thermostat.storage.model.VmInfo;
+
+import java.util.Objects;
+
+public class MatchContext {
+
+    private final HostInfo hostInfo;
+    private final AgentInformation agentInfo;
+    private final VmInfo vmInfo;
+
+    private MatchContext(Builder builder) {
+        this.hostInfo = builder.hostInfo;
+        this.agentInfo = builder.agentInfo;
+        this.vmInfo = builder.vmInfo;
+    }
+
+    public HostInfo getHostInfo() {
+        return hostInfo;
+    }
+
+    public AgentInformation getAgentInfo() {
+        return agentInfo;
+    }
+
+    public VmInfo getVmInfo() {
+        return vmInfo;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof MatchContext)) {
+            return false;
+        }
+
+        MatchContext m = (MatchContext) o;
+        return Objects.equals(hostInfo, m.hostInfo)
+                && Objects.equals(agentInfo, m.agentInfo)
+                && Objects.equals(vmInfo, m.vmInfo);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(hostInfo, agentInfo, vmInfo);
+    }
+
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    public static class Builder {
+
+        private HostInfo hostInfo;
+        private AgentInformation agentInfo;
+        private VmInfo vmInfo;
+
+        private Builder() {
+            hostInfo = null;
+            agentInfo = null;
+            vmInfo = null;
+        }
+
+        public Builder hostInfo(HostInfo hostInfo) {
+            this.hostInfo = hostInfo;
+            return this;
+        }
+
+        public Builder agentInfo(AgentInformation agentInfo) {
+            this.agentInfo = agentInfo;
+            return this;
+        }
+
+        public Builder vmInfo(VmInfo vmInfo) {
+            this.vmInfo = vmInfo;
+            return this;
+        }
+
+        public MatchContext build() {
+            return new MatchContext(this);
+        }
+
+    }
+
+}
--- a/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/Matcher.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/Matcher.java	Tue Aug 18 11:15:33 2015 -0400
@@ -36,8 +36,8 @@
 
 package com.redhat.thermostat.vm.find.command.internal;
 
-interface Matcher<T> {
+interface Matcher {
 
-    boolean match(T t);
+    boolean match(MatchContext matchContext);
 
 }
--- a/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/ResultsRenderer.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/ResultsRenderer.java	Tue Aug 18 11:15:33 2015 -0400
@@ -36,11 +36,8 @@
 
 package com.redhat.thermostat.vm.find.command.internal;
 
-import com.redhat.thermostat.common.Pair;
 import com.redhat.thermostat.common.cli.Arguments;
 import com.redhat.thermostat.common.cli.SortedTableRenderer;
-import com.redhat.thermostat.storage.model.HostInfo;
-import com.redhat.thermostat.storage.model.VmInfo;
 
 import java.io.PrintStream;
 import java.util.ArrayList;
@@ -77,8 +74,8 @@
             return cliSwitch;
         }
 
-        String getAdaptedField(Pair<HostInfo, VmInfo> pair) {
-            return fieldAdapter.map(pair);
+        String getAdaptedField(MatchContext matchContext) {
+            return fieldAdapter.map(matchContext);
         }
     }
 
@@ -101,13 +98,13 @@
         }
     }
 
-    void print(PrintStream printStream, Iterable<Pair<HostInfo, VmInfo>> pairs) {
+    void print(PrintStream printStream, Iterable<MatchContext> matchContexts) {
         SortedTableRenderer renderer = new SortedTableRenderer(enabledFields.size());
         if (!isShortOutput()) {
             renderer.printHeader(getHeaderFields().toArray(new String[enabledFields.size()]));
         }
-        for (Pair<HostInfo, VmInfo> pair : pairs) {
-            List<String> info = getInfo(pair);
+        for (MatchContext context : matchContexts) {
+            List<String> info = getInfo(context);
             renderer.printLine(info.toArray(new String[enabledFields.size()]));
         }
         renderer.render(printStream);
@@ -125,95 +122,85 @@
         return list;
     }
 
-    List<String> getInfo(Pair<HostInfo, VmInfo> pair) {
+    List<String> getInfo(MatchContext matchContext) {
         List<String> list = new ArrayList<>();
         for (Field field : enabledFields) {
-            list.add(field.getAdaptedField(pair));
+            list.add(field.getAdaptedField(matchContext));
         }
         return list;
     }
 
     interface FieldAdapter {
-        String map(Pair<HostInfo, VmInfo> pair);
+        String map(MatchContext matchContext);
     }
 
     static class VmIdFieldAdapter implements FieldAdapter {
         @Override
-        public String map(Pair<HostInfo, VmInfo> pair) {
-            VmInfo vmInfo = pair.getSecond();
-            return vmInfo.getVmId();
+        public String map(MatchContext matchContext) {
+            return matchContext.getVmInfo().getVmId();
         }
     }
 
     static class MainClassFieldAdapter implements FieldAdapter {
         @Override
-        public String map(Pair<HostInfo, VmInfo> pair) {
-            VmInfo vmInfo = pair.getSecond();
-            return vmInfo.getMainClass();
+        public String map(MatchContext matchContext) {
+            return matchContext.getVmInfo().getMainClass();
         }
     }
 
     static class VmNameFieldAdapter implements FieldAdapter {
         @Override
-        public String map(Pair<HostInfo, VmInfo> pair) {
-            VmInfo vmInfo = pair.getSecond();
-            return vmInfo.getVmName();
+        public String map(MatchContext matchContext) {
+            return matchContext.getVmInfo().getVmName();
         }
     }
 
     static class JavaVersionFieldAdapter implements FieldAdapter {
         @Override
-        public String map(Pair<HostInfo, VmInfo> pair) {
-            VmInfo vmInfo = pair.getSecond();
-            return vmInfo.getJavaVersion();
+        public String map(MatchContext matchContext) {
+            return matchContext.getVmInfo().getJavaVersion();
         }
     }
 
     static class VmVersionFieldAdapter implements FieldAdapter {
         @Override
-        public String map(Pair<HostInfo, VmInfo> pair) {
-            VmInfo vmInfo = pair.getSecond();
-            return vmInfo.getVmVersion();
+        public String map(MatchContext matchContext) {
+            return matchContext.getVmInfo().getVmVersion();
         }
     }
 
     static class PidFieldAdapter implements FieldAdapter {
         @Override
-        public String map(Pair<HostInfo, VmInfo> pair) {
-            VmInfo vmInfo = pair.getSecond();
-            return Integer.toString(vmInfo.getVmPid());
+        public String map(MatchContext matchContext) {
+            return Integer.toString(matchContext.getVmInfo().getVmPid());
         }
     }
 
     static class UsernameFieldAdapter implements FieldAdapter {
         @Override
-        public String map(Pair<HostInfo, VmInfo> pair) {
-            VmInfo vmInfo = pair.getSecond();
-            return vmInfo.getUsername();
+        public String map(MatchContext matchContext) {
+            return matchContext.getVmInfo().getUsername();
         }
     }
 
     static class HostnameFieldAdapter implements FieldAdapter {
         @Override
-        public String map(Pair<HostInfo, VmInfo> pair) {
-            HostInfo hostInfo = pair.getFirst();
-            return hostInfo.getHostname();
+        public String map(MatchContext matchContext) {
+            return matchContext.getHostInfo().getHostname();
         }
     }
 
     static class OsNameFieldAdapter implements FieldAdapter {
         @Override
-        public String map(Pair<HostInfo, VmInfo> pair) {
-            HostInfo hostInfo = pair.getFirst();
-            return hostInfo.getOsName();
+        public String map(MatchContext matchContext) {
+            return matchContext.getHostInfo().getOsName();
         }
     }
 
     static class OsKernelFieldAdapter implements FieldAdapter {
         @Override
-        public String map(Pair<HostInfo, VmInfo> pair) {
-            HostInfo hostInfo = pair.getFirst();
-            return hostInfo.getOsKernel();
+        public String map(MatchContext matchContext) {
+            return matchContext.getHostInfo().getOsKernel();
         }
     }
 
--- a/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/VmCriterion.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/VmCriterion.java	Tue Aug 18 11:15:33 2015 -0400
@@ -36,14 +36,12 @@
 
 package com.redhat.thermostat.vm.find.command.internal;
 
-import com.redhat.thermostat.storage.model.VmInfo;
-
 import java.nio.file.InvalidPathException;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.regex.PatternSyntaxException;
 
-enum VmCriterion implements CriterionMatcher<VmInfo, String> {
+enum VmCriterion implements CriterionMatcher {
     JAVA_VERSION("javaversion", new JavaVersionMatcher()),
     MAINCLASS("mainclass", new MainclassMatcher()),
     VM_NAME("vmname", new VmNameMatcher()),
@@ -54,16 +52,16 @@
     ;
 
     private final String cliSwitch;
-    private final CriterionMatcher<VmInfo, String> criterionMatcher;
+    private final CriterionMatcher criterionMatcher;
 
-    VmCriterion(String cliSwitch, CriterionMatcher<VmInfo, String> criterionMatcher) {
+    VmCriterion(String cliSwitch, CriterionMatcher criterionMatcher) {
         this.cliSwitch = cliSwitch;
         this.criterionMatcher = criterionMatcher;
     }
 
     @Override
-    public boolean match(VmInfo vmInfo, String value) {
-        return this.criterionMatcher.match(vmInfo, value);
+    public boolean match(MatchContext matchContext, String value) {
+        return this.criterionMatcher.match(matchContext, value);
     }
 
     String getCliSwitch() {
@@ -79,68 +77,69 @@
         throw new IllegalArgumentException(string + " is not a legal VmCriterion");
     }
 
-    static class JavaVersionMatcher implements CriterionMatcher<VmInfo, String> {
+    static class JavaVersionMatcher implements CriterionMatcher {
         @Override
-        public boolean match(VmInfo vmInfo, String s) {
-            return vmInfo.getJavaVersion().equals(s);
+        public boolean match(MatchContext matchContext, String s) {
+            return matchContext.getVmInfo().getJavaVersion().equals(s);
         }
     }
 
-    static class MainclassMatcher implements CriterionMatcher<VmInfo, String> {
+    static class MainclassMatcher implements CriterionMatcher {
         @Override
-        public boolean match(VmInfo vmInfo, String s) {
+        public boolean match(MatchContext matchContext, String s) {
             try {
-                return vmInfo.getMainClass().equals(s) || vmInfo.getMainClass().contains(s) || vmInfo.getMainClass().matches(s);
+                String mainClass = matchContext.getVmInfo().getMainClass();
+                return mainClass.equals(s) || mainClass.contains(s) || mainClass.matches(s);
             } catch (PatternSyntaxException e) {
                 return false;
             }
         }
     }
 
-    static class VmNameMatcher implements CriterionMatcher<VmInfo, String> {
+    static class VmNameMatcher implements CriterionMatcher {
         @Override
-        public boolean match(VmInfo vmInfo, String s) {
-            return vmInfo.getVmName().equals(s);
+        public boolean match(MatchContext matchContext, String s) {
+            return matchContext.getVmInfo().getVmName().equals(s);
         }
     }
 
-    static class VmArgsMatcher implements CriterionMatcher<VmInfo, String> {
+    static class VmArgsMatcher implements CriterionMatcher {
         @Override
-        public boolean match(VmInfo vmInfo, String s) {
+        public boolean match(MatchContext matchContext, String s) {
             if (!s.contains(",")) {
-                return vmInfo.getVmArguments().contains(s);
+                return matchContext.getVmInfo().getVmArguments().contains(s);
             }
             boolean allPresent = true;
             String[] args = s.split(",");
             for (String arg : args) {
-                allPresent = allPresent && vmInfo.getVmArguments().contains(arg);
+                allPresent = allPresent && matchContext.getVmInfo().getVmArguments().contains(arg);
             }
             return allPresent;
         }
     }
 
-    static class VmVersionMatcher implements CriterionMatcher<VmInfo, String> {
+    static class VmVersionMatcher implements CriterionMatcher {
         @Override
-        public boolean match(VmInfo vmInfo, String s) {
-            return vmInfo.getVmVersion().equals(s);
+        public boolean match(MatchContext matchContext, String s) {
+            return matchContext.getVmInfo().getVmVersion().equals(s);
         }
     }
 
-    static class UsernameMatcher implements CriterionMatcher<VmInfo, String> {
+    static class UsernameMatcher implements CriterionMatcher {
         @Override
-        public boolean match(VmInfo vmInfo, String s) {
-            return vmInfo.getUsername().equals(s);
+        public boolean match(MatchContext matchContext, String s) {
+            return matchContext.getVmInfo().getUsername().equals(s);
         }
     }
 
-    static class JavaHomeMatcher implements CriterionMatcher<VmInfo, String> {
+    static class JavaHomeMatcher implements CriterionMatcher {
         @Override
-        public boolean match(VmInfo vmInfo, String s) {
-            if (vmInfo.getJavaHome().equals(s)) {
+        public boolean match(MatchContext matchContext, String s) {
+            if (matchContext.getVmInfo().getJavaHome().equals(s)) {
                 return true;
             }
             try {
-                Path vmPath = Paths.get(vmInfo.getJavaHome());
+                Path vmPath = Paths.get(matchContext.getVmInfo().getJavaHome());
                 Path givenPath = Paths.get(s);
                 return vmPath.equals(givenPath);
             } catch (InvalidPathException e) {
--- a/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/VmMatcher.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/main/java/com/redhat/thermostat/vm/find/command/internal/VmMatcher.java	Tue Aug 18 11:15:33 2015 -0400
@@ -36,11 +36,9 @@
 
 package com.redhat.thermostat.vm.find.command.internal;
 
-import com.redhat.thermostat.storage.model.VmInfo;
-
 import java.util.Map;
 
-class VmMatcher extends AbstractMatcher<VmInfo> {
+class VmMatcher extends AbstractMatcher {
 
     VmMatcher(Map<String, String> criteriaMap) {
         for (Map.Entry<String, String> entry : criteriaMap.entrySet()) {
--- a/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/AbstractMatcherTest.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/AbstractMatcherTest.java	Tue Aug 18 11:15:33 2015 -0400
@@ -36,7 +36,7 @@
 
 package com.redhat.thermostat.vm.find.command.internal;
 
-import com.redhat.thermostat.storage.model.BasePojo;
+import com.redhat.thermostat.storage.model.AgentInformation;
 import org.junit.Test;
 
 import static org.hamcrest.CoreMatchers.is;
@@ -44,12 +44,12 @@
 
 public class AbstractMatcherTest {
 
-    static class TestMatcher extends AbstractMatcher<BasePojo> {
+    static class TestMatcher extends AbstractMatcher {
         TestMatcher() {
-            CriterionMatcher<BasePojo, String> matcher = new CriterionMatcher<BasePojo, String>() {
+            CriterionMatcher matcher = new CriterionMatcher() {
                 @Override
-                public boolean match(BasePojo pojo, String s) {
-                    return pojo.getAgentId().equals(s);
+                public boolean match(MatchContext matchContext, String s) {
+                    return matchContext.getAgentInfo().getAgentId().equals(s);
                 }
             };
             criteriaMap.put(matcher, "foo");
@@ -58,9 +58,11 @@
 
     @Test
     public void testMatch() {
-        AbstractMatcher<BasePojo> matcher = new TestMatcher();
-        BasePojo foo = new BasePojo("foo");
-        BasePojo bar = new BasePojo("bar");
+        AbstractMatcher matcher = new TestMatcher();
+        AgentInformation fooAgent = new AgentInformation("foo");
+        AgentInformation barAgent = new AgentInformation("bar");
+        MatchContext foo = MatchContext.builder().agentInfo(fooAgent).build();
+        MatchContext bar = MatchContext.builder().agentInfo(barAgent).build();
         assertThat(matcher.match(foo), is(true));
         assertThat(matcher.match(bar), is(false));
     }
--- a/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/FindVmCommandTest.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/FindVmCommandTest.java	Tue Aug 18 11:15:33 2015 -0400
@@ -450,10 +450,26 @@
         Set<VmRef> vmRefs2 = Collections.singleton(vmRef3);
         Set<VmRef> vmRefs3 = Collections.singleton(vmRef4);
 
-        Pair<HostInfo, VmInfo> pair1 = new Pair<>(host1, vm1);
-        Pair<HostInfo, VmInfo> pair2 = new Pair<>(host1, vm2);
-        Pair<HostInfo, VmInfo> pair3 = new Pair<>(host2, vm3);
-        Pair<HostInfo, VmInfo> pair4 = new Pair<>(host3, vm4);
+        MatchContext context1 = MatchContext.builder()
+                .hostInfo(host1)
+                .agentInfo(agentInfo1)
+                .vmInfo(vm1)
+                .build();
+        MatchContext context2 = MatchContext.builder()
+                .hostInfo(host1)
+                .agentInfo(agentInfo1)
+                .vmInfo(vm2)
+                .build();
+        MatchContext context3 = MatchContext.builder()
+                .hostInfo(host2)
+                .agentInfo(agentInfo2)
+                .vmInfo(vm3)
+                .build();
+        MatchContext context4 = MatchContext.builder()
+                .hostInfo(host3)
+                .agentInfo(agentInfo3)
+                .vmInfo(vm4)
+                .build();
 
         FindVmCommand command = new FindVmCommand();
 
@@ -484,10 +500,11 @@
         HostMatcher hostMatcher1 = new HostMatcher(hostMap1);
         Map<String, String> vmMap1 = new HashMap<>();
         VmMatcher vmMatcher1 = new VmMatcher(vmMap1);
-        List<Pair<HostInfo, VmInfo>> result1 = command.performSearch(agents, hostMatcher1, vmMatcher1);
+        List<MatchContext> result1 = FindVmCommand.performSearch(hostInfoDAO, vmInfoDAO,
+                agents, hostMatcher1, vmMatcher1);
         assertThat(result1.size(), is(4));
-        for (Pair<HostInfo, VmInfo> pair : Arrays.asList(pair1, pair2, pair3, pair4)) {
-            assertThat(result1.contains(pair), is(true));
+        for (MatchContext context : Arrays.asList(context1, context2, context3, context4)) {
+            assertThat(result1.contains(context), is(true));
         }
 
         Map<String, String> hostMap2 = new HashMap<>();
@@ -496,7 +513,8 @@
         Map<String, String> vmMap2 = new HashMap<>();
         vmMap2.put("javaversion", "1.8");
         VmMatcher vmMatcher2 = new VmMatcher(vmMap2);
-        List<Pair<HostInfo, VmInfo>> result2 = command.performSearch(agents, hostMatcher2, vmMatcher2);
+        List<MatchContext> result2 = FindVmCommand.performSearch(hostInfoDAO, vmInfoDAO,
+                agents, hostMatcher2, vmMatcher2);
         assertThat(result2.size(), is(0));
 
         Map<String, String> hostMap3 = new HashMap<>();
@@ -504,10 +522,11 @@
         HostMatcher hostMatcher3 = new HostMatcher(hostMap3);
         Map<String, String> vmMap3 = new HashMap<>();
         VmMatcher vmMatcher3 = new VmMatcher(vmMap3);
-        List<Pair<HostInfo, VmInfo>> result3 = command.performSearch(agents, hostMatcher3, vmMatcher3);
+        List<MatchContext> result3 = FindVmCommand.performSearch(hostInfoDAO, vmInfoDAO,
+                agents, hostMatcher3, vmMatcher3);
         assertThat(result3.size(), is(3));
-        for (Pair<HostInfo, VmInfo> pair : Arrays.asList(pair1, pair2, pair3)) {
-            assertThat(result3.contains(pair), is(true));
+        for (MatchContext context : Arrays.asList(context1, context2, context3)) {
+            assertThat(result3.contains(context), is(true));
         }
 
         Map<String, String> hostMap4 = new HashMap<>();
@@ -516,10 +535,11 @@
         Map<String, String> vmMap4 = new HashMap<>();
         vmMap4.put("javaversion", "1.8");
         VmMatcher vmMatcher4 = new VmMatcher(vmMap4);
-        List<Pair<HostInfo, VmInfo>> result4 = command.performSearch(agents, hostMatcher4, vmMatcher4);
+        List<MatchContext> result4 = FindVmCommand.performSearch(hostInfoDAO, vmInfoDAO,
+                agents, hostMatcher4, vmMatcher4);
         assertThat(result4.size(), is(2));
-        for (Pair<HostInfo, VmInfo> pair : Arrays.asList(pair1, pair2)) {
-            assertThat(result4.contains(pair), is(true));
+        for (MatchContext context : Arrays.asList(context1, context2)) {
+            assertThat(result4.contains(context), is(true));
         }
     }
 
@@ -542,19 +562,19 @@
         command.setHostInfoDAO(hostInfoDAO);
 
         HostMatcher allMatcher = new HostMatcher(Collections.<String, String>emptyMap());
-        List<AgentInformation> all = command.filterAgents(agents, allMatcher);
+        List<AgentInformation> all = FindVmCommand.filterAgents(hostInfoDAO, agents, allMatcher);
         assertThat(all, is(equalTo(agents)));
 
         Map<String, String> noneMap = new HashMap<>();
         noneMap.put("hostname", "none-host");
         HostMatcher noneMatcher = new HostMatcher(noneMap);
-        List<AgentInformation> none = command.filterAgents(agents, noneMatcher);
+        List<AgentInformation> none = FindVmCommand.filterAgents(hostInfoDAO, agents, noneMatcher);
         assertThat(none, is(equalTo(Collections.<AgentInformation>emptyList())));
 
         Map<String, String> fooMap = new HashMap<>();
         fooMap.put("hostname", "foo-host");
         HostMatcher fooMatcher = new HostMatcher(fooMap);
-        List<AgentInformation> fooList = command.filterAgents(agents, fooMatcher);
+        List<AgentInformation> fooList = FindVmCommand.filterAgents(hostInfoDAO, agents, fooMatcher);
         assertThat(fooList, is(equalTo(Collections.singletonList(foo))));
     }
 
@@ -584,6 +604,19 @@
         vmInfo3.setJavaVersion("1.7");
         VmRef vmRef3 = new VmRef(hostRef, vmInfo3);
 
+        HostInfo hostInfo = new HostInfo();
+        hostInfo.setHostname("foo-host");
+        hostInfo.setOsKernel("linux");
+        hostInfo.setAgentId("foo-agent");
+        hostInfo.setOsName("foo-linux");
+        hostInfo.setCpuCount(2);
+        hostInfo.setCpuModel("foo-cpu");
+        hostInfo.setTotalMemory(4096l);
+
+        HostInfoDAO hostInfoDAO = mock(HostInfoDAO.class);
+        when(hostInfoDAO.getAliveHosts()).thenReturn(Collections.singleton(hostRef));
+        when(hostInfoDAO.getAliveHosts()).thenReturn(Collections.singleton(hostRef));
+
         VmInfoDAO vmInfoDAO = mock(VmInfoDAO.class);
         when(vmInfoDAO.getVMs(hostRef)).thenReturn(new HashSet<>(Arrays.asList(vmRef1, vmRef2, vmRef3)));
         when(vmInfoDAO.getVmInfo(vmRef1)).thenReturn(vmInfo1);
@@ -594,25 +627,25 @@
         command.setVmInfoDAO(vmInfoDAO);
 
         VmMatcher allMatcher = new VmMatcher(Collections.<String, String>emptyMap());
-        List<VmInfo> all = command.getMatchingVms(agent, allMatcher);
+        List<VmInfo> all = FindVmCommand.getMatchingVms(hostInfoDAO, vmInfoDAO, agent, hostInfo, allMatcher);
         assertThat(all, is(equalTo(Arrays.asList(vmInfo1, vmInfo2, vmInfo3))));
 
         Map<String, String> userMap = new HashMap<>();
         userMap.put("username", "foo-user");
         VmMatcher userMatcher = new VmMatcher(userMap);
-        List<VmInfo> users = command.getMatchingVms(agent, userMatcher);
+        List<VmInfo> users = FindVmCommand.getMatchingVms(hostInfoDAO, vmInfoDAO, agent, hostInfo, userMatcher);
         assertThat(users, is(equalTo(Collections.singletonList(vmInfo1))));
 
         Map<String, String> versionMap = new HashMap<>();
         versionMap.put("javaversion", "1.8");
         VmMatcher versionMatcher = new VmMatcher(versionMap);
-        List<VmInfo> versions = command.getMatchingVms(agent, versionMatcher);
+        List<VmInfo> versions = FindVmCommand.getMatchingVms(hostInfoDAO, vmInfoDAO, agent, hostInfo, versionMatcher);
         assertThat(versions, is(equalTo(Arrays.asList(vmInfo1, vmInfo2))));
 
         Map<String, String> noneMap = new HashMap<>();
         noneMap.put("javaversion", "1.0");
         VmMatcher noneMatcher = new VmMatcher(noneMap);
-        List<VmInfo> none = command.getMatchingVms(agent, noneMatcher);
+        List<VmInfo> none = FindVmCommand.getMatchingVms(hostInfoDAO, vmInfoDAO, agent, hostInfo, noneMatcher);
         assertThat(none, is(equalTo(Collections.<VmInfo>emptyList())));
     }
 
--- a/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/HostCriterionTest.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/HostCriterionTest.java	Tue Aug 18 11:15:33 2015 -0400
@@ -49,11 +49,12 @@
         HostCriterion hostCriterion = HostCriterion.HOSTNAME;
         HostInfo hostInfo = new HostInfo();
         hostInfo.setHostname("foo");
-        assertThat(hostCriterion.match(hostInfo, "foo"), is(true));
-        assertThat(hostCriterion.match(hostInfo, "fo"), is(false));
-        assertThat(hostCriterion.match(hostInfo, "oo"), is(false));
-        assertThat(hostCriterion.match(hostInfo, "bar"), is(false));
-        assertThat(hostCriterion.match(hostInfo, "fooo"), is(false));
+        MatchContext matchContext = MatchContext.builder().hostInfo(hostInfo).build();
+        assertThat(hostCriterion.match(matchContext, "foo"), is(true));
+        assertThat(hostCriterion.match(matchContext, "fo"), is(false));
+        assertThat(hostCriterion.match(matchContext, "oo"), is(false));
+        assertThat(hostCriterion.match(matchContext, "bar"), is(false));
+        assertThat(hostCriterion.match(matchContext, "fooo"), is(false));
     }
 
     @Test
@@ -61,11 +62,12 @@
         HostCriterion hostCriterion = HostCriterion.OS_KERNEL;
         HostInfo hostInfo = new HostInfo();
         hostInfo.setOsKernel("foo");
-        assertThat(hostCriterion.match(hostInfo, "foo"), is(true));
-        assertThat(hostCriterion.match(hostInfo, "fo"), is(true));
-        assertThat(hostCriterion.match(hostInfo, "oo"), is(true));
-        assertThat(hostCriterion.match(hostInfo, "bar"), is(false));
-        assertThat(hostCriterion.match(hostInfo, "fooo"), is(false));
+        MatchContext matchContext = MatchContext.builder().hostInfo(hostInfo).build();
+        assertThat(hostCriterion.match(matchContext, "foo"), is(true));
+        assertThat(hostCriterion.match(matchContext, "fo"), is(true));
+        assertThat(hostCriterion.match(matchContext, "oo"), is(true));
+        assertThat(hostCriterion.match(matchContext, "bar"), is(false));
+        assertThat(hostCriterion.match(matchContext, "fooo"), is(false));
     }
 
     @Test
@@ -73,11 +75,12 @@
         HostCriterion hostCriterion = HostCriterion.OS_NAME;
         HostInfo hostInfo = new HostInfo();
         hostInfo.setOsName("foo");
-        assertThat(hostCriterion.match(hostInfo, "foo"), is(true));
-        assertThat(hostCriterion.match(hostInfo, "fo"), is(true));
-        assertThat(hostCriterion.match(hostInfo, "oo"), is(true));
-        assertThat(hostCriterion.match(hostInfo, "bar"), is(false));
-        assertThat(hostCriterion.match(hostInfo, "fooo"), is(false));
+        MatchContext matchContext = MatchContext.builder().hostInfo(hostInfo).build();
+        assertThat(hostCriterion.match(matchContext, "foo"), is(true));
+        assertThat(hostCriterion.match(matchContext, "fo"), is(true));
+        assertThat(hostCriterion.match(matchContext, "oo"), is(true));
+        assertThat(hostCriterion.match(matchContext, "bar"), is(false));
+        assertThat(hostCriterion.match(matchContext, "fooo"), is(false));
     }
 
     @Test
--- a/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/HostMatcherTest.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/HostMatcherTest.java	Tue Aug 18 11:15:33 2015 -0400
@@ -62,7 +62,10 @@
         host2.setHostname("foo");
         host2.setOsName("baz");
 
-        assertThat(matcher.match(host1), is(true));
-        assertThat(matcher.match(host2), is(false));
+        MatchContext matchContext1 = MatchContext.builder().hostInfo(host1).build();
+        MatchContext matchContext2 = MatchContext.builder().hostInfo(host2).build();
+
+        assertThat(matcher.match(matchContext1), is(true));
+        assertThat(matcher.match(matchContext2), is(false));
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/MatchContextTest.java	Tue Aug 18 11:15:33 2015 -0400
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2012-2016 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.vm.find.command.internal;
+
+import com.redhat.thermostat.storage.model.AgentInformation;
+import com.redhat.thermostat.storage.model.HostInfo;
+import com.redhat.thermostat.storage.model.VmInfo;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.core.IsNot.not;
+import static org.junit.Assert.assertThat;
+
+public class MatchContextTest {
+
+    @Test
+    public void testDefaultValuesAreNull() {
+        MatchContext context = MatchContext.builder().build();
+        assertThat(context.getAgentInfo(), is(equalTo(null)));
+        assertThat(context.getHostInfo(), is(equalTo(null)));
+        assertThat(context.getVmInfo(), is(equalTo(null)));
+    }
+
+    @Test
+    public void testGetters() {
+        AgentInformation agentInfo = new AgentInformation();
+        HostInfo hostInfo = new HostInfo();
+        VmInfo vmInfo = new VmInfo();
+        MatchContext context = MatchContext.builder()
+                .agentInfo(agentInfo)
+                .hostInfo(hostInfo)
+                .vmInfo(vmInfo)
+                .build();
+        assertThat(context.getAgentInfo(), is(agentInfo));
+        assertThat(context.getHostInfo(), is(hostInfo));
+        assertThat(context.getVmInfo(), is(vmInfo));
+    }
+
+    @Test
+    public void testEquals() {
+        MatchContext defaultContext = MatchContext.builder().build();
+        AgentInformation agentInfo = new AgentInformation();
+        HostInfo hostInfo = new HostInfo();
+        VmInfo vmInfo = new VmInfo();
+        MatchContext customizedContext = MatchContext.builder()
+                .agentInfo(agentInfo)
+                .hostInfo(hostInfo)
+                .vmInfo(vmInfo)
+                .build();
+        MatchContext customizedContext2 = MatchContext.builder()
+                .agentInfo(agentInfo)
+                .hostInfo(hostInfo)
+                .vmInfo(vmInfo)
+                .build();
+        assertThat(customizedContext.equals(customizedContext2), is(true));
+        assertThat(customizedContext2.equals(customizedContext), is(true));
+        assertThat(customizedContext.equals(defaultContext), is(false));
+        assertThat(customizedContext.equals(new Object()), is(false));
+        assertThat(customizedContext.equals(null), is(false));
+    }
+
+    @Test
+    public void testHashCode() {
+        MatchContext defaultContext = MatchContext.builder().build();
+        AgentInformation agentInfo = new AgentInformation();
+        HostInfo hostInfo = new HostInfo();
+        VmInfo vmInfo = new VmInfo();
+        MatchContext customizedContext = MatchContext.builder()
+                .agentInfo(agentInfo)
+                .hostInfo(hostInfo)
+                .vmInfo(vmInfo)
+                .build();
+        MatchContext customizedContext2 = MatchContext.builder()
+                .agentInfo(agentInfo)
+                .hostInfo(hostInfo)
+                .vmInfo(vmInfo)
+                .build();
+        assertThat(defaultContext.hashCode(), is(not(equalTo(customizedContext.hashCode()))));
+        assertThat(customizedContext.hashCode(), is(equalTo(customizedContext2.hashCode())));
+    }
+
+}
--- a/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/ResultsRendererTest.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/ResultsRendererTest.java	Tue Aug 18 11:15:33 2015 -0400
@@ -36,8 +36,8 @@
 
 package com.redhat.thermostat.vm.find.command.internal;
 
-import com.redhat.thermostat.common.Pair;
 import com.redhat.thermostat.common.cli.Arguments;
+import com.redhat.thermostat.storage.model.AgentInformation;
 import com.redhat.thermostat.storage.model.HostInfo;
 import com.redhat.thermostat.storage.model.VmInfo;
 import org.junit.Test;
@@ -59,14 +59,24 @@
 public class ResultsRendererTest {
 
     private static final HostInfo HOST_INFO = new HostInfo();
+    private static final AgentInformation AGENT_INFO = new AgentInformation();
     private static final VmInfo VM_INFO = new VmInfo();
-    private static final Pair<HostInfo, VmInfo> PAIR = new Pair<>(HOST_INFO, VM_INFO);
+    private static final MatchContext MATCH_CONTEXT = MatchContext.builder()
+            .hostInfo(HOST_INFO)
+            .agentInfo(AGENT_INFO)
+            .vmInfo(VM_INFO)
+            .build();
 
     static {
         HOST_INFO.setOsName("foo-os");
         HOST_INFO.setHostname("foo-host");
         HOST_INFO.setOsKernel("foo-kern");
 
+        AGENT_INFO.setAlive(true);
+        AGENT_INFO.setStartTime(150l);
+        AGENT_INFO.setStopTime(100l);
+        AGENT_INFO.setAgentId("foo-agent");
+
         VM_INFO.setJavaHome("/some/path/to/jdk");
         VM_INFO.setUsername("foo-user");
         VM_INFO.setVmVersion("20.5.6");
@@ -81,70 +91,70 @@
     @Test
     public void testVmId() {
         ResultsRenderer.Field field = ResultsRenderer.Field.VM_ID;
-        String result = field.getAdaptedField(PAIR);
+        String result = field.getAdaptedField(MATCH_CONTEXT);
         assertThat(result, containsString("foo-id"));
     }
 
     @Test
     public void testMainclass() {
         ResultsRenderer.Field field = ResultsRenderer.Field.MAINCLASS;
-        String result = field.getAdaptedField(PAIR);
+        String result = field.getAdaptedField(MATCH_CONTEXT);
         assertThat(result, containsString("com.example.java.ExampleApplet"));
     }
 
     @Test
     public void testVmName() {
         ResultsRenderer.Field field = ResultsRenderer.Field.VMNAME;
-        String result = field.getAdaptedField(PAIR);
+        String result = field.getAdaptedField(MATCH_CONTEXT);
         assertThat(result, containsString("Example JVM Implementation"));
     }
 
     @Test
     public void testJavaVersion() {
         ResultsRenderer.Field field = ResultsRenderer.Field.JAVAVERSION;
-        String result = field.getAdaptedField(PAIR);
+        String result = field.getAdaptedField(MATCH_CONTEXT);
         assertThat(result, containsString("1.8"));
     }
 
     @Test
     public void testVmVersion() {
         ResultsRenderer.Field field = ResultsRenderer.Field.VMVERSION;
-        String result = field.getAdaptedField(PAIR);
+        String result = field.getAdaptedField(MATCH_CONTEXT);
         assertThat(result, containsString("20.5.6"));
     }
 
     @Test
     public void testPid() {
         ResultsRenderer.Field field = ResultsRenderer.Field.PID;
-        String result = field.getAdaptedField(PAIR);
+        String result = field.getAdaptedField(MATCH_CONTEXT);
         assertThat(result, containsString("2"));
     }
 
     @Test
     public void testUsername() {
         ResultsRenderer.Field field = ResultsRenderer.Field.USERNAME;
-        String result = field.getAdaptedField(PAIR);
+        String result = field.getAdaptedField(MATCH_CONTEXT);
         assertThat(result, containsString("foo-user"));
     }
 
     @Test
     public void testHostname() {
         ResultsRenderer.Field field = ResultsRenderer.Field.HOSTNAME;
-        String result = field.getAdaptedField(PAIR);
+        String result = field.getAdaptedField(MATCH_CONTEXT);
         assertThat(result, containsString("foo-host"));
     }
 
     @Test
     public void testOsName() {
         ResultsRenderer.Field field = ResultsRenderer.Field.OSNAME;
-        String result = field.getAdaptedField(PAIR);
+        String result = field.getAdaptedField(MATCH_CONTEXT);
         assertThat(result, containsString("foo-os"));
     }
 
     @Test
     public void testOsKernel() {
         ResultsRenderer.Field field = ResultsRenderer.Field.OSKERNEL;
-        String result = field.getAdaptedField(PAIR);
+        String result = field.getAdaptedField(MATCH_CONTEXT);
         assertThat(result, containsString("foo-kern"));
     }
 
@@ -204,7 +214,7 @@
         when(arguments.hasArgument(ResultsRenderer.Field.HOSTNAME.getCliSwitch())).thenReturn(true);
         when(arguments.hasArgument(ResultsRenderer.Field.PID.getCliSwitch())).thenReturn(true);
         ResultsRenderer renderer = new ResultsRenderer(arguments);
-        List<String> info = renderer.getInfo(PAIR);
+        List<String> info = renderer.getInfo(MATCH_CONTEXT);
         assertThat(info, is(equalTo(Arrays.asList("2", "foo-host"))));
     }
 
@@ -216,7 +226,7 @@
         when(arguments.hasArgument(ResultsRenderer.Field.HOSTNAME.getCliSwitch())).thenReturn(true);
         when(arguments.hasArgument(ResultsRenderer.Field.PID.getCliSwitch())).thenReturn(true);
         ResultsRenderer renderer = new ResultsRenderer(arguments);
-        renderer.print(ps, Collections.singleton(PAIR));
+        renderer.print(ps, Collections.singleton(MATCH_CONTEXT));
         String output = baos.toString();
         assertThat(output, containsString("HOSTNAME"));
         assertThat(output, containsString("PID"));
--- a/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/VmCriterionTest.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/VmCriterionTest.java	Tue Aug 18 11:15:33 2015 -0400
@@ -49,13 +49,14 @@
         VmCriterion criterion = VmCriterion.JAVA_VERSION;
         VmInfo vmInfo = new VmInfo();
         vmInfo.setJavaVersion("1.8");
-        assertThat(criterion.match(vmInfo, "1.8"), is(true));
-        assertThat(criterion.match(vmInfo, "1.80"), is(false));
-        assertThat(criterion.match(vmInfo, "1.8_u45"), is(false));
-        assertThat(criterion.match(vmInfo, "1.7"), is(false));
-        assertThat(criterion.match(vmInfo, "1."), is(false));
-        assertThat(criterion.match(vmInfo, "1"), is(false));
-        assertThat(criterion.match(vmInfo, "8"), is(false));
+        MatchContext matchContext = MatchContext.builder().vmInfo(vmInfo).build();
+        assertThat(criterion.match(matchContext, "1.8"), is(true));
+        assertThat(criterion.match(matchContext, "1.80"), is(false));
+        assertThat(criterion.match(matchContext, "1.8_u45"), is(false));
+        assertThat(criterion.match(matchContext, "1.7"), is(false));
+        assertThat(criterion.match(matchContext, "1."), is(false));
+        assertThat(criterion.match(matchContext, "1"), is(false));
+        assertThat(criterion.match(matchContext, "8"), is(false));
     }
 
     @Test
@@ -63,18 +64,19 @@
         VmCriterion criterion = VmCriterion.MAINCLASS;
         VmInfo vmInfo = new VmInfo();
         vmInfo.setMainClass("com.example.java.ExampleApplet");
-        assertThat(criterion.match(vmInfo, "com.example.java.ExampleApplet"), is(true));
-        assertThat(criterion.match(vmInfo, "com.example.java.ExampleApplet.*"), is(true));
-        assertThat(criterion.match(vmInfo, "com.example.java.ExampleApplet.+"), is(false));
-        assertThat(criterion.match(vmInfo, "com.example.java.Example.+"), is(true));
-        assertThat(criterion.match(vmInfo, "ExampleApplet"), is(true));
-        assertThat(criterion.match(vmInfo, ".*Applet"), is(true));
-        assertThat(criterion.match(vmInfo, ".*Applet.+"), is(false));
-        assertThat(criterion.match(vmInfo, ".*"), is(true));
-        assertThat(criterion.match(vmInfo, "*"), is(false));
-        assertThat(criterion.match(vmInfo, "com.example.java"), is(true));
-        assertThat(criterion.match(vmInfo, "com.example.java..*"), is(true));
-        assertThat(criterion.match(vmInfo, "com.example.java.ExampleApplet2"), is(false));
+        MatchContext matchContext = MatchContext.builder().vmInfo(vmInfo).build();
+        assertThat(criterion.match(matchContext, "com.example.java.ExampleApplet"), is(true));
+        assertThat(criterion.match(matchContext, "com.example.java.ExampleApplet.*"), is(true));
+        assertThat(criterion.match(matchContext, "com.example.java.ExampleApplet.+"), is(false));
+        assertThat(criterion.match(matchContext, "com.example.java.Example.+"), is(true));
+        assertThat(criterion.match(matchContext, "ExampleApplet"), is(true));
+        assertThat(criterion.match(matchContext, ".*Applet"), is(true));
+        assertThat(criterion.match(matchContext, ".*Applet.+"), is(false));
+        assertThat(criterion.match(matchContext, ".*"), is(true));
+        assertThat(criterion.match(matchContext, "*"), is(false));
+        assertThat(criterion.match(matchContext, "com.example.java"), is(true));
+        assertThat(criterion.match(matchContext, "com.example.java..*"), is(true));
+        assertThat(criterion.match(matchContext, "com.example.java.ExampleApplet2"), is(false));
     }
 
     @Test
@@ -82,11 +84,12 @@
         VmCriterion criterion = VmCriterion.VM_NAME;
         VmInfo vmInfo = new VmInfo();
         vmInfo.setVmName("Example JVM Implementation Name");
-        assertThat(criterion.match(vmInfo, "Example JVM Implementation Name"), is(true));
-        assertThat(criterion.match(vmInfo, "Example JVM Implementation Name 2"), is(false));
-        assertThat(criterion.match(vmInfo, "JVM Implementation"), is(false));
-        assertThat(criterion.match(vmInfo, "Example JVM"), is(false));
-        assertThat(criterion.match(vmInfo, "*"), is(false));
+        MatchContext matchContext = MatchContext.builder().vmInfo(vmInfo).build();
+        assertThat(criterion.match(matchContext, "Example JVM Implementation Name"), is(true));
+        assertThat(criterion.match(matchContext, "Example JVM Implementation Name 2"), is(false));
+        assertThat(criterion.match(matchContext, "JVM Implementation"), is(false));
+        assertThat(criterion.match(matchContext, "Example JVM"), is(false));
+        assertThat(criterion.match(matchContext, "*"), is(false));
     }
 
     @Test
@@ -94,15 +97,16 @@
         VmCriterion criterion = VmCriterion.VM_ARGS;
         VmInfo vmInfo = new VmInfo();
         vmInfo.setVmArguments("-Xmx1024M -Xms1024M");
-        assertThat(criterion.match(vmInfo, "-Xmx1024M -Xms1024M"), is(true));
-        assertThat(criterion.match(vmInfo, "-Xmx1024M,-Xms1024M"), is(true));
-        assertThat(criterion.match(vmInfo, "-Xms1024M,-Xmx1024M"), is(true));
-        assertThat(criterion.match(vmInfo, "-Xmx1024M"), is(true));
-        assertThat(criterion.match(vmInfo, "-Xms1024M"), is(true));
-        assertThat(criterion.match(vmInfo, "Xmx1024M"), is(true));
-        assertThat(criterion.match(vmInfo, "Xmx"), is(true));
-        assertThat(criterion.match(vmInfo, "Xms,Xmx"), is(true));
-        assertThat(criterion.match(vmInfo, "-Xmx2048M"), is(false));
+        MatchContext matchContext = MatchContext.builder().vmInfo(vmInfo).build();
+        assertThat(criterion.match(matchContext, "-Xmx1024M -Xms1024M"), is(true));
+        assertThat(criterion.match(matchContext, "-Xmx1024M,-Xms1024M"), is(true));
+        assertThat(criterion.match(matchContext, "-Xms1024M,-Xmx1024M"), is(true));
+        assertThat(criterion.match(matchContext, "-Xmx1024M"), is(true));
+        assertThat(criterion.match(matchContext, "-Xms1024M"), is(true));
+        assertThat(criterion.match(matchContext, "Xmx1024M"), is(true));
+        assertThat(criterion.match(matchContext, "Xmx"), is(true));
+        assertThat(criterion.match(matchContext, "Xms,Xmx"), is(true));
+        assertThat(criterion.match(matchContext, "-Xmx2048M"), is(false));
     }
 
     @Test
@@ -110,13 +114,14 @@
         VmCriterion criterion = VmCriterion.VM_VERSION;
         VmInfo vmInfo = new VmInfo();
         vmInfo.setVmVersion("20.5.6");
-        assertThat(criterion.match(vmInfo, "20.5.6"), is(true));
-        assertThat(criterion.match(vmInfo, "20.5,6"), is(false));
-        assertThat(criterion.match(vmInfo, "20.5.8"), is(false));
-        assertThat(criterion.match(vmInfo, "21.5.6"), is(false));
-        assertThat(criterion.match(vmInfo, "20"), is(false));
-        assertThat(criterion.match(vmInfo, "20+"), is(false));
-        assertThat(criterion.match(vmInfo, "<=21"), is(false));
+        MatchContext matchContext = MatchContext.builder().vmInfo(vmInfo).build();
+        assertThat(criterion.match(matchContext, "20.5.6"), is(true));
+        assertThat(criterion.match(matchContext, "20.5,6"), is(false));
+        assertThat(criterion.match(matchContext, "20.5.8"), is(false));
+        assertThat(criterion.match(matchContext, "21.5.6"), is(false));
+        assertThat(criterion.match(matchContext, "20"), is(false));
+        assertThat(criterion.match(matchContext, "20+"), is(false));
+        assertThat(criterion.match(matchContext, "<=21"), is(false));
     }
 
     @Test
@@ -124,11 +129,12 @@
         VmCriterion criterion = VmCriterion.USERNAME;
         VmInfo vmInfo = new VmInfo();
         vmInfo.setUsername("foo-user");
-        assertThat(criterion.match(vmInfo, "foo-user"), is(true));
-        assertThat(criterion.match(vmInfo, "foo"), is(false));
-        assertThat(criterion.match(vmInfo, "user"), is(false));
-        assertThat(criterion.match(vmInfo, "*"), is(false));
-        assertThat(criterion.match(vmInfo, ".*"), is(false));
+        MatchContext matchContext = MatchContext.builder().vmInfo(vmInfo).build();
+        assertThat(criterion.match(matchContext, "foo-user"), is(true));
+        assertThat(criterion.match(matchContext, "foo"), is(false));
+        assertThat(criterion.match(matchContext, "user"), is(false));
+        assertThat(criterion.match(matchContext, "*"), is(false));
+        assertThat(criterion.match(matchContext, ".*"), is(false));
     }
 
     @Test
@@ -136,13 +142,14 @@
         VmCriterion criterion = VmCriterion.JAVA_HOME;
         VmInfo vmInfo = new VmInfo();
         vmInfo.setJavaHome("/some/filesystem/path/to/jdk");
-        assertThat(criterion.match(vmInfo, "/some/filesystem/path/to/jdk"), is(true));
-        assertThat(criterion.match(vmInfo, "/some/filesystem/path"), is(false));
-        assertThat(criterion.match(vmInfo, "/some/filesystem/path/to/"), is(false));
-        assertThat(criterion.match(vmInfo, "/some/filesystem/path/to/jdk/"), is(true));
-        assertThat(criterion.match(vmInfo, "some/filesystem/path/to/jdk/"), is(false));
-        assertThat(criterion.match(vmInfo, "/other/some/filesystem/path/to/jdk/"), is(false));
-        assertThat(criterion.match(vmInfo, "/some/filesystem/path"), is(false));
+        MatchContext matchContext = MatchContext.builder().vmInfo(vmInfo).build();
+        assertThat(criterion.match(matchContext, "/some/filesystem/path/to/jdk"), is(true));
+        assertThat(criterion.match(matchContext, "/some/filesystem/path"), is(false));
+        assertThat(criterion.match(matchContext, "/some/filesystem/path/to/"), is(false));
+        assertThat(criterion.match(matchContext, "/some/filesystem/path/to/jdk/"), is(true));
+        assertThat(criterion.match(matchContext, "some/filesystem/path/to/jdk/"), is(false));
+        assertThat(criterion.match(matchContext, "/other/some/filesystem/path/to/jdk/"), is(false));
+        assertThat(criterion.match(matchContext, "/some/filesystem/path"), is(false));
     }
 
     @Test
--- a/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/VmMatcherTest.java	Fri Aug 14 13:38:40 2015 -0400
+++ b/vm-find/command/src/test/java/com/redhat/thermostat/vm/find/command/internal/VmMatcherTest.java	Tue Aug 18 11:15:33 2015 -0400
@@ -55,11 +55,13 @@
 
         VmInfo vmInfo1 = new VmInfo();
         vmInfo1.setUsername("foo-user");
+        MatchContext matchContext1 = MatchContext.builder().vmInfo(vmInfo1).build();
 
         VmInfo vmInfo2 = new VmInfo();
         vmInfo2.setUsername("bar-user");
+        MatchContext matchContext2 = MatchContext.builder().vmInfo(vmInfo2).build();
 
-        assertThat(matcher.match(vmInfo1), is(true));
-        assertThat(matcher.match(vmInfo2), is(false));
+        assertThat(matcher.match(matchContext1), is(true));
+        assertThat(matcher.match(matchContext2), is(false));
     }
 }