diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/IMAPolicy.java b/HIRS_Utils/src/main/java/hirs/data/persist/IMAPolicy.java
index 35f71d2d..c46cb290 100644
--- a/HIRS_Utils/src/main/java/hirs/data/persist/IMAPolicy.java
+++ b/HIRS_Utils/src/main/java/hirs/data/persist/IMAPolicy.java
@@ -457,9 +457,11 @@ public class IMAPolicy extends Policy implements HasBaselines {
         Multimap<String, String> equivalentPaths = HashMultimap.create();
 
         // define equivalences
-        equivalentPaths.put("/bin/", "/usr/bin/");
-        equivalentPaths.put("/lib/", "/usr/lib/");
-        equivalentPaths.put("/lib64/", "/usr/lib64/");
+        equivalentPaths.put("/bin/",     "/usr/bin/");
+        equivalentPaths.put("/lib/",     "/usr/lib/");
+        equivalentPaths.put("/lib64/",   "/usr/lib64/");
+        equivalentPaths.put("/usr/bin/", "/usr/sbin/");
+        equivalentPaths.put("/sbin/",    "/usr/sbin/");
 
         // populate inverse relationships
         Multimap<String, String> bidirectionalEquivalences = HashMultimap.create();
diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/ImaAcceptableRecordBaseline.java b/HIRS_Utils/src/main/java/hirs/data/persist/ImaAcceptableRecordBaseline.java
index a76411bc..920efbb2 100644
--- a/HIRS_Utils/src/main/java/hirs/data/persist/ImaAcceptableRecordBaseline.java
+++ b/HIRS_Utils/src/main/java/hirs/data/persist/ImaAcceptableRecordBaseline.java
@@ -1,6 +1,7 @@
 package hirs.data.persist;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
+import hirs.ima.matching.BatchImaMatchStatus;
 import hirs.persist.ImaBaselineRecordManager;
 
 import javax.persistence.Entity;
@@ -14,6 +15,7 @@ import java.util.Set;
  */
 @Entity
 public abstract class ImaAcceptableRecordBaseline extends ImaBaseline<IMABaselineRecord> {
+
     /**
      * Creates a new ImaAcceptableRecordBaseline with the given name.
      *
@@ -29,6 +31,34 @@ public abstract class ImaAcceptableRecordBaseline extends ImaBaseline<IMABaselin
     protected ImaAcceptableRecordBaseline() {
     }
 
+    /**
+     * Similar to contains, but only considers the hash value and does not consider
+     * the path as relevant to matching at all.
+     *
+     * Each type of baseline specifies its own
+     * 'contains' algorithm for deciding whether the given measurements are
+     * considered as matches, mismatches, or unknowns to the baseline.  The 'contains' method
+     * of ImaAcceptableRecordBaselines that is normally used to judge measurement records
+     * against baseline records considers both paths and hashes; this method offers an
+     * additional mechanism for finding matching baseline records solely based
+     * on matching hash values.
+     *
+     * @param records
+     *            measurement records to find in this baseline
+     * @param recordManager
+     *            an ImaBaselineRecordManager that can be used to retrieve persisted records
+     * @param imaPolicy
+     *            the IMA policy to use while determining if a baseline contains the given records
+     *
+     * @return batch match status for the measurement records, according only to hashes
+     */
+    @JsonIgnore
+    public abstract BatchImaMatchStatus<IMABaselineRecord> containsHashes(
+            Collection<IMAMeasurementRecord> records,
+            ImaBaselineRecordManager recordManager,
+            IMAPolicy imaPolicy
+    );
+
     /**
      * Returns an unmodifiable set of IMA baseline records found in the IMA
      * baseline. The returned set only contains the baseline records from this
diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/ImaBaseline.java b/HIRS_Utils/src/main/java/hirs/data/persist/ImaBaseline.java
index dd25cced..30b0ee8a 100644
--- a/HIRS_Utils/src/main/java/hirs/data/persist/ImaBaseline.java
+++ b/HIRS_Utils/src/main/java/hirs/data/persist/ImaBaseline.java
@@ -75,7 +75,7 @@ public abstract class ImaBaseline<T extends AbstractImaBaselineRecord> extends B
      * @param imaPolicy
      *            the IMA policy to use while determining if a baseline contains the given records
      *
-     * @return search status for the measurement record
+     * @return batch match status for the measurement records
      */
     public abstract BatchImaMatchStatus<T> contains(
             Collection<IMAMeasurementRecord> records,
diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/ImaBlacklistBaseline.java b/HIRS_Utils/src/main/java/hirs/data/persist/ImaBlacklistBaseline.java
index ec6e289b..0948404d 100644
--- a/HIRS_Utils/src/main/java/hirs/data/persist/ImaBlacklistBaseline.java
+++ b/HIRS_Utils/src/main/java/hirs/data/persist/ImaBlacklistBaseline.java
@@ -3,7 +3,6 @@ package hirs.data.persist;
 import com.fasterxml.jackson.annotation.JsonIgnore;
 import com.google.common.base.Preconditions;
 import hirs.ima.matching.BatchImaMatchStatus;
-import hirs.ima.matching.IMAMatchStatus;
 import hirs.ima.matching.ImaBlacklistRecordMatcher;
 import hirs.persist.ImaBaselineRecordManager;
 
@@ -11,11 +10,9 @@ import javax.persistence.CascadeType;
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.OneToMany;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedHashSet;
-import java.util.List;
 import java.util.Set;
 
 /**
@@ -53,22 +50,10 @@ public class ImaBlacklistBaseline extends ImaBaseline<ImaBlacklistRecord> {
             final Collection<IMAMeasurementRecord> records,
             final ImaBaselineRecordManager recordManager,
             final IMAPolicy imaPolicy) {
-        if (records == null) {
-            throw new IllegalArgumentException("Records cannot be null");
-        }
-
-        if (imaPolicy == null) {
-            throw new IllegalArgumentException("IMA policy cannot be null");
-        }
-
-        ImaBlacklistRecordMatcher recordMatcher =
-                new ImaBlacklistRecordMatcher(imaBlacklistRecords, imaPolicy, this);
-        List<IMAMatchStatus<ImaBlacklistRecord>> matchStatuses = new ArrayList<>();
-        for (IMAMeasurementRecord record : records) {
-            matchStatuses.add(recordMatcher.contains(record));
-        }
-
-        return new BatchImaMatchStatus<>(matchStatuses);
+        Preconditions.checkArgument(records != null, "Records cannot be null");
+        Preconditions.checkArgument(imaPolicy != null, "IMA policy cannot be null");
+        return new ImaBlacklistRecordMatcher(imaBlacklistRecords, imaPolicy, this)
+                .batchMatch(records);
     }
 
     /**
diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/ImaIgnoreSetBaseline.java b/HIRS_Utils/src/main/java/hirs/data/persist/ImaIgnoreSetBaseline.java
index f72fe9d8..b2b20e16 100644
--- a/HIRS_Utils/src/main/java/hirs/data/persist/ImaIgnoreSetBaseline.java
+++ b/HIRS_Utils/src/main/java/hirs/data/persist/ImaIgnoreSetBaseline.java
@@ -7,17 +7,15 @@ package hirs.data.persist;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
 
+import com.google.common.base.Preconditions;
 import hirs.ima.matching.BatchImaMatchStatus;
-import hirs.ima.matching.IMAMatchStatus;
 import hirs.ima.matching.ImaIgnoreSetRecordMatcher;
 import hirs.persist.ImaBaselineRecordManager;
 import hirs.utils.RegexFilePathMatcher;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Set;
 
 import javax.persistence.Access;
@@ -157,21 +155,10 @@ public class ImaIgnoreSetBaseline extends ImaBaseline<ImaIgnoreSetRecord> {
             final ImaBaselineRecordManager recordManager,
             final IMAPolicy imaPolicy
     ) {
-        if (records == null) {
-            throw new IllegalArgumentException("Records cannot be null");
-        }
-
-        if (imaPolicy == null) {
-            throw new IllegalArgumentException("IMA policy cannot be null");
-        }
-
-        ImaIgnoreSetRecordMatcher recordMatcher =
-                new ImaIgnoreSetRecordMatcher(imaIgnoreSetRecords, imaPolicy, this);
-        List<IMAMatchStatus<ImaIgnoreSetRecord>> matchStatuses = new ArrayList<>();
-        for (IMAMeasurementRecord record : records) {
-            matchStatuses.add(recordMatcher.contains(record));
-        }
-        return new BatchImaMatchStatus<>(matchStatuses);
+        Preconditions.checkArgument(records != null, "Records cannot be null");
+        Preconditions.checkArgument(imaPolicy != null, "IMA policy cannot be null");
+        return new ImaIgnoreSetRecordMatcher(imaIgnoreSetRecords, imaPolicy, this)
+                .batchMatch(records);
     }
 
     /**
diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/QueryableRecordImaBaseline.java b/HIRS_Utils/src/main/java/hirs/data/persist/QueryableRecordImaBaseline.java
index 3cd0f613..2ad3ea45 100644
--- a/HIRS_Utils/src/main/java/hirs/data/persist/QueryableRecordImaBaseline.java
+++ b/HIRS_Utils/src/main/java/hirs/data/persist/QueryableRecordImaBaseline.java
@@ -1,18 +1,20 @@
 package hirs.data.persist;
 
+import com.google.common.base.Preconditions;
 import hirs.ima.matching.BatchImaMatchStatus;
 import hirs.ima.matching.IMAMatchStatus;
-import hirs.ima.matching.ImaAcceptableRecordMatcher;
+import hirs.ima.matching.ImaAcceptableHashRecordMatcher;
+import hirs.ima.matching.ImaAcceptablePathAndHashRecordMatcher;
 import hirs.ima.matching.ImaRecordMatcher;
 import hirs.persist.ImaBaselineRecordManager;
 import hirs.utils.Callback;
 import org.hibernate.Criteria;
 
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
-import java.util.List;
+import java.util.Objects;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 /**
  * This class defines the basis of operation for a baseline that supports querying
@@ -50,13 +52,8 @@ public abstract class QueryableRecordImaBaseline extends ImaAcceptableRecordBase
             final Collection<IMAMeasurementRecord> records,
             final ImaBaselineRecordManager recordManager,
             final IMAPolicy imaPolicy) {
-        if (records == null) {
-            throw new IllegalArgumentException("Records cannot be null");
-        }
-
-        if (recordManager == null) {
-            throw new IllegalArgumentException("ImaBaselineRecordManager cannot be null");
-        }
+        Preconditions.checkArgument(records != null, "records cannot be null");
+        Preconditions.checkArgument(recordManager != null, "record manager cannot be null");
 
         final Collection<String> pathsToFind = new HashSet<>();
         for (IMAMeasurementRecord record : records) {
@@ -79,14 +76,45 @@ public abstract class QueryableRecordImaBaseline extends ImaAcceptableRecordBase
                     }
         });
 
-        ImaAcceptableRecordMatcher recordMatcher =
-                new ImaAcceptableRecordMatcher(retrievedRecords, imaPolicy, this);
-        List<IMAMatchStatus<IMABaselineRecord>> matchStatuses = new ArrayList<>();
-        for (IMAMeasurementRecord record : records) {
-            matchStatuses.add(recordMatcher.contains(record));
-        }
+        return new ImaAcceptablePathAndHashRecordMatcher(retrievedRecords, imaPolicy, this)
+                .batchMatch(records);
+    }
 
-        return new BatchImaMatchStatus<>(matchStatuses);
+    /**
+     * Check membership of the given {@link IMAMeasurementRecord}s in this baseline.
+     *
+     * @param records the records to attempt to match
+     * @param recordManager the {@link ImaBaselineRecordManager} to query
+     * @param imaPolicy the IMA policy to use while determining if a baseline contains the records
+     *
+     * @return a collection of {@link IMAMatchStatus}es reflecting the results
+     */
+    @Override
+    public final BatchImaMatchStatus<IMABaselineRecord> containsHashes(
+            final Collection<IMAMeasurementRecord> records,
+            final ImaBaselineRecordManager recordManager,
+            final IMAPolicy imaPolicy) {
+        Preconditions.checkArgument(records != null, "records cannot be null");
+        Preconditions.checkArgument(recordManager != null, "record manager cannot be null");
+
+        final Set<Digest> hashesToFind = records.stream()
+                .filter(Objects::nonNull)
+                .map(IMAMeasurementRecord::getHash)
+                .collect(Collectors.toSet());
+
+        Collection<IMABaselineRecord> retrievedRecords = recordManager.iterateOverBaselineRecords(
+                this, new Callback<IMABaselineRecord, IMABaselineRecord>() {
+                    @Override
+                    public IMABaselineRecord call(final IMABaselineRecord baselineRecord) {
+                        if (hashesToFind.contains(baselineRecord.getHash())) {
+                            return baselineRecord;
+                        }
+                        return null;
+                    }
+                });
+
+        return new ImaAcceptableHashRecordMatcher(retrievedRecords, imaPolicy, this)
+                .batchMatch(records);
     }
 
     @Override
diff --git a/HIRS_Utils/src/main/java/hirs/data/persist/SimpleImaBaseline.java b/HIRS_Utils/src/main/java/hirs/data/persist/SimpleImaBaseline.java
index f3b355f4..137484bb 100644
--- a/HIRS_Utils/src/main/java/hirs/data/persist/SimpleImaBaseline.java
+++ b/HIRS_Utils/src/main/java/hirs/data/persist/SimpleImaBaseline.java
@@ -1,9 +1,10 @@
 package hirs.data.persist;
 
 import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.google.common.base.Preconditions;
 import hirs.ima.matching.BatchImaMatchStatus;
-import hirs.ima.matching.IMAMatchStatus;
-import hirs.ima.matching.ImaAcceptableRecordMatcher;
+import hirs.ima.matching.ImaAcceptableHashRecordMatcher;
+import hirs.ima.matching.ImaAcceptablePathAndHashRecordMatcher;
 import hirs.persist.ImaBaselineRecordManager;
 import org.apache.logging.log4j.Logger;
 
@@ -15,12 +16,10 @@ import javax.persistence.Entity;
 import javax.persistence.FetchType;
 import javax.persistence.OneToMany;
 import java.net.URL;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.LinkedHashSet;
-import java.util.List;
 import java.util.Set;
 
 import static org.apache.logging.log4j.LogManager.getLogger;
@@ -175,21 +174,24 @@ public class SimpleImaBaseline extends ImaAcceptableRecordBaseline {
             final Collection<IMAMeasurementRecord> records,
             final ImaBaselineRecordManager recordManager,
             final IMAPolicy imaPolicy) {
-        if (records == null) {
-            throw new IllegalArgumentException("Records cannot be null");
-        }
+        Preconditions.checkArgument(records != null, "Records cannot be null");
+        Preconditions.checkArgument(imaPolicy != null, "IMA policy cannot be null");
 
-        if (imaPolicy == null) {
-            throw new IllegalArgumentException("IMA policy cannot be null");
-        }
+        return new ImaAcceptablePathAndHashRecordMatcher(imaRecords, imaPolicy, this)
+                .batchMatch(records);
+    }
 
-        ImaAcceptableRecordMatcher recordMatcher =
-                new ImaAcceptableRecordMatcher(imaRecords, imaPolicy, this);
-        List<IMAMatchStatus<IMABaselineRecord>> matchStatuses = new ArrayList<>();
-        for (IMAMeasurementRecord record : records) {
-            matchStatuses.add(recordMatcher.contains(record));
-        }
-        return new BatchImaMatchStatus<>(matchStatuses);
+
+    @Override
+    public BatchImaMatchStatus<IMABaselineRecord> containsHashes(
+            final Collection<IMAMeasurementRecord> records,
+            final ImaBaselineRecordManager recordManager,
+            final IMAPolicy imaPolicy) {
+        Preconditions.checkArgument(records != null, "Records cannot be null");
+        Preconditions.checkArgument(imaPolicy != null, "IMA policy cannot be null");
+
+        return new ImaAcceptableHashRecordMatcher(imaRecords, imaPolicy, this)
+                .batchMatch(records);
     }
 
     @Override
diff --git a/HIRS_Utils/src/main/java/hirs/ima/matching/BatchImaMatchStatus.java b/HIRS_Utils/src/main/java/hirs/ima/matching/BatchImaMatchStatus.java
index e985822c..db75e367 100644
--- a/HIRS_Utils/src/main/java/hirs/ima/matching/BatchImaMatchStatus.java
+++ b/HIRS_Utils/src/main/java/hirs/ima/matching/BatchImaMatchStatus.java
@@ -307,4 +307,11 @@ public class BatchImaMatchStatus<T extends AbstractImaBaselineRecord> {
     public int hashCode() {
         return Objects.hash(matchStatuses);
     }
+
+    @Override
+    public String toString() {
+        return "BatchImaMatchStatus{"
+                + "matchStatuses=" + matchStatuses
+                + '}';
+    }
 }
diff --git a/HIRS_Utils/src/main/java/hirs/ima/matching/ImaAcceptableHashRecordMatcher.java b/HIRS_Utils/src/main/java/hirs/ima/matching/ImaAcceptableHashRecordMatcher.java
new file mode 100644
index 00000000..ae3c3ede
--- /dev/null
+++ b/HIRS_Utils/src/main/java/hirs/ima/matching/ImaAcceptableHashRecordMatcher.java
@@ -0,0 +1,59 @@
+package hirs.ima.matching;
+
+import com.google.common.base.Preconditions;
+import hirs.data.persist.IMABaselineRecord;
+import hirs.data.persist.IMAMeasurementRecord;
+import hirs.data.persist.IMAPolicy;
+import hirs.data.persist.ImaBaseline;
+import hirs.data.persist.ReportMatchStatus;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * This class extends the base matching functionality of {@link ImaRecordMatcher} to
+ * compare {@link IMAMeasurementRecord}s against a collection of {@link IMABaselineRecord}s
+ * based solely on their hashes.
+ */
+public class ImaAcceptableHashRecordMatcher extends ImaRecordMatcher<IMABaselineRecord> {
+    /**
+     * Construct a new ImaAcceptablePathAndHashRecordMatcher.
+     *
+     * @param records     the baseline records to use for matching
+     * @param imaPolicy   the IMA policy to reference during matching; its partial path and path
+     *                    equivalence settings influence matching behavior
+     * @param imaBaseline the IMA baseline these records were sourced from; this is only used to
+     */
+    public ImaAcceptableHashRecordMatcher(
+            final Collection<IMABaselineRecord> records,
+            final IMAPolicy imaPolicy,
+            final ImaBaseline imaBaseline) {
+        super(records, imaPolicy, imaBaseline);
+    }
+
+    /**
+     * Returns an IMAMatchStatus indicating whether the given {@link IMAMeasurementRecord} is
+     * contained within the originally provided {@link IMABaselineRecord}s.
+     *
+     * @param record the record to look up
+     * @return an IMAMatchStatus indicating whether the record is a match or unknown to
+     *         the given baseline records
+     */
+    @Override
+    public IMAMatchStatus<IMABaselineRecord> contains(final IMAMeasurementRecord record) {
+        Preconditions.checkArgument(record != null, "Cannot match on null record.");
+
+        final Set<IMABaselineRecord> matchingRecords = getRelatedBaselineRecordsByHash(record);
+
+        if (matchingRecords.isEmpty()) {
+            return new IMAMatchStatus<>(record, ReportMatchStatus.UNKNOWN, getImaBaseline());
+        }
+
+        return new IMAMatchStatus<>(
+                record,
+                ReportMatchStatus.MATCH,
+                matchingRecords,
+                getImaBaseline()
+        );
+    }
+}
diff --git a/HIRS_Utils/src/main/java/hirs/ima/matching/ImaAcceptableRecordMatcher.java b/HIRS_Utils/src/main/java/hirs/ima/matching/ImaAcceptablePathAndHashRecordMatcher.java
similarity index 89%
rename from HIRS_Utils/src/main/java/hirs/ima/matching/ImaAcceptableRecordMatcher.java
rename to HIRS_Utils/src/main/java/hirs/ima/matching/ImaAcceptablePathAndHashRecordMatcher.java
index 768a0765..5b91adf6 100644
--- a/HIRS_Utils/src/main/java/hirs/ima/matching/ImaAcceptableRecordMatcher.java
+++ b/HIRS_Utils/src/main/java/hirs/ima/matching/ImaAcceptablePathAndHashRecordMatcher.java
@@ -1,5 +1,6 @@
 package hirs.ima.matching;
 
+import com.google.common.base.Preconditions;
 import hirs.data.persist.DigestComparisonResultType;
 import hirs.data.persist.IMABaselineRecord;
 import hirs.data.persist.IMAMeasurementRecord;
@@ -16,20 +17,21 @@ import static org.apache.logging.log4j.LogManager.getLogger;
 
 /**
  * This class extends the base matching functionality of {@link ImaRecordMatcher} to
- * compare {@link IMAMeasurementRecord}s against a collection of {@link IMABaselineRecord}s.
+ * compare {@link IMAMeasurementRecord}s against a collection of {@link IMABaselineRecord}s
+ * based on both their paths and hashes.
  */
-public class ImaAcceptableRecordMatcher extends ImaRecordMatcher<IMABaselineRecord> {
-    private static final Logger LOGGER = getLogger(ImaAcceptableRecordMatcher.class);
+public class ImaAcceptablePathAndHashRecordMatcher extends ImaRecordMatcher<IMABaselineRecord> {
+    private static final Logger LOGGER = getLogger(ImaAcceptablePathAndHashRecordMatcher.class);
 
     /**
-     * Construct a new ImaAcceptableRecordMatcher.
+     * Construct a new ImaAcceptablePathAndHashRecordMatcher.
      *
      * @param records     the baseline records to use for matching
      * @param imaPolicy   the IMA policy to reference during matching; its partial path and path
      *                    equivalence settings influence matching behavior
      * @param imaBaseline the IMA baseline these records were sourced from; this is only used to
      */
-    public ImaAcceptableRecordMatcher(
+    public ImaAcceptablePathAndHashRecordMatcher(
             final Collection<IMABaselineRecord> records,
             final IMAPolicy imaPolicy,
             final ImaBaseline imaBaseline) {
@@ -46,9 +48,7 @@ public class ImaAcceptableRecordMatcher extends ImaRecordMatcher<IMABaselineReco
      */
     @Override
     public IMAMatchStatus<IMABaselineRecord> contains(final IMAMeasurementRecord record) {
-        if (record == null) {
-            throw new IllegalArgumentException("Cannot match on null record.");
-        }
+        Preconditions.checkArgument(record != null, "Cannot match on null record.");
 
         final Set<IMABaselineRecord> matchRecords = new HashSet<>();
         final Set<IMABaselineRecord> mismatchRecords = new HashSet<>();
diff --git a/HIRS_Utils/src/main/java/hirs/ima/matching/ImaRecordMatcher.java b/HIRS_Utils/src/main/java/hirs/ima/matching/ImaRecordMatcher.java
index 700a6819..2e38fc4a 100644
--- a/HIRS_Utils/src/main/java/hirs/ima/matching/ImaRecordMatcher.java
+++ b/HIRS_Utils/src/main/java/hirs/ima/matching/ImaRecordMatcher.java
@@ -9,8 +9,10 @@ import hirs.data.persist.IMAPolicy;
 import hirs.data.persist.AbstractImaBaselineRecord;
 import hirs.data.persist.ImaBaseline;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashSet;
+import java.util.List;
 import java.util.Set;
 
 /**
@@ -67,6 +69,22 @@ public abstract class ImaRecordMatcher<T extends AbstractImaBaselineRecord> {
      */
     public abstract IMAMatchStatus<T> contains(IMAMeasurementRecord record);
 
+    /**
+     * Given a collection of measurement records, populate and return a BatchImaMatchStatus
+     * instance containing the match results according to this ImaRecordMatcher's matching
+     * behavior and the given IMA policy, baseline, and baseline records.
+     *
+     * @param records the measurement records to match to baseline records
+     * @return a BatchImaMatchStatus containing the match status of all the given records
+     */
+    public BatchImaMatchStatus<T> batchMatch(final Collection<IMAMeasurementRecord> records) {
+        List<IMAMatchStatus<T>> matchStatuses = new ArrayList<>();
+        for (IMAMeasurementRecord record : records) {
+            matchStatuses.add(contains(record));
+        }
+        return new BatchImaMatchStatus<>(matchStatuses);
+    }
+
     /**
      * Gets all IMA baseline records that are related to the given IMA measurement record
      * as determined by path similarity or equivalency.  This method respects the IMA policy
diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/BroadRepoImaBaselineTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/BroadRepoImaBaselineTest.java
index e89d68b2..a7221129 100644
--- a/HIRS_Utils/src/test/java/hirs/data/persist/BroadRepoImaBaselineTest.java
+++ b/HIRS_Utils/src/test/java/hirs/data/persist/BroadRepoImaBaselineTest.java
@@ -5,6 +5,7 @@ import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 
+import hirs.ima.matching.BatchImaMatchStatus;
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 import hirs.ima.matching.IMAMatchStatus;
@@ -249,6 +250,122 @@ public class BroadRepoImaBaselineTest extends SpringPersistenceTest {
         );
     }
 
+    /**
+     * Test that ensures a BroadRepoImaBaseline can correctly determine if
+     * it contains any matching baseline records solely based upon a given measurement
+     * record's hash.
+     *
+     * @throws UnsupportedEncodingException
+     *             if an error is encountered while getting the test digest
+     */
+    @Test
+    public final void containsHashes() throws UnsupportedEncodingException {
+        BroadRepoImaBaseline testBaseline = new BroadRepoImaBaseline(BASELINE_NAME);
+        Repository testRepo = new TestRepository("Test Repository", 0);
+        DBRepositoryManager repoManager = new DBRepositoryManager(sessionFactory);
+        testRepo = repoManager.saveRepository(testRepo);
+        RepoPackage testRepoPackage =
+                new RPMRepoPackage(NAME, VERSION1, RELEASE1, ARCHITECTURE, testRepo);
+        Set<IMABaselineRecord> imaRecords = new HashSet<>();
+        imaRecords.add(SimpleImaBaselineTest.createTestIMARecord(FILEPATH1));
+        testRepoPackage.setAllMeasurements(imaRecords, RepoPackageTest.getTestDigest());
+        repoManager.saveRepoPackage(testRepoPackage);
+        Set<Repository<?>> originalRepositories = new HashSet<>();
+        originalRepositories.add(testRepo);
+        testBaseline.setRepositories(originalRepositories);
+        testBaseline.update(repoManager);
+
+        DBBaselineManager baselineManager = new DBBaselineManager(sessionFactory);
+        BroadRepoImaBaseline savedBaseline =
+                (BroadRepoImaBaseline) baselineManager.save(testBaseline);
+
+        IMABaselineRecord baselineRecord = SimpleImaBaselineTest.createTestIMARecord(FILEPATH1);
+        IMAMeasurementRecord measurementRecord = new IMAMeasurementRecord(
+                baselineRecord.getPath(),
+                baselineRecord.getHash()
+        );
+        Assert.assertEquals(
+                savedBaseline.containsHashes(
+                        Collections.singletonList(measurementRecord),
+                        new DbImaBaselineRecordManager(sessionFactory),
+                        SimpleImaBaselineTest.getTestImaPolicy(false)
+
+                ).getIMAMatchStatuses(measurementRecord),
+                Collections.singleton(
+                        new IMAMatchStatus<>(
+                                measurementRecord, ReportMatchStatus.MATCH, baselineRecord, baseline
+                        )
+                )
+        );
+
+        measurementRecord = new IMAMeasurementRecord(
+                "/some/other/file",
+                baselineRecord.getHash()
+        );
+        Assert.assertEquals(
+                savedBaseline.containsHashes(
+                        Collections.singletonList(measurementRecord),
+                        new DbImaBaselineRecordManager(sessionFactory),
+                        SimpleImaBaselineTest.getTestImaPolicy(false)
+
+                ).getIMAMatchStatuses(measurementRecord),
+                Collections.singleton(
+                        new IMAMatchStatus<>(
+                                measurementRecord, ReportMatchStatus.MATCH, baselineRecord, baseline
+                        )
+                )
+        );
+    }
+
+    /**
+     * Test that ensures a BroadRepoImaBaseline can correctly determine that
+     * it does not contain any matching baseline records solely based upon a given measurement
+     * record's hash.
+     *
+     * @throws UnsupportedEncodingException
+     *             if an error is encountered while getting the test digest
+     */
+    @Test
+    public final void containsHashesWithNoMatches() throws UnsupportedEncodingException {
+        BroadRepoImaBaseline testBaseline = new BroadRepoImaBaseline(BASELINE_NAME);
+        Repository testRepo = new TestRepository("Test Repository", 0);
+        DBRepositoryManager repoManager = new DBRepositoryManager(sessionFactory);
+        testRepo = repoManager.saveRepository(testRepo);
+        RepoPackage testRepoPackage =
+                new RPMRepoPackage(NAME, VERSION1, RELEASE1, ARCHITECTURE, testRepo);
+        Set<IMABaselineRecord> imaRecords = new HashSet<>();
+        imaRecords.add(SimpleImaBaselineTest.createTestIMARecord(FILEPATH1));
+        testRepoPackage.setAllMeasurements(imaRecords, RepoPackageTest.getTestDigest());
+        repoManager.saveRepoPackage(testRepoPackage);
+        Set<Repository<?>> originalRepositories = new HashSet<>();
+        originalRepositories.add(testRepo);
+        testBaseline.setRepositories(originalRepositories);
+        testBaseline.update(repoManager);
+
+        DBBaselineManager baselineManager = new DBBaselineManager(sessionFactory);
+        BroadRepoImaBaseline savedBaseline =
+                (BroadRepoImaBaseline) baselineManager.save(testBaseline);
+
+        IMABaselineRecord baselineRecord = SimpleImaBaselineTest.createTestIMARecord(FILEPATH1);
+        IMAMeasurementRecord measurementRecord = new IMAMeasurementRecord(
+                baselineRecord.getPath(),
+                SimpleImaBaselineTest.getDigest("0d5f3c2f7f3003d2e4baddc46ed4763a4954f648")
+        );
+        Assert.assertEquals(
+                savedBaseline.containsHashes(
+                        Collections.singletonList(measurementRecord),
+                        new DbImaBaselineRecordManager(sessionFactory),
+                        SimpleImaBaselineTest.getTestImaPolicy(false)
+
+                ),
+                new BatchImaMatchStatus<>(Collections.singleton(new IMAMatchStatus<>(
+                        measurementRecord,
+                        ReportMatchStatus.UNKNOWN,
+                        baseline
+                )))
+        );
+    }
+
     /**
      * Tests that the <code>Set</code> of <code>Repositories</code>s associated with this baseline
      * can be set, retrieved, and returned.
diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/SimpleImaBaselineTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/SimpleImaBaselineTest.java
index 9dadf964..263a9073 100644
--- a/HIRS_Utils/src/test/java/hirs/data/persist/SimpleImaBaselineTest.java
+++ b/HIRS_Utils/src/test/java/hirs/data/persist/SimpleImaBaselineTest.java
@@ -1,5 +1,6 @@
 package hirs.data.persist;
 
+import hirs.ima.matching.BatchImaMatchStatus;
 import hirs.ima.matching.IMAMatchStatus;
 import hirs.persist.BaselineManager;
 import hirs.persist.DBBaselineManager;
@@ -223,6 +224,15 @@ public class SimpleImaBaselineTest extends SpringPersistenceTest {
         ).getIMAMatchStatuses(record).iterator().next();
     }
 
+    private BatchImaMatchStatus<IMABaselineRecord> baselineContainsHashes(
+            final SimpleImaBaseline baseline,
+            final IMAMeasurementRecord record,
+            final IMAPolicy imaPolicy) {
+        return baseline.containsHashes(
+                Collections.singletonList(record), recordManager, imaPolicy
+        );
+    }
+
     /**
      * Create a test IMAPolicy object.
      *
@@ -601,6 +611,91 @@ public class SimpleImaBaselineTest extends SpringPersistenceTest {
         }
     }
 
+    /**
+     * Simple test that ensures a SimpleImaBaseline can determine whether it contains
+     * baseline records that match measurement records based solely on their hashes.
+     */
+    @Test
+    public final void containsHashes() {
+        final SimpleImaBaseline baseline = new SimpleImaBaseline("TestBaseline");
+        final String baselineGradleFilename = "/usr/bin/gradle";
+        final String measuredGradleFilename = "/usr/bin/gradle_by_another_name";
+        final Digest gradleHash = getDigest("33333c2f7f3003d2e4baddc46ed4763a49543333");
+
+        final IMABaselineRecord baseRecSameNameMatchingHash = new IMABaselineRecord(
+                measuredGradleFilename, gradleHash
+        );
+
+        final IMABaselineRecord baseRecDifferentNameMatchingHash = new IMABaselineRecord(
+                baselineGradleFilename, gradleHash
+        );
+
+        baseline.addToBaseline(baseRecSameNameMatchingHash);
+        baseline.addToBaseline(baseRecDifferentNameMatchingHash);
+
+        baseline.addToBaseline(new IMABaselineRecord(
+                baselineGradleFilename,
+                getDigest("00000c2f7f3003d2e4baddc46ed4763a49543333")
+        ));
+        baseline.addToBaseline(new IMABaselineRecord(
+                measuredGradleFilename,
+                getDigest("00000c2f7f3003d2e4baddc46ed4763a49543333")
+        ));
+
+
+        IMAMeasurementRecord measurementRecord = new IMAMeasurementRecord(
+                measuredGradleFilename, gradleHash
+        );
+
+        Set<IMABaselineRecord> matchingRecords = new HashSet<>(Arrays.asList(
+                baseRecSameNameMatchingHash,
+                baseRecDifferentNameMatchingHash
+        ));
+
+        Assert.assertEquals(
+                baselineContainsHashes(baseline, measurementRecord, getTestImaPolicy(false)),
+                new BatchImaMatchStatus<>(
+                        Collections.singleton(new IMAMatchStatus<>(
+                                measurementRecord,
+                                ReportMatchStatus.MATCH,
+                                matchingRecords,
+                                baseline
+                        ))
+                )
+        );
+    }
+
+    /**
+     * Simple test that ensures a SimpleImaBaseline can determine whether it contains
+     * baseline records that match measurement records based solely on their hashes.
+     */
+    @Test
+    public final void containsHashesWithNoMatches() {
+        final SimpleImaBaseline baseline = new SimpleImaBaseline("TestBaseline");
+        final String baselineGradleFilename = "/usr/bin/gradle";
+        final String measuredGradleFilename = "/usr/bin/gradle_by_another_name";
+        final Digest gradleHash = getDigest("33333c2f7f3003d2e4baddc46ed4763a49543333");
+
+        baseline.addToBaseline(new IMABaselineRecord(
+                baselineGradleFilename,
+                getDigest("00000c2f7f3003d2e4baddc46ed4763a49543333")
+        ));
+
+        IMAMeasurementRecord record = new IMAMeasurementRecord(
+                measuredGradleFilename, gradleHash
+        );
+
+        Assert.assertEquals(baselineContainsHashes(baseline, record, getTestImaPolicy(false)),
+                new BatchImaMatchStatus<>(
+                        Collections.singleton(new IMAMatchStatus<>(
+                                record,
+                                ReportMatchStatus.UNKNOWN,
+                                baseline
+                        ))
+                )
+        );
+    }
+
     /**
      * Tests that getBaselineRecords() returns a list of IMA records.
      *
diff --git a/HIRS_Utils/src/test/java/hirs/data/persist/TargetedRepoImaBaselineTest.java b/HIRS_Utils/src/test/java/hirs/data/persist/TargetedRepoImaBaselineTest.java
index 430e29f0..adcc48d7 100644
--- a/HIRS_Utils/src/test/java/hirs/data/persist/TargetedRepoImaBaselineTest.java
+++ b/HIRS_Utils/src/test/java/hirs/data/persist/TargetedRepoImaBaselineTest.java
@@ -8,6 +8,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
+import hirs.ima.matching.BatchImaMatchStatus;
 import hirs.ima.matching.IMAMatchStatus;
 import hirs.persist.BaselineManager;
 import hirs.persist.DBBaselineManager;
@@ -355,6 +356,123 @@ public class TargetedRepoImaBaselineTest extends SpringPersistenceTest {
         );
     }
 
+    /**
+     * Test that ensures a TargetedRepoImaBaseline can correctly determine if
+     * it contains any matching baseline records solely based upon a given measurement
+     * record's hash.
+     *
+     * @throws UnsupportedEncodingException
+     *             if an error is encountered while getting the test digest
+     */
+    @Test
+    public final void containsHashes() throws UnsupportedEncodingException {
+        TargetedRepoImaBaseline testBaseline = new TargetedRepoImaBaseline(BASELINE_NAME);
+        Repository testRepo = new TestRepository("Test Repository", 0);
+        DBRepositoryManager repoManager = new DBRepositoryManager(sessionFactory);
+        testRepo = repoManager.saveRepository(testRepo);
+        RepoPackage testRepoPackage =
+                new RPMRepoPackage(NAME, VERSION1, RELEASE1, ARCHITECTURE, testRepo);
+        Set<IMABaselineRecord> imaRecords = new HashSet<>();
+        imaRecords.add(SimpleImaBaselineTest.createTestIMARecord(FILEPATH1));
+        testRepoPackage.setAllMeasurements(imaRecords, RepoPackageTest.getTestDigest());
+        repoManager.saveRepoPackage(testRepoPackage);
+        Set<RepoPackage> originalPackages = new HashSet<>();
+        originalPackages.add(testRepoPackage);
+        testBaseline.setRepoPackages(originalPackages);
+
+        DBBaselineManager baselineManager = new DBBaselineManager(sessionFactory);
+        TargetedRepoImaBaseline savedBaseline =
+                (TargetedRepoImaBaseline) baselineManager.save(testBaseline);
+
+        IMABaselineRecord baselineRecord = SimpleImaBaselineTest.createTestIMARecord(FILEPATH1);
+        IMAMeasurementRecord measurementRecord = new IMAMeasurementRecord(
+                baselineRecord.getPath(),
+                baselineRecord.getHash()
+        );
+
+        Assert.assertEquals(
+                savedBaseline.containsHashes(
+                        Collections.singletonList(measurementRecord),
+                        new DbImaBaselineRecordManager(sessionFactory),
+                        SimpleImaBaselineTest.getTestImaPolicy(false)
+
+                ).getIMAMatchStatuses(measurementRecord),
+                Collections.singleton(
+                        new IMAMatchStatus<>(
+                                measurementRecord, ReportMatchStatus.MATCH, baselineRecord, baseline
+                        )
+                )
+        );
+
+        measurementRecord = new IMAMeasurementRecord(
+                "/some/other/file",
+                baselineRecord.getHash()
+        );
+        Assert.assertEquals(
+                savedBaseline.containsHashes(
+                        Collections.singletonList(measurementRecord),
+                        new DbImaBaselineRecordManager(sessionFactory),
+                        SimpleImaBaselineTest.getTestImaPolicy(false)
+
+                ).getIMAMatchStatuses(measurementRecord),
+                Collections.singleton(
+                        new IMAMatchStatus<>(
+                                measurementRecord, ReportMatchStatus.MATCH, baselineRecord, baseline
+                        )
+                )
+        );
+    }
+
+    /**
+     * Test that ensures a TargetedRepoImaBaseline can correctly determine that
+     * it does not contain any matching baseline records solely based upon a given measurement
+     * record's hash.
+     *
+     * @throws UnsupportedEncodingException
+     *             if an error is encountered while getting the test digest
+     */
+    @Test
+    public final void containsHashesWithNoMatches() throws UnsupportedEncodingException {
+        TargetedRepoImaBaseline testBaseline = new TargetedRepoImaBaseline(BASELINE_NAME);
+        Repository testRepo = new TestRepository("Test Repository", 0);
+        DBRepositoryManager repoManager = new DBRepositoryManager(sessionFactory);
+        testRepo = repoManager.saveRepository(testRepo);
+        RepoPackage testRepoPackage =
+                new RPMRepoPackage(NAME, VERSION1, RELEASE1, ARCHITECTURE, testRepo);
+        Set<IMABaselineRecord> imaRecords = new HashSet<>();
+        imaRecords.add(SimpleImaBaselineTest.createTestIMARecord(FILEPATH1));
+        testRepoPackage.setAllMeasurements(imaRecords, RepoPackageTest.getTestDigest());
+        repoManager.saveRepoPackage(testRepoPackage);
+        Set<RepoPackage> originalPackages = new HashSet<>();
+        originalPackages.add(testRepoPackage);
+        testBaseline.setRepoPackages(originalPackages);
+
+        DBBaselineManager baselineManager = new DBBaselineManager(sessionFactory);
+        TargetedRepoImaBaseline savedBaseline =
+                (TargetedRepoImaBaseline) baselineManager.save(testBaseline);
+
+        IMABaselineRecord baselineRecord = SimpleImaBaselineTest.createTestIMARecord(FILEPATH1);
+
+        IMAMeasurementRecord measurementRecord = new IMAMeasurementRecord(
+                baselineRecord.getPath(),
+                SimpleImaBaselineTest.getDigest("0d5f3c2f7f3003d2e4baddc46ed4763a4954f648")
+        );
+
+        Assert.assertEquals(
+                savedBaseline.containsHashes(
+                        Collections.singletonList(measurementRecord),
+                        new DbImaBaselineRecordManager(sessionFactory),
+                        SimpleImaBaselineTest.getTestImaPolicy(false)
+
+                ),
+                new BatchImaMatchStatus<>(Collections.singleton(new IMAMatchStatus<>(
+                        measurementRecord,
+                        ReportMatchStatus.UNKNOWN,
+                        baseline
+                )))
+        );
+    }
+
     /**
      * Tests that a <code>TargetedRepoImaBaseline</code> can be archived.
      */
diff --git a/HIRS_Utils/src/test/java/hirs/ima/matching/ImaAcceptableHashRecordMatcherTest.java b/HIRS_Utils/src/test/java/hirs/ima/matching/ImaAcceptableHashRecordMatcherTest.java
new file mode 100644
index 00000000..d7d3309f
--- /dev/null
+++ b/HIRS_Utils/src/test/java/hirs/ima/matching/ImaAcceptableHashRecordMatcherTest.java
@@ -0,0 +1,153 @@
+package hirs.ima.matching;
+
+import hirs.data.persist.Digest;
+import hirs.data.persist.IMABaselineRecord;
+import hirs.data.persist.IMAMeasurementRecord;
+import hirs.data.persist.ReportMatchStatus;
+import hirs.data.persist.SimpleImaBaseline;
+import hirs.data.persist.SimpleImaBaselineTest;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Tests for the ImaAcceptableHashRecordMatcher.  These are basic tests of its functionality;
+ * more complete tests for contains() as used operationally by baselines that test various
+ * permutations of parameters are located in SimpleImaBaselineTest, BroadRepoImaBaselineTest,
+ * TargetedRepoImaBaselineTest, ImaBlacklistBaselineTest, and ImaIgnoreSetBaselineTest.
+ */
+public class ImaAcceptableHashRecordMatcherTest {
+    private static final String FILENAME_1 = "/bin/ls";
+    private static final String FILENAME_2 = "/bin/ls_with_another_name";
+    private static final Digest HASH_1 =
+            SimpleImaBaselineTest.getDigest("33333c2f7f3003d2e4baddc46ed4763a49543333");
+    private static final Digest HASH_2 =
+            SimpleImaBaselineTest.getDigest("00000c2f7f3003d2e4baddc46ed4763a49543333");
+
+    /**
+     * Tests that the 'contains' method functions if no records are given.
+     */
+    @Test
+    public void testContainsEmpty() {
+        SimpleImaBaseline baseline = getTestSimpleImaBaseline();
+        IMAMeasurementRecord measurementRecord = new IMAMeasurementRecord(FILENAME_1, HASH_1);
+        Assert.assertEquals(
+                new ImaAcceptableHashRecordMatcher(
+                        Collections.emptyList(),
+                        SimpleImaBaselineTest.getTestImaPolicy(false),
+                        baseline).contains(measurementRecord),
+                new IMAMatchStatus(measurementRecord, ReportMatchStatus.UNKNOWN, baseline)
+        );
+    }
+
+    /**
+     * Tests that the 'contains' method functions if a matching record is given in the case of that
+     * matching record being both filename and hash.
+     */
+    @Test
+    public void testContainsSameFilename() {
+        SimpleImaBaseline baseline = getTestSimpleImaBaseline();
+        IMAMeasurementRecord measurementRecord = new IMAMeasurementRecord(FILENAME_1, HASH_1);
+        IMABaselineRecord baselineRecord = new IMABaselineRecord(FILENAME_1, HASH_1);
+        Assert.assertEquals(
+                new ImaAcceptableHashRecordMatcher(
+                        Collections.singletonList(baselineRecord),
+                        SimpleImaBaselineTest.getTestImaPolicy(false),
+                        baseline).contains(measurementRecord),
+                new IMAMatchStatus<>(
+                        measurementRecord, ReportMatchStatus.MATCH, baselineRecord, baseline
+                )
+        );
+    }
+
+    /**
+     * Tests that the 'contains' method matches on hash properly, even if
+     * a measurement record has a different filename than the matching baseline record.
+     */
+    @Test
+    public void testContainsDifferentFilename() {
+        SimpleImaBaseline baseline = getTestSimpleImaBaseline();
+        IMAMeasurementRecord measurementRecord = new IMAMeasurementRecord(FILENAME_2, HASH_1);
+        IMABaselineRecord baselineRecord = new IMABaselineRecord(FILENAME_1, HASH_1);
+        Assert.assertEquals(
+                new ImaAcceptableHashRecordMatcher(
+                        Collections.singletonList(baselineRecord),
+                        SimpleImaBaselineTest.getTestImaPolicy(false),
+                        baseline).contains(measurementRecord),
+                new IMAMatchStatus<>(
+                        measurementRecord, ReportMatchStatus.MATCH, baselineRecord, baseline
+                )
+        );
+    }
+
+    /**
+     * Tests that the 'contains' method returns the expected 'UNKNOWN' match
+     * status if no record matches the collected measurement in a nonempty baseline.
+     */
+    @Test
+    public void testContainsNonEmptyButUnknown() {
+        SimpleImaBaseline baseline = getTestSimpleImaBaseline();
+        IMAMeasurementRecord measurementRecord = new IMAMeasurementRecord(FILENAME_1, HASH_1);
+        IMABaselineRecord baselineRecord = new IMABaselineRecord(FILENAME_1, HASH_2);
+        Assert.assertEquals(
+                new ImaAcceptableHashRecordMatcher(
+                        Collections.singletonList(baselineRecord),
+                        SimpleImaBaselineTest.getTestImaPolicy(false),
+                        baseline).contains(measurementRecord),
+                new IMAMatchStatus(measurementRecord, ReportMatchStatus.UNKNOWN, baseline)
+        );
+    }
+
+    /**
+     * Tests that the 'contains' method returns all matching baseline records from a
+     * baseline when there are multiple matches to a given measurement record.
+     */
+    @Test
+    public void testContainsMultipleMatchingBaselineRecords() {
+        SimpleImaBaseline baseline = getTestSimpleImaBaseline();
+        IMAMeasurementRecord measurementRecord = new IMAMeasurementRecord(FILENAME_1, HASH_1);
+        Set<IMABaselineRecord> baselineRecords = new HashSet<>(Arrays.asList(
+                new IMABaselineRecord(FILENAME_1, HASH_1),
+                new IMABaselineRecord(FILENAME_2, HASH_1),
+                new IMABaselineRecord(FILENAME_1, HASH_2)
+        ));
+        Assert.assertEquals(
+                new ImaAcceptableHashRecordMatcher(
+                        baselineRecords,
+                        SimpleImaBaselineTest.getTestImaPolicy(false),
+                        baseline
+                ).contains(measurementRecord),
+                new IMAMatchStatus<>(
+                        measurementRecord,
+                        ReportMatchStatus.MATCH,
+                        new HashSet<>(Arrays.asList(
+                            new IMABaselineRecord(FILENAME_1, HASH_1),
+                            new IMABaselineRecord(FILENAME_2, HASH_1))
+                        ),
+                        baseline
+                )
+        );
+    }
+
+    /**
+     * Tests that the 'contains' method throws an IllegalArgumentException if given a null
+     * measurement record to check.
+     */
+    @Test(expectedExceptions = IllegalArgumentException.class)
+    public void testContainsOnNullRecord() {
+        SimpleImaBaseline baseline = getTestSimpleImaBaseline();
+        IMABaselineRecord baselineRecord = new IMABaselineRecord(FILENAME_1, HASH_1);
+        new ImaAcceptableHashRecordMatcher(
+                Collections.singletonList(baselineRecord),
+                SimpleImaBaselineTest.getTestImaPolicy(false),
+                baseline).contains(null);
+    }
+
+    private static SimpleImaBaseline getTestSimpleImaBaseline() {
+        return new SimpleImaBaseline("Test IMA Baseline");
+    }
+}
diff --git a/HIRS_Utils/src/test/java/hirs/ima/ImaAcceptableRecordMatcherTest.java b/HIRS_Utils/src/test/java/hirs/ima/matching/ImaAcceptablePathAndHashRecordMatcherTest.java
similarity index 63%
rename from HIRS_Utils/src/test/java/hirs/ima/ImaAcceptableRecordMatcherTest.java
rename to HIRS_Utils/src/test/java/hirs/ima/matching/ImaAcceptablePathAndHashRecordMatcherTest.java
index 8363dcd5..b0bdbddc 100644
--- a/HIRS_Utils/src/test/java/hirs/ima/ImaAcceptableRecordMatcherTest.java
+++ b/HIRS_Utils/src/test/java/hirs/ima/matching/ImaAcceptablePathAndHashRecordMatcherTest.java
@@ -1,26 +1,27 @@
-package hirs.ima;
+package hirs.ima.matching;
 
 import hirs.data.persist.Digest;
+import hirs.data.persist.DigestTest;
 import hirs.data.persist.IMABaselineRecord;
 import hirs.data.persist.IMAMeasurementRecord;
+import hirs.data.persist.ImaAcceptableRecordBaseline;
 import hirs.data.persist.ReportMatchStatus;
 import hirs.data.persist.SimpleImaBaseline;
-import hirs.ima.matching.IMAMatchStatus;
-import hirs.ima.matching.ImaAcceptableRecordMatcher;
+import hirs.data.persist.SimpleImaBaselineTest;
 import org.testng.Assert;
 import org.testng.annotations.Test;
-import hirs.data.persist.SimpleImaBaselineTest;
 
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.List;
 
 /**
- * Tests ImaAcceptableRecordMatcher.  These are very basic tests of its functionality;
+ * Tests ImaAcceptablePathAndHashRecordMatcher.  These are very basic tests of its functionality;
  * more complete tests for contains() as used operationally by baselines that test various
  * permutations of parameters are located in SimpleImaBaselineTest, BroadRepoImaBaselineTest,
  * TargetedRepoImaBaselineTest, ImaBlacklistBaselineTest, and ImaIgnoreSetBaselineTest.
  */
-public class ImaAcceptableRecordMatcherTest {
+public class ImaAcceptablePathAndHashRecordMatcherTest {
     private static final String FILE_1 = "/bin/ls";
     private static final String PARTIAL_FILE_1 = "ls";
     private static final Digest HASH_1 =
@@ -33,6 +34,7 @@ public class ImaAcceptableRecordMatcherTest {
     private static final Digest LIB64_LD_HASH =
             SimpleImaBaselineTest.getDigest("55555c2f7f3003d2e4baddc46ed4763a49543333");
 
+    private static final Digest ONES = DigestTest.getTestSHA1Digest();
 
     /**
      * Tests that contains functions if no records are given.
@@ -42,7 +44,7 @@ public class ImaAcceptableRecordMatcherTest {
         SimpleImaBaseline baseline = getTestSimpleImaBaseline();
         IMAMeasurementRecord measurementRecord = new IMAMeasurementRecord(FILE_1, HASH_1);
         Assert.assertEquals(
-                new ImaAcceptableRecordMatcher(
+                new ImaAcceptablePathAndHashRecordMatcher(
                         Collections.emptyList(),
                         SimpleImaBaselineTest.getTestImaPolicy(false),
                         baseline).contains(measurementRecord),
@@ -59,7 +61,7 @@ public class ImaAcceptableRecordMatcherTest {
         IMAMeasurementRecord measurementRecord = new IMAMeasurementRecord(FILE_1, HASH_1);
         IMABaselineRecord baselineRecord = new IMABaselineRecord(FILE_1, HASH_1);
         Assert.assertEquals(
-                new ImaAcceptableRecordMatcher(
+                new ImaAcceptablePathAndHashRecordMatcher(
                         Collections.singletonList(baselineRecord),
                         SimpleImaBaselineTest.getTestImaPolicy(false),
                         baseline).contains(measurementRecord),
@@ -78,7 +80,7 @@ public class ImaAcceptableRecordMatcherTest {
         IMAMeasurementRecord measurementRecord = new IMAMeasurementRecord(PARTIAL_FILE_1, HASH_1);
         IMABaselineRecord baselineRecord = new IMABaselineRecord(FILE_1, HASH_1);
         Assert.assertEquals(
-                new ImaAcceptableRecordMatcher(
+                new ImaAcceptablePathAndHashRecordMatcher(
                         Collections.singletonList(baselineRecord),
                         SimpleImaBaselineTest.getTestImaPolicy(true),
                         baseline).contains(measurementRecord),
@@ -99,16 +101,82 @@ public class ImaAcceptableRecordMatcherTest {
         IMAMeasurementRecord measurementRecord =
                 new IMAMeasurementRecord(LIB64_LD_FILE, USR_LIB64_LD_HASH);
         Assert.assertEquals(
-                new ImaAcceptableRecordMatcher(
+                new ImaAcceptablePathAndHashRecordMatcher(
                         Collections.singletonList(baselineRecord),
                         SimpleImaBaselineTest.getTestImaPolicy(false),
-                        baseline).contains(measurementRecord),
+                        baseline
+                ).contains(measurementRecord),
                 new IMAMatchStatus<>(
                         measurementRecord, ReportMatchStatus.MATCH, baselineRecord, baseline
                 )
         );
     }
 
+    /**
+     * Tests that contains correctly matches equivalent paths for real-world
+     * examples that have been seen.
+     */
+    @Test
+    public void testContainsExperiencedEquivalentPaths() {
+        List<List<String>> pairs = Arrays.asList(
+                Arrays.asList("/usr/sbin/dhclient", "/sbin/dhclient"),
+                Arrays.asList("/usr/sbin/sysctl", "/sbin/sysctl"),
+                Arrays.asList("/usr/sbin/swapon", "/sbin/swapon"),
+                Arrays.asList("/sbin/audispd", "/usr/sbin/audispd"),
+                Arrays.asList("/usr/sbin/sysctl", "/sbin/sysctl"),
+                Arrays.asList("/sbin/ldconfig", "/usr/sbin/ldconfig"),
+                Arrays.asList("/sbin/kexec", "/usr/sbin/kexec"),
+                Arrays.asList("/usr/sbin/ip", "/sbin/ip"),
+                Arrays.asList("/usr/bin/bash", "/bin/bash")
+        );
+
+        for (List<String> pair : pairs) {
+            testEquivalentNames(pair.get(0), pair.get(1));
+        }
+    }
+
+    /**
+     * Tests that contains correctly matches equivalent paths.
+     */
+    @Test
+    public void testContainsExhaustiveEquivalentPaths() {
+        List<List<String>> pairs = Arrays.asList(
+                Arrays.asList("/bin/foofile", "/usr/bin/foofile"),
+                Arrays.asList("/lib/foofile", "/usr/lib/foofile"),
+                Arrays.asList("/lib64/foofile", "/usr/lib64/foofile"),
+                Arrays.asList("/usr/bin/foofile", "/usr/sbin/foofile"),
+                Arrays.asList("/sbin/foofile", "/usr/sbin/foofile")
+        );
+
+        for (int i = 0; i < pairs.size(); i++) {
+            List<String> equivPair = pairs.get(i);
+
+            testEquivalentNames(equivPair.get(0), equivPair.get(1));
+            testEquivalentNames(equivPair.get(1), equivPair.get(0));
+        }
+    }
+
+    private void testEquivalentNames(final String measuredFilename, final String baselineFilename) {
+        final IMAMeasurementRecord measurementRecord =
+                new IMAMeasurementRecord(measuredFilename, ONES);
+        final IMABaselineRecord baselineRecord = new IMABaselineRecord(baselineFilename, ONES);
+        final ImaAcceptableRecordBaseline baseline = getTestSimpleImaBaseline();
+
+        Assert.assertEquals(
+                new ImaAcceptablePathAndHashRecordMatcher(
+                        Collections.singleton(baselineRecord),
+                        SimpleImaBaselineTest.getTestImaPolicy(false),
+                        baseline
+                ).contains(measurementRecord),
+                new IMAMatchStatus<>(
+                        measurementRecord,
+                        ReportMatchStatus.MATCH,
+                        baselineRecord,
+                        baseline
+                )
+        );
+    }
+
     /**
      * This tests a case where a baseline includes a file at both /lib64 and /usr/lib64
      * with distinct hashes, and a report contains an entry for a file at /usr/lib64 whose hash
@@ -128,7 +196,7 @@ public class ImaAcceptableRecordMatcherTest {
         IMAMeasurementRecord measurementRecord =
                 new IMAMeasurementRecord(USR_LIB64_LD_FILE, LIB64_LD_HASH);
         Assert.assertEquals(
-                new ImaAcceptableRecordMatcher(
+                new ImaAcceptablePathAndHashRecordMatcher(
                         Arrays.asList(libBaselineRecord, usrLibBaselineRecord),
                         SimpleImaBaselineTest.getTestImaPolicy(false),
                         baseline).contains(measurementRecord),
diff --git a/HIRS_Utils/src/test/java/hirs/ima/matching/package-info.java b/HIRS_Utils/src/test/java/hirs/ima/matching/package-info.java
new file mode 100644
index 00000000..ae6bbdc2
--- /dev/null
+++ b/HIRS_Utils/src/test/java/hirs/ima/matching/package-info.java
@@ -0,0 +1,5 @@
+/**
+ * Contains classes that perform record matching from IMA measurement records
+ * to IMA baselines records.
+ */
+package hirs.ima.matching;