	function superselect2 (selectlist ) {
		// config
		var listlength = 10;
		var curlength=10;
		
		
		// datadeclaration
		var baselist = selectlist;
		var name = baselist.name;
		//there should be only one element with this name
		var baseelement = document.getElementsByName(baselist.name)[0];
		var data = new Array();
		var items = new Array();
		var defaultvalue = null;
		//functions
		
		var gethighlight = function() {
			res = null;
			for (var i=0;i<listlength;i++) {
				if (items[i].className=="lihover") {
					res = i;
					break;	
				}
			}
			return res;
		}
		
		var clearhighlight = function () {
			var res=gethighlight();
			if (res!=null)
				if (items[i])
					items[i].className="li";
		}
		
		var parselist = function () {
			for (var i = 0;i<baselist.length; i++) {
				var dat = new Object();
				dat.value = baselist.options[i].value;
				dat.name =  baselist.options[i].text;
				if (baselist.options[i].defaultSelected)
					defaultvalue=i;
				data.push(dat);
			}
		}
		
		this.check = function () {
			if (hidden.value!='')
				return true;
			else 
				return false;
		}
		
		this.printall = function () {
			for (var i = 0; i<data.length; i++) {
				document.writeln("i: "+i+"<br />");
				for (var prob in data[i]) {
					document.writeln(prob+ " as " + i + " is "+ data[i][prob]+ "<br />");
				}
			}
		}
		
		
		var filllist = function () {
			var array = input.value.toLowerCase().split('');
			var reg = new RegExp(array.join('\\S*'));
			//alert(reg);
			var count = 0;
			var i=0;
			var run=true;
			while (run) {
				if (reg.test(data[i].name.toLowerCase())) {
					var out = document.createElement("span");
					var org = data[i].name;
					var pos=0;
					var strong = null;
					for (var j=0;j<org.length;j++) {
						if (array[pos] && org.charAt(j)) {
							if (org.charAt(j).toLowerCase()==array[pos].toLowerCase()) {
								strong = document.createElement("strong");
								strong.appendChild(document.createTextNode(org.charAt(j)));
								out.appendChild(strong);
								pos++;
							}
							else
								out.appendChild(document.createTextNode(org.charAt(j)));
						}
						else
							out.appendChild(document.createTextNode(org.charAt(j)));
					}
					items[count].replaceChild(out,items[count].firstChild);//.nodeValue=s;
					items[count].id = i;
					items[count].style["display"]="block";
					count++;
					if (count==listlength) {
						run=false;
					}
				}
				i++;
				if (i==data.length)
					run=false;
				if (run==false)
					break;
			}
			curlength=count;
			for (var i=count;i<listlength;i++)
				items[i].style["display"]="none";

		}
		
		var itemchoose = function (text) {
				var i = parseInt(text);
				hidden.value = data[i].value;
				input.value = data[i].name;
				hide();
				filllist();
		}
		
		var show = function() {
			listcontainer.style["display"]="block";
			if (hidden.value!='')
				filllist();
		}
		
		var hide = function() {
			listcontainer.style["display"]="none";
			if (hidden.value=='') { //nothing was selected
				input.value="";
				filllist();
			}
			else { //something was selected before
				var i=0;
				var id=parseInt(hidden.value);
				while (data[i].value!=id)
					i++;
				input.value = data[i].name; 
			}
		}
		
		this.remove = function () {
			baselist.parentNode.removeChild(baselist.previousSibling);
			baselist.parentNode.removeChild(baselist.previousSibling);
			baselist.name = name;
		}
		
		var handlekey = function (keyevent) {
			if (!keyevent)
				keyevent = window.event;
			code = keyevent.keyCode;
			switch (code) {
				case 40: //down
					var cur = gethighlight();
					if (cur==null) {
						items[0].className="lihover";
					}
					else {
						items[cur].className="li";
						cur++;
						if (cur==curlength)
							cur--;
						items[cur].className="lihover";
					}						
					break;
				case 38: //up
					var cur = gethighlight();
					if (cur!=null) {
						items[cur].className="li";
						cur--;
						if (cur==-1)
							cur++;
						items[cur].className="lihover";
					}
					break;
				case 13: //enter
					var cur = gethighlight();
					if (cur!=null) {
						itemchoose(items[cur].id);	
					}
					input.blur(); //preventing form to be send
					break;
				case 27: //escape
					var cur = gethighlight();
					if (cur!=null) {
						itemchoose(items[cur].id);
					}
					input.blur(); //preventing form to be send
					break;
				default:
					break;	
			}
			
		}
		
		//run
		parselist();
		
		//generating necessary elements for output
		//container with all elements of the superselect list
		var container = document.createElement("div");
		container.id="div_" + name;
		container.className = "superselect";
		
		//input for value
		var hidden = document.createElement("input");
		hidden.type = "hidden";
		container.appendChild(hidden);
		hidden.name = name;
		
		//input for userinput
		var input = document.createElement("input");
		input.className = "input";
		input.type = "text";
		container.appendChild(input);
		
		var cleaner = document.createElement("div");
		cleaner.className="cleaner";
		cleaner.onclick = function() {
			//clearhighlight();
			input.value="";
			hidden.value="";
			filllist();
			show();
			input.focus();
		}
		
		container.appendChild(cleaner);
		
		var clearer = document.createElement("div");
		clearer.className="clearer";
		container.appendChild(clearer);
		
		//div container for list
		var listcontainer = document.createElement("div");
		listcontainer.className = "superselect";
		var innercontainer = document.createElement("div");
		innercontainer.className = "list";
		var listparent = document.createElement("div");
		listparent.className="ul";
		
		for (var i=0;i<listlength;i++) {
			var item = document.createElement("div");
			item.className="li";
			item.id = i;
			var text = document.createTextNode(i);
			item.appendChild(text);
			listparent.appendChild(item);
			
			item.onmouseover = function () {
				var cur = gethighlight();
				if (cur!=null)
					items[cur].className="";
				this.className="lihover";
	
			}
			
			item.onmouseout = function() {
				this.className = "li";
			}
			
			item.onmousedown = function() {				
				itemchoose(this.id);
				input.blur();
			}
			
			items.push(item);
			
		}
		innercontainer.appendChild(listparent);
		listcontainer.appendChild(innercontainer);
		//container.appendChild(listcontainer);
		
		input.onblur = function () {
			hide();
		}
		
		input.onfocus = function () {
			show(); 
		}
		
		input.onkeyup = function() {
			filllist();	
		}
		
		input.onkeydown = handlekey;
	
		filllist();
		if (defaultvalue!=null) 
			itemchoose(defaultvalue);
		
		baseelement.parentNode.insertBefore(container,baseelement);
		baseelement.parentNode.insertBefore(listcontainer,baseelement);
		baseelement.style["display"]="none";
		baseelement.name="old_"+name;
		hide();
	}
	
	function superselect2handler(form) {
		var list = new Array();
		var elements = new Array();
		var missingmessages = new Array();
		var action = form.action;
		var n = 0;
		
		form.action="javascript:superselects.check();";
		//there should be only one form with this name
		document.getElementsByName(form.name)[0]["onsubmit"]="alert(\"ok\")";
		
		this.add = function (selectlist,message) {
			list.push(new superselect2(selectlist));
			elements.push(selectlist);
			missingmessages.push(message)
			n++;
			return (n-1);
		}
		
		this.update = function(id) {
			list[id].remove();
			list[id] = new superselect2(elements[id]);
		}
		
		this.check = function () {
			var ok = true;
			var error = new Array();
			for (var supers in list) {
				if (!list[supers].check()) {
					ok=false;
					error.push(missingmessages[supers]);
				}
			}
			if (ok) {
				form.action = action;
				form.submit();	
			}
			else {
				//var error = new errordisplay(error);	
				alert(error.join("\n"));
			}
		}	
		
		
	}
