static bool DeserializeTimeSpan(JsonDeserializer deserializer, JsonTokenizer tokenizer, out object value)
        {
            if (tokenizer.HasSpecialChar)
            {
                tokenizer.SkipValueBody();
            }
            else if (tokenizer.TokenIsString)
            {
                TimeSpan t;
                if (TryParseTime(tokenizer.Token, out t))
                {
                    value = t;
                    return(true);
                }
            }
            else
            {
                double v;
                if (JsonConvert.TryParse(tokenizer.Token, out v))
                {
                    value = TimeSpan.FromSeconds(v);
                    return(true);
                }
            }

            value = null;
            return(false);
        }
        static bool DeserializeBoolean(JsonDeserializer deserializer, JsonTokenizer tokenizer, out object value)
        {
            if (tokenizer.HasSpecialChar)
            {
                tokenizer.SkipValueBody();
            }
            else
            {
                string t = tokenizer.Token;
                if (t == "false")
                {
                    value = false; return(true);
                }
                if (t == "true")
                {
                    value = true; return(true);
                }

                double v;
                if (JsonConvert.TryParse(t, out v))
                {
                    value = Math.Abs(v) >= 1 - 1e-7;
                    return(true);
                }
            }

            value = null;
            return(false);
        }
        static bool DeserializeDateTime(JsonDeserializer deserializer, JsonTokenizer tokenizer, out object value)
        {
            if (tokenizer.HasSpecialChar)
            {
                tokenizer.SkipValueBody();
            }
            else if (tokenizer.TokenIsString)
            {
                DateTime d;
                if (DateTime.TryParse(tokenizer.Token, CultureInfo.InvariantCulture, DateTimeStyles.None, out d))
                {
                    value = d;
                    return(true);
                }
            }
            else
            {
                double v;
                if (JsonConvert.TryParse(tokenizer.Token, out v))
                {
                    value = ConvertUnixDateTime(v);
                    return(true);
                }
            }

            value = null;
            return(false);
        }
        void DeserializeObject(JsonTokenizer tokenizer, object instance, JsonTypeCacheEntry cache)
        {
            bool isNameExpected = false;

            while (true)
            {
                if (isNameExpected)
                {
                    tokenizer.ReadString();
                }
                else
                {
                    tokenizer.ReadNext();
                    if (tokenizer.SpecialChar == '}')
                    {
                        return;
                    }

                    if (!tokenizer.TokenIsString)
                    {
                        throw new JsonException("String expected");
                    }

                    isNameExpected = true;
                }

                string n = tokenizer.Token;

                tokenizer.ReadColon();

                JsonTypeMemberEntry me;
                if (cache.Members != null && cache.Members.TryGetValue(n, out me) && me.WriteValue != null)
                {
                    tokenizer.ReadNext();

                    object v;
                    if (TryDeserializeValue(tokenizer, me.MemberType, out v))
                    {
                        me.WriteValue(instance, v);
                    }
                }
                else
                {
                    tokenizer.SkipValue();
                }

                tokenizer.ReadNext();

                switch (tokenizer.SpecialChar)
                {
                case ',': break;

                case '}': return;

                default: throw new JsonException("Unexpected token");
                }
            }
        }
        static bool DeserializeInteger_string(JsonDeserializer deserializer, JsonTokenizer tokenizer, out object value)
        {
            if (tokenizer.HasSpecialChar)
            {
                tokenizer.SkipValueBody();
                value = null;
                return(false);
            }

            value = tokenizer.Token;
            return(true);
        }
 T Deserialize <T>(JsonTokenizer tokenizer) where T : new()
 {
     if (tokenizer.TryReadNext() && tokenizer.HasSpecialChar && tokenizer.SpecialChar == '{')
     {
         object v;
         if (TryDeserializeValue(tokenizer, typeof(T), out v))
         {
             return((T)v);
         }
     }
     return(new T());
 }
        static bool DeserializeInteger_double(JsonDeserializer deserializer, JsonTokenizer tokenizer, out object value)
        {
            if (tokenizer.HasSpecialChar)
            {
                tokenizer.SkipValueBody();
            }
            else
            {
                double v;
                if (JsonConvert.TryParse(tokenizer.Token, out v))
                {
                    value = v;
                    return(true);
                }
            }

            value = null;
            return(false);
        }
        object DeserializeArray(JsonTokenizer tokenizer, Type elementType)
        {
            if (!tokenizer.BeginReadArray())
            {
                return(Array.CreateInstance(elementType, 0));
            }

            var list = new List <object>();

            DeserializeCollection(tokenizer, elementType, list.Add);

            int c   = list.Count;
            var res = Array.CreateInstance(elementType, c);

            for (int i = 0; i < c; i++)
            {
                res.SetValue(list[i], i);
            }

            return(res);
        }
        void DeserializeCollection(JsonTokenizer tokenizer, Type elementType, Action <object> add)
        {
            while (true)
            {
                object v;
                if (TryDeserializeValue(tokenizer, elementType, out v))
                {
                    add(v);
                }

                tokenizer.ReadNext();
                switch (tokenizer.SpecialChar)
                {
                case ',': tokenizer.ReadNext(); break;

                case ']': return;

                default: throw new JsonException("Unexpected token");
                }
            }
        }
        static bool DeserializeInteger_ulong(JsonDeserializer deserializer, JsonTokenizer tokenizer, out object value)
        {
            if (tokenizer.HasSpecialChar)
            {
                tokenizer.SkipValueBody();
            }
            else
            {
                double v;
                if (JsonConvert.TryParse(tokenizer.Token, out v))
                {
                    v = Math.Round(v);
                    ulong i   = unchecked ((ulong)v);
                    bool  res = v - i == 0;
                    value = res ? (object)i : null;
                    return(res);
                }
            }

            value = null;
            return(false);
        }
        bool TryDeserializeValue(JsonTokenizer tokenizer, Type type, out object value)
        {
            JsonConverter <string, object> conv;

            if (tokenizer.Token == "null")
            {
                if (m_Converters != null && m_Converters.TryGetValue(type, out conv))
                {
                    value = conv(null);
                    return(true);
                }

                value = null;
                return(!type.IsValueType || type.GetGenericTypeDefinition() == typeof(Nullable <>));
            }

            if (m_Converters != null && tokenizer.TokenIsString && m_Converters.TryGetValue(type, out conv))
            {
                value = conv(tokenizer.Token);
                return(true);
            }

            return(m_Deserializers.GetOrAdd(type, RetrieveDeserializer2)(this, tokenizer, out value));
        }
        public T Deserialize <T>(string json) where T : new()
        {
            var tokenizer = new JsonTokenizer(json);

            return(Deserialize <T>(tokenizer));
        }