private JsonContract CreateContract(Type objectType)
        {
            if (JsonTypeReflector.GetJsonObjectAttribute(objectType) != null)
            {
                return(CreateObjectContract(objectType));
            }
            if (CollectionUtils.IsDictionaryType(objectType))
            {
                return(CreateDictionaryContract(objectType));
            }
            if (typeof(IEnumerable).IsAssignableFrom(objectType))
            {
                return(CreateArrayContract(objectType));
            }

            return(CreateObjectContract(objectType));
        }
        /// <summary>
        /// Creates a <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.
        /// </summary>
        /// <param name="contract">The member's declaring types <see cref="JsonObjectContract"/>.</param>
        /// <param name="member">The member to create a <see cref="JsonProperty"/> for.</param>
        /// <returns>A created <see cref="JsonProperty"/> for the given <see cref="MemberInfo"/>.</returns>
        protected virtual JsonProperty CreateProperty(JsonObjectContract contract, MemberInfo member)
        {
            JsonProperty property = new JsonProperty();

            property.Member = member;

#if !PocketPC
            DataContractAttribute dataContractAttribute = JsonTypeReflector.GetDataContractAttribute(member.DeclaringType);

            DataMemberAttribute dataMemberAttribute;
            if (dataContractAttribute != null)
            {
                dataMemberAttribute = JsonTypeReflector.GetAttribute <DataMemberAttribute>(member);
            }
            else
            {
                dataMemberAttribute = null;
            }
#endif

            JsonPropertyAttribute propertyAttribute = JsonTypeReflector.GetAttribute <JsonPropertyAttribute>(member);
            bool hasIgnoreAttribute = (JsonTypeReflector.GetAttribute <JsonIgnoreAttribute>(member) != null);

            string mappedName;
            if (propertyAttribute != null && propertyAttribute.PropertyName != null)
            {
                mappedName = propertyAttribute.PropertyName;
            }
#if !PocketPC
            else if (dataMemberAttribute != null && dataMemberAttribute.Name != null)
            {
                mappedName = dataMemberAttribute.Name;
            }
#endif
            else
            {
                mappedName = member.Name;
            }

            property.PropertyName = ResolvePropertyName(mappedName);

            if (propertyAttribute != null)
            {
                property.Required = propertyAttribute.IsRequired;
            }
#if !PocketPC
            else if (dataMemberAttribute != null)
            {
                property.Required = dataMemberAttribute.IsRequired;
            }
#endif
            else
            {
                property.Required = false;
            }

            property.Ignored = (hasIgnoreAttribute ||
                                (contract.MemberSerialization == MemberSerialization.OptIn &&
                                 propertyAttribute == null
#if !PocketPC
                                 && dataMemberAttribute == null
#endif
                                ));

            property.Readable = ReflectionUtils.CanReadMemberValue(member);
            property.Writable = ReflectionUtils.CanSetMemberValue(member);

            property.MemberConverter = JsonTypeReflector.GetConverter(member, ReflectionUtils.GetMemberUnderlyingType(member));

            DefaultValueAttribute defaultValueAttribute = JsonTypeReflector.GetAttribute <DefaultValueAttribute>(member);
            property.DefaultValue = (defaultValueAttribute != null) ? defaultValueAttribute.Value : null;

            property.NullValueHandling     = (propertyAttribute != null) ? propertyAttribute._nullValueHandling : null;
            property.DefaultValueHandling  = (propertyAttribute != null) ? propertyAttribute._defaultValueHandling : null;
            property.ReferenceLoopHandling = (propertyAttribute != null) ? propertyAttribute._referenceLoopHandling : null;
            property.IsReference           = (propertyAttribute != null) ? propertyAttribute._isReference : null;

            return(property);
        }
        private void SetPropertyValue(JsonProperty property, JsonReader reader, object target)
        {
            if (property.Ignored)
            {
                reader.Skip();
                return;
            }

            // get the member's underlying type
            Type memberType = ReflectionUtils.GetMemberUnderlyingType(property.Member);

            object currentValue     = null;
            bool   useExistingValue = false;

            if ((_serializer.ObjectCreationHandling == ObjectCreationHandling.Auto || _serializer.ObjectCreationHandling == ObjectCreationHandling.Reuse) &&
                (reader.TokenType == JsonToken.StartArray || reader.TokenType == JsonToken.StartObject))
            {
                currentValue = ReflectionUtils.GetMemberValue(property.Member, target);

                useExistingValue = (currentValue != null && !memberType.IsArray && !ReflectionUtils.InheritsGenericDefinition(memberType, typeof(ReadOnlyCollection <>)));
            }

            if (!property.Writable && !useExistingValue)
            {
                reader.Skip();
                return;
            }

            object value = CreateValue(reader, memberType, (useExistingValue) ? currentValue : null, JsonTypeReflector.GetConverter(property.Member, memberType));

            if (!useExistingValue && ShouldSetPropertyValue(property, value))
            {
                ReflectionUtils.SetMemberValue(property.Member, target, value);
            }
        }