    Ext.ns('Ext.ux');
    /**
     * @class Ext.ux.TabScrollerMenu
     * @extends Object
     * Plugin (ptype = 'tabscrollermenu') for adding a tab menu to a TabBar is the Tabs overflow.
     * @constructor
     * @param {Object} config Configuration options
     * @ptype tabscrollermenu
     */
    Ext.define('Ext.ux.TabScrollerMenu', {
        alias: 'plugin.tabscrollermenu',

        uses: ['Ext.menu.Menu'],

        /**
         * @cfg {Number} pageSize How many items to allow per submenu.
         */
        pageSize: 10,
        /**
         * @cfg {Number} maxText How long should the title of each {@link Ext.menu.Item} be.
         */
        maxText: 15,
        /**
         * @cfg {String} menuPrefixText Text to prefix the submenus.
         */
        menuPrefixText: 'Items',
        constructor: function(config) {
            config = config || {};
            Ext.apply(this, config);
        },
        //private
        init: function(tabPanel) {
            var me = this;

            Ext.apply(tabPanel, me.parentOverrides);
            me.tabPanel = tabPanel;

            tabPanel.on({
                render: function() {
                    me.tabBar = tabPanel.tabBar;
                    me.layout = me.tabBar.layout;
                    me.layout.overflowHandler.handleOverflow = Ext.Function.bind(me.showButton, me);
                    me.layout.overflowHandler.clearOverflow = Ext.Function.createSequence(me.layout.overflowHandler.clearOverflow, me.hideButton, me);
                },
                single: true
            });
        },

        showButton: function() {
            var me = this,
                result = Ext.getClass(me.layout.overflowHandler).prototype.handleOverflow.apply(me.layout.overflowHandler, arguments);

            if (!me.menuButton) {
                me.menuButton = me.tabBar.body.createChild({
                    cls: Ext.baseCSSPrefix + 'tab-tabmenu-right'
                }, me.tabBar.body.child('.' + Ext.baseCSSPrefix + 'box-scroller-right'));
                me.menuButton.addClsOnOver(Ext.baseCSSPrefix + 'tab-tabmenu-over');
                me.menuButton.on('click', me.showTabsMenu, me);
            }
            me.menuButton.show();
            result.reservedSpace += me.menuButton.getWidth();
            return result;
        },

        hideButton: function() {
            var me = this;
            if (me.menuButton) {
                me.menuButton.hide();
            }
        },

        /**
         * Returns an the current page size (this.pageSize);
         * @return {Number} this.pageSize The current page size.
         */
        getPageSize: function() {
            return this.pageSize;
        },
        /**
         * Sets the number of menu items per submenu "page size".
         * @param {Number} pageSize The page size
         */
        setPageSize: function(pageSize) {
            this.pageSize = pageSize;
        },
        /**
         * Returns the current maxText length;
         * @return {Number} this.maxText The current max text length.
         */
        getMaxText: function() {
            return this.maxText;
        },
        /**
         * Sets the maximum text size for each menu item.
         * @param {Number} t The max text per each menu item.
         */
        setMaxText: function(t) {
            this.maxText = t;
        },
        /**
         * Returns the current menu prefix text String.;
         * @return {String} this.menuPrefixText The current menu prefix text.
         */
        getMenuPrefixText: function() {
            return this.menuPrefixText;
        },
        /**
         * Sets the menu prefix text String.
         * @param {String} t The menu prefix text.
         */
        setMenuPrefixText: function(t) {
            this.menuPrefixText = t;
        },

        showTabsMenu: function(e) {
            var me = this;

            if (me.tabsMenu) {
                me.tabsMenu.removeAll();
            } else {
                me.tabsMenu = Ext.create('Ext.menu.Menu');
                me.tabPanel.on('destroy', me.tabsMenu.destroy, me.tabsMenu);
            }

            me.generateTabMenuItems();

            var target = Ext.get(e.getTarget());
            var xy = target.getXY();

            //Y param + 24 pixels
            xy[1] += 24;

            me.tabsMenu.showAt(xy);
        },

        // private
        generateTabMenuItems: function() {
            var me = this,
                tabPanel = me.tabPanel,
                curActive = tabPanel.getActiveTab(),
                totalItems = tabPanel.items.getCount(),
                pageSize = me.getPageSize(),
                numSubMenus = Math.floor(totalItems / pageSize),
                remainder = totalItems % pageSize,
                i, curPage, menuItems, x, item, start, index;

            if (totalItems > pageSize) {

                // Loop through all of the items and create submenus in chunks of 10
                for (i = 0; i < numSubMenus; i++) {
                    curPage = (i + 1) * pageSize;
                    menuItems = [];

                    for (x = 0; x < pageSize; x++) {
                        index = x + curPage - pageSize;
                        item = tabPanel.items.get(index);
                        menuItems.push(me.autoGenMenuItem(item));
                    }

                    me.tabsMenu.add({
                        text: me.getMenuPrefixText() + ' ' + (curPage - pageSize + 1) + ' - ' + curPage,
                        menu: menuItems
                    });
                }
                // remaining items
                if (remainder > 0) {
                    start = numSubMenus * pageSize;
                    menuItems = [];
                    for (i = start; i < totalItems; i++) {
                        item = tabPanel.items.get(i);
                        menuItems.push(me.autoGenMenuItem(item));
                    }

                    me.tabsMenu.add({
                        text: me.menuPrefixText + ' ' + (start + 1) + ' - ' + (start + menuItems.length),
                        menu: menuItems
                    });

                }
            }
            else {
                tabPanel.items.each(function(item) {
                    if (item.id != curActive.id && !item.hidden) {
                        me.tabsMenu.add(me.autoGenMenuItem(item));
                    }
                });
            }
        },

        // private
        autoGenMenuItem: function(item) {
            var maxText = this.getMaxText(),
                text = Ext.util.Format.ellipsis(item.title, maxText);

            return {
                text: text,
                handler: this.showTabFromMenu,
                scope: this,
                disabled: item.disabled,
                tabToShow: item,
                iconCls: item.iconCls
            };
        },

        // private
        showTabFromMenu: function(menuItem) {
            this.tabPanel.setActiveTab(menuItem.tabToShow);
        }
    });