Array.prototype.indexOf = function(value)
{
	var result = -1;
	for(var i = 0; result == -1 && i < this.length; i++)
		if(this[i] == value) result = i;
	return result;
}
Array.prototype.contains = function(value)
{
	return (this.indexOf(value) > -1);
}
String.prototype.contains = function(s)
{
	return (this.indexOf(s) > -1);
}

function StringBuilder(init)
{
	if(typeof init == 'number')
		this.__innerStrings = new Array(init);
	else if(typeof init == 'string')
		this.__innerStrings = [init];
	else
		this.__innerStrings = [];
		
	if(typeof StringBuilder.__initialized == 'undefined')
	{
		StringBuilder.prototype.append = function(s)
		{
			if(typeof s == 'string')
				this.__innerStrings.push(s);
			else
				throw new Error('"s" must be of type "String"');
		}
		
		StringBuilder.prototype.appendFormat = function(f)
		{
			if(typeof f == 'undefined' || f == null) throw new Error('Argument Null Exception. f cannot be null.');
			if(typeof arguments == 'undefined' || arguments == null || arguments.length < 2) throw new Error('Argument Null Exception. arguments cannot be null.');
			
			var r = new RegExp('{[\\d]+}', 'g');
			if(!r.test(f)) throw new Error('The format string does not contain any properly formated replacment tokens, i.e. "{#}"');
			
			var result = f;
			var m = f.match(r);
			var p = [];
			for(var a = 1; a < arguments.length; a++)
				p.push(arguments[a]);
			for(var i = 0; i < m.length; i++)
			{
				var index = new Number(m[i].match(new RegExp('[\\d]+'))[0]);
				if(index > p.length - 1) throw new Error('The format string contains indexes outside the range of the given arguments.');
				result = result.replace(m[i], p[index]);
			}
			
			this.append(result);
		}
		
		StringBuilder.prototype.toString = function()
		{
			if(this.__innerStrings.length > 0)
				return this.__innerStrings.join('');
			else
				return '';
		}
		
		StringBuilder.__initialized = true;
	}
}

function Dictionary()
{
	this.keys = [];
	this.values = [];
	this.count = 0;
	
	if(typeof Dictionary.__initialized == 'undefined')
	{
		Dictionary.prototype.isSynchronous = function()
		{
			return (this.keys.length == this.values.length);
		}
	
		Dictionary.prototype.__validate = function()
		{
			if(!this.isSynchronous())
				throw new Error('This Dictionary\'s keys and values are no longer synchronized. The Dictionary is invalid.');
		}
	
		Dictionary.prototype.containsKey = function(key)
		{
			this.__validate();
			return this.keys.contains(key);
		}
		
		Dictionary.prototype.containsValue = function(value)
		{
			this.__validate();
			return this.values.contains(value);
		}
		
		Dictionary.prototype.add = function(key, value)
		{
			this.__validate();
			if(typeof key == 'undefined' || key == null) throw new Error('The key can not be null.');
			if(!this.containsKey(key))
			{
				this.keys.push(key);
				this.values.push(value);
				this.count++;
			}
			else
				throw new Error('Dictionary already contains this key: ' + key);
		}
		
		Dictionary.prototype.update = function(key, value)
		{
			this.__validate();
			if(typeof key == 'undefined' || key == null) throw new Error('The key can not be null.');
			if(this.containsKey(key))
			{
				var index = this.keys.indexOf(key);
				this.values[index] = value;
			}
			else
				this.add(key, value);
		}
		
		Dictionary.prototype.clear = function()
		{
			delete this.keys;
			delete this.values;
			
			this.count = 0;
			this.keys = [];
			this.values = [];
		}
		
		Dictionary.prototype.remove = function(key)
		{
			this.__validate();
			if(typeof key == 'undefined' || key == null) throw new Error('The key can not be null.');
			if(this.containsKey(key))
			{
				var index = this.keys.indexOf(key);
				this.keys.splice(index, 1);
				this.values.splice(index, 1);
				this.count = this.keys.length;
			}
			else
				throw new Error('This Dictionary does not contain the key: ' + key + '.  The key cannot be removed.');
		}
		
		Dictionary.prototype.item = function(key)
		{
			if(this.containsKey(key))
			{
				return this.values[this.keys.indexOf(key)];
			}
			else throw new Error('This Dictionary does not contain the key: ' + key);
		}
		
		Dictionary.prototype.itemAt = function(index)
		{
			if(index < 0 || (this.keys.length - 1) < index) throw new Error('index is outside of the Dictionary bounds');
			return this.values[index];
		}
	
		Dictionary.__initialized = true;
	}
}

function QueryString(qs)
{	
	if (typeof QueryString.__initialized == 'undefined')
	{
		QueryString.prototype.toString = function ()
		{
			var result = new StringBuilder('?');
			for (var i = 0; i < this.count; i++)
			{
				result.appendFormat('{0}={1}', encodeURIComponent(this.keys[i]), encodeURIComponent(this.values[i]));
				if(i < (this.count - 1)) result.append('&');
			}
			
			return result.toString();
		}
		
		QueryString.prototype.parse = function (qs)
		{
			if (/\?/.test(qs)) qs = qs.replace(/\?/, '');
			if (/=/.test(qs))
			{
				var chunks = qs.split('&');
				for (var i = 0; i < chunks.length; i++)
				{
					var kvp = chunks[i].split('=');
					this.add(decodeURIComponent(kvp[0]), decodeURIComponent(kvp[1]));
				}
			}
			else throw new Error('The given string does not appear to have any key value pairs.');
		}
		
		QueryString.__initialized = true;
	}
	
	Dictionary.call(this);
	
	if(qs) this.parse(qs);
	this.current = null;
	if(window.location.search == qs) this.current = this;
	else this.current = new QueryString(window.location.search);
}
QueryString.prototype = new Dictionary();

/* Globals */
window.vx_progid = false;
var vx_ActiveXmlHttpRequests = [];
var vx_ActiveAjaxRequests = new Dictionary();
var vx_QueuedAjaxRequests = new Dictionary();
var vx_AjaxResponseCache = new Dictionary();

function vx_AjaxUtil()
{	
	if(typeof vx_AjaxUtil.__initialized == 'undefined')
	{
		vx_AjaxUtil.prototype.abortAll = function()
		{
			var arids = [];
			var qrids = [];
			if(vx_ActiveAjaxRequests && vx_ActiveAjaxRequests.count > 0)
			{
				for(var aari = 0; aari < vx_ActiveAjaxRequests.count; aari++)
				{
					rids.push(vx_ActiveAjaxRequests.keys[aari]);
				}
			}
			if(vx_QueuedAjaxRequests && vx_QueuedAjaxRequests.count > 0)
			{
				for(var qari = 0; qari < vx_QueuedAjaxRequests.count; qari++)
				{
					qrids.push(vx_QueuedAjaxRequests.keys[qari]);
				}
			}				
			for(var r = 0; r < arids.length; r++)
				if(vx_ActiveAjaxRequests.item(arids[r])) vx_ActiveAjaxRequests.item(arids[r]).abort();
				
			for(var r = 0; r < qrids.length; r++)
				if(vx_QueuedAjaxRequests.item(qrids[r])) vx_QueuedAjaxRequests.item(qrids[r]).abort();
		}
		
		vx_AjaxUtil.prototype.__abortAll__Service = function(dic, match)
		{
			if(dic instanceof Dictionary)
			{
				var serviceIDs = [];
				if(dic && dic.count > 0)
				{
					for(var index = 0; index < dic.count; index++)
					{
						if(dic.keys[index].contains(match))
							serviceIDs.push(dic.keys[index]);
					}
				}
				
				for(var sid = 0; sid < serviceIDs.length; sid++)
					if(dic.item(serviceIDs[sid])) dic.item(serviceIDs[sid]).abort();
			}
		}
		
		vx_AjaxUtil.prototype.abortAllActiveService = function(service)
		{
			this.__abortAll__Service(vx_ActiveAjaxRequests, service);
		}
		
		vx_AjaxUtil.prototype.abortAllQueuedService = function(service)
		{
			this.__abortAll__Service(vx_QueuedAjaxRequests, service);
		}
		
		vx_AjaxUtil.prototype.abortAllService = function(service)
		{
			this.abortAllActiveService(service);
			this.abortAllQueuedService(service);
		}
		
		vx_AjaxUtil.prototype.abortAllActiveServiceMethod = function(service, method)
		{
			this.__abortAll__Service(vx_ActiveAjaxRequests, service + '/' + method);
		}
		
		vx_AjaxUtil.prototype.abortAllQueuedServiceMethod = function(service, method)
		{
			this.__abortAll__Service(vx_QueuedAjaxRequests, service + '/' + method);
		}
		
		vx_AjaxUtil.prototype.abortAllServiceMethod = function(service, method)
		{
			this.abortAllService(service + '/' + method);
		}
		
		vx_AjaxUtil.prototype.__numberOf__Requests = function(dic, match)
		{
			var result = 0;
			if(dic instanceof Dictionary)
			{
				for(var index = 0; index < dic.keys.length; index++)
					if(dic.keys[index].contains(match)) result++;
			}
			return result;
		}
		
		vx_AjaxUtil.prototype.numberOfActiveRequests = function()
		{
			return vx_ActiveAjaxRequests.count;
		}
		
		vx_AjaxUtil.prototype.numberOfQueuedRequests = function()
		{
			return vx_QueuedAjaxRequests.count;
		}
		
		vx_AjaxUtil.prototype.numberOfRequests = function()
		{
			return this.numberOfActiveRequests() + this.numberOfQueuedRequests();
		}
		
		vx_AjaxUtil.prototype.numberOfActiveServiceRequests = function(service)
		{
			return this.__numberOf__Requests(vx_ActiveAjaxRequests, service);
		}
		
		vx_AjaxUtil.prototype.numberOfQueuedServiceRequests = function(service)
		{
			return this.__numberOf__Requests(vx_QueuedAjaxRequests, service);
		}
		
		vx_AjaxUtil.prototype.numberOfServiceRequests = function(service)
		{
			return this.numberOfActiveServiceRequests(service) + this.numberOfQueuedServiceRequests(service)
		}
		
		vx_AjaxUtil.prototype.numberOfServiceMethodRequests = function(service, method)
		{
			return this.numberOfServiceRequests(service + '/' + method);
		}
		
		vx_AjaxUtil.prototype.numberOfActiveServiceMethodRequests = function(service, method)
		{
			return this.numberOfActiveServiceRequests(service + '/' + method);
		}
		
		vx_AjaxUtil.prototype.numberOfQueuedServiceMethodRequests = function(service, method)
		{
			return this.numberOfQueuedServiceRequests(service + '/' + method);
		}
		
		vx_AjaxUtil.__initialized = true;
	}
}
var vx_AjaxUtil = new vx_AjaxUtil();

function vx_ActiveXmlHttpRequest()
{
	if(typeof vx_ActiveXmlHttpRequest.__initialized == 'undefined')
	{
		vx_ActiveXmlHttpRequest.prototype.__createXMLHttpRequest = function()
		{
			var result;
			if (window.XMLHttpRequest) result = new XMLHttpRequest();
			else if (window.vx_progid) result = new ActiveXObject(window.vx_progid);
			else
			{
				//Pulled "'Msxml2.XMLHTTP.5.0', 'Msxml2.XMLHTTP.4.0'," and ", 'MSXML2.XMLHTTP' do to MSDN rec.
				var progIDs = ['Msxml2.XMLHTTP.6.0', 'MSXML2.XMLHTTP.3.0', 'Microsoft.XMLHTTP'];
				for (var i = 0; !result && i < progIDs.length; ++i)
				{
					var progID = progIDs[i];
					try
					{
						var x = new ActiveXObject(progID);
						window.vx_progid = progID;
						result = x;
					}
					catch(e) { }
				}
			}
			return result;
		}
		 vx_ActiveXmlHttpRequest.__initialized = true;
	}
	
	this.request = this.__createXMLHttpRequest();
	if(vx_ActiveXmlHttpRequests) vx_ActiveXmlHttpRequests[this.index = vx_ActiveXmlHttpRequests.length] = this;
}

function vx_AjaxRequest(serviceUrl, method)
{
	if(!serviceUrl) throw new Error('You must supply a service URL for the request.');
	if(typeof serviceUrl != 'string') throw new Error('serviceUrl must be a string.');
	
	this.serviceUrl = serviceUrl;
	this.serviceMethod = method;
	this.userName = null;
	this.password = null;
	this.parameters = new Dictionary();
	this.readyState = 0;
	this.response = null;
	this.responseTime = 0;
	this.cacheResponse = true;
	this.asynchronous = true;
	this.timeout = 0;
	this.allowMultiple = false;
	this.allowMultipleService = true;
	this.allowMultipleServiceMethod = true;
	this.aborted = false;
	this.retryCount = 0;
	
	this.__id = null;
	this.__timeoutID = null;
	this.__holdingID = null;
	this.__start = 0;
	this.__requestHandlers = [];
	this.__requestHandlersArgs = [];
	this.__responseHandlers = [];
	this.__responseHandlersArgs = [];
	this.__abortHandlers = [];
	this.__abortHandlersArgs = [];
	this.__listeners = [];
	this.__listenersArgs = [];
	this.__instance = null;
	this.__readyStates = ['UNINITIALIZED', 'LOADING', 'LOADED', 'INTERACTIVE', 'COMPLETED'];
	this.__maxRetries = 3;
	
	if(typeof vx_AjaxRequest.__initialized == 'undefined')
	{
		vx_AjaxRequest.prototype.toString = function()
		{
			if(typeof this.serviceUrl == 'undefined' || this.serviceUrl == null) 
				throw new Error('This object is not properly initialized.  serviceUrl is not set.');
				
			var result = new StringBuilder(this.serviceUrl);
			if(this.serviceMethod)
			{
				result.append('/');
				result.append(this.serviceMethod);
			}
			if(this.parameters.count > 0)
			{
				if(!this.serviceUrl.contains('?') && !(this.serviceMethod && this.serviceMethod.contains('?')))
					result.append('?');
				for(var i = 0; i < this.parameters.count; i++)
				{
					result.appendFormat('{0}={1}', escape(this.parameters.keys[i]), escape(this.parameters.values[i]));
					if(i < this.parameters.count - 1)
						result.append('&');
				}
			}
			return result.toString();
		}
		
		vx_AjaxRequest.prototype.getState = function()
		{
			var result = 'UNKNOWN';
			if(this.readyState > -1 && this.readyState < this.__readyStates.length)
				result = this.__readyStates[this.readyState];
			return result;
		}

		vx_AjaxRequest.prototype.addRequestHandler = function(handler)
		{
			if(typeof handler != 'function') throw new Error('Handler must be a function or method');

			var index = this.__requestHandlers.length;
			this.__requestHandlers[index] = handler;
			if(typeof arguments == 'undefined' || arguments.length < 2)
				this.__requestHandlersArgs[index] = null;
			else
				this.__requestHandlersArgs[index] = arguments;
		}
		
		vx_AjaxRequest.prototype.removeRequestHandler = function(handler)
		{
			if(typeof handler != 'function') throw new Error('Handler must be a function or method');

			if(!this.__requestHandlers.contains(handler))
				throw new Error('this handler is not registered');
			
			for(var index = 0; index < this.__requestHandlers.length; index++)
			{
				if(this.__requestHandlers[index] == handler)
				{
					if(arguments.length > 1 && this.__requestHandlersArgs[index] 
						&& (arguments.length == this.__requestHandlersArgs[index].length))
					{
						var match = true;
						for(var arg = 1; match && arg < this.__requestHandlersArgs[index].length; arg++)
						{
							match = (this.__requestHandlersArgs[index][arg] == arguments[arg])
						}
						if(match)
						{
							delete this.__requestHandlers[index];
							delete this.__requestHandlersArgs[index];
						}
					}
					else
					{
						delete this.__requestHandlers[index];
						delete this.__requestHandlersArgs[index];
					}	
				}
			}
		}
		
		vx_AjaxRequest.prototype.addResponseHandler = function(handler)
		{
			if(typeof handler != 'function') throw new Error('Handler must be a function or method');

			var index = this.__responseHandlers.length;
			this.__responseHandlers[index] = handler;
			if(typeof arguments == 'undefined' || arguments.length < 2)
				this.__responseHandlersArgs[index] = null;
			else
				this.__responseHandlersArgs[index] = arguments;	
		}
		
		vx_AjaxRequest.prototype.removeResponseHandler = function(handler)
		{
			if(typeof handler != 'function') throw new Error('Handler must be a function or method');

			if(!this.__responseHandlers.contains(handler))
				throw new Error('this handler is not registered');
			
			for(var index = 0; index < this.__responseHandlers.length; index++)
			{
				if(this.__responseHandlers[index] == handler)
				{
					if(arguments.length > 1 && this.__responseHandlersArgs[index] 
						&& (arguments.length == this.__responseHandlersArgs[index].length))
					{
						var match = true;
						for(var arg = 1; match && arg < this.__responseHandlersArgs[index].length; arg++)
						{
							match = (this.__responseHandlersArgs[index][arg] == arguments[arg])
						}
						if(match)
						{
							delete this.__responseHandlers[index];
							delete this.__responseHandlersArgs[index];
						}
					}
					else
					{
						delete this.__responseHandlers[index];
						delete this.__responseHandlersArgs[index];
					}	
				}
			}
		}
		
		vx_AjaxRequest.prototype.addAbortHandler = function(handler)
		{
			if(typeof handler != 'function') throw new Error('Handler must be a function or method');

			if(this.__abortHandlers.contains(handler))
				throw new Error('this handler is already registered');
				
			var index = this.__abortHandlers.length;
			this.__abortHandlers[index] = handler;
			if(typeof arguments == 'undefined' || arguments.length < 2)
				this.__abortHandlersArgs[index] = null;
			else
				this.__abortHandlersArgs[index] = arguments;
		}
		
		vx_AjaxRequest.prototype.removeAbortHandler = function(handler)
		{
			if(typeof handler != 'function') throw new Error('Handler must be a function or method');

			if(!this.__abortHandlers.contains(handler))
				throw new Error('this handler is not registered');
			
			for(var index = 0; index < this.__abortHandlers.length; index++)
			{
				if(this.__abortHandlers[index] == handler)
				{
					if(arguments.length > 1 && this.__abortHandlersArgs[index] 
						&& (arguments.length == this.__abortHandlersArgs[index].length))
					{
						var match = true;
						for(var arg = 1; match && arg < this.__abortHandlersArgs[index].length; arg++)
						{
							match = (this.__abortHandlersArgs[index][arg] == arguments[arg])
						}
						if(match)
						{
							delete this.__abortHandlers[index];
							delete this.__abortHandlersArgs[index];
						}
					}
					else
					{
						delete this.__abortHandlers[index];
						delete this.__abortHandlersArgs[index];
					}	
				}
			}
		}
		
		vx_AjaxRequest.prototype.addListener = function(handler)
		{
			if(typeof handler != 'function') throw new Error('Handler must be a function or method');

			var index = this.__listeners.length;
			this.__listeners[index] = handler;
			if(typeof arguments == 'undefined' || arguments.length < 2) 
				this.__listenersArgs[index] = null;
			else
				this.__listenersArgs[index] = arguments;
		}
		
		vx_AjaxRequest.prototype.removeListener = function(handler)
		{
			if(typeof handler != 'function') throw new Error('Handler must be a function or method');

			if(!this.__listeners.contains(handler))
				throw new Error('this handler is not registered');
			
			for(var index = 0; index < this.__listeners.length; index++) 
			{
				if(this.__listeners[index] == handler)
				{
					if(arguments.length > 1 && this.__listenersArgs[index] 
						&& (arguments.length == this.__listenersArgs[index].length))
					{
						var match = true;
						for(var arg = 1; match && arg < this.__listenersArgs[index].length; arg++)
						{
							match = (this.__listenersArgs[index][arg] == arguments[arg])
						}
						if(match)
						{
							delete this.__listeners[index];
							delete this.__listenersArgs[index];
						}
					}
					else
					{
						delete this.__listeners[index];
						delete this.__listenersArgs[index];
					}	
				}
			}
		}
		
		vx_AjaxRequest.prototype.__fireRequestHandlers = function()
		{
			for(var handler = 0; handler < this.__requestHandlers.length; handler++)
			{
				if(typeof this.__requestHandlers[handler] == 'function')
				{
					var sbhandler = new StringBuilder();
					sbhandler.append('this.__requestHandlers[handler](');
					if(typeof this.__requestHandlersArgs[handler] != 'undefined' && this.__requestHandlersArgs[handler] != null)
					{
						for(var arg = 1; arg < this.__requestHandlersArgs[handler].length; arg++)
						{
							sbhandler.append('this.__requestHandlersArgs[handler][' + arg + ']');
							if(arg < this.__requestHandlersArgs[handler].length - 1) sbhandler.append(', ');
						}
					}
					sbhandler.append(');'); 
					
					eval(sbhandler.toString());
				}
			}
		}
		
		vx_AjaxRequest.prototype.__fireResponseHandlers = function()
		{
			for(var handler = 0; handler < this.__responseHandlers.length; handler++)
			{
				if(typeof this.__responseHandlers[handler] == 'function')
				{
					var sbhandler = new StringBuilder();
					sbhandler.append('this.__responseHandlers[handler](this.response');
					if(typeof this.__responseHandlersArgs[handler] != 'undefined' && this.__responseHandlersArgs[handler] != null)
					{
						for(var arg = 1; arg < this.__responseHandlersArgs[handler].length; arg++)
							sbhandler.append(', this.__responseHandlersArgs[handler][' + arg + ']');
					}
					sbhandler.append(');'); 
					
					eval(sbhandler.toString());
				}
			}
		}
		
		vx_AjaxRequest.prototype.__fireAbortHandlers = function()
		{
			for(var handler = 0; handler < this.__abortHandlers.length; handler++)
			{
				if(typeof this.__abortHandlers[handler] == 'function')
				{
					var sbhandler = new StringBuilder();
					sbhandler.append('this.__abortHandlers[handler](');
					if(typeof this.__abortHandlersArgs[handler] != 'undefined' && this.__abortHandlersArgs[handler] != null)
					{
						for(var arg = 1; arg < this.__abortHandlersArgs[handler].length; arg++)
						{
							sbhandler.append('this.__abortHandlersArgs[handler][' + arg + ']');
							if(arg < this.__abortHandlersArgs[handler].length - 1) sbhandler.append(', ');
						}
					}
					sbhandler.append(');'); 
					
					eval(sbhandler.toString());
				}
			}
		}
		
		vx_AjaxRequest.prototype.__fireListeners = function()
		{
			for(var handler = 0; handler < this.__listeners.length; handler++)
			{
				if(typeof this.__listeners[handler] == 'function')
				{
					var sbhandler = new StringBuilder();
					sbhandler.append('this.__listeners[handler](this, ');
					if(typeof this.__listenersArgs[handler] != 'undefined' && this.__listenersArgs[handler] != null)
					{
						for(var arg = 1; arg < this.__listenersArgs[handler].length; arg++)
							sbhandler.append(', this.__listenersArgs[handler][' + arg + ']');
					}
					sbhandler.append(');'); 
					
					eval(sbhandler.toString());
				}
			}
		}
		
		vx_AjaxRequest.prototype.__onReadyStateChange = function()
		{
			if(!this.aborted)
			{
				if(this.__instance && this.__instance.request)
					this.readyState = this.__instance.request.readyState;

				this.__fireListeners();

				if(this.readyState == 4)
				{
					if(this.timeout > 0) clearTimeout(this.__timeoutID);
					if(this.__id && vx_ActiveAjaxRequests && vx_ActiveAjaxRequests.containsKey(this.__id)) vx_ActiveAjaxRequests.remove(this.__id);
				
					if(this.__instance)
					{
						this.responseTime = new Date().getTime() - this.__start;
						this.response = new vx_AjaxResponse(this);
					}
					else
						this.response = vx_AjaxResponseCache.item(this.toString());
					
					if(this.response && this.response.httpStatusCode == 200)
					{
						if (this.cacheResponse && vx_AjaxResponseCache && !vx_AjaxResponseCache.containsKey(this.toString()))
							vx_AjaxResponseCache.add(this.toString(), this.response);

						this.__fireResponseHandlers();
						
						if(this.__instance && this.__instance.request)
							delete vx_ActiveXmlHttpRequests[this.__instance.index];
						
						delete this.__instance;
						this.__instance = null;
					}
					else if (this.retryCount < this.__maxRetries)
					{
						if(this.__instance && this.__instance.request)
							delete vx_ActiveXmlHttpRequests[this.__instance.index];
						
						delete this.__instance;
						this.__instance = null;
						this.retryCount++;
						this.readyState = 1;
						this.send();
					}
					else
					{
						this.__fireResponseHandlers();
						
						if(this.__instance && this.__instance.request)
							delete vx_ActiveXmlHttpRequests[this.__instance.index];
						
						delete this.__instance;
						this.__instance = null;
					}
				}
			}
		}
		
		vx_AjaxRequest.prototype.abort = function()
		{
			this.aborted = true;
			if(this.__holdingID)
			{
				clearInterval(this.__holdingID);
				if(vx_QueuedAjaxRequests && vx_QueuedAjaxRequests.keys.contains(this.__id))
					vx_QueuedAjaxRequests.remove(this.__id);
				this.__holdingID = null;
			}
			if(typeof this.__instance != 'undefined' && this.__instance != null 
				&& typeof this.__instance.request != 'undefined' && this.__instance.request != null
				&& typeof this.__instance.request.readyState != 'undefined'
				&& this.__instance.request.readyState > 0 && this.__instance.request.readyState < 4)
			{
				this.__instance.request.abort();
				if(this.__instance)
				{
					if(vx_ActiveXmlHttpRequests)
						delete vx_ActiveXmlHttpRequests[this.__instance.index];
					if(vx_ActiveAjaxRequests) vx_ActiveAjaxRequests.remove(this.__id)
					delete this.__instance;
					this.__instance = null;
				}
			}
			this.__fireAbortHandlers();
		}
		
		vx_AjaxRequest.prototype.send = function()
		{
			if(typeof this.serviceUrl == 'undefined' || this.serviceUrl == null) 
				throw new Error('This object is not properly initialized.  serviceUrl is not set.');
				
			if(typeof this.__id == 'undefined' || this.__id == null)
			{
				var sbk = new StringBuilder(new Date().getTime().toString());
				sbk.append('_');
				sbk.append(this.toString());
				this.__id = sbk.toString();
				delete sbk;
			}
			
			this.__fireRequestHandlers();
			
			if(this.cacheResponse && vx_AjaxResponseCache && vx_AjaxResponseCache.keys.contains(this.toString()))
			{
				this.readyState = 4;
				this.__onReadyStateChange();
			}
			else
			{
				
				var clearToSend = true;
				clearToSend = (this.allowMultiple || vx_AjaxUtil.numberOfActiveServiceRequests(this.toString()) == 0);
				if(clearToSend) clearToSend = (this.allowMultipleServiceMethod || vx_AjaxUtil.numberOfActiveServiceMethodRequests(this.serviceUrl, this.serviceMethod) == 0);
				if(clearToSend) clearToSend = (this.allowMultipleService || vx_AjaxUtil.numberOfActiveServiceRequests(this.serviceUrl) == 0);
				if(clearToSend)
				{
					this.__instance = new vx_ActiveXmlHttpRequest();
					if(this.__instance && this.__instance.request)
					{
						if(vx_ActiveAjaxRequests)
							vx_ActiveAjaxRequests.add(this.__id, this);
					
						var method = 'GET';
						//IIS6.0 webservices protect against missing http header "content-length", 
						//which is not supplied if nothing is passed with the xmlhttp.send method,
						//and the request is a post.
//						if(this.parameters.count == 0)
//							method = 'GET';
						if ($.browser.mozilla)
							method = 'POST';
						
						var url = null;
						var data = null;
						if (method == 'POST')
						{
							var parts = this.toString().split('?');
							url = parts[0];
							if(parts.length > 1) 
							{
								data = parts[1];
							}
						}
						else
						{
							url = this.toString();
						}
						if(this.userName)
							this.__instance.request.open(method, url, (this.asynchronous && (this.__responseHandlers.length > 0 || this.__listeners.length > 0)), this.userName, this.password);
						else
							this.__instance.request.open(method, url, (this.asynchronous && (this.__responseHandlers.length > 0 || this.__listeners.length > 0)));
							
						var me = this;
						this.__instance.request.onreadystatechange = function() {me.__onReadyStateChange();}
							
						this.__instance.request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
						//Post page variables to web service request
						if(typeof(tracker_cid) != 'undefined' && tracker_cid)
							this.__instance.request.setRequestHeader("aid", tracker_cid);
						if(typeof(tracker_sid) != 'undefined' && tracker_sid)
							this.__instance.request.setRequestHeader("sid", tracker_sid);
						if(typeof(tracker_pvid) != 'undefined' && tracker_pvid)
							this.__instance.request.setRequestHeader("pvid", tracker_pvid);
						if(typeof(tracker_zip) != 'undefined' && tracker_zip)
							this.__instance.request.setRequestHeader("zip", tracker_zip);
						if(typeof(tracker_brand) != 'undefined' && tracker_brand)
							this.__instance.request.setRequestHeader("brand", tracker_brand);
						this.__start = new Date().getTime();
						if(this.timeout > 0 && vx_ActiveAjaxRequests) this.__timeoutID = setTimeout("vx_ActiveAjaxRequests.item('" + this.__id + "').abort()", this.timeout);
						this.__instance.request.send(data);
						
						if (window.XMLHttpRequest && !this.asynchronous)
						{
							//Gecko browsers do not fire the onreadystatechange event for synchronous calls.
							this.__onReadyStateChange();
						}
					}
					else throw new Error('Unable to create a new ActiveXmlHttpRequest');
				}
				else if(this.cacheResponse)
				{
					if(this.__holdingID == null)
					{
						if(vx_QueuedAjaxRequests && !vx_QueuedAjaxRequests.containsKey(this.__id))
							vx_QueuedAjaxRequests.add(this.__id, this);
						var me = this;
						me.__holdingID = setInterval(function()
						{
							if(vx_AjaxResponseCache && vx_AjaxResponseCache.containsKey(me.toString()))
							{
								clearInterval(me.__holdingID);
								if(vx_QueuedAjaxRequests && vx_QueuedAjaxRequests.containsKey(me.__id))
								{
									try
									{
										vx_QueuedAjaxRequests.remove(me.__id);
									}
									catch(e){}
								}
								me.__holdingID = null;
								me.readyState = 4;
								me.__onReadyStateChange();
							}
							else 
							{
								if(me.allowMultiple || vx_AjaxUtil.numberOfActiveServiceRequests(me.toString()) == 0)
								{
									if(me.allowMultipleServiceMethod || vx_AjaxUtil.numberOfActiveServiceMethodRequests(me.serviceUrl, me.serviceMethod) == 0)
									{
										if(me.allowMultipleService || vx_AjaxUtil.numberOfActiveServiceRequests(me.serviceUrl) == 0)
										{
											clearInterval(me.__holdingID);
											if(vx_QueuedAjaxRequests && vx_QueuedAjaxRequests.containsKey(me.__id))
												vx_QueuedAjaxRequests.remove(me.__id);
											me.__holdingID = null;
											me.send();
										}
									}
								}
							}
						}, 500);
					}
				}
				else
				{
					if(this.__holdingID == null)
					{
						if(vx_QueuedAjaxRequests && !vx_QueuedAjaxRequests.containsKey(this.__id))
							vx_QueuedAjaxRequests.add(this.__id, this);
						var me = this;
						me.__holdingID = setInterval(function()
						{
							if(me.allowMultiple || vx_AjaxUtil.numberOfActiveServiceRequests(me.toString()) == 0)
							{
								if(me.allowMultipleServiceMethod || vx_AjaxUtil.numberOfActiveServiceMethodRequests(me.serviceUrl, me.serviceMethod) == 0)
								{
									if(me.allowMultipleService || vx_AjaxUtil.numberOfActiveServiceRequests(me.serviceUrl) == 0)
									{
										clearInterval(me.__holdingID);
										if(vx_QueuedAjaxRequests && vx_QueuedAjaxRequests.containsKey(me.__id))
											vx_QueuedAjaxRequests.remove(me.__id);
										me.__holdingID = null;
										me.send();
									}
								}
							}
						}, 500);
					}
				}
			}
			
			return this.response;
		}
		
		vx_AjaxRequest.__initialized = true;
	}
}

function vx_AjaxResponse(vx_ajax)
{
	if(!(vx_ajax instanceof vx_AjaxRequest)) throw new Error('An AjaxResponse can only be constructed using an vx_AjaxRequest Object, that has completed a request.')

	if(typeof vx_AjaxResponse.__initialized == 'undefined')
	{
		vx_AjaxResponse.prototype.__parseResponse = function()
		{
			var result = null; 
			if(this.httpStatusCode == 200 && this.xml && this.xml.documentElement && this.xml.documentElement.hasChildNodes())
			{
				var doc = this.xml.documentElement;
				if((doc.childNodes[0] && doc.childNodes[0].hasChildNodes()) || (doc.childNodes[1] && doc.childNodes[1].hasChildNodes()))
				{
					if(doc.childNodes[0].firstChild)
						this.value = doc.childNodes[0].firstChild.nodeValue;
					else if (doc.childNodes[1] && doc.childNodes[1].firstChild) //Becuase Gecko thinks a \r is a node.
						this.value = doc.childNodes[1].firstChild.nodeValue;
					if(this.value)
					{
						if(this.value.indexOf('{') == 0)
						{
							result = new Array();
							for(n = 0; n < doc.childNodes.length; n++)
							{
								if(doc.childNodes[n] && doc.childNodes[n].firstChild 
									&& doc.childNodes[n].firstChild.nodeValue && doc.childNodes[n].firstChild.nodeValue.indexOf('{') == 0)
								{
									eval('result.push(' + doc.childNodes[n].firstChild.nodeValue + ');');
								}
							}
						}
						else
						{
							result = new Array();
							for(n = 0; n < doc.childNodes.length; n++)
							{
								if(doc.childNodes[n] && doc.childNodes[n].firstChild && doc.childNodes[n].firstChild.nodeValue)
									result.push(doc.childNodes[n].firstChild.nodeValue);
							}
						}
					}
				}
				else
				{
					this.value = doc.firstChild.nodeValue;
					if(this.value.indexOf('{') == 0)
						eval('result = ' + this.value);	
				}
			}
			return result;
		}
		
		vx_AjaxResponse.__initialized = true;
	}

	this.responseTime = vx_ajax.responseTime;
	var x = vx_ajax.__instance.request;

	try
	{
		//Firefox has an issue where accessing the status property can throw an exception.
		this.httpStatusCode = (x.status ? x.status : null);
		this.httpStatusText = (x.statusText ? x.statusText : null);
	}
	catch(ex)
	{
		this.httpStatusCode = null;
		this.httpStatusText = null;
	}
	this.body = null;
	this.stream = null;
	if(!window.XMLHttpRequest)
	{
		this.body = x.responseBody;
		this.stream = x.responseStream;
	}

	this.value = null;
	this.text = x.responseText;
	this.xml = x.responseXML;
	this.object = this.__parseResponse();
	this.error = null;
	if(this.httpStatusCode != 200)
		this.error = {'number': this.httpStatusCode, 'message': this.text, 'description': this.httpStatusText};
}

function LazyRef(id, instance)
{
	this.id = id;
	this.__instance = instance;
	this.instance = function()
	{
		if(!this.__instance && this.id)
		{
			var req = new vx_AjaxRequest('/_webservices/ObjectSerializationRequests.asmx', 'GetObject');
			req.parameters.add('id', this.id);
			req.asynchronous = false;
			var response = req.send();
			if(response && response.object)
				this.__instance = response.object;
			
			response = null;
		}
		return this.__instance;
	}	
}

