public static bool Change <T>(
            this IPropertyOwner owner, T oldValue, T value, Action setter, [CallerMemberName] string propertyName = null,
            params string[] derivedProperties)
        {
            if (AreEqual(oldValue, value))
            {
                return(false);
            }
            string isDefaultedPropertyName = PropertyOwnerExtensions.IsDefaultedPropertyName(propertyName);
            bool   isDefaultedChange       = owner.HasProperty(isDefaultedPropertyName) &&
                                             (owner.IsDefaulted(propertyName) ^ ((object)value is null));

            PropertyChangeNotifier.OnChanging(owner, propertyName);
            if (isDefaultedChange)
            {
                PropertyChangeNotifier.OnChanging(owner, isDefaultedPropertyName);
            }
            if (derivedProperties?.Any() ?? false)
            {
                PropertyChangeNotifier.OnChanging(owner, derivedProperties);
            }
            setter();
            PropertyChangeNotifier.OnChanged(owner, propertyName);
            if (isDefaultedChange)
            {
                PropertyChangeNotifier.OnChanged(owner, isDefaultedPropertyName);
            }
            if (derivedProperties?.Any() ?? false)
            {
                PropertyChangeNotifier.OnChanged(owner, derivedProperties);
            }
            return(true);
        }