private void SetValue(object value, string propertyName, bool forceSetValue)
        {
            PropertyData propertyData = GetPropertyData(propertyName, nameof(propertyName));

            ValidateValueForType(value, propertyData.Type);

            // Calling Equals calls the overriden method even when the value is boxed
            bool?valuesEqual = propertyData.Value?.Equals(value);

            if (forceSetValue || (valuesEqual == null && !ReferenceEquals(value, null)) || valuesEqual == false)
            {
                object oldValue = propertyData.Value;
                propertyData.Value = value;

                if (IsPropertyChangedCallbackInvokingEnabled)
                {
                    propertyData.InvokePropertyChangedCallback(this, new PropertyChangedCallbackArgs(oldValue, value));
                }

                if (IsPropertyChangedEventInvokingEnabled)
                {
                    OnPropertyChanged(propertyName);
                }
            }
        }