diff --git a/SabreTools.Core/ModelBackedItem.cs b/SabreTools.Core/ModelBackedItem.cs
new file mode 100644
index 00000000..99809c73
--- /dev/null
+++ b/SabreTools.Core/ModelBackedItem.cs
@@ -0,0 +1,161 @@
+using System.Xml.Serialization;
+using Newtonsoft.Json;
+using SabreTools.Core.Tools;
+
+namespace SabreTools.Core
+{
+ ///
+ /// Represents an item that's backed by a DictionaryBase item
+ ///
+ public abstract class ModelBackedItem where T : Models.Metadata.DictionaryBase
+ {
+ ///
+ /// Internal model wrapped by this DatItem
+ ///
+ [JsonIgnore, XmlIgnore]
+ protected Models.Metadata.DictionaryBase _internal;
+
+ #region Constructors
+
+ public ModelBackedItem()
+ {
+ _internal = new DummyItem();
+ }
+
+ #endregion
+
+ #region Accessors
+
+ ///
+ /// Get the value from a field based on the type provided
+ ///
+ /// Type of the value to get from the internal model
+ /// Field to retrieve
+ /// Value from the field, if possible
+ public U? GetFieldValue(string? fieldName)
+ {
+ // Invalid field cannot be processed
+ if (string.IsNullOrEmpty(fieldName))
+ return default;
+
+ // Get the value based on the type
+ return _internal!.Read(fieldName!);
+ }
+
+ ///
+ /// Get the value from a field based on the type provided
+ ///
+ /// Field to retrieve
+ /// Value from the field, if possible
+ public bool? GetBoolFieldValue(string? fieldName)
+ {
+ // Invalid field cannot be processed
+ if (string.IsNullOrEmpty(fieldName) || !_internal.ContainsKey(fieldName!))
+ return default;
+
+ // Get the value based on the type
+ return _internal.ReadBool(fieldName!);
+ }
+
+ ///
+ /// Get the value from a field based on the type provided
+ ///
+ /// Field to retrieve
+ /// Value from the field, if possible
+ public double? GetDoubleFieldValue(string? fieldName)
+ {
+ // Invalid field cannot be processed
+ if (string.IsNullOrEmpty(fieldName) || !_internal.ContainsKey(fieldName!))
+ return default;
+
+ // Try to parse directly
+ double? doubleValue = _internal.ReadDouble(fieldName!);
+ if (doubleValue != null)
+ return doubleValue;
+
+ // Try to parse from the string
+ string? stringValue = _internal.ReadString(fieldName!);
+ return NumberHelper.ConvertToDouble(stringValue);
+ }
+
+ ///
+ /// Get the value from a field based on the type provided
+ ///
+ /// Field to retrieve
+ /// Value from the field, if possible
+ public long? GetInt64FieldValue(string? fieldName)
+ {
+ // Invalid field cannot be processed
+ if (string.IsNullOrEmpty(fieldName) || !_internal.ContainsKey(fieldName!))
+ return default;
+
+ // Try to parse directly
+ long? longValue = _internal.ReadLong(fieldName!);
+ if (longValue != null)
+ return longValue;
+
+ // Try to parse from the string
+ string? stringValue = _internal.ReadString(fieldName!);
+ return NumberHelper.ConvertToInt64(stringValue);
+ }
+
+ ///
+ /// Get the value from a field based on the type provided
+ ///
+ /// Field to retrieve
+ /// Value from the field, if possible
+ public string? GetStringFieldValue(string? fieldName)
+ {
+ // Invalid field cannot be processed
+ if (string.IsNullOrEmpty(fieldName) || !_internal.ContainsKey(fieldName!))
+ return default;
+
+ // Get the value based on the type
+ return _internal.ReadString(fieldName!);
+ }
+
+ ///
+ /// Get the value from a field based on the type provided
+ ///
+ /// Field to retrieve
+ /// Value from the field, if possible
+ public string[]? GetStringArrayFieldValue(string? fieldName)
+ {
+ // Invalid field cannot be processed
+ if (string.IsNullOrEmpty(fieldName) || !_internal.ContainsKey(fieldName!))
+ return default;
+
+ // Get the value based on the type
+ return _internal.ReadStringArray(fieldName!);
+ }
+
+ ///
+ /// Set the value from a field based on the type provided
+ ///
+ /// Type of the value to set in the internal model
+ /// Field to set
+ /// Value to set
+ /// True if the value was set, false otherwise
+ public bool SetFieldValue(string? fieldName, U? value)
+ {
+ // Invalid field cannot be processed
+ if (string.IsNullOrEmpty(fieldName))
+ return false;
+
+ // Set the value based on the type
+ _internal[fieldName!] = value;
+ return true;
+ }
+
+ #endregion
+
+ #region Dummy Classes
+
+ ///
+ /// Dummy item for use with the default constructor
+ ///
+ private class DummyItem : Models.Metadata.DictionaryBase { }
+
+ #endregion
+ }
+}