using Apewer;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections;
using System.Collections.Generic;
#if !NET20
using System.Dynamic;
#endif
using System.Reflection;
using System.Text;

namespace Apewer
{

    /// <summary>Json。</summary>
    [Serializable]
    public class Json
#if !NET20
        : DynamicObject
#endif
    {

        #region 配置。

        [NonSerialized]
        private static bool _throw = false;

        [NonSerialized]
        private static bool _recursively = true;

        /// <summary>允许产生 Exception,默认为不允许。</summary>
        public static bool AllowException { get { return _throw; } set { _throw = value; } }

        /// <summary>当存在递归引用时候包含递归项。指定为 True 时递归项为 Null 值,指定为 False 时不包含递归项。默认值:False。</summary>
        public static bool AllowRecursively { get { return _recursively; } set { _recursively = value; } }

        #endregion

        #region 构造。

        #region 基础。

        [NonSerialized]
        private JToken _jtoken = null;

        [NonSerialized]
        private JArray _jarray = null;

        [NonSerialized]
        private JObject _jobject = null;

        [NonSerialized]
        private JProperty _jproperty = null;

        [NonSerialized]
        private JValue _jvalue = null;

        #endregion

        #region Reset

        /// <summary>重置当前对象为空。</summary>
        public void Reset()
        {
            Construct();
        }

        /// <summary>使用指定的文本重置当前对象。</summary>
        public bool Reset(string json)
        {
            Construct();
            if (json == null)
            {
                if (AllowException) throw new ArgumentNullException("json", "参数无效。");
                return false;
            }
            var parsed = Parse(json);
            if (parsed == null) return false;
            Construct(parsed._jtoken);
            return true;
        }

        /// <summary>使用指定的对象重置当前对象。</summary>
        /// <exception cref="System.Exception"></exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        public bool Reset(Json json)
        {
            Construct();
            if (json == null)
            {
                if (AllowException) throw new ArgumentNullException("json", "参数无效。");
                return false;
            }
            var parsed = Parse(json.ToString());
            if (parsed == null) return false;
            Construct(parsed._jtoken);
            return true;
        }

        /// <summary>使用指定的字典对象重置当前对象。</summary>
        /// <exception cref="System.Exception"></exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        public bool Reset(Dictionary<string, string> dictionary)
        {
            Construct();
            if (dictionary == null)
            {
                if (AllowException) throw new ArgumentNullException("dictionary", "参数无效。");
                return false;
            }
            var json = NewObject();
            foreach (var item in dictionary) json[item.Key] = item.Value;
            Construct(json._jtoken);
            return true;
        }

        /// <summary>使用指定的文本字典对象重置当前对象。</summary>
        /// <exception cref="System.Exception"></exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        public bool Reset(TextSet dictionary)
        {
            Construct();
            if (dictionary == null)
            {
                if (AllowException) throw new ArgumentNullException("dictionary", "参数无效。");
                return false;
            }
            return Reset(dictionary.Origin);
        }

        /// <summary>使用指定的文本字典对象重置当前对象。</summary>
        /// <exception cref="System.Exception"></exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        public bool Reset(ObjectSet<string> dictionary)
        {
            Construct();
            if (dictionary == null)
            {
                if (AllowException) throw new ArgumentNullException("dictionary", "参数无效。");
                return false;
            }
            return Reset(dictionary.Origin);
        }

        #endregion

        private void Construct(JToken jtoken = null)
        {
            _jtoken = jtoken;
            _jarray = null;
            _jobject = null;
            _jproperty = null;
            _jvalue = null;
            if (_jtoken != null)
            {
                if (_jtoken is JArray) _jarray = (JArray)_jtoken;
                if (_jtoken is JObject) _jobject = (JObject)_jtoken;
                if (_jtoken is JProperty) _jproperty = (JProperty)_jtoken;
                if (_jtoken is JValue) _jvalue = (JValue)_jtoken;
            }
        }

        private Json(JToken jtoken)
        {
            Construct(jtoken);
        }

        /// <summary>创建 Json Object 实例。</summary>
        public Json()
        {
            Construct(new JObject());
        }

        #endregion

        #region 属性。

        /// <summary>用于兼容 SimpleJson 的操作。</summary>
        public string this[string name]
        {
            get
            {
                var property = GetProperty(name);
                if (property == null) return "";
                return property.ToString();
            }
            set
            {
                SetProperty(name, value ?? "");
            }
        }

        private JTokenType TokenType
        {
            get
            {
                if (_jtoken == null) return JTokenType.None;
                else return _jtoken.Type;
                //if (_jtoken == null) return 0;
                //switch (_jtoken.Type)
                //{
                //    case JTokenType.None: return 0;
                //    case JTokenType.Object: return 1;
                //    case JTokenType.Array: return 2;
                //    case JTokenType.Constructor: return 3;
                //    case JTokenType.Property: return 4;
                //    case JTokenType.Comment: return 5;
                //    case JTokenType.Integer: return 6;
                //    case JTokenType.Float: return 7;
                //    case JTokenType.String: return 8;
                //    case JTokenType.Boolean: return 9;
                //    case JTokenType.Null: return 10;
                //    case JTokenType.Undefined: return 11;
                //    case JTokenType.Date: return 12;
                //    case JTokenType.Raw: return 13;
                //    case JTokenType.Bytes: return 14;
                //    case JTokenType.Guid: return 15;
                //    case JTokenType.Uri: return 16;
                //    case JTokenType.TimeSpan: return 17;
                //    default: return 0;
                //}
            }
        }

        /// <summary>
        /// <para>获取当前实例的类型。可能的类型:</para>
        /// <para>None Object Array Constructor Property Comment Integer Float String</para>
        /// <para>Boolean Null Undefined Date Raw Bytes Guid Uri TimeSpan</para>
        /// </summary>
        public string Type { get { return TokenType.ToString(); } }

        /// <summary>实例有效。</summary>
        public
            bool Available
        { get { return _jtoken != null && TokenType != JTokenType.None; } }

        /// <summary>获取当前实例的值,当为 Json 格式时缩进。</summary>
        public string Lucid { get { return ToString(true); } }

        /// <summary>获取当前实例的值,当为 Json 格式时不缩进。</summary>
        public string Text { get { return ToString(false); } }

        /// <summary>当前实例类型为 Property 时,获取名称。</summary>
        public string Name
        {
            get { return _jproperty == null ? null : _jproperty.Name; }
        }

        /// <summary>获取值。</summary>
        public object Value
        {
            get
            {
                if (_jvalue != null)
                {
                    if (_jvalue.Value == null) return null;
                    if (_jvalue.Value is JToken) return new Json((JToken)_jvalue.Value);
                    else return _jvalue.Value;
                }
                if (_jproperty != null)
                {
                    if (_jproperty.Value == null) return null;
                    if (_jproperty.Value is JToken) return new Json((JToken)_jproperty.Value);
                    else return _jproperty.Value;
                }
                return null;
            }
        }

        /// <summary>实例无效。</summary>
        public bool IsNull { get { return _jtoken == null; } }

        #endregion

        #region Private Get

        private List<Json> PrivateGetProperties { get { return GetProperties(); } }

        private List<Json> PrivateGetValues { get { return GetValues(); } }

        private List<Json> PrivateGetObjects { get { return GetObjects(); } }

        private List<Json> PrivateGetItems { get { return GetItems(); } }

        #endregion

        #region Object : Get/Set

        /// <summary>获取所有类型为 Property 的子项。</summary>
        public List<Json> GetProperties()
        {
            var list = new List<Json>();
            if (_jobject != null)
            {
                var children = _jobject.Children();
                foreach (var child in children)
                {
                    var json = new Json(child);
                    list.Add(json);
                }
            }
            return list;
        }

        /// <summary>当前实例类型为 Object 时搜索属性,失败时返回 Null。</summary>
        /// <param name="name">将要搜索的属性名称,不可为 Null。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException"></exception>
        public Json GetProperty(string name)
        {
            if (_jobject == null || TokenType != JTokenType.Object)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return null;
            }

            if (name == null)
            {
                if (_throw) throw new ArgumentNullException("name", "参数无效。");
                return null;
            }

            var children = _jtoken.Children<JProperty>();
            foreach (var child in children)
            {
                if (child.Name == name)
                {
                    var json = new Json(child.Value);
                    return json;
                }
            }
            return null;
        }

        /// <summary>当前实例类型为 Object 时添加属性,值为 Null,已存在的属性将被替换。</summary>
        /// <param name="name">将要添加的属性名称,不可为 Null。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetProperty(string name)
        {
            if (_jobject == null || TokenType != JTokenType.Object)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            if (name == null)
            {
                if (_throw) throw new ArgumentNullException("name", "参数无效。");
                return false;
            }

            var children = _jobject.Children<JProperty>();
            foreach (var child in children)
            {
                if (child.Name == name)
                {
                    _jobject.Remove(name);
                    break;
                }
            }

            _jobject.Add(name, null);
            return true;
        }

        /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
        /// <param name="property">将要添加的属性。</param>
        /// <exception cref="System.ArgumentException"></exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetProperty(Json property)
        {
            if (_jobject == null || TokenType != JTokenType.Object)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            if (property == null)
            {
                if (_throw) throw new ArgumentNullException("property", "参数无效。");
                return false;
            }

            if (property._jproperty == null || property.TokenType != JTokenType.Property)
            {
                if (_throw) throw new ArgumentException("property", "将要设置的属性无效。");
                return false;
            }

            var name = property._jproperty.Name;
            var children = _jobject.Children<JProperty>();
            foreach (var child in children)
            {
                if (child.Name == name)
                {
                    _jobject.Remove(name);
                    break;
                }
            }

            _jobject.Add(name, property._jtoken);
            return true;
        }

        /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
        /// <param name="name">将要添加的属性名称,不可为 Null。</param>
        /// <param name="value">将要添加的属性值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetProperty(string name, bool value)
        {
            if (_jobject == null || TokenType != JTokenType.Object)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            if (name == null)
            {
                if (_throw) throw new ArgumentNullException("name", "参数无效。");
                return false;
            }

            var children = _jobject.Children<JProperty>();
            foreach (var child in children)
            {
                if (child.Name == name)
                {
                    _jobject.Remove(name);
                    break;
                }
            }

            _jobject.Add(name, value);
            return true;
        }

        /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
        /// <param name="name">将要添加的属性名称,不可为 Null。</param>
        /// <param name="value">将要添加的属性值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetProperty(string name, string value)
        {
            if (_jobject == null || TokenType != JTokenType.Object)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            if (name == null)
            {
                if (_throw) throw new ArgumentNullException("name", "参数无效。");
                return false;
            }

            var children = _jobject.Children<JProperty>();
            foreach (var child in children)
            {
                if (child.Name == name)
                {
                    _jobject.Remove(name);
                    break;
                }
            }

            _jobject.Add(name, value);
            return true;
        }

        /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
        /// <param name="name">将要添加的属性名称,不可为 Null。</param>
        /// <param name="value">将要添加的属性值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetProperty(string name, int value)
        {
            if (_jobject == null || TokenType != JTokenType.Object)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            if (name == null)
            {
                if (_throw) throw new ArgumentNullException("name", "参数无效。");
                return false;
            }

            var children = _jobject.Children<JProperty>();
            foreach (var child in children)
            {
                if (child.Name == name)
                {
                    _jobject.Remove(name);
                    break;
                }
            }

            _jobject.Add(name, value);
            return true;
        }

        /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
        /// <param name="name">将要添加的属性名称,不可为 Null。</param>
        /// <param name="value">将要添加的属性值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetProperty(string name, long value)
        {
            if (_jobject == null || TokenType != JTokenType.Object)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            if (name == null)
            {
                if (_throw) throw new ArgumentNullException("name", "参数无效。");
                return false;
            }

            var children = _jobject.Children<JProperty>();
            foreach (var child in children)
            {
                if (child.Name == name)
                {
                    _jobject.Remove(name);
                    break;
                }
            }

            _jobject.Add(name, value);
            return true;
        }

        /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
        /// <param name="name">将要添加的属性名称,不可为 Null。</param>
        /// <param name="value">将要添加的属性值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetProperty(string name, float value)
        {
            if (_jobject == null || TokenType != JTokenType.Object)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            if (name == null)
            {
                if (_throw) throw new ArgumentNullException("name", "参数无效。");
                return false;
            }

            var children = _jobject.Children<JProperty>();
            foreach (var child in children)
            {
                if (child.Name == name)
                {
                    _jobject.Remove(name);
                    break;
                }
            }

            _jobject.Add(name, value);
            return true;
        }

        /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
        /// <param name="name">将要添加的属性名称,不可为 Null。</param>
        /// <param name="value">将要添加的属性值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetProperty(string name, double value)
        {
            if (_jobject == null || TokenType != JTokenType.Object)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            if (name == null)
            {
                if (_throw) throw new ArgumentNullException("name", "参数无效。");
                return false;
            }

            var children = _jobject.Children<JProperty>();
            foreach (var child in children)
            {
                if (child.Name == name)
                {
                    _jobject.Remove(name);
                    break;
                }
            }

            _jobject.Add(name, value);
            return true;
        }

        /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
        /// <param name="name">将要添加的属性名称,不可为 Null。</param>
        /// <param name="value">将要添加的属性值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetProperty(string name, decimal value)
        {
            if (_jobject == null || TokenType != JTokenType.Object)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            if (name == null)
            {
                if (_throw) throw new ArgumentNullException("name", "参数无效。");
                return false;
            }

            var children = _jobject.Children<JProperty>();
            foreach (var child in children)
            {
                if (child.Name == name)
                {
                    _jobject.Remove(name);
                    break;
                }
            }

            _jobject.Add(name, value);
            return true;
        }

        /// <summary>当前实例类型为 Object 时添加属性,已存在的属性将被替换。</summary>
        /// <param name="name">将要添加的属性名称,不可为 Null。</param>
        /// <param name="value">将要添加的属性值。</param>
        /// <exception cref="System.ArgumentException"></exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetProperty(string name, Json value)
        {
            if (_jobject == null || TokenType != JTokenType.Object)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            if (name == null)
            {
                if (_throw) throw new ArgumentNullException("name", "参数无效。");
                return false;
            }

            var children = _jobject.Children<JProperty>();
            foreach (var child in children)
            {
                if (child.Name == name)
                {
                    _jobject.Remove(name);
                    break;
                }
            }

            if (value == null)
            {
                _jobject.Add(name, null);
            }
            else
            {
                if (value._jtoken == null)
                {
                    _jobject.Add(name, null);
                }
                else
                {
                    _jobject.Add(name, value._jtoken);
                }
            }
            return true;
        }

        #endregion

        #region Array

        /// <summary>获取所有类型为 Value 的子项。</summary>
        public List<Json> GetValues()
        {
            var list = new List<Json>();
            if (_jarray != null)
            {
                var children = _jarray.Children<JValue>();
                foreach (var child in children)
                {
                    var json = new Json(child);
                    list.Add(json);
                }
            }
            return list;
        }

        /// <summary>获取所有类型为 Object 的子项。</summary>
        public List<Json> GetObjects()
        {
            var list = new List<Json>();
            if (_jarray != null)
            {
                var children = _jarray.Children<JObject>();
                foreach (var child in children)
                {
                    var json = new Json(child);
                    list.Add(json);
                }
            }
            return list;
        }

        /// <summary>获取 Array 中的所有元素。</summary>
        public List<Json> GetItems()
        {
            var list = new List<Json>();
            if (_jarray != null)
            {
                var children = _jarray.Children();
                foreach (var child in children)
                {
                    var json = new Json(child);
                    list.Add(json);
                }
            }
            return list;
        }

        /// <summary>当前实例类型为 Array 时添加 Null 元素。</summary>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool AddItem()
        {
            if (_jarray == null || TokenType != JTokenType.Array)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
                return false;
            }

            _jarray.Add(JValue.CreateNull());
            return true;
        }

        /// <summary>当前实例类型为 Array 时添加元素。</summary>
        /// <param name="json">将要添加的元素。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool AddItem(Json json)
        {
            if (json == null)
            {
                return AddItem();
            }

            if (_jarray == null || TokenType != JTokenType.Array)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
                return false;
            }

            if (json._jtoken == null || json.TokenType == JTokenType.None)
            {
                if (_throw) throw new ArgumentException("json", "将要设置的元素无效。");
                return false;
            }

            _jarray.Add(json._jtoken);
            return true;
        }

        /// <summary>当前实例类型为 Array 时添加元素。</summary>
        /// <param name="value">将要添加的元素。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool AddItem(string value)
        {
            if (_jarray == null || TokenType != JTokenType.Array)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
                return false;
            }

            _jarray.Add(value ?? "");
            return true;
        }

        /// <summary>当前实例类型为 Array 时添加元素。</summary>
        /// <param name="value">将要添加的元素。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool AddItem(bool value)
        {
            if (_jarray == null || TokenType != JTokenType.Array)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
                return false;
            }

            _jarray.Add(value);
            return true;
        }

        /// <summary>当前实例类型为 Array 时添加元素。</summary>
        /// <param name="value">将要添加的元素。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool AddItem(int value)
        {
            if (_jarray == null || TokenType != JTokenType.Array)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
                return false;
            }

            _jarray.Add(value);
            return true;
        }

        /// <summary>当前实例类型为 Array 时添加元素。</summary>
        /// <param name="value">将要添加的元素。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool AddItem(long value)
        {
            if (_jarray == null || TokenType != JTokenType.Array)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
                return false;
            }

            _jarray.Add(value);
            return true;
        }

        /// <summary>当前实例类型为 Array 时添加元素。</summary>
        /// <param name="value">将要添加的元素。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool AddItem(float value)
        {
            if (_jarray == null || TokenType != JTokenType.Array)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
                return false;
            }

            _jarray.Add(value);
            return true;
        }

        /// <summary>当前实例类型为 Array 时添加元素。</summary>
        /// <param name="value">将要添加的元素。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool AddItem(double value)
        {
            if (_jarray == null || TokenType != JTokenType.Array)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
                return false;
            }

            _jarray.Add(value);
            return true;
        }

        /// <summary>当前实例类型为 Array 时添加元素。</summary>
        /// <param name="value">将要添加的元素。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool AddItem(decimal value)
        {
            if (_jarray == null || TokenType != JTokenType.Array)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持元素。");
                return false;
            }

            _jarray.Add(value);
            return true;
        }

        /// <summary>从 Parent 中移除。</summary>
        /// <exception cref="System.InvalidOperationException"></exception>
        /// <exception cref="ArgumentOutOfRangeException"></exception>
        public bool Remove()
        {
            if (_jtoken == null) return false;

            if (_jtoken.Parent == null)
            {
                if (_throw) throw new InvalidOperationException("Parent 对象丢失。");
                return false;
            }

            try
            {
                _jtoken.Remove();
                return true;
            }
            catch (Exception exception)
            {
                if (_throw) throw exception;
                return false;
            }
        }

        #endregion

        #region Property

        /// <summary>Json 对象实例为空。</summary>
        public bool IsNone { get { return TokenType == JTokenType.None; } }

        /// <summary>Json 对象为 Object 实例。</summary>
        public bool IsObject { get { return TokenType == JTokenType.Object; } }

        /// <summary>Json 对象为 Array 实例。</summary>
        public bool IsArray { get { return TokenType == JTokenType.Array; } }

        /// <summary>Json 对象为 Property 实例。</summary>
        public bool IsProperty { get { return TokenType == JTokenType.Property; } }

        /// <summary>Json 对象为 String 实例。</summary>
        public bool IsString { get { return TokenType == JTokenType.String; } }

        /// <summary>当前实例类型为 Property 时设置 Null 值。</summary>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetValue()
        {
            var available = _jproperty != null && TokenType == JTokenType.Property;
            if (!available)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            _jproperty.Value = JValue.CreateNull();
            return true;
        }

        /// <summary>当前实例类型为 Property 时设置值。</summary>
        /// <param name="value">将要设置的值。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetValue(Json value)
        {
            var available = _jproperty != null && TokenType == JTokenType.Property;
            if (!available)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            if (value == null)
            {
                _jproperty.Value = JValue.CreateNull();
                return true;
            }

            if (value._jtoken == null || value.TokenType == JTokenType.None)
            {
                _jproperty.Value = JValue.CreateNull();
                return true;
            }

            _jproperty.Value = new JValue(value._jtoken);
            return true;
        }

        /// <summary>当前实例类型为 Property 时设置值。</summary>
        /// <param name="value">将要设置的值。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetValue(string value)
        {
            var available = _jproperty != null && TokenType == JTokenType.Property;
            if (!available)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            _jproperty.Value = value == null ? JValue.CreateNull() : JValue.CreateString(value);
            return true;
        }

        /// <summary>当前实例类型为 Property 时设置值。</summary>
        /// <param name="value">将要设置的值。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetValue(bool value)
        {
            var available = _jproperty != null && TokenType == JTokenType.Property;
            if (!available)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            _jproperty.Value = new JValue(value);
            return true;
        }

        /// <summary>当前实例类型为 Property 时设置值。</summary>
        /// <param name="value">将要设置的值。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetValue(int value)
        {
            var available = _jproperty != null && TokenType == JTokenType.Property;
            if (!available)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            _jproperty.Value = new JValue(value);
            return true;
        }

        /// <summary>当前实例类型为 Property 时设置值。</summary>
        /// <param name="value">将要设置的值。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetValue(long value)
        {
            var available = _jproperty != null && TokenType == JTokenType.Property;
            if (!available)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            _jproperty.Value = new JValue(value);
            return true;
        }

        /// <summary>当前实例类型为 Property 时设置值。</summary>
        /// <param name="value">将要设置的值。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetValue(float value)
        {
            var available = _jproperty != null && TokenType == JTokenType.Property;
            if (!available)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            _jproperty.Value = new JValue(value);
            return true;
        }

        /// <summary>当前实例类型为 Property 时设置值。</summary>
        /// <param name="value">将要设置的值。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetValue(double value)
        {
            var available = _jproperty != null && TokenType == JTokenType.Property;
            if (!available)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            _jproperty.Value = new JValue(value);
            return true;
        }

        /// <summary>当前实例类型为 Property 时设置值。</summary>
        /// <param name="value">将要设置的值。</param>
        /// <exception cref="System.InvalidOperationException"></exception>
        public bool SetValue(decimal value)
        {
            var available = _jproperty != null && TokenType == JTokenType.Property;
            if (!available)
            {
                if (_throw) throw new InvalidOperationException("当前实例不支持属性。");
                return false;
            }

            _jproperty.Value = new JValue(value);
            return true;
        }

        #endregion

        #region Import / Export

        #region From Text

        /// <summary>从 String 到 Json 的隐式转换。</summary>
        /// <exception cref="System.Exception"></exception>
        public static implicit operator Json(string text)
        {
            return Parse(text);
        }

        /// <summary>解析文本为 Json 对象,失败时返回 Null。</summary>
        /// <exception cref="System.Exception"></exception>
        public static Json Parse(string text)
        {
            try
            {
                var jtoken = JToken.Parse(text);
                var json = new Json(jtoken);
                return json;
            }
            catch (Exception exception)
            {
                if (AllowException) throw exception;
                return null;
            }
        }

        #endregion

        #region From Entity

        /// <summary>解析实现 IList 的对象为 Json 对象,失败时返回 Null。</summary>
        /// <param name="entity">将要解析的对象。</param>
        /// <param name="lower">在 Json 中将属性名称转换为小写。</param>
        /// <param name="depth">限制 Json 层级深度,当值小于零时将不限制深度。</param>
        /// <param name="force">强制解析属性,忽略 Serializable 特性。</param>
        public static Json Parse(IList entity, bool lower = false, int depth = -1, bool force = false)
        {
            if (entity == null) return null;
            var recursive = new List<object>();
            recursive.Add(entity);
            return Parse(entity, lower, recursive, depth, force);
        }

        /// <summary>解析实现 IDictionary 的对象为 Json 对象,失败时返回 Null。</summary>
        /// <param name="entity">将要解析的对象。</param>
        /// <param name="lower">在 Json 中将属性名称转换为小写。</param>
        /// <param name="depth">限制 Json 层级深度,当值小于零时将不限制深度。</param>
        /// <param name="force">强制解析属性,忽略 Serializable 特性。</param>
        public static Json Parse(IDictionary entity, bool lower = false, int depth = -1, bool force = false)
        {
            if (entity == null) return null;
            var recursive = new List<object>();
            recursive.Add(entity);
            return Parse(entity, lower, recursive, depth, force);
        }

        /// <summary>
        /// <para>解析对象为 Json 对象,包含所有公共属性,失败时返回 Null。</para>
        /// <para>String 对象将解析文本;Json 对象将返回实例;String 对象将解析文本;实现 IDictionary 或 IList 的对象将解析内容。</para>
        /// </summary>
        /// <param name="entity">将要解析的对象。</param>
        /// <param name="lower">在 Json 中将属性名称转换为小写。</param>
        /// <param name="depth">限制 Json 层级深度,当值小于零时将不限制深度。</param>
        /// <param name="force">强制解析属性,忽略 Serializable 特性。</param>
        /// <exception cref="System.Exception"></exception>
        public static Json Parse(object entity, bool lower = false, int depth = -1, bool force = false)
        {
            if (entity == null) return null;
            var recursive = new List<object>();
            recursive.Add(entity);
            return Parse(entity, lower, recursive, depth, force);
        }

        private static Json Parse(IList list, bool lower, List<object> previous, int depth, bool force)
        {
            if (list == null) return null;
            if (list is IToJson) return ((IToJson)list).ToJson();
            // IList 不再需要 SerializableAttribute 特性。
            // {
            //     var ltype = list.GetType();
            //     var sas = ltype.GetCustomAttributes(typeof(SerializableAttribute), false);
            //     if (sas == null || sas.Length < 1) return null;
            // }

            var json = NewArray();
            try
            {
                foreach (var item in list)
                {
                    var value = item;

                    // 检查递归引用。
                    var recursively = false;
                    foreach (var r in previous)
                    {
                        if (ReferenceEquals(r, value))
                        {
                            if (AllowRecursively) json.AddItem();
                            recursively = true;
                            break;
                        }
                    }
                    if (recursively) continue;

                    // 处理 Type 对象。
                    if (value.GetType().Equals(typeof(Type)) && (previous.Count > 2))
                    {
                        value = ((Type)value).FullName;
                    }

                    // 处理 Assembly 对象。
                    if (value.GetType().Equals(typeof(Assembly)) && (previous.Count > 2))
                    {
                        value = ((Assembly)value).FullName;
                    }

                    if (value == null) { json.AddItem(); }
                    else if (value is DateTime) { json.AddItem(value.ToString()); }
                    else if (value is Boolean) { json.AddItem((Boolean)value); }
                    else if (value is Int32) { json.AddItem((Int32)value); }
                    else if (value is Int64) { json.AddItem((Int64)value); }
                    else if (value is Single) { json.AddItem((Single)value); }
                    else if (value is Double) { json.AddItem((Double)value); }
                    else if (value is Decimal) { json.AddItem((Decimal)value); }
                    else if (value is String) { json.AddItem((String)value); }
                    else if (value is Json) { json.AddItem(value as Json); }
                    else
                    {
                        if ((depth < 0) || (0 < depth && previous.Count < depth))
                        {
                            var recursive = new List<object>();
                            recursive.AddRange(previous);
                            recursive.Add(value);

                            if (value is IDictionary) { json.AddItem(Parse(value as IDictionary, lower, recursive, depth, force)); }
                            else if (value is IList) { json.AddItem(Parse(value as IList, lower, recursive, depth, force)); }
                            else { json.AddItem(Parse(value, lower, recursive, depth, force)); }
                        }
                        else
                        {
                            json.AddItem(value.ToString());
                        }
                    }
                }
            }
            catch { }
            return json;
        }

        private static Json Parse(IDictionary dictionary, bool lower, List<object> previous, int depth, bool force)
        {
            if (dictionary == null) return null;
            if (dictionary is IToJson) return ((IToJson)dictionary).ToJson();
            // IDictionary 不再需要 SerializableAttribute 特性。
            // {
            //     var dtype = dictionary.GetType();
            //     var sas = dtype.GetCustomAttributes(typeof(SerializableAttribute), false);
            //     if (sas == null || sas.Length < 1) return null;
            // }

            var json = NewObject();
            try
            {
                var keys = dictionary.Keys;
                foreach (var key in keys)
                {
                    try
                    {
                        var field = key.ToString();
                        if (lower && !string.IsNullOrEmpty(field)) field = field.ToLower();

                        var value = dictionary[key];

                        // 检查递归引用。           
                        var recursively = false;
                        foreach (var r in previous)
                        {
                            if (ReferenceEquals(r, value))
                            {
                                if (AllowRecursively) json.SetProperty(field);
                                recursively = true;
                                break;
                            }
                        }
                        if (recursively) continue;

                        // 检查 System.Attribute.TypeId。
                        if (field == "TypeId" || field == "typeid")
                        {
                            if ((value != null) && (value is Type))
                            {
                                json.SetProperty(field, ((Type)value).FullName);
                                continue;
                            }
                        }

                        if (value != null)
                        {
                            // 处理 Type 对象。
                            if (value.GetType().Equals(typeof(Type)) && (previous.Count > 2))
                            {
                                value = ((Type)value).FullName;
                            }

                            // 处理 Assembly 对象。
                            if (value.GetType().Equals(typeof(Assembly)) && (previous.Count > 2))
                            {
                                value = ((Assembly)value).FullName;
                            }
                        }

                        if (value == null) { json.AddItem(); }
                        else if (value is DateTime) { json.SetProperty(field, value.ToString()); }
                        else if (value is Boolean) { json.SetProperty(field, (Boolean)value); }
                        else if (value is Int32) { json.SetProperty(field, (Int32)value); }
                        else if (value is Int64) { json.SetProperty(field, (Int64)value); }
                        else if (value is Single) { json.SetProperty(field, (Single)value); }
                        else if (value is Double) { json.SetProperty(field, (Double)value); }
                        else if (value is Decimal) { json.SetProperty(field, (Decimal)value); }
                        else if (value is String) { json.SetProperty(field, (String)value); }
                        else if (value is Json) { json.SetProperty(field, value as Json); }
                        else
                        {
                            if ((depth < 0) || (0 < depth && previous.Count < depth))
                            {
                                var recursive = new List<object>();
                                recursive.AddRange(previous);
                                recursive.Add(value);

                                if (value is IDictionary) { json.SetProperty(field, Parse(value as IDictionary, lower, recursive, depth, force)); }
                                else if (value is IList) { json.SetProperty(field, Parse(value as IList, lower, recursive, depth, force)); }
                                else { json.SetProperty(field, Parse(value, lower, recursive, depth, force)); }
                            }
                            else
                            {
                                json.SetProperty(field, value.ToString());
                            }
                        }
                    }
                    catch { }
                }
            }
            catch { }
            return json;
        }

        private static Json Parse(object entity, bool lower, List<object> previous, int depth, bool force)
        {
            if (entity == null) return null;
            if (entity is IToJson) return ((IToJson)entity).ToJson();
            if (!force && !CanSerialize(entity.GetType(), false)) return null;

            var type = null as Type;
            try { type = entity.GetType(); }
            catch (Exception exception)
            {
                if (AllowException) throw exception;
                return null;
            }

            if (entity is Json) { if (lower) ToLower(entity as Json); return entity as Json; }
            else if (entity is String) { return Parse((String)entity, lower); }
            else if (entity is IDictionary) { return Parse(entity as IDictionary, (bool)lower); }
            else if (entity is IList) { return Parse(entity as IList, (bool)lower); }

            var independent = ClassUtility.ContainsAttribute<IndependentAttribute>(type);

            var properties = type.GetProperties();
            if (properties.LongLength > 0L)
            {
                var dict = new Dictionary<string, object>();
                foreach (var property in properties)
                {
                    var field = property.Name;
                    if (field == null) continue;

                    // 有 Independent 的对象不包含继承属性。
                    if (independent)
                    {
                        if (!property.DeclaringType.Equals(type)) continue;
                    }

                    // 处理 Assembly 对象的 DefinedTypes 和 ExportedTypes 属性。
                    if (entity is Assembly)
                    {
                        var assembly = entity as Assembly;
                        if (assembly != null)
                        {
                            if (field == "DefinedTypes" || field == "ExportedTypes")
                            {
                                continue;
                            }
                        }
                    }

                    var getter = property.GetGetMethod(false);
                    if (getter == null) continue;
                    if (getter.IsStatic) continue;

                    var value = null as object;
                    try
                    {
                        value = getter.Invoke((object)entity, null);

                        // 处理 Type 对象。
                        if (getter.ReturnType.Equals(typeof(Type)) && (previous.Count > 2))
                        {
                            value = ((Type)value).FullName;
                        }

                        // 处理 Assembly 对象。
                        if (getter.ReturnType.Equals(typeof(Assembly)) && (previous.Count > 2))
                        {
                            value = ((Assembly)value).FullName;
                        }
                    }
                    catch (Exception ex)
                    {
                        value = ex.Message;
                    }

                    if (!dict.ContainsKey(field)) dict.Add(field, value);
                }
                var json = Parse(dict, lower, previous, depth, force);
                return json;
            }
            else
            {
                return NewObject();
            }
        }

        #endregion

        #region To Text

        /// <summary>导出文本,可指定缩进。若类型为 String,则导出 String 值,忽略缩进。</summary>
        internal static string Export(Json json, bool indented)
        {
            if (json == null) return "";
            if (json._jtoken == null) return "";
            if (json.TokenType == JTokenType.String && json._jvalue != null)
            {
                return json._jvalue.Value.ToString();
            }
            return json._jtoken.ToString(indented ? Formatting.Indented : Formatting.None);
        }

        /// <summary>从 Json 到 String 的隐式转换,默认不缩进。</summary>
        public static implicit operator string(Json json)
        {
            return Export(json, false);
        }

        /// <summary>生成字符串,默认不缩进。若类型为 String,则导出 String 值。</summary>
        public override string ToString()
        {
            return Export(this, false);
        }

        /// <summary>生成字符串,可指定缩进。若类型为 String,则导出 String 值,忽略缩进。</summary>
        public string ToString(bool indented)
        {
            return Export(this, indented);
        }

        #endregion

        #region To Entity

        /// <summary>填充类型实例,失败时返回 NULL 值。</summary>
        public static T FillObject<T>(Json json, bool ignoreCase = true, string ignoreCharacters = null, bool force = false) where T : class, new()
        {
            if (json == null) return null;
            if (json._jtoken == null) return null;
            if (json.TokenType != JTokenType.Object) return null;

            var entity = Activator.CreateInstance(typeof(T));
            FillObject(entity, json, ignoreCase, ignoreCharacters, force);
            return (T)entity;
        }

        /// <summary>填充类型实例,失败时返回 NULL 值。</summary>
        public static List<T> FillArray<T>(Json json, bool ignoreCase = true, string ignoreCharacters = null, bool force = false) where T : class, new()
        {
            if (json == null) return null;
            if (json._jtoken == null) return null;
            if (json.TokenType != JTokenType.Array) return null;

            var list = new List<T>();
            FillArray(list, json, ignoreCase, ignoreCharacters, force);
            return list;
        }

        private static void FillObject(object entity, Json json, bool ignoreCase, string ignoreCharacters, bool force)
        {
            if (entity == null) return;
            if (json == null) return;
            if (json.TokenType != JTokenType.Object) return;

            var jps = json.GetProperties();
            if (jps.Count < 1) return;

            var etype = entity.GetType();
            var eps = etype.GetProperties();
            if (eps.Length < 1) return;

            foreach (var ep in eps)
            {
                foreach (var jp in jps)
                {
                    var jpn = TextUtility.Trim(jp.Name);
                    var epn = TextUtility.Trim(ep.Name);

                    if (ignoreCharacters != null)
                    {
                        var characters = ignoreCharacters.ToCharArray();
                        foreach (var character in characters)
                        {
                            jpn.Replace(character.ToString(), "");
                            epn.Replace(character.ToString(), "");
                        }
                    }

                    if (ignoreCase)
                    {
                        if (jpn.Length > 0) jpn = jpn.ToLower();
                        if (epn.Length > 0) epn = epn.ToLower();
                    }

                    if (jpn.Length < 1 || epn.Length < 1) continue;
                    if (jpn != epn) continue;

                    var value = jp.Value;
                    if (value == null) continue;

                    FillProperty(entity, ep, value, ignoreCase, ignoreCharacters, force);
                }
            }
        }

        private static void FillArray(object array, Json json, bool ignoreCase, string ignoreCharacters, bool force)
        {
            if (array == null) return;
            if (json == null) return;
            if (json.TokenType != JTokenType.Array) return;

            var type = array.GetType();
            var subtypes = type.GetGenericArguments();
            if (subtypes.Length < 1) return;
            var subtype = subtypes[0];

            var methods = type.GetMethods();
            var add = null as MethodInfo;
            foreach (var method in methods)
            {
                if (method.Name == "Add")
                {
                    var parameters = method.GetParameters();
                    if (parameters.Length == 1)
                    {
                        if (parameters[0].ParameterType.FullName == subtype.FullName)
                        {
                            add = method;
                            break;
                        }
                    }
                }
            }
            if (add == null) return;

            var jis = json.GetItems();
            foreach (var ji in jis)
            {
                var parameter = new object[1] { null };
                if (subtype.FullName == typeof(Json).FullName)
                {
                    parameter[0] = ji;
                    add.Invoke(array, parameter);
                }
                else
                {
                    switch (subtype.FullName)
                    {
                        case "System.String":
                            parameter[0] = (ji.TokenType == JTokenType.Null) ? null : ji.Text;
                            add.Invoke(array, parameter);
                            break;
                        case "System.Int32":
                            parameter[0] = TextUtility.GetInt32(ji.Text);
                            add.Invoke(array, parameter);
                            break;
                        case "System.Int64":
                            parameter[0] = TextUtility.GetInt64(ji.Text);
                            add.Invoke(array, parameter);
                            break;
                        case "System.Double":
                            parameter[0] = TextUtility.GetDouble(ji.Text);
                            add.Invoke(array, parameter);
                            break;
                        case "System.Decimal":
                            parameter[0] = TextUtility.GetDecimal(ji.Text);
                            add.Invoke(array, parameter);
                            break;
                        default:
                            var serializable = force ? true : CanSerialize(subtype, false);
                            if (serializable && (ji is Json))
                            {
                                switch (ji.TokenType)
                                {
                                    case JTokenType.Object:
                                        var subobject = Activator.CreateInstance(subtype);
                                        FillObject(subobject, ji, ignoreCase, ignoreCharacters, force);
                                        parameter[0] = subobject;
                                        add.Invoke(array, parameter);
                                        break;
                                    case JTokenType.Array:
                                        var subarray = Activator.CreateInstance(subtype);
                                        FillArray(subarray, ji, ignoreCase, ignoreCharacters, force);
                                        parameter[0] = subarray;
                                        add.Invoke(array, parameter);
                                        break;
                                }
                            }
                            break;
                    }
                }
            }
        }

        private static void FillProperty(object entity, PropertyInfo property, object value, bool ignoreCase, string ignoreCharacters, bool force)
        {
            if (entity == null) return;
            if (property == null) return;
            if (value == null) return;

            var setter = property.GetSetMethod();
            if (setter == null) return;

            var ptname = property.PropertyType.FullName;
            var parameter = new object[1] { null };

            if (ptname == typeof(Json).FullName)
            {
                if (value is Json)
                {
                    parameter[0] = value;
                    setter.Invoke(entity, parameter);
                }
            }
            else
            {
                switch (ptname)
                {
                    case "System.DateTime":
                        try
                        {
                            parameter[0] = DateTime.Parse(value.ToString());
                            setter.Invoke(entity, parameter);
                        }
                        catch (Exception exception)
                        {
                            if (AllowException) throw exception;
                            parameter[0] = TextUtility.EmptyString;
                            setter.Invoke(entity, parameter);
                        }
                        break;
                    case "System.String":
                        if (value is Json) parameter[0] = ((Json)value).TokenType == JTokenType.Null ? null : ((Json)value).Text;
                        else parameter[0] = value.ToString();
                        setter.Invoke(entity, parameter);
                        break;
                    case "System.Int32":
                        parameter[0] = TextUtility.GetInt32(value.ToString());
                        setter.Invoke(entity, parameter);
                        break;
                    case "System.Int64":
                        parameter[0] = TextUtility.GetInt64(value.ToString());
                        setter.Invoke(entity, parameter);
                        break;
                    case "System.Double":
                        parameter[0] = TextUtility.GetDouble(value.ToString());
                        setter.Invoke(entity, parameter);
                        break;
                    case "System.Decimal":
                        parameter[0] = TextUtility.GetDecimal(value.ToString());
                        setter.Invoke(entity, parameter);
                        break;
                    default:
                        var serializable = force ? true : CanSerialize(property.PropertyType, false);
                        if (serializable && (value is Json))
                        {
                            switch (((Json)value).TokenType)
                            {
                                case JTokenType.Object:
                                    var subobject = Activator.CreateInstance(property.PropertyType);
                                    FillObject(subobject, (Json)value, ignoreCase, ignoreCharacters, force);
                                    parameter[0] = subobject;
                                    setter.Invoke(entity, parameter);
                                    break;
                                case JTokenType.Array:
                                    var subarray = Activator.CreateInstance(property.PropertyType);
                                    FillArray(subarray, (Json)value, ignoreCase, ignoreCharacters, force);
                                    parameter[0] = subarray;
                                    setter.Invoke(entity, parameter);
                                    break;
                            }
                        }
                        break;
                }
            }
        }

        #endregion

        #endregion

        #region Dynamic

#if !NET20

        /// <summary></summary>
        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {
            var contains = false;
            if (IsObject)
            {
                var property = GetProperty(binder.Name);
                contains = property != null;
                result = contains ? property.Value : null;
                return contains;
            }

            result = null;
            return contains;
        }

        /// <summary></summary>
        public override bool TrySetMember(SetMemberBinder binder, object value)
        {
            var name = binder.Name;

            if (value == null) return SetProperty(name);
            if (value is Json) return SetProperty(name, (Json)value);
            if (value is string) return SetProperty(name, (string)value);
            if (value is bool) return SetProperty(name, (bool)value);
            if (value is int) return SetProperty(name, (int)value);
            if (value is long) return SetProperty(name, (long)value);
            if (value is float) return SetProperty(name, (float)value);
            if (value is double) return SetProperty(name, (double)value);
            if (value is decimal) return SetProperty(name, (decimal)value);

            return false;
        }

#endif

        #endregion

        #region Statics

        #region 创建实例。

        /// <summary>创建新对象。</summary>
        public static Json NewObject()
        {
            return new Json(new JObject());
        }

        /// <summary>创建新对象。</summary>
        public static Json NewObject(Dictionary<string, string> dictionary)
        {
            var json = new Json(null);
            json.Reset(dictionary);
            return json;
        }

        /// <summary>创建新对象。</summary>
        public static Json NewObject(TextSet dictionary)
        {
            var json = new Json(null);
            json.Reset(dictionary);
            return json;
        }

        /// <summary>创建新对象。</summary>
        public static Json NewObject(ObjectSet<string> dictionary)
        {
            var json = new Json(null);
            json.Reset(dictionary);
            return json;
        }

        /// <summary>创建新对象。</summary>
        public static Json NewArray()
        {
            return new Json(new JArray());
        }

        /// <summary>新建类型为 Property 的实例,值为 Null,失败时返回 Null。</summary>
        /// <param name="name">Property 名称,不可为 Null。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static Json NewProperty(string name)
        {
            if (name == null)
            {
                if (AllowException) throw new ArgumentNullException("name", "参数无效。");
                return null;
            }
            return new Json(new JProperty(name, null));
        }

        /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
        /// <param name="name">Property 名称,不可为 Null。</param>
        /// <param name="value">Property 值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static Json NewProperty(string name, string value)
        {
            if (name == null)
            {
                if (AllowException) throw new ArgumentNullException("name", "参数无效。");
                return null;
            }
            return new Json(new JProperty(name, value));
        }

        /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
        /// <param name="name">Property 名称,不可为 Null。</param>
        /// <param name="value">Property 值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static Json NewProperty(string name, bool value)
        {
            if (name == null)
            {
                if (AllowException) throw new ArgumentNullException("name", "参数无效。");
                return null;
            }
            return new Json(new JProperty(name, value));
        }

        /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
        /// <param name="name">Property 名称,不可为 Null。</param>
        /// <param name="value">Property 值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static Json NewProperty(string name, int value)
        {
            if (name == null)
            {
                if (AllowException) throw new ArgumentNullException("name", "参数无效。");
                return null;
            }
            return new Json(new JProperty(name, value));
        }

        /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
        /// <param name="name">Property 名称,不可为 Null。</param>
        /// <param name="value">Property 值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static Json NewProperty(string name, long value)
        {
            if (name == null)
            {
                if (AllowException) throw new ArgumentNullException("name", "参数无效。");
                return null;
            }
            return new Json(new JProperty(name, value));
        }

        /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
        /// <param name="name">Property 名称,不可为 Null。</param>
        /// <param name="value">Property 值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static Json NewProperty(string name, float value)
        {
            if (name == null)
            {
                if (AllowException) throw new ArgumentNullException("name", "参数无效。");
                return null;
            }
            return new Json(new JProperty(name, value));
        }

        /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
        /// <param name="name">Property 名称,不可为 Null。</param>
        /// <param name="value">Property 值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static Json NewProperty(string name, double value)
        {
            if (name == null)
            {
                if (AllowException) throw new ArgumentNullException("name", "参数无效。");
                return null;
            }
            return new Json(new JProperty(name, value));
        }

        /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
        /// <param name="name">Property 名称,不可为 Null。</param>
        /// <param name="value">Property 值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static Json NewProperty(string name, decimal value)
        {
            if (name == null)
            {
                if (AllowException) throw new ArgumentNullException("name", "参数无效。");
                return null;
            }
            return new Json(new JProperty(name, value));
        }

        /// <summary>新建类型为 Property 的实例,失败时返回 Null。</summary>
        /// <param name="name">Property 名称,不可为 Null。</param>
        /// <param name="value">Property 值。</param>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static Json NewProperty(string name, Json value)
        {
            if (name == null)
            {
                if (AllowException) throw new ArgumentNullException("name", "参数无效。");
                return null;
            }
            if (value == null) return new Json(new JProperty(name, null));
            return new Json(new JProperty(name, null));
        }

        #endregion

        /// <summary>格式化 Json 文本。</summary>
        public static string Format(string text)
        {
            if (text == null || text == "") return "";
            try
            {
                var serializer = new Newtonsoft.Json.JsonSerializer();
                var tr = (System.IO.TextReader)(new System.IO.StringReader(text));
                var jtr = new Newtonsoft.Json.JsonTextReader(tr);
                var obj = serializer.Deserialize(jtr);
                if (obj != null)
                {
                    var textWriter = new System.IO.StringWriter();
                    var jsonWriter = new Newtonsoft.Json.JsonTextWriter(textWriter)
                    {
                        Formatting = Newtonsoft.Json.Formatting.Indented,
                        Indentation = 4,
                        IndentChar = ' '
                    };
                    serializer.Serialize(jsonWriter, obj);
                    return textWriter.ToString();
                }
                else
                {
                    return text;
                }
            }
            catch
            {
                return text ?? "";
            }
        }

        /// <summary>设置属性名称为小写。</summary>
        public static Json ToLower(Json json)
        {
            if (json == null) return null;
            switch (json.TokenType)
            {
                case JTokenType.Array:
                    var items = json.GetItems();
                    foreach (var i in items) ToLower(i);
                    break;
                case JTokenType.Object:
                    var properties = json.GetProperties();
                    foreach (var i in properties)
                    {
                        ToLower(i);

                        var name = i._jproperty.Name;
                        var value = i._jproperty.Value;

                        if (!string.IsNullOrEmpty(name))
                        {
                            var lower = name.ToLower();
                            if (name != lower)
                            {
                                i.Remove();
                                json._jobject.Add(lower, value);
                            }
                        }
                        ToLower(new Json(value));
                    }
                    break;
            }
            return json;
        }

        private static bool CanSerialize(Type type, bool inherit = false)
        {
            if (type == null) return false;

            var nsas = type.GetCustomAttributes(typeof(NonSerializedAttribute), inherit);
            if (nsas != null && nsas.Length > 0) return false;

            var sas = type.GetCustomAttributes(typeof(SerializableAttribute), inherit);
            if (sas == null || sas.Length < 1) return false;

            return true;
        }

        #endregion

    }

}