function ajax_engine (id, AJAX_CALL_URL, CALLBACK,  PARAMETER, REFPARAMETER, COUNT) {
	this.id = id;
	this.AJAX_CALL_URL=AJAX_CALL_URL;
	this.CALLBACK=CALLBACK;
	this.PARAMETER = ( PARAMETER == undefined ) ? "" : PARAMETER;
	this.REFPARAMETER = ( REFPARAMETER == undefined ) ? null : REFPARAMETER;
	this.RESTYPE="plain";											//xml or plain
	this.REQUEST_DELAY = 1000;										//delay beetwen 2 calls
	this.AJAX_TIMEOUT = 900;										//time beetwen request and callback
	this.COUNT = ( COUNT == undefined ) ? 1 : COUNT;				//request count
	this.AJAX_CALL_COUNTER = this.COUNT;
	this.LAST_REQUEST = (this.COUNT > 1 ) ? false: true;			//last request flag
	this.AJAX_DEBUG = false;										//debug flag
	this.AJAX_LAST_RESULT="NONE_INITIAL";							//the calling result
	this.AJAX_LAST_STATUS="NONE_INITIAL";							//the calling status
	this.AJAX_FRAMEWORK_STOP = false;
	
	this.doNothing = function () {}
	
	this.setDelay = function(s) { 
		try {this.REQUEST_DELAY_DELAY=parseInt(s);}
		catch(e) {}
		if (this.REQUEST_DELAY<200){this.REQUEST_DELAY=200;}
		this.AJAX_TIMEOUT=this.REQUEST_DELAY-100;
		}
	
	this.setCallUrl = function (u) { this.AJAX_CALL_URL = u; }
	this.setParameter = function (p) { this.PARAMETER = p; }
	this.setDebug = function(s) { this.AJAX_DEBUG = s; }
	this.setRestype = function(s) { this.RESTYPE = s; }
	this.setCount = function(c) { 
		try { this.COUNT = parseInt(c);  }
		catch(e) {}
		if ( this.COUNT > 1 ) { 
			this.AJAX_CALL_COUNTER = this.count;
			this.LAST_REQUEST = false; 
			}
		}
	this.stop = function () { this.AJAX_FRAMEWORK_STOP=true; this.CALLBACK = this.id+".doNothing" }
	this.start = function () {
		if ( this.AJAX_DEBUG ) { this.createDebugDiv(); }
		if ( this.COUNT == 1 ) { this.get_ajax_data(); }
		else { this.loop(); }
		}
	
	this.getTransport = function() {
		var transport=false;
		//define xmlhttprequest for doof IE
		/*@cc_on @*/
		/*@if (@_jscript_version >= 5)
		try {transport = new ActiveXObject("Msxml2.XMLHTTP");}
		catch (e) {
			try {
				transport = new ActiveXObject("Microsoft.XMLHTTP");
				return transport;
				}
			catch (e) {}
			}
		@end @*/
		//define xmlhttprequest for every other Brouser on this planet ;)
		if (typeof XMLHttpRequest!="undefined") {
			try {
				transport = new XMLHttpRequest();
				return transport;
				}
			catch (e) {}
			}
		if (window.createRequest) {
			try {
				transport = window.createRequest();
				return transport;
				}
			catch (e) {}
			}
			
		return transport;
		}
	
	this.getFormValues = function(fobj) {
		var str = "";
		for(var i = 0;i < fobj.elements.length;i++) {
			switch(fobj.elements[i].type){
			case "text":
			case "textarea":
			case "password":
				str += fobj.elements[i].name + "=" + encodeURIComponent(fobj.elements[i].value) + "&";
				break;
			case "hidden":
			//hidden cannot be disabled
				str += fobj.elements[i].name + "=" + encodeURIComponent(fobj.elements[i].value) + "&";
				break;
			case "checkbox":
				if (fobj.elements[i].checked) {
					str += fobj.elements[i].name + "=" + encodeURIComponent(fobj.elements[i].value) + "&";
                    // alert(str);
					}
				else {
					str += fobj.elements[i].name + "=&";
				}
				/* else {
					if (fobj.elements[i].value="1") {val="0";}
					else {val="off";}
					str += fobj.elements[i].name + "=" + val + "&";
					} */
				break;
			case "radio":
				if (fobj.elements[i].checked) {
					str += fobj.elements[i].name + "=" + encodeURIComponent(fobj.elements[i].value) + "&";
					}
				break;
			case "select-one":
				str += fobj.elements[i].name + "=" + encodeURIComponent(fobj.elements[i].options[fobj.elements[i].selectedIndex].value) + "&";
				break;
			case "select-multiple":
				for (var j = 0; j < fobj.elements[i].length; j++){
					var optElem = fobj.elements[i].options[j];
					if (optElem.selected == true){
						str += fobj.elements[i].name + "=" + encodeURIComponent(optElem.value) + "&";
						}
					}
				break;
			}
		}
		//Strip final &amp;
		str = str.substr(0,(str.length - 1));
		//alert(str);
		return str;
		}
	
	this.log = function (message) {
		//log schreiben
		if (this.AJAX_DEBUG) {
			log("ajax_engine", message);
			}
		}
	
	this.createDebugDiv = function() {
		if (document.getElementById("ajax_debug_div")==undefined) {
			mdd = document.createElement("div");
			mdd.id = "ajax_debug_div";
			mdd.style.color="black"
			mdd.style.position="absolute";
			mdd.style.border="solid red 2px";
			mdd.style.width="300px";
			mdd.style.height="150px";
			mdd.style.overflow="auto";
			mdd.style.top="0px";
			mdd.style.backgroundColor="white";
			document.body.appendChild(mdd);
			}
		}
		
	this.get_ajax_data = function() {
		this.log("get_ajax_data");
		var request = this.getTransport();
		request.setParent = function(p) { this.parent = p; }
		request.setParent(this);
		vvv = request;
		if (!request) {
			this.stop();
			alert("NO AJAX POSSIBLE");
			return false;
			}
		
		if (this.PARAMETER.elements) {
			this.AJAX_ADDITIONAL_PARAMETER=this.getFormValues(this.PARAMETER);
			}
		else {
			this.AJAX_ADDITIONAL_PARAMETER=this.PARAMETER;
			}
		env_time = new Date().getTime();
		if ( this.AJAX_ADDITIONAL_PARAMETER != "") { 
			this.AJAX_ADDITIONAL_PARAMETER = this.AJAX_ADDITIONAL_PARAMETER+"&";
			} 
		this.AJAX_ADDITIONAL_PARAMETER += "ajax_ts_no_cache="+env_time; //+"&id="+SESSION_ID;
		
		request.open("POST", this.AJAX_CALL_URL, true);
		request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
		request.setRequestHeader("Content-length", this.AJAX_ADDITIONAL_PARAMETER.length);
		request.setRequestHeader("Connection","close");
		request.onreadystatechange=function() {
			if (request.readyState==4) {
				try {
					request.parent.AJAX_LAST_STATUS=request.status;
					if (request.parent.AJAX_RESTYPE_XML) {request.parent.AJAX_LAST_RESULT=request.responseXML;}
					else {request.parent.AJAX_LAST_RESULT=request.responseText;}
					if ( request.parent.LAST_REQUEST ) {
						if (typeof(request.parent.CALLBACK)=="string") {
							setTimeout(request.parent.CALLBACK+"("+request.parent.id+".AJAX_LAST_RESULT)",1);
							}
						else if (typeof(request.parent.CALLBACK)=="function") {
							//setTimeout(request.parent.CALLBACK,1, request.parent.AJAX_LAST_RESULT, request.parent.REFPARAMETER); <- this doesn't work in doof IE too !!!!!
							setTimeout(	function() {
										request.parent.CALLBACK(request.parent.AJAX_LAST_RESULT, 
																request.parent.REFPARAMETER )
										},1
									);
							}
						else {
							alert(request.parent.CALLBACK);
							}
						}
					}
				catch (e) {
					//alert(e);
					this.AJAX_LAST_STATUS="ERROR";
					this.AJAX_LAST_RESULT="ERROR";
					}
				}
			}
		request.send(this.AJAX_ADDITIONAL_PARAMETER);
		}
	
	
	this.loop = function () {
		if (this.AJAX_LAST_STATUS == 401 || this.AJAX_LAST_STATUS == 404) {
			this.log("Status: "+this.AJAX_LAST_STATUS+", stop ajax");
			this.stop();
			}
		setTimeout(this.CALLBACK+"("+this.id+".AJAX_LAST_RESULT)",this.AJAX_TIMEOUT);
		if (this.AJAX_CALL_COUNTER && this.AJAX_FRAMEWORK_STOP==false) {
			if (this.AJAX_CALL_COUNTER!=1) { setTimeout(this.id+".loop()",this.REQUEST_DELAY);	}
			else { this.LAST_REQUEST = true }
			this.get_ajax_data();
			}
		if (this.AJAX_CALL_COUNTER>0) {	this.AJAX_CALL_COUNTER -= 1; }
		}
	}

