diff --git a/SabreTools.Filter/FilterRunner.cs b/SabreTools.Filter/FilterRunner.cs
new file mode 100644
index 00000000..e7c480f6
--- /dev/null
+++ b/SabreTools.Filter/FilterRunner.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using SabreTools.Models.Internal;
+
+namespace SabreTools.Filter
+{
+ ///
+ /// Represents a set of filters that can be run against an object
+ ///
+ public class FilterRunner
+ {
+ ///
+ /// Set of filters to be run against an object
+ ///
+ public FilterObject[] Filters { get; init; }
+
+ public FilterRunner(FilterObject[]? filters)
+ {
+ if (filters == null)
+ throw new ArgumentNullException(nameof(filters));
+
+ this.Filters = filters;
+ }
+
+ public FilterRunner(string[]? filterStrings)
+ {
+ if (filterStrings == null)
+ throw new ArgumentNullException(nameof(filterStrings));
+
+ var filters = new List();
+ foreach (string filterString in filterStrings)
+ {
+ filters.Add(new FilterObject(filterString));
+ }
+
+ this.Filters = filters.ToArray();
+ }
+
+ ///
+ /// Run filtering on a DictionaryBase item
+ ///
+ public bool Run(DictionaryBase dictionaryBase)
+ {
+ string? itemName = dictionaryBase switch
+ {
+ Header => MetadataFile.HeaderKey,
+ Machine => MetadataFile.MachineKey,
+ DatItem => dictionaryBase.ReadString(DatItem.TypeKey),
+ _ => null,
+ };
+
+ // Loop through and run each filter in order
+ foreach (var filter in this.Filters)
+ {
+ // TODO: Make this step more accurate
+ // If the filter isn't for this object type, skip
+ if (filter.Key[0] != itemName)
+ continue;
+
+ // If we don't get a match, it's a failure
+ if (!filter.Matches(dictionaryBase))
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/SabreTools.Models/Internal/ItemType.cs b/SabreTools.Models/Internal/ItemType.cs
index 581594ae..0e495af9 100644
--- a/SabreTools.Models/Internal/ItemType.cs
+++ b/SabreTools.Models/Internal/ItemType.cs
@@ -3,6 +3,7 @@ namespace SabreTools.Models.Internal
///
/// Determine what type of file an item is
///
+ /// TODO: Create attribute for internal names
public enum ItemType
{
///