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.IO;
  using System.Globalization;
  #if !(NET20 || NET35 || SILVERLIGHT || PORTABLE)
  using System.Threading.Tasks;
  #endif
  using Raven.Imports.Newtonsoft.Json.Utilities;
  using System.Xml;
  using Raven.Imports.Newtonsoft.Json.Converters;
  using System.Text;
  #if !NET20 && (!SILVERLIGHT || WINDOWS_PHONE) && !PORTABLE
  using System.Xml.Linq;
  #endif
  #if NETFX_CORE
  using IConvertible = Raven.Imports.Newtonsoft.Json.Utilities.Convertible;
  #endif
  
  namespace Raven.Imports.Newtonsoft.Json
  {
    /// <summary>
    /// Provides methods for converting between common language runtime types and JSON types.
    /// </summary>
    /// <example>
    ///   <code lang="cs" source="..\Src\Newtonsoft.Json.Tests\Documentation\SerializationTests.cs" region="SerializeObject" title="Serializing and Deserializing JSON with JsonConvert" />
    /// </example>
    public static class JsonConvert
    {
      /// <summary>
      /// Represents JavaScript's boolean value true as a string. This field is read-only.
      /// </summary>
      public static readonly string True = "true";
  
      /// <summary>
      /// Represents JavaScript's boolean value false as a string. This field is read-only.
      /// </summary>
      public static readonly string False = "false";
  
      /// <summary>
      /// Represents JavaScript's null as a string. This field is read-only.
      /// </summary>
      public static readonly string Null = "null";
  
      /// <summary>
      /// Represents JavaScript's undefined as a string. This field is read-only.
      /// </summary>
      public static readonly string Undefined = "undefined";
  
      /// <summary>
      /// Represents JavaScript's positive infinity as a string. This field is read-only.
      /// </summary>
      public static readonly string PositiveInfinity = "Infinity";
  
      /// <summary>
      /// Represents JavaScript's negative infinity as a string. This field is read-only.
      /// </summary>
      public static readonly string NegativeInfinity = "-Infinity";
  
      /// <summary>
      /// Represents JavaScript's NaN as a string. This field is read-only.
      /// </summary>
      public static readonly string NaN = "NaN";
  
      internal static readonly long InitialJavaScriptDateTicks = 621355968000000000;
  
      /// <summary>
      /// Converts the <see cref="DateTime"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="DateTime"/>.</returns>
      public static string ToString(DateTime value)
      {
        return ToString(value, DateFormatHandling.IsoDateFormat, DateTimeZoneHandling.RoundtripKind);
      }
  
      /// <summary>
      /// Converts the <see cref="DateTime"/> to its JSON string representation using the <see cref="DateFormatHandling"/> specified.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <param name="format">The format the date will be converted to.</param>
      /// <param name="timeZoneHandling">The time zone handling when the date is converted to a string.</param>
      /// <returns>A JSON string representation of the <see cref="DateTime"/>.</returns>
      public static string ToString(DateTime value, DateFormatHandling format, DateTimeZoneHandling timeZoneHandling)
      {
        DateTime updatedDateTime = EnsureDateTime(value, timeZoneHandling);
  
        using (StringWriter writer = StringUtils.CreateStringWriter(64))
        {
          WriteDateTimeString(writer, updatedDateTime, updatedDateTime.GetUtcOffset(), updatedDateTime.Kind, format, '"');
          return writer.ToString();
        }
      }
  
      internal static DateTime EnsureDateTime(DateTime value, DateTimeZoneHandling timeZone)
      {
        switch (timeZone)
        {
          case DateTimeZoneHandling.Local:
            value = SwitchToLocalTime(value);
            break;
          case DateTimeZoneHandling.Utc:
            value = SwitchToUtcTime(value);
            break;
          case DateTimeZoneHandling.Unspecified:
            value = new DateTime(value.Ticks, DateTimeKind.Unspecified);
            break;
          case DateTimeZoneHandling.RoundtripKind:
            break;
          default:
            throw new ArgumentException("Invalid date time handling value.");
        }
  
        return value;
      }
  
  #if !PocketPC && !NET20
      /// <summary>
      /// Converts the <see cref="DateTimeOffset"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="DateTimeOffset"/>.</returns>
      public static string ToString(DateTimeOffset value)
      {
        return ToString(value, DateFormatHandling.IsoDateFormat);
      }
  
      /// <summary>
      /// Converts the <see cref="DateTimeOffset"/> to its JSON string representation using the <see cref="DateFormatHandling"/> specified.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <param name="format">The format the date will be converted to.</param>
      /// <returns>A JSON string representation of the <see cref="DateTimeOffset"/>.</returns>
      public static string ToString(DateTimeOffset value, DateFormatHandling format)
      {
        return ToString(value, format, '"');
      }
  
      internal static string ToString(DateTimeOffset value, DateFormatHandling format, char quoteChar)
      {
        using (StringWriter writer = StringUtils.CreateStringWriter(64))
        {
          WriteDateTimeString(writer, (format == DateFormatHandling.IsoDateFormat) ? value.DateTime : value.UtcDateTime, value.Offset, DateTimeKind.Local, format, quoteChar);
          return writer.ToString();
        }
      }
  #endif
  
      internal static void WriteDateTimeString(TextWriter writer, DateTime value, DateFormatHandling format, char quoteChar)
      {
        WriteDateTimeString(writer, value, value.GetUtcOffset(), value.Kind, format, quoteChar);
      }
  
      internal static void WriteDateTimeString(TextWriter writer, DateTime value, TimeSpan offset, DateTimeKind kind, DateFormatHandling format, char quoteChar)
      {
        if (format == DateFormatHandling.MicrosoftDateFormat)
        {
          long javaScriptTicks = ConvertDateTimeToJavaScriptTicks(value, offset);
  
          writer.Write(quoteChar);
          writer.Write(@"\/Date(");
          writer.Write(javaScriptTicks);
  
          switch (kind)
          {
            case DateTimeKind.Unspecified:
              if (value != DateTime.MaxValue && value != DateTime.MinValue)
                WriteDateTimeOffset(writer, offset, format);
              break;
            case DateTimeKind.Local:
              WriteDateTimeOffset(writer, offset, format);
              break;
          }
  
          writer.Write(@")\/");
          writer.Write(quoteChar);
        }
        else
        {
          writer.Write(quoteChar);
          writer.Write(value.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss.FFFFFFF", CultureInfo.InvariantCulture));
  
          switch (kind)
          {
            case DateTimeKind.Local:
              WriteDateTimeOffset(writer, offset, format);
              break;
            case DateTimeKind.Utc:
              writer.Write("Z");
              break;
          }
  
  
          writer.Write(quoteChar);
        }
      }
  
      internal static void WriteDateTimeOffset(TextWriter writer, TimeSpan offset, DateFormatHandling format)
      {
        writer.Write((offset.Ticks >= 0L) ? "+" : "-");
  
        int absHours = Math.Abs(offset.Hours);
        if (absHours < 10)
          writer.Write(0);
        writer.Write(absHours);
  
        if (format == DateFormatHandling.IsoDateFormat)
          writer.Write(':');
  
        int absMinutes = Math.Abs(offset.Minutes);
        if (absMinutes < 10)
          writer.Write(0);
        writer.Write(absMinutes);
      }
  
      private static long ToUniversalTicks(DateTime dateTime)
      {
        if (dateTime.Kind == DateTimeKind.Utc)
          return dateTime.Ticks;
  
        return ToUniversalTicks(dateTime, dateTime.GetUtcOffset());
      }
  
      private static long ToUniversalTicks(DateTime dateTime, TimeSpan offset)
      {
        // special case min and max value
        // they never have a timezone appended to avoid issues
        if (dateTime.Kind == DateTimeKind.Utc || dateTime == DateTime.MaxValue || dateTime == DateTime.MinValue)
          return dateTime.Ticks;
  
        long ticks = dateTime.Ticks - offset.Ticks;
        if (ticks > 3155378975999999999L)
          return 3155378975999999999L;
  
        if (ticks < 0L)
          return 0L;
  
        return ticks;
      }
  
      internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, TimeSpan offset)
      {
        long universialTicks = ToUniversalTicks(dateTime, offset);
  
        return UniversialTicksToJavaScriptTicks(universialTicks);
      }
  
      internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime)
      {
        return ConvertDateTimeToJavaScriptTicks(dateTime, true);
      }
  
      internal static long ConvertDateTimeToJavaScriptTicks(DateTime dateTime, bool convertToUtc)
      {
        long ticks = (convertToUtc) ? ToUniversalTicks(dateTime) : dateTime.Ticks;
  
        return UniversialTicksToJavaScriptTicks(ticks);
      }
  
      private static long UniversialTicksToJavaScriptTicks(long universialTicks)
      {
        long javaScriptTicks = (universialTicks - InitialJavaScriptDateTicks)/10000;
  
        return javaScriptTicks;
      }
  
      internal static DateTime ConvertJavaScriptTicksToDateTime(long javaScriptTicks)
      {
        DateTime dateTime = new DateTime((javaScriptTicks*10000) + InitialJavaScriptDateTicks, DateTimeKind.Utc);
  
        return dateTime;
      }
  
      private static DateTime SwitchToLocalTime(DateTime value)
      {
        switch (value.Kind)
        {
          case DateTimeKind.Unspecified:
            return new DateTime(value.Ticks, DateTimeKind.Local);
  
          case DateTimeKind.Utc:
            return value.ToLocalTime();
  
          case DateTimeKind.Local:
            return value;
        }
        return value;
      }
  
      private static DateTime SwitchToUtcTime(DateTime value)
      {
        switch (value.Kind)
        {
          case DateTimeKind.Unspecified:
            return new DateTime(value.Ticks, DateTimeKind.Utc);
  
          case DateTimeKind.Utc:
            return value;
  
          case DateTimeKind.Local:
            return value.ToUniversalTime();
        }
        return value;
      }
  
      /// <summary>
      /// Converts the <see cref="Boolean"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="Boolean"/>.</returns>
      public static string ToString(bool value)
      {
        return (value) ? True : False;
      }
  
      /// <summary>
      /// Converts the <see cref="Char"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="Char"/>.</returns>
      public static string ToString(char value)
      {
        return ToString(char.ToString(value));
      }
  
      /// <summary>
      /// Converts the <see cref="Enum"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="Enum"/>.</returns>
      public static string ToString(Enum value)
      {
        return value.ToString("D");
      }
  
      /// <summary>
      /// Converts the <see cref="Int32"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="Int32"/>.</returns>
      public static string ToString(int value)
      {
        return value.ToString(null, CultureInfo.InvariantCulture);
      }
  
      /// <summary>
      /// Converts the <see cref="Int16"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="Int16"/>.</returns>
      public static string ToString(short value)
      {
        return value.ToString(null, CultureInfo.InvariantCulture);
      }
  
      /// <summary>
      /// Converts the <see cref="UInt16"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="UInt16"/>.</returns>
      public static string ToString(ushort value)
      {
        return value.ToString(null, CultureInfo.InvariantCulture);
      }
  
      /// <summary>
      /// Converts the <see cref="UInt32"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="UInt32"/>.</returns>
      public static string ToString(uint value)
      {
        return value.ToString(null, CultureInfo.InvariantCulture);
      }
  
      /// <summary>
      /// Converts the <see cref="Int64"/>  to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="Int64"/>.</returns>
      public static string ToString(long value)
      {
        return value.ToString(null, CultureInfo.InvariantCulture);
      }
  
      /// <summary>
      /// Converts the <see cref="UInt64"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="UInt64"/>.</returns>
      public static string ToString(ulong value)
      {
        return value.ToString(null, CultureInfo.InvariantCulture);
      }
  
      /// <summary>
      /// Converts the <see cref="Single"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="Single"/>.</returns>
      public static string ToString(float value)
      {
        return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
      }
  
      /// <summary>
      /// Converts the <see cref="Double"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="Double"/>.</returns>
      public static string ToString(double value)
      {
        return EnsureDecimalPlace(value, value.ToString("R", CultureInfo.InvariantCulture));
      }
  
      private static string EnsureDecimalPlace(double value, string text)
      {
        if (double.IsNaN(value) || double.IsInfinity(value) || text.IndexOf('.') != -1 || text.IndexOf('E') != -1 || text.IndexOf('e') != -1)
          return text;
  
        return text + ".0";
      }
  
      private static string EnsureDecimalPlace(string text)
      {
        if (text.IndexOf('.') != -1)
          return text;
  
        return text + ".0";
      }
  
      /// <summary>
      /// Converts the <see cref="Byte"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="Byte"/>.</returns>
      public static string ToString(byte value)
      {
        return value.ToString(null, CultureInfo.InvariantCulture);
      }
  
      /// <summary>
      /// Converts the <see cref="SByte"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="SByte"/>.</returns>
      public static string ToString(sbyte value)
      {
        return value.ToString(null, CultureInfo.InvariantCulture);
      }
  
      /// <summary>
      /// Converts the <see cref="Decimal"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="SByte"/>.</returns>
      public static string ToString(decimal value)
      {
        return EnsureDecimalPlace(value.ToString(null, CultureInfo.InvariantCulture));
      }
  
      /// <summary>
      /// Converts the <see cref="Guid"/> to its JSON string representation.
      /// </summary>
      /// <param name="value">The value to convert.</param>
      /// <returns>A JSON string representation of the <see cref="Guid"/>.</returns>
      public static string ToString(Guid value)
      {
        return ToString(value, '"');
      }
  
      internal static string ToString(Guid value, char quoteChar)
      {
        string text = null;
  
  #if !(NETFX_CORE || PORTABLE)
        text = value.ToString("D", CultureInfo.InvariantCulture);
  #else
        text = value.ToString("D");
  #endif
  
  
gt:       return quoteChar + text + quoteChar;