The source code

    Ext.ns('Ext.ux');

    /**
     * Ext.ux.MultiCombo
     */
    Ext.ux.MultiCombo = Ext.extend(Ext.form.ComboBox, {

    	/**
    	 * @cfg {String} overClass [x-grid3-row-over]
    	 */
    	overClass : 'x-grid3-row-over',
    	/**
    	 * @cfg {Boolean} enableKeyEvents for typeAhead
    	 */
    	enableKeyEvents: true,
    	/**
    	 * @cfg {String} selectedClass [x-grid3-row-selected]
    	 */
    	selectedClass: 'x-grid3-row-selected',
    	/**
    	 * @cfg {String} highlightClass The css class applied to rows which are hovered with mouse
    	 * selected via key-nav, or highlighted when a text-query matches a single item.
    	 */
    	highlightClass: 'x-grid3-row-over',
    	/**
    	 * @cfg {Number} autoSelectKey [44] COMMA Sets the key used to auto-select an auto-suggest
    	 * highlighted query.  When pressed, the highlighted text-item will be selected as if the user
    	 * selected the row with a mouse click.
    	 */
    	autoSelectKey : 44,
    	/**
    	 * @cfg {String} allSelectedText Text to display when all items are selected
    	 */
    	allSelectedText : 'All selected',
    	/**
    	 * @cfg {Number} maxDisplayRows The maximum number of rows to show before applying vscroll
    	 */
    	maxDisplayRows: null,

    	mode: 'local',
    	triggerAction: 'all',
    	typeAhead: true,

    	// private
    	highlightIndex : null,
    	highlightIndexPrev : null,

    	query : null,

    	/**
    	 * @cfg {Array} value CheckboxCombo expresses its value as an array.
    	 */
    	value: [],

    	/**
    	 * @cfg {Integer} minChars [0]
    	 */
    	minChars: 0,

    	initComponent : function() {
    		var cls = 'x-combo-list';

    		// when blurring out of field, ensure that rawValue contains ONLY items contained in Store.
    		this.on('blur', this.validateSelections.createDelegate(this));

    		// create an auto-select key handler, like *nix-based console [tab] key behaviour
    		this.on('keypress', function(field, ev) {
    			if (ev.getKey() == this.autoSelectKey) {	// COMMA
    				this.onAutoSelect();
    			}
    		},this);

    		this.addEvents(
    			/**
    			 * @event initview Fires when Combo#initView is called.
    			 * gives plugins a chance to interact with DataView
    			 * @author Chris Scott
    			 * @param {Combo} this
    			 * @param {DataView} dv
    			 */
    			'initview',
                'clearall'
    		);

    		// when list expands, constrain the height with @cfg maxDisplayRows
    		if (this.maxDisplayRows) {
    			this.on('expand', function(){
    				var cnt = this.store.getCount();
    				if (cnt > this.maxDisplayRows) {
    					var children = this.view.getNodes();
    					var h = 0;
    					for (var n = 0; n < this.maxDisplayRows; n++) {
    						h += Ext.fly(children[n]).getHeight();
    					}
    					this.maxHeight = h;
    				}
    			}, this, {
    				single: true
    			});
    		}

    		this.on('beforequery', this.onQuery, this);

    		// Enforce that plugins is an Array.
    		if (typeof(this.plugins) == 'undefined'){
    			this.plugins = [];
    		}
    		else if (!Ext.isArray(this.plugins)) {
    			this.plugins = [this.plugins];
    		}

    		var tmp = this.value;	// for case where transform is set.
    		Ext.ux.MultiCombo.superclass.initComponent.call(this);
    		if (this.transform) {
    			if (typeof(tmp) == 'undefined') {
    				tmp = [];
    			}
    			this.setValue(tmp);
    		}
    	},

    	// private
        onViewClick : function(dv, index, node, ev){
    		var rec = this.store.getAt(index);
    		this.onSelect(rec, index);
    		this.el.focus();
    		/*
            if(doFocus !== false){
                this.el.focus();
            }
            */
        },

    	// onTriggerClick, overrides Ext.form.ComboBox#onTriggerClick
    	onTriggerClick: function() {
    		if (this.highlightIndex != -1) {
    			this.clearHighlight();
    		}
    		this.highlightIndex = -1;

    		if(this.disabled){
                return;
            }
    		if(this.isExpanded()){
                this.collapse();
                this.el.focus();
            }else {
                this.onFocus({});
    			if(this.triggerAction == 'all') {
    				this.doQuery(this.getRawValue(), true);
    				var vlen = this.getValue().length, slen = this.view.getSelectedRecords().length;
    				if (vlen != slen || vlen == 0) {
    					this.selectByValue(this.value, true);
    				}
                } else {
                    this.expand();
    				this.doQuery(this.getRawValue());
                }

    			this.highlightIndex = -1
    			this.highlightIndexPrev = null;
    			this.selectNext();
    			this.scrollIntoView();
                this.el.focus();
            }
    	},

    	// onQuery, beforequery listener, @return false
    	onQuery : function(qe) {
    		q = qe.query;
            forceAll = qe.forceAll;
            if(forceAll === true || (q.length >= this.minChars)){
                if(this.lastQuery !== q){
    				if (typeof(this.lastQuery) != 'undefined') {
    					if (q.match(new RegExp('^'+this.allSelectedText))) {
    						this.query = this.store.data;
    					}
    					else if (this.lastQuery.length > q.length) {
    						var items = q.replace(/\s+/g, '').split(',');
    						if (items[items.length-1].length == 0) {
    							items.pop();
    						}
    						this.query = this.store.data.filterBy(this.store.createFilterFn(this.displayField, new RegExp('^'+items.join('$|^')+'$', "i"), false, false));
    					}
    					else {
    						this.query = null;
    					}
    				}
                    this.lastQuery = q;
                    if(this.mode == 'local'){
    					var raw = this.getRawValue();
    					if (raw == this.allSelectedText) {

    					}
    					var items = raw.replace(/\s+/g, '').split(',');
    					var last = items.pop();
    					this.matches = this.store.data.filterBy(this.store.createFilterFn(this.displayField, new RegExp('^'+last, "i"), false, false)).filterBy(this.createTypeAheadFilterFn(items));
    					if (this.matches.getCount() == 0) {
    						this.clearHighlight();
    					}
    					if (q.length == 0) {
    						this.view.clearSelections();
    						this.updateValue([]);
    					}

                        this.onLoad();
                    } else {
                        this.store.baseParams[this.queryParam] = q;
                        this.store.load({
                            params: this.getParams(q)
                        });
                        this.expand();
                    }
                }else{
                    this.selectedIndex = -1;
                    this.onLoad();
                }
            }

    		return false;
    	},

    	// onLoad, overrides Ext.form.ComboBox#onLoad
    	onLoad : function(){

            if(!this.hasFocus){
                return;
            }
            if(this.store.getCount() > 0){
                if (!this.isExpanded()) {
    				this.expand();
    				this.restrictHeight();
    			}
                if(this.lastQuery == this.allQuery){
                    if(this.editable){
                        this.el.dom.select();
                    }
                }else{
    				if (this.query != null) {
    					var values = [], indexes = [];
    					this.query.each(function(r){
    						values.push(r.data[this.valueField]);
    						indexes.push(this.store.indexOf(r));
    					}, this);
    					this.view.clearSelections();
    					this.updateValue(values, this.getRawValue());
    					this.view.select(indexes);
    				}
    				if (this.matches != null) {
    					if (this.matches.getCount() == 1) {
    						this.highlight(this.store.indexOf(this.matches.first()));
    						this.scrollIntoView();
    					}
    				}
    				else {
    					// @HACK: If store was configured with a proxy, set its mode to local now that its populated with data.
    					// Re-execute the query now.
    					this.mode = 'local';
    					this.lastQuery = undefined;
    					this.doQuery(this.getRawValue(), true);
    				}
                    if(this.typeAhead && this.lastKey != Ext.EventObject.DOWN && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
    					this.taTask.delay(this.typeAheadDelay);
                    }
                }
            }else{
                this.onEmptyResults();
            }
        },

    	onSelect : function(record, index) {
    		if (index == -1) {
    			throw new Error('MultiCombo#onSelect did not receive a valid index');
    		}

    		// select only when user clicks [apply] button
    		if (this.selectOnApply == true) {
    			return;
    		}

    		if (this.fireEvent('beforeselect', this, record, index) !== false) {
    			var text = [];
    			var value = [];
    			var rs = this.view.getSelectedRecords();
    			for (var n = 0, len = rs.length; n < len; n++) {
    				text.push(rs[n].data[this.displayField]);
    				value.push(rs[n].data[this.valueField]);
    			}
    			this.updateValue(value, (value.length != this.store.getCount()) ? text.join(', ') : this.allSelectedText);
    			var node = this.view.getNode(index);
    			this.innerList.scrollChildIntoView(node, false);
    			this.fireEvent('select', this, record, index);
    		}
    	},

    	// private
        onViewOver : function(ev, node){
    		var t = ev.getTarget(this.view.itemSelector);
    		if (t == null) {
    			return;
    		}
    		this.highlightIndex = this.store.indexOf(this.view.getRecord(t));
    		this.clearHighlight();
    		this.highlight(this.highlightIndex);
            if(this.inKeyMode){ // prevent key nav and mouse over conflicts
                return;null
            }
            return;
        },

    	// private
        onTypeAhead : function(){
    		if(this.store.getCount() > 0){
    			this.inKeyMode = false;
                var raw = this.getRawValue();
    			var pos = this.getCaretPosition(raw);
    			var items = [];
    			var query = '';
    			if (pos !== false && pos < raw.length) {
    				items = raw.substr(0, pos).replace(/\s+/g, '').split(',');
    				query = items.pop();
    			} else {
    				items = raw.replace(/\s+/g, '').split(',');
    				query = items.pop();
    			}
    			var rs = this.store.data.filterBy(this.store.createFilterFn(this.displayField, new RegExp(query, "i"), false, false)).filterBy(this.createTypeAheadFilterFn(items));

    			if (rs.getCount() == 1) {
    				var r = rs.first();
    				var rindex = this.store.indexOf(r)
    				if (!this.view.isSelected(rindex)) {
    		            this.typeAheadSelected = true;
    					var selStart = raw.length;
    					var len = items.join(',').length;
    					var selEnd = null;
    					var newValue = r.data[this.displayField];
    					if (pos !== false && pos < raw.length) {
    						var insertIdx = items.length;
    						var selStart = pos;
    						items = raw.replace(/\s+/g, '').split(',');
    						items.splice(insertIdx, 1, newValue);
    						selEnd = items.slice(0, insertIdx+1).join(', ').length;
    						this.highlight(rindex);
    						this.scrollIntoView();

    					}
    					else {
    						items.push(newValue);
    					}
    					var len = items.join(',').length;
    		            if(selStart != len){
    						var lastWord = raw.split(',').pop();
    						if (items.length >1 && lastWord.match(/^\s+/) == null) {
    							selStart++;
    						}
    						this.setRawValue(items.join(', '));
    		                this.selectText(selStart, (selEnd!=null) ? selEnd : this.getRawValue().length);
    		            }
    				}
    			}
            }
        },

    	apply : function() {
    		var selected = 	this.view.getSelectedRecords();
    		var value = [];
    		for (var n=0,len=selected.length;n -1 && !this.view.isSelected(idx)) {
    			var rec = this.store.getAt(idx);
    			this.select(idx);
    		}
    	},
    	// filters-out already-selected items from type-ahead queries.
    	// e.g.: if store contains: "betty, barney, bart" and betty is already selected,
    	// when user types "b", only "bart" and "barney" should be returned as possible matches,
    	// since betty is *already* selected
    	createTypeAheadFilterFn : function(items) {
    		var key = this.displayField;
    		return function(rec) {
    			var re = new RegExp(rec.data[key], "i");
    			var add = true;
    			for (var n=0,len=items.length;n/**
    	 * setValue
    	 * Accepts a comma-separated list of ids or an array.  if given a string, will conver to Array.
    	 * @param {Array, String} v
    	 */
    	setValue : function(v) {
    		var text = [];
    		var value = [];

    		if (typeof(v) == 'string') {	// <-- "1,2,3"
    			value = v.match(/\d+/g); // <-- strip multiple spaces and split on ","
                if(value){
    			    for (var n=0,len=value.length;n/**
         * Select an item in the dropdown list by its numeric index in the list. This function does NOT cause the select event to fire.
         * The store must be loaded and the list expanded for this function to work, otherwise use setValue.
         * @param {Number} index The zero-based index of the list item to select
         * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the
         * selected item if it is not currently in view (defaults to true)
         */
        select : function(index, scrollIntoView){
    		if (!typeof(index) == 'number') {
    			throw new Error('MultiCombo#select expected @param {Number} index but got: ' + typeof(index));
    		}
            this.view.isSelected(index) ? this.view.deselect(index, true) : this.view.select(index, true);
    		this.onSelect(this.store.getAt(index), index);

    		this.matches = null;
            if(scrollIntoView !== false){
                var el = this.view.getNode(index);
                if(el){
                    this.innerList.scrollChildIntoView(el, false);
                }
            }

        },

    	getLastValue : function() {
    		return Ext.util.Format.trim(this.getRawValue().split(',').pop());
    	},

    	/**
         * Select an item in the dropdown list by its data value. This function does NOT cause the select event to fire.
         * The store must be loaded and the list expanded for this function to work, otherwise use setValue.
         * @param {String} value The data value of the item to select
         * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the
         * selected item if it is not currently in view (defaults to true)
         * @return {Boolean} True if the value matched an item in the list, else false
         */
        selectByValue : function(v, scrollIntoView){
    		if (v.length) {
    			var indexes = [];
    			var rs = this.store.data.filterBy(this.store.createFilterFn(this.valueField, new RegExp(v.join('|'), "i"))).each(function(r){
    				indexes.push(this.store.indexOf(r));
    			}, this);
    			if (indexes.length) {
    				this.view.select(indexes);
    				return true;
    			}
    		}
    		else {
    			this.view.clearSelections();
    			this.setRawValue('');
    			return false;
    		}
        },

    	// private
        initEvents : function(){
            Ext.form.ComboBox.superclass.initEvents.call(this);
            this.keyNav = new Ext.KeyNav(this.el, {
                "up" : function(e){
    				this.lastKey = Ext.EventObject.UP;
                    this.inKeyMode = true;
                    this.selectPrev();
    				this.scrollIntoView();
                },

                "down" : function(e){
                    this.inKeyMode = true;
    				if(!this.isExpanded()){
    					this.lastKey = Ext.EventObject.DOWN;
                        this.onTriggerClick();
                    }else{
                        this.selectNext();
    					this.scrollIntoView();
                    }

                },

                "enter" : function(e){
    				var idx = this.highlightIndex;
    				if (this.inKeyMode === true) {
    					if (this.plugins.length && (idx <= -1)) {
    						if (this.plugins[idx + 1]) {
    							this.plugins[idx + 1].onEnter(this);
    						}
    					}
    					else
    						if (this.plugins.length && this.highlightIndex == 0 && this.highlightIndexPrev == -1) {
    							if (this.plugins[idx]) {
    								this.plugins[idx].onEnter(this);
    							}
    						}
    						else {
    							var idx = this.getHighlightedIndex() || 0;
    							if (this.highlightIndex != null && idx != null) {
    								this.select(idx, true);
    								//this.delayedCheck = true;
    								//this.unsetDelayCheck.defer(10, this);

    							}
    						}
    				}
    				else {
    					var v = this.getLastValue();
    					var raw = this.getRawValue();

    					/** this block should be moved to method getCurrentWord
    					 *
    					 */
    					var pos = this.getCaretPosition(raw);
    					var word = '';
    					if (pos !== false && pos < raw.length) {
    						word = Ext.util.Format.trim(raw.substr(0, pos).split(',').pop());
    					} else {
    						word = Ext.util.Format.trim(raw.split(',').pop());
    					}
    					/*******************************************************/

    					var idx = this.store.find(this.displayField, word);
    					if (idx != -1) {
    						var rec = this.store.getAt(idx);
    						this.select(idx, true);
    					}
    					raw = this.getRawValue();
    					this.selectText(raw.length, raw.length);
    					this.collapse();
    				}
                },

                "esc" : function(e){
                    this.collapse();
                },

                "tab" : function(e){
    				if (this.matches != null && this.matches.getCount() == 1) {
    					var idx = this.store.indexOf(this.matches.first());
    					if (!this.view.isSelected(idx)) {
    						this.select(this.store.indexOf(this.matches.first()), true);
    					}
    				}
    				else if (this.value.length == 0 && this.getRawValue().length > 0) {
    					this.setRawValue('');
    				}
    				this.collapse();
                    return true;
                },

                scope : this,

                doRelay : function(foo, bar, hname){
                    if(hname == 'down' || this.scope.isExpanded()){
                       return Ext.KeyNav.prototype.doRelay.apply(this, arguments);
                    }
                    return true;
                },

                forceKeyDown : true
            });
            this.queryDelay = Math.max(this.queryDelay || 10,
                    this.mode == 'local' ? 10 : 250);
            this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
            if(this.typeAhead){
                this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
            }
            if(this.editable !== false){
                this.el.on("keyup", this.onKeyUp, this);
            }
            if(this.forceSelection){
                this.on('blur', this.doForce, this);
            }
        },

    	// private, blur-handler to ensure that rawValue contains only values from selections, in the same order as selected
    	validateSelections : function(field) {
    		var v = this.getValue();
    		var text = [];
    		for (var i=0,len=v.length;i=0) {
    				text.push(this.store.getAt(idx).data[this.displayField]);
    			}
    		}
    		this.setRawValue(text.join(', '));
    	},

    	scrollIntoView : function() {
    		var el = this.getHighlightedNode();
    		if (el) {
    			this.innerList.scrollChildIntoView(el);
    		}
    	},

    	// private
        selectNext : function(){
    		this.clearHighlight();
    		if (this.highlightIndex == null) {
    			this.highlightIndex = -1;
    		}
    		if (this.highlightIndex <= -1 && this.highlightIndexPrev != -1) {
    			if (this.plugins.length > 0) {
    				var idx = Math.abs(this.highlightIndex)-1;
    				if (this.plugins.length >= Math.abs(this.highlightIndex)) {
    					this.plugins[idx].selectNext(this);
    					this.highlightIndexPrev = this.highlightIndex;
    					this.highlightIndex++;
    					return false;
    				}
    			}
    		}
    		if (this.highlightIndexPrev == -1 && this.highlightIndex == 0) {
    			this.highlightIndex = -1;
    		}
    		var ct = this.store.getCount();
    		if(ct > 0){
                if (this.highlightIndex == -1 || this.highlightIndex+1 < ct) {
    				if (this.highlightIndex == -1) {
    					this.highlightIndexPrev = 0;
    				}
    				else {
    					this.highlightIndexPrev = this.highlightIndex -1;
    				}
    				this.highlight(++this.highlightIndex);

    			}
    			else {
    				this.highlight(ct-1);
    			}
            }
        },

        // private
        selectPrev : function(){
    		this.clearHighlight();
    		if (this.highlightIndex <= 0) {
    			var idx = Math.abs(this.highlightIndex);
    			if (this.plugins.length >= idx+1 && this.highlightIndexPrev >= 0) {
    				this.clearHighlight();
    				this.plugins[idx].selectPrev(this);
    				this.highlightIndexPrev = this.highlightIndex;
    				this.highlightIndex--;
    				if (this.highlightIndex == -1) {
    					this.highlightIndexPrev = -1;
    				}
    				return false;
    			}
    			else {
    				this.highlightIndex = -1;
    				this.highlightIndexPrev = -1;
    				this.collapse();
    				return;
    			}
    		}

    		this.highlightIndexPrev = this.highlightIndex;
            var ct = this.store.getCount();
            if(ct > 0){
    			if (this.highlighIndex == -1) {
    				this.highlightIndex = 0;
    			}
    			else if (this.highlightIndex != 0) {
    				this.highlightIndex--;
    			}
    			else if (this.highlightIndex == 0) {
    				this.collapse();
    			}
    			this.highlight(this.highlightIndex);
            }
        },

    	collapse : function() {
    		if (this.isExpanded()) {
    			this.highlightIndex = null;
    			this.highlightIndexPrev = null;
    		}
    		Ext.ux.MultiCombo.superclass.collapse.call(this);
    	},

    	highlight : function(index) {
    		this.view.el.select('.'+this.highlightClass).removeClass(this.highlightClass);
    		var node = Ext.fly(this.view.getNode(index));
    		if (node) {
    			node.addClass(this.highlightClass);
    		}
    	},

    	getHighlightedIndex : function() {
    		var node = this.view.el.child('.' + this.highlightClass, true);
    		return (node) ? this.store.indexOf(this.view.getRecord(node)) : this.highlightIndex;
    	},
    	getHighlightedNode : function() {
    		return this.view.el.child('.'+this.highlightClass, true);
    	},

    	clearHighlight : function() {
    		if (typeof(this.view) != 'object') { return false; }
    		var el = this.view.el.select('.'+this.highlightClass);
    		if (el) {
    			el.removeClass(this.highlightClass);
    		}
    	},

        // private
        initList : function(){
            if(!this.list){
                var cls = 'x-combo-list';

                this.list = new Ext.Layer({
                    shadow: this.shadow, cls: [cls, this.listClass].join(' '), constrain:false
                });

                var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
                this.list.setWidth(lw);
                this.list.swallowEvent('mousewheel');
                this.assetHeight = 0;
                if(this.syncFont !== false){
                    this.list.setStyle('font-size', this.el.getStyle('font-size'));
                }
                if(this.title){
                    this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
                    this.assetHeight += this.header.getHeight();
                }

                this.innerList = this.list.createChild({cls:cls+'-inner'});
                this.innerList.on('mouseover', this.onViewOver, this);
                this.innerList.on('mousemove', this.onViewMove, this);
                this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));

                if(this.pageSize){
                    this.footer = this.list.createChild({cls:cls+'-ft'});
                    this.pageTb = new Ext.PagingToolbar({
                        store:this.store,
                        pageSize: this.pageSize,
                        renderTo:this.footer
                    });
                    this.assetHeight += this.footer.getHeight();
                }

                if(!this.tpl){
                    /**
                    * @cfg {String/Ext.XTemplate} tpl The template string, or {@link Ext.XTemplate}
                    * instance to use to display each item in the dropdown list. Use
                    * this to create custom UI layouts for items in the list.
                    *
                    * If you wish to preserve the default visual look of list items, add the CSS
                    * class name x-combo-list-item to the template's container element.
                    *
                    * The template must contain one or more substitution parameters using field
                    * names from the Combo's {@link #store Store}. An example of a custom template
                    * would be adding an ext:qtip attribute which might display other fields
                    * from the Store.
                    *
                    * The dropdown list is displayed in a DataView. See {@link Ext.DataView} for details.
                    */
                    this.tpl = '{' + this.displayField + '}';
                    /**
                     * @cfg {String} itemSelector
                     * This setting is required if a custom XTemplate has been specified in {@link #tpl}
                     * which assigns a class other than 'x-combo-list-item' to dropdown list items.
                     * A simple CSS selector (e.g. div.some-class or span:first-child) that will be
                     * used to determine what nodes the DataView which handles the dropdown display will
                     * be working with.
                     */
                }

                /**
                * The {@link Ext.DataView DataView} used to display the ComboBox's options.
                * @type Ext.DataView
                */
                this.view = new Ext.DataView({
                    applyTo: this.innerList,
                    tpl: this.tpl,
    				simpleSelect: true,
                    multiSelect: true,
    				overClass: this.overClass,
                    selectedClass: this.selectedClass,
                    itemSelector: this.itemSelector || '.' + cls + '-item'
                });
                this.view.on('click', this.onViewClick, this);
    			this.fireEvent('initview', this, this.view);
                this.bindStore(this.store, true);

                if(this.resizable){
                    this.resizer = new Ext.Resizable(this.list,  {
                       pinned:true, handles:'se'
                    });
                    this.resizer.on('resize', function(r, w, h){
                        this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
                        this.listWidth = w;
                        this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
                        this.restrictHeight();
                    }, this);
                    this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
                }
            }
        }
    });

    Ext.reg('multicombo', Ext.ux.MultiCombo);