private void SerializeValue(JsonWriter writer, object value, JsonContract valueContract, JsonProperty member, JsonContract collectionValueContract)
        {
            JsonConverter converter = (member != null) ? member.Converter : null;

            if (value == null)
            {
                writer.WriteNull();
                return;
            }

            if ((converter != null ||
                 ((converter = valueContract.Converter) != null) ||
                 ((converter = Serializer.GetMatchingConverter(valueContract.UnderlyingType)) != null) ||
                 ((converter = valueContract.InternalConverter) != null)) &&
                converter.CanWrite)
            {
                SerializeConvertable(writer, converter, value, valueContract);
            }
            else if (valueContract is JsonPrimitiveContract)
            {
                SerializePrimitive(writer, value, (JsonPrimitiveContract)valueContract, member, collectionValueContract);
            }
            else if (valueContract is JsonStringContract)
            {
                SerializeString(writer, value, (JsonStringContract)valueContract);
            }
            else if (valueContract is JsonObjectContract)
            {
                SerializeObject(writer, value, (JsonObjectContract)valueContract, member, collectionValueContract);
            }
            else if (valueContract is JsonDictionaryContract)
            {
                JsonDictionaryContract dictionaryContract = (JsonDictionaryContract)valueContract;
                SerializeDictionary(writer, dictionaryContract.CreateWrapper(value), dictionaryContract, member, collectionValueContract);
            }
            else if (valueContract is JsonArrayContract)
            {
                JsonArrayContract arrayContract = (JsonArrayContract)valueContract;
                if (!arrayContract.IsMultidimensionalArray)
                {
                    SerializeList(writer, arrayContract.CreateWrapper(value), arrayContract, member, collectionValueContract);
                }
                else
                {
                    SerializeMultidimensionalArray(writer, (Array)value, arrayContract, member, collectionValueContract);
                }
            }
            else if (valueContract is JsonLinqContract)
            {
                ((JToken)value).WriteTo(writer, (Serializer.Converters != null) ? Serializer.Converters.ToArray() : null);
            }
#if !((UNITY_WINRT && !UNITY_EDITOR) || (UNITY_WP8 || UNITY_WP_8_1))
            else if (valueContract is JsonISerializableContract)
            {
                SerializeISerializable(writer, (ISerializable)value, (JsonISerializableContract)valueContract);
            }
#endif
        }
		private object CreateAndPopulateList(JsonReader reader, string reference, JsonArrayContract contract)
		{
			return CollectionUtils.CreateAndPopulateList(contract.CreatedType, (l, isTemporaryListReference) =>
			{
				if (reference != null && isTemporaryListReference)
					throw new JsonSerializationException("Cannot preserve reference to array or readonly list: {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
				if (contract.OnSerializing != null && isTemporaryListReference)
					throw new JsonSerializationException("Cannot call OnSerializing on an array or readonly list: {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));
				if (contract.OnError != null && isTemporaryListReference)
					throw new JsonSerializationException("Cannot call OnError on an array or readonly list: {0}".FormatWith(CultureInfo.InvariantCulture, contract.UnderlyingType));

				if (!contract.IsMultidimensionalArray)
					PopulateList(contract.CreateWrapper(l), reader, reference, contract);
				else
					PopulateMultidimensionalArray(l, reader, reference, contract);
			});
		}
    private IList CreateNewList(JsonReader reader, JsonArrayContract contract, out bool createdFromNonDefaultConstructor)
    {
      // some types like non-generic IEnumerable can be serialized but not deserialized
      if (!contract.CanDeserialize)
        throw JsonSerializationException.Create(reader, "Cannot create and populate list type {0}.".FormatWith(CultureInfo.InvariantCulture, contract.CreatedType));

      if (contract.IsReadOnlyOrFixedSize)
      {
        createdFromNonDefaultConstructor = true;
        IList list = contract.CreateTemporaryCollection();

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

        return list;
      }
      else if (contract.DefaultCreator != null && (!contract.DefaultCreatorNonPublic || Serializer._constructorHandling == ConstructorHandling.AllowNonPublicDefaultConstructor))
      {
        object list = contract.DefaultCreator();

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

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