Show:
                            /**
                             * The Scheduler Component
                             *
                             * @module aui-scheduler
                             * @submodule aui-scheduler-view-table
                             */
                            
                            var Lang = A.Lang,
                                isFunction = Lang.isFunction,
                            
                                DateMath = A.DataType.DateMath,
                                WidgetStdMod = A.WidgetStdMod,
                            
                                WEEK_LENGTH = DateMath.WEEK_LENGTH,
                            
                                getNodeListHTMLParser = function(selector, sizeCondition) {
                                    return function(srcNode) {
                                        var nodes = srcNode.all(selector);
                                        return (nodes.size() >= sizeCondition) ? nodes : null;
                                    };
                                },
                            
                                getCN = A.getClassName,
                            
                                CSS_ICON = getCN('icon'),
                                CSS_ICON_ARROWSTOP_LEFT = getCN('icon', 'arrowstop-1-l'),
                                CSS_ICON_ARROWSTOP_RIGHT = getCN('icon', 'arrowstop-1-r'),
                                CSS_SVT_COLGRID = getCN('scheduler-view', 'table', 'colgrid'),
                                CSS_SVT_COLGRID_FIRST = getCN('scheduler-view', 'table', 'colgrid', 'first'),
                                CSS_SVT_COLGRID_TODAY = getCN('scheduler-view', 'table', 'colgrid', 'today'),
                                CSS_SVT_CONTAINER = getCN('scheduler-view', 'table', 'container'),
                                CSS_SVT_EVENTS_OVERLAY_NODE = getCN('scheduler-view', 'table', 'events', 'overlay', 'node'),
                                CSS_SVT_EVENTS_OVERLAY_NODE_BODY = getCN('scheduler-view', 'table', 'events', 'overlay', 'node', 'body'),
                                CSS_SVT_EVENTS_OVERLAY_NODE_CLOSE = getCN('scheduler-view', 'table', 'events', 'overlay', 'node', 'close'),
                                CSS_SVT_HEADER_COL = getCN('scheduler-view', 'table', 'header', 'col'),
                                CSS_SVT_HEADER_DAY = getCN('scheduler-view', 'table', 'header', 'day'),
                                CSS_SVT_HEADER_TABLE = getCN('scheduler-view', 'table', 'header', 'table'),
                                CSS_SVT_MORE = getCN('scheduler-view', 'table', 'more'),
                                CSS_SVT_ROW = getCN('scheduler-view', 'table', 'row'),
                                CSS_SVT_ROW_CONTAINER = getCN('scheduler-view', 'table', 'row', 'container'),
                                CSS_SVT_TABLE_DATA = getCN('scheduler-view', 'table', 'data'),
                                CSS_SVT_TABLE_DATA_COL = getCN('scheduler-view', 'table', 'data', 'col'),
                                CSS_SVT_TABLE_DATA_COL_TITLE = getCN('scheduler-view', 'table', 'data', 'col', 'title'),
                                CSS_SVT_TABLE_DATA_COL_TITLE_DOWN = getCN('scheduler-view', 'table', 'data', 'col', 'title', 'down'),
                                CSS_SVT_TABLE_DATA_COL_TITLE_FIRST = getCN('scheduler-view', 'table', 'data', 'col', 'title', 'first'),
                                CSS_SVT_TABLE_DATA_COL_TITLE_NEXT = getCN('scheduler-view', 'table', 'data', 'col', 'title', 'next'),
                                CSS_SVT_TABLE_DATA_COL_TITLE_TODAY = getCN('scheduler-view', 'table', 'data', 'col', 'title', 'today'),
                                CSS_SVT_TABLE_DATA_EVENT = getCN('scheduler-view', 'table', 'data', 'event'),
                                CSS_SVT_TABLE_DATA_EVENT_LEFT = getCN('scheduler-view', 'table', 'data', 'event', 'left'),
                                CSS_SVT_TABLE_DATA_EVENT_RIGHT = getCN('scheduler-view', 'table', 'data', 'event', 'right'),
                                CSS_SVT_TABLE_DATA_FIRST = getCN('scheduler-view', 'table', 'data', 'first'),
                                CSS_SVT_TABLE_GRID = getCN('scheduler-view', 'table', 'grid'),
                                CSS_SVT_TABLE_GRID_CONTAINER = getCN('scheduler-view', 'table', 'grid', 'container'),
                                CSS_SVT_TABLE_GRID_FIRST = getCN('scheduler-view', 'table', 'grid', 'first'),
                            
                                TPL_SVT_CONTAINER = '<div class="' + CSS_SVT_CONTAINER + '">' +
                                    '<div class="' + CSS_SVT_ROW_CONTAINER + '"></div>' +
                                    '</div>',
                            
                                TPL_SVT_EVENTS_OVERLAY_NODE = '<div class="' + CSS_SVT_EVENTS_OVERLAY_NODE + '">' +
                                    '<div class="' + CSS_SVT_EVENTS_OVERLAY_NODE_BODY + '"></div>' +
                                    '<a href="javascript:;" class="' + CSS_SVT_EVENTS_OVERLAY_NODE_CLOSE + '">{label}</a>' +
                                    '</div>',
                            
                                TPL_SVT_GRID_COLUMN = '<td class="' + CSS_SVT_COLGRID + '">&nbsp;</td>',
                            
                                TPL_SVT_HEADER_DAY = '<th class="' + CSS_SVT_HEADER_DAY + '"><div>&nbsp;</div></th>',
                            
                                TPL_SVT_HEADER_TABLE = '<table cellspacing="0" cellpadding="0" class="' + CSS_SVT_HEADER_TABLE + '">' +
                                    '<tbody>' +
                                    '<tr class="' + CSS_SVT_HEADER_COL + '"></tr>' +
                                    '</tbody>' +
                                    '</table>',
                            
                                TPL_SVT_MORE = '<a href="javascript:;" class="' + CSS_SVT_MORE + '">{showMoreLabel}</a>',
                            
                                TPL_SVT_ROW = '<div class="' + CSS_SVT_ROW + '"></div>',
                            
                                TPL_SVT_TABLE_DATA = '<table cellspacing="0" cellpadding="0" class="' + CSS_SVT_TABLE_DATA + '">' +
                                    '<tbody></tbody>' +
                                    '</table>',
                            
                                TPL_SVT_TABLE_GRID = '<div class="' + CSS_SVT_TABLE_GRID_CONTAINER + '">' +
                                    '<table cellspacing="0" cellpadding="0" class="' + CSS_SVT_TABLE_GRID + '">' +
                                    '<tbody>' +
                                    '<tr></tr>' +
                                    '</tbody>' +
                                    '</table></div>',
                            
                                TPL_SVT_EV_ICON_LEFT = '<span class="' + [CSS_ICON, CSS_ICON_ARROWSTOP_LEFT].join(' ') + '"></span>',
                                TPL_SVT_EV_ICON_RIGHT = '<span class="' + [CSS_ICON, CSS_ICON_ARROWSTOP_RIGHT].join(' ') + '"></span>',
                            
                                TPL_SVT_TABLE_DATA_COL = '<td class="' + CSS_SVT_TABLE_DATA_COL + '"><div></div></td>',
                                TPL_SVT_TABLE_DATA_ROW = '<tr></tr>';
                            
                            /**
                             * A base class for `SchedulerTableView`.
                             *
                             * @class A.SchedulerTableView
                             * @extends A.SchedulerView
                             * @param {Object} config Object literal specifying widget configuration
                             *     properties.
                             * @constructor
                             */
                            var SchedulerTableView = A.Component.create({
                            
                                /**
                                 * Static property provides a string to identify the class.
                                 *
                                 * @property NAME
                                 * @type {String}
                                 * @static
                                 */
                                NAME: 'scheduler-view-table',
                            
                                /**
                                 * Static property used to define the default attribute
                                 * configuration for the `SchedulerTableView`.
                                 *
                                 * @property ATTRS
                                 * @type {Object}
                                 * @static
                                 */
                                ATTRS: {
                            
                                    /**
                                     * Determines the content of Scheduler table view's body section.
                                     *
                                     * @attribute bodyContent
                                     * @default ''
                                     * @type {String}
                                     */
                                    bodyContent: {
                                        value: ''
                                    },
                            
                                    /**
                                     * Contains the number of days to display per interval in the
                                     * `SchedulerTableView`.
                                     *
                                     * @attribute displayDaysInterval
                                     * @default 42
                                     * @type {Number}
                                     */
                                    displayDaysInterval: {
                                        value: 42
                                    },
                            
                                    /**
                                     * Contains the number of rows to display in the `SchedulerTableView`.
                                     *
                                     * @attribute displayRows
                                     * @default 3
                                     * @type {Number}
                                     */
                                    displayRows: {
                                        value: 3
                                    },
                            
                                    /**
                                     * The element or locator to constrain the events overlay.
                                     *
                                     * When a cell has more events than can be shown, it offers an option
                                     * to open an overlay to see all of them by clicking in a "See x more"
                                     * link. This overlay should be constrained by another element, lest
                                     * it could be cropped or would resize the entire document.
                                     *
                                     * The default value is `true`, in which case the overlay is constrained
                                     * to the viewport.
                                     *
                                     * @attribute eventsOverlayConstrain
                                     * @default null
                                     * @type {Boolean | Node | String}
                                     * @writeOnce
                                     */
                                    eventsOverlayConstrain: {
                                        value: true,
                                        writeOnce: true
                                    },
                            
                                    /**
                                     * Indicates whether the height of the `SchedulerTableView` is fixed.
                                     *
                                     * @attribute fixedHeight
                                     * @default true
                                     * @type {Boolean}
                                     */
                                    fixedHeight: {
                                        value: true
                                    },
                            
                                    /**
                                     * Determines the name for this `SchedulerTableView`.
                                     *
                                     * @attribute name
                                     * @default 'table'
                                     * @type {String}
                                     */
                                    name: {
                                        value: 'table'
                                    },
                            
                                    /**
                                     * Contains the function that formats the header date.
                                     *
                                     * @attribute headerDateFormatter
                                     * @type {Function}
                                     */
                                    headerDateFormatter: {
                                        value: function(date) {
                                            var instance = this;
                                            var scheduler = instance.get('scheduler');
                            
                                            return A.DataType.Date.format(
                                                date, {
                                                    format: '%a',
                                                    locale: scheduler.get('locale')
                                                }
                                            );
                                        },
                                        validator: isFunction
                                    },
                            
                                    /**
                                     * Contains the function that formats the navigation date.
                                     *
                                     * @attribute navigationDateFormatter
                                     * @type {Function}
                                     */
                                    navigationDateFormatter: {
                                        value: function(date) {
                                            var instance = this;
                                            var scheduler = instance.get('scheduler');
                            
                                            return A.DataType.Date.format(
                                                date, {
                                                    format: '%b %Y',
                                                    locale: scheduler.get('locale')
                                                }
                                            );
                                        },
                                        validator: isFunction
                                    },
                            
                                    /**
                                     * Indicates whether the `SchedulerTableView` is scrollable.
                                     *
                                     * @attribute scrollable
                                     * @default false
                                     * @type {Boolean}
                                     */
                                    scrollable: {
                                        value: false
                                    },
                            
                                    /**
                                     * Contains the collection of strings used to label elements of the UI.
                                     *
                                     * @attribute strings
                                     * @type {Object}
                                     */
                                    strings: {
                                        value: {
                                            close: 'Close',
                                            showMore: 'Show {0} more'
                                        }
                                    },
                            
                                    /**
                                     * Contains the function that returns the `headerTable` node.
                                     *
                                     * @attribute headerTableNode
                                     * @type {Node}
                                     */
                                    headerTableNode: {
                                        valueFn: function() {
                                            return A.Node.create(TPL_SVT_HEADER_TABLE);
                                        }
                                    },
                            
                                    /**
                                     * Contains the function that returns the `colHeaderDays` node.
                                     *
                                     * @attribute colHeaderDaysNode
                                     * @type {Node}
                                     */
                                    colHeaderDaysNode: {
                                        valueFn: '_valueColHeaderDaysNode'
                                    },
                            
                                    /**
                                     * Contains the function that returns the `rowsContainer` node.
                                     *
                                     * @attribute rowsContainerNode
                                     * @type {Node}
                                     */
                                    rowsContainerNode: {
                                        valueFn: function() {
                                            return A.Node.create(TPL_SVT_CONTAINER);
                                        }
                                    },
                            
                                    /**
                                     * Contains the function that returns the `tableGrid` node.
                                     *
                                     * @attribute tableGridNode
                                     * @type {Node}
                                     */
                                    tableGridNode: {
                                        valueFn: '_valueTableGridNode'
                                    }
                                },
                            
                                /**
                                 * Contains an object hash, defining how attribute values are to be parsed
                                 * from markup contained in the widget's bounding box.
                                 *
                                 * @property HTML_PARSER
                                 * @type {Object}
                                 * @static
                                 */
                                HTML_PARSER: {
                                    colHeaderDaysNode: getNodeListHTMLParser('.' + CSS_SVT_HEADER_DAY, 7),
                                    headerTableNode: '.' + CSS_SVT_HEADER_TABLE,
                                    rowsContainerNode: '.' + CSS_SVT_CONTAINER,
                                    tableGridNode: getNodeListHTMLParser('.' + CSS_SVT_TABLE_GRID, 7)
                                },
                            
                                /**
                                 * Static property used to define which component it extends.
                                 *
                                 * @property EXTENDS
                                 * @type {Object}
                                 * @static
                                 */
                                EXTENDS: A.SchedulerView,
                            
                                prototype: {
                                    evtDateStack: null,
                                    evtRenderedStack: null,
                                    rowDataTableStack: null,
                            
                                    /**
                                     * Construction logic executed during `SchedulerTableView` instantiation.
                                     * Lifecycle.
                                     *
                                     * @method initializer
                                     * @protected
                                     */
                                    initializer: function() {
                                        var instance = this;
                            
                                        instance.evtDateStack = {};
                                        instance.evtRenderedStack = {};
                                        instance.rowDataTableStack = {};
                            
                                        instance.colHeaderDaysNode = instance.get('colHeaderDaysNode');
                                        instance.headerTableNode = instance.get('headerTableNode');
                                        instance.rowsContainerNode = instance.get('rowsContainerNode');
                                        instance.tableGridNode = instance.get('tableGridNode');
                                        instance.columnDayHeader = instance.headerTableNode.one('.' + CSS_SVT_HEADER_COL);
                                        instance.columnTableGrid = A.NodeList.create();
                                        instance.tableRowContainer = instance.rowsContainerNode.one('.' + CSS_SVT_ROW_CONTAINER);
                                        instance.tableRows = A.NodeList.create();
                                    },
                            
                                    /**
                                     * Binds the events on the `SchedulerTableView` UI. Lifecycle.
                                     *
                                     * @method bindUI
                                     * @protected
                                     */
                                    bindUI: function() {
                                        var instance = this;
                            
                                        instance.rowsContainerNode.delegate('click', A.bind(instance._onClickMore, instance), '.' +
                                            CSS_SVT_MORE);
                                    },
                            
                                    /**
                                     * Renders the `SchedulerTableView` component instance. Lifecycle.
                                     *
                                     * @method renderUI
                                     * @protected
                                     */
                                    renderUI: function() {
                                        var instance = this,
                                            displayRowsCount = instance._getDisplayRowsCount(),
                                            rowIndex;
                            
                                        for (rowIndex = 0; rowIndex < displayRowsCount; rowIndex++) {
                                            instance.tableRows.push(
                                                instance.buildGridRowNode(rowIndex)
                                            );
                                        }
                            
                                        instance._renderEventsOverlay();
                            
                                        instance.colHeaderDaysNode.appendTo(instance.columnDayHeader);
                                        instance.tableRows.appendTo(instance.tableRowContainer);
                                    },
                            
                                    /**
                                     * Builds a row of events.
                                     *
                                     * @method buildEventsRow
                                     * @param {Date} rowStartDate
                                     * @param {Date} rowEndDate
                                     * @param {Number} rowDisplayIndex
                                     * @return {Node}
                                     */
                                    buildEventsRow: function(rowStartDate, rowEndDate, rowDisplayIndex) {
                                        var instance = this;
                                        var displayRows = instance.get('displayRows');
                            
                                        var rowRenderedColumns = 0;
                                        var rowNode = A.Node.create(TPL_SVT_TABLE_DATA_ROW);
                            
                                        var renderedEvents = false;
                            
                                        instance.loopDates(rowStartDate, rowEndDate, function(celDate, index) {
                                            var key = instance._getEvtRenderedStackKey(celDate);
                            
                                            var evtRenderedStack = instance.evtRenderedStack[key];
                            
                                            if (!evtRenderedStack) {
                                                instance.evtRenderedStack[key] = [];
                            
                                                evtRenderedStack = instance.evtRenderedStack[key];
                                            }
                            
                                            if (rowRenderedColumns > index) {
                                                evtRenderedStack.push(null);
                            
                                                return;
                                            }
                            
                                            var events = instance.evtDateStack[key];
                                            if (!events) {
                                                events = [];
                                            }
                            
                                            events = A.Array.filter(events, function(currEvent) {
                                                return currEvent.get('visible');
                                            });
                            
                                            var evt = instance._getRenderableEvent(events, rowStartDate, rowEndDate, celDate);
                            
                                            var evtColNode = A.Node.create(TPL_SVT_TABLE_DATA_COL);
                                            var evtNodeContainer = evtColNode.one('div');
                            
                                            if ((evtRenderedStack.length < events.length) && displayRows && (rowDisplayIndex === (displayRows - 1))) {
                                                var strings = instance.get('strings');
                            
                                                var showMoreLabel = Lang.sub(
                                                    strings.showMore,
                                                    [
                                                        (events.length - evtRenderedStack.length)
                                                    ]
                                                );
                            
                                                var showMoreEventsLink = A.Node.create(
                                                    Lang.sub(
                                                        TPL_SVT_MORE, {
                                                            showMoreLabel: showMoreLabel
                                                        }
                                                    )
                                                );
                            
                                                showMoreEventsLink.setData('events', events);
                            
                                                evtNodeContainer.append(showMoreEventsLink);
                                                renderedEvents = true;
                                            }
                                            else if (evt) {
                                                var evtSplitInfo = instance._getEvtSplitInfo(evt, celDate, rowStartDate, rowEndDate);
                            
                                                evtColNode.attr('colspan', evtSplitInfo.colspan);
                            
                                                rowRenderedColumns += (evtSplitInfo.colspan - 1);
                            
                                                instance._syncEventNodeContainerUI(evt, evtNodeContainer, evtSplitInfo);
                                                instance._syncEventNodeUI(evt, evtNodeContainer, celDate);
                            
                                                evtRenderedStack.push(evt);
                                                renderedEvents = true;
                                            }
                            
                                            rowRenderedColumns++;
                            
                                            rowNode.append(evtColNode);
                                        });
                            
                                        return renderedEvents ? rowNode : null;
                                    },
                            
                                    /**
                                     * Builds a table of events.
                                     *
                                     * @method buildEventsTable
                                     * @param {Date} rowStartDate
                                     * @param {Date} rowEndDate
                                     * @return {Node}
                                     */
                                    buildEventsTable: function(rowStartDate, rowEndDate) {
                                        var instance = this,
                                            displayRows = instance.get('displayRows'),
                                            end = false,
                                            intervalStartDate = DateMath.clearTime(instance._findCurrentIntervalStart()),
                                            cacheKey = String(intervalStartDate.getTime()).concat(rowStartDate.getTime()).concat(rowEndDate.getTime()),
                                            rowDataTableNode = instance.rowDataTableStack[cacheKey],
                                            rowDisplayIndex = 0;
                            
                                        if (!rowDataTableNode) {
                                            rowDataTableNode = A.Node.create(TPL_SVT_TABLE_DATA);
                            
                                            var tableBody = rowDataTableNode.one('tbody');
                                            var titleRowNode = instance.buildEventsTitleRow(rowDataTableNode, rowStartDate, rowEndDate);
                            
                                            tableBody.append(titleRowNode);
                            
                                            while (!end) {
                                                var rowNode = instance.buildEventsRow(rowStartDate, rowEndDate, rowDisplayIndex);
                            
                                                if (rowNode) {
                                                    tableBody.append(rowNode);
                            
                                                    rowDisplayIndex++;
                                                    if (displayRows && rowDisplayIndex >= displayRows) {
                                                        end = true;
                                                    }
                                                }
                                                else {
                                                    end = true;
                                                }
                                            }
                            
                                            instance.rowDataTableStack[cacheKey] = rowDataTableNode;
                                        }
                            
                                        return rowDataTableNode;
                                    },
                            
                                    /**
                                     * Builds a row with the title and today's date.
                                     *
                                     * @method buildEventsTitleRow
                                     * @param {Node} tableNode
                                     * @param {Date} rowStartDate
                                     * @param {Date} rowEndDate
                                     * @return {Node} titleRowNode The title row `Node`.
                                     */
                                    buildEventsTitleRow: function(tableNode, rowStartDate, rowEndDate) {
                                        var instance = this;
                            
                                        var todayDate = instance.get('scheduler').get('todayDate');
                            
                                        var titleRowNode = A.Node.create(TPL_SVT_TABLE_DATA_ROW);
                            
                                        instance.loopDates(rowStartDate, rowEndDate, function(celDate, index) {
                                            var colTitleNode = A.Node.create(TPL_SVT_TABLE_DATA_COL);
                            
                                            colTitleNode
                                                .addClass(CSS_SVT_TABLE_DATA_COL_TITLE)
                                                .toggleClass(
                                                    CSS_SVT_TABLE_DATA_COL_TITLE_FIRST, (index === 0))
                                                .toggleClass(
                                                    CSS_SVT_TABLE_DATA_COL_TITLE_TODAY, !DateMath.isDayOverlap(celDate, todayDate))
                                                .toggleClass(
                                                    CSS_SVT_TABLE_DATA_COL_TITLE_NEXT, !DateMath.isDayOverlap(
                                                        DateMath.subtract(celDate, DateMath.DAY, 1), todayDate))
                                                .toggleClass(
                                                    CSS_SVT_TABLE_DATA_COL_TITLE_DOWN, !DateMath.isDayOverlap(
                                                        DateMath.subtract(celDate, DateMath.WEEK, 1), todayDate));
                            
                                            titleRowNode.append(
                                                colTitleNode.setContent(celDate.getDate())
                                            );
                                        });
                            
                                        return titleRowNode;
                                    },
                            
                                    /**
                                     * Builds a new row `Node` and appends a table grid `Node`. Returns the
                                     * row `Node`.
                                     *
                                     * @method buildGridRowNode
                                     * @param {Number} rowIndex
                                     * @return {Node} A row `Node`.
                                     */
                                    buildGridRowNode: function(rowIndex) {
                                        var instance = this;
                            
                                        var tableGridNode = instance._getTableGridNode(rowIndex);
                            
                                        var rowNode = A.Node.create(TPL_SVT_ROW);
                            
                                        rowNode.append(
                                            tableGridNode.toggleClass(CSS_SVT_TABLE_GRID_FIRST, (rowIndex === 0))
                                        );
                            
                                        return rowNode;
                                    },
                            
                                    /**
                                     * Removes all data from `evtDateStack`, `evtRenderedStack` and
                                     * `rowDateTableStack`.
                                     *
                                     * @method flushViewCache
                                     */
                                    flushViewCache: function() {
                                        var instance = this;
                            
                                        instance.evtDateStack = {};
                                        instance.evtRenderedStack = {};
                                        instance.rowDataTableStack = {};
                                    },
                            
                                    /**
                                     * Returns the date interval in which this view shows events for.
                                     *
                                     * @method getDateInterval
                                     * @return {Object} Object with 2 keys: startDate and endDate. Undefined
                                     *   keys are interpreted as unlimited sides of the interval.
                                     */
                                    getDateInterval: function() {
                                        var daysAmount = this.getWeekDaysCount() * this._getDisplayRowsCount() - 1,
                                            startDate = this._findCurrentIntervalStart();
                            
                                        return {
                                            endDate: DateMath.toLastHour(DateMath.add(startDate, DateMath.DAY, daysAmount)),
                                            startDate: DateMath.toMidnight(startDate)
                                        };
                                    },
                            
                                    /**
                                     * Returns the list of all events that intersect with a given date.
                                     *
                                     * @method getIntersectEvents
                                     * @param {Date} date
                                     * @return {Array} The list of all events that intersect with a given
                                     * date.
                                     */
                                    getIntersectEvents: function(date) {
                                        var instance = this;
                                        var scheduler = instance.get('scheduler');
                            
                                        var key = instance._getEvtRenderedStackKey(date);
                            
                                        if (!instance.evtDateStack[key]) {
                                            var events = scheduler.getIntersectEvents(date);
                            
                                            instance.evtDateStack[key] = A.Array.filter(
                                                events, instance.get('filterFn')
                                            );
                                        }
                            
                                        return instance.evtDateStack[key];
                                    },
                            
                                    /**
                                     * Returns the value of the date that follows the `SchedulerTableView`'s
                                     current date.
                                     *
                                     * @method getNextDate
                                     * @return {Date} The value of the date that follows the
                                     * `SchedulerTableView`'scurrent date.
                                     */
                                    getNextDate: function() {
                                        var instance = this;
                                        var scheduler = instance.get('scheduler');
                                        var viewDate = scheduler.get('viewDate');
                                        var displayDaysInterval = instance.get('displayDaysInterval');
                            
                                        return DateMath.toLastHour(DateMath.add(viewDate, DateMath.DAY, displayDaysInterval));
                                    },
                            
                                    /**
                                     * Returns the value of the date that preceeds the
                                     * `SchedulerTableView`'s current date.
                                     *
                                     * @method getPrevDate
                                     * @return {Date} The value of the date that preceeds the
                                     * `SchedulerTableView`'s current date.
                                     */
                                    getPrevDate: function() {
                                        var instance = this;
                                        var scheduler = instance.get('scheduler');
                                        var viewDate = scheduler.get('viewDate');
                                        var displayDaysInterval = instance.get('displayDaysInterval');
                            
                                        return DateMath.toMidnight(DateMath.subtract(viewDate, DateMath.DAY, displayDaysInterval));
                                    },
                            
                                    /**
                                     * Get the number of days that should be shown in the week.
                                     *
                                     * @method getWeekDaysCount
                                     * @return {Number}
                                     */
                                    getWeekDaysCount: function() {
                                        var displayDaysInterval = this.get('displayDaysInterval');
                            
                                        return Math.min(displayDaysInterval, WEEK_LENGTH);
                                    },
                            
                                    /**
                                     * Hides this `SchedulerViewTable` event's `overlay` component.
                                     *
                                     * @method hideEventsOverlay
                                     */
                                    hideEventsOverlay: function() {
                                        var instance = this;
                            
                                        instance.eventsOverlay.set('visible', false);
                                    },
                            
                                    /**
                                     * Applies a given function to each date between `startDate` and
                                     * `endDate`.
                                     *
                                     * @method loopDates
                                     * @param {Date} startDate
                                     * @param {Date} endDate
                                     * @param {Function} fn
                                     * @param {String} incrementBy  The field constant to be used for
                                     * performing addition.
                                     * @param {Number} factor   The ratio used to calculate the number of
                                     * units (measured in the field constant) to add to the date.
                                     */
                                    loopDates: function(startDate, endDate, fn, incrementBy, factor) {
                                        var instance = this;
                                        var countDays = DateMath.countDays(startDate, endDate) + 1;
                                        var curDate = DateMath.clone(startDate);
                                        var index;
                            
                                        for (index = 0; index < countDays; index++) {
                                            fn.apply(instance, [curDate, index]);
                            
                                            curDate = DateMath.add(curDate, (incrementBy || DateMath.DAY), (factor || 1));
                                        }
                                    },
                            
                                    /**
                                     * Plots all events in the current view.
                                     *
                                     * @method plotEvents
                                     */
                                    plotEvents: function() {
                                        var instance = this;
                                        var intervalStartDate = instance._findCurrentIntervalStart();
                                        var startDateRef = DateMath.safeClearTime(intervalStartDate);
                            
                                        instance.flushViewCache();
                            
                                        instance.hideEventsOverlay();
                            
                                        instance.bodyNode.all('.' + CSS_SVT_TABLE_DATA).remove();
                            
                                        var weekDaysCount = this.getWeekDaysCount();
                            
                                        var finalDate = DateMath.add(startDateRef, DateMath.DAY, (weekDaysCount * this.tableRows.size()) - 1);
                                        instance._findIntersections(startDateRef, finalDate);
                            
                                        instance.tableRows.each(function(rowNode, index) {
                                            var rowStartDate = DateMath.add(startDateRef, DateMath.DAY, weekDaysCount * index);
                                            var rowEndDate = DateMath.add(rowStartDate, DateMath.DAY, weekDaysCount - 1);
                            
                                            var tableNode = instance.buildEventsTable(rowStartDate, rowEndDate);
                            
                                            if (index === 0) {
                                                tableNode.addClass(CSS_SVT_TABLE_DATA_FIRST);
                                            }
                            
                                            rowNode.append(tableNode);
                                        });
                                    },
                            
                                    /**
                                     * Updates the `SchedulerTableView`'s `colHeaderDaysNode` to reflect
                                     * any changes made to the instance attributes.
                                     *
                                     * @method syncDaysHeaderUI
                                     */
                                    syncDaysHeaderUI: function() {
                                        var instance = this;
                                        var scheduler = instance.get('scheduler');
                                        var viewDate = scheduler.get('viewDate');
                                        var formatter = instance.get('headerDateFormatter');
                                        var firstDayOfWeekDt = instance._findFirstDayOfWeek(viewDate);
                            
                                        instance.colHeaderDaysNode.all('div').each(
                                            function(columnNode, i) {
                                                var columnDate = DateMath.add(firstDayOfWeekDt, DateMath.DAY, i);
                            
                                                columnNode.html(formatter.call(instance, columnDate));
                                            }
                                        );
                                    },
                            
                                    /**
                                     * Updates the `SchedulerTableView`'s column grid by moving styling to
                                     * the current day cell `Node`.
                                     *
                                     * @method syncGridUI
                                     */
                                    syncGridUI: function() {
                                        var instance = this;
                                        var scheduler = instance.get('scheduler');
                                        var todayDate = scheduler.get('todayDate');
                            
                                        instance.columnTableGrid.removeClass(CSS_SVT_COLGRID_TODAY);
                            
                                        var intervalStartDate = instance._findCurrentIntervalStart();
                                        var intervalEndDate = instance._findCurrentIntervalEnd();
                            
                                        if (DateMath.between(todayDate, intervalStartDate, intervalEndDate)) {
                                            var firstDayOfWeek = scheduler.get('firstDayOfWeek');
                                            var firstWeekDay = instance._findFirstDayOfWeek(todayDate);
                            
                                            var rowIndex = DateMath.getWeekNumber(todayDate, firstDayOfWeek) - DateMath.getWeekNumber(
                                                intervalStartDate, firstDayOfWeek);
                                            var colIndex = (todayDate.getDate() - firstWeekDay.getDate());
                                            var celIndex = instance._getCellIndex([colIndex, rowIndex]);
                            
                                            var todayCel = instance.columnTableGrid.item(celIndex);
                            
                                            if (todayCel) {
                                                todayCel.addClass(CSS_SVT_COLGRID_TODAY);
                                            }
                                        }
                                    },
                            
                                    /**
                                     * Sync SchedulerView content.
                                     *
                                     * @method syncStdContent
                                     */
                                    syncStdContent: function() {
                                        var instance = this;
                            
                                        instance.setStdModContent(
                                            WidgetStdMod.BODY, instance.rowsContainerNode.getDOM());
                            
                                        instance.setStdModContent(
                                            WidgetStdMod.HEADER, instance.headerTableNode.getDOM());
                                    },
                            
                                    /**
                                     * Adds the given event to the stack for all dates between the given
                                     * range.
                                     *
                                     * @method _addEventToAllDates
                                     * @param {A.SchedulerEvent} event
                                     * @param {Date} firstDate
                                     * @param {Date} lastDate
                                     * @protected
                                     */
                                    _addEventToAllDates: function(event, firstDate, lastDate) {
                                        var instance = this,
                                            currentDate = firstDate,
                                            eventEndDate = event.getClearEndDate();
                            
                                        if (DateMath.after(lastDate, eventEndDate)) {
                                            lastDate = eventEndDate;
                                        }
                            
                                        while (!DateMath.after(currentDate, lastDate)) {
                                            this._addToEvtDateStack(
                                                instance._getEvtRenderedStackKey(currentDate),
                                                event
                                            );
                            
                                            currentDate = DateMath.add(currentDate, DateMath.DAY, 1);
                                        }
                                    },
                            
                                    /**
                                     * Adds the given event to the stack for the given date key.
                                     *
                                     * @method _addToEvtDateStack
                                     * @param {String} key String representation of a date
                                     * @param {A.SchedulerEvent} event
                                     * @protected
                                     */
                                    _addToEvtDateStack: function(key, event) {
                                        if (!this.evtDateStack[key]) {
                                            this.evtDateStack[key] = [];
                                        }
                                        this.evtDateStack[key].push(event);
                                    },
                            
                                    /**
                                     * Returns this `SchedulerTableView`'s date ending interval.
                                     *
                                     * @method _findCurrentIntervalEnd
                                     * @protected
                                     * @return {Date} This `SchedulerTableView`'s date ending interval.
                                     */
                                    _findCurrentIntervalEnd: function() {
                                        var instance = this;
                                        var scheduler = instance.get('scheduler');
                                        var viewDate = scheduler.get('viewDate');
                                        var displayDaysInterval = instance.get('displayDaysInterval');
                            
                                        return DateMath.add(viewDate, DateMath.DAY, displayDaysInterval);
                                    },
                            
                                    /**
                                     * Returns this `SchedulerTableView`'s date starting interval.
                                     *
                                     * @method _findCurrentIntervalStart
                                     * @protected
                                     * @return {Date} This `SchedulerTableView`'s date starting interval.
                                     */
                                    _findCurrentIntervalStart: function() {
                                        var instance = this;
                                        var scheduler = instance.get('scheduler');
                            
                                        return scheduler.get('viewDate');
                                    },
                            
                                    /**
                                     * Returns the first day of the week.
                                     *
                                     * @method _findFirstDayOfWeek
                                     * @param {Date} date
                                     * @protected
                                     * @return {Date} The first day of the week.
                                     */
                                    _findFirstDayOfWeek: function(date) {
                                        var instance = this;
                                        var scheduler = instance.get('scheduler');
                                        var firstDayOfWeek = scheduler.get('firstDayOfWeek');
                            
                                        return DateMath.getFirstDayOfWeek(date, firstDayOfWeek);
                                    },
                            
                                    /**
                                     * Finds the events that intersect each of the given dates, but without
                                     * duplicating the event on different days. Events will show up on the
                                     * day that first intersected with it.
                                     *
                                     * @method _findIntersections
                                     * @param {Date} startDate
                                     * @param {Date} endDate
                                     * @protected
                                     */
                                    _findIntersections: function(startDate, endDate) {
                                        var currentDate = startDate,
                                            eventEndDate,
                                            events = this.get('scheduler').getEvents(null, true),
                                            eventStartDate,
                                            filterFn = this.get('filterFn'),
                                            i = 0;
                            
                                        // Sort events by start date and time (they are sorted in a different way
                                        // by default).
                                        events.sort(function(evt1, evt2) {
                                            return evt1.isAfter(evt2) ? 1 : -1;
                                        });
                            
                                        while (i < events.length) {
                                            eventStartDate = events[i].getClearStartDate();
                                            eventEndDate = events[i].getClearEndDate();
                            
                                            if (DateMath.after(currentDate, eventEndDate)) {
                                                // Ignore events that end before the current date.
                                                i++;
                                            }
                                            else if (DateMath.before(currentDate, eventStartDate)) {
                                                // This is the first event that starts after the current date.
                                                // Let's jump to the next date then.
                                                currentDate = DateMath.add(currentDate, DateMath.DAY, 1);
                                                if (DateMath.after(currentDate, endDate)) {
                                                    // The current date is past the last date we want to find
                                                    // intersections for. Exit the loop.
                                                    break;
                                                }
                                            }
                                            else {
                                                if (!filterFn || filterFn(events[i])) {
                                                    this._addEventToAllDates(events[i], currentDate, endDate);
                                                }
                            
                                                i++;
                                            }
                                        }
                                    },
                            
                                    /**
                                     * Returns the cell index at a given `position`.
                                     *
                                     * @method _getCellIndex
                                     * @param {Array} position
                                     * @protected
                                     * @return {Number} The cell index at a given `position`.
                                     */
                                    _getCellIndex: function(position) {
                                        return position[1] * WEEK_LENGTH + position[0];
                                    },
                            
                                    /**
                                     * Returns the display rows count.
                                     *
                                     * @method _getDisplayRowsCount
                                     * @protected
                                     * @return {Number} The display rows count.
                                     */
                                    _getDisplayRowsCount: function() {
                                        var instance = this;
                                        var displayDaysInterval = instance.get('displayDaysInterval');
                            
                                        return Math.ceil(displayDaysInterval / WEEK_LENGTH);
                                    },
                            
                                    /**
                                     * Returns the display row days count.
                                     *
                                     * @method _getDisplayRowDaysCount
                                     * @protected
                                     * @return {Number} The display row days count.
                                     */
                                    _getDisplayRowDaysCount: function() {
                                        var instance = this;
                                        var displayDaysInterval = instance.get('displayDaysInterval');
                            
                                        return Math.min(displayDaysInterval, WEEK_LENGTH);
                                    },
                            
                                    /**
                                     * Returns the label that belongs to a given `A.SchedulerEvent`.
                                     *
                                     * @method _getEvtLabel
                                     * @param {A.SchedulerEvent} evt A `Scheduler` event.
                                     * @protected
                                     * @return {String} The label that belongs to a given `A.SchedulerEvent`.
                                     */
                                    _getEvtLabel: function(evt) {
                                        var endDate = evt.get('endDate');
                                        var startDate = evt.get('startDate');
                            
                                        return [startDate.getHours(), '-', endDate.getHours(), ' ', evt.get('content')].join('');
                                    },
                            
                                    /**
                                     * Returns a unique string representation for a date (disregarding time).
                                     *
                                     * @method _getEvtRenderedStackKey
                                     * @param {Date} date A date
                                     * @protected
                                     * @return {String} one string that uniquely represents the date.
                                     */
                                    _getEvtRenderedStackKey: function(date) {
                                        var day = Lang.String.padNumber(date.getDate(), 2),
                                            month = Lang.String.padNumber(date.getMonth(), 2);
                            
                                        return [date.getFullYear(), month, day].join('');
                                    },
                            
                                    /**
                                     * Returns nn object containing the `colspan`, `left` and
                                     * `right` values that determine a `SchedulerEvent`'s split information.
                                     *
                                     * @method _getEvtSplitInfo
                                     * @param {A.SchedulerEvent} evt A `Scheduler` event.
                                     * @param celDate
                                     * @param {Date} rowStartDate
                                     * @param {Date} rowEndDate
                                     * @return {Object} info An object containing the `colspan`, `left` and
                                     * `right` values that determine a `SchedulerEvent`'s split information.
                                     * @protected
                                     */
                                    _getEvtSplitInfo: function(evt, celDate, rowStartDate, rowEndDate) {
                                        var startDate = evt.getClearStartDate();
                                        var endDate = evt.getClearEndDate();
                            
                                        var maxColspan = DateMath.countDays(rowEndDate, celDate);
                            
                                        var info = {
                                            colspan: Math.min(DateMath.countDays(endDate, celDate), maxColspan) + 1,
                                            left: DateMath.before(startDate, rowStartDate),
                                            right: DateMath.after(endDate, rowEndDate)
                                        };
                            
                                        return info;
                                    },
                            
                                    /**
                                     * Returns either a `SchedulerEvent` that is not yet rendered and has a
                                     * `startDate` that does not overlap with with a given `celDate` or is
                                     * a continuation of an existing event.
                                     *
                                     * @method _getRenderableEvent
                                     * @param {EventFacade} event
                                     * @param {Date} rowStartDate
                                     * @param {Date} rowEndDate
                                     * @param {Date} celDate
                                     * @return {A.SchedulerEvent|null} Either a `SchedulerEvent` that is not
                                     *     yet rendered and has a`startDate` that does not overlap with with
                                     *     a given `celDate` or is a continuation of an existing event.
                                     * @protected
                                     */
                                    _getRenderableEvent: function(events, rowStartDate, rowEndDate, celDate) {
                                        var instance = this,
                                            key = instance._getEvtRenderedStackKey(celDate),
                                            i;
                            
                                        if (!instance.evtRenderedStack[key]) {
                                            instance.evtRenderedStack[key] = [];
                                        }
                            
                                        for (i = 0; i < events.length; i++) {
                                            var evt = events[i];
                            
                                            var startDate = evt.get('startDate');
                            
                                            var isEventDateContinuation = DateMath.after(celDate, startDate) && !DateMath.isDayOverlap(celDate,
                                                rowStartDate);
                                            var isEventStartDateDay = !DateMath.isDayOverlap(startDate, celDate);
                            
                                            var isRendered = A.Array.indexOf(instance.evtRenderedStack[key], evt) > -1;
                            
                                            if (!isRendered && (isEventStartDateDay || isEventDateContinuation)) {
                                                return evt;
                                            }
                                        }
                            
                                        return null;
                                    },
                            
                                    /**
                                     * Returns the table grid `Node` for a given `rowIndex`.
                                     *
                                     * @method _getTableGridNode
                                     * @param {Number} rowIndex
                                     * @return {Node} tableGridNode The table grid `Node` from a given
                                     *     `rowIndex`.
                                     * @protected
                                     */
                                    _getTableGridNode: function(rowIndex) {
                                        var instance = this,
                                            displayDaysInterval = instance.get('displayDaysInterval'),
                                            tableGridNode = instance.tableGridNode.item(rowIndex),
                                            firstRowNode = tableGridNode.one('tr'),
                                            i;
                            
                                        for (i = 0; i < Math.min(displayDaysInterval, WEEK_LENGTH); i++) {
                                            var columnNode = A.Node.create(TPL_SVT_GRID_COLUMN);
                            
                                            firstRowNode.append(columnNode);
                            
                                            if (i === 0) {
                                                columnNode.addClass(CSS_SVT_COLGRID_FIRST);
                                            }
                            
                                            instance.columnTableGrid.push(columnNode);
                                        }
                            
                                        return tableGridNode;
                                    },
                            
                                    /**
                                     * Handles `SchedulerEvent` `click` events for the `SchedulerViewTable`.
                                     *
                                     * @method _onClickMore
                                     * @param {EventFacade} event
                                     * @protected
                                     */
                                    _onClickMore: function(event) {
                                        var instance = this;
                            
                                        var target = event.target;
                                        var events = target.getData('events');
                                        var eventsNodeList = A.NodeList.create();
                            
                                        A.Array.each(events, function(evt) {
                                            evt.syncNodeTitleUI();
                            
                                            var evtNode = evt.get('node').item(0).clone();
                            
                                            evtNode.setData('scheduler-event', evt);
                            
                                            evtNode.setStyles({
                                                height: 'auto',
                                                left: 0,
                                                position: 'relative',
                                                top: 0,
                                                width: 'auto'
                                            });
                            
                                            eventsNodeList.push(evtNode);
                                        });
                            
                                        instance.eventsOverlay.bodyNode.one('.' + CSS_SVT_EVENTS_OVERLAY_NODE_BODY).setContent(
                                            eventsNodeList);
                            
                                        instance.eventsOverlay.setAttrs({
                                            visible: true,
                                            xy: target.getXY()
                                        });
                                    },
                            
                                    /**
                                     * Renders this `SchedulerViewTable` event's `overlay` component.
                                     *
                                     * @method _renderEventsOverlay
                                     * @protected
                                     */
                                    _renderEventsOverlay: function() {
                                        var instance = this;
                                        var strings = instance.get('strings');
                            
                                        instance.eventsOverlay = new A.Overlay({
                                            align: {
                                                points: ['tl', 'tl']
                                            },
                                            bodyContent: Lang.sub(
                                                TPL_SVT_EVENTS_OVERLAY_NODE, {
                                                    label: strings.close
                                                }
                                            ),
                                            constrain: instance.get('eventsOverlayConstrain'),
                                            render: instance.get('boundingBox'),
                                            visible: false,
                                            width: 250,
                                            zIndex: 450
                                        });
                            
                                        instance.eventsOverlay.bodyNode.delegate('click', A.bind(instance.hideEventsOverlay, instance), '.' +
                                            CSS_SVT_EVENTS_OVERLAY_NODE_CLOSE);
                                    },
                            
                                    /**
                                     * Updates a given `Node`'s UI with a given `evtSplitInfo` value.
                                     * any changes made to the instance attributes.
                                     *
                                     * @method _syncEventNodeContainerUI
                                     * @param {A.SchedulerEvent} evt A `Scheduler` event.
                                     * @param node
                                     * @param {Object} evtSplitInfo An object containing the `colspan`,
                                     *     `left` and `right` values that determine a `SchedulerEvent`'s
                                     *     split information.
                                     * @protected
                                     */
                                    _syncEventNodeContainerUI: function(evt, node, evtSplitInfo) {
                                        node.addClass(CSS_SVT_TABLE_DATA_EVENT);
                            
                                        if (evtSplitInfo.left) {
                                            node.addClass(CSS_SVT_TABLE_DATA_EVENT_LEFT).prepend(TPL_SVT_EV_ICON_LEFT);
                                        }
                            
                                        if (evtSplitInfo.right) {
                                            node.addClass(CSS_SVT_TABLE_DATA_EVENT_RIGHT).append(TPL_SVT_EV_ICON_RIGHT);
                                        }
                                    },
                            
                                    /**
                                     * Updates a given `SchedulerEvent` `Node` with the given `celDate` and
                                     * appends it to a given `container` `Node`.
                                     *
                                     * @method _syncEventNodeUI
                                     * @param {A.SchedulerEvent} evt A `Scheduler` event.
                                     * @param container
                                     * @param celDate
                                     * @protected
                                     */
                                    _syncEventNodeUI: function(evt, container, celDate) {
                                        var instance = this;
                                        var scheduler = instance.get('scheduler');
                                        var firstDayOfWeek = scheduler.get('firstDayOfWeek');
                            
                                        var evtNodeList = evt.get('node');
                                        var startDate = evt.get('startDate');
                            
                                        var intervalStartDate = DateMath.clearTime(instance._findCurrentIntervalStart());
                                        var startDateFirstDayOfWeek = DateMath.clearTime(DateMath.getFirstDayOfWeek(
                                            new Date(Math.max(startDate, intervalStartDate)),
                                            firstDayOfWeek
                                        ));
                                        var paddingNodeIndex = Math.floor(DateMath.countDays(celDate, startDateFirstDayOfWeek) / WEEK_LENGTH);
                            
                                        if (evtNodeList.size() <= paddingNodeIndex) {
                                            evt.addPaddingNode();
                                        }
                            
                                        if (evtNodeList.size() <= paddingNodeIndex) {
                                            paddingNodeIndex = evtNodeList.size() - 1;
                                        }
                            
                                        var evtNode = evtNodeList.item(paddingNodeIndex);
                            
                                        evtNode.show();
                                        evtNode.setStyles({
                                            height: 'auto',
                                            left: 0,
                                            top: 0,
                                            width: 'auto'
                                        });
                            
                                        evtNode.appendTo(container);
                            
                                        evt.syncUI();
                                    },
                            
                                    /**
                                     * Sets `date` on the UI.
                                     *
                                     * @method _uiSetDate
                                     * @protected
                                     */
                                    _uiSetDate: function() {
                                        var instance = this;
                            
                                        instance.syncDaysHeaderUI();
                                        instance.syncGridUI();
                                    },
                            
                                    /**
                                     * Returns the value of `colHeaderDaysNode`.
                                     *
                                     * @method _valueColHeaderDaysNode
                                     * @protected
                                     */
                                    _valueColHeaderDaysNode: function() {
                                        var instance = this;
                            
                                        var displayDaysInterval = instance.get('displayDaysInterval');
                                        var weekDaysCount = Math.min(displayDaysInterval, WEEK_LENGTH);
                            
                                        return instance._valueNodeList(weekDaysCount, TPL_SVT_HEADER_DAY);
                                    },
                            
                                    /**
                                     * Returns the value of `tableGridNode`.
                                     *
                                     * @method _valueTableGridNode
                                     * @protected
                                     */
                                    _valueTableGridNode: function() {
                                        var instance = this;
                            
                                        var displayDaysInterval = instance.get('displayDaysInterval');
                                        var weekDaysCount = Math.min(displayDaysInterval, WEEK_LENGTH);
                            
                                        return instance._valueNodeList(weekDaysCount, TPL_SVT_TABLE_GRID);
                                    },
                            
                                    /**
                                     * Returns the a new `NodeList` with a given size and template.
                                     *
                                     * @method _valueNodeList
                                     * @param size
                                     * @param tpl
                                     * @protected
                                     */
                                    _valueNodeList: function(size, tpl) {
                                        var buffer = [];
                            
                                        while (size--) {
                                            buffer.push(tpl);
                                        }
                            
                                        return A.NodeList.create(buffer.join(''));
                                    }
                                }
                            });
                            
                            A.SchedulerTableView = SchedulerTableView;