function suggest(id,url,size,func,onchange) {

	var that=this;
	this.id=id;
	if(typeof(id)=='object') this.field=id;
	else this.field=el(id);
	this.field.setAttribute('autocomplete','off');
	this.field.onfocus=function(){that.field.select()};
	this.remote=url;
	this.target=func;
	this.onchange=onchange;
	this.size=size;
	this.current=null;
	this.scront=0;
	this.scrtop=0;
	this.total=0;
	this.debug=false;
	this.cache=new Array();
	this.is_cached=false;
	this.requested=false;
	this.sugbox=el(id+'_suggest');
	this.sugbox.classname='suggest';
	register_event('onclick',function(){that.hideBox()});
	this.sugbox.onblur=function() {that.hideBox()};
	register_event('onkeyup',function(evt) {
		if(isIE) var key=event.keyCode;
		else var key=evt.which;
		if(key==38) {
			that.changeItem('up');
		} else if(key==40) {
			that.changeItem('down');
		} else if(key>31 || key==8) {
			that.checkCache();
			return true;
		}
		return false;
	},this.field);
	register_event('onkeydown',function(evt) {
		if(isIE) var key=event.keyCode;
		else var key=evt.which;
		if(key==9 || key==13) {
			that.chooseItem();
		} else if(key==27) {
			that.hideBox();
		}
		return false;
	},this.field);
	register_event('onkeydown',function(evt) {
		if(isIE) var key=event.keyCode;
		else var key=evt.which;
		if(key==38) {
			that.changeItem('up');
		} else if(key==40) {
			that.changeItem('down');
		} else if(key==9 || key==13) {
			that.chooseItem();
		} else if(key==27) {
			that.hideBox();
		}
		return false;
	},this.sugbox);

	this.checkCache=function() {
		if(this.field.value.length<1) {
			this.hideBox();
			return;
		}
		this.current=null;
		if(this.cache[this.field.value.substr(0,1).toLowerCase()]) {
			this.sugbox.style.width='auto';
			this.sugbox.style.height='auto';
			this.showBox();
			this.getResults(false);
		} else if(this.field.value.length==1 || !this.requested) {
			var url=this.remote;
			if(this.field.value=='~') {
				this.debug=true;
				this.field.value='a';
			}
			if(this.remote.indexOf('?')>-1) {
				url+=this.field.value;
			}
			if(this.is_cached && /\.xml$|\.txt$/i.test(this.remote)) {
				this.hideBox();
				return;
			} else {
				this.sugbox.style.width=(this.size+4)+'px';
				this.sugbox.style.height='auto';
				var load_msg='<div style="margin:3px; color:#dd0000; font-size:11px; font-weight:bold">'
				if(language=='portuguese') load_msg+='Carregando...';
				else if(language=='spanish') load_msg+='Cargando...';
				else load_msg+='Loading...';
				this.sugbox.innerHTML=load_msg+'</div>';
				this.showBox();
				get_data(function(data,httpheader){that.getResults(data,httpheader)},url);
				this.requested=true;
			}
		}
	}

	this.getResults=function(response,httpheader) {
		//alert(httpheader+'\n\n'+response+'\n\n'+this.remote); // debug
		var keyword,value;
		this.is_cached=true;
		this.sugbox.style.width=(this.size+4)+'px';
		this.sugbox.style.height='160px';
		if(response) {
			var item,counter;
			if(typeof(response)=='string') {
				var titles=response.split('\n');
				var values=new Array();
			} else if(typeof(response)=='object') {
				var titles=response.getElementsByTagName('title');
				var values=response.getElementsByTagName('value');
			} else if(typeof(response)=='array') {
				var titles=response;
				var values=new Array();
			} else {
				throw('RUNTIME ERROR: invalid response from server in suggest("'+this.id+'","'+this.remote+'")');
			}
			if(titles.length>0) {
				for(loop=0;loop<titles.length;loop++) {
					if(typeof(response)=='string') {
						item=titles[loop];
					} else if(typeof(response)=='object') {
						item=titles[loop].firstChild.data;
					}
					keyword=item.substr(0,1).toLowerCase();
					if(!this.cache[keyword]) {
						this.cache[keyword]=new Array();
					}
					counter=this.cache[keyword].length;
					this.cache[keyword][counter]=new Array();
					this.cache[keyword][counter][0]=item;
					if(values.length>0 && values[loop]) {
						value=values[loop].firstChild.data;
						this.cache[keyword][counter][1]=value;
					}
				}
			}
		}
		keyword=this.field.value.substr(0,1).toLowerCase();
		if(this.cache[keyword]) {
			var ck,fd; this.total=0;
			var table=document.createElement('table');
			table.setAttribute('border',0);
			table.setAttribute('cellspacing',0);
			//table.setAttribute('width','100%');
			table.style.width='1000px';
			var tbody=document.createElement('tbody');
			fd=this.field.value.toLowerCase();
			fd=fd.replace('á','a').replace('à','a').replace('ã','a').replace('â','a').replace('é','e').replace('ê','e').replace('í','i').replace('ó','o').replace('ô','o').replace('ú','u').replace('ü','u').replace('ç','c').replace('ñ','n');
			for(loop=0;loop<this.cache[keyword].length;loop++) {
				ck=this.cache[keyword][loop][0].substr(0,this.field.value.length).toLowerCase();
				ck=ck.replace('á','a').replace('à','a').replace('ã','a').replace('â','a').replace('é','e').replace('ê','e').replace('í','i').replace('ó','o').replace('ô','o').replace('ú','u').replace('ü','u').replace('ç','c').replace('ñ','n');
				if(ck!=fd) continue;
				var tr=document.createElement('tr');
				tr.setAttribute('id',this.total);
				var td=document.createElement('td');
				//td.setAttribute('nowrap','nowrap');
				td.style.height='16px';
				td.style.padding='0px 3px 0px 3px';
				td.style.whiteSpace='nowrap';
				td.onmouseover=function() {that.itemOver(this)};
				td.onmouseout=function() {that.itemOut(this)};
				td.onmousedown=function() {that.chooseItem(this)};
				if(this.cache[keyword][loop][1]) {
					td.id=this.cache[keyword][loop][1];
				}
				td.innerHTML=this.cache[keyword][loop][0];
				tr.appendChild(td);
				tbody.appendChild(tr);
				this.total++;
			}
			if(this.total>0) {
				table.appendChild(tbody);
				var divsug=document.createElement('div');
				divsug.style.width=(this.size-17)+'px';
				divsug.style.height='auto';
				divsug.style.position='absolute';
				divsug.style.zIndex=zIndex();
				divsug.style.padding=0;
				divsug.style.margin=0;
				divsug.style.left=0;
				divsug.style.top=0;
				divsug.style.overflow='hidden';
				//divsug.style.backgroundColor='#ffc';
				divsug.appendChild(table);
				this.sugbox.innerHTML='';
				this.sugbox.appendChild(divsug);
				//this.sugbox.style.width=(divsug.offsetWidth+35)+'px';
				// define largura da lista igual ao tamanho do campo, se for menor
				/* if(this.sugbox.offsetWidth<(this.size+4)) {
					this.sugbox.style.width=(this.size+4)+'px';
				} */
				if(isIE) {
					shim=document.createElement('div');
					shim.style.position='absolute';
					shim.style.zIndex=zIndex()-5;
					shim.style.padding=0;
					shim.style.margin=0;
					shim.style.left=0;
					shim.style.top=0;
					shim.innerHTML='<iframe width="100%" height="100%" scrolling="no" frameborder="no" marginheight="0" marginwidth="0"></iframe>';
					this.sugbox.appendChild(shim);
					shim.style.width=divsug.offsetWidth;
					shim.style.height=divsug.offsetHeight;
				}
			} else {
				this.hideBox();
			}
		} else {
			this.hideBox();
		}
	}

	this.itemOver=function(item) {
		if(this.current) {
			this.current.className='';
		}
		this.current=item;
		this.current.className='current';
		this.scront=parseInt(this.current.parentNode.id);
		this.scrtop=parseInt(this.sugbox.scrollTop/16);
		this.sugbox.scrollTop=(this.scrtop*16);
	}

	this.itemOut=function(item) {
		item.className='';
	}

	this.changeItem=function(way) {
		if(!this.field.value) return true;
		if(this.current!=null) {
			this.current.className='';
			switch(way) {
				case 'up':
					if(this.current!=this.sugbox.firstChild.firstChild.firstChild.firstChild.firstChild) {
						this.current=this.current.parentNode.previousSibling.firstChild;
						this.scront--;
						if(this.scront<0) this.scront=0;
						if(this.scront<this.scrtop) {
							this.scrtop--;
						}
					}
					break;
				case 'down':
					if(this.current!=this.sugbox.firstChild.firstChild.firstChild.lastChild.firstChild) {
						this.current=this.current.parentNode.nextSibling.firstChild;
						this.scront++;
						if(this.scront>this.total) this.scront=this.total;
						if(this.scront>this.scrtop+9) {
							this.scrtop++;
						}
					}
					break;
			}
		} else {
			switch(way) {
				case 'up':
					this.current=this.sugbox.firstChild.firstChild.firstChild.lastChild.firstChild;
					this.scrtop=this.total-9;
					this.scront=this.total;
					break;
				case 'down':
					this.current=this.sugbox.firstChild.firstChild.firstChild.firstChild.firstChild;
					this.scrtop=0;
					this.scront=0;
					break;
			}
		}
		this.sugbox.scrollTop=(this.scrtop*16);
		this.current.className='current';
		if(isFF || isNS) {
			this.field.setSelectionRange(this.field.value.length,1);
		}
	}

	this.hideBox=function() {
		this.current=null;
		this.sugbox.style.display='none';
	}

	this.showBox=function() {
		var pos=findPos(this.field);
		var px=pos.x;
		var py=pos.y+parseInt(this.field.offsetHeight);
		this.sugbox.style.left=px+'px';
		this.sugbox.style.top=py+'px';
		this.current=null;
		this.sugbox.style.zIndex=zIndex();
		this.sugbox.style.display='block';
	}

	this.chooseItem=function(item) {
		if(item) this.current=item;
		if(!this.current) return;
		this.field.value=this.current.innerHTML;
		if(typeof(this.target)=='function') {
			if(typeof(this.current.id)!='undefined') {
				this.target(this.current.id);
			}
		}
		if(this.onchange) {
			this.onchange(this.field.value);
		}
		this.hideBox();
		return false;
	}

}