public static string CreateJSONString(LogicJSONNode root, int ensureCapacity = 20)
        {
            StringBuilder builder = new StringBuilder(ensureCapacity);

            root.WriteToString(builder);
            return(builder.ToString());
        }
        private static LogicJSONArray ParseArray(CharStream stream)
        {
            stream.SkipWhitespace();

            if (stream.Read() != '[')
            {
                LogicJSONParser.ParseError("Not an array");
                return(null);
            }

            LogicJSONArray jsonArray = new LogicJSONArray();

            stream.SkipWhitespace();

            char nextChar = stream.NextChar();

            if (nextChar != '\0')
            {
                if (nextChar == ']')
                {
                    stream.Read();
                    return(jsonArray);
                }

                while (true)
                {
                    LogicJSONNode node = LogicJSONParser.ParseValue(stream);

                    if (node != null)
                    {
                        jsonArray.Add(node);
                        stream.SkipWhitespace();

                        nextChar = stream.Read();

                        if (nextChar != ',')
                        {
                            if (nextChar == ']')
                            {
                                return(jsonArray);
                            }

                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            LogicJSONParser.ParseError("Not an array");
            return(null);
        }
        public LogicJSONString GetJSONString(int index)
        {
            LogicJSONNode node = this.m_items[index];

            if (node.GetJSONNodeType() != LogicJSONNodeType.STRING)
            {
                Debugger.Warning(string.Format("LogicJSONObject::getJSONString wrong type {0}, index {1}", node.GetJSONNodeType(), index));
                return(null);
            }

            return((LogicJSONString)node);
        }
        public LogicJSONObject GetJSONObject(int index)
        {
            LogicJSONNode node = this.m_items[index];

            if (node.GetJSONNodeType() != LogicJSONNodeType.OBJECT)
            {
                Debugger.Warning("LogicJSONObject::getJSONObject wrong type " + node.GetJSONNodeType() + ", index " + index);
                return(null);
            }

            return((LogicJSONObject)node);
        }
        public LogicJSONBoolean GetJSONBoolean(int index)
        {
            LogicJSONNode node = this.m_items[index];

            if (node.GetJSONNodeType() != LogicJSONNodeType.BOOLEAN)
            {
                Debugger.Warning(string.Format("LogicJSONObject::getJSONBoolean wrong type {0}, index {1}", node.GetJSONNodeType(), index));
                return(null);
            }

            return((LogicJSONBoolean)node);
        }
        private static LogicJSONNode ParseValue(CharStream stream)
        {
            stream.SkipWhitespace();

            char          charValue = stream.NextChar();
            LogicJSONNode node      = null;

            switch (charValue)
            {
            case '{':
                node = LogicJSONParser.ParseObject(stream);
                break;

            case '[':
                node = LogicJSONParser.ParseArray(stream);
                break;

            case 'n':
                node = LogicJSONParser.ParseNull(stream);
                break;

            case 'f':
                node = LogicJSONParser.ParseBoolean(stream);
                break;

            case 't':
                node = LogicJSONParser.ParseBoolean(stream);
                break;

            case '"':
                node = LogicJSONParser.ParseString(stream);
                break;

            case '-':
                node = LogicJSONParser.ParseNumber(stream);
                break;

            default:
                if (charValue >= '0' && charValue <= '9')
                {
                    node = LogicJSONParser.ParseNumber(stream);
                }
                else
                {
                    LogicJSONParser.ParseError("Not of any recognized value: " + charValue);
                }

                break;
            }

            return(node);
        }
        public LogicJSONNumber GetJSONNumber(string key)
        {
            int itemIndex = this.m_keys.IndexOf(key);

            if (itemIndex == -1)
            {
                return(null);
            }

            LogicJSONNode node = this.m_items[itemIndex];

            if (node.GetJSONNodeType() == LogicJSONNodeType.NUMBER)
            {
                return((LogicJSONNumber)node);
            }

            Debugger.Warning(string.Format("LogicJSONObject::getJSONNumber type is {0}, key {1}", node.GetJSONNodeType(), key));

            return(null);
        }
        public void Put(string key, LogicJSONNode item)
        {
            int keyIndex = this.m_keys.IndexOf(key);

            if (keyIndex != -1)
            {
                Debugger.Error(string.Format("LogicJSONObject::put already contains key {0}", key));
            }
            else
            {
                int itemIndex = this.m_items.IndexOf(item);

                if (itemIndex != -1)
                {
                    Debugger.Error(string.Format("LogicJSONObject::put already contains the given JSONNode pointer. Key {0}", key));
                }
                else
                {
                    this.m_items.Add(item);
                    this.m_keys.Add(key);
                }
            }
        }
        private static LogicJSONObject ParseObject(CharStream stream)
        {
            stream.SkipWhitespace();

            if (stream.Read() != '{')
            {
                LogicJSONParser.ParseError("Not an object");
                return(null);
            }

            LogicJSONObject jsonObject = new LogicJSONObject();

            stream.SkipWhitespace();

            char nextChar = stream.NextChar();

            if (nextChar != '\0')
            {
                if (nextChar == '}')
                {
                    stream.Read();
                    return(jsonObject);
                }

                while (true)
                {
                    LogicJSONString key = LogicJSONParser.ParseString(stream);

                    if (key != null)
                    {
                        stream.SkipWhitespace();

                        nextChar = stream.Read();

                        if (nextChar != ':')
                        {
                            break;
                        }

                        LogicJSONNode node = LogicJSONParser.ParseValue(stream);

                        if (node != null)
                        {
                            jsonObject.Put(key.GetStringValue(), node);
                            stream.SkipWhitespace();

                            nextChar = stream.Read();

                            if (nextChar != ',')
                            {
                                if (nextChar == '}')
                                {
                                    return(jsonObject);
                                }

                                break;
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            LogicJSONParser.ParseError("Not an object");
            return(null);
        }
 public void Add(LogicJSONNode item)
 {
     this.m_items.Add(item);
 }