private void SerializeDynamic(JsonWriter writer, IDynamicMetaObjectProvider value, JsonDynamicContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)
		{
			OnSerializing(writer, contract, value);
			_serializeStack.Add(value);

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

			int initialDepth = writer.Top;

			for (int index = 0; index < contract.Properties.Count; index++)
			{
				JsonProperty property = contract.Properties[index];

				// only write non-dynamic properties that have an explicit attribute
				if (property.HasMemberAttribute)
				{
					try
					{
						object memberValue;
						JsonContract memberContract;

						if (!CalculatePropertyValues(writer, value, contract, member, property, out memberContract, out memberValue))
							continue;

						property.WritePropertyName(writer);
						SerializeValue(writer, memberValue, memberContract, property, contract, member);
					}
					catch (Exception ex)
					{
						if (IsErrorHandled(value, contract, property.PropertyName, null, writer.ContainerPath, ex))
							HandleError(writer, initialDepth);
						else
							throw;
					}
				}
			}

			foreach (var memberName in value.GetDynamicMemberNames())
			{
				object memberValue;
				if (contract.TryGetMember(value, memberName, out memberValue))
				{
					try
					{
						JsonContract valueContract = GetContractSafe(memberValue);

						if (!ShouldWriteDynamicProperty(memberValue))
							continue;

						if (CheckForCircularReference(writer, memberValue, null, valueContract, contract, member))
						{
							string resolvedPropertyName = (contract.PropertyNameResolver != null) ? contract.PropertyNameResolver(memberName) : memberName;

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

			writer.WriteEndObject();

			_serializeStack.RemoveAt(_serializeStack.Count - 1);
			OnSerialized(writer, contract, value);
		}
		private object CreateDynamic(JsonReader reader, JsonDynamicContract contract, JsonProperty member, string id)
		{
			IDynamicMetaObjectProvider newObject;

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

			if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
				newObject = (IDynamicMetaObjectProvider) contract.DefaultCreator();
			else
				throw JsonSerializationException.Create(reader, "Unable to find a default constructor to use for type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));

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

			OnDeserializing(reader, contract, newObject);

			int initialDepth = reader.Depth;

			bool finished = false;
			do
			{
				switch (reader.TokenType)
				{
					case JsonToken.PropertyName:
						string memberName = reader.Value.ToString();

						try
						{
							if (!reader.Read())
								throw JsonSerializationException.Create(reader, "Unexpected end when setting {0}'s value.".FormatWith(CultureInfo.InvariantCulture, memberName));

							// first attempt to find a settable property, otherwise fall back to a dynamic set without type
							JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);

							if (property != null && property.Writable && !property.Ignored)
							{
								if (property.PropertyContract == null)
									property.PropertyContract = GetContractSafe(property.PropertyType);

								JsonConverter propertyConverter = GetConverter(property.PropertyContract, property.MemberConverter, null, null);

								if (!SetPropertyValue(property, propertyConverter, null, member, reader, newObject))
									reader.Skip();
							}
							else
							{
								Type t = (JsonReader.IsPrimitiveToken(reader.TokenType)) ? reader.ValueType : typeof (IDynamicMetaObjectProvider);

								JsonContract dynamicMemberContract = GetContractSafe(t);
								JsonConverter dynamicMemberConverter = GetConverter(dynamicMemberContract, null, null, member);

								object value;
								if (dynamicMemberConverter != null && dynamicMemberConverter.CanRead)
									value = DeserializeConvertable(dynamicMemberConverter, reader, t, null);
								else
									value = CreateValueInternal(reader, t, dynamicMemberContract, null, null, member, null);

								contract.TrySetMember(newObject, memberName, value);
							}
						}
						catch (Exception ex)
						{
							if (IsErrorHandled(newObject, contract, memberName, reader as IJsonLineInfo, reader.Path, ex))
								HandleError(reader, true, initialDepth);
							else
								throw;
						}
						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, newObject, "Unexpected end when deserializing object.");

			OnDeserialized(reader, contract, newObject);

			return newObject;
		}