Show:
                            /**
                             * The Button Component
                             *
                             * @module aui-button
                             */
                            
                            var CLASS_NAMES = {
                                    BUTTON: A.getClassName('btn'),
                                    BUTTON_DEFAULT: A.getClassName('btn', 'default'),
                                    BUTTON_GROUP: A.getClassName('btn', 'group'),
                                    DISABLED: A.getClassName('disabled'),
                                    LABEL: A.getClassName('label'),
                                    PRIMARY: A.getClassName('btn', 'primary'),
                                    SELECTED: A.getClassName('active'),
                                    TOGGLE: A.getClassName('togglebtn')
                                };
                            
                            /**
                             * A base class for `ButtonExt`.
                             *
                             * @class A.ButtonExt
                             * @param {Object} config Object literal specifying widget configuration
                             *     properties.
                             * @constructor
                             */
                            var ButtonExt = function(config) {
                                if (config && config.domType && this._domTypeValidator(config.domType)) {
                                    this._setEarlyButtonDomType(config.domType);
                                }
                            };
                            
                            /**
                             * Defines the default attribute configuration for the `ButtonExt`.
                             *
                             * @property ATTRS
                             * @type {Object}
                             * @static
                             */
                            ButtonExt.ATTRS = {
                            
                                /**
                                 * CSS class to be automatically added to the `boundingBox`.
                                 *
                                 * @attribute cssClass
                                 * @type {String}
                                 */
                                cssClass: {
                                    validator: A.Lang.isString,
                                    value: ''
                                },
                            
                                /**
                                 * Defines if the button will discard the default button classes.
                                 *
                                 * @attribute discardDefaultButtonCssClasses
                                 * @default false
                                 * @type {Boolean}
                                 */
                                discardDefaultButtonCssClasses: {
                                    validator: A.Lang.isBoolean,
                                    value: false,
                                    writeOnce: true
                                },
                            
                                /**
                                 * Defines the HTML type attribute of element e.g. `<input type="button">`.
                                 *
                                 * @attribute domType
                                 * @type {String}
                                 * @writeOnce
                                 */
                                domType: {
                                    validator: '_domTypeValidator',
                                    writeOnce: true
                                },
                            
                                /**
                                 * Contains a CSS class of the icon to use. A list of icons can be found
                                 * [here](http://liferay.github.io/alloy-bootstrap/base-css.html#icons).
                                 *
                                 * @attribute icon
                                 * @type {String}
                                 */
                                icon: {},
                            
                                /**
                                 * Defines markup template for icon, passed in as a node e.g.
                                 * `Y.Node.create('<span></span>')`.
                                 *
                                 * @attribute iconElement
                                 * @default 'A.Node.create("<span></span>")'
                                 */
                                iconElement: {
                                    valueFn: function() {
                                        return A.Node.create(this.ICON_TEMPLATE);
                                    }
                                },
                            
                                /**
                                 * Sets position of icon.
                                 *
                                 * @attribute iconAlign
                                 * @default 'left'
                                 * @type {String}
                                 */
                                iconAlign: {
                                    validator: A.Lang.isString,
                                    value: 'left'
                                }
                            };
                            
                            /**
                             * Defines how attribute values are to be parsed from markup contained in
                             * `ButtonExt`.
                             *
                             * @property HTML_PARSER
                             * @type {Object}
                             * @static
                             */
                            ButtonExt.HTML_PARSER = {
                                iconElement: 'span'
                            };
                            
                            /**
                             * Updates the HTML markup specified as the `template` argument with the
                             * passed `type`.
                             *
                             * @method getTypedButtonTemplate
                             * @param {String} template
                             * @param {String} type
                             * @return {String} The parsed template containing the DOM `type`, e.g.
                             *     `<button {type} />` generates `<button type="button" />`.
                             * @static
                             */
                            ButtonExt.getTypedButtonTemplate = function(template, type) {
                                return A.Lang.sub(template, {
                                    type: ' type="' + type + '"'
                                });
                            };
                            
                            ButtonExt.prototype = {
                                ICON_TEMPLATE: '<span></span>',
                                TEMPLATE: '<button{type}></button>',
                            
                                /**
                                 * Construction logic executed during `ButtonExt` instantiation. Lifecycle.
                                 *
                                 * @method initializer
                                 * @protected
                                 */
                                initializer: function() {
                                    this.before(this.renderButtonExtUI, this, 'renderUI');
                                    this.after(this.syncButtonExtUI, this, 'syncUI');
                                    this.after({
                                        iconChange: this._afterIconChange,
                                        iconAlignChange: this._afterIconAlignChange
                                    });
                                },
                            
                                /**
                                 * Includes default button classes if necessary.
                                 * Fires after `renderUI` method. 
                                 *
                                 * @method renderButtonExtUI
                                 * @protected
                                 */
                                renderButtonExtUI: function() {
                                    var cssClass = this.get('cssClass');
                            
                                    if (!this.get('discardDefaultButtonCssClasses')) {
                                        cssClass = [cssClass, CLASS_NAMES.BUTTON_DEFAULT, CLASS_NAMES.BUTTON].join(' ');
                                        this.set('cssClass', cssClass);
                                    }
                                },
                            
                                /**
                                 * Updates icon CSS class.
                                 *
                                 * @method syncButtonExtUI
                                 */
                                syncButtonExtUI: function() {
                                    this._uiSetIcon(this.get('icon'));
                                    this._setButtonRole();
                                },
                            
                                /**
                                 * Fires after `iconAlign` attribute change.
                                 *
                                 * @method _afterIconAlignChange
                                 * @param {EventFacade} event
                                 * @protected
                                 */
                                _afterIconAlignChange: function(event) {
                                    this._uiSetIconAlign(event.newVal);
                                },
                            
                                /**
                                 * Fires after `icon` attribute change.
                                 *
                                 * @method _afterIconChange
                                 * @param {EventFacade} event
                                 * @protected
                                 */
                                _afterIconChange: function(event) {
                                    this._uiSetIcon(event.newVal);
                                },
                            
                                /**
                                 * Checks if the domType attribute has a valid value.
                                 *
                                 * @method _domTypeValidator
                                 * @param {String} type
                                 * @protected
                                 */
                                _domTypeValidator: function(type) {
                                    return type.toLowerCase() === 'button' || type.toLowerCase() === 'submit';
                                },
                            
                                /**
                                 * Sets the role attribute on the bounding box to 'button';
                                 *
                                 * @method setButtonRole
                                 * @protected
                                 */
                                _setButtonRole: function() {
                                    this.get('boundingBox').setAttribute('role', 'button');
                                },
                            
                                /**
                                 * Sets button type on bounding box template before constructor is invoked.
                                 * The type is set before widget creates the bounding box node.
                                 *
                                 * @method _setEarlyButtonDomType
                                 * @param {String} type
                                 * @protected
                                 */
                                _setEarlyButtonDomType: function(type) {
                                    this.BOUNDING_TEMPLATE = A.ButtonExt.getTypedButtonTemplate(
                                        ButtonExt.prototype.TEMPLATE, type);
                                },
                            
                                /**
                                 * Adds class name for button icon.
                                 *
                                 * @method _uiSetIcon
                                 * @param {String} val
                                 * @protected
                                 */
                                _uiSetIcon: function(val) {
                                    if (val) {
                                       this.get('iconElement').set('className', val);
                                       this._uiSetIconAlign(this.get('iconAlign'));
                                   }
                                },
                            
                                /**
                                 * Adds alignment for button icon.
                                 *
                                 * @method _uiSetIconAlign
                                 * @param {String} val
                                 * @protected
                                 */
                                _uiSetIconAlign: function(val) {
                                    // Y.Button labelHTML feature assumes any HTML inside the button is the
                                    // label and the icon HTML is contained on its value. To workaround this
                                    // issue on icon alignment fetchs the reference from DOM, if not
                                    // available uses the one created by HTML_PARSER
                                    var iconElement = this.getNode().one(A.ButtonExt.HTML_PARSER.iconElement);
                                    if (!iconElement) {
                                        iconElement = this.get('iconElement');
                                    }
                            
                                    A.Button.syncIconUI(this.get('boundingBox'), iconElement, val);
                                }
                            };
                            
                            A.ButtonExt = ButtonExt;
                            
                            /**
                             * A base class for ButtonCore.
                             *
                             * @class A.ButtonCore
                             * @constructor
                             */
                            
                            /**
                             * Contains CSS class names to use for `ButtonCore`.
                             *
                             * @property CLASS_NAMES
                             * @static
                             */
                            A.ButtonCore.CLASS_NAMES = CLASS_NAMES;
                            
                            var Button = A.Button;
                            
                            Button.NAME = 'aui-button';
                            
                            Button.CSS_PREFIX = 'aui-button';
                            
                            Button.CLASS_NAMES = CLASS_NAMES;
                            
                            /**
                             * A base class for Button.
                             *
                             * @class A.Button
                             * @extends Button
                             * @uses A.ButtonExt, A.WidgetCssClass, A.WidgetToggle
                             * @constructor
                             * @example
                            ```
                            <button id="myButton"></button>
                            <button id="myToggleButton"></button>
                            ```
                             * @example
                            ```
                            YUI().use(
                              'aui-button',
                              function(Y) {
                                new Y.Button(
                                  {
                                    icon: 'icon-print',
                                    iconAlign: 'left',
                                    label: 'Basic',
                                    srcNode: '#myButton'
                                  }
                                ).render();
                            
                                new Y.ToggleButton(
                                  {
                                    label: 'Click to toggle',
                                    srcNode: '#myToggleButton'
                                  }
                                ).render();
                              }
                            );
                            ```
                             */
                            A.Button = A.Base.create(Button.NAME, Button, [ButtonExt, A.WidgetCssClass, A.WidgetToggle], {}, {
                            
                                /**
                                 * Returns an object literal containing widget constructor data specified in
                                 * the node.
                                 *
                                 * @method getWidgetLazyConstructorFromNodeData
                                 * @param {Node} node
                                 * @return {Object} The configuration object for the widget.
                                 */
                                getWidgetLazyConstructorFromNodeData: function(node) {
                                    var config = node.getData('widgetConstructor') || {};
                            
                                    config.boundingBox = node;
                                    config.render = true;
                                    return config;
                                },
                            
                                /**
                                 * Returns a boolean, true if node has widget constructor data.
                                 *
                                 * @method hasWidgetLazyConstructorData
                                 * @param {Node} node
                                 * @return {Boolean} Whether the node has a cached widget constructor data.
                                 */
                                hasWidgetLazyConstructorData: function(node) {
                                    return node.getData('widgetConstructor') !== undefined;
                                },
                            
                                /**
                                 * Updates node's widget constructor data attribute with config.
                                 *
                                 * @method setWidgetLazyConstructorNodeData
                                 * @param {Node} node
                                 * @param {Object} config
                                 */
                                setWidgetLazyConstructorNodeData: function(node, config) {
                                    node.setData('widgetConstructor', config);
                                },
                            
                                /**
                                 * Updates icon alignment in button.
                                 *
                                 * @method syncIconUI
                                 * @param {Node} buttonElement The button element.
                                 * @param {Node} iconElement The icon element to be aligned.
                                 * @param {String} iconAlign The align position, e.g right or left.
                                 */
                                syncIconUI: function(buttonElement, iconElement, iconAlign) {
                                    var insertPos = 0,
                                        textNode = A.config.doc.createTextNode(' ');
                            
                                    if (iconAlign === 'right') {
                                        insertPos = null;
                                    }
                            
                                    buttonElement.insert(textNode, insertPos);
                                    buttonElement.insert(iconElement, insertPos);
                                }
                            });
                            
                            var ToggleButton = A.ToggleButton;
                            
                            ToggleButton.NAME = 'togglebtn';
                            
                            ToggleButton.CSS_PREFIX = CLASS_NAMES.TOGGLE;
                            
                            ToggleButton.CLASS_NAMES = CLASS_NAMES;
                            
                            /**
                             * A base class for ToggleButton.
                             *
                             * @class A.ToggleButton
                             * @uses A.ButtonExt, A.WidgetCssClass
                             * @param {Object} config Object literal specifying widget configuration
                             *     properties.
                             * @constructor
                             */
                            A.ToggleButton = A.Base.create(ToggleButton.NAME, ToggleButton, [ButtonExt, A.WidgetCssClass], {}, {});
                            
                            var ButtonGroup = A.ButtonGroup;
                            
                            ButtonGroup.NAME = 'btngroup';
                            
                            ButtonGroup.CSS_PREFIX = CLASS_NAMES.BUTTON_GROUP;
                            
                            ButtonGroup.CLASS_NAMES = CLASS_NAMES;
                            
                            /**
                             * A base class for ButtonGroup.
                             *
                             * @class A.ButtonGroup
                             * @constructor
                             */
                            A.mix(ButtonGroup.prototype, {
                            
                                // Bootstrap button group depends on buttons to be a direct children,
                                // force one-box widget.
                                CONTENT_TEMPLATE: null,
                            
                                /**
                                 * Constructor for `A.ButtonGroup`. Lifecycle.
                                 *
                                 * @method initializer
                                 * @protected
                                 */
                                initializer: function() {
                                    this.after('selectionChange', this._afterSelectionChange);
                                },
                            
                                /**
                                 * Renders the `ButtonGroup` component instance. Lifecycle.
                                 *
                                 * @method renderUI
                                 * @protected
                                 */
                                renderUI: function() {
                                    var boundingBox = this.get('boundingBox'),
                                        type = this.get('type');
                            
                                    this.getButtons().each(function(button) {
                                        if (!button.button && !A.instanceOf(A.Widget.getByNode(button), A.Button)) {
                                            // TODO: This shouldn't assume button is always default.
                                            // A.Plugin.Button doesn't current allow augmentation, therefore
                                            // it can't add A.ButtonExt extra attributes to it.
                                            button.addClass(A.ButtonCore.CLASS_NAMES.BUTTON_DEFAULT);
                                            button.setAttribute('role', 'option');
                            
                                            if (A.Button.hasWidgetLazyConstructorData(button)) {
                                                new A.Button(A.Button.getWidgetLazyConstructorFromNodeData(button));
                                                A.Button.setWidgetLazyConstructorNodeData(button, null);
                                            }
                                            else {
                                                button.plug(A.Plugin.Button);
                                            }
                                        }
                                    });
                            
                                    boundingBox.setAttrs({
                                        'aria-multiselectable': (type === 'checkbox') ? true : false,
                                        role: 'listbox'
                                    });
                            
                                    this.syncAriaSelected(this.getButtons());
                                },
                            
                                /**
                                 * Returns the `item` or `node` of specified `index`.
                                 *
                                 * @method item
                                 * @param {Number} index
                                 * @return {Button | Node} The item as `Button` or `Node` instance.
                                 */
                                item: function(index) {
                                    var item,
                                        node;
                            
                                    node = this.getButtons().item(index);
                                    item = A.Widget.getByNode(node);
                            
                                    if (A.instanceOf(item, Button)) {
                                        return item;
                                    }
                            
                                    return node;
                                },
                            
                                /**
                                 * Selects items by adding the active class name.
                                 *
                                 * @method select
                                 * @param {Array} items
                                 */
                                select: function(items) {
                                    return this.toggleSelect(items, true);
                                },
                            
                                /**
                                 * Updates the 'aria-selected' attribute on all buttons.
                                 *
                                 * @method syncAriaSelected
                                 * @param {Array} buttons
                                 */
                                syncAriaSelected: function(buttons) {
                                    var selected;
                            
                                    buttons.each(function(button) {
                                        selected = button.hasClass(A.ButtonGroup.CLASS_NAMES.SELECTED);
                            
                                        button.setAttribute('aria-selected', selected);
                                    });
                                },
                            
                                /**
                                 * Toggles selection by adding or removing the active class name.
                                 *
                                 * @method toggleSelect
                                 * @param {Array} items
                                 * @param {Boolean} forceSelection Whether selection should be forced.
                                 */
                                toggleSelect: function(items, forceSelection) {
                                    var buttons = this.getButtons(),
                                        instance = this,
                                        type = this.get('type');
                            
                                    if (A.Lang.isUndefined(items)) {
                                        items = buttons.getDOMNodes();
                                    }
                                    if (!A.Lang.isArray(items)) {
                                        items = A.Array(items);
                                    }
                            
                                    A.Array.each(items, function(item) {
                                        if (A.Lang.isNumber(item)) {
                                            item = buttons.item(item);
                                        }
                                        // Make sure the passed dom nodes are instance of Node
                                        item = A.one(item);
                            
                                        if (type === 'checkbox') {
                                            // If item is already selected...
                                            if (item.hasClass(A.ButtonGroup.CLASS_NAMES.SELECTED)) {
                                                if (forceSelection === true) {
                                                    // Prevent click
                                                    return;
                                                }
                                            }
                                            // If item is not selected yet...
                                            else if (forceSelection === false) {
                                                // Prevent click
                                                return;
                                            }
                                        }
                            
                                        instance._handleClick({
                                            target: item
                                        });
                                    });
                                },
                            
                                /**
                                 * Selects items by adding the active class name.
                                 *
                                 * @method unselect
                                 * @param {Array} items
                                 */
                                unselect: function(items) {
                                    return this.toggleSelect(items, false);
                                },
                            
                                /**
                                 * Fires after 'selectionChange' event.
                                 *
                                 * @method _afterSelectionChange
                                 * @protected
                                 */
                                _afterSelectionChange: function() {
                                    this.syncAriaSelected(this.getButtons());
                                }
                            }, true);