/*
  * The Merge function is experimental. Use at your own risk.
  */
 public void Merge(JSONObject obj)
 {
     MergeRecur(this, obj);
 }
 /// <summary>
 /// Merge object right into left recursively
 /// </summary>
 /// <param name="left">The left (base) object</param>
 /// <param name="right">The right (new) object</param>
 static void MergeRecur(JSONObject left, JSONObject right)
 {
     if (left.type == Type.NULL)
         left.Absorb(right);
     else if (left.type == Type.OBJECT && right.type == Type.OBJECT)
     {
         for (int i = 0; i < right.list.Count; i++)
         {
             string key = right.keys[i];
             if (right[i].isContainer)
             {
                 if (left.HasField(key))
                     MergeRecur(left[key], right[i]);
                 else
                     left.AddField(key, right[i]);
             }
             else
             {
                 if (left.HasField(key))
                     left.SetField(key, right[i]);
                 else
                     left.AddField(key, right[i]);
             }
         }
     }
     else if (left.type == Type.ARRAY && right.type == Type.ARRAY)
     {
         if (right.Count > left.Count)
         {
             return;
         }
         for (int i = 0; i < right.list.Count; i++)
         {
             if (left[i].type == right[i].type)
             {			//Only overwrite with the same type
                 if (left[i].isContainer)
                     MergeRecur(left[i], right[i]);
                 else
                 {
                     left[i] = right[i];
                 }
             }
         }
     }
 }
 public void SetField(string name, JSONObject obj)
 {
     if (HasField(name))
     {
         list.Remove(this[name]);
         keys.Remove(name);
     }
     AddField(name, obj);
 }
 public void AddField(string name, JSONObject obj)
 {
     if (obj)
     {		//Don't do anything if the object is null
         if (type != Type.OBJECT)
         {
             if (keys == null)
                 keys = new List<string>();
             if (type == Type.ARRAY)
             {
                 for (int i = 0; i < list.Count; i++)
                     keys.Add(i + "");
             }
             else
                 if (list == null)
                     list = new List<JSONObject>();
             type = Type.OBJECT;		//Congratulations, son, you're an OBJECT now
         }
         keys.Add(name);
         list.Add(obj);
     }
 }
 public void Add(JSONObject obj)
 {
     if (obj)
     {		//Don't do anything if the object is null
         if (type != Type.ARRAY)
         {
             type = Type.ARRAY;		//Congratulations, son, you're an ARRAY now
             if (list == null)
                 list = new List<JSONObject>();
         }
         list.Add(obj);
     }
 }
 public void Absorb(JSONObject obj)
 {
     list.AddRange(obj.list);
     keys.AddRange(obj.keys);
     str = obj.str;
     n = obj.n;
     b = obj.b;
     type = obj.type;
 }
 public JSONObject(JSONObject[] objs)
 {
     type = Type.ARRAY;
     list = new List<JSONObject>(objs);
 }