// This define's an object describing the request and does not need a constructor because there are not methods
			// on this object
			/* This object literal contains all the information used by the RequestManager object
			var oRequest = {
			
				priority: 1,
				type: 'post',
				url: 'example.htm',
				data: 'post_data',
				oncancel: function () {},
				onsuccess: function () {},
				onnotmodified: function () {},
				onfailure: function () {},
				scope: oObject
			
			}*/
			
			// Handles the request per page, and according to HTTP 1.1  there can only two requests per page at a time
			var RequestManager = (function () {
			
				var oManager = {
					
					// used to ensure that low priority queues will be requested by setting atime limit on how
					// long they last before they must be submitted
					AGE_LIMIT : 5000,
					
					// used if the priority property in the send function is not a number
					DEFAULT_PRIORITY : 10,
					
					// every 250 milliseconds the _checkActiveRequests
					INTERVAL : 250,
					
					// An array of active request
					_active : new Array(),
					
					// Returns a neative number if the first number is less than the second (first should come before the second)
					// Returns a positive number is the first number is greater than the second (first shoudl come after the second)
					// Returns 0 if the two number are equal and should not change position
					_pending : new PriorityQueue(function (oRequest1, oRequest2) {
						return oRequest1.priority - oRequest2.priority;
					}),
					
					// promotes queues with low priorities to be called after a certain period defined above
					// with AGE_LIMIT, number is in milliseconds
					_agePromote : function () {
					
						for (var i =0; i < this._pending.size(); i++) {
							var oRequest = this._pending.item(i);
							oRequest.age += this.INTERVAL;
							if (oRequest.age >= this.AGE_LIMIT) {
								oRequest.age = 0;
								oRequest.priority--;
							}
						}
						this._pending.prioritize();
					},
					
					_checkActiveRequests : function () {
					
						var oRequest = null;
						var oTransport = null;
						
						for (var i=this._active.length-1; i >=0; i--) {
						
							oRequest = this._active[i];
							oTransport = oRequest.transport;
							
							if (oTransport.readyState == 4) {
								oRequest.active = false;
								this._active.splice(i, 1);
								var fnCallback = null;
								if (oTransport.status >= 200 && oTransport.status < 300) {
									if (typeof oRequest.onsuccess == 'function') {
										fnCallback = oRequest.onsuccess;
									}
								} else if (oTransport.status == 304) {
									if (typeof oRequest.onnotmodified == 'function') {
										fnCallback = oRequest.onnotmodified;
									}
								} else {
									if (typeof oRequest.onfailure == 'function') {
										fnCallback = oRequest.onfailure;
									}
								}
								if (fnCallback != null) {
								
									setTimeout((function (fnCallback, oRequest, oTransport) {
										
										return function () {
													
											fnCallback.call(oRequest.scope||window, {
											status : oTransport.status,
											data : ((oRequest.responseType == 'XML')?oTransport.responseXML:oTransport.responseText),
											request : oRequest});
											
										}
											
									}) (fnCallback, oRequest, oTransport), 1);
								
								}
							}
						
						}
					
					
					},
					
					// creates the XMLHttpRequest Object
					_createTransport : function () {
					
						if (typeof XMLHttpRequest != 'undefined') {
							return new XMLHttpRequest();
						} else if (typeof ActiveXObject != 'undefined') {
							var oHttp = null;
							try {
								oHttp = new ActiveXObject('MSXML2.XmlHttp.6.0');
								return oHttp;
							} catch (oEx) {
								try {
									oHttp = new ActiveXObject ('MSXML2.XmlHttp.3.0');
									return oHttp;
								} catch (oEx2) {
									throw Error('Cannot create XMLHttp object.');
								}
							}
						
						}
					
					},
					
					// the function first checks to see if the request object is avalialable.
					// if the object is, which means no more than 2 requests are active, it fires
					// off another request by callingon the get method of the PriorityQueue object
					// the active property is set to active to show that it is sending the information
					_sendNext : function () {
					
						if (this._active.length < 2) {
						
							var oRequest = this._pending.get();
							if (oRequest != null) {
								this._active.push(oRequest);
								oRequest.transport = this._createTransport();
								oRequest.transport.open(oRequest.type, oRequest.url, true);
								if (oRequest.type == 'POST') {
									oRequest.transport.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
								}
								oRequest.transport.setRequestHeader('If-Modified-Since', 'Sat, 1 Jan 2000 00:00:00 GMT');
								oRequest.transport.send(oRequest.data);
								oRequest.active = true;
							}
						
						}
					
					},
					
					// Cancels a request
					cancel : function (oRequest) {
					
						if (!this._pending.remove(oRequest)) {
						
							oRequest.transport.abort();
							
							if (this._active[0] === oRequest) {
								this._active.shift();
							} else if (this._active[1] === oRequest) {
								this._active.pop();
							}
							
							if (typeof oRequest.oncancel == 'function') {
								oRequest.oncancel.call(oRequest.scope||window,
									{request : oRequest});
							}
						}
					},
					
					// Periodic Refresh
					poll : function (oRequest) {
						oRequest.priority = 3;
						this.send(oRequest);
					},
					
					// predictive fetch
					prefetch : function (oRequest) {
						oRequest.priority = 5;
						this.send(oRequest);
					},
					
					// First checks whether the priority is valid in the request description object
					// if not a number a default priority of 10 is defined, thus eliminating the rish of an error
					// occuring in the queue
					// the active property is set to false, which indicates if the request is active or not
					// last step is to add the object into the priority queue
					send : function (oRequest) {
					
						if (typeof oRequest.priority != 'number') {
							oRequest.priority = this.DEFAULT_PRIORITY;
						}
						
						oRequest.active = false;
						oRequest.age = 0;
						this._pending.put(oRequest);
						
				},
				
				// user action
				submit : function (oRequest) {
					oRequest.priority = 0;
					this.send(oRequest);
				},
				
				// Submission Throttling
				submitPart : function (oRequest) {
					oRequest.priority = 2;
					this.send(oRequest);
				}
			};
				//initialization
				setInterval(function () {
					RequestManager._checkActiveRequests();
					RequestManager._sendNext();
					RequestManager._agePromote();
				}, oManager.INTERVAL);
				
				// return the object
				return oManager; 
			
			}) ();