function XMLRequest(async, cmode) {
	//
	// Variables (properties)
	var xmlhttp;
	var response;
	var setEventHandler = false;
	var asynchronousCommunication = async;
	var eventHandler = "";
	var communicationMode = cmode;
	var privEventHandler = "";
	//
	// Methods
	this.send = privSend;
	this.setEventHandler = privSetExternalEventHandler;
	//
	// Constructor (?)
	if (window.XMLHttpRequest) {
		xmlhttp = new XMLHttpRequest();
		privSetEventHandler(true);
	} else if (window.ActiveXObject) {
		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}
	//
	// Method declarations
	function privError(text) {
		alert('Failure in the server communication!\n'+text);
		return false;
	}
	function privSetExternalEventHandler(func) {
		privEventHandler = func;
	}
	function privStateChange() {
		if (privEventHandler != "") {
			if (xmlhttp.readyState == 4) {
				if (communicationMode == "XML") {
					privEventHandler(xmlhttp.readyState, xmlhttp.responseXML?xmlhttp.responseXML.documentElement:null);
				} else {
					privEventHandler(xmlhttp.readyState, xmlhttp.responseText?xmlhttp.responseText:null);
				}
			} else {
				privEventHandler(xmlhttp.readyState, false);
			}
		}
		//
		// Reset the xmlhttprequest object
		if (xmlhttp.readyState == 4) {
			xmlhttp.abort();
			privSetEventHandler(true);
		}
		return true;
		//
		// do something?
	}
	function privSetEventHandler(force) {
		if (!setEventHandler || force) {
			xmlhttp.onreadystatechange = privStateChange;
			//xmlhttp.onerror = function(e) {throw('XMLHTTPRequest returned an error');/*if(privEventHandler)privEventHandler(false, false);*/};
			setEventHandler = true;
		}
	}
	function privSend(url, content) {
		if ((xmlhttp.readyState < 2) || (xmlhttp.readyState == 4)) {
			xmlhttp.open('GET', url, asynchronousCommunication);
			privSetEventHandler(false);
			xmlhttp.send(null);
			if (!asynchronousCommunication) {
				if (xmlhttp.status == 200) {
					if (communicationMode == "XML") {
						return xmlhttp.responseXML.documentElement;
					} else {
						return xmlhttp.responseText;
					}
				} else return privError('Server returned: (' + xmlhttp.status + ') ' + xmlhttp.statusText);
				xmlhttp.readyState = 0;
			} else {
				//
				// Asynchronous mode, no data received yet (probably)
				return false;
			}
		} else return privError('Data channel is busy (' + xmlhttp.readyState + ')');
	}
}