private void SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
		{
			var 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, 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);
		}
		private object PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, string id)
		{
			var 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;
						try
						{
							try
							{
								object dt;
								// this is for correctly reading ISO and MS formatted dictionary keys
								if ((keyTypeCode == PrimitiveTypeCode.DateTime || keyTypeCode == PrimitiveTypeCode.DateTimeNullable) && DateTimeUtils.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTime, reader.DateTimeZoneHandling, out dt))
								{
									keyValue = dt;
								}
#if !NET20
								else if ((keyTypeCode == PrimitiveTypeCode.DateTimeOffset || keyTypeCode == PrimitiveTypeCode.DateTimeOffsetNullable) && DateTimeUtils.TryParseDateTime(keyValue.ToString(), DateParseHandling.DateTimeOffset, reader.DateTimeZoneHandling, out dt))
								{
									keyValue = dt;
								}
#endif
								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 void SerializeDictionary(JsonWriter writer, IDictionary values, JsonDictionaryContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
        {
            var    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, 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);
        }
		private IDictionary CreateNewDictionary(JsonReader reader, JsonDictionaryContract contract, out bool createdFromNonDefaultConstructor)
		{
			if (contract.IsReadOnlyOrFixedSize)
			{
				createdFromNonDefaultConstructor = 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);

				createdFromNonDefaultConstructor = false;
				return (IDictionary) dictionary;
			}
			else if (contract.ParametrizedConstructor != null)
			{
				createdFromNonDefaultConstructor = true;
				return contract.CreateTemporaryDictionary();
			}
			else
			{
				throw JsonSerializationException.Create(reader, "Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
			}
		}