/// <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 object CreateObjectFromNonDefaultConstructor(JsonObjectContract contract, JsonReader reader)
        {
            Type objectType = contract.UnderlyingType;

            // object should have a single constructor
            ConstructorInfo c = objectType.GetConstructors(BindingFlags.Public | BindingFlags.Instance).SingleOrDefault();

            if (c == null)
            {
                throw new JsonSerializationException("Could not find a public constructor for type {0}.".FormatWith(CultureInfo.InvariantCulture, objectType));
            }

            // create a dictionary to put retrieved values into
            IDictionary <JsonProperty, object> propertyValues = contract.Properties.Where(p => !p.Ignored).ToDictionary(kv => kv, kv => (object)null);

            bool exit = false;

            do
            {
                switch (reader.TokenType)
                {
                case JsonToken.PropertyName:
                    string memberName = reader.Value.ToString();
                    if (!reader.Read())
                    {
                        throw new JsonSerializationException("Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));
                    }

                    JsonProperty property;
                    // attempt exact case match first
                    // then try match ignoring case
                    if (contract.Properties.TryGetClosestMatchProperty(memberName, out property))
                    {
                        if (!property.Ignored)
                        {
                            Type memberType = ReflectionUtils.GetMemberUnderlyingType(property.Member);
                            propertyValues[property] = CreateValue(reader, memberType, null, property.MemberConverter);
                        }
                    }
                    else
                    {
                        if (_serializer.MissingMemberHandling == MissingMemberHandling.Error)
                        {
                            throw new JsonSerializationException("Could not find member '{0}' on object of type '{1}'".FormatWith(CultureInfo.InvariantCulture, memberName, objectType.Name));
                        }

                        reader.Skip();
                    }
                    break;

                case JsonToken.EndObject:
                    exit = true;
                    break;

                default:
                    throw new JsonSerializationException("Unexpected token when deserializing object: " + reader.TokenType);
                }
            } while (!exit && reader.Read());

            IDictionary <ParameterInfo, object> constructorParameters   = c.GetParameters().ToDictionary(p => p, p => (object)null);
            IDictionary <JsonProperty, object>  remainingPropertyValues = new Dictionary <JsonProperty, object>();

            foreach (KeyValuePair <JsonProperty, object> propertyValue in propertyValues)
            {
                ParameterInfo matchingConstructorParameter = constructorParameters.ForgivingCaseSensitiveFind(kv => kv.Key.Name, propertyValue.Key.PropertyName).Key;
                if (matchingConstructorParameter != null)
                {
                    constructorParameters[matchingConstructorParameter] = propertyValue.Value;
                }
                else
                {
                    remainingPropertyValues.Add(propertyValue);
                }
            }

            object createdObject = ReflectionUtils.CreateInstance(objectType, constructorParameters.Values.ToArray());

            contract.InvokeOnDeserializing(createdObject);

            // go through unused values and set the newly created object's properties
            foreach (KeyValuePair <JsonProperty, object> remainingPropertyValue in remainingPropertyValues)
            {
                if (ShouldSetPropertyValue(remainingPropertyValue.Key, remainingPropertyValue.Value))
                {
                    ReflectionUtils.SetMemberValue(remainingPropertyValue.Key.Member, createdObject, remainingPropertyValue.Value);
                }
            }

            contract.InvokeOnDeserialized(createdObject);
            return(createdObject);
        }