private void SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContract collectionValueContract)
        {
            contract.InvokeOnSerializing(values.UnderlyingCollection, this.Serializer.Context);

            this._serializeStack.Add(values.UnderlyingCollection);

            bool isReference        = contract.IsReference ?? this.HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
            bool includeTypeDetails = this.ShouldWriteType(TypeNameHandling.Arrays, contract, member, collectionValueContract);

            if (isReference || includeTypeDetails)
            {
                writer.WriteStartObject();

                if (isReference)
                {
                    writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
                    writer.WriteValue(this.Serializer.ReferenceResolver.GetReference(this, values.UnderlyingCollection));
                }
                if (includeTypeDetails)
                {
                    this.WriteTypeProperty(writer, values.UnderlyingCollection.GetType());
                }
                writer.WritePropertyName(JsonTypeReflector.ArrayValuesPropertyName);
            }

            if (contract.CollectionItemContract == null)
            {
                contract.CollectionItemContract = this.Serializer.ContractResolver.ResolveContract(contract.CollectionItemType ?? typeof(object));
            }

            JsonContract collectionItemValueContract = (contract.CollectionItemContract.UnderlyingType.IsSealed) ? contract.CollectionItemContract : null;

            writer.WriteStartArray();

            int initialDepth = writer.Top;

            int index = 0;

            // note that an error in the IEnumerable won't be caught
            foreach (object value in values)
            {
                try
                {
                    JsonContract valueContract = collectionItemValueContract ?? this.GetContractSafe(value);

                    if (this.ShouldWriteReference(value, null, valueContract))
                    {
                        this.WriteReference(writer, value);
                    }
                    else
                    {
                        if (this.CheckForCircularReference(value, null, contract))
                        {
                            this.SerializeValue(writer, value, valueContract, null, contract.CollectionItemContract);
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (this.IsErrorHandled(values.UnderlyingCollection, contract, index, ex))
                    {
                        this.HandleError(writer, initialDepth);
                    }
                    else
                    {
                        throw;
                    }
                }
                finally
                {
                    index++;
                }
            }

            writer.WriteEndArray();

            if (isReference || includeTypeDetails)
            {
                writer.WriteEndObject();
            }

            this._serializeStack.RemoveAt(this._serializeStack.Count - 1);

            contract.InvokeOnSerialized(values.UnderlyingCollection, this.Serializer.Context);
        }
    private void SerializeList(JsonWriter writer, IWrappedCollection values, JsonArrayContract contract, JsonProperty member, JsonContract collectionValueContract)
    {
      contract.InvokeOnSerializing(values.UnderlyingCollection, Serializer.Context);

      _serializeStack.Add(values.UnderlyingCollection);

      bool isReference = contract.IsReference ?? HasFlag(Serializer.PreserveReferencesHandling, PreserveReferencesHandling.Arrays);
      bool includeTypeDetails = ShouldWriteType(TypeNameHandling.Arrays, contract, member, collectionValueContract);

      if (isReference || includeTypeDetails)
      {
        writer.WriteStartObject();

        if (isReference)
        {
          writer.WritePropertyName(JsonTypeReflector.IdPropertyName);
          writer.WriteValue(Serializer.ReferenceResolver.GetReference(this, values.UnderlyingCollection));
        }
        if (includeTypeDetails)
        {
          WriteTypeProperty(writer, values.UnderlyingCollection.GetType());
        }
        writer.WritePropertyName(JsonTypeReflector.ArrayValuesPropertyName);
      }

      if (contract.CollectionItemContract == null)
        contract.CollectionItemContract = Serializer.ContractResolver.ResolveContract(contract.CollectionItemType ?? typeof(object));

      JsonContract collectionItemValueContract = (contract.CollectionItemContract.UnderlyingType.IsSealed) ? contract.CollectionItemContract : null;

      writer.WriteStartArray();

      int initialDepth = writer.Top;

      int index = 0;
      // note that an error in the IEnumerable won't be caught
      foreach (object value in values)
      {
        try
        {
          JsonContract valueContract = collectionItemValueContract ?? GetContractSafe(value);

          if (ShouldWriteReference(value, null, valueContract))
          {
            WriteReference(writer, value);
          }
          else
          {
            if (CheckForCircularReference(value, null, contract))
            {
              SerializeValue(writer, value, valueContract, null, contract.CollectionItemContract);
            }
          }
        }
        catch (Exception ex)
        {
          if (IsErrorHandled(values.UnderlyingCollection, contract, index, ex))
            HandleError(writer, initialDepth);
          else
            throw;
        }
        finally
        {
          index++;
        }
      }

      writer.WriteEndArray();

      if (isReference || includeTypeDetails)
      {
        writer.WriteEndObject();
      }

      _serializeStack.RemoveAt(_serializeStack.Count - 1);

      contract.InvokeOnSerialized(values.UnderlyingCollection, Serializer.Context);
    }