context: #region License
  // Copyright (c) 2007 James Newton-King
  //
  // Permission is hereby granted, free of charge, to any person
  // obtaining a copy of this software and associated documentation
  // files (the "Software"), to deal in the Software without
  // restriction, including without limitation the rights to use,
  // copy, modify, merge, publish, distribute, sublicense, and/or sell
  // copies of the Software, and to permit persons to whom the
  // Software is furnished to do so, subject to the following
  // conditions:
  //
  // The above copyright notice and this permission notice shall be
  // included in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  // OTHER DEALINGS IN THE SOFTWARE.
  #endregion
  
  using System;
  using System.Collections.Generic;
  using System.IO;
  using Newtonsoft.Json.Converters;
  using Newtonsoft.Json.Serialization;
  using Newtonsoft.Json.Utilities;
  using System.Runtime.Serialization;
  using ErrorEventArgs=Newtonsoft.Json.Serialization.ErrorEventArgs;
  
  namespace Newtonsoft.Json
  {
    /// <summary>
    /// Serializes and deserializes objects into and from the JSON format.
    /// The <see cref="JsonSerializer"/> enables you to control how objects are encoded into JSON.
    /// </summary>
    public class JsonSerializer
    {
      #region Properties
      private TypeNameHandling _typeNameHandling;
      private PreserveReferencesHandling _preserveReferencesHandling;
      private ReferenceLoopHandling _referenceLoopHandling;
      private MissingMemberHandling _missingMemberHandling;
      private ObjectCreationHandling _objectCreationHandling;
      private NullValueHandling _nullValueHandling;
      private DefaultValueHandling _defaultValueHandling;
      private ConstructorHandling _constructorHandling;
      private JsonConverterCollection _converters;
      private IContractResolver _contractResolver;
      private IReferenceResolver _referenceResolver;
      private SerializationBinder _binder;
      private StreamingContext _context;
  
      /// <summary>
      /// Occurs when the <see cref="JsonSerializer"/> errors during serialization and deserialization.
      /// </summary>
      public virtual event EventHandler<ErrorEventArgs> Error;
  
      /// <summary>
      /// Gets or sets the <see cref="IReferenceResolver"/> used by the serializer when resolving references.
      /// </summary>
      public virtual IReferenceResolver ReferenceResolver
      {
        get
        {
          if (_referenceResolver == null)
            _referenceResolver = new DefaultReferenceResolver();
  
          return _referenceResolver;
        }
        set
        {
          if (value == null)
            throw new ArgumentNullException("value", "Reference resolver cannot be null.");
  
          _referenceResolver = value;
        }
      }
  
      /// <summary>
      /// Gets or sets the <see cref="SerializationBinder"/> used by the serializer when resolving type names.
      /// </summary>
      public virtual SerializationBinder Binder
      {
        get
        {
          return _binder;
        }
        set
        {
          if (value == null)
            throw new ArgumentNullException("value", "Serialization binder cannot be null.");
  
          _binder = value;
        }
      }
  
      /// <summary>
      /// Gets or sets how type name writing and reading is handled by the serializer.
      /// </summary>
      public virtual TypeNameHandling TypeNameHandling
      {
        get { return _typeNameHandling; }
        set
        {
          if (value < TypeNameHandling.None || value > TypeNameHandling.All)
            throw new ArgumentOutOfRangeException("value");
  
          _typeNameHandling = value;
        }
      }
  
      /// <summary>
      /// Gets or sets how object references are preserved by the serializer.
      /// </summary>
      public virtual PreserveReferencesHandling PreserveReferencesHandling
      {
        get { return _preserveReferencesHandling; }
        set
        {
          if (value < PreserveReferencesHandling.None || value > PreserveReferencesHandling.All)
            throw new ArgumentOutOfRangeException("value");
  
          _preserveReferencesHandling = value;
        }
      }
  
      /// <summary>
      /// Get or set how reference loops (e.g. a class referencing itself) is handled.
      /// </summary>
      public virtual ReferenceLoopHandling ReferenceLoopHandling
      {
        get { return _referenceLoopHandling; }
        set
        {
          if (value < ReferenceLoopHandling.Error || value > ReferenceLoopHandling.Serialize)
            throw new ArgumentOutOfRangeException("value");
  
          _referenceLoopHandling = value;
        }
      }
  
      /// <summary>
      /// Get or set how missing members (e.g. JSON contains a property that isn't a member on the object) are handled during deserialization.
      /// </summary>
      public virtual MissingMemberHandling MissingMemberHandling
      {
        get { return _missingMemberHandling; }
        set
        {
          if (value < MissingMemberHandling.Ignore || value > MissingMemberHandling.Error)
            throw new ArgumentOutOfRangeException("value");
  
          _missingMemberHandling = value;
        }
      }
  
      /// <summary>
      /// Get or set how null values are handled during serialization and deserialization.
      /// </summary>
      public virtual NullValueHandling NullValueHandling
      {
        get { return _nullValueHandling; }
        set
        {
          if (value < NullValueHandling.Include || value > NullValueHandling.Ignore)
            throw new ArgumentOutOfRangeException("value");
  
          _nullValueHandling = value;
        }
      }
  
      /// <summary>
      /// Get or set how null default are handled during serialization and deserialization.
      /// </summary>
      public virtual DefaultValueHandling DefaultValueHandling
      {
        get { return _defaultValueHandling; }
        set
        {
          if (value < DefaultValueHandling.Include || value > DefaultValueHandling.Ignore)
            throw new ArgumentOutOfRangeException("value");
  
          _defaultValueHandling = value;
        }
      }
  
      /// <summary>
      /// Gets or sets how objects are created during deserialization.
      /// </summary>
      /// <value>The object creation handling.</value>
      public virtual ObjectCreationHandling ObjectCreationHandling
      {
        get { return _objectCreationHandling; }
        set
        {
          if (value < ObjectCreationHandling.Auto || value > ObjectCreationHandling.Replace)
  
gt:           throw new ArgumentOutOfRangeException("value");