	
	//========= General (static) Properties =========
													
	AsyncRequest.prototype.requestName			= null;
	AsyncRequest.prototype.requestURL			= null;
	AsyncRequest.prototype.request				= null;
	AsyncRequest.prototype.response				= null;	
	AsyncRequest.prototype.isRequestCompleted 	= null;
	
	AsyncRequest.prototype.functionObject	 	= null;	
	AsyncRequest.prototype.onSuccessFunction 	= null;	
	AsyncRequest.prototype.onErrorFunction 		= null;	
	
	/**
	 * AsyncRequest - Constructor
	 * Create a new AsyncRequest object.
	 */
	function AsyncRequest()
	{
		this.requestName 		= "NULL";
		this.requestURL			= "NULL";		
		this.isRequestCompleted	= false;
	}
	
	/**
	 */
	AsyncRequest.prototype.getRequestName = function ()
	{
		return this.requestName;
	};
	
	/**
	 */
	AsyncRequest.prototype.setRequestName = function (name)
	{
		this.requestName = name;
	};
	
	/**	
	 */
	AsyncRequest.prototype.getRequestURL = function ()
	{
		return this.requestURL;
	};
	
	/**	 
	 */
	AsyncRequest.prototype.setRequestURL = function (url)
	{
		this.requestURL = url;
	};	
	
	/**	
	 */
	AsyncRequest.prototype.getFunctionObject = function ()
	{
		return this.functionObject;
	};
	
	/**	 
	 */
	AsyncRequest.prototype.setFunctionObject = function (obj)
	{
		this.functionObject = obj;
	};
	
	/**	
	 */
	AsyncRequest.prototype.getOnSuccessFunction = function ()
	{
		return this.onSuccessFunction;
	};
	
	/**	 
	 */
	AsyncRequest.prototype.setOnSuccessFunction = function (func)
	{
		this.onSuccessFunction = func;
	};
		
	/**	
	 */
	AsyncRequest.prototype.getOnErrorFunction = function ()
	{
		return this.onErrorFunction;
	};
	
	/**	 
	 */
	AsyncRequest.prototype.setOnErrorFunction = function (func)
	{
		this.onErrorFunction = func;
	};
		
	/**	
	 * Returns the result of the request.  Make sure, you call this function
	 * only within your callback function (as set by setCallBackFunction).
	 */
	AsyncRequest.prototype.getResponseText = function ()
	{
		if (this.request)
		{
			return this.request.responseText;
		}
	};
	
	/**	
	 * Returns true if the request was successful and completed with no errors.
	 * Make sure you call this function before starting to process any responeses.
	 */
	AsyncRequest.prototype.isStatusOk = function ()
	{
		if (this.request)
		{
			return this.request.status == 200;
		}
		else
		{
			return false;
		}
	};
	
	/**	
	 * Ensures that the AsyncRequest object has the required parameters
	 * before issuing an asynchronous request.
	 */
	AsyncRequest.prototype.isAsyncRequestValid = function ()
	{
		var message = "";
		if (!this.requestURL || this.requestURL == "NULL" )
		{
			message = "The Request URL has not been initialized";
		}
		else if (!this.onSuccessFunction)
		{
			message = "No onSuccess() function specified for async request.";
		}
		else if (!this.onErrorFunction)
		{
			message = "No onError() function specified for async request.";
		}
		
		if (message !== "")
		{
			alert ("ERROR: " + message);
			return false;
		}
		
		return true;
	};
		
	/**
	 * Processes your asynchronous request
	 */
	 		
	AsyncRequest.prototype.processRequest = function ()
	{											 
		//alert ('processRequest called ...');
		
		if ( ! this.isAsyncRequestValid() )
		{	
			return;
		}
		
	    this.request = false;	
	    var d = new Date();
	    if (this.requestURL.indexOf("?") == -1) 
	    {
	        this.requestURL += "?cacheBuster=" + d.getTime();
	    } 
	    else 
	    {
	        this.requestURL += "&cacheBuster=" + d.getTime();
	    }
	                
	    this.response 				= new AsyncHttpResponse();
	    this.response.statusCode 	= -1;
	    this.response.url 			= this.requestURL;
	            
	    if (window.XMLHttpRequest) 
	    {
	        // branch for native XMLHttpRequest object
	        try 
	        {
	            this.request = new XMLHttpRequest();
	        } 
	        catch (e) 
	        {
	            this.request = false;
	        }
	    } 
	    else if(window.ActiveXObject) 
	    {
	        // branch for IE/Windows ActiveX version
	        try 
	        {
	            this.request = new ActiveXObject("Msxml2.XMLHTTP");
	        } 
	        catch(e) 
	        {
	            try 
	            {
	                this.request = new ActiveXObject("Microsoft.XMLHTTP");
	            } 
	            catch(e) 
	            {
	                this.request = false;
	            }
	        }
	    }
	
		//alert ('processRequest: checking the this.request ...');
		
	    if (this.request) 
	    {
	    	//Since this is an asynchronous call, register a call back function to check for the status.	    	
	    	var thisAsyncRequest = this;		
			function timerRelay() 
			{ 				
				thisAsyncRequest.asyncRequestCallback.call(thisAsyncRequest);
			}
	        this.request.onreadystatechange = timerRelay;	        
	        
	        //Since an async request does not timeout, we have 
	        //to create a timeout here to abort the request after
	        //30 seconds.
	        this.isRequestCompleted = false;
	        var timeoutToken = window.setTimeout( function()
			{
		      if ( ! thisAsyncRequest.isRequestCompleted )
		      {
		         // alert ("Unable to connect to URL [" + thisAsyncRequest.requestURL + "].  The request has timed out.");
		         thisAsyncRequest.request.abort();
		      }
		      window.clearTimeout(timeoutToken);   
		    }, 60000);  //abort after 1 minute
	        
	        try 
	        {
	            this.request.open("GET", this.requestURL, true); // Asynchronous request	            
	            this.request.send(""); 	            
	        } 
	        catch (e) 
	        {
	        	if (typeof(e) == 'string')
                {
                	this.response.exceptionText = e;
                }
                else
                {
                	this.response.exceptionText = e.description;
                }
                	        		            
	            alert ("[" + this.requestURL + "] Error: " + this.response.exceptionText);
	        }	        
	    }	    	    
	};				
	
	
	/**
	 * The first this argument to the call method by default means, call the onErrorFunction on the
	 * 'this' object.  The second 'this' argument passes the requestObject to the callback function.
	 */
	AsyncRequest.prototype.asyncRequestCallback = function ()
	{	
		//alert ('processRequest, call back function called ');	
		if ( ! this.functionObject )		
		{
			this.functionObject = window;
		}
		
	    if (this.request.readyState == 4)
	    {	    	
	    	this.isRequestCompleted = true;	  
	    	if ( this.isStatusOk() && this.onSuccessFunction )  	
	    	{
	        	this.onSuccessFunction.call(this.functionObject, this);
	        }
	        else if (this.onErrorFunction)
	        {
	        	this.onErrorFunction.call(this.functionObject, this);  	        	
	        }
	    }
	};		
	
	/**
	 * toString
	 * Returns a string representation of this AsyncRequest 
	 */
	AsyncRequest.prototype.toString = function ()
	{	
		var buffer;
		
		buffer += "Async Request Name: 	[" + this.requestName 			+ "], ";
		buffer += "Request URL: 		[" + this.requestURL 			+ "], ";
		buffer += "Request: 			[" + this.request 				+ "], ";
		buffer += "Response: 			[" + this.response				+ "], ";
		buffer += "Request Completed? 	[" + this.isRequestCompleted	+ "], ";		
		buffer += "Function Object	 	[" + this.functionObject		+ "], ";						
		buffer += "On Success Function 	[" + this.onSuccessFunction		+ "], ";						
		buffer += "On Error Function 	[" + this.onErrorFunction		+ "], ";						
						
		return buffer;
	};			
	
function AsyncHttpResponse(statusCode, statusText, responseText, responseXml, exceptionText, url) 
{
    this.statusCode = statusCode;
    this.statusText = statusText;
    this.responseText = responseText;
    this.responseXml = responseXml;
    this.exceptionText = exceptionText;
    this.url = url;  
}