Show:
                            /**
                             * Provides an interface for working with button-like DOM nodes
                             *
                             * @module button-core
                             * @since 3.5.0
                             */
                            var getClassName = Y.ClassNameManager.getClassName,
                                AttributeCore = Y.AttributeCore;
                            
                            /**
                             * Creates a button
                             *
                             * @class ButtonCore
                             * @uses AttributeCore
                             * @param config {Object} Configuration object
                             * @constructor
                             */
                            function ButtonCore(config) {
                                this.initializer(config);
                            }
                            
                            ButtonCore.prototype = {
                            
                                /**
                                 *
                                 * @property TEMPLATE
                                 * @type {String}
                                 * @default <button/>
                                 */
                                TEMPLATE: '<button/>',
                            
                                /**
                                 *
                                 * @property constructor
                                 * @type {Object}
                                 * @default ButtonCore
                                 * @private
                                 */
                                constructor: ButtonCore,
                            
                                /**
                                 * @method initializer
                                 * @description Internal init() handler.
                                 * @param config {Object} Config object.
                                 * @private
                                 */
                                initializer: function(config) {
                                    this._initNode(config);
                                    this._initAttributes(config);
                                    this._renderUI(config);
                                },
                            
                                /**
                                 * @method _initNode
                                 * @description Node initializer
                                 * @param config {Object} Config object.
                                 * @private
                                 */
                                _initNode: function(config) {
                                    if (config.host) {
                                        this._host = Y.one(config.host);
                                    } else {
                                        this._host = Y.Node.create(this.TEMPLATE);
                                    }
                                },
                            
                                /**
                                 * @method _initAttributes
                                 * @description  Attribute initializer
                                 * @param config {Object} Config object.
                                 * @private
                                 */
                                _initAttributes: function(config) {
                                    AttributeCore.call(this, ButtonCore.ATTRS, config);
                                },
                            
                                /**
                                 * @method renderUI
                                 * @description Renders any UI/DOM elements for Button instances
                                 * @param config {Object} Config object.
                                 * @private
                                 */
                                _renderUI: function() {
                                    var node = this.getNode(),
                                        nodeName = node.get('nodeName').toLowerCase();
                            
                                    // Set some default node attributes
                                    node.addClass(ButtonCore.CLASS_NAMES.BUTTON);
                            
                                    if (nodeName !== 'button' && nodeName !== 'input') {
                                        node.set('role', 'button');
                                    }
                                },
                            
                                /**
                                 * @method enable
                                 * @description Sets the button's `disabled` DOM attribute to `false`
                                 * @public
                                 */
                                enable: function() {
                                    this.set('disabled', false);
                                },
                            
                                /**
                                 * @method disable
                                 * @description Sets the button's `disabled` DOM attribute to `true`
                                 * @public
                                 */
                                disable: function() {
                                    this.set('disabled', true);
                                },
                            
                                /**
                                 * @method getNode
                                 * @description Gets the button's host node
                                 * @return {Node} The host node instance
                                 * @public
                                 */
                                getNode: function() {
                                    if (!this._host) {
                                        // If this._host doesn't exist, that means this._initNode
                                        // was never executed, meaning this is likely a Widget and
                                        // the host node should point to the boundingBox.
                                        this._host = this.get('boundingBox');
                                    }
                            
                                    return this._host;
                                },
                            
                                /**
                                 * @method _getLabel
                                 * @description Getter for a button's `label` ATTR
                                 * @return {String} The text label of the button
                                 * @private
                                 */
                                _getLabel: function () {
                                    var node = this.getNode(),
                                        label = ButtonCore._getTextLabelFromNode(node);
                            
                                    return label;
                                },
                            
                                /**
                                 * @method _getLabelHTML
                                 * @description Getter for a button's `labelHTML` ATTR
                                 * @return {String} The HTML label of the button
                                 * @private
                                 */
                                _getLabelHTML: function () {
                                    var node = this.getNode(),
                                        labelHTML = ButtonCore._getHTMLFromNode(node);
                            
                                    return labelHTML;
                                },
                            
                                /**
                                 * @method _setLabel
                                 * @description Setter for a button's `label` ATTR
                                 * @param value {String} The value to set for `label`
                                 * @param name {String} The name of this ATTR (`label`)
                                 * @param opts {Object} Additional options
                                 *    @param opts.src {String} A string identifying the callee.
                                 *        `internal` will not sync this value with the `labelHTML` ATTR
                                 * @return {String} The text label for the given node
                                 * @private
                                 */
                                _setLabel: function (value, name, opts) {
                                    var label = Y.Escape.html(value);
                            
                                    if (!opts || opts.src !== 'internal') {
                                        this.set('labelHTML', label, {src: 'internal'});
                                    }
                            
                                    return label;
                                },
                            
                                /**
                                 * @method _setLabelHTML
                                 * @description Setter for a button's `labelHTML` ATTR
                                 * @param value {String} The value to set for `labelHTML`
                                 * @param name {String} The name of this ATTR (`labelHTML`)
                                 * @param opts {Object} Additional options
                                 *    @param opts.src {String} A string identifying the callee.
                                 *        `internal` will not sync this value with the `label` ATTR
                                 * @return {String} The HTML label for the given node
                                 * @private
                                 */
                                _setLabelHTML: function (value, name, opts) {
                                    var node = this.getNode(),
                                        labelNode = ButtonCore._getLabelNodeFromParent(node),
                                        nodeName = node.get('nodeName').toLowerCase();
                            
                                    if (nodeName === 'input') {
                                        labelNode.set('value', value);
                                    }
                                    else {
                                        labelNode.setHTML(value);
                                    }
                            
                                    if (!opts || opts.src !== 'internal') {
                                        this.set('label', value, {src: 'internal'});
                                    }
                            
                                    return value;
                                },
                            
                                /**
                                 * @method _setDisabled
                                 * @description Setter for the `disabled` ATTR
                                 * @param value {boolean}
                                 * @private
                                 */
                                _setDisabled: function(value) {
                                    var node = this.getNode();
                            
                                    node.getDOMNode().disabled = value; // avoid rerunning setter when this === node
                                    node.toggleClass(ButtonCore.CLASS_NAMES.DISABLED, value);
                            
                                    return value;
                                }
                            };
                            
                            // ButtonCore inherits from AttributeCore
                            Y.mix(ButtonCore.prototype, AttributeCore.prototype);
                            
                            /**
                             * Attribute configuration.
                             *
                             * @property ATTRS
                             * @type {Object}
                             * @protected
                             * @static
                             */
                            ButtonCore.ATTRS = {
                            
                                /**
                                 * The text of the button's label
                                 *
                                 * @config label
                                 * @type String
                                 */
                                label: {
                                    setter: '_setLabel',
                                    getter: '_getLabel',
                                    lazyAdd: false
                                },
                            
                                /**
                                 * The HTML of the button's label
                                 *
                                 * This attribute accepts HTML and inserts it into the DOM **without**
                                 * sanitization.  This attribute should only be used with HTML that has
                                 * either been escaped (using `Y.Escape.html`), or sanitized according to
                                 * the requirements of your application.
                                 *
                                 * If all you need is support for text labels, please use the `label`
                                 * attribute instead.
                                 *
                                 * @config labelHTML
                                 * @type HTML
                                 */
                                labelHTML: {
                                    setter: '_setLabelHTML',
                                    getter: '_getLabelHTML',
                                    lazyAdd: false
                                },
                            
                                /**
                                 * The button's enabled/disabled state
                                 *
                                 * @config disabled
                                 * @type Boolean
                                 */
                                disabled: {
                                    value: false,
                                    setter: '_setDisabled',
                                    lazyAdd: false
                                }
                            };
                            
                            /**
                             * Name of this component.
                             *
                             * @property NAME
                             * @type String
                             * @static
                             */
                            ButtonCore.NAME = "button";
                            
                            /**
                             * Array of static constants used to identify the classnames applied to DOM nodes
                             *
                             * @property CLASS_NAMES
                             * @type {Object}
                             * @public
                             * @static
                             */
                            ButtonCore.CLASS_NAMES = {
                                BUTTON  : getClassName('button'),
                                DISABLED: getClassName('button', 'disabled'),
                                SELECTED: getClassName('button', 'selected'),
                                LABEL   : getClassName('button', 'label')
                            };
                            
                            /**
                             * Array of static constants used to for applying ARIA states
                             *
                             * @property ARIA_STATES
                             * @type {Object}
                             * @private
                             * @static
                             */
                            ButtonCore.ARIA_STATES = {
                                PRESSED : 'aria-pressed',
                                CHECKED : 'aria-checked'
                            };
                            
                            /**
                             * Array of static constants used to for applying ARIA roles
                             *
                             * @property ARIA_ROLES
                             * @type {Object}
                             * @private
                             * @static
                             */
                            ButtonCore.ARIA_ROLES = {
                                BUTTON  : 'button',
                                CHECKBOX: 'checkbox',
                                TOGGLE  : 'toggle'
                            };
                            
                            /**
                             * Finds the label node within a button
                             *
                             * @method _getLabelNodeFromParent
                             * @param node {Node} The parent node
                             * @return {Node} The label node
                             * @private
                             * @static
                             */
                            ButtonCore._getLabelNodeFromParent = function (node) {
                                var labelNode = (node.one('.' + ButtonCore.CLASS_NAMES.LABEL) || node);
                            
                                return labelNode;
                            };
                            
                            /**
                             * Gets a text label from a node
                             *
                             * @method _getTextLabelFromNode
                             * @param node {Node} The parent node
                             * @return {String} The text label for a given node
                             * @private
                             * @static
                             */
                            ButtonCore._getTextLabelFromNode = function (node) {
                                var labelNode = ButtonCore._getLabelNodeFromParent(node),
                                    nodeName = labelNode.get('nodeName').toLowerCase(),
                                    label = labelNode.get(nodeName === 'input' ? 'value' : 'text');
                            
                                return label;
                            };
                            
                            /**
                             * A utility method that gets an HTML label from a given node
                             *
                             * @method _getHTMLFromNode
                             * @param node {Node} The parent node
                             * @return {String} The HTML label for a given node
                             * @private
                             * @static
                             */
                            ButtonCore._getHTMLFromNode = function (node) {
                                var labelNode = ButtonCore._getLabelNodeFromParent(node),
                                    label = labelNode.getHTML();
                            
                                return label;
                            };
                            
                            /**
                             * Gets the disabled attribute from a node
                             *
                             * @method _getDisabledFromNode
                             * @param node {Node} The parent node
                             * @return {boolean} The disabled state for a given node
                             * @private
                             * @static
                             */
                            ButtonCore._getDisabledFromNode = function (node) {
                                return node.get('disabled');
                            };
                            
                            // Export ButtonCore
                            Y.ButtonCore = ButtonCore;