	var obj = {},		_threads = {}, // each thread represent an area...		_hashtable = [],		_oDefaultConfig = {relative: false, baseURI:document.location},		_loadingClass = 'loading',		_classname = 'yui-dispatchable';
	
	
	var constants = { LOADING: 1, DISPATCHED: 2, ERROR: 3, EMPTY: 4, proxy: '/dispatcher.php?uri=', CSSNODE: 1, JSNODE: 2 };			var reScriptTag = /<script([^>]*)>([\s\S]*?)<\/script>/igm,		  reScriptTagSrc = /src=(['"]?)([^"']*)\1/i,		  reScriptTagRel = /rel=(['"]?)([^"']*)\1/i,		  reLinkTag = /<link([^>]*)(>[\s]*<\/link>|>)/igm,		  reLinkTagSrc = /href=(['"]?)([^"']*)\1/i,	 reStyleTag = /<style([^>]*)>([\s\S]*?)<\/style>/igm,	 reTagParams = new RegExp('([\\w-\.]+)\\s*=\\s*(".*?"|\'.*?\'|\\w+)*', 'im');		var reCSS3rdFile    = new RegExp('url\\s*\\(([^\\)]*)', 'igm'); // [url(image.gif] - also can include quotes

	var _onloadCB;
	var _onloadScope;
	
	function filterAjax(data, id, onloadFunction, onloadScope) {
		//alert("onloadFunction " + onloadFunction);
		_onloadCB = onloadFunction;
		//alert("_onloadCB2: " + typeof(_onloadCB));
		_onloadScope = onloadScope;
		if(typeof(id)=="undefined") {
			id = 100;
			while(!typeof(_threads[id]) == "undefined") {
				id++;
			}
		}
		var ret = parse(id, data);
		dispatch(id);
		return ret;
	}
	
	/**	* Parse the string, remove the script tags, and create the execution thread...	* @public	* @param {Object} hd    		Element reference	* @param {string} s     		String with the script tags inside...	* @return string	*/    function parse( hd, s, config ) {
		_threads[hd] = {chunks: []};
		config = config || {};		config.uri = config.uri || null;		config.relative = config.relative || _oDefaultConfig.relative;		var m = true, attr = false,		    base = ""; //_baseURI(config.uri); // calculation of the base path...		// searching and cut out all style tags, push them into thread		// ej. <style title="" type="text/css"></style>		// not supported yet. <!--@import url("http://us.js2.yimg.com/us.js.yimg.com/lib/hdr/ygma_2.19.css");body{margin:0px 4px;}-->		s = s.replace(reStyleTag,		  function (str,p1,p2,offset,s) {			// apply the inline style automatically			if (p2) {			    obj.applyCSS(p2, _getParams(p1), config);			}		    return "";	      }		);		// searching and cut out all Link tags, push them into thread		// ej. <link rel="stylesheet" type="text/css" href='/themes/bubbling/css/common.css' />		s = s.replace(reLinkTag,		  function (str,p1,p2,offset,s) {
			// add a remote style to buffer			if(p1){			  attr = p1.match(reLinkTagSrc);			  if(attr) {			    if (config.relative) {					attr[2] = _relativeURI(base, attr[2]); // path correction process...				}			    _threads[hd].chunks.push ({					src: attr[2],					content: '',					type: constants.CSSNODE,					params: _getParams(p1)				});			  }			}		    return "";	      }		);		// searching and cut out all script tags, push them into thread		s = s.replace(reScriptTag,		  function (str,p1,p2,offset,s) {			// add a remote script to buffer			if(p1){			  attr = p1.match(reScriptTagSrc);			  if(attr) {				var rel = p1.match(reScriptTagRel);				rel = (rel?rel[2]:null);			    if (config.relative) {					attr[2] = _relativeURI(base, attr[2]); // path correction process...				}			    _threads[hd].chunks.push ({					src: attr[2],					content: '',					type: constants.JSNODE,					rel: rel,					params: _getParams(p1)				});			  }			}			// add a inline script to buffer			if (p2) {
			    _threads[hd].chunks.push ({					src: null,					content: p2,					type: constants.JSNODE,					params: _getParams(p1)				});			}		    return "";	      }		);		return s;    }
	
  	/**	* Dispatching the next node of the handle	* @public	* @param {Object} hd     		Thread's handle	* @param {Object} config    Used to pass the user configuration thru the chain of execution	* @return boolean	*/	function dispatch( hd, config ) {
	  var callback = null, flag = true, node = null, uri = '', i = 0;	  config = config || {};	  if (obj.isAlive(hd)) {	  	node = _threads[hd].chunks.shift();	  	if (typeof(node) == "object" && node.src) {		  // cheching the uri in the hashtable		  config.hash = _hashtable.length; // default hash (at the end of the table)		  for (i=0; i<_hashtable.length; i++) {		  	if (_hashtable[i].uri == node.src) {				if ((_hashtable[i].status == constants.DISPATCHED) && !config.override) {					// this uri was already dispatched by this plugin and will be discarted...					flag = false;				} else {					// the uri already exists in the table				}		  		config.hash = i;				break;			}		  }		  if (flag) {		  	// fetching the remote script using the YUI Get Utility		    uri = obj.firewall (node.src, config, true);			if (typeof(uri)=="string" && (uri !== '')) {				_hashtable[config.hash] = {uri: node.src, proxy: uri, status: constants.LOADING};				if (node.type === constants.JSNODE) {					obj.area = hd;					obj.destroyer = _threads[hd].destroyer;
					//alert("getting script: " + uri);
					config.handle = $.getScript(uri, 
						function() {						    _hashtable[config.hash].status = constants.DISPATCHED;							config.hash = null; // resetting the config.hash for the next iteration...							// continue with the thread							dispatch( hd, config );						}.bind(obj)					);				} else if (node.type === constants.CSSNODE) {
					loadcssfile(uri);					_hashtable[config.hash].status = constants.DISPATCHED;					// continue with the thread					dispatch( hd, config );				}			}		  } else {		  	// continue with the thread execution			dispatch( hd, config );		  }		}		else {		  // the node represent an inline script (don't have hash value)		  config.hash = null;		  exec (hd, node.content, config);		}	  } else {	  	// ending the execution thread	  	obj.kill(hd);		_onLoad (config);	  }	}
	
	function loadcssfile(filename){		var fileref=document.createElement("link");		fileref.setAttribute("rel", "stylesheet");		fileref.setAttribute("type", "text/css");		fileref.setAttribute("href", filename);				if (typeof fileref!="undefined")			document.getElementsByTagName("head")[0].appendChild(fileref);	}
	
	/**	* Executing a javascript script segment	* @public	* @param {Object} hd     		Thread's handle	* @param {string} c     		Content to execute	* @param {Object} config    User configuration (useful for future implementations)	* @return boolean	*/	function exec( hd, c, config ) {	  var status = constants.EMPTY;	  if (c && (c !== '')) {		config.scope = (config.scope?config.scope:window);		try{		  // initialize a new anonymous container for the script, dont make it part of this object scope chain		  status = constants.DISPATCHED;		  // instead send in a variable that points to this object...		  this.scriptScope = null;		  if (!config.hash || (_hashtable[config.hash].status != constants.DISPATCHED)) {			 obj.area = hd;			 obj.destroyer = _threads[hd].destroyer;			 // you can define your own evaluation routine for inline scripts			 if (typeof(config.evalRoutine)=="function") {				 this.scriptScope = config.evalRoutine(c, config);			 } else {				 // hacking the new Function utility to create a gateway to the current execution var...				 //this.scriptScope = new (new Function('_container_', c+'; return this;'))(config.scope);
				 //alert("processing js");
				if(window.execScript) {
					window.execScript(c);
				} else if ( $.browser.safari ) {	                  // safari doesn't provide a synchronous global eval					window.setTimeout( c, 0 );
				} else {
				 	window.eval(c);
				}
		     }			 		  }		}catch(e){		  status = constants.ERROR;		  if (typeof(config.error)=="function") {			  config.error.apply ( config, [hd, c, _hashtable] );		  } else {
			  throw new			    Error ("Dispacher: Script Execution Error ("+e+")");		  }		}	  }	  // updating the status of the remote script in the hashtable	  if (typeof(config.hash)=="number") {		_hashtable[config.hash].status = status;		config.hash = null; // resetting the config.hash for the next iteration...	  }	  dispatch( hd, config );	}	
	Function.prototype.bind = function(o){ var fn = this; return function(){ return fn.apply(o, arguments); }; };
		function _getParams ( str, validator ) {		var p = null, r = {};		validator = validator || {};		// capturing the params into an object literal (r)		if(typeof(str)=="string"){		  while(p = reTagParams.exec(str)){		  	// apply validation if exists, if the value is null will be discarted			p[2] = (validator.hasOwnProperty(p[1])?validator[p[1]]:p[2]);			if (p[2]) {			   r[p[1]] = _handleQuotes(p[2]);			}			str = str.replace(reTagParams, '');		  }		}		return r;	}	function _baseURI ( uri ) {		uri = ((typeof(uri)=="string" && (uri.indexOf('/') > -1))?uri:_oDefaultConfig.baseURI) + ''; // the default base is the current document uri (hack to convert to string)		return uri.substr (0, uri.lastIndexOf('/')+1); // forget the file name	}	function _relativeURI( base, uri ) {	  	// is the url is relative (not http..., not / at the begining)		if(uri && !reURI.test(uri) && (uri.indexOf('/') !== 0)){		  uri = base+uri;		}	    return uri;	}	function _onStart (config) {		 // onStart (before the loading)		 config.onStart = config.before || config.onStart;		 if (typeof(config.onStart)=="function") {		   config.onStart.apply ( config, [config.element] );		   config.onStart = null; // because the process method will try to executed again...		 }	}
		function _onLoad (config) {		 // onLoad (after the execution)		 config.onLoad = config.after || config.onLoad;
		 //alert("_onload " + typeof(_onloadCB));
		// if(typeof(_onloadCB) == "function" || typeof(_onloadCB) == "object") {
			try {
				//alert("onloadtest: " + String(_onloadCB));
				//alert(typeof(_onloadCB));
				//_onloadCB.apply(_onloadScope);
				eval(_onloadCB).apply(_onloadScope);
			} catch(e) {}
		// }		 if (typeof(config.onLoad)=="function") {		   config.onLoad.apply ( config, [config.element] );		 }	}	
	

	    
	// utilities	function _handleQuotes( str ) {	  if (String(str).length > 0) {	  	str = str.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");  // trim		str = str.replace(/^(['|"])*(\S*(?:\s+\S+)*)\1$/, "$2"); // un-quotes	  }	  return str;	}
	
	/**	* * Kill a process...	* @public	* @param {object} handle   Process handle	* @return void	*/	obj.kill = function ( hd ) {		if (hd && !typeof(_threads[hd])=="object") {			_threads[hd] = {chunks: [], destroyer: null};		} else if (this.isAlive (hd)) {			_threads[hd].chunks = []; // discarding the handle...		}	};	
		    
    /**	* * Injecting CSS in the current page	* @public	* @param {string} cssCode   CSS content that will be injected	* @param {object} params    Literal object with the tag configuration params	* @param {object} config    Literal object with the dispatcher configuration values	* @return boolean  the operation result	*/	obj.applyCSS = function( cssCode, params, config ) {		params = params || {};		var styleElement = document.createElement("style"), base = params.href || '';		// calculation of the base path...		config = config || {};		config.uri = config.uri || _oDefaultConfig.baseURI;		config.relative = config.relative || _oDefaultConfig.relative;		if (config.relative) {			base = _baseURI(config.uri); // calculation of the base path...			base = _relativeURI(base, params.href); // path correction process...		}		base = _baseURI(base);		// path correction process...		// ej: (image.gif) or ("image.gif") or ('image.gif') or (http://fullpath/image.gif)		/*  In the case of DXImageTransform.Microsoft.AlphaImageLoader(src='image.png',sizingMethod='scale');		    The use of the AlphaImageLoader ultimately proved to be			an unreliable solution for IE 6 as it never handled relative paths well.			It seems like the AlphaImageLoader always expects the paths to be relative			to the page the CSS is included in, rather than relative to the CSS file itself. */  		cssCode = cssCode.replace(reCSS3rdFile,		  function (str,p1,offset,s) {			p1 = _handleQuotes (p1);			p1 = 'url('+_relativeURI(base, p1);			return p1;		  }		);		// the CSS is ready...	    styleElement.type = "text/css";	    if (typeof(styleElement.styleSheet)=="object") {	      styleElement.styleSheet.cssText = cssCode;	    } else {	      styleElement.appendChild(document.createTextNode(cssCode));	    }	    try{	      document.getElementsByTagName("head")[0].appendChild(styleElement);	    }catch(e){		  throw new		    Error ("Dispacher: CSS Processing Error ("+e+")");		  return false;	    }	    return true;	};
		
	/**	* Analyze the uri before start the downloading process (if the uri isn't in over the current domain name, the dispatcher can use a proxy)	* @public	* @param {String} uri     	  Remote URL	* @param {Object} config      Used to pass the user configuration thru the chain of execution	* @param {Boolean} monolitic  Do not use proxy	* @return String	*/	obj.firewall = function( uri, config, monolitic ) {		var sDomain = null,			sProtocol = null,			m = null;		// AJAX url don´t work with &amp;		while (uri.indexOf ( '&amp;' ) > -1) {		    uri = uri.replace ( '&amp;', '&' );		}		// defining the proxy for cross-domain scripting...		config.proxy = config.proxy || constants.proxy;		if (typeof(config.firewall)=="function") {		  // external verification only...		  uri = config.firewall.apply ( config, [uri] );		} else {			// internal verification only...			// monolithic execution discard the cross-domain capabilities			if (!config.monolithic && !monolitic && config.proxy) {				m = uri.match(reURI); // checking the RE to verify if the url is external...				if (m && (m[2] !== document.domain)) {					// the uri is external, escaping especial chars and use a proxy					uri = config.proxy + escape(uri);				}			}		}		return uri;	};
				/**	* * Fetching a remote javascript file that will be processed thru this object...	* @public	* @param {object} uri       Remote js file that will be loaded using AJAX	* @param {object} config    Literal object with the user configuration vars	* @return string  ID reference to the new dispatcher's thread	*/	obj.jsLoader = function( uri, config ){
		//alert("jsLoader");	   if ($L.isString(uri) && (uri !== '')) {	   	 config = config || {};		 $E.generateId ( config ); // generating an unique ID for the thread (config.id)		 obj.kill (config.id);	   	 // add a remote script to buffer 	     _threads[config.id].chunks = [{			src: uri,			content: '',			type: constants.JSNODE,			params: {href: uri}		 }];		 config.underground = true;		 _onStart(config);		 dispatch (config.id, config); // starting the execution chain		 return config.id;	   }	   return null;	};
		/**	* * Fetching a remote CSS file that will be processed thru this object...	* @public	* @param {object} uri       Remote CSS file that will be loaded using AJAX	* @param {object} config    Literal object with the user configuration vars	* @return string  ID reference to the new dispatcher's thread	*/	obj.cssLoader = function( uri, config ){	   if ($L.isString(uri) && (uri !== '')) {	   	 config = config || {};		 $E.generateId ( config ); // generating an unique ID for the thread (config.id)		 obj.kill (config.id);	   	 // add a remote script to buffer	     _threads[config.id].chunks = [{			src: uri,			content: '',			type: constants.CSSNODE,			params: {href: uri}		 }];		 config.underground = true;		 _onStart(config);		 dispatch (config.id, config); // starting the execution chain		 return config.id;	   }	   return null;	};
	
	/**	* * Verify if the a process is still alive	* @public	* @param {object} hd   Process handle	* @return boolean	*/	obj.isAlive = function ( hd ) {		return (hd && (_threads[hd].chunks.length > 0) );	};

