private bool CalculatePropertyDetails(JsonProperty property, ref JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target, out bool useExistingValue, out object currentValue, out JsonContract propertyContract, out bool gottenCurrentValue)
        {
            currentValue = null;
            useExistingValue = false;
            propertyContract = null;
            gottenCurrentValue = false;

            if (property.Ignored)
                return true;

            JsonToken tokenType = reader.TokenType;

            if (property.PropertyContract == null)
                property.PropertyContract = GetContractSafe(property.PropertyType);

            ObjectCreationHandling objectCreationHandling =
              property.ObjectCreationHandling.GetValueOrDefault(Serializer._objectCreationHandling);

            if ((objectCreationHandling != ObjectCreationHandling.Replace)
                && (tokenType == JsonToken.StartArray || tokenType == JsonToken.StartObject)
                && property.Readable)
            {
                currentValue = property.ValueProvider.GetValue(target);
                gottenCurrentValue = true;

                if (currentValue != null)
                {
                    propertyContract = GetContractSafe(currentValue.GetType());

                    useExistingValue = (!propertyContract.IsReadOnlyOrFixedSize && !propertyContract.UnderlyingType.IsValueType());
                }
            }

            if (!property.Writable && !useExistingValue)
                return true;

            // test tokentype here because null might not be convertable to some types, e.g. ignoring null when applied to DateTime
            if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore && tokenType == JsonToken.Null)
                return true;

            // test tokentype here because default value might not be convertable to actual type, e.g. default of "" for DateTime
            if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Ignore)
                && !HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate)
                && JsonReader.IsPrimitiveToken(tokenType)
                && MiscellaneousUtils.ValueEquals(reader.Value, property.GetResolvedDefaultValue()))
                return true;

            if (currentValue == null)
            {
                propertyContract = property.PropertyContract;
            }
            else
            {
                propertyContract = GetContractSafe(currentValue.GetType());

                if (propertyContract != property.PropertyContract)
                    propertyConverter = GetConverter(propertyContract, property.MemberConverter, containerContract, containerProperty);
            }

            return false;
        }
        private bool ShouldWriteProperty(object memberValue, JsonProperty property)
        {
            if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore &&
                memberValue == null)
                return false;

            if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Ignore)
                && MiscellaneousUtils.ValueEquals(memberValue, property.GetResolvedDefaultValue()))
                return false;

            return true;
        }
        private bool ShouldSetPropertyValue(JsonProperty property, object value)
        {
            if (property.NullValueHandling.GetValueOrDefault(Serializer._nullValueHandling) == NullValueHandling.Ignore && value == null)
                return false;

            if (HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Ignore)
                && !HasFlag(property.DefaultValueHandling.GetValueOrDefault(Serializer._defaultValueHandling), DefaultValueHandling.Populate)
                && MiscellaneousUtils.ValueEquals(value, property.GetResolvedDefaultValue()))
                return false;

            if (!property.Writable)
                return false;

            return true;
        }