Show:
                            var BaseCellEditor,
                                REGEX_BR = /<br\s*\/?>/gi,
                                REGEX_NL = /[\r\n]/g,
                                TPL_BR = '<br/>';
                            
                            /**
                             * Abstract class BaseCellEditor.
                             *
                             * @class A.BaseCellEditor
                             * @extends Overlay
                             * @param {Object} config Object literal specifying widget configuration
                             * properties.
                             * @constructor
                             */
                            BaseCellEditor = A.Component.create({
                            
                                /**
                                 * Static property provides a string to identify the class.
                                 *
                                 * @property NAME
                                 * @type String
                                 * @static
                                 */
                                NAME: 'baseCellEditor',
                            
                                /**
                                 * Static property used to define the default attribute configuration for
                                 * the `A.BaseCellEditor`.
                                 *
                                 * @property ATTRS
                                 * @type Object
                                 * @static
                                 */
                                ATTRS: {
                                    /**
                                     * The node to constrain the widget's bounding box to, when setting xy.
                                     * Can also be set to true, to constrain to the viewport.
                                     *
                                     * @attribute constrain
                                     * @type boolean | Node
                                     * @default true
                                     */
                                    constrain: {
                                        value: true
                                    },
                            
                                    /**
                                     * Indicates if `A.BaseCellEditor` is able to edit a cell's value.
                                     *
                                     * @attribute editable
                                     * @default false
                                     * @type Boolean
                                     */
                                    editable: {
                                        value: false,
                                        validator: A.Lang.isBoolean
                                    },
                            
                                    /**
                                     * Defines the `name` of the `A.BaseCellEditor` input.
                                     *
                                     * @attribute elementName
                                     * @default 'value'
                                     * @type String
                                     */
                                    elementName: {
                                        value: 'value',
                                        validator: A.Lang.isString
                                    },
                            
                                    /**
                                     * Overrides `footerContent`. Defaults to a blank string.
                                     *
                                     * Originally defined in `WidgetStdMod`.
                                     *
                                     * @attribute footerContent
                                     * @default ''
                                     * @type String
                                     */
                                    footerContent: {
                                        value: ''
                                    },
                            
                                    /**
                                     * Indicates if `A.BaseCellEditor` is hidden on the `save` event.
                                     *
                                     * @attribute hideOnSave
                                     * @default true
                                     * @type Boolean
                                     */
                                    hideOnSave: {
                                        value: true,
                                        validator: A.Lang.isBoolean
                                    },
                            
                                    /**
                                     * Set input formatter for HTML display.
                                     *
                                     * Default Function replaces line feeds (`[\r\n]`) with `<br>`.
                                     *
                                     * @attribute inputFormatter
                                     * @type Function
                                     */
                                    inputFormatter: {
                                        value: function(val) {
                                            if (A.Lang.isString(val)) {
                                                val = val.replace(REGEX_NL, TPL_BR);
                                            }
                            
                                            return val;
                                        }
                                    },
                            
                                    /**
                                     * Set output formatter for data storage.
                                     *
                                     * Default Function unescapes HTML Entities as well as replaces `<br>`
                                     * with line feeds (`\n`).
                                     *
                                     * Set attribute `unescapeValue` to 'false' to keep HTML Entities
                                     * unchanged.
                                     *
                                     * @attribute outputFormatter
                                     * @type Function
                                     */
                                    outputFormatter: {
                                        value: function(val) {
                                            var instance = this;
                            
                                            if (A.Lang.isString(val)) {
                                                if (instance.get('unescapeValue')) {
                                                    val = A.Lang.String.unescapeEntities(val);
                                                }
                            
                                                val = val.replace(REGEX_BR, '\n');
                                            }
                            
                                            return val;
                                        }
                                    },
                            
                                    /**
                                     * Indicates if `A.BaseCellEditor` toolbar is shown.
                                     *
                                     * @attribute showToolbar
                                     * @default true
                                     * @type Boolean
                                     */
                                    showToolbar: {
                                        value: true,
                                        validator: A.Lang.isBoolean
                                    },
                            
                                    /**
                                     * Collection of strings used to label elements of UI.
                                     *
                                     * @attribute strings
                                     * @type Object
                                     */
                                    strings: {
                                        value: {
                                            edit: 'Edit',
                                            save: 'Save',
                                            cancel: 'Cancel'
                                        }
                                    },
                            
                                    /**
                                     * Number defining the `tabindex` of `A.BaseCellEditor` input.
                                     *
                                     * @attribute tabIndex
                                     * @default 1
                                     * @type Number
                                     */
                                    tabIndex: {
                                        value: 1
                                    },
                            
                                    /**
                                     * Defines the `Toolbar` config for the `A.BaseCellEditor`.
                                     *
                                     * @attribute toolbar
                                     * @default null
                                     * @type Object
                                     */
                                    toolbar: {
                                        setter: '_setToolbar',
                                        validator: A.Lang.isObject,
                                        value: null
                                    },
                            
                                    /**
                                     * Indicates whether or not HTML Entities get unescaped on input.
                                     *
                                     * See `outputFormatter` for more details.
                                     *
                                     * @attribute unescapeValue
                                     * @default true
                                     * @type Boolean
                                     */
                                    unescapeValue: {
                                        value: true,
                                        validator: A.Lang.isBoolean
                                    },
                            
                                    /**
                                     * Defines the `FormValidator` config for the `A.BaseCellEditor`.
                                     *
                                     * @attribute validator
                                     * @default null
                                     * @type Object
                                     */
                                    validator: {
                                        setter: '_setValidator',
                                        validator: A.Lang.isObject,
                                        value: null
                                    },
                            
                                    /**
                                     * Stores the input value of `A.BaseCellEditor`.
                                     *
                                     * @attribute value
                                     * @default ''
                                     * @type String
                                     */
                                    value: {
                                        value: ''
                                    },
                            
                                    /**
                                     * Indicates if `A.BaseCellEditor` is visible.
                                     *
                                     * Originally defined in `Widget`.
                                     *
                                     * @attribute visible
                                     * @default false
                                     * @type Boolean
                                     */
                                    visible: {
                                        value: false
                                    }
                                },
                            
                                /**
                                 * Static property used to define which component it extends.
                                 *
                                 * @property EXTENDS
                                 * @type Object
                                 * @static
                                 */
                                EXTENDS: A.Overlay,
                            
                                /**
                                 * Static property used to define the UI attributes.
                                 *
                                 * @property UI_ATTRS
                                 * @type Array
                                 * @static
                                 */
                                UI_ATTRS: ['editable', 'showToolbar', 'value'],
                            
                                prototype: {
                                    CONTENT_TEMPLATE: '<form></form>',
                                    ELEMENT_TEMPLATE: null,
                            
                                    elements: null,
                                    validator: null,
                            
                                    _hDocEscKeyEv: null,
                                    _hDocMouseDownEv: null,
                            
                                    /**
                                     * Construction logic executed during the `A.BaseCellEditor`
                                     * instantiation. Lifecycle.
                                     *
                                     * @method initializer
                                     * @protected
                                     */
                                    initializer: function() {
                                        this._initEvents();
                                    },
                            
                                    /**
                                     * Destructor lifecycle implementation for the `A.BaseCellEditor` class.
                                     *
                                     * @method destructor
                                     * @protected
                                     */
                                    destructor: function() {
                                        var hDocEscKey = this._hDocEscKeyEv,
                                            hDocMouseDown = this._hDocMouseDownEv,
                                            toolbar = this.toolbar,
                                            validator = this.validator;
                            
                                        if (hDocEscKey) {
                                            hDocEscKey.detach();
                                        }
                            
                                        if (hDocMouseDown) {
                                            hDocMouseDown.detach();
                                        }
                            
                                        if (toolbar) {
                                            toolbar.destroy();
                                        }
                            
                                        if (validator) {
                                            validator.destroy();
                                        }
                                    },
                            
                                    /**
                                     * Utility method, which calls the passed `inputFormatter` Function,
                                     * using `val` as an argument.
                                     *
                                     * @method formatValue
                                     * @param {Function} inputFormatter See `inputFormatter` attribute.
                                     * @param {mixed} val
                                     * @return {mixed} Formated Value.
                                     */
                                    formatValue: function(inputFormatter, val) {
                                        var instance = this;
                            
                                        if (A.Lang.isFunction(inputFormatter)) {
                                            val = inputFormatter.call(instance, val);
                                        }
                            
                                        return val;
                                    },
                            
                                    /**
                                     * Gets and formats the `A.BaseCellEditor` input value.
                                     *
                                     * @method getValue
                                     * @return {mixed} Formated Value.
                                     */
                                    getValue: function() {
                                        var instance = this;
                            
                                        return instance.formatValue(
                                            instance.get('inputFormatter'),
                                            instance.getElementsValue()
                                        );
                                    },
                            
                                    /**
                                     * `publish()` custom events during `initializer`.
                                     *
                                     * @method _initEvents
                                     * @protected
                                     */
                                    _initEvents: function() {
                                        var instance = this;
                            
                                        instance.publish({
                                            cancel: {
                                                defaultFn: instance._defCancelFn
                                            },
                            
                                            initEdit: {
                                                defaultFn: instance._defInitEditFn,
                                                fireOnce: true
                                            },
                            
                                            initValidator: {
                                                defaultFn: instance._defInitValidatorFn,
                                                fireOnce: true
                                            },
                            
                                            initToolbar: {
                                                defaultFn: instance._defInitToolbarFn,
                                                fireOnce: true
                                            },
                            
                                            save: {
                                                defaultFn: instance._defSaveFn
                                            }
                                        });
                            
                                        instance.after({
                                            render: instance._afterRender,
                                            visibleChange: A.debounce(instance._debounceVisibleChange, 350, instance)
                                        });
                            
                                        instance.on({
                                            'form-validator:submit': A.bind(instance._onSubmit, instance)
                                        });
                                    },
                            
                                    /**
                                     * Fires after the `render` event. Initializes validation and toolbar.
                                     *
                                     * @method _afterRender
                                     * @protected
                                     */
                                    _afterRender: function() {
                                        var instance = this;
                            
                                        instance._handleInitValidatorEvent();
                                        instance._handleInitToolbarEvent();
                                    },
                            
                                    /**
                                     * Default callback for the `cancel` event. Hides the `A.BaseCellEditor`.
                                     *
                                     * @method _defCancelFn
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _defCancelFn: function() {
                                        this.hide();
                                    },
                            
                                    /**
                                     * Default callback for the `initValidator` event. Initializes the
                                     * `FormValidator` using the config from the `validator`
                                     * attribute.
                                     *
                                     * @method _defInitValidatorFn
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _defInitValidatorFn: function() {
                                        var instance = this;
                            
                                        instance.validator = new A.FormValidator(
                                            instance.get('validator')
                                        );
                                    },
                            
                                    /**
                                     * Default callback for the `initToolbar` event. Initializes the
                                     * `Toolbar` using the config from the `toolbar` attribute.
                                     *
                                     * @method _defInitToolbarFn
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _defInitToolbarFn: function() {
                                        var instance = this;
                            
                                        var editable = instance.get('editable');
                            
                                        instance.toolbar = new A.Toolbar(
                                            instance.get('toolbar')
                                        ).render(instance.footerNode);
                            
                                        if (editable) {
                                            instance._uiSetEditable(editable);
                                        }
                                    },
                            
                                    /**
                                     * Default callback for the `save` event. Conditionally hides the
                                     * `A.BaseCellEditor` based on the `hideOnSave` attribute.
                                     *
                                     * @method _defSaveFn
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _defSaveFn: function() {
                                        var instance = this;
                            
                                        if (instance.get('hideOnSave')) {
                                            instance.hide();
                                        }
                                    },
                            
                                    /**
                                     * Fires after the `visibleChange` event. Binds the `mousedown` event
                                     * listener and `keydown` event listener for the escape key.
                                     *
                                     * See: `_onDocMouseDownExt` and `_onEscKey` for details.
                                     *
                                     * @method _debounceVisibleChange
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _debounceVisibleChange: function(event) {
                                        var instance = this;
                            
                                        var hDocEscKey = instance._hDocEscKeyEv;
                                        var hDocMouseDown = instance._hDocMouseDownEv;
                            
                                        if (event.newVal) {
                                            if (!hDocEscKey) {
                                                instance._hDocEscKeyEv = A.getDoc().on('key', A.bind(instance._onEscKey, instance), 'down:27');
                                            }
                            
                                            if (!hDocMouseDown) {
                                                instance._hDocMouseDownEv = A.getDoc().on('mousedown', A.bind(instance._onDocMouseDownExt, instance));
                                            }
                                        }
                                        else {
                                            if (hDocEscKey) {
                                                hDocEscKey.detach();
                            
                                                instance._hDocEscKeyEv = null;
                                            }
                            
                                            if (hDocMouseDown) {
                                                hDocMouseDown.detach();
                            
                                                instance._hDocMouseDownEv = null;
                                            }
                                        }
                                    },
                            
                                    /**
                                     * Fires the `click` event.
                                     *
                                     * @method _handleCancelEvent
                                     * @protected
                                     */
                                    _handleCancelEvent: function() {
                                        var instance = this;
                            
                                        instance.fire('cancel');
                                    },
                            
                                    /**
                                     * Fires the `edit` event.
                                     *
                                     * @method _handleEditEvent
                                     * @protected
                                     */
                                    _handleEditEvent: function() {
                                        var instance = this;
                            
                                        instance.fire('edit');
                                    },
                            
                                    /**
                                     * Fires the `initEdit` event when the `A.BaseCellEditor` is rendered.
                                     *
                                     * @method _handleInitEditEvent
                                     * @protected
                                     */
                                    _handleInitEditEvent: function() {
                                        var instance = this;
                            
                                        if (instance.get('rendered')) {
                                            this.fire('initEdit');
                                        }
                                    },
                            
                                    /**
                                     * Fires the `initValidator` event when the `A.BaseCellEditor` is
                                     * rendered.
                                     *
                                     * @method _handleInitValidatorEvent
                                     * @protected
                                     */
                                    _handleInitValidatorEvent: function() {
                                        var instance = this;
                            
                                        if (instance.get('rendered')) {
                                            this.fire('initValidator');
                                        }
                                    },
                            
                                    /**
                                     * Fires the `initToolbar` event when the `A.BaseCellEditor` is rendered
                                     * and the toolbar is visible.
                                     *
                                     * @method _handleInitToolbarEvent
                                     * @protected
                                     */
                                    _handleInitToolbarEvent: function() {
                                        var instance = this;
                            
                                        if (instance.get('rendered') && instance.get('showToolbar')) {
                                            this.fire('initToolbar');
                                        }
                                    },
                            
                                    /**
                                     * Fires the `save` event when the cell values are valid.
                                     *
                                     * @method _handleSaveEvent
                                     * @protected
                                     */
                                    _handleSaveEvent: function() {
                                        var instance = this;
                            
                                        instance.validator.validate();
                            
                                        if (!instance.validator.hasErrors()) {
                                            instance.fire('save', {
                                                newVal: instance.getValue(),
                                                prevVal: instance.get('value')
                                            });
                                        }
                                    },
                            
                                    /**
                                     * Fires after the `visibleChange` event binding the mousedown event.
                                     *
                                     * @method _onDocMouseDownExt
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _onDocMouseDownExt: function(event) {
                                        var instance = this;
                            
                                        var boundingBox = instance.get('boundingBox');
                            
                                        if (!boundingBox.contains(event.target)) {
                                            instance._handleCancelEvent();
                                        }
                                    },
                            
                                    /**
                                     * Fires the `keydown` event listener for the esc key.
                                     *
                                     * @method _onEscKey
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _onEscKey: function() {
                                        var instance = this;
                            
                                        instance._handleCancelEvent();
                                    },
                            
                                    /**
                                     * Fires the `submit` event.
                                     *
                                     * @method _onSubmit
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _onSubmit: function(event) {
                                        var validator = event.validator;
                            
                                        if (validator) {
                                            validator.formEvent.halt();
                                        }
                                    },
                            
                                    /**
                                     * Setter for Toolbar attribute.
                                     *
                                     * @method _setToolbar
                                     * @param {Object} val
                                     * @protected
                                     */
                                    _setToolbar: function(val) {
                                        var instance = this;
                            
                                        var strings = instance.getStrings();
                            
                                        return A.merge({
                                            activeState: false,
                                            children: [
                                                [
                                                    {
                                                        on: {
                                                            click: A.bind(instance._handleSaveEvent, instance)
                                                        },
                                                        label: strings.save,
                                                        icon: 'glyphicon glyphicon-ok-sign'
                                                    },
                                                    {
                                                        on: {
                                                            click: A.bind(instance._handleCancelEvent, instance)
                                                        },
                                                        label: strings.cancel
                                                    }
                                                ]
                                            ]
                                        }, val);
                                    },
                            
                                    /**
                                     * Setter for Validator attribute.
                                     *
                                     * @method _setValidator
                                     * @param {Object} val
                                     * @protected
                                     */
                                    _setValidator: function(val) {
                                        var instance = this;
                            
                                        return A.merge({
                                                boundingBox: instance.get('contentBox'),
                                                bubbleTargets: instance
                                            },
                                            val
                                        );
                                    },
                            
                                    /**
                                     * Setter for ShowToolbar attribute.
                                     *
                                     * @method _uiSetShowToolbar
                                     * @param val
                                     * @protected
                                     */
                                    _uiSetShowToolbar: function(val) {
                                        var instance = this;
                            
                                        var footerNode = instance.footerNode;
                            
                                        if (val) {
                                            footerNode.show();
                                        }
                                        else {
                                            footerNode.hide();
                                        }
                            
                                        instance._handleInitToolbarEvent();
                                    },
                            
                                    /**
                                     * Gets the `A.BaseCellEditor` input value.
                                     *
                                     * NOTE FOR DEVELOPERS: Yoy *may* want to replace the methods from
                                     * this section on your implementation.
                                     *
                                     * @method getElementsValue
                                     * @return {String} Input value.
                                     */
                                    getElementsValue: function() {
                                        var instance = this;
                            
                                        var elements = instance.elements;
                            
                                        if (elements) {
                                            return elements.get('value');
                                        }
                            
                                        return '';
                                    },
                            
                                    /**
                                     * Render the `A.BaseCellEditor` component instance. Lifecycle.
                                     *
                                     * @method renderUI
                                     * @protected
                                     */
                                    renderUI: function() {
                                        var instance = this;
                            
                                        if (instance.ELEMENT_TEMPLATE) {
                                            instance.elements = A.Node.create(instance.ELEMENT_TEMPLATE);
                            
                                            instance._syncElementsName();
                            
                                            instance.setStdModContent(A.WidgetStdMod.BODY, instance.elements);
                                        }
                                    },
                            
                                    /**
                                     * Default callback for `initEdit` event of `A.BaseCellEditor`.
                                     *
                                     * @method _defInitEditFn
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _defInitEditFn: function() {},
                            
                                    /**
                                     * Syncs the element focus.
                                     *
                                     * @method _syncElementsFocus
                                     * @protected
                                     */
                                    _syncElementsFocus: function() {
                                        var instance = this;
                            
                                        instance.elements.selectText();
                                    },
                            
                                    /**
                                     * Syncs the name attribute of form input.
                                     *
                                     * @method _syncElementsName
                                     * @protected
                                     */
                                    _syncElementsName: function() {
                                        var instance = this;
                            
                                        instance.elements.setAttribute(
                                            'name',
                                            instance.get('elementName')
                                        );
                                    },
                            
                                    /**
                                     * Syncs the cell editor focus.
                                     *
                                     * @method _syncFocus
                                     * @protected
                                     */
                                    _syncFocus: function() {
                                        var instance = this;
                            
                                        A.later(0, instance, instance._syncElementsFocus);
                                    },
                            
                                    /**
                                     * Syncs the name attribute of form input.
                                     *
                                     * @method _uiSetEditable
                                     * @param val
                                     * @protected
                                     */
                                    _uiSetEditable: function(val) {
                                        var instance = this;
                            
                                        var toolbar = instance.toolbar;
                            
                                        if (instance.get('rendered') && toolbar) {
                                            if (val) {
                                                toolbar.add(
                                                    [
                                                        {
                                                            icon: 'glyphicon glyphicon-edit',
                                                            label: instance.getString('edit'),
                                                            on: {
                                                                click: A.bind(instance._handleEditEvent, instance)
                                                            }
                                                        }
                                                    ], 1
                                                );
                                            }
                                            else {
                                                toolbar.remove(1);
                                            }
                                        }
                                    },
                            
                                    /**
                                     * Sets and formats `A.BaseCellEditor` input value.
                                     *
                                     * @method _uiSetValue
                                     * @param val
                                     * @protected
                                     */
                                    _uiSetValue: function(val) {
                                        var instance = this;
                            
                                        var elements = instance.elements;
                            
                                        if (elements) {
                                            elements.val(
                                                instance.formatValue(instance.get('outputFormatter'), val)
                                            );
                                        }
                                    }
                                }
                            });
                            
                            A.BaseCellEditor = BaseCellEditor;