    /**
     * @class Ext.util.JSON
     * Modified version of Douglas Crockford"s json.js that doesn"t
     * mess with the Object prototype
     * http://www.json.org/js.html
     * @singleton
     */
    Ext.util.JSON = new (function(){
        var useHasOwn = !!{}.hasOwnProperty;

        // crashes Safari in some instances
        //var validRE = /^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/;

        var pad = function(n) {
            return n < 10 ? "0" + n : n;
        };

        var m = {
            "\b": '\\b',
            "\t": '\\t',
            "\n": '\\n',
            "\f": '\\f',
            "\r": '\\r',
            '"' : '\\"',
            "\\": '\\\\'
        };

        var encodeString = function(s){
            if (/["\\\x00-\x1f]/.test(s)) {
                return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
                    var c = m[b];
                    if(c){
                        return c;
                    }
                    c = b.charCodeAt();
                    return "\\u00" +
                        Math.floor(c / 16).toString(16) +
                        (c % 16).toString(16);
                }) + '"';
            }
            return '"' + s + '"';
        };

        var encodeArray = function(o){
            var a = ["["], b, i, l = o.length, v;
                for (i = 0; i < l; i += 1) {
                    v = o[i];
                    switch (typeof v) {
                        case "undefined":
                        case "function":
                        case "unknown":
                            break;
                        default:
                            if (b) {
                                a.push(',');
                            }
                            a.push(v === null ? "null" : Ext.util.JSON.encode(v));
                            b = true;
                    }
                }
                a.push("]");
                return a.join("");
        };

        this.encodeDate = function(o){
            return '"' + o.getFullYear() + "-" +
                    pad(o.getMonth() + 1) + "-" +
                    pad(o.getDate()) + "T" +
                    pad(o.getHours()) + ":" +
                    pad(o.getMinutes()) + ":" +
                    pad(o.getSeconds()) + '"';
        };

        /**
         * Encodes an Object, Array or other value
         * @param {Mixed} o The variable to encode
         * @return {String} The JSON string
         */
        this.encode = function(o){
            if(typeof o == "undefined" || o === null){
                return "null";
            }else if(Ext.isArray(o)){
                return encodeArray(o);
            }else if(Ext.isDate(o)){
                return Ext.util.JSON.encodeDate(o);
            }else if(typeof o == "string"){
                return encodeString(o);
            }else if(typeof o == "number"){
                return isFinite(o) ? String(o) : "null";
            }else if(typeof o == "boolean"){
                return String(o);
            }else {
                var a = ["{"], b, i, v;
                for (i in o) {
                    if(!useHasOwn || o.hasOwnProperty(i)) {
                        v = o[i];
                        switch (typeof v) {
                        case "undefined":
                        case "function":
                        case "unknown":
                            break;
                        default:
                            if(b){
                                a.push(',');
                            }
                            a.push(this.encode(i), ":",
                                    v === null ? "null" : this.encode(v));
                            b = true;
                        }
                    }
                }
                a.push("}");
                return a.join("");
            }
        };

        /**
         * Decodes (parses) a JSON string to an object. If the JSON is invalid, this function throws a SyntaxError unless the safe option is set.
         * @param {String} json The JSON string
         * @param {Boolean} safe (optional) If set to true and the JSON is malformed, null is returned.
         * @return {Object} The resulting object
         */
        this.decode = function(json, safe){
            var fn = function(){
                return eval("(" + json + ')');
            };
            if(safe){
                try{
                    return fn();
                }catch(e){
                    return null;
                }
            }else{
                return fn();
            }
        };
    })();
    /**
     * Shorthand for {@link Ext.util.JSON#encode}
     * @param {Mixed} o The variable to encode
     * @return {String} The JSON string
     * @member Ext
     * @method encode
     */
    Ext.encode = Ext.util.JSON.encode;
    /**
     * Shorthand for {@link Ext.util.JSON#decode}
     * @param {String} json The JSON string
     * @param {Boolean} safe (optional) Whether to return null or throw an exception if the JSON is invalid.
     * @return {Object} The resulting object
     * @member Ext
     * @method decode
     */
    Ext.decode = Ext.util.JSON.decode;