private void HandleKeyChanged(AttributeItem attributeItem, string oldKey, string newKey)
        {
            if (attributeItem.IsReadOnly)
            {
                Debug.LogError($"CharacterAttributeItemsManager.HandleKeyChanged: Attempt to change key of read-only attribute. OldKey:{oldKey} NewKey:{newKey}");
                attributeItem.Key = oldKey;
            }
            else if (newKey.Length > 256 || !Regex.IsMatch(newKey, "^[A-Za-z0-9_]+$"))
            {
                Debug.Log($"CharacterAttributeItemsManager.HandleKeyChanged: New key does not follow rules MaxLength:256 Pattern:[A-Za-z0-9_]+ OldKey:{oldKey} NewKey:{newKey}");
                attributeItem.Key = oldKey;
            }
            else if (_customAttributes.ContainsKey(newKey))
            {
                Debug.Log($"CharacterAttributeItemsManager.HandleKeyChanged: This key already exists. Key:{newKey}");
                attributeItem.Key = oldKey;
            }
            else
            {
                if (!attributeItem.IsNew && !_removedAttributes.Contains(oldKey))
                {
                    _removedAttributes.Add(oldKey);
                }

                if (_removedAttributes.Contains(newKey))
                {
                    _removedAttributes.Remove(newKey);
                }

                _customAttributes.Remove(oldKey);
                _customAttributes[newKey] = attributeItem;

                attributeItem.IsModified = true;
            }
        }
 private void HandleValueChanged(AttributeItem attributeItem, string oldValue, string newValue)
 {
     if (attributeItem.IsReadOnly)
     {
         Debug.LogError($"CharacterAttributeItemsManager.HandleValueChanged: Attempt to change value of read-only attribute. Key:{attributeItem.Key} OldValue:{oldValue} NewValue:{newValue}");
         attributeItem.Value = oldValue;
     }
     else if (newValue.Length > 256)
     {
         Debug.Log($"CharacterAttributeItemsManager.HandleValueChanged: New value does not follow rule MaxLength:256 Key:{attributeItem.Key} OldValue:{oldValue} NewValue:{newValue}");
         attributeItem.Value = oldValue;
     }
     else
     {
         attributeItem.IsModified = true;
     }
 }
        private void HandleRemoveRequest(AttributeItem attributeItem)
        {
            if (attributeItem.IsReadOnly)
            {
                Debug.LogError($"CharacterAttributeItemsManager.HandleRemoveRequest: Attempt to remove read-only attribute. Key:{attributeItem.Key} Value:{attributeItem.Value}");
            }
            else
            {
                var key = attributeItem.Key;

                if (!attributeItem.IsNew && !_removedAttributes.Contains(key))
                {
                    _removedAttributes.Add(key);
                }

                _customAttributes.Remove(key);
                Destroy(attributeItem.gameObject);
            }
        }