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 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;
		}
        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;
        }