private object PopulateDictionary (IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, string id)
		{
			IWrappedDictionary wrappedDictionary = dictionary as IWrappedDictionary;
			object underlyingDictionary = wrappedDictionary != null ? wrappedDictionary.UnderlyingDictionary : dictionary;

			if (id != null)
				AddReference(reader, id, underlyingDictionary);

			OnDeserializing(reader, contract, underlyingDictionary);

			int initialDepth = reader.Depth;

			if (contract.KeyContract == null)
				contract.KeyContract = GetContractSafe(contract.DictionaryKeyType);

			if (contract.ItemContract == null)
				contract.ItemContract = GetContractSafe(contract.DictionaryValueType);

			JsonConverter dictionaryValueConverter = contract.ItemConverter ?? GetConverter(contract.ItemContract, null, contract, containerProperty);
			PrimitiveTypeCode keyTypeCode = (contract.KeyContract is JsonPrimitiveContract) ? ((JsonPrimitiveContract)contract.KeyContract).TypeCode : PrimitiveTypeCode.Empty;

			bool finished = false;
			do {
				switch (reader.TokenType) {
				case JsonToken.PropertyName:
					object keyValue = reader.Value;
					if (CheckPropertyName(reader, keyValue.ToString()))
						continue;

					try {
						try {
							DateParseHandling dateParseHandling;
							switch (keyTypeCode) {
							case PrimitiveTypeCode.DateTime:
							case PrimitiveTypeCode.DateTimeNullable:
								dateParseHandling = DateParseHandling.DateTime;
								break;
#if !NET20
							case PrimitiveTypeCode.DateTimeOffset:
							case PrimitiveTypeCode.DateTimeOffsetNullable:
								dateParseHandling = DateParseHandling.DateTimeOffset;
								break;
#endif
							default:
								dateParseHandling = DateParseHandling.None;
								break;
							}

							// this is for correctly reading ISO and MS formatted dictionary keys
							object dt;
							if (dateParseHandling != DateParseHandling.None && DateTimeUtils.TryParseDateTime(keyValue.ToString(), dateParseHandling, reader.DateTimeZoneHandling, reader.DateFormatString, reader.Culture, out dt))
								keyValue = dt;
							else
								keyValue = EnsureType(reader, keyValue, CultureInfo.InvariantCulture, contract.KeyContract, contract.DictionaryKeyType);
						}
						catch (Exception ex) {
							throw JsonSerializationException.Create(reader, "Could not convert string '{0}' to dictionary key type '{1}'. Create a TypeConverter to convert from the string to the key type object.".FormatWith(CultureInfo.InvariantCulture, reader.Value, contract.DictionaryKeyType), ex);
						}

						if (!ReadForType(reader, contract.ItemContract, dictionaryValueConverter != null))
							throw JsonSerializationException.Create(reader, "Unexpected end when deserializing object.");

						object itemValue;
						if (dictionaryValueConverter != null && dictionaryValueConverter.CanRead)
							itemValue = DeserializeConvertable(dictionaryValueConverter, reader, contract.DictionaryValueType, null);
						else
							itemValue = CreateValueInternal(reader, contract.DictionaryValueType, contract.ItemContract, null, contract, containerProperty, null);

						dictionary[keyValue] = itemValue;
					}
					catch (Exception ex) {
						if (IsErrorHandled(underlyingDictionary, contract, keyValue, reader as IJsonLineInfo, reader.Path, ex))
							HandleError(reader, true, initialDepth);
						else
							throw;
					}
					break;
				case JsonToken.Comment:
					break;
				case JsonToken.EndObject:
					finished = true;
					break;
				default:
					throw JsonSerializationException.Create(reader, "Unexpected token when deserializing object: " + reader.TokenType);
				}
			} while (!finished && reader.Read());

			if (!finished)
				ThrowUnexpectedEndException(reader, contract, underlyingDictionary, "Unexpected end when deserializing object.");

			OnDeserialized(reader, contract, underlyingDictionary);
			return underlyingDictionary;
		}
		private IDictionary CreateNewDictionary (JsonReader reader, JsonDictionaryContract contract, out bool createdFromNonDefaultCreator)
		{
			if (contract.IsReadOnlyOrFixedSize) {
				createdFromNonDefaultCreator = true;
				return contract.CreateTemporaryDictionary();
			}
			else if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor)) {
				object dictionary = contract.DefaultCreator();

				if (contract.ShouldCreateWrapper)
					dictionary = contract.CreateWrapper(dictionary);

				createdFromNonDefaultCreator = false;
				return (IDictionary)dictionary;
			}
			else if (contract.HasParametrizedCreator) {
				createdFromNonDefaultCreator = true;
				return contract.CreateTemporaryDictionary();
			}
			else {
				if (!contract.IsInstantiable)
					throw JsonSerializationException.Create(reader, "Could not create an instance of type {0}. Type is an interface or abstract class and cannot be instantiated.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));

				throw JsonSerializationException.Create(reader, "Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
			}
		}
        private void SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
        {
            IWrappedDictionary wrappedDictionary = values as IWrappedDictionary;
            object underlyingDictionary = wrappedDictionary != null ? wrappedDictionary.UnderlyingDictionary : values;

            OnSerializing(writer, contract, underlyingDictionary);
            _serializeStack.Add(underlyingDictionary);

            WriteObjectStart(writer, underlyingDictionary, contract, member, collectionContract, containerProperty);

            if (contract.ItemContract == null)
                contract.ItemContract = Serializer._contractResolver.ResolveContract(contract.DictionaryValueType ?? typeof(object));

            if (contract.KeyContract == null)
                contract.KeyContract = Serializer._contractResolver.ResolveContract(contract.DictionaryKeyType ?? typeof(object));

            int initialDepth = writer.Top;

            foreach (DictionaryEntry entry in values)
            {
                bool escape;
                string propertyName = GetPropertyName(writer, entry.Key, contract.KeyContract, out escape);

                propertyName = (contract.PropertyNameResolver != null)
                    ? contract.PropertyNameResolver(propertyName)
                    : propertyName;

                try
                {
                    object value = entry.Value;
                    JsonContract valueContract = contract.FinalItemContract ?? GetContractSafe(value);

                    if (ShouldWriteReference(value, null, valueContract, contract, member))
                    {
                        writer.WritePropertyName(propertyName, escape);
                        WriteReference(writer, value);
                    }
                    else
                    {
                        if (!CheckForCircularReference(writer, value, null, valueContract, contract, member))
                            continue;

                        writer.WritePropertyName(propertyName, escape);

                        SerializeValue(writer, value, valueContract, null, contract, member);
                    }
                }
                catch (Exception ex)
                {
                    if (IsErrorHandled(underlyingDictionary, contract, propertyName, null, writer.ContainerPath, ex))
                        HandleError(writer, initialDepth);
                    else
                        throw;
                }
            }

            writer.WriteEndObject();

            _serializeStack.RemoveAt(_serializeStack.Count - 1);

            OnSerialized(writer, contract, underlyingDictionary);
        }