    Ext.ux.GroupTab = Ext.extend(Ext.Container, {
        mainItem: 0,

        expanded: true,

        deferredRender: true,

        activeTab: null,

        idDelimiter: '__',

        headerAsText: false,

        frame: false,

        hideBorders: true,

        initComponent: function(config){
            Ext.apply(this, config);
            this.frame = false;

            Ext.ux.GroupTab.superclass.initComponent.call(this);

            this.addEvents('activate', 'deactivate', 'changemainitem', 'beforetabchange', 'tabchange');

            this.setLayout(new Ext.layout.CardLayout({
                deferredRender: this.deferredRender
            }));

            if (!this.stack) {
                this.stack = Ext.TabPanel.AccessStack();
            }

            this.initItems();

            this.on('beforerender', function(){
                this.groupEl = this.ownerCt.getGroupEl(this);
            }, this);

            this.on('add', this.onAdd, this, {
                target: this
            });
            this.on('remove', this.onRemove, this, {
                target: this
            });

            if (this.mainItem !== undefined) {
                var item = (typeof this.mainItem == 'object') ? this.mainItem : this.items.get(this.mainItem);
                delete this.mainItem;
                this.setMainItem(item);
            }
        },

        /**
         * Sets the specified tab as the active tab. This method fires the {@link #beforetabchange} event which
         * can return false to cancel the tab change.
         * @param {String/Panel} tab The id or tab Panel to activate
         */
        setActiveTab : function(item){
            item = this.getComponent(item);
            if(!item || this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
                return;
            }
            if(!this.rendered){
                this.activeTab = item;
                return;
            }
            if(this.activeTab != item){
                if(this.activeTab && this.activeTab != this.mainItem){
                    var oldEl = this.getTabEl(this.activeTab);
                    if(oldEl){
                        Ext.fly(oldEl).removeClass('x-grouptabs-strip-active');
                    }
                    this.activeTab.fireEvent('deactivate', this.activeTab);
                }
                var el = this.getTabEl(item);
                Ext.fly(el).addClass('x-grouptabs-strip-active');
                this.activeTab = item;
                this.stack.add(item);

                this.layout.setActiveItem(item);
                if(this.layoutOnTabChange && item.doLayout){
                    item.doLayout();
                }
                if(this.scrolling){
                    this.scrollToTab(item, this.animScroll);
                }

                item.fireEvent('activate', item);
                this.fireEvent('tabchange', this, item);
            }
        },

        getTabEl: function(item){
            if (item == this.mainItem) {
                return this.groupEl;
            }
            return Ext.TabPanel.prototype.getTabEl.call(this, item);
        },

        onRender: function(ct, position){
            Ext.ux.GroupTab.superclass.onRender.call(this, ct, position);

            this.strip = Ext.fly(this.groupEl).createChild({
                tag: 'ul',
                cls: 'x-grouptabs-sub'
            });

            this.tooltip = new Ext.ToolTip({
               target: this.groupEl,
               delegate: 'a.x-grouptabs-text',
               trackMouse: true,
               renderTo: document.body,
               listeners: {
                   beforeshow: function(tip) {
                       var item = (tip.triggerElement.parentNode === this.mainItem.tabEl)
                           ? this.mainItem
                           : this.findById(tip.triggerElement.parentNode.id.split(this.idDelimiter)[1]);

                       if(!item.tabTip) {
                           return false;
                       }
                       tip.body.dom.innerHTML = item.tabTip;
                   },
                   scope: this
               }
            });

            if (!this.itemTpl) {
                var tt = new Ext.Template('', '{text}', '');
                tt.disableFormats = true;
                tt.compile();
                Ext.ux.GroupTab.prototype.itemTpl = tt;
            }

            this.items.each(this.initTab, this);
        },

        afterRender: function(){
            Ext.ux.GroupTab.superclass.afterRender.call(this);

            if (this.activeTab !== undefined) {
                var item = (typeof this.activeTab == 'object') ? this.activeTab : this.items.get(this.activeTab);
                delete this.activeTab;
                this.setActiveTab(item);
            }
        },

        // private
        initTab: function(item, index){
            var before = this.strip.dom.childNodes[index];
            var p = Ext.TabPanel.prototype.getTemplateArgs.call(this, item);

            if (item === this.mainItem) {
                item.tabEl = this.groupEl;
                p.cls += ' x-grouptabs-main-item';
            }

            var el = before ? this.itemTpl.insertBefore(before, p) : this.itemTpl.append(this.strip, p);

            item.tabEl = item.tabEl || el;

            item.on('disable', this.onItemDisabled, this);
            item.on('enable', this.onItemEnabled, this);
            item.on('titlechange', this.onItemTitleChanged, this);
            item.on('iconchange', this.onItemIconChanged, this);
            item.on('beforeshow', this.onBeforeShowItem, this);
        },

        setMainItem: function(item){
            item = this.getComponent(item);
            if (!item || this.fireEvent('changemainitem', this, item, this.mainItem) === false) {
                return;
            }

            this.mainItem = item;
        },

        getMainItem: function(){
            return this.mainItem || null;
        },

        // private
        onBeforeShowItem: function(item){
            if (item != this.activeTab) {
                this.setActiveTab(item);
                return false;
            }
        },

        // private
        onAdd: function(gt, item, index){
            if (this.rendered) {
                this.initTab.call(this, item, index);
            }
        },

        // private
        onRemove: function(tp, item){
            Ext.destroy(Ext.get(this.getTabEl(item)));
            this.stack.remove(item);
            item.un('disable', this.onItemDisabled, this);
            item.un('enable', this.onItemEnabled, this);
            item.un('titlechange', this.onItemTitleChanged, this);
            item.un('iconchange', this.onItemIconChanged, this);
            item.un('beforeshow', this.onBeforeShowItem, this);
            if (item == this.activeTab) {
                var next = this.stack.next();
                if (next) {
                    this.setActiveTab(next);
                }
                else if (this.items.getCount() > 0) {
                    this.setActiveTab(0);
                }
                else {
                    this.activeTab = null;
                }
            }
        },

        // private
        onBeforeAdd: function(item){
            var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
            if (existing) {
                this.setActiveTab(item);
                return false;
            }
            Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
            var es = item.elements;
            item.elements = es ? es.replace(',header', '') : es;
            item.border = (item.border === true);
        },

        // private
        onItemDisabled: Ext.TabPanel.prototype.onItemDisabled,
        onItemEnabled: Ext.TabPanel.prototype.onItemEnabled,

        // private
        onItemTitleChanged: function(item){
            var el = this.getTabEl(item);
            if (el) {
                Ext.fly(el).child('a.x-grouptabs-text', true).innerHTML = item.title;
            }
        },

        //private
        onItemIconChanged: function(item, iconCls, oldCls){
            var el = this.getTabEl(item);
            if (el) {
                Ext.fly(el).child('a.x-grouptabs-text').replaceClass(oldCls, iconCls);
            }
        },

        beforeDestroy: function(){
            Ext.TabPanel.prototype.beforeDestroy.call(this);
            this.tooltip.destroy();
        }
    });

    Ext.reg('grouptab', Ext.ux.GroupTab);