(function($)
{
	//list of which characters are unicoded
	var escapeRegx  = /[\u0000-\u001F\u007F-\uFFFF\x22\x5c]/g;
	var escapeMap = {
		'\b': '\\b'		,'\f': '\\f'
		,'\n': '\\n'	,'\r': '\\r'
		,'\t': '\\t'	,'"' : '\\"'
		,'\/': '\\/'	,'\\': '\\\\'
	};

	//type constants
	var TYPE_ARRAY =	"array";
	var TYPE_OBJECT =	"object";
	var TYPE_STRING =	"string";
	var TYPE_NUMBER =	"number";
	var TYPE_BOOL =		"boolean";
	var TYPE_NULL =		"null";
	var TYPE_FUNCTION =	"function";
	var TYPE_UNDEF =	"undefined";

	//string constants
	var S_UNICODE =	"\\u";
	var S_000 =		"000";
	var S_CO =		"{";	//curly brace open
	var S_CC =		"}";	//curly brace closed
	var S_BO =		"[";	//brace open
	var S_BC =		"]";	//brace closed
	var S_COMMA =	",";
	var S_PROTO =   "prototype";
	var S_QUOTE =   "\"";
	var S_QCOLN =   "\":";
	var S_EMPTY =   "";

	//regx constants
	var X_CREP = /,}/g;
	var X_BREP = /,]/g;

	//this is a lite version of jQuery.type (jquery.wsdom-1.js)
	function findType(subject)
	{
		//typeof(null) == "object" so check seperately
		if (null == subject) { return TYPE_NULL; }

		var objectType = typeof(subject);
		if (TYPE_OBJECT == objectType)
		{
			//check for specific objects since they all are considered type 'Object'
			switch(subject.constructor)
			{
			case Array:		objectType = TYPE_ARRAY;	break;
			case String:	objectType = TYPE_STRING;	break;
			case Number:	objectType = TYPE_NUMBER;	break; //here for exclusion
			case Boolean:	objectType = TYPE_BOOL;		break; //here for exclusion
			}
		}
		return objectType;
	}

	//escape unicode characters (callback function for String.replace)
	function unicodeEscape(c)
	{
		return escapeMap[c] || S_UNICODE + (S_000 + c.charCodeAt(0).toString(16)).slice(-4);
	}

	//object -> JSON string
	function parseObject(subject, rref)
	{
		//do the reference check
		if (null != rref)
		{
			for (var i=rref.length-1; i>=0; i--)
			{
				if (subject === rref[i]) { subject=undefined; } //hit self reference so nullify it
			}
			if (null != subject)
			{
				rref.push(subject); //save ourself for children
			}
		}

		var objectType = findType(subject);
		var output = S_EMPTY;

		switch(objectType)
		{
		case TYPE_OBJECT:
			output += S_CO;
			for (var prop in subject)
			{
				if (!subject.hasOwnProperty(prop) || S_PROTO == prop) { continue; } //remove native properties and nulls
				output += S_QUOTE + prop + S_QCOLN
					+ parseObject(subject[prop], rref)
					+ S_COMMA;
			}
			output += S_CC;
			break;
		case TYPE_FUNCTION:
		    throw new Error("serizlier doesn't support functions");
		    //output += TYPE_NULL;
			break;
		case TYPE_ARRAY:
			output += S_BO;
			for (var index=0, count=subject.length; index<count; index++)
			{
				output += parseObject(subject[index], rref) + S_COMMA;
			}
			output += S_BC;
			break;
		case TYPE_STRING:
			output += S_QUOTE + subject.replace(escapeRegx, unicodeEscape) + S_QUOTE;
			break;
		case TYPE_NULL:
		case TYPE_UNDEF:
			output += TYPE_NULL;
			break;
		default:
			output += String(subject).toString();
		}

		rref && rref.pop(); //done so remove ourselves
		return output;
	}

	function toJSON(val,reviver,space)
	{
		var output = parseObject(val);
		return output.replace(X_CREP,S_CC).replace(X_BREP,S_BC);
	}

	//Jquery interface for toJSON
	//http://wiki.ecmascript.org/doku.php?id=es3.1:es3.1_proposal_working_draft
	//http://wiki.ecmascript.org/doku.php?id=es3.1:json_support
	//the spec has the following interface
	//  - JSON.stringify(val, reviver, space)
	//  - JSON.parse(val, reviver);
	// AR - I don't want to implement the reviver and space pieces yet

	function fromJSON(json, reviver)
	{
		var revived;
		json && eval("revived="+json);
		return revived;
	}

	//===========================================================================
	//attach methods to jQuery object
	//===========================================================================

	/**
	Converts a javascript variable to a json encoded string.
	@param {object} val variable to turn into a json encoded string
	@param {function} reviver not implemented
	@param {string} space not implemented
	@return {string} a json encoded string
	@member jQuery
	*/
	$.toJSON = toJSON;
	/**
	Converts a json encoded string into a native javascript object
	@param {string} json a json encoded string
	@param {function} reviver not implemented
	@return {object} javasript object created from json string
	@member jQuery
	*/
	$.fromJSON = fromJSON;
})(jQuery);
