function ComboInput(
	oElement,
	oClassElement,
	oOptionsElement,
	bTemplate
	) {

	ComboInput.baseConstructor.call(
		this,
		oElement,
		oClassElement,
		bTemplate
		);

	this.oOptionsElement = oOptionsElement;

	if(this.isTemplate()) {
		return;
	}

	this.iPageSize = oOptionsElement.size || ComboInput.DEFAULT_PAGE_SIZE;

	Common.Class.add(
		this.oOptionsElement,
		ComboInput.CLASS_NAME_COMBO_LIST
		);

	this.aOptions = [];
	this.aOptionsCurrent = [];

	this.oElement.setAttribute('autocomplete', 'off');
	this.oOptionsElement.setAttribute('size', this.iPageSize);

	this.iSelectedIndex = 0;
	this.sLastSearchValue = null;

	this.initOptions();
	this.addExtendedHandlers();
	this.hideOptions();

	oOptionsElement.innerHTML = '';

}

ComboInput.DEFAULT_PAGE_SIZE = 5;

ComboInput.CLASS_NAME_COMBO_LIST        = 'combo-list';
ComboInput.CLASS_NAME_COMBO_LIST_ACTIVE = 'combo-field-active';

ComboInput.inheritFrom(
	TextInput,
	{

		addExtendedHandlers : function() {

			var oThis = this;

			Common.Event.add(
				this.oElement,
				FormWidget.EVENT_TYPE_KEYUP,
				function(oEvent) {

					oThis.dispatchKeyEvent(Common.Event.normalize(oEvent).iKeyCode);

				}
				);

			Common.Event.add(
				this.oElement,
				[FormWidget.EVENT_TYPE_CLICK, FormWidget.EVENT_TYPE_FOCUS],
				function(oEvent) {

					oThis.updateOptions(true);

				}
				);

			Common.Event.add(
				this.oElement,
				FormWidget.EVENT_TYPE_KEYPRESS,
				function(oEvent) {

					var oEvent = Common.Event.normalize(oEvent);

					if(oEvent.iKeyCode == FormWidget.KEY_CODE_ENTER) {
						Common.Event.cancel(oEvent);
					}

				}
				);

			
			Common.Event.add(
				document,
				FormWidget.EVENT_TYPE_CLICK,
				function(oEvent) {

					if(Common.Event.normalize(oEvent).target == oThis.oElement) {
						return;
					}
					oThis.hideOptions();

				}
				);

			
			Common.Event.add(
				this.oOptionsElement,
				FormWidget.EVENT_TYPE_BLUR,
				function() {

					oThis.hideOptions();

				}
				);
			


			Common.Event.add(
				this.oOptionsElement,
				FormWidget.EVENT_TYPE_FOCUS,
				function(oEvent) {

					oThis.showOptions();

					Common.Event.cancel(oEvent);

				}
				);


			Common.Event.add(
				this.oOptionsElement,
				[FormWidget.EVENT_TYPE_CLICK, FormWidget.EVENT_TYPE_CHANGE],
				function(oEvent) {
					oThis.selectFromOptions(oEvent);
				}
				);
		},

		initOptions : function() {
			var aOptions = this.oOptionsElement.options;
			
			this.aOptions = [];
			for(var i = 0; i < aOptions.length; i++) {
				this.aOptions[i] = {
					sLabel       : aOptions[i].innerHTML,
					sValue       : aOptions[i].value,
					sSearchValue : aOptions[i].innerHTML.toLowerCase()
					};
			}
			

			this.aOptionsCurrent = this.aOptions;

		},

		dispatchKeyEvent : function(iKeyCode) {

			switch(iKeyCode) {

				case FormWidget.KEY_CODE_ARROW_UP:
					this.selectPrevOption();
				break;

				case FormWidget.KEY_CODE_ARROW_DOWN:
					this.selectNextOption();
				break;

				case FormWidget.KEY_CODE_PAGE_UP:
					this.selectPrevPage();
				break;

				case FormWidget.KEY_CODE_PAGE_DOWN:
					this.selectNextPage();
				break;

				case FormWidget.KEY_CODE_HOME:
					this.selectFirstOption();
				break;

				case FormWidget.KEY_CODE_END:
					this.selectLastOption();
				break;

				case FormWidget.KEY_CODE_ENTER:
					this.selectFromOptions();
				break;

				default:
					this.updateOptions(false);
				break;

			}

		},

		selectPrevOption : function() {

			if(this.iSelectedIndex > 0) {
				this.iSelectedIndex--;
			}

			this.updateSelectedIndex();

		},

		selectNextOption : function() {

			if(this.iSelectedIndex < this.oOptionsElement.options.length - 1) {
				this.iSelectedIndex++;
			}

			this.updateSelectedIndex();

		},

		selectPrevPage : function() {

			var iPrevPageIndex = this.iSelectedIndex - this.iPageSize;

			if(iPrevPageIndex > 0) {
				this.iSelectedIndex = iPrevPageIndex;
			}
			else {
				this.iSelectedIndex = 0;
			}

			this.updateSelectedIndex();

		},

		selectNextPage : function() {

			var iNextPageIndex = this.iSelectedIndex + this.iPageSize;

			if(iNextPageIndex < this.oOptionsElement.options.length - 1) {
				this.iSelectedIndex = iNextPageIndex;
			}
			else {
				this.iSelectedIndex = this.oOptionsElement.options.length - 1;
			}

			this.updateSelectedIndex();

		},

		selectFirstOption : function() {

			this.iSelectedIndex = 0;

			this.updateSelectedIndex();

		},

		selectLastOption : function() {

			this.iSelectedIndex = this.oOptionsElement.options.length - 1;

			this.updateSelectedIndex();

		},

		selectFromOptions : function(oEvent) {
			if(this.oOptionsElement.options.length > 0 && this.oOptionsElement.selectedIndex > -1) {

				this.iSelectedIndex = this.oOptionsElement.selectedIndex;
				this.oElement.value = this.oOptionsElement.options[this.iSelectedIndex].innerHTML;
				this.sLastSearchValue = this.oElement.value.toLowerCase();
				this.processEvents(true);
				this.oOptionsElement.blur();
				//this.oElement.focus();
				this.hideOptions();
				this.oElement.blur();
			} else {
				var oEvent = Common.Event.normalize(oEvent);
				Common.Event.cancel(oEvent);
			}
			try {
				if (typeof eval('change_' + this.oElement.id) == 'function') {
					eval('change_' + this.oElement.id)()
				}
			} catch (e) {}

		},

		updateSelectedIndex : function() {

			if(this.iSelectedIndex > -1) {
				this.oOptionsElement.selectedIndex = this.iSelectedIndex;
			}

		},

		updateOptions : function(bAlways) {

			var sNewValue = this.oElement.value.toLowerCase();

			if(!bAlways && this.sLastSearchValue == sNewValue) {
				return;
			}

			var
				i = 0,
				iLength = this.aOptionsCurrent.length,
				iOptionsCount = 0,
				bFound = false
				;

			this.sLastSearchValue = sNewValue;

			this.oOptionsElement.options.length = 0;

			while(i < iLength) {

				if(this.aOptionsCurrent[i].sSearchValue.indexOf(sNewValue) > -1 && (this.aOptionsCurrent[i].sSearchValue.indexOf(sNewValue) == 0 || this.aOptionsCurrent[i].sSearchValue.indexOf(' ' + sNewValue) > -1 || this.aOptionsCurrent[i].sSearchValue.indexOf('(' + sNewValue) > -1) ) {
					this.oOptionsElement.options[iOptionsCount] = new Option(this.aOptionsCurrent[i].sLabel, this.aOptionsCurrent[i].sValue);
					iOptionsCount++;
					if(sNewValue == this.aOptionsCurrent[i].sSearchValue) {

						this.iSelectedIndex = iOptionsCount - 1;
						bFound = true;
					}

				}

				i++;

			}

			/*if(window.opera) {

				this.oOptionsElement.style.display = 'none';
				this.oOptionsElement.style.display = 'block';

			}*/

			if(!bFound) {
				this.iSelectedIndex = -1;
			}

			if(iOptionsCount > 0) {
				if (iOptionsCount == 1 && sNewValue == this.oOptionsElement.options[0].text.toLowerCase()) {
					this.hideOptions();
				} else {
					this.updateSelectedIndex();
					this.showOptions();
				}
			}
			else {
				this.hideOptions();
			}

		},

		showOptions : function() {

			this.addClass(ComboInput.CLASS_NAME_COMBO_LIST_ACTIVE);

		},

		hideOptions : function() {
			
			this.removeClass(ComboInput.CLASS_NAME_COMBO_LIST_ACTIVE);
			
			if(!(this.iSelectedIndex > -1)) {
				
				this.oOptionsElement.options.length = 0;
			}

		},

		enableOptionsByValue : function(
			aPatternGroups,
			bJoin
			) {

			this.aOptionsCurrent = [];

			for(var i = 0, bMatched, bEnable, oOption; i < this.aOptions.length; i++) {

				oOption = this.aOptions[i];

				bEnable = false;

				for(var j = 0; j < aPatternGroups.length; j++) {

					bMatched = false;

					for(var k = 0; k < aPatternGroups[j].length && !bMatched; k++) {
						bMatched = oOption.sValue.match(aPatternGroups[j][k])? true : false;
					}

					if(bMatched) {
						if(bJoin || j == 0) {
							bEnable	= true;
						}
					}
					else {
						bEnable = false;
					}

				}

				if(bEnable) {
					this.aOptionsCurrent.push(oOption);
				}

			}

			this.sLastSearchValue = null;
			this.iSelectedIndex = -1;

		},

		disable : function(bByParent) {

			if(!ComboInput.superClass.disable.call(this, bByParent)) {
				return false;
			}

			this.oOptionsElement.disabled = true;

			return true;

		},

		enable : function(bByParent) {

			if(!ComboInput.superClass.enable.call(this, bByParent)) {
				return false;
			}

			this.oOptionsElement.disabled = false;

			return true;

		},

		updateElements : function(iIndex) {

			this.oOptionsElement = document.getElementById(iIndex > 0?
				this.oOptionsElement.id.match(Multiplicator.REG_EXP_REPLACE)[1] + '_' + iIndex :
				this.oOptionsElement.id
				);

			ComboInput.superClass.updateElements.call(this, iIndex);

		},

		clone : function(
			oElement,
			oClassElement,
			iIndex
			) {

			return new ComboInput(
				oElement,
				oClassElement,
				document.getElementById(this.oOptionsElement.id.match(Multiplicator.REG_EXP_REPLACE)[1] + '_' + iIndex),
				false
				);

		},

		destruct : function() {

			this.oOptionsElement = null;

			ComboInput.superClass.destruct.call(this);

		}

	}
	);