dojo.declare("dojom.classes.JSON", null, 
{
	    
	constructor: function ()
	{	
	},
	count: function(json)
	{
		var i = 0
		for(var key in json) i++;
		return i;
	},
	
	stringify: function(value, whitelist) 
	{
		var m = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
    	};
    	
    	var a,          // The array holding the partial texts.
        	i,          // The loop counter.
       	 	k,          // The member key.
        	l,          // Length.
        	r = /["\\\x00-\x1f\x7f-\x9f"]/g,
        	v;          // The member value.

        switch (typeof value) 
        {

			// If the string contains no control characters, no quote characters, and no
			// backslash characters, then we can safely slap some quotes around it.
			// Otherwise we must also replace the offending characters with safe sequences.
			case 'string': return r.test(value) ?
	        	'"' + value.replace(r, function (a){
		                var c = m[a];
		                if (c)
		                   return c;
		                   
		                c = a.charCodeAt();
		                return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
		            })
				+ '"' :
				'"' + value + '"';
	          
			// JSON numbers must be finite. Encode non-finite numbers as null.
			case 'number': return isFinite(value) ? String(value) : 'null';

            case 'boolean':
            
            case 'null': return String(value);

			// Due to a specification blunder in ECMAScript,
			// typeof null is 'object', so watch out for that case.
            case 'object':
                if (!value)
                    return 'null';
                
				// If the object has a toJSON method, call it, and stringify the result.
                if (typeof value.toJSON === 'function')
                    return this.stringify(value.toJSON());
                    
                a = [];
                if (typeof value.length === 'number' &&!(value.propertyIsEnumerable('length'))) 
				{
					// The object is an array. Stringify every element. Use null as a placeholder
					// for non-JSON values.

                    l = value.length;
                    for (i = 0; i < l; i += 1)
                        a.push(this.stringify(value[i], whitelist) || 'null');

					// Join all of the elements together and wrap them in brackets.
                    return '[' + a.join(',') + ']';
                }
                
                if (whitelist){
					// If a whitelist (array of keys) is provided, use it to select the components
					// of the object.

                    l = whitelist.length;
                    for (i = 0; i < l; i += 1) 
                    {
                        k = whitelist[i];
                        if (typeof k === 'string') 
                        {
                            v = this.stringify(value[k], whitelist);
                            if (v) {
                                a.push(this.stringify(k) + ':' + v);
                            }
                        }
                    }
                } 
                else 
                {
					// Otherwise, iterate through all of the keys in the object.
                    for (k in value) 
                    {
                        if (typeof k === 'string') 
                        {
                            v = this.stringify(value[k], whitelist);
                            if (v) a.push(this.stringify(k) + ':' + v);
                        }
                    }
                }
				
				// Join all of the member texts together and wrap them in braces.
                return '{' + a.join(',') + '}';
		}
	},
        
	parse: function (text, filter) 
	{
		var j;
		function walk(k, v) 
	    {
	    	var i, n;
	        if (v && typeof v === 'object') 
	        {
	        	for (i in v) 
	        	{
	            	if (Object.prototype.hasOwnProperty.apply(v, [i])) 
	            	{
						n = walk(i, v[i]);
						if (n !== undefined) 
							v[i] = n;
					}
				}
			}
		return filter(k, v);
		}
		
		
		// Parsing happens in three stages. In the first stage, we run the text against
		// regular expressions that look for non-JSON patterns. We are especially
		// concerned with '()' and 'new' because they can cause invocation, and '='
		// because it can cause mutation. But just to be safe, we want to reject all
		// unexpected forms.
		
		// We split the first stage into 4 regexp operations in order to work around
		// crippling inefficiencies in IE's and Safari's regexp engines. First we
		// replace all backslash pairs with '@' (a non-JSON character). Second, we
		// replace all simple value tokens with ']' characters. Third, we delete all
		// open brackets that follow a colon or comma or that begin the text. Finally,
		// we look to see that the remaining characters are only whitespace or ']' or
		// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
		
		if (/^[\],:{}\s]*$/.test(text.replace(/\\./g, '@').
		replace(/"[^"\\\n\r]*|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
		replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) 
		{
			// In the second stage we use the eval function to compile the text into a
			// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
			// in JavaScript: it can begin a block or an object literal. We wrap the text
			// in parens to eliminate the ambiguity.
		
			j = eval('(' + text + ')');
		
			// In the optional third stage, we recursively walk the new structure, passing
			// each name/value pair to a filter function for possible transformation.
		
			return typeof filter === 'function' ? walk('', j) : j;
		}
		
		// If the text is not JSON parseable, then a SyntaxError is thrown.
		throw new SyntaxError('parseJSON');
	}
});

if (!window.JSON) 
			JSON = new dojom.classes.JSON();

