/**
 *	Inherit the methods of another class.  You may inherit from as many classes as you want
 *
 *	@param superClass The super class to inherit
 *	@param superClass2 The second class to inherit
 *		...
 *	@param superClassN The Nth class to inherit
 */
Object.prototype.inherit = function() {
	for (var x = 0; x < arguments.length; x++) {
		for (var meth in arguments[x].prototype) {
			if (this.prototype[meth] == undefined && meth.substr(0, 2) != "i_") {
				// Only inherit methods which are not already defined.
				this.prototype[meth] = arguments[x].prototype[meth];
			}
		}
	}
}


/*

	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ResourceManager %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

*/
	/**
	 *	ResourceManager
	 *	This class provides a way to import external resources into this document.  Using this class 
	 *	instead of just importing the files via html tags, gains the benefit of priority, and progress
	 *	tracking.
	 *
	 *	@constructor
	 */
	function ResourceManager() {
		// This class is mainly static, do not instantiate.
	}

	/**
	 *	The number of connections the ResourceManager is allowed to use
	 */
	ResourceManager.max_connections = 2;
	ResourceManager.top_priority = -1000;
	
	
	/**
	 *	The amount of time before a resource is considered timed out.
	 */
	ResourceManager.resource_timeout = 120000;
	
	/**
	 *	Whether cache is enabled (true), or cache is disabled on all files (false)
	 */
	ResourceManager.cache = true;
	
	/**
	 *	Whether to require strict javascript execution monitoring to ensure that all scripts have loaded
	 *	before their callbacks are executed.  This requires special code in all JS files.
	 */
	ResourceManager.strict_javascript = true;
	
	/**
	 *	An array of resource requests which need to be imported into the document
	 */
	ResourceManager.requests = Array();
	
	/**
	 *	An array of active requests
	 */
	ResourceManager.active_requests = Array();
	
	/**
	 *	The number of connections which the ResourceManager is currently using (do not change)
	 */
	ResourceManager.connections = 0;
	
	/**
	 *	The total number of resources which need to be imported before the request list will be empty
	 */
	ResourceManager.resources_remaining = 0;
	
	/**
	 *	Whether or not resources will be downloaded and imported 
	 */
	ResourceManager.i_enabled = false;
	
	/**
	 *	An array of listeners which need to be updated about the progress of resources
	 */
	ResourceManager.listeners = Array();
	
	/**
	 *	Whether timeouts are noticed by default
	 */
	ResourceManager.i_noticeTimeout = true;
	
	
	
	/**
	 *	Generate a random string to use for anti-cache
	 *
	 *	@param len (Optional) the length of the string you want, 10 is used by default
	 *
	 *	@return a string of random alpha numeric characters
	 */
	ResourceManager.randomString = function(len) {
		var str = "";
		len = (len == undefined ? 10 : len);
		
		var selection = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
		for (var x = 0; x < len; x++) {
			str+=selection.substr(Math.random() * selection.length, 1);
		}
		return str;
	}
	
	
	/**
	 *	Push a request object onto the main request list
	 *
	 *	@private
	 *
	 *	@param request The ResourceRequest object to push onto the main request list.
	 *
	 *	@return the object just pushed
	 */
	ResourceManager.push_request = function(request) {
		ResourceManager.requests[ResourceManager.requests.length] = request;
		ResourceManager.updateCounter(1);
		ResourceManager.pollConnections();
		return request;
	}
	
	/**
	 *	Get/Set if timeout messages should be used
	 *
	 *	@param state (Optional) True if timeout messages should be displayed, false otherwise
	 *
	 *	@return the current usage of timeout warnings
	 */
	ResourceManager.noticeTimeout = function(state) {
		if (state != undefined) {
			ResourceManager.i_noticeTimeout = state;
		}
		return ResourceManager.i_noticeTimeout;
	}
	
	
	/**
	 *	Get/Set the enabled state of hte resource manager.  No resources will be downloaded while the 
	 *	state is false.  This provides a good time to set any handlers, or progress bars before the 
	 *	script may give process priority to something else.
	 *
	 *	@param state (Optional) The state of whether resources will be downloaded
	 *
	 *	@return the current state of resource downloading
	 */
	ResourceManager.enabled = function(state) {
		if (state != undefined ){
			ResourceManager.i_enabled = state;
			ResourceManager.pollConnections();
		}
		return ResourceManager.i_enabled;
	}
	
	/**
	 *	Post a message to any resource listeners
	 *
	 *	@param resource The resource posting this message
	 *	@param message The message the resource is posting
	 */
	ResourceManager.postMessage = function(resource, message) {
		for (var x = 0; x < ResourceManager.listeners.length; x++) {
			if (!ResourceManager.listeners[x].done()) {
				ResourceManager.listeners[x].resource_post(resource, message);
			}
		}
	}
	
	/**
	 *	Increment/Decrement the resource request counter
	 *
	 *	@private
	 *
	 *	@param val The value to add to the resource counter
	 *	@param resource The resource that just completed (only needed for decrementing)
	 *
	 *	@return the current value of the resource counter
	 */
	ResourceManager.updateCounter = function(val, resource) {
		ResourceManager.resources_remaining+=val;
		if (val < 0) {
			for (var x = 0; x < ResourceManager.listeners.length; x++) {
				if (!ResourceManager.listeners[x].done()) {
					ResourceManager.listeners[x].resource_completed(resource);
				}
			}
		}
		return ResourceManager.resources_remaining;
	}
	
	/**
	 *	Get the next resource which should be downloaded.  The resource returned will be the 
	 *	resource with the largest priority
	 *
	 *	@private
	 *
	 *	@param removeNext Whether or not to remove the returned resource
	 *
	 *	@return a ResourceRequest object, or one of its sub classes
	 */
	ResourceManager.nextResource = function(removeNext) {
		var topPriority = -1000;
		var nextReq;
		for (var x = 0; x < ResourceManager.requests.length; x++) {
			if (ResourceManager.requests[x].priority() > topPriority) {
				nextReq = x;
				topPriority = ResourceManager.requests[x].priority();
			}
		}
		
		if (topPriority < ResourceManager.top_priority)
			return undefined;
		
		if (nextReq != undefined) {
                        ResourceManager.top_priority = topPriority;
			var req = ResourceManager.requests[nextReq];
			if (removeNext == true) {
				ResourceManager.requests.splice(nextReq, 1);
			}
			return req;
		}
		else {
			return undefined;
		}
	}
	
	/**
	 *	Check for free connections and fill them if possible
	 *
	 *	@private
	 *
	 *	@return true if the ResourceManager is enabled, false otherwise.
	 */
	ResourceManager.pollConnections = function() {
		if (ResourceManager.enabled() == true) {
			var free = (ResourceManager.max_connections - ResourceManager.connections);
			var nextReq = Array();
			
			while (ResourceManager.requests.length > 0 && free > 0) {
				var nextR = ResourceManager.nextResource(true);
				if (nextR != undefined) {
					nextReq[nextReq.length] = nextR;
					free--;
				}
				else {
					break;
				}
			}
			for (var x = 0; x < nextReq.length; x++) {
				nextReq[x].initiate();
			}
			
			return true;
		}
		return false;
	}
	
	
	/**
	 *	get a ResourceListener object which will be updated with the status of all resources currently in the 
	 *	request list.  Resources added after this call, will not be included in the updates.  
	 *
	 *	@return a ResourceListner object
	 */
	ResourceManager.getResourceListener = function() {
		var rl = new ResourceListener();
		ResourceManager.listeners[ResourceManager.listeners.length] = rl;
		return rl;
	}
	
	/**
	 *	Get a ResourceRequest sub class for a given resource URL
	 *
	 *	@private
	 *
	 *	@param p The parent of the new resource request
	 *	@param url The URL to the resource
	 *	@param callback The callback method to execute when this resouce finishes
	 *	@param post (Optional) A ResourcePost object to use as a form submission when requesting the resource
	 *	@param args (Optional) An array of arguments to pass down to the callback
	 *	@param priority The priority level for this resource
	 *	@param description the description of this resoruce (status message text)
	 *	@param extension (Optional) A string which contains the actual data file extension.  This can be used to
	 *				override the resource type for any given resource.  For example, if you had a 
	 *				cgi, which outputted javascript, you could override the cgi file type with 'js'
	 *
	 *	@return a variant of ResourceRequest
	 */
	ResourceManager.getResourceRequest = function(p, url, callback, post, args, priority, description, extension) {
		var resource;
		var ext = "";
		var query = false;
		var hasQuery = (url.indexOf('?') > 0 ? true : false);
		
		for (var x = url.length - 1; x >= 0; x--) {
			if (query == hasQuery) {
				if (url.charAt(x) == '.') {
					break;
				}
				ext = url.charAt(x) + ext;
			}
			if (url.charAt(x) == '?') {
				query = true;
			}
		}
		ext = ext.toLowerCase();
		
		if (extension != undefined) {
			ext = extension;
		}
		
		switch (ext) {
			
			// Images
				case 'gif': case 'jpg': case 'jpeg': case 'png': case 'bmp': case 'tiff': case 'psd':
				
					resource = new ImageResource(p, url, callback, post, args, priority, description);
					break;
				
			// Ascii files (HTML, server script results, xml, etc...)
				case 'xml': case 'fcg':	case 'php': case 'html': case 'txt': case 'cgi': case 'pl':
				case 'asp': case 'log':	case 'shtml': case 'htm':
				
					resource = new AsciiResource(p, url, callback, post, args, priority, description);
					break;
					
			// CSS files
				case 'css':
					
					resource = new CSSResource(p, url, callback, post, args, priority, description);
					break;
					
			// JavaScript resource
				case 'js': case 'javascript':
					
					resource = new JavaScriptResource(p, url, callback, post, args, priority, description);
					break;
					
			// Default (Unknown type)
				default:
					alert('An unknown file type was requested in the ResourceManager.  Please define' + 
						' a download method for files of type ' + ext + '.');
					return false;
					
		}

		return resource;
	}
	
	/**
	 *	Request that a resource be imported into this document
	 *
	 *	@param url The url to the resource you want imported
	 *	@param priority (Optional) The priority of this resource.  The larger the priority, the sooner
	 *			the file will be imported.
	 *	@param callback (Optional) The method to execute when the resource has finished importing
	 *	@param post (Optional) A ResourcePost object to use as a form submission when requesting the resource
	 *	@param args (Optional) An array of arguments to pass down to the callback
	 *	@param description (Optional) A short status message to display before this resource is loaded
	 *	@param extension (Optional) A string which contains the actual data file extension.  This can be used to
	 *				override the resource type for any given resource.  For example, if you had a 
	 *				cgi, which outputted javascript, you could override the cgi file type with 'js'
	 *
	 *	@return a ResourceRequest object which you can use to spawn dependencies.
	 */
	ResourceManager.request = function(url, priority, callback, post, args, description, extension) {
		var resource = ResourceManager.getResourceRequest(undefined, url, callback, post, args, priority, description, extension);
		ResourceManager.push_request(resource);
		return resource;
		
	}
	
	/**
	 *	Request a resource into the parent document from an iframe.
	 *
	 *	@param url The url to the resource you want imported
	 *	@param priority (Optional) The priority of this resource.  The larger the priority, the sooner
	 *			the file will be imported.
	 *	@param callback (Optional) The method to execute when the resource has finished importing
	 *	@param post (Optional) A ResourcePost object to use as a form submission when requesting the resource
	 *	@param args (Optional) An array of arguments to pass down to the callback
	 *	@param description (Optional) A short status message to display before this resource is loaded
	 *	@param extension (Optional) A string which contains the actual data file extension.  This can be used to
	 *				override the resource type for any given resource.  For example, if you had a 
	 *				cgi, which outputted javascript, you could override the cgi file type with 'js'
	 *
	 *	@return a ResourceRequest object which you can use to spawn dependencies.
	 */
	ResourceManager.requestRemote = function(url, priority, callback, post, args, description, extension) {
		var dx = new Image();
		dx.onload = function() {
			alert("Onload");
			ResourceManager.request(url, priority, callback, post, args, description, extension);
		}
		dx.src = "./img/ico_myday.gif";
		
	}

	/**
	 * Request that a JavaScript class file be downloaded, and the class therein be instantiated.
	 * This function provides a mechanism for deferred loading of classes from the server.
	 *
	 * @param className A string containing the name of the class to be instantiated.
	 * @param urls Either a String containing the URL of the resource to be imported, or an 
	 * Array of Strings containing multiple URLs.  If an array, the handler will be called upon
	 * the import of the last URL in the array.
	 * @param priority (Optional) The priority of these resources.
	 * @param ctorArgs (Optional) An argument to be passed to the class constructor.
	 * @param callback (Optional) A callback function to be run after the object has been 
	 * instantiated.  This callback will take two arguments: the newly instantiated object,
	 * and the optional cbArgs pass-through argument.
	 * @param cbArgs (Optional) A parameter to be passed as the second argument to the callback.
	 */
	ResourceManager.requestObject = function(className,urls,priority,ctorArgs,callback,cbArgs) {
		if (!urls) {
			return;
		}
		var handlerArgs = new Array();
		handlerArgs.push(className);
		handlerArgs.push(ctorArgs);
		handlerArgs.push(callback);
		handlerArgs.push(cbArgs);
		if (!urls.splice) {
			return ResourceManager.request(urls,priority,
				ResourceManager.handleRequestObject,
				null,handlerArgs);
		}
		if (urls.length == 1) {
			return ResourceManager.request(urls[0],priority,
				ResourceManager.handleRequestObject,
				null,handlerArgs);
		} 
		for (var i=0;i<(urls.length-1);i++) {
			ResourceManager.request(urls[i],priority);
		}
		return ResourceManager.request(urls[urls.length-1],priority,
			ResourceManager.handleRequestObject,null,handlerArgs);
	}

	/**
	 * @private
	 *
	 * Handler for requestObject.  Instantiates the specified class and executes the callback, if any.
	 * Executed after the requested resources have been imported.
	 *
	 * @param data
	 * @param xml
	 * @param request
	 * @param args
	 */
	ResourceManager.handleRequestObject = function(data,xml,request,args) {
		if (!args) {
			return;
		}
		var className = args[0];
		if (!className) {
			return;
		}

		var classNames = Array();
		if(className instanceof Array) {
			classNames = className;
		} else {
			classNames.push(className);
		}

		var ctorArgs = args[1];

		for(var i = 0; i < classNames.length; i++) {
			if (ctorArgs) {
				var obj = eval("new " + classNames[i] + "(ctorArgs)");
			} else {
				var obj = eval("new " + classNames[i] + "()");
			}
			if (!obj) {
				return;
			}
			var callback = args[2];
			if (!callback) {
				return;
			}
			var cbArgs = args[3];
			callback(obj,cbArgs);
		}
	}
	
/*

	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ResourceRequest %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

*/
	/**
	 *	ResourceRequest
	 *	This class represents a resource which needs to be imported into the document.  You can
	 *	use this object to cancel a resource, or to spawn dependencies off a resource.  A dependency
	 *	is a child resource request which will be added to the main resource request list after this
	 *	request finishes importing.  This should be used in cases where a script may fail because it requires
	 *	a function defined in a different script file.  If you make the dependent script a child of
	 *	this resource request, then it will never get executed unless this resource is imported first.
	 *
	 *	@constructor
	 * 
	 *	@param p The parent of this ResourceRequest.  This would either be undefined for a root request, or another
	 *			ResourceRequest which this request is a dependent of
	 *	@param url The URL of the resource to import
	 *	@param callback The method to execute when this resource finishes importing
	 *	@param post (Optional) A ResourcePost object to use as a form submission when requesting the resource
	 *	@param args (Optional) An array of arguments to pass down to the callback
	 *	@param priority (Optional) The numeric priority of this resource.  Larger numbers will be imported first.
	 *				(default = 0)
	 *	@param description (Opional) A descriptive status message to be displayed before this resource beings 
	 *				loading.
	 *	@param cached (Optional) If set to false, this resource will get a new copy regardless of whether it was cached.
	 */
	function ResourceRequest(p, url, callback, post, args, priority, description, cached) {
		this.superConstructor(p, url, callback, post, args, priority, description, cached);
	}
	
	/**
	 *	This is the super constructor for all sub classes of this class.  
	 *
	 *	@param url The URL of the resource to import
	 *	@param callback The method to execute when this resource finishes importing
	 *	@param post (Optional) A ResourcePost object to use as a form submission when requesting the resource
	 *	@param args (Optional) An array of arguments to pass down to the callback
	 *	@param priority (Optional) The numeric priority of this resource.  Larger numbers will be imported first.
	 *				(default = 0)
	 *	@param description (Opional) A descriptive status message to be displayed before this resource beings 
	 *				loading.
	 *	@param cached (Optional) If set to false, this resource will get a new copy regardless of whether it was cached
	 */
	ResourceRequest.prototype.superConstructor = function(parent, url, callback, post, args, priority, description, cache) {
		this.i_url = url;			// The URL of the resource we need to import
		this.i_parent = parent;			// The parent resource, if one exists. If this resource is in the main
							// request list, and is therefore not dependent on any unloaded resources
							// this value will be undefined.
		this.i_priority = priority;		// The priority level of this request
		this.i_callback = callback;		// The callback method to execute when this request finishes
		this.i_dependents = Array();		// Any child requests which are dependent on this resource being 
							// imported first.
							
		this.i_args = args;			// An array of arguments to pass to the callback
		this.i_post = post;			// A form post if necessary
		this.i_description = description;
		
		this.i_complete = false;		// Whether or not this resource is completed.
		this.i_active = false;			// Whether or not this resource is currently being imported
		this.i_enabled = true;			// Whether or not this resource still needs to be imported (cancelled?)
		
		this.i_cache = (cache == undefined ? true : false); // Whether or not to ignore browser cache.
	}
	 
	/**
	 *	Get/Set the form post object used to make this request.  Some resources do not allow form posts. These 
	 *	resources will ignore any post objects passed in.
	 *
	 *	@param post (Optional) The new ResourcePost object to assign for this resource
	 *
	 *	@return the current post object assigned to this request
	 */
	ResourceRequest.prototype.post = function(post) {
		if (post != undefined) {
			this.i_post = post;
		}
		return this.i_post;
	}
	 
	/**
	 *	Get/Set the array of arguments which is passed down to the callback when this resource completes
	 *
	 *	@param args (Optional) The new list of arguments to pass to the callback
	 *
	 *	@return the current array of argumnets, or undefined if not set
	 */
	ResourceRequest.prototype.args = function(args) {
		if (args != undefined) {
			this.i_args = args;
		}
		return this.i_args;
	}
	 
	/**
	 *	Get whether this resource has completed
	 *
	 *	@return true if the resource has completed, false otherwise
	 */
	ResourceRequest.prototype.complete = function() {
		return this.i_complete;
	}
	 
	 
	/**
	 *	Get/Set whether this resource may utilize the browser cache to speed up future loading.
	 *
	 *	@param state (Optional) The new state of whether cache is enabled for this resource.  If set to true, the
	 *				resource will attempt to cache, otherwise it will never cache.
	 *
	 *	@return the current cache state
	 */
	ResourceRequest.prototype.cache = function(state) {
		if (state != undefined) {
			this.i_cache = state;
		}
		return this.i_cache;
	}
	 
	/**
	 *	Get the parent of this resource request.  This is either undefined because the resource is 
	 *	currently being imported by the ResourceManager, or the parent resource this resoruce is 
	 *	dependent on.
	 *
	 *	@return The parent resource this resource is depdent on.  Undefined if this resource is in the main list
	 *		and is therefore no longer dependent on any other resource.
	 */
	ResourceRequest.prototype.parent = function() {
		return this.i_parent;
	}
	
	/**
	 *	Get/Set the description of this resource.  This is used to help display which resources are loading 
	 *
	 *	@param description (Optional) A new description for this resource
	 *
	 *	@return the current description of this resource
	 */
	ResourceRequest.prototype.description = function(description) {
		if (description != undefined) {
			this.i_description = description;
		}
		return (this.i_description != undefined ? this.i_description : "Loading: " + this.url());
	}
	
	/**
	 *	Get the URL of this resource
	 *
	 *	@return the URL of this resource
	 */
	ResourceRequest.prototype.url = function() {
		var rURL = this.i_url;
		if (ResourceManager.cache == false || this.cache() == false) {
			rURL = rURL + (rURL.indexOf('?') > -1 ? "&" : "?") + "anti-cache=" + ResourceManager.randomString();
		}
		return rURL;
	}
	
	/**
	 *	Get whether this resource is still enabled for a future import.
	 *
	 *	@return true if this resoruce will still be imported, false if this resource is dead
	 */
	ResourceRequest.prototype.enabled = function() {
		return this.i_enabled;
	}
	
	/**
	 *	Cancel this resource.  This will disable the resource and remove it from the parent or main
	 *	request list.
	 *
	 *	@return true if the resource was cancelled, false otherwise
	 */
	ResourceRequest.prototype.cancel = function() {
		if (this.parnet() != undefined) {
			for (var x = 0; x < this.parent().dependents().length; x++) {
				if (this.parent().dependents()[x] == this) {
					this.parent().dependents().splice(x, 1);
					ResourceManager.updateCounter(this.dependentCount() * -1, this);
					this.i_enabled = false;
					return true;
				}
			}
		}
		else {
			for (var x = 0; x < ResourceManager.requests.length; x++) {
				if (ResourceManager.requests[x] == this) {
					ResourceManager.requests.splice(x, 1);
					ResourceManager.updateCounter(this.dependentCount() * -1, this);
					this.i_enabled = false;
					return true;
				}
			}
		}
		return false;
	}
	
	/**
	 *	Get/Set the priority of this resource
	 *
	 *	@param priority (Optional) The numeric priority of this resource.  Larger values will be 
	 *				imported first.
	 *
	 *	@return the current priority of this resource
	 */
	ResourceRequest.prototype.priority = function(priority) {
		if (priority != undefined) {
			this.i_priority = priority;
		}
		return this.i_priority;
	}
	
	/**
	 *	Get/Set the callback method to execute when this resource is imported.
	 *
	 *	@param callback (Optional) A new callback to execute when this resource finishes importing
	 *					The callback will be passed 4 arguments.  The first is any data
	 *					which was obtained during the request (ascii requests), the XML dom
	 *					if the reuqest was for an XML document, then the
	 *					resource request object, then the array of arguments which were set 
	 *					when the request was made.
	 *
	 *	@return The current callback
	 */
	ResourceRequest.prototype.callback = function(callback) {
		if (callback != undefined) {
			this.i_callback = callback;
		}
		return this.i_callback;
	}
	
	/**
	 *	Get an array of dependents.  These are sub requests which will not be queued up until after this
	 *	resource has been imported.
	 *
	 *	@return an Array of resource's which need to be imported after this resource completes
	 */
	ResourceRequest.prototype.dependents = function() {
		return this.i_dependents; 
	}
	
	/**
	 *	Handler for when this resource has completed being imported
	 *
	 *	@private
	 *
	 *	@param successful True if the request completed successfully, false otherwise
	 *	@param data Any data you want passed to the callback
	 *	@param xml (Optional) Any xml DOM's which were returned.  This is really only for Ascii resources.
	 */
	ResourceRequest.prototype.request_complete = function(successful, data, xml) {
		if (this.i_complete == false) {
			this.i_complete = true;
			this.i_active = false;
			for (var x = 0; x < ResourceManager.active_requests.length; x++) {
				if (ResourceManager.active_requests[x] == this) {
					ResourceManager.active_requests.splice(x, 1);
					break;
				}
			}
			
			
			ResourceManager.connections--;
			ResourceManager.updateCounter(-1, this);
			if (successful == true) {
				for (var x = 0; x < this.i_dependents.length; x++) {
					this.i_dependents[x].i_parent = undefined;
					ResourceManager.push_request(this.i_dependents[x]);
				}
			}
			if (ResourceManager.active_requests.length == 0) {
				ResourceManager.top_priority = -1000;
			}
			setTimeout(ResourceManager.pollConnections, 1);
			if (successful == true) {	
				
				//check the session validity of the returned data
				//if the session is bad, don't even pass the data to the handler
				//(most GDS apps can't handle invalid data -- ugh...)
				if( this.resource_session_check( data, xml ) ) { 
					if (this.i_callback != undefined) {
						var cb = this.callback();
						var me = this;

						setTimeout(function() {
									  if( cb.splice != undefined ) {
									  cb[0][cb[1]](data, xml, me, me.args());
									  } else if( typeof( cb ) == "object" ) {
									  cb.execute( data, xml, me, me.args() );
									  } else {
									  cb(data, xml, me, me.args());
									  }
									  }, 1);
					}
				}else{
					//invalid session, lets kill this
					sessionTimeout( true, true );
				}
			}
		}
	}

	/**
	 * Check a resource's data and XML for indication of an invalid session.
	 * If found -- logout
	 *
	 * @param data Text data from request
	 * @param xml XML Document from request
	 */
	ResourceRequest.prototype.resource_session_check = function( data, xml ) {
		if( xml ) {
			return XML.checkResponseSession( xml );
		}

		return true;
	}
	
	
	/**
	 *	Initiate this resource to being downloading and importing into the document
	 *
	 *	@private
	 *
	 *	@return true
	 */
	ResourceRequest.prototype.initiate = function() {
		this.i_active = true;
		ResourceManager.connections++;
		
		ResourceManager.active_requests[ResourceManager.active_requests.length] = this;
		
		ResourceManager.postMessage(this, this.description());
	
		var me = this;
		setTimeout(function() {
			me.validateComplete();
		}, ResourceManager.resource_timeout);
	
	
		if (this.start_import != undefined) {
			this.start_import();
		}
		else {
			alert('A resource was requested which does not have a download procedure defined.  Please make sure that all objects added to the ResourceManager include start_import methods.' +
				"\n This resource will not be imported \n\n" + this.url());
			this.request_complete(false);
		}
		return true;
	}
	
	/**
	 *	Validate that this resource has not timed out
	 */
	ResourceRequest.prototype.validateComplete = function() {
		if (!this.i_complete && ResourceManager.enabled()) {
			if (ResourceManager.noticeTimeout()) {
				//ResourceManager.enabled(false);
				if (confirm(this.url() + "\n\n" + "A required resource could not be loaded, would you like to try again?")) {
					window.location.reload(false);
				}
			}
		}
	}
	
	/**
	 * 	Get the number of dependents of this resource, including this resource
	 *
	 *	@return the number of dependents
	 */
	ResourceRequest.prototype.depdentCount = function() {
		var c = 1;
		for (var x = 0; x < this.i_dependents.length; x++) {
			c+=this.i_dependents[x].dependentCount();
		}
		return c;
	}
	
	/**
	 *	Request that a resource be imported into this document as a dependent of this resource
	 *
	 *	@param url The url to the resource you want imported
	 *	@param priority The priority of this resource.  The larger the priority, the sooner
	 *			the file will be imported.
	 *	@param callback The method to execute when the resource has finished importing
	 *
	 *	@return a ResourceRequest object which you can use to spawn dependencies.
	 */
	ResourceRequest.prototype.request = function(url, priority, callback) {
		var requestIndex = this.i_dependents.length;
		this.i_dependents[requestIndex] = ResourceManager.getResourceRequest(this, url, callback, priority, description);
		ResourceManager.updateCount(1);
		return this.i_dependents[requestIndex];
	}
	
	
/*

	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ImageResource %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

*/
	/**
	 *	ImageResource
	 *	This is a sub class of the ResourceRequest object.  This object defines how to import an image 
	 *	resource.
	 *
	 *	@constructor
	 * 
	 *	@param p The parent of this ResourceRequest.  This would either be undefined for a root request, or another
	 *			ResourceRequest which this request is a dependent of
	 *	@param url The URL of the resource to import
	 *	@param callback The method to execute when this resource finishes importing
	 *	@param post (Optional) A ResourcePost object to use as a form submission when requesting the resource
	 *	@param args (Optional) An array of arguments to pass down to the callback
	 *	@param priority (Optional) The numeric priority of this resource.  Larger numbers will be imported first.
	 *				(default = 0)
	 *	@param description (Opional) A descriptive status message to be displayed before this resource beings 
	 *				loading.
	 */
	function ImageResource(p, url, callback, post, args, priority, description) {
		this.superConstructor(p, url, callback, post, args, priority, description);
	}
	
	/**
	 *	Get/Set the url of this resource
	 *
	 *	@param url (Optional) The new url for this resource
	 *
	 *	@return the current url of this resource (always cached)
	 */
	ImageResource.prototype.url = function(url) {
		if (url != undefined) {
			this.i_url = url;
		}
		return this.i_url;
	}
	
	/**
	 *	The handler that gets called when the image finishes downloading
	 *
	 *	@return true
	 */
	ImageResource.prototype.completeDownload = function() {
		var me = this.rreq;
		me.request_complete(true);
	}
	
	/**
	 *	The handler that gets called when the image fails downloading
	 *
	 *	@return true
	 */
	ImageResource.prototype.failDownload = function() {
		var me = this.rreq;
		alert('Unable to download image resource: ' + me.url());
		me.request_complete(false);
		
	}
	
	/**
	 *	Start downloading and importing the resource
	 *
	 *	@return true
	 */
	ImageResource.prototype.start_import = function() {
		this.i_image = new Image();
		this.i_image.rreq = this;
		this.i_image.onload = this.completeDownload;
		this.i_image.onerror = this.failDownload;
		this.i_image.onabort = this.failDownload;
		this.i_image.src = this.url();
	}
	
	ImageResource.inherit(ResourceRequest);
	
/*

	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% AsciiResource %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

*/
	/**
	 *	AsciiResource
	 *	This is a sub class of the ResourceRequest object.  This object defines how to import ascii resources
	 *	such as server side script results, html files, text files, xml files, etc...
	 *
	 *	@constructor
	 * 
	 *	@param p The parent of this ResourceRequest.  This would either be undefined for a root request, or another
	 *			ResourceRequest which this request is a dependent of
	 *	@param url The URL of the resource to import
	 *	@param callback The method to execute when this resource finishes importing
	 *	@param post (Optional) A ResourcePost object to use as a form submission when requesting the resource
	 *	@param args (Optional) An array of arguments to pass down to the callback
	 *	@param priority (Optional) The numeric priority of this resource.  Larger numbers will be imported first.
	 *				(default = 0)
	 *	@param description (Opional) A descriptive status message to be displayed before this resource beings 
	 *				loading.
	 */
	function AsciiResource(p, url, callback, post, args, priority, description) {
		this.superConstructor(p, url, callback, post, args, priority, description);
	}
	
	
	/**
	 *	The handler that gets called when the file finishes downloading
	 *
	 *	@return true
	 *
	 *	@param data The data that was inside the ascii file
	 */
	AsciiResource.prototype.completeDownload = function(data, xml) {
		var tm;
		try {
			tm = this.i_server.getResponseHeader("Session-timeout");
			if (tm == 1) {
				sessionTimeout(true);
				this.request_complete(false);
				return true;
			}
		}
		catch (e) { }
		
		this.request_complete(true, data, xml);
	}
	
	/**
	 *	The handler that gets called when the file fails downloading
	 *
	 *	@return true
	 */
	AsciiResource.prototype.failDownload = function() {
		alert('Unable to download ascii resource: ' + this.url());
		this.request_complete(false);
		
	}
	
	/**
	 *	Start downloading and importing the resource
	 *
	 *	@return true
	 */
	AsciiResource.prototype.start_import = function() {
		this.i_server = (document.all ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest());
		var server = this.i_server;
		var me = this;
		this.i_server.onreadystatechange = function() {
			if (server.readyState == 4) {
				me.completeDownload(server.responseText, server.responseXML);		
			}
		};
		
		try {
			this.i_server.open((this.post() != undefined ? "post" : "get"), this.url(), true);
			this.i_server.send((this.post() != undefined ? this.post().toString() : null));
		}
		catch (e) { 
			alert(e.message);
			this.failDownload();
		}
	}

	
	AsciiResource.inherit(ResourceRequest);
	
/*

	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% CSSResource %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

*/
	/**
	 *	CSSResource
	 *	This is a sub class of the ResourceRequest object.  This object defines how to import a CSS style
	 *	definition file
	 *
	 *	@constructor
	 *
	 *	@param p The parent of this ResourceRequest.  This would either be undefined for a root request, or another
	 *			ResourceRequest which this request is a dependent of
	 *	@param url The URL of the resource to import
	 *	@param callback The method to execute when this resource finishes importing
	 *	@param post (Optional) A ResourcePost object to use as a form submission when requesting the resource
	 *	@param args (Optional) An array of arguments to pass down to the callback
	 *	@param priority (Optional) The numeric priority of this resource.  Larger numbers will be imported first.
	 *				(default = 0)
	 *	@param description (Opional) A descriptive status message to be displayed before this resource beings 
	 *				loading.
	 */
	function CSSResource(p, url, callback, post, args, priority, description) {
		this.superConstructor(p, url, callback, post, args, priority, description);
	}
	
	/**
	 *	Whether or not CSS files in FireFox are compiled into a single resource in order to perserve a low number
	 *	of CSS document objects.  This will cause large number of CSS files to load more slowly, but if you notice
	 * 	CSS information missing for no aparent reason, it would be a good idea to set this flag in order to continue
	 *	development.  Since the production version is always compiled into a single resource, this is a development aid
	 *	only and should not be set to true in CVS.
	 */
	CSSResource.compile_results = true;
	
	/**
	 *	The handler that gets called when the script finishes downloading
	 *
	 *	@return true
	 */
	CSSResource.prototype.completeDownload = function(data) {
		if (CSSResource.compile_results == true) {
			if (CSSResource.activeStylesheet == undefined) {
				CSSResource.activeStylesheet = document.createElement('STYLE');
				CSSResource.activeStylesheet.type = "text/css";
				CSSResource.activeStylesheet.id = "GDSStyleID";
				document.getElementsByTagName('head')[0].appendChild(CSSResource.activeStylesheet);
			}	
			CSSResource.activeStylesheet.innerHTML += data;
		}
		else {
			var s = document.createElement('STYLE');
			s.type = "text/css";
			s.innerHTML = data;
			document.getElementsByTagName('head')[0].appendChild(s);
		}
		
		this.request_complete(true);
	}
	
	/**
	 *	The handler that gets called when the script fails downloading
	 *
	 *	@return true
	 */
	CSSResource.prototype.failDownload = function() {
		alert('Unable to download stylesheet resource: ' + me.url());
		this.request_complete(false);
		
	}
	
	
	/**
	 *	The handler that gets called when the script finishes downloading
	 *
	 *	@return true
	 */
	CSSResource.prototype.completeIEDownload = function() {
		var me = this.rreq;
		me.request_complete(true);
	}
	
	/**
	 *	The handler that gets called when the script fails downloading
	 *
	 *	@return true
	 */
	CSSResource.prototype.failIEDownload = function() {
		var me = this.rreq;
		alert('Unable to download stylesheet resource: ' + me.url());
		me.request_complete(false);
		
	}
	
	
	/**
	 *	Start downloading and importing the resource
	 *
	 *	@return true
	 */
	CSSResource.prototype.start_import = function() {
		if (document.all) {
			var sheet = document.createElement('link');
			sheet.rel = 'stylesheet';
			sheet.type = 'text/css';
			sheet.rreq = this;
			sheet.onload = this.completeIEDownload;
			sheet.onerror = this.failIEDownload;
			sheet.onabort = this.failIEDownload;
			sheet.onreadystatechange = this.completeIEDownload;
			sheet.href = this.url();	
			document.getElementsByTagName('head')[0].appendChild(sheet);
		}
		else {
			this.i_server = (document.all ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest());
			var server = this.i_server;
			var me = this;
			this.i_server.onreadystatechange = function() {
				if (server.readyState == 4) {
					me.completeDownload(server.responseText);		
				}
			};

			try {
				this.i_server.open("get", this.url(), true);
				this.i_server.send(null);
			}
			catch (e) { 
				this.failDownload();
			}
		}
	}
	
	CSSResource.inherit(ResourceRequest);
	
/*

	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% JavaScriptResource %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

*/
	/**
	 *	JavaScriptResource
	 *	This is a sub class of the ResourceRequest object.  This object defines how to import a javascript file
	 *
	 *	@constructor
	 *
	 *	@param p The parent of this ResourceRequest.  This would either be undefined for a root request, or another
	 *			ResourceRequest which this request is a dependent of
	 *	@param url The URL of the resource to import
	 *	@param callback The method to execute when this resource finishes importing
	 *	@param post (Optional) A ResourcePost object to use as a form submission when requesting the resource
	 *	@param args (Optional) An array of arguments to pass down to the callback
	 *	@param priority (Optional) The numeric priority of this resource.  Larger numbers will be imported first.
	 *				(default = 0)
	 *	@param description (Opional) A descriptive status message to be displayed before this resource beings 
	 *				loading.
	 */
	function JavaScriptResource(p, url, callback, post, args, priority, description) {
		this.superConstructor(p, url, callback, post, args, priority, description);
	}
	
	/**
	 *	An array of all requests which have gone out
	 */
	JavaScriptResource.resources = Array();
	
	/**
	 *	The handler that gets called when the script finishes downloading
	 *
	 *	@return true
	 */
	JavaScriptResource.prototype.completeDownload = function() {
		var me = this.rreq;
		me.request_complete(true);
	}
	
	/**
	 *	The handler that gets called when the script fails downloading
	 *
	 *	@return true
	 */
	JavaScriptResource.prototype.failDownload = function() {
		var me = this.rreq;
		alert('Unable to download script resource: ' + me.url());
		me.request_complete(false);
		
	}
	
	/**
	 *	Notify the resource manager that this file has finished loading
	 *
	 *	@param file_path The path to the file which finished loading
	 *
	 *	@return true
	 */
	JavaScriptResource.notifyComplete = function(file_path) {
		
		for (var x = 0; x < JavaScriptResource.resources.length; x++) {
			var u = JavaScriptResource.resources[x].url();
			if (u.indexOf('?') >= 0) {
				u = u.substr(0, u.indexOf('?'));
			}
			if( u.substr(0,4) == "http" ) {
				for( var q = 0; q < 3; q++ ) {
					try {
						u = u.substring(u.indexOf("/") + 1);
					}catch(e) {
						console.log( 'Error removing hostname' );
					}
				}
				u = "/" + u;
			}
			if (u == file_path) {
				JavaScriptResource.resources[x].request_complete(true);
				JavaScriptResource.resources.splice(x, 1);
				return true;
			}
		}
		return false;
	}
	
	/**
	 *	Start downloading and importing the resource
	 *
	 *	@return true
	 */
	JavaScriptResource.prototype.start_import = function() {
		var script = document.createElement('script');
		script.type = 'text/javascript';
		script.rreq = this;
		
		script.onerror = this.failDownload;
		script.onabort = this.failDownload;
		if (ResourceManager.strict_javascript) {
			JavaScriptResource.resources[JavaScriptResource.resources.length] = this;
		}
		else {
			script.onload = this.completeDownload;
			script.onreadystatechange = this.completeDownload;
		}
		script.src = this.url();		
		document.getElementsByTagName('head')[0].appendChild(script);
	}
	
	JavaScriptResource.inherit(ResourceRequest);
	

	
	
	
/*
	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ResourceListener %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
*/
	/**
	 *	ResourceListener
	 *	This class provides an object which can be obtained from the ResourceManager to monitor the progress
	 *	of all files currently in the download list.  If new files are added, they will not be included, and
	 *	the progress will still reach 100% when the original resource set finishes.
	 *
	 *	@constructor
	 */
	function ResourceListener() {
		this.reset();
	}
	

	/**
	 *	Reset the resource listener to use the current resource request queue.  This may look
	 *	odd to the user, since the progress will jump backwards.
	 */
	ResourceListener.prototype.reset = function() {
		this.i_resources = Array();
		this.i_completed = 0;
		this.i_done = false;
		
		var recQ = Array();
		for (var x = 0; x < ResourceManager.requests.length; x++) {
			recQ[x] = ResourceManager.requests[x];
		}
		for (var x = 0; x < ResourceManager.active_requests.length; x++) {
			recQ[recQ.length] = ResourceManager.active_requests[x];
		}
		
		while (recQ.length > 0) {
			var sub = recQ[0];
			recQ.splice(0, 1);
			
			if (sub.dependents() != undefined) {
				for (var x = 0; x < sub.dependents().length; x++) {
					recQ[recQ.length] = sub.dependents()[x];
				}
			}
			
			if (sub.complete()) {
				this.i_completed++;
			}
			
			this.i_resources[this.i_resources.length] = sub;
		}
		
		if (this.onchange != undefined) {
			this.onchange(this.percent());
		}
	}
	
	/**
	 *	Get whether this listener is no longer needed, because it has completed
	 *
	 *	@return true if the resource listener can be ignored, false otherwise
	 */
	ResourceListener.prototype.done = function() {
		if (this.i_done == false) {
			if (this.i_resources.length == this.i_completed) {
				this.i_done = true;
				
				// Cleanup memory usage for this listener
				for (var x = 0; x < this.i_resources.length; x++) {
					this.i_resources[x] = null;
				}
				
				this.onchange = null;
				this.onstatusmessage = null;
			}
		}
		return this.i_done;
	}
	
	/**
	 *	Get the percentage completed
	 *
	 *	@return the percent completed
	 */
	ResourceListener.prototype.percent = function() {
		if (this.i_resources.length <= 0) {
			return 100;
		}
		if (this.i_resources.length == this.i_completed) {
			return 100;
		}
		return Math.floor((this.i_completed / this.i_resources.length) * 100);
	}
	
	/**
	 *	Internal handler for when a resource completes
	 *
	 *	@private
	 *
	 *	@param resource The ResourceRequest object that just completed
	 */
	ResourceListener.prototype.resource_completed = function(resource) {
		for (var x = 0; x < this.i_resources.length; x++) {
			if (resource == this.i_resources[x]) {
				this.i_completed++;
				if (this.onchange != undefined) {
					this.onchange(this.percent());
				}
				if (this.i_completed == this.i_resources.length) {
					if (this.oncomplete != undefined) {
						this.oncomplete();
					}
				}
				return true;
			}
		}
		return false;
	}
	
	/**
	 *	Internal handler for when a resource posts an initiation message
	 *
	 *	@private
	 *
	 *	@param resource The resource posting the message
	 *	@param message The message the resource is posting
	 */
	ResourceListener.prototype.resource_post = function(resource, message) {
		for (var x = 0; x < this.i_resources.length; x++) {
			if (resource == this.i_resources[x]) {
				if (this.onstatusmessage != undefined) {
					this.onstatusmessage(message, resource);
				}
				return true;
			}
		}
		return false;
	}

	/**
	 *	Handler which is called when the resource list has completed a download and is therefore
	 *	at a new percentage of completion.  You can use this to update progress bars.
	 *
	 *	@param percent The new percentage of completion
	 */
	ResourceListener.prototype.onchange = function(percent) {}
	
	/**
	 *	Handler which is called when a resource is being initiated and posts a status message.
	 *	You can use this to update a status box.
	 *
	 *	@param message  The status message being posted
	 *	@param resource The resource that is posting this message
	 */
	ResourceListener.prototype.onstatusmessage = function(message, resource) {}
	
	/**
	 *	Handler for when all resources have finished being imported
	 */
	ResourceListener.prototype.oncomplete = function() {} 




/*

	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ResourceXMLBlock %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

*/
	/**
	 *	ResourceXMLBlock
	 *	This class allows you to include pre processed blocks of XML to a ResourceXML tree.  You will not be able
	 *	to add children, or read into this block, but it will be included in any string convertions of the entire
	 *	XML tree.
	 *
	 *	@constructor
	 *
	 *	@param block_text The XML to add
	 */
	function ResourceXMLBlock(block_text) {
		this.i_block_text = block_text;
	}
	
	
	/**
	 *	Get/Set the block text of this node
	 *
	 *	@param text (Optional) The new block text
	 *
	 *	@return the current block text
	 */
	ResourceXMLBlock.prototype.text = function(text) {
		if (text != undefined) {
			this.i_block_text = text;
		}
		return this.i_block_text;
	}
	
	/**
	 *	Get this block's text
	 *
	 *	@return the string of text assigned to this block
	 */
	ResourceXMLBlock.prototype.toString = function() {
		return this.i_block_text;
	}

/*

	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ResourceXMLNode %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	
*/
	/**
	 *	ResourceXMLNode 
	 *	This class provides a single node, and a collection of children used to construct an XML document
	 *
	 *	@constructor
	 *
	 *	@param nodeName The name of this node
	 *	@param value The value of this node (empty if there are children)
	 *	@param cdata (Optional) Enclose this tag in cdata tags.  This should only be done if there are no children
	 */
	function ResourceXMLNode(nodeName, value, cdata) {
		this.i_name = nodeName;			// The name of this node
		this.i_value = value;			// The value of this node
		this.i_forceCDATA = (cdata != undefined ? cdata : false);
		
		this.i_children = Array();
	}
	
	/**
	 *	Get/Set the name of this node
	 *
	 *	@param name (Optional) A new name for this node
	 *
	 *	@return the current name of this node
	 */
	ResourceXMLNode.prototype.name = function(name) {
		if (name != undefined) {
			this.i_name = name;
		}
		return this.i_name;
	}
	
	/**
	 *	Get/Set the value of this node
	 *
	 *	@param value (Optional) The new value to assign to this node
	 *
	 *	@return the current value of this node
	 */
	ResourceXMLNode.prototype.value = function(value) {
		if (value != undefined) {
			this.i_value = value;
		}
		return this.i_value;
	}
	
	/**
	 *	Get/Set if this tag should be wrapped in CDATA tags.  If so, there should not be any
	 *	child nodes
	 *
	 *	@param state (Optional) The new cdata wrapper state
	 *
	 *	@return if there are currently CDATA tags wrapping this tag
	 */
	ResourceXMLNode.prototype.forceCDATA = function(state) {
		if (state != undefined) {
			this.i_forceCDATA = state;
		}
		return this.i_forceCDATA;
	}
	
	/**
	 *	Get an array of child nodes
	 *
	 *	@param index (Optional) The index of a node in the node collection that you want
	 *
	 *	@return An array of child nodes, or a single node if an index was passed
	 */
	ResourceXMLNode.prototype.children = function(index) {
		if (index != undefined) {
			return this.i_children[index];
		}
		return this.i_children;
	}
	
	/**
	 *	Add a child node
	 *
	 *	@param node The node to add as a child
	 *
	 *	@return the node which was just added
	 */
	ResourceXMLNode.prototype.addNode = function(node) {
		this.i_children[this.i_children.length] = node;
		return node;
	}

	/**
	 * Adds a leaf node to the resource tree.
	 *
	 * @param nodeName The name of the node.
	 * @param value The value of the node.
	 * @param cdata (Optional) Whether to enclose this value in cdata tags.  Should not contain any children.
	 *
	 * @return The newly created node.
	 */
	ResourceXMLNode.prototype.addLeafNode = function(nodeName,value, cdata) {
		return this.addNode(new ResourceXMLNode(nodeName,value, cdata));
	}
	
	/**
	 *	Remove a child node
	 *
	 *	@param node The node to remove
	 *
	 *	@return true if the node was removed, false otherwise
	 */
	ResourceXMLNode.prototype.removeNode = function(node) {
		for (var x = 0; x < this.i_children.length; x++) {
			if (this.i_children[x] == node) {
				this.i_children.splice(x, 1);
				return true;
			}
		}
		return false;
	}	
	
	/**
	 *	Convert this node into an XML string
	 *
	 *	@return a string with this node and its children
	 */
	ResourceXMLNode.prototype.toString = function() {
		var str = "<" + this.name() + ">" + (this.forceCDATA() ? "<![CDATA[" : "");
		if (this.i_children.length == 0) {
			str+=this.value();
		}
		else {
			for (var x = 0; x < this.i_children.length; x++) {
				str+=this.i_children[x].toString();
			}
		}
		str+=(this.forceCDATA() ? "]]>" : "") + "</" + this.name() + ">";
		return str;
	}	



/*

	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ResourcePost %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

*/
	/**
	 *	ResourcePost
	 *	This class provides a virtual form object.  You can create simulated form posts by setting various name/value
	 *	pairs, and then accessing the object as a string.
	 *
	 *	@constructor
	 */
	function ResourcePost() {
		this.params = Array();
	}

	/**
	 *	Get/Set a value pair
	 *
	 *	@param name The name of the value you are getting or setting
	 *	@param value (Optional) A replacement value for the value currently stored for the given name
	 *
	 *	@return the value currently assigned to the name given.
	 */
	ResourcePost.prototype.param = function(name, value) {
		if (value != undefined) {
			this.params['cx_' + name] = value;
		}
		return this.params['cx_' + name];
	}

	/**
	 *	Get the post object in the form of a string.  This should be identical to the data transmitted by the browser
	 *	during a legitimate form post.
	 *
	 *	@return A string representing the form post data.
	 */
	ResourcePost.prototype.toString = function() {
		var str = "";
		for (i in this.params) {
			if (i.substr(0, 3) == 'cx_') {
				var ui = i.substr(3);
				if (str != "") {
					str+="&";
				}
				str+=escape(ui) + "=" + escape(this.params[i]);
				str = str.replace( /\+/g, "%2B" ); // escape + signs #135213
			}
		}
		return str;
	}

