    /**
     * Internal utility class that provides default configuration for cell editing.
     * @private
     */
    Ext.define('Ext.grid.CellEditor', {
        extend: 'Ext.Editor',
        constructor: function(config) {
            config = Ext.apply({}, config);

            if (config.field) {
                config.field.monitorTab = false;
            }
            this.callParent([config]);
        },

        /**
         * @private
         * Hide the grid cell text when editor is shown.
         *
         * There are 2 reasons this needs to happen:
         *
         * 1. checkbox editor does not take up enough space to hide the underlying text.
         *
         * 2. When columnLines are turned off in browsers that don't support text-overflow:
         *    ellipsis (firefox 6 and below and IE quirks), the text extends to the last pixel
         *    in the cell, however the right border of the cell editor is always positioned 1px
         *    offset from the edge of the cell (to give it the appearance of being "inside" the
         *    cell.  This results in 1px of the underlying cell text being visible to the right
         *    of the cell editor if the text is not hidden.
         *
         * We can't just hide the entire cell, because then treecolumn's icons would be hidden
         * as well.  We also can't just set "color: transparent" to hide the text because it is
         * not supported by IE8 and below.  The only remaining solution is to remove the text
         * from the text node and then add it back when the editor is hidden.
         */
        onShow: function() {
            var me = this,
                innerCell = me.boundEl.first(),
                lastChild,
                textNode;

            if (innerCell) {
                lastChild = innerCell.dom.lastChild;
                if(lastChild && lastChild.nodeType === 3) {
                    // if the cell has a text node, save a reference to it
                    textNode = me.cellTextNode = innerCell.dom.lastChild;
                    // save the cell text so we can add it back when we're done editing
                    me.cellTextValue = textNode.nodeValue;
                    // The text node has to have at least one character in it, or the cell borders
                    // in IE quirks mode will not show correctly, so let's use a non-breaking space.
                    textNode.nodeValue = me.emptyText;
                }
            }
            me.callParent(arguments);
        },

        /**
         * @private
         * Show the grid cell text when the editor is hidden by adding the text back to the text node
         */
        onHide: function() {
            var me = this,
                innerCell = me.boundEl.first(),
                node = me.cellTextNode;

            if (innerCell && node) {
                // The value may have changed since we started, so only restore it
                // if the value is the same as our space we set earlier
                if (node.nodeValue == me.emptyText) {
                    node.nodeValue = me.cellTextValue;
                }
                delete me.cellTextNode;
                delete me.cellTextValue;
            }
            me.callParent(arguments);
        },

        /**
         * @private
         * Fix checkbox blur when it is clicked.
         */
        afterRender: function() {
            var me = this,
                field = me.field;

            me.callParent(arguments);
            if (field.isXType('checkboxfield')) {
                field.mon(field.inputEl, {
                    mousedown: me.onCheckBoxMouseDown,
                    click: me.onCheckBoxClick,
                    scope: me
                });
            }
        },

        /**
         * @private
         * Because when checkbox is clicked it loses focus  completeEdit is bypassed.
         */
        onCheckBoxMouseDown: function() {
            this.completeEdit = Ext.emptyFn;
        },

        /**
         * @private
         * Restore checkbox focus and completeEdit method.
         */
        onCheckBoxClick: function() {
            delete this.completeEdit;
            this.field.focus(false, 10);
        },

        /**
         * @private
         * Realigns the Editor to the grid cell, or to the text node in the grid inner cell
         * if the inner cell contains multiple child nodes.
         */
        realign: function(autoSize) {
            var me = this,
                boundEl = me.boundEl,
                innerCell = boundEl.first(),
                children = innerCell.dom.childNodes,
                childCount = children.length,
                offsets = Ext.Array.clone(me.offsets),
                inputEl = me.field.inputEl,
                lastChild, leftBound, rightBound, width;

            // If the inner cell has more than one child, or the first child node is not a text node,
            // let's assume this cell contains additional elements before the text node.
            // This is the case for tree cells, but could also be used to accomodate grid cells that
            // have a custom renderer that render, say, an icon followed by some text for example
            // For now however, this support will only be used for trees.
            if(me.isForTree && (childCount > 1 || (childCount === 1 && children[0].nodeType !== 3))) {
                // get the inner cell's last child
                lastChild = innerCell.last();
                // calculate the left bound of the text node
                leftBound = lastChild.getOffsetsTo(innerCell)[0] + lastChild.getWidth();
                // calculate the right bound of the text node (this is assumed to be the right edge of
                // the inner cell, since we are assuming the text node is always the last node in the
                // inner cell)
                rightBound = innerCell.getWidth();
                // difference between right and left bound is the text node's allowed "width",
                // this will be used as the width for the editor.
                width = rightBound - leftBound;
                // adjust width for column lines - this ensures the editor will be the same width
                // regardless of columLines config
                if(!me.editingPlugin.grid.columnLines) {
                    width --;
                }
                // set the editor's x offset to the left bound position
                offsets[0] += leftBound;

                me.addCls(Ext.baseCSSPrefix + 'grid-editor-on-text-node');
            } else {
                width = boundEl.getWidth() - 1;
            }

            if (autoSize === true) {
                me.field.setWidth(width);
            }

            me.alignTo(boundEl, me.alignment, offsets);
        },

        onEditorTab: function(e){
            var field = this.field;
            if (field.onEditorTab) {
                field.onEditorTab(e);
            }
        },

        emptyText: '\u00a0',

        alignment: "tl-tl",
        hideEl : false,
        cls: Ext.baseCSSPrefix + "small-editor " + Ext.baseCSSPrefix + "grid-editor",
        shim: false,
        shadow: false
    });