/*
	libXmlRequest
	Source: org.cote.js.xml
	Copyright 2002 - 2009. All Rights Reserved.
	Version: SPEC-2.0.1.0226.2009
	Author: Stephen W. Cote
	Email: sw.cote@gmail.com
	Project: http://www.whitefrost.com/projects/engine/
	License: http://www.whitefrost.com/projects/engine/code/engine.license.txt
*/

/*
	REMARKS

		The org, org.cote, and org.cote.js defs are a literal translation from the Engine project.
		The structure is left intact for compatibility.
	
		The package structure is considered part of the branding and copyright; do not alter it.


	BROWSER SUPPORT
		
		Mozilla-based browsers (eg: Mozilla, Firebird, NS 7)
			XSL and XPath supported as of 1.2

		Internet Explorer 5.01 and later
			MSXML Support is defined as MSXML2.XMLHTTP.3.0

		Safari 1.0.3: XMLHttpRequest, no XPath, no XSL

		Opera 8: XMLHttpRequest, no XPath, no XSL

		Konqueror: No / unknown

	SERVER SUPPORT NOTE
	
		Some Application Servers such as Perl and PhP expect XML Posts to be set with a specific content type.
		The default encoding for version SPEC-1.5.1.0909.2005 is "text/xml".
		It may be necessary to specify "application/x-www-form-urlencoded" or "multipart/form-data" for posted XML data to be interpreted on the server.

	USAGE
	
		Synchronous GET:
			[xml_dom_object] = getXml(path);

			Example:
			var oXml = org.cote.js.xml.getXml("/Data/Test1.xml");

		Asynchronous GET:
			[int] = getXml(path,custom_handler,1,{optional_id});

			Example:
			function HandleXml(s,v){
				var oXml = v.xdom;
			}
			org.cote.js.xml.getXml("/Data/Test1.xml",HandleXml,1);
			
		Cached Asynchronous GET:
			[int] = getXml(path,custom_handler,1,request_id,1);
			
			Example:
			function HandleXml(s,v){
				var oXml = v.xdom;
			}
			org.cote.js.xml.getXml("/Data/Test1.xml",HandleXml,1,"cache-me",1);
			
		Synchronous POST:
			[xml_dom_object] = postXml(path,data);
			
			Example:
			
			var oPostThis = org.cote.js.xml.newXmlDocument("Request");
			var oData = oPostThis.createElement("data");
			oData.setAttribute("id","data-id");
			oData.setAttribute("value","data-value");
			oPostThis.documentElement.appendChild(oData);
			
			var oResponseXml = org.cote.js.xml.postXml("/Data/TestData.aspx",oPostThis);
			
		Asynchronous POST:
			[int] = postXml(path,data,custom_handler,1,{optional_id});
			
			Example:
			
			
			function HandleXml(s,v){
				var oResponseXml = v.xdom;
			}
			var oPostThis = org.cote.js.xml.newXmlDocument("Request");
			var oResponseXml = org.cote.js.xml.postXml("/Data/TestData.aspx",oPostThis,HandlePostXml,1);
			

		Notes:
			custom_handler, required for asynchronous requests, is invoked with two parameters:
			"onloadxml", and a generic object.  The object includes two properties:
			object.id is the request id, and object.xdom refers to the XML DOM.
			If the request fails, object.xdom will be null.
			
	INTERNAL NOTES
		
		The spec for XMLHttpRequest specifies that all handlers are cleared after each request.
		Therefore, the internal handlers are cleared after each request.  If not, they don't fire on subsequent requests.

	BUGS and BUG FIXES
		02/26/2009 : Update raw text handling
			Add better raw text handling for JSON support.  Include a few JSON hooks for convenience.
			
        04/23/2008 : IE 7 Fix for native XMLHttpRequest via FileSystem
            Add a special case for IE 7 support of local filesystem requests via XMLHttpRequest
            The resolution was to degrade to a DOM Document load.
	
	    04/17/2007 : Merge
	        Merge corrections between different versions of library.
	        Investigate issue with Mozilla posting on Vista to IIS 7

		11/15/2005 : Typo
			Fixed typo for asynchronous non-cached non-IE requests.

		10/10/2005 : Safari bug fixes
			Add corrections for Safari request header and creating new XML documents

		09/09/2005 : clearCache wasn't actually clearing the cache.		
			Some method cleanup required.
			
			The internal event handler, and therefore any custom event handler, for asynchronous calls that fail due to exceeding the pool size, was not being called.  This has been fixed.
			
		09/08/2005 : Improve support
			Improved support for Opera and Safari.

		06/17/2003 : Race condition occurs in multiple requests using the same request id
			Status: fixed
			
			XML Requests are stored in an array so as to keep track of the request for asynchronous and synchronous actions.
			A property on a request item is used for caching, if caching is enabled.

			Whether caching is enabled or the request is synchronous or asynchronous,
			a race condition ensues if multiple requests are made at the same time, with the same id.
			The bug is the first request is incomplete, and subsequent requests fail in cache request,
			or fail in the internal request handler.
			
			The solution was to tack on a unique back-up id if the same-id request is incomplete.
			This results in two requests for the same XML file, but the result is returned with the original request id.
			If caching is enabled, then the cache return the same-id request once the first request is finished.

			This was originally fixed only for cached, synchronous requests, but then expanded to included all requests.

		05/30/2003 : Event handler problem in Mozilla 1.4RC1
			Status: fixed; duplicate clean-up still open

			Latest Mozilla build, 1.4RC1 won't use the same event listener for the same object.
			Solution: add event listener at the time of the request, then strip it off later.
			
			This will also clean up the duplicate code for adding event listeners for pooled and non-pooled objects, which is pretty much the same.

		05/08/2003 : Event handler problem in IE
			Status: fixed; refer race-condition fix
			
			The IE sync bug cropped up again outside of the cached http feature.
			If the feature is turned off, it seems the requests can get
			stacked up (see Engine Demo #10 in IE), and cause the browser to hang
			or fail (see Moz) to completely load the XML.
			
			Multiple requests seem to be ok, up to an undetermined point.
			
			The feature should be left intact for heavy use anyway, but it is crucial to
			note because it then becomes a requirement for heavy use.

		12/28/2002
			Status: fixed
			
			Fixed bug in returnXmlHttpObjectToPool; this was causing a monster headache!



pseudo code for selectSingleNode / selectNodes

window.selectNodes = function (d,v,c){
  var elName = v.replace(/[^\w].*$/,'');
  elName = d.getElementsByTagName(elName);
  var attrToMatch = v.replace(/^.*@/,'').replace(/\s*=.*$/,'');
  var valToMatch = v.replace(/^[^']*'/,'').replace(/'.*$/,'');
  for(var i=0;elName[i];i++){if(elName[i].getAttribute(attrToMatch)==valToMatch){return [elName[i]];}}
  return [];
}
*/

var org = {};
org.cote = {};
org.cote.js = {};

org.cote.js.xml={
	object_version:"SPEC-1.9.13.0427.2008",
	xml_content_type:"text/xml",
	text_content_type:"text/plain",
	counter:0,
	_xml_requests:[],
	_xml_requests_map:[],

	ax_http_control:"MSXML2.XMLHTTP.4.0",
	ax_dom_control:"MSXML.DOMDocument",
	gadget_mode:0,
	gadget_xml_control:"Core.Gadget.GadgetXmlHttp",
	gadget_base_path:0,
	base_path:0,
	_xml_http_cache_enabled:1,
	setCacheEnabled:function(b){
		org.cote.js.xml.clearCache();
		org.cote.js.xml._xml_http_cache_enabled = b;
	},
	getCacheEnabled:function(){
		return org.cote.js.xml._xml_http_cache_enabled;
	},

	_xml_namespace_resolver:[
		["soapenc","http://schemas.xmlsoap.org/soap/encoding/"],
		["wsdl","http://schemas.xmlsoap.org/wsdl/"],
		["soap","http://schemas.xmlsoap.org/wsdl/soap/"],
		["SOAP-ENV","http://schemas.xmlsoap.org/soap/envelope/"]
	],
	_xml_namespace_url:{},
	_xml_namespace_uri:{},
	_xml_namespace_hashed:0,

	_xml_http_objects:[],
	_xml_http_object_use:0,
	_xml_http_object_count:0,
	_xml_http_object_pool_size:5,
	_xml_http_object_pool_max:10,
	
	/* notate whether the pool was created */
	_xml_http_pool_created:0,

	/* notate whether the pool was created */
	_xml_http_pool_enabled:1,

	/* static class init - used to add in message subscriptions on demand */
	si:0,
	setPoolEnabled:function(b){
		org.cote.js.xml._xml_http_pool_enabled = b;
	},
	getPoolEnabled:function(){
		return org.cote.js.xml._xml_http_pool_enabled;
	},
	newXmlDocument:function(n){
		/*
			n = required "root node" name;
		*/
		
		var r = 0,e;
		if(!n) return 0;
		if(typeof document.implementation != "undefined" && typeof document.implementation.createDocument != "undefined"){
			r = document.implementation.createDocument("",n,null);
			/* Safari bug */
			if(r != null && r.documentElement == null){
				r.appendChild(r.createElement(n));
			}
		}
		else if(typeof ActiveXObject != "undefined"){
			r = new ActiveXObject(org.cote.js.xml.ax_dom_control);
			e = r.createElement(n);
			r.appendChild(e);
		}
		else{
		    /// ...
		}
		return r;
	},

	clear:function(){
		var _x = org.cote.js.xml;

		_x.clearCache();
		_x.resetXmlHttpObjectPool();
		
		_x._xml_requests = [];
		_xml_requests_map = [];
		
		return 1;

	},

	
	/*
		2005/09/09 - better clear out the cached ids and arrays as well as nullifying the object pointers
	*/
	clearCache:function(){
		var _x = org.cote.js.xml,i = 0,o;
		for(;i<_x._xml_requests.length;i++){
			o = _x._xml_requests[i];
			if(o.c && typeof o.cd == "object"){
				o.cd = 0;
			}
			o.obj = null;
			o.ih = null;
			o.h = null;
		}
		_x._xml_requests = [];
		_x._xml_requests_map = [];
	},
	
	getXmlHttpArray:function(){
		return org.cote.js.xml._xml_http_objects;
	},
	
	resetXmlHttpObjectPool:function(){
		var _x = org.cote.js.xml,i = 0,o;
		_x._xml_http_pool_created = 1;
		_x._xml_http_object_use=0;
		_x._xml_http_objects=[];
		_x._xml_http_object_count = _x._xml_http_object_pool_size;
		for(;i < _x._xml_http_object_pool_size; i++)
			o = _x._xml_http_objects[i] = _x.newXmlHttpObject(1,i);
		
	},
	
	testXmlHttpObject:function(){
		return org.cote.js.xml.newXmlHttpObject(null,null,1);
	},
	
	newXmlHttpObject:function(b,i,z){
		/*
			b = return a hash for use with pooling
			i = pool index value.  b must be true for i to be used
			z = used for testing object creation
		*/
		var o = null,v,f;
		if(typeof XMLHttpRequest != "undefined"){	
			o = new XMLHttpRequest();
			if(z) return 1;
		}
		else if(typeof ActiveXObject != "undefined"){
			try{
				o = new ActiveXObject(org.cote.js.xml.ax_http_control);
				if(z) return 1;
			}
			catch(e){
				alert("XMLError: " + (e.description?e.description:e.message));
			}
			if(z) return 0;
		}
		
		if(b && typeof i == "number"){
			v= {
				o:o,
				u:0,
/*				use_count:0,*/
				i:i,
				/* vid = variant id */
				v:-1,
				h:0
			};

			return v;
		}
		else{
	
			return o;
	
		}
	
	},
	
	returnXmlHttpObjectToPool:function(i,y){
		var _x = org.cote.js.xml,b=0,o,a;
		a = _x._xml_http_objects;

		if(typeof a[i] == "object"){
			o = a[i];
			if(o.i >= _x._xml_http_object_pool_size)
			{
				a[i] = 0;
			}
			

			try{
				if(!y){
					/* 2005/09/07 Fix for Opera 8 */
					/*
						Why bother checking the instance of?
						Either XMLHttpRequest is here and use it, or it's not so don't use it
					*/
					/*if(typeof XMLHttpRequest == "function" || (typeof XMLHttpRequest == "object" &&  o.xml_object instanceof XMLHttpRequest))*/
					/* 2005/09/08 Fix for Safari */
					if(typeof XMLHttpRequest != "undefined"){
						if(typeof o.o.removeEventListener == "function")
							o.o.removeEventListener("load",o.h,false);
						else
							o.o.onreadystatechange = _x._stub;
					}
					else if(typeof ActiveXObject != "undefined" &&  o.o instanceof ActiveXObject)
						o.o.onreadystatechange=_x._stub;
					
					o.h = 0;
				}
			}
			catch(e){
				alert("Error in returnXmlHttpObjectToPool: " + (e.description?e.description:e.message));
			}		

			o.o.abort();
			o.u = 0;
			o.v = -1;


/*
				if(typeof ActiveXObject != "undefined" && o.o instanceof ActiveXObject)
					o.o.onreadystatechange = o.h;
*/				
			_x._xml_http_object_use--;
		}
		
		else{
			alert("Invalid pool id '" + i + "'");
		}
		
		return 1;
	},
	
	getXmlHttpObjectFromPool:function(y){
		var _x = org.cote.js.xml,i = 0,b=0,o,a,n=-1,z = 0;

		if(!_x._xml_http_pool_created) _x.resetXmlHttpObjectPool();
		a = _x._xml_http_objects;
		for(;i<a.length;i++){
			if(typeof a[i] == "object" && typeof a[i].u == "number" && !a[i].u){
				a[i].u = 1;
				b = i;
				/* yes, we indeed got a good mark */
				z = 1;
				break;
			}
			/* mark the next known null marker for re-use*/
			if(n == -1 && !a[i])
				n = i;
			
		}

		if(!z){
			b = (n > -1)?n:a.length;
			if(b < _x._xml_http_object_pool_max){
				a[b] = _x.newXmlHttpObject(1,b);
				a[b].u = 1;
			}
			else{
				return null;
			}
		}

		if(b > -1){
			_x._xml_http_object_use++;
			o = a[b];
			try{
				if(!y){

					/* 2005/09/07 Fix for Opera 8 */
					/*
						Why bother checking the instance of?
						Either XMLHttpRequest is here and use it, or it's not so don't use it
					*/
					
					/*if(typeof XMLHttpRequest == "function" || (typeof XMLHttpRequest == "object" &&  o.xml_object instanceof XMLHttpRequest)){*/
					/* 2005/09/08 Fix for Safari */
					if(typeof XMLHttpRequest != "undefined"){
						if(typeof o.o.addEventListener == "function"){
							o.h = function(){org.cote.js.xml._handle_xml_request_load(b);};
							o.o.addEventListener("load",o.h,false);
						}
						else{
							o.h = function(){org.cote.js.xml._handle_xml_request_readystatechange(b);};
							o.o.onreadystatechange = o.h;
						}
					}
					else if(typeof ActiveXObject != "undefined" &&  o.o instanceof ActiveXObject){
						o.h = function(){org.cote.js.xml._handle_xml_request_readystatechange(b);};
						/*
							Can't attach an event to this object with attachEvent
						*/
						o.o.onreadystatechange=o.h;
					}
				}
			}
			catch(e){
				alert("Error in getXmlHttpObjectFromPool: " + (e.description?e.description:e.message));
			}		

			return o;
		}
		
		return null;

	},
	
	
	_handle_xml_request_load:function(i){
		/*
			i = xml id
		*/
		var _x=org.cote.js.xml,o,v,z;
		try{
		
		
			if(_x._xml_http_pool_enabled && typeof _x._xml_http_objects[i] == "object"){
				z = _x._xml_http_objects[i].v;
				if(z == -1){
					alert("Invalid pool index for " + i);
					return 0;
				}
				i = z;
			}
		
		    
			if(typeof _x._xml_requests_map[i] == "number"){
				o = _x._xml_requests[_x._xml_requests_map[i]];
				
				v = {text:null, xdom:null, json:null, id:(o.bi?o.bi:i)};
				
				
				if(
					o.u.match(/^file:/i)
					&&
					typeof ActiveXObject == "function"
					&&
					o.o instanceof ActiveXObject
				){
					var mp = new ActiveXObject(_x.ax_dom_control);
					mp.loadXML(o.o.responseText);
					v.xdom = mp;
				} else  if(o.o != null && (o.t || o.o.responseXML != null)){
					if(o.t){
						v.text = o.o.responseText;
						if(o.t == 2 && typeof JSON != "undefined"){
							try{
								v.json = JSON.parse(v.text,_x.JSONReviver);
							}
							catch(e){
								v.json = null;
								v.error = e.message;
							}
						}
					}
					else v.xdom = o.o.responseXML;
				}
				else if(o.o != null)
					alert("Error loading '" + o.u + "'. Response text is: " + o.o.responseText);
				
				else
					alert("Error loading '" + o.u + "'. The internal XML object reference is null.  Async is " + o.a + "; Pool Index is " + o.pi);
				
	
				o.r = 1;
			
				if(o.ih){
					o.ih = 0;
				}
				
				
				if(_x._xml_http_cache_enabled && o.c){
					o.cd = v.xdom;
				}
				
				
				if(typeof o.h=="function") o.h("onloadxml",v);
	
				/*
					clear out the request object
				*/
				
				if(o.pi > -1)
					_x.returnXmlHttpObjectToPool(o.pi,!o.a);
				
				
				o.o = 0;
	
			}
			else{
				alert("Invalid id reference: " + i,"200.4");
			}

		}
		catch(e){
			alert("Error in handle_xml_request_load: " + (e.description?e.description:e.message));
		}
	},

	_handle_xml_request_readystatechange:function(i){
		var _x=org.cote.js.xml,o;

		/*
			Slightly different behavior for pooled requests and non-pooled requests.
			
			Ultimately, the issue IE won't detach the onreadystate event handler, so the index into the pool is passed
			instead of the unique request id.  This should actually be better anyway as it removes the need to constantly 
			attach and detach event handlers on the pooled objects.
		*/
		
		if(_x._xml_http_pool_enabled && typeof _x._xml_http_objects[i] == "object"){
			o = _x._xml_http_objects[i];
			if(o != null && typeof o.o == "object" && o.o.readyState == 4){
				_x._handle_xml_request_load(i);
			}
		}
		else  if(typeof _x._xml_requests_map[i] == "number"){
			o = _x._xml_requests[_x._xml_requests_map[i]];
			if(typeof o.o == "object" && o.o.readyState == 4){

				_x._handle_xml_request_load(i);
			}
		}
	},
	/*
		getXml(path,handler,async,id,caching);
		
		id is optional.  Use this where two or more xml transactions will be directed
		through the same handler.
		
	*/


	getJSON:function(p,h,a,i,c){
	/*
			p = path
			h = handler
			a = async
			i = id
			c = cached
	*/
		return org.cote.js.xml._request_xmlhttp(p,h,a,i,0,null,c,2);
	},
	getText:function(p,h,a,i,c){
	/*
			p = path
			h = handler
			a = async
			i = id
			c = cached
	*/
		return org.cote.js.xml._request_xmlhttp(p,h,a,i,0,null,c,1);
	},
	
	getXml:function(p,h,a,i,c){
	/*
			p = path
			h = handler
			a = async
			i = id
			c = cached
	*/
		return org.cote.js.xml._request_xmlhttp(p,h,a,i,0,null,c);
	},
	
	postJSON:function(p,d,h,a,i){
		/*
			Caching is not provided for the postXml wrapper.
		*/
		if(typeof JSON == "undefined"){
			alert("Missing JSON interpreter");
			return 0;
		}
		return org.cote.js.xml._request_xmlhttp(p,h,a,i,1,JSON.stringify(d),0,2);
	},	
	postText:function(p,d,h,a,i){
		/*
			Caching is not provided for the postXml wrapper.
		*/
		return org.cote.js.xml._request_xmlhttp(p,h,a,i,1,d,0,1);
	},
	postXml:function(p,d,h,a,i){
		/*
			Caching is not provided for the postXml wrapper.
		*/
		return org.cote.js.xml._request_xmlhttp(p,h,a,i,1,d,0);
	},
	/*
		_request_xml is asynchronous.
	*/
	///
	_request_xmlhttp:function(p,h,a,i,x,d,c,t){
		/*
			p = path
			h = handler
			a = async
			i = id
			x = is_post as bool
			d = data as string or DomDocument
			
			r = pool/new x obj
			b = bool
			
			c = cache result
			
			t = treat response only as text.  1 == text, 2 == json
		*/
		
		var _x=org.cote.js.xml,f,o=null,v,y,z,r,b,b_ia,g,bi=0;
		
		if(!_x.si) _x.StaticInitialize();

		if(typeof p != "string" || p.length == 0){
			alert("Invalid path parameter in _request_xmlhttp");
			return 0;
		}
		
		if(typeof c=="undefined") c = 0;
		if(typeof x=="undefined") x = 0;
		if(typeof d=="undefined") d = null;

		z = (x?"POST":"GET");
		if(typeof i!="string") i="swc-" + (++_x.counter) + "-" + parseInt(Math.random()*10000);

		/* check for a cached instance */
		if(
			_x._xml_http_cache_enabled
			&&
			typeof _x._xml_requests_map[i] == "number"
			&&
			/// typeof _x._xml_requests[_x._xml_requests_map[i]] == "object"
			( r = _x._xml_requests[_x._xml_requests_map[i]] )
		){
			/// r = _x._xml_requests[_x._xml_requests_map[i]];
			
			if(r.c){
				if(!t && typeof r.cd == "object")
					b = {xdom:r.cd, id:i};
				else if(t && typeof r.ct == "object"){
					b = {text:r.ct, id:i};
					if(t == 2 && typeof JSON != "undefined")
						b.json = JSON.parse(r.ct,_x.JSONReviver);	
					
				}
				if(b){
					if(typeof h == "function") h("onloadxml",b);
					
					return r.cd;
				}
			}
			
			/*
				Race condition for an XML document with a specific id,
				that hasn't finished loading
				
				If there is a request, and that request isn't complete,
				then cook up a backup-request id and disable caching
			*/
			/*
				06/17/2003
					Removed '!r.a && ' check for sync only requests
					Removed 'r.c' check for caching
			*/
			 else  if(!r.r){
				/* force disable caching for this request */
				c = 0;
				/* backup the id */
				bi = i;
				/* create a random id */
				i = "swc-" + (++_x.counter) + "-" + parseInt(Math.random()*10000);
			
			}
		}

		
		/* get a new XML object, or a pooled object depending on the settings */
		
		b = _x._xml_http_pool_enabled;
		if(_x.gadget_mode){
			a = 0;
			b = 0;
			p = _x.gadget_base_path + p;
			r = new ActiveXObject(_x.gadget_xml_control);
		}
		else if(b){
			
			{
			
			r = _x.getXmlHttpObjectFromPool(!a);

			}
			
		}
		else{
		
			r = _x.newXmlHttpObject();
		
		}
		
		/*
			Unable to obtain an XML object, so bail out.
		*/
		if(!(b ? (r && r.o) : r ) ){

			/* 2005/09/09 - raise the handler for async requests */
			b = {text:null, xdom:null, error:"Null XML object in _request_xmlhttp", id:i};
			/// alert(b.error);
			if(typeof h == "function") h("onloadxml",b);

			return 0;
		}

		/* update the pool id reference, if pooling is enabled */
		
		if(b) r.v = i;
		
		/// Create a new internal object representing the xml request 
		///
		y = _x._xml_requests.length;

		_x._xml_requests[y] = {
			u:p,
			i:i,
			bi:bi,
			a:a,
			o:(b?r.o:r),
			ih:0,
			h:h,
			pi:(b?r.i:-1),
			c:c,
			cd:0,
			r:0,
			t:t
		};
		
		/// Map the object to the id
		///
		_x._xml_requests_map[i]=y;
		o = _x._xml_requests[y].o;

		/// Massage the path reference
		///
		if(!p.match(/:\/\//)){
			var m,e=new RegExp("^/");
			if(!p.match(e)){
				if(_x.base_path){
					p = _x.base_path + p;
				}
				else{
					m=location.pathname;
					if(m.match(/\\/)) m = m.replace(/\\/g,"/");
					m=m.substring(0,m.lastIndexOf("/")+1);
					p=m + p;
				}
			}

			if(!location.protocol.match(/^file:$/i))
				p=location.protocol + "//" + location.host + p;
			
			else
				p = location.protocol + "//" + p;
		}

		_x._xml_requests[y].u = p;

		/*
			Add event handlers based on instance of XML object
			
			Must check for typeof object before instanceof or IE will bomb out.
			
			Check for:
				a) this is not a pooled request; pooled requests use index->id maps
				b) this as an async request
				c) the type of request object
		*/
		b_ia = (typeof ActiveXObject != "undefined" &&  o instanceof ActiveXObject)?1:0;
		
		/// 2008/04/24
		/// Fix for IE 7 file system support
		/// The native XMLHttpRequest support is reported as an ActiveX instance
		/// Treat this filesystem request as a cache request
		/// Include a check to allow IE 6 through, since it works just fine
		///
		
		if(b_ia && typeof XMLHttpRequest != "undefined" && p.match(/^file/i)){
		        _x.returnXmlHttpObjectToPool(_x._xml_requests[y].pi,!a);
		        o = new ActiveXObject(org.cote.js.xml.ax_dom_control);
		        /// Restore any backup id
		        ///
		        if(bi) i = bi;
				o.load(p);
				b = {xdom:o, id:i};
				if(typeof h == "function") h("onloadxml",b);
				return o;
		}
		
		try{
			/*
				05/30/2003
				Remove check for async only because non-pooled async requests should also go through the load listener.
			*/
			/*if(!b && typeof XMLHttpRequest != "undefined" && o instanceof XMLHttpRequest){*/
			/*if(!b && a && (typeof XMLHttpRequest == "function" || (typeof XMLHttpRequest == "object" && o instanceof XMLHttpRequest))){*/

			if(!b &&  a && typeof XMLHttpRequest != "undefined"){
				if(typeof o.addEventListener == "function"){
					_x._xml_requests[y].ih = function(){org.cote.js.xml._handle_xml_request_load(i);};
					o.addEventListener("load",_x._xml_requests[y].ih,false);
				}
				else{
					_x._xml_requests[y].ih = function(){org.cote.js.xml._handle_xml_request_readystatechange(i);};
					o.onreadystatechange=_x._xml_requests[y].ih;
				}
			}

			else if(!b && a && b_ia){
				_x._xml_requests[y].ih = function(){org.cote.js.xml._handle_xml_request_readystatechange(i);};
				/*
					Can't attach an event to this object with attachEvent
				*/
				o.onreadystatechange=_x._xml_requests[y].ih;
			}
		}
		catch(e){
			alert("Error in _request_xmlhttp: " + (e.description?e.description:e.message));
		}		

		
		/*
			There is a problem with the ActiveXObject not liking the multiple levels of object references,
			particularly the embedded array reference into the http_objects array used for pooling.
			The good news is this only seems to apply to syncronous requests, and only for ActiveXObjects.
			The bad news is fixing the problem requires the following:
				- change the onreadystatechange handler to point elsewhere.  Since this can't be null, its pointed at an empty stub function.
				- set the array reference for http_objects to null.
			At this point, those referencers are:
		*/
		
		if(b && !a){
/*			if(b_ia) o.onreadystatechange = _x._stub;*/
			_x._xml_http_objects[_x._xml_requests[y].pi] = 0;
		}
		
		
		g = (a?true:false);
		o.open(z,p,g);

		/// If supported, include the outgoing content type
		///
		if (typeof o.setRequestHeader != "undefined") {
			o.setRequestHeader("Content-Type", (t ? _x.text_content_type : _x.xml_content_type ));
			/*
			if(x){
			    if(typeof d == "object") o.setRequestHeader("Content-Length", org.cote.js.xml.serialize(d).length);
            }
            */
		}
		o.send(d);
		if(!a){
			/*
				Don't use the reference in the requests array here because it loses context when he open and send methods are invoked.
				Instead, since this is synchronous, just use 'o'
				
				This is symptomatic of the IE problem mentioned above, but the root cause seems to be
				the manner in which the ActiveXObject is stored in the array.
				
				The issue manifests as querying responseXML throws an error, or undefined and the object references get out of sync.
				This can be tested by comparing o == _x._xml_requests[y].obj
				
				With the IE fix in place, the test is true.
				Mozilla is false, but that isn't an issue (right now) because the response can still be obtained.
			*/

			z = (t ? o.responseText : o.responseXML);

			
			if(
				!t
				&&
				p.match(/^file:/i)
				&&
				b_ia
			){
				var mp = new ActiveXObject(org.cote.js.xml.ax_dom_control);
				mp.loadXML(o.responseText);
				z = mp;

			}
			
			
			/*
				Now that the request has been made, time for part 2 of the IE Synchronous problem.
				Reset the pool object (where the o property contains the XMLHTTPRequest object) to the array.
				Also, manually invoke the _handle_xml_request_load method
			*/
			
			if(b){
				/*&& b_ia*/
				_x._xml_http_objects[_x._xml_requests[y].pi] = r;
				_x._handle_xml_request_load(_x._xml_requests[y].pi);
			}
			else{
			
				 _x._handle_xml_request_load(i);
							
			
			}			
			
			
			_x._xml_requests[y].o = null;
			
			if(!b && _x._xml_requests[y].pi > -1)
				_x.returnXmlHttpObjectToPool(_x._xml_requests[y].pi,!a);
			
			
			return z;
		}
		return 1;
	},

	transformNode:function(x, s, n, i, j, p){
		/*
			x = xml document
			s = xsl document
			n = optional node reference
			i = optional id for requesting XML
			j = optional id for requesting XSL
			p = optional cache bit for requesting XSL
		*/

		var xp, o = null,_x = org.cote.js.xml,v,a,b,c,d;

		if(typeof x == "string" && x.length > 0){
			if(p && !i) p =0;
			v = x;
			x = _x.getXml(x,0,0,i,p);

			if(v.match(/\?(\S*)$/)){
				v = v.match(/\?(\S*)/)[1];
				a = v.split("&");
				for(b=0;b<a.length;b++){
					c = a[b].split("=");
					x.documentElement.setAttribute(c[0],c[1]);
				}
			}
		}

		if(typeof s == "string" && s.length > 0){
			if(p && !j) p =0;
			s = _x.getXml(s,0,0,j,p);
		}
		
		if(typeof x != "object" || x == null || typeof s != "object" || s == null){
			alert("Invalid parameters in transformNode. Xml Node = " + x + ", xsl document = " + s);
			return o;
		}

		if(typeof n != "object") n = x;

		try{
			if(typeof XSLTProcessor != "undefined"){
				xp = new XSLTProcessor();
				xp.importStylesheet(s);
				o = xp.transformToFragment(n,document);
				if(o) o = o.firstChild;
			}
	
			else if(typeof ActiveXObject != "undefined" && x instanceof ActiveXObject){
				o = new ActiveXObject(org.cote.js.xml.ax_dom_control);
				xp = n.transformNode(s);
				o.loadXML(xp);
				o = o.documentElement;
			}
			else{
				alert("Error in transformNode: " + (e.description?e.description:e.message));
			}
		}
		catch(e){
			alert("Error in transformNode: " + (e.description?e.description:e.message));
		}
		
		return o;

	},
	HashNamespaces:function(){
		var _x = org.cote.js.xml,a,i=0,o;
		_x._xml_namespace_uri = {};
		_x._xml_namespace_url = {};
		for(;i< _x._xml_namespace_resolver.length;i++){
			o = _x._xml_namespace_resolver[i];
			_x._xml_namespace_uri[o[0]]=o[1];
			_x._xml_namespace_url[o[1]]=o[0];
		}
		_x._xml_namespace_hashed=1;
	},
	getURIForURL:function(u){
		var _x = org.cote.js.xml,q;
		if(!_x._xml_namespace_hashed) _x.HashNamespaces();
		q = _x._xml_namespace_url[u];
		return (q?q:"");
	},
	getURLForURI:function(i){
		var _x = org.cote.js.xml,q;
		if(!_x._xml_namespace_hashed) _x.HashNamespaces();
		q = _x._xml_namespace_uri[i];
		return (q?q:"");
	},

	lookupNamespaceURI:function(n){
		var _x = org.cote.js.xml;
		if(!_x._xml_namespace_hashed) _x.HashNamespaces();
		if(_x._xml_namespace_uri[n])
			
			{
			return _x._xml_namespace_uri[n];
			
			}
			else{
				// alert("Could not resolve '" + n + "'");
			}

		return "";
	},
	
	selectSingleNode:function(d,x,c){
		/*
			d = XmlDocument
			x = xpath
			c = context node
		*/
		var s,i,n;
		if(typeof d.evaluate != "undefined"){
			c = (c ? c : d.documentElement);
			s = d.evaluate(x,c,org.cote.js.xml,0,null);

			return s.iterateNext();
		}
		else if(typeof d.selectNodes != "undefined"){
			return (c ? c : d).selectSingleNode(x);
		}

		return 0;
	
	},
	
	selectNodes:function(d,x,c){
		/*
			d = XmlDocument
			x = xpath
			c = context node
		*/
		var s,a = [],i,n;
		if(typeof d.evaluate != "undefined"){
			c = (c ? c : d.documentElement);
			s = d.evaluate(x,c,org.cote.js.xml,0,null);

			n = s.iterateNext();

			while( typeof n == "object" && n != null){
				a[a.length] = n;
				n = s.iterateNext();
			}

			return a;

		}

		else if(typeof d.selectNodes != "undefined"){
			return (c ? c : d).selectNodes(x);
		}

		return a;
	
	},

	/*
		queryNode is useful for light DOM queries when
		XPath is not available, or when querying against an HTML
		DOM for nodes with specific attribute values.
	*/
	
	queryNodes:function(x,p,n,a,v){
		return org.cote.js.xml._queryNode(x,p,n,a,v,1);
	},
	
	queryNode:function(x,p,n,a,v){
		return org.cote.js.xml._queryNode(x,p,n,a,v,0);
	},
	_queryNode:function(x,p,n,a,v,z){
		/*
			 x = xdom
			 p = parent path
			 n = node path
			 a = attribute name
			 v = attribute value
			 
			 z = node or nodes
		*/

		var i=0,b,e,c,r=[];
		if(!z) r = null;
		
		c = x.getElementsByTagName(p);
		
		if(typeof n=="string"){

			if(!c.length){
				if(!z) return null;
				else return r;
			}
			c = c[0]; 
			e = c.getElementsByTagName(n);
		}
		else e = c;

		
		for(;i<e.length;i++){
			b = e[i];
			if((!a && !v) || (b.getAttribute(a) == v)){
				/*
					single query
				*/
				if(!z){
					r = b;
					break;
				}

				else r[r.length]=b;
				
			}
		}
		return r;
	},
	
	serialize:function(n){
		var v;
		if(typeof XMLSerializer != "undefined"){
			return (new XMLSerializer()).serializeToString(n);
		}
		else if(typeof n.xml == "string"){
			return n.xml;
		}
	},
	
	getCDATAValue:function(n){
		var c,d="",i=0,e;

		if(n == null) return d;

		c = n.childNodes;
		for(;i<c.length;i++){
			e=c[i];
			if(e.nodeName=="#cdata-section") d+=e.nodeValue;
		}
		return d;
	},
	
	getInnerText:function(s){
		var r = "",a,i,e;
		if(typeof s == "string") return s;
		if(s == null) return r;
		if(typeof s== "object" && s.nodeType==3) return s.nodeValue;
		if(s.hasChildNodes()){
			a = s.childNodes;
			for(i=0;i<a.length;i++){
				e = a[i];
				if(e.nodeType==3 || e.nodeType == 4) r+=e.nodeValue;
				if(e.nodeType==1 && e.hasChildNodes()){
					r+=org.cote.js.xml.getInnerText(e);
				}
			}
		}
		return r;
	},
	
	removeChildren:function(o){
		var i;
		for(i=o.childNodes.length-1;i>=0;i--)
			o.removeChild(o.childNodes[i]);
		
	},
	
	
/// Prototype for Mozilla
	swapNode : function (n,c){
		if(!n || !c) return;
		if(typeof n.swapNode != "undefined") n.swapNode(c);
		else{
		    var s = n.nextSibling;
			var p = n.parentNode;
			p.replaceChild(n,c);
			p.insertBefore(c, s);
		}
	},
	
	setInnerXHTML:function(t,s,p,d,z,c,h,ch){
		/*
			t = target
			s = source
			p = preserve
			d = target document object
			z = no recursion
			
			c = preserve whitespace
			
			h = html refactor ; clone the node instead of creating the element and copy attributes
			
			
			
			r = return node reference
		*/
		var y,e,a,l,x,n,v,r = 0,b,f;
		
		/* typeof d == "undefined" */
		if(!d) d = document;
		
		b = (d == document?1:0);
		
		if(!p)
			org.cote.js.xml.removeChildren(t);
		

		y=(s && typeof s=="object")?s.nodeType :(typeof s=="string")?33:-1;
		switch(y){
			case 1:
				if(h){
					e = s.cloneNode(false);
				}
				else{
				    f = s.nodeName;
				    if(typeof ch == "function") f = ch(y,f);
				    if(!f) return 0;
					e=d.createElement(f);
					a=s.attributes;
					l=a.length;
					for(x=0;x<l;x++){
						n=a[x].nodeName;
						v=a[x].nodeValue;
    				    if(typeof ch == "function"){
    				        n = ch(2,n);
    				        v = ch(2,v);
    				    }
	
						/*
							Must check for d == document to make sure whether this is the HTML DOM or not, because
							these cases only apply to IE oddness in the HTML DOM, not the XML DOMs.
						*/
						/* stupid IE */
						if(b && n=="style"){
							e.style.cssText=v;
						}
						/* stupid IE */
						else if(b && n=="id"){
							e.id=v;
						}
	
						/* stupid IE */
						else if(b && n=="class"){
							e.className=v;
						}
	
						/* stupid IE */
						else if(b && n.match(/^on/i)){
							eval("e." + n + "=function(){" + v  +"}");
						}
						else{
							e.setAttribute(n,v);
						}
					}
				}
				if(!z && s.hasChildNodes()){
					a=s.childNodes;
					l=a.length;
					for(x=0;x<l;x++)
						org.cote.js.xml.setInnerXHTML(e,a[x],1,d,z,c,h,ch);
					
				}

				/* stupid IE */
				if(b && s.nodeName.match(/input/i) && s.getAttribute("checked")){
					e.checked=true;
				}

				t.appendChild(e);
				r = e;
				break;
			case 3:
				e=s.nodeValue;
    		    if(typeof ch == "function") e = ch(y,e);
				if(e){
					e=e.replace(/\s+/g," ");
					t.appendChild(d.createTextNode(e));
					r = e;
				}
				break;
			/* CDATA */
			case 4:
				e = s.nodeValue;
				if(typeof ch == "function") e = ch(y,e);
				t.appendChild(d.createCDATASection(e));
				break;
			case 8:
				/*
					Ignore comments
				*/
				break;
			case 33:
				e=s;
				if(typeof ch == "function") e = ch(y,e);
				if(e){
					if(!c){
						e=e.replace(/^\s*/,"");
						e=e.replace(/\s*$/,"");
						e=e.replace(/\s+/g," ");
					}
					t.appendChild(d.createTextNode(e));
					r = e;
				}
				break;
			default:
				
				break;
		}
		return r;
	},

	/* stub is used for swapping handlers on IE */	
	_stub:function(){
		/* do nothing */
	},
	
	StaticInitialize:function(){
		org.cote.js.xml.si = 1;
	},
	
	destroy:function(){
		
		var _x = org.cote.js.xml;
		_x.clearCache();
		_x._xml_requests = [];
		_xml_requests_map = [];	
		_x._xml_http_pool_created = 0;
		_x._xml_http_object_use = 0;
		_x._xml_http_objects=[];
	},

	/// JSONRevivor for date values
	///
	JSONReviver : function (k, v) {
		var a;
		if( typeof v == "string" && (a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(v)))
			return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4],+a[5], +a[6]));
		return v;
	}
};

