
	function ajaxConnection(instanceName, parentInstanceName) {
			if (parentInstanceName == null) eval(instanceName + " = this;");
		var _instanceName = instanceName;
		var _parentInstanceName = ((parentInstanceName == null) ? null : parentInstanceName);
		var _url = '';
		var _events = new Array;
		var _parameters = new Array;
		_parameters['get'] = new Array;
		_parameters['post'] = new Array;
		_parameters['file'] = new Array;
		var _ajaxInstance = null;
		var outputString = '';
		var _outputSections = new Array;
		var _outputHandler = null;
		var _formBoundary = '-----------------------------' + Math.round(new Date().getTime() / 1000); 
		
			this.openConnection = function() {
					if (window.XMLHttpRequest) {
				  		_ajaxInstance =new XMLHttpRequest();
				  	} else {
				  		_ajaxInstance =new ActiveXObject("Microsoft.XMLHTTP");
				  	}
					
				var getString = this._compileGet();
					if (getString != '') {
						getString += '&';
					}
				getString += 'r=' + this.createEventIdentifier();
				_ajaxInstance.open('POST', _url + '?' + getString, true);
					
				
				_ajaxInstance.onreadystatechange = function() {
					if (_ajaxInstance.readyState==4 && _ajaxInstance.status==200) {
						outputString = _ajaxInstance.responseText;
						var callString = '';
							if (_parentInstanceName != null) callString += _parentInstanceName +'.';
						
						callString += _instanceName;

							if (outputString != '') eval(callString + ".decompileOutput();");
						
						eval(callString + ".callEvent('output');");
  					}
				  }
				/* _ajaxInstance.upload.addEventListener("progress", function(e) {  
					if (e.lengthComputable) {  
							var percentage = Math.round((e.loaded * 100) / e.total);  
									
							var callString = '';
								if (_parentInstanceName != null) callString += _parentInstanceName +'.';
									
							callString += _instanceName;
							
							eval(callString + ".callEvent('loading', '"+percentage+"');");
						}  
				 }, false);  */
								
				/* _ajaxInstance.upload.addEventListener("load", function(e){  
				
					var callString = '';
						if (_parentInstanceName != null) callString += _parentInstanceName +'.';
									
					callString += _instanceName;
					eval(callString + ".callEvent('load');");
				 }, false); */
				 
				_ajaxInstance.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // simulate a file MIME POST request.  
				var formData = this._compileform();
				var postData = this._compilePost();
				//alert(formData.length);
				_ajaxInstance.setRequestHeader("Content-Length", postData.length);  
					//if (formData != '') {
						//_ajaxInstance.sendAsBinary(formData); //No support in newer versions
					//} else {
						_ajaxInstance.send(postData);
					//}
				

			}
			
			this.setUrl = function(url) {
				_url = url;
			}
			
			this.setParameter = function(type, name, value, extraData) {
					if (extraData == null) extraData = '';
					if (!(value instanceof Array)) {
						value = new Array(value);
					}
					for (var n  = 0; n < value.length; n++) {
						var newParameter = new Array;
						newParameter['name'] = name;
						newParameter['value'] = value[n];
						newParameter['extraData'] = extraData;
						
							if (_parameters[type.toLowerCase()] == null) _parameters[type.toLowerCase()] = new Array;
						_parameters[type.toLowerCase()][_parameters[type.toLowerCase()].length] = newParameter;
					}
			}
			
			this._getParameters = function(type) {
					return ((_parameters[type.toLowerCase()] != null) ? _parameters[type.toLowerCase()] : new Array);
			}
			
			this._compileGet = function() {
				var returnString = '';
				var getVars = this._getParameters('get');
					for (var n = 0; n < getVars.length; n++) {
							if (returnString != '') returnString += '&';
						returnString += getVars[n]['name']+'='+getVars[n]['value'];
					}
				return returnString;
			}
			
			this._compilePost = function() {
				var returnString = '';
				var postVars = this._getParameters('post');
					for (var n = 0; n < postVars.length; n++) {
							if (returnString != '') returnString += '&';
						returnString += postVars[n]['name']+'='+escape(postVars[n]['value']);
					}
				return returnString;
			}
			
			this._compileform = function() {
				var form_string = '';
				var postVars = this._getParameters('post');
					for (var n = 0; n < postVars.length; n++) {
						form_string += "--" + _formBoundary + "\r\n";  
						form_string += "Content-Disposition: form-data; name='"+postVars[n]['name']+"'\r\n\r\n";  
						form_string += postVars[n]['value'] + "\r\n";  
					}
				var fileVars = this._getParameters('file');
					for (var n = 0; n < fileVars.length; n++) {
							if ((fileVars[n]['extraData'] == '') || (fileVars[n]['value'] == '')) continue;
						form_string += "--" + _formBoundary + "\r\n";  
						form_string += "Content-Disposition: multipart/form-data; name='"+fileVars[n]['name']+"'; filename='" + fileVars[n]['extraData'] + "'\r\n";  
						form_string += "Content-Type: application/octet-stream\r\n\r\n";
						form_string += fileVars[n]['value'] + "\r\n";  
					}
					if (form_string != '') form_string += "--" + _formBoundary + "--";
					
				return form_string;
			}
			
			this._compileParameters = function(type) {
				var returnString = '';
					if (_parameters[type]) {
							for (var n = 0; n < _parameters[type].length; n++) {
									if (returnString != '') returnString += '&';
								returnString += _parameters[type][n]['name']+'='+_parameters[type][n]['value'];
							}
					}
				return returnString;
			}
			
			this._selectConnectionMethod = function() {
					if (_parameters['post'].length > 0) {
						return 'POST';
					} else {
						return 'GET';
					}
			}
			
			this._removeNewLines = function(string) {
					if (string == null) string = '';
				return string.replace(/[\n\r\t]*/g, '');
			}
			
			this.decompileOutput = function() {
				var string = outputString;//this._removeNewLines(outputString);
				var sections = string.match(/%section([a-zA-Z0-9])+%/g);
					if (sections == null) {
						this._setSection('content', outputString);
					} else{
						
							for (var n = 0; n < sections.length; n++) {
								var sectionName = sections[n].replace(/%/g, '').replace('section', '');
								var regString = "%section" + sectionName + "%(.*)%endSection" + sectionName + "%";
								var regEx = new RegExp('%section' + sectionName + '%((?:.|\n|\r)*)%endSection' + sectionName + '%',"g");
									
									//alert(_parentInstanceName + ' - ' + sectionName.toLowerCase() + ' - ' + _parentInstanceName[sectionName.toLowerCase()]);
								var result = regEx.exec(string);
									if (eval(_parentInstanceName+'.'+sectionName.toLowerCase()) != null) {
										eval(_parentInstanceName+'.'+sectionName.toLowerCase()+"='"+result[1]+"'");
									}
									
									if (result != null) {
										this._setSection(sectionName, result[1]);
									}
								sections[n] = '';
							}
					}
				
			}
			
			this._setSection = function(name, value) {
					if (value == null) value = '';
					if (name == null) {
							for (var sectionName in _outputSections) {
									if (_outputHandler != null) {
										eval(_outputHandler+"(sectionName, value);");
									}
								this.callEvent('onSet'+sectionName.toUpperCase(), value);
							}
					} else {
						_outputSections[name] = value;
							if (_outputHandler != null) {
								eval(_outputHandler+"(name, value);");
								//_outputHandler.setTemplateVariable(sectionName, value);
							}
						this.callEvent('onSet'+name.toUpperCase(), value);
					}
					
			}
			
			this._getSection = function(name) {
					if (_outputSections[name] == null) _outputSections[name] = '';
				return _outputSections[name];
			}
		/*
			Event Handleing.
		*/
			this.createEventIdentifier = function() {
				var identifer = Math.ceil(Math.random()*100000);	
				
				return identifer;
			}
			
			this.createEvents = function(type) {
					if (_events[type] == null) _events[type] = new Array;
			}
			
			this.attachEvent = function(type, functionName, overwritable, overwriteOld) {
				type = type.toLowerCase();
				this.createEvents(type);
					if (overwriteOld == null) overwriteOld= false;
					if (overwritable == null) overwritable = true;
				var newFunctions = new Array;
				
					for (var eventIdentifier in _events[type]) {
							if (!_events[type][eventIdentifier].overwritable || !overwriteOld) newFunctions[eventIdentifier] = _events[type][eventIdentifier];
					}
					
				var newFunction = new Array;
				newFunction['functionCall'] = functionName;
				newFunction['overwritable'] = overwritable;
				
				var newIdentifier =this.createEventIdentifier();
				
				newFunctions[newIdentifier] = newFunction;
				
				_events[type] = newFunctions;
				
				return newIdentifier; //Return the identifier;
			}
			
			this.unAttachEvent = function(type, identifier) {
				type = type.toLowerCase();
				var newFunctions = new Array;
				
					for (var eventIdentifier in _events[type]) {
							if (eventIdentifier != identifier) newFunctions[eventIdentifier] = _events[type][eventIdentifier];
					}
					
				_events[type] = newFunctions;
			}
			
			this.callEvent = function(type, callString) {
				type = type.toLowerCase();
					if (callString == null) callString = outputString;
				this.createEvents(type);
					for (var eventIdentifier in _events[type]) {
						var string = callString;
						eval(_events[type][eventIdentifier].functionCall);
					}
			}
			
			this.setOutputHandler = function(outputHandlerName) {
				_outputHandler = outputHandlerName;
			}

	}
