internal static YJSONContent ParseJson(string data, int start, int stop)
        {
            int          cur_pos = SkipGarbage(data, start, stop);
            YJSONContent res;

            if (data[cur_pos] == '[')
            {
                res = new YJSONArray(data, start, stop);
            }
            else if (data[cur_pos] == '{')
            {
                res = new YJSONObject(data, start, stop);
            }
            else if (data[cur_pos] == '"')
            {
                res = new YJSONString(data, start, stop);
            }
            else
            {
                res = new YJSONNumber(data, start, stop);
            }
            res.parse();
            return(res);
        }
        public double getDouble(string key)
        {
            YJSONNumber yint = (YJSONNumber)parsed[key];

            return(yint.getDouble());
        }
        public long getLong(string key)
        {
            YJSONNumber yint = (YJSONNumber)parsed[key];

            return(yint.getLong());
        }
        public int getInt(string key)
        {
            YJSONNumber yint = (YJSONNumber)parsed[key];

            return(yint.getInt());
        }
        public override int parse()
        {
            string current_name = "";
            int    name_start   = _data_start;
            int    cur_pos      = SkipGarbage(_data, _data_start, _data_boundary);

            if (_data.Length <= cur_pos || _data[cur_pos] != '{')
            {
                throw new System.Exception(FormatError("Opening braces was expected", cur_pos));
            }
            cur_pos++;
            Tjstate state = Tjstate.JWAITFORNAME;


            while (cur_pos < _data_boundary)
            {
                char sti = _data[cur_pos];
                switch (state)
                {
                case Tjstate.JWAITFORNAME:
                    if (sti == '"')
                    {
                        state      = Tjstate.JWAITFORENDOFNAME;
                        name_start = cur_pos + 1;
                    }
                    else if (sti == '}')
                    {
                        _data_len = cur_pos + 1 - _data_start;
                        return(_data_len);
                    }
                    else
                    {
                        if (sti != ' ' && sti != '\n' && sti != '\r')
                        {
                            throw new System.Exception(FormatError("invalid char: was expecting \"", cur_pos));
                        }
                    }
                    break;

                case Tjstate.JWAITFORENDOFNAME:
                    if (sti == '"')
                    {
                        current_name = _data.Substring(name_start, cur_pos - name_start);
                        state        = Tjstate.JWAITFORCOLON;
                    }
                    else
                    {
                        if (sti < 32)
                        {
                            throw new System.Exception(FormatError("invalid char: was expecting an identifier compliant char", cur_pos));
                        }
                    }
                    break;

                case Tjstate.JWAITFORCOLON:
                    if (sti == ':')
                    {
                        state = Tjstate.JWAITFORDATA;
                    }
                    else
                    {
                        if (sti != ' ' && sti != '\n' && sti != '\r')
                        {
                            throw new System.Exception(
                                      FormatError("invalid char: was expecting \"", cur_pos));
                        }
                    }
                    break;

                case Tjstate.JWAITFORDATA:
                    if (sti == '{')
                    {
                        YJSONObject jobj = new YJSONObject(_data, cur_pos, _data_boundary);
                        int         len  = jobj.parse();
                        cur_pos += len;
                        parsed.Add(current_name, jobj);
                        _keys.Add(current_name);
                        state = Tjstate.JWAITFORNEXTSTRUCTMEMBER;
                        //cur_pos is already incremented
                        continue;
                    }
                    else if (sti == '[')
                    {
                        YJSONArray jobj = new YJSONArray(_data, cur_pos, _data_boundary);
                        int        len  = jobj.parse();
                        cur_pos += len;
                        parsed.Add(current_name, jobj);
                        _keys.Add(current_name);
                        state = Tjstate.JWAITFORNEXTSTRUCTMEMBER;
                        //cur_pos is already incremented
                        continue;
                    }
                    else if (sti == '"')
                    {
                        YJSONString jobj = new YJSONString(_data, cur_pos, _data_boundary);
                        int         len  = jobj.parse();
                        cur_pos += len;
                        parsed.Add(current_name, jobj);
                        _keys.Add(current_name);
                        state = Tjstate.JWAITFORNEXTSTRUCTMEMBER;
                        //cur_pos is already incremented
                        continue;
                    }
                    else if (sti == '-' || (sti >= '0' && sti <= '9'))
                    {
                        YJSONNumber jobj = new YJSONNumber(_data, cur_pos, _data_boundary);
                        int         len  = jobj.parse();
                        cur_pos += len;
                        parsed.Add(current_name, jobj);
                        _keys.Add(current_name);
                        state = Tjstate.JWAITFORNEXTSTRUCTMEMBER;
                        //cur_pos is already incremented
                        continue;
                    }
                    else if (sti != ' ' && sti != '\n' && sti != '\r')
                    {
                        throw new System.Exception(FormatError("invalid char: was expecting  \",0..9,t or f", cur_pos));
                    }
                    break;

                case Tjstate.JWAITFORNEXTSTRUCTMEMBER:
                    if (sti == ',')
                    {
                        state      = Tjstate.JWAITFORNAME;
                        name_start = cur_pos + 1;
                    }
                    else if (sti == '}')
                    {
                        _data_len = cur_pos + 1 - _data_start;
                        return(_data_len);
                    }
                    else
                    {
                        if (sti != ' ' && sti != '\n' && sti != '\r')
                        {
                            throw new System.Exception(FormatError("invalid char: was expecting ,", cur_pos));
                        }
                    }
                    break;

                case Tjstate.JWAITFORNEXTARRAYITEM:
                case Tjstate.JWAITFORSTRINGVALUE:
                case Tjstate.JWAITFORINTVALUE:
                case Tjstate.JWAITFORBOOLVALUE:
                    throw new System.Exception(FormatError("invalid state for YJSONObject", cur_pos));
                }
                cur_pos++;
            }
            throw new System.Exception(FormatError("unexpected end of data", cur_pos));
        }
        public long getLong(int i)
        {
            YJSONNumber ystr = (YJSONNumber)_arrayValue[i];

            return(ystr.getLong());
        }
        public int getInt(int i)
        {
            YJSONNumber ystr = (YJSONNumber)_arrayValue[i];

            return(ystr.getInt());
        }
        public override int parse()
        {
            int cur_pos = SkipGarbage(_data, _data_start, _data_boundary);

            if (_data[cur_pos] != '[')
            {
                throw new System.Exception(FormatError("Opening braces was expected", cur_pos));
            }
            cur_pos++;
            Tjstate state = Tjstate.JWAITFORDATA;

            while (cur_pos < _data_boundary)
            {
                char sti = _data[cur_pos];
                switch (state)
                {
                case Tjstate.JWAITFORDATA:
                    if (sti == '{')
                    {
                        YJSONObject jobj = new YJSONObject(_data, cur_pos, _data_boundary);
                        int         len  = jobj.parse();
                        cur_pos += len;
                        _arrayValue.Add(jobj);
                        state = Tjstate.JWAITFORNEXTARRAYITEM;
                        //cur_pos is already incremented
                        continue;
                    }
                    else if (sti == '[')
                    {
                        YJSONArray jobj = new YJSONArray(_data, cur_pos, _data_boundary);
                        int        len  = jobj.parse();
                        cur_pos += len;
                        _arrayValue.Add(jobj);
                        state = Tjstate.JWAITFORNEXTARRAYITEM;
                        //cur_pos is already incremented
                        continue;
                    }
                    else if (sti == '"')
                    {
                        YJSONString jobj = new YJSONString(_data, cur_pos, _data_boundary);
                        int         len  = jobj.parse();
                        cur_pos += len;
                        _arrayValue.Add(jobj);
                        state = Tjstate.JWAITFORNEXTARRAYITEM;
                        //cur_pos is already incremented
                        continue;
                    }
                    else if (sti == '-' || (sti >= '0' && sti <= '9'))
                    {
                        YJSONNumber jobj = new YJSONNumber(_data, cur_pos, _data_boundary);
                        int         len  = jobj.parse();
                        cur_pos += len;
                        _arrayValue.Add(jobj);
                        state = Tjstate.JWAITFORNEXTARRAYITEM;
                        //cur_pos is already incremented
                        continue;
                    }
                    else if (sti == ']')
                    {
                        _data_len = cur_pos + 1 - _data_start;
                        return(_data_len);
                    }
                    else if (sti != ' ' && sti != '\n' && sti != '\r')
                    {
                        throw new System.Exception(FormatError("invalid char: was expecting  \",0..9,t or f", cur_pos));
                    }
                    break;

                case Tjstate.JWAITFORNEXTARRAYITEM:
                    if (sti == ',')
                    {
                        state = Tjstate.JWAITFORDATA;
                    }
                    else if (sti == ']')
                    {
                        _data_len = cur_pos + 1 - _data_start;
                        return(_data_len);
                    }
                    else
                    {
                        if (sti != ' ' && sti != '\n' && sti != '\r')
                        {
                            throw new System.Exception(FormatError("invalid char: was expecting ,", cur_pos));
                        }
                    }
                    break;

                default:
                    throw new System.Exception(FormatError("invalid state for YJSONObject", cur_pos));
                }
                cur_pos++;
            }
            throw new System.Exception(FormatError("unexpected end of data", cur_pos));
        }