
	var emprise = {};
	
	emprise.XMLRequestPool = {

		__activePool: [],
		__requestPool: [],
		__activeXObjects: ["MSXML2.XMLHTTP.5.0","MSXML2.XMLHTTP.4.0","MSXML2.XMLHTTP.3.0","MSXML2.XMLHTTP","Microsoft.XMLHTTP"],
		__activeRequestType: null,
		__activeRequestIndex: undefined,
		// JHM: 2007-09-25 - Added fatalErrors property in order to allow special processing for certain server response codes which normally indicate fatal error
		// Removing a code from this list will allow requests to pass through to their callback
		fatalErrors: [400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,500,501,502,503,504,505],

		MaxPoolSize: 8,

		// Create a new http request object
		__createHTTPRequest: function() {

			// Determine the type of request object to create, only has to be done once
			if (this.__activeRequestType == null) {

				// Native XMLHttpRequest object (Mozilla, etc.)
				try {
					this.__activeRequestType = "Native";
					return new XMLHttpRequest();
				} catch (e) {}

				// Microsoft ActiveX object
				for (var i = 0; i < this.__activeXObjects.length; i++) {
					try {
						this.__activeRequestType = this.__activeXObjects[i];
						this.__activeRequestIndex = i;
						return new ActiveXObject(this.__activeXObjects[i]);
					} catch (e) {}
				}

			} else {
				if (this.__activeRequestType == "Native") {
					try { return new XMLHttpRequest(); } catch (e) {}
				} else {
					try { return new ActiveXObject(this.__activeRequestType); } catch (e) {}
				}
			}

			// No request object found
			this.__activeRequestType = null;
			throw "Unable to create XMLHttpRequest object!";

		},
		// Pull a request object from the pool or create one
		__getHttpRequest: function() {
			if (this.__requestPool.length > 0) {
				return this.__requestPool.pop();
			}
			return this.__createHTTPRequest();
		},
		// Return a request object to the pool
		__returnHttpRequest: function(request) {
			// Make sure we don't have too many objects floating around
			request.onreadystatechange = function() { };
			if (this.__requestPool.length >= this.MaxPoolSize) { delete request; }
			else { this.__requestPool.push(request); }
		},
		cancelRequest: function(request) {
			request.abort();
			this.__returnHttpRequest(request);			
		},
		// JHM: 2007-09-25 - Added onError parameter, defined as function(message, reference) callback
		sendRequest: function(url, handler, data, reference, onError) {

			if (onError == undefined) { onError = null; }

			// Get a request object from the pool
			// JHM: 2007-09-25 - Added try/catch to handle failure to create any request object
			try {
				var request = this.__getHttpRequest();
			} catch (e) {
				if (onError != null) {
					onError("Error Creating XMLHttpRequest: " + e.message, reference);
				}
				return false;
			}

			// JHM: 2007-08-15 - Added IE check, when using 7 and the native XMLHttpRequest
			// object or 6/7 and the 5.0 version of the ActiveX object requests to local files
			// will fail.  The code now handles IE separately and catches request.open failures,
			// updating the __activeRequestType and trying again with the next in line
			try {
				// Send the request (asynchronous if handler is valid)
				request.open((data==undefined?"GET":"POST"), url, (handler != undefined));
			} catch (e) {
				if (emprise.__isIE) {
					request.onreadystatechange = function() { };
					delete request;

					if (this.__activeRequestType == "Native") {
						this.__activeRequestIndex = 0;
					}

					var i = this.__activeRequestIndex;
					for (; i < this.__activeXObjects.length; i++) {
						try {
							this.__activeRequestType = this.__activeXObjects[i];
							this.__activeRequestIndex = i;

							request = new ActiveXObject(this.__activeXObjects[i]);
							request.open((data==undefined?"GET":"POST"), url, (handler != undefined));

							break;
						} catch (e) {
							request.onreadystatechange = function() { };
							delete request;
							continue;
						}
					}

				// JHM: 2007-09-25 - Added error checking for non-IE failure on open request
				} else if (onError != null) {
					onError("Error opening connection: " + e.message, reference);
				}
			}

			// JHM: 2007-12-07 - Added correct headers when sending a request as POST
			if (data != undefined) {
				request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
				request.setRequestHeader("Content-length", data.length);
				request.setRequestHeader("Connection", "close");
			}

			// Build the call back if handler is valid
			if(handler) {
				var self = this;
				request.onreadystatechange = function() {
					// Ignore all states except complete
					if (request.readyState == 4) {
						// Clear state change event
						request.onreadystatechange = function() { };
						// JHM: 2007-09-25 - Added checking status code for >= 400, trigger onError (if defined) and don't
						// execute callback
						var statusValid = true;
						var errorCodes = self.fatalErrors;
						for (var i = 0; i < errorCodes.length; i++) {
							if (request.status == errorCodes[i]) {
								statusValid = false;
								if (onError != null) {
									onError("Error retrieving file: " + request.status, reference, request);
								}
								break;
							}
						}
						if (statusValid) {
							// Handle response
							handler(request, reference);
						}
						// Return the http object to the pool
						self.__returnHttpRequest(request);
					}
				};
			} else {
				// Clear state change event
				request.onreadystatechange = function() { };
			}

			try {
				if (data == undefined) { data = null; }

				// Open the connection
				request.send(data);
			} catch (e) {
				// Return the request object to the pool
				this.__returnHttpRequest(request);
				// JHM: 2007-09-25 - Added calling onError (if defined) rather than throwing an exception
				if (onError != null) {
					onError("Connection Failed: " + e.message, reference);
				}
			}

			return request;
		}

	};			

