    /**
     * @class Ext.layout.container.Box
     * @extends Ext.layout.container.Container
     * <p>Base Class for HBoxLayout and VBoxLayout Classes. Generally it should not need to be used directly.</p>
     */

    Ext.define('Ext.layout.container.Box', {

        /* Begin Definitions */

        alias: ['layout.box'],
        extend: 'Ext.layout.container.Container',
        alternateClassName: 'Ext.layout.BoxLayout',

        requires: [
            'Ext.layout.container.boxOverflow.None',
            'Ext.layout.container.boxOverflow.Menu',
            'Ext.layout.container.boxOverflow.Scroller',
            'Ext.util.Format',
            'Ext.dd.DragDropManager'
        ],

        /* End Definitions */

        /**
         * @cfg {Mixed} animate
         * <p>If truthy, child Component are <i>animated</i> into position whenever the Container
         * is layed out. If this option is numeric, it is used as the animation duration in milliseconds.</p>
         * <p>May be set as a property at any time.</p>
         */

        /**
         * @cfg {Object} defaultMargins
         * <p>If the individual contained items do not have a <tt>margins</tt>
         * property specified or margin specified via CSS, the default margins from this property will be
         * applied to each item.</p>
         * <br><p>This property may be specified as an object containing margins
         * to apply in the format:</p><pre><code>
    {
        top: (top margin),
        right: (right margin),
        bottom: (bottom margin),
        left: (left margin)
    }</code></pre>
         * <p>This property may also be specified as a string containing
         * space-separated, numeric margin values. The order of the sides associated
         * with each value matches the way CSS processes margin values:</p>
         * <div class="mdetail-params"><ul>
         * <li>If there is only one value, it applies to all sides.</li>
         * <li>If there are two values, the top and bottom borders are set to the
         * first value and the right and left are set to the second.</li>
         * <li>If there are three values, the top is set to the first value, the left
         * and right are set to the second, and the bottom is set to the third.</li>
         * <li>If there are four values, they apply to the top, right, bottom, and
         * left, respectively.</li>
         * </ul></div>
         * <p>Defaults to:</p><pre><code>
         * {top:0, right:0, bottom:0, left:0}
         * </code></pre>
         */
        defaultMargins: {
            top: 0,
            right: 0,
            bottom: 0,
            left: 0
        },

        /**
         * @cfg {String} padding
         * <p>Sets the padding to be applied to all child items managed by this layout.</p>
         * <p>This property must be specified as a string containing
         * space-separated, numeric padding values. The order of the sides associated
         * with each value matches the way CSS processes padding values:</p>
         * <div class="mdetail-params"><ul>
         * <li>If there is only one value, it applies to all sides.</li>
         * <li>If there are two values, the top and bottom borders are set to the
         * first value and the right and left are set to the second.</li>
         * <li>If there are three values, the top is set to the first value, the left
         * and right are set to the second, and the bottom is set to the third.</li>
         * <li>If there are four values, they apply to the top, right, bottom, and
         * left, respectively.</li>
         * </ul></div>
         * <p>Defaults to: <code>"0"</code></p>
         */
        padding: '0',
        // documented in subclasses
        pack: 'start',

        /**
         * @cfg {String} pack
         * Controls how the child items of the container are packed together. Acceptable configuration values
         * for this property are:
         * <div class="mdetail-params"><ul>
         * <li><b><tt>start</tt></b> : <b>Default</b><div class="sub-desc">child items are packed together at
         * <b>left</b> side of container</div></li>
         * <li><b><tt>center</tt></b> : <div class="sub-desc">child items are packed together at
         * <b>mid-width</b> of container</div></li>
         * <li><b><tt>end</tt></b> : <div class="sub-desc">child items are packed together at <b>right</b>
         * side of container</div></li>
         * </ul></div>
         */
        /**
         * @cfg {Number} flex
         * This configuration option is to be applied to <b>child <tt>items</tt></b> of the container managed
         * by this layout. Each child item with a <tt>flex</tt> property will be flexed <b>horizontally</b>
         * according to each item's <b>relative</b> <tt>flex</tt> value compared to the sum of all items with
         * a <tt>flex</tt> value specified.  Any child items that have either a <tt>flex = 0</tt> or
         * <tt>flex = undefined</tt> will not be 'flexed' (the initial size will not be changed).
         */

        type: 'box',
        scrollOffset: 0,
        itemCls: Ext.baseCSSPrefix + 'box-item',
        targetCls: Ext.baseCSSPrefix + 'box-layout-ct',
        innerCls: Ext.baseCSSPrefix + 'box-inner',

        bindToOwnerCtContainer: true,

        fixedLayout: false,

        // availableSpaceOffset is used to adjust the availableWidth, typically used
        // to reserve space for a scrollbar
        availableSpaceOffset: 0,

        // whether or not to reserve the availableSpaceOffset in layout calculations
        reserveOffset: true,

        /**
         * @cfg {Boolean} clearInnerCtOnLayout
         */
        clearInnerCtOnLayout: false,

        flexSortFn: function (a, b) {
            var maxParallelPrefix = 'max' + this.parallelPrefixCap,
                infiniteValue = Infinity;
            a = a.component[maxParallelPrefix] || infiniteValue;
            b = b.component[maxParallelPrefix] || infiniteValue;
            // IE 6/7 Don't like Infinity - Infinity...
            if (!isFinite(a) && !isFinite(b)) {
                return false;
            }
            return a - b;
        },

        // Sort into *descending* order.
        minSizeSortFn: function(a, b) {
            return b.available - a.available;
        },

        constructor: function(config) {
            var me = this;

            me.callParent(arguments);

            // The sort function needs access to properties in this, so must be bound.
            me.flexSortFn = Ext.Function.bind(me.flexSortFn, me);

            me.initOverflowHandler();
        },

        /**
         * @private
         * Returns the current size and positioning of the passed child item.
         * @param {Component} child The child Component to calculate the box for
         * @return {Object} Object containing box measurements for the child. Properties are left,top,width,height.
         */
        getChildBox: function(child) {
            child = child.el || this.owner.getComponent(child).el;
            return {
                left: child.getLeft(true),
                top: child.getTop(true),
                width: child.getWidth(),
                height: child.getHeight()
            };
        },

        /**
         * @private
         * Calculates the size and positioning of the passed child item.
         * @param {Component} child The child Component to calculate the box for
         * @return {Object} Object containing box measurements for the child. Properties are left,top,width,height.
         */
        calculateChildBox: function(child) {
            var me = this,
                boxes = me.calculateChildBoxes(me.getVisibleItems(), me.getLayoutTargetSize()).boxes,
                ln = boxes.length,
                i = 0;

            child = me.owner.getComponent(child);
            for (; i < ln; i++) {
                if (boxes[i].component === child) {
                    return boxes[i];
                }
            }
        },

        /**
         * @private
         * Calculates the size and positioning of each item in the box. This iterates over all of the rendered,
         * visible items and returns a height, width, top and left for each, as well as a reference to each. Also
         * returns meta data such as maxSize which are useful when resizing layout wrappers such as this.innerCt.
         * @param {Array} visibleItems The array of all rendered, visible items to be calculated for
         * @param {Object} targetSize Object containing target size and height
         * @return {Object} Object containing box measurements for each child, plus meta data
         */
        calculateChildBoxes: function(visibleItems, targetSize) {
            var me = this,
                math = Math,
                mmax = math.max,
                infiniteValue = Infinity,
                undefinedValue,

                parallelPrefix = me.parallelPrefix,
                parallelPrefixCap = me.parallelPrefixCap,
                perpendicularPrefix = me.perpendicularPrefix,
                perpendicularPrefixCap = me.perpendicularPrefixCap,
                parallelMinString = 'min' + parallelPrefixCap,
                perpendicularMinString = 'min' + perpendicularPrefixCap,
                perpendicularMaxString = 'max' + perpendicularPrefixCap,

                parallelSize = targetSize[parallelPrefix] - me.scrollOffset,
                perpendicularSize = targetSize[perpendicularPrefix],
                padding = me.padding,
                parallelOffset = padding[me.parallelBefore],
                paddingParallel = parallelOffset + padding[me.parallelAfter],
                perpendicularOffset = padding[me.perpendicularLeftTop],
                paddingPerpendicular =  perpendicularOffset + padding[me.perpendicularRightBottom],
                availPerpendicularSize = mmax(0, perpendicularSize - paddingPerpendicular),

                isStart = me.pack == 'start',
                isCenter = me.pack == 'center',
                isEnd = me.pack == 'end',

                constrain = Ext.Number.constrain,
                visibleCount = visibleItems.length,
                nonFlexSize = 0,
                totalFlex = 0,
                desiredSize = 0,
                minimumSize = 0,
                maxSize = 0,
                boxes = [],
                minSizes = [],
                calculatedWidth,

                i, child, childParallel, childPerpendicular, childMargins, childSize, minParallel, tmpObj, shortfall,
                tooNarrow, availableSpace, minSize, item, length, itemIndex, box, oldSize, newSize, reduction, diff,
                flexedBoxes, remainingSpace, remainingFlex, flexedSize, parallelMargins, calcs, offset,
                perpendicularMargins, stretchSize;

            //gather the total flex of all flexed items and the width taken up by fixed width items
            for (i = 0; i < visibleCount; i++) {
                child = visibleItems[i];
                childPerpendicular = child[perpendicularPrefix];
                me.layoutItem(child);
                childMargins = child.margins;
                parallelMargins = childMargins[me.parallelBefore] + childMargins[me.parallelAfter];

                // Create the box description object for this child item.
                tmpObj = {
                    component: child,
                    margins: childMargins
                };

                // flex and not 'auto' width
                if (child.flex) {
                    totalFlex += child.flex;
                    childParallel = undefinedValue;
                }
                // Not flexed or 'auto' width or undefined width
                else {
                    if (!(child[parallelPrefix] && childPerpendicular)) {
                        childSize = child.getSize();
                    }
                    childParallel = child[parallelPrefix] || childSize[parallelPrefix];
                    childPerpendicular = childPerpendicular || childSize[perpendicularPrefix];
                }

                nonFlexSize += parallelMargins + (childParallel || 0);
                desiredSize += parallelMargins + (child.flex ? child[parallelMinString] || 0 : childParallel);
                minimumSize += parallelMargins + (child[parallelMinString] || childParallel || 0);

                // Max height for align - force layout of non-laid out subcontainers without a numeric height
                if (typeof childPerpendicular != 'number') {
                    // Clear any static sizing and revert to flow so we can get a proper measurement
                    // child['set' + perpendicularPrefixCap](null);
                    childPerpendicular = child['get' + perpendicularPrefixCap]();
                }

                // Track the maximum perpendicular size for use by the stretch and stretchmax align config values.
                maxSize = mmax(maxSize, childPerpendicular + childMargins[me.perpendicularLeftTop] + childMargins[me.perpendicularRightBottom]);

                tmpObj[parallelPrefix] = childParallel || undefinedValue;
                tmpObj[perpendicularPrefix] = childPerpendicular || undefinedValue;
                boxes.push(tmpObj);
            }
            shortfall = desiredSize - parallelSize;
            tooNarrow = minimumSize > parallelSize;

            //the space available to the flexed items
            availableSpace = mmax(0, parallelSize - nonFlexSize - paddingParallel - (me.reserveOffset ? me.availableSpaceOffset : 0));

            if (tooNarrow) {
                for (i = 0; i < visibleCount; i++) {
                    box = boxes[i];
                    minSize = visibleItems[i][parallelMinString] || visibleItems[i][parallelPrefix] || box[parallelPrefix];
                    box.dirtySize = box.dirtySize || box[parallelPrefix] != minSize;
                    box[parallelPrefix] = minSize;
                }
            }
            else {
                //all flexed items should be sized to their minimum size, other items should be shrunk down until
                //the shortfall has been accounted for
                if (shortfall > 0) {
                    /*
                     * When we have a shortfall but are not tooNarrow, we need to shrink the width of each non-flexed item.
                     * Flexed items are immediately reduced to their minWidth and anything already at minWidth is ignored.
                     * The remaining items are collected into the minWidths array, which is later used to distribute the shortfall.
                     */
                    for (i = 0; i < visibleCount; i++) {
                        item = visibleItems[i];
                        minSize = item[parallelMinString] || 0;

                        //shrink each non-flex tab by an equal amount to make them all fit. Flexed items are all
                        //shrunk to their minSize because they're flexible and should be the first to lose size
                        if (item.flex) {
                            box = boxes[i];
                            box.dirtySize = box.dirtySize || box[parallelPrefix] != minSize;
                            box[parallelPrefix] = minSize;
                        }
                        else {
                            minSizes.push({
                                minSize: minSize,
                                available: boxes[i][parallelPrefix] - minSize,
                                index: i
                            });
                        }
                    }

                    //sort by descending amount of width remaining before minWidth is reached
                    Ext.Array.sort(minSizes, me.minSizeSortFn);

                    /*
                     * Distribute the shortfall (difference between total desired size of all items and actual size available)
                     * between the non-flexed items. We try to distribute the shortfall evenly, but apply it to items with the
                     * smallest difference between their size and minSize first, so that if reducing the size by the average
                     * amount would make that item less than its minSize, we carry the remainder over to the next item.
                     */
                    for (i = 0, length = minSizes.length; i < length; i++) {
                        itemIndex = minSizes[i].index;

                        if (itemIndex == undefinedValue) {
                            continue;
                        }
                        item = visibleItems[itemIndex];
                        minSize = minSizes[i].minSize;

                        box = boxes[itemIndex];
                        oldSize = box[parallelPrefix];
                        newSize = mmax(minSize, oldSize - math.ceil(shortfall / (length - i)));
                        reduction = oldSize - newSize;

                        box.dirtySize = box.dirtySize || box[parallelPrefix] != newSize;
                        box[parallelPrefix] = newSize;
                        shortfall -= reduction;
                    }
                }
                else {
                    remainingSpace = availableSpace;
                    remainingFlex = totalFlex;
                    flexedBoxes = [];

                    // Create an array containing *just the flexed boxes* for allocation of remainingSpace
                    for (i = 0; i < visibleCount; i++) {
                        child = visibleItems[i];
                        if (isStart && child.flex) {
                            flexedBoxes.push(boxes[Ext.Array.indexOf(visibleItems, child)]);
                        }
                    }
                    // The flexed boxes need to be sorted in ascending order of maxSize to work properly
                    // so that unallocated space caused by maxWidth being less than flexed width
                    // can be reallocated to subsequent flexed boxes.
                    Ext.Array.sort(flexedBoxes, me.flexSortFn);

                    // Calculate the size of each flexed item, and attempt to set it.
                    for (i = 0; i < flexedBoxes.length; i++) {
                        calcs = flexedBoxes[i];
                        child = calcs.component;
                        childMargins = calcs.margins;

                        flexedSize = math.ceil((child.flex / remainingFlex) * remainingSpace);

                        // Implement maxSize and minSize check
                        flexedSize = Math.max(child['min' + parallelPrefixCap] || 0, math.min(child['max' + parallelPrefixCap] || infiniteValue, flexedSize));

                        // Remaining space has already had all parallel margins subtracted from it, so just subtract consumed size
                        remainingSpace -= flexedSize;
                        remainingFlex -= child.flex;

                        calcs.dirtySize = calcs.dirtySize || calcs[parallelPrefix] != flexedSize;
                        calcs[parallelPrefix] = flexedSize;
                    }
                }
            }

            if (isCenter) {
                parallelOffset += availableSpace / 2;
            }
            else if (isEnd) {
                parallelOffset += availableSpace;
            }

            // Fix for left and right docked Components in a dock component layout. This is for docked Headers and docked Toolbars.
            // Older Microsoft browsers do not size a position:absolute element's width to match its content.
            // So in this case, in the updateInnerCtSize method we may need to adjust the size of the owning Container's element explicitly based upon
            // the discovered max width. So here we put a calculatedWidth property in the metadata to facilitate this.
            if (me.owner.dock && (Ext.isIE6 || Ext.isIE7 || Ext.isIEQuirks) && !me.owner.width && me.direction == 'vertical') {

                calculatedWidth = maxSize + me.owner.el.getPadding('lr') + me.owner.el.getBorderWidth('lr');
                if (me.owner.frameSize) {
                    calculatedWidth += me.owner.frameSize.left + me.owner.frameSize.right;
                }
                // If the owning element is not sized, calculate the available width to center or stretch in based upon maxSize
                availPerpendicularSize = Math.min(availPerpendicularSize, targetSize.width = maxSize + padding.left + padding.right);
            }

            //finally, calculate the left and top position of each item
            for (i = 0; i < visibleCount; i++) {
                child = visibleItems[i];
                calcs = boxes[i];

                childMargins = calcs.margins;

                perpendicularMargins = childMargins[me.perpendicularLeftTop] + childMargins[me.perpendicularRightBottom];

                // Advance past the "before" margin
                parallelOffset += childMargins[me.parallelBefore];

                calcs[me.parallelBefore] = parallelOffset;
                calcs[me.perpendicularLeftTop] = perpendicularOffset + childMargins[me.perpendicularLeftTop];

                if (me.align == 'stretch') {
                    stretchSize = constrain(availPerpendicularSize - perpendicularMargins, child[perpendicularMinString] || 0, child[perpendicularMaxString] || infiniteValue);
                    calcs.dirtySize = calcs.dirtySize || calcs[perpendicularPrefix] != stretchSize;
                    calcs[perpendicularPrefix] = stretchSize;
                }
                else if (me.align == 'stretchmax') {
                    stretchSize = constrain(maxSize - perpendicularMargins, child[perpendicularMinString] || 0, child[perpendicularMaxString] || infiniteValue);
                    calcs.dirtySize = calcs.dirtySize || calcs[perpendicularPrefix] != stretchSize;
                    calcs[perpendicularPrefix] = stretchSize;
                }
                else if (me.align == me.alignCenteringString) {
                    // When calculating a centered position within the content box of the innerCt, the width of the borders must be subtracted from
                    // the size to yield the space available to center within.
                    // The updateInnerCtSize method explicitly adds the border widths to the set size of the innerCt.
                    diff = mmax(availPerpendicularSize, maxSize) - me.innerCt.getBorderWidth(me.perpendicularLT + me.perpendicularRB) - calcs[perpendicularPrefix];
                    if (diff > 0) {
                        calcs[me.perpendicularLeftTop] = perpendicularOffset + Math.round(diff / 2);
                    }
                }

                // Advance past the box size and the "after" margin
                parallelOffset += (calcs[parallelPrefix] || 0) + childMargins[me.parallelAfter];
            }

            return {
                boxes: boxes,
                meta : {
                    calculatedWidth: calculatedWidth,
                    maxSize: maxSize,
                    nonFlexSize: nonFlexSize,
                    desiredSize: desiredSize,
                    minimumSize: minimumSize,
                    shortfall: shortfall,
                    tooNarrow: tooNarrow
                }
            };
        },

        onRemove: function(comp){
            this.callParent(arguments);
            if (this.overflowHandler) {
                this.overflowHandler.onRemove(comp);
            }
        },

        /**
         * @private
         */
        initOverflowHandler: function() {
            var handler = this.overflowHandler;

            if (typeof handler == 'string') {
                handler = {
                    type: handler
                };
            }

            var handlerType = 'None';
            if (handler && handler.type !== undefined) {
                handlerType = handler.type;
            }

            var constructor = Ext.layout.container.boxOverflow[handlerType];
            if (constructor[this.type]) {
                constructor = constructor[this.type];
            }

            this.overflowHandler = Ext.create('Ext.layout.container.boxOverflow.' + handlerType, this, handler);
        },

        /**
         * @private
         * Runs the child box calculations and caches them in childBoxCache. Subclasses can used these cached values
         * when laying out
         */
        onLayout: function() {
            this.callParent();
            // Clear the innerCt size so it doesn't influence the child items.
            if (this.clearInnerCtOnLayout === true && this.adjustmentPass !== true) {
                this.innerCt.setSize(null, null);
            }

            var me = this,
                targetSize = me.getLayoutTargetSize(),
                items = me.getVisibleItems(),
                calcs = me.calculateChildBoxes(items, targetSize),
                boxes = calcs.boxes,
                meta = calcs.meta,
                handler, method, results;

            if (me.autoSize && calcs.meta.desiredSize) {
                targetSize[me.parallelPrefix] = calcs.meta.desiredSize;
            }

            //invoke the overflow handler, if one is configured
            if (meta.shortfall > 0) {
                handler = me.overflowHandler;
                method = meta.tooNarrow ? 'handleOverflow': 'clearOverflow';

                results = handler[method](calcs, targetSize);

                if (results) {
                    if (results.targetSize) {
                        targetSize = results.targetSize;
                    }

                    if (results.recalculate) {
                        items = me.getVisibleItems(owner);
                        calcs = me.calculateChildBoxes(items, targetSize);
                        boxes = calcs.boxes;
                    }
                }
            } else {
                me.overflowHandler.clearOverflow();
            }

            /**
             * @private
             * @property layoutTargetLastSize
             * @type Object
             * Private cache of the last measured size of the layout target. This should never be used except by
             * BoxLayout subclasses during their onLayout run.
             */
            me.layoutTargetLastSize = targetSize;

            /**
             * @private
             * @property childBoxCache
             * @type Array
             * Array of the last calculated height, width, top and left positions of each visible rendered component
             * within the Box layout.
             */
            me.childBoxCache = calcs;

            me.updateInnerCtSize(targetSize, calcs);
            me.updateChildBoxes(boxes);
            me.handleTargetOverflow(targetSize);
        },

        /**
         * Resizes and repositions each child component
         * @param {Array} boxes The box measurements
         */
        updateChildBoxes: function(boxes) {
            var me = this,
                i = 0,
                length = boxes.length,
                animQueue = [],
                dd = Ext.dd.DDM.getDDById(me.innerCt.id), // Any DD active on this layout's element (The BoxReorderer plugin does this.)
                oldBox, newBox, changed, comp, boxAnim, animCallback;

            for (; i < length; i++) {
                newBox = boxes[i];
                comp = newBox.component;

                // If a Component is being drag/dropped, skip positioning it.
                // Accomodate the BoxReorderer plugin: Its current dragEl must not be positioned by the layout
                if (dd && (dd.getDragEl() === comp.el.dom)) {
                    continue;
                }

                changed = false;

                oldBox = me.getChildBox(comp);

                // If we are animating, we build up an array of Anim config objects, one for each
                // child Component which has any changed box properties. Those with unchanged
                // properties are not animated.
                if (me.animate) {
                    // Animate may be a config object containing callback.
                    animCallback = me.animate.callback || me.animate;
                    boxAnim = {
                        layoutAnimation: true,  // Component Target handler must use set*Calculated*Size
                        target: comp,
                        from: {},
                        to: {},
                        listeners: {}
                    };
                    // Only set from and to properties when there's a change.
                    // Perform as few Component setter methods as possible.
                    // Temporarily set the property values that we are not animating
                    // so that doComponentLayout does not auto-size them.
                    if (!isNaN(newBox.width) && (newBox.width != oldBox.width)) {
                        changed = true;
                        // boxAnim.from.width = oldBox.width;
                        boxAnim.to.width = newBox.width;
                    }
                    if (!isNaN(newBox.height) && (newBox.height != oldBox.height)) {
                        changed = true;
                        // boxAnim.from.height = oldBox.height;
                        boxAnim.to.height = newBox.height;
                    }
                    if (!isNaN(newBox.left) && (newBox.left != oldBox.left)) {
                        changed = true;
                        // boxAnim.from.left = oldBox.left;
                        boxAnim.to.left = newBox.left;
                    }
                    if (!isNaN(newBox.top) && (newBox.top != oldBox.top)) {
                        changed = true;
                        // boxAnim.from.top = oldBox.top;
                        boxAnim.to.top = newBox.top;
                    }
                    if (changed) {
                        animQueue.push(boxAnim);
                    }
                } else {
                    if (newBox.dirtySize) {
                        if (newBox.width !== oldBox.width || newBox.height !== oldBox.height) {
                            me.setItemSize(comp, newBox.width, newBox.height);
                        }
                    }
                    // Don't set positions to NaN
                    if (isNaN(newBox.left) || isNaN(newBox.top)) {
                        continue;
                    }
                    comp.setPosition(newBox.left, newBox.top);
                }
            }

            // Kick off any queued animations
            length = animQueue.length;
            if (length) {

                // A function which cleans up when a Component's animation is done.
                // The last one to finish calls the callback.
                var afterAnimate = function(anim) {
                    // When we've animated all changed boxes into position, clear our busy flag and call the callback.
                    length -= 1;
                    if (!length) {
                        me.layoutBusy = false;
                        if (Ext.isFunction(animCallback)) {
                            animCallback();
                        }
                    }
                };

                var beforeAnimate = function() {
                    me.layoutBusy = true;
                };

                // Start each box animation off
                for (i = 0, length = animQueue.length; i < length; i++) {
                    boxAnim = animQueue[i];

                    // Clean up the Component after. Clean up the *layout* after the last animation finishes
                    boxAnim.listeners.afteranimate = afterAnimate;

                    // The layout is busy during animation, and may not be called, so set the flag when the first animation begins
                    if (!i) {
                        boxAnim.listeners.beforeanimate = beforeAnimate;
                    }
                    if (me.animate.duration) {
                        boxAnim.duration = me.animate.duration;
                    }
                    comp = boxAnim.target;
                    delete boxAnim.target;
                    // Stop any currently running animation
                    comp.stopAnimation();
                    comp.animate(boxAnim);
                }
            }
        },

        /**
         * @private
         * Called by onRender just before the child components are sized and positioned. This resizes the innerCt
         * to make sure all child items fit within it. We call this before sizing the children because if our child
         * items are larger than the previous innerCt size the browser will insert scrollbars and then remove them
         * again immediately afterwards, giving a performance hit.
         * Subclasses should provide an implementation.
         * @param {Object} currentSize The current height and width of the innerCt
         * @param {Array} calculations The new box calculations of all items to be laid out
         */
        updateInnerCtSize: function(tSize, calcs) {
            var me = this,
                mmax = Math.max,
                align = me.align,
                padding = me.padding,
                width = tSize.width,
                height = tSize.height,
                meta = calcs.meta,
                innerCtWidth,
                innerCtHeight;

            if (me.direction == 'horizontal') {
                innerCtWidth = width;
                innerCtHeight = meta.maxSize + padding.top + padding.bottom + me.innerCt.getBorderWidth('tb');

                if (align == 'stretch') {
                    innerCtHeight = height;
                }
                else if (align == 'middle') {
                    innerCtHeight = mmax(height, innerCtHeight);
                }
            } else {
                innerCtHeight = height;
                innerCtWidth = meta.maxSize + padding.left + padding.right + me.innerCt.getBorderWidth('lr');

                if (align == 'stretch') {
                    innerCtWidth = width;
                }
                else if (align == 'center') {
                    innerCtWidth = mmax(width, innerCtWidth);
                }
            }
            me.getRenderTarget().setSize(innerCtWidth || undefined, innerCtHeight || undefined);

            // If a calculated width has been found (and this only happens for auto-width vertical docked Components in old Microsoft browsers)
            // then, if the Component has not assumed the size of its content, set it to do so.
            if (meta.calculatedWidth && me.owner.el.getWidth() > meta.calculatedWidth) {
                me.owner.el.setWidth(meta.calculatedWidth);
            }

            if (me.innerCt.dom.scrollTop) {
                me.innerCt.dom.scrollTop = 0;
            }
        },

        /**
         * @private
         * This should be called after onLayout of any BoxLayout subclass. If the target's overflow is not set to 'hidden',
         * we need to lay out a second time because the scrollbars may have modified the height and width of the layout
         * target. Having a Box layout inside such a target is therefore not recommended.
         * @param {Object} previousTargetSize The size and height of the layout target before we just laid out
         * @param {Ext.container.Container} container The container
         * @param {Ext.core.Element} target The target element
         * @return True if the layout overflowed, and was reflowed in a secondary onLayout call.
         */
        handleTargetOverflow: function(previousTargetSize) {
            var target = this.getTarget(),
                overflow = target.getStyle('overflow'),
                newTargetSize;

            if (overflow && overflow != 'hidden' && !this.adjustmentPass) {
                newTargetSize = this.getLayoutTargetSize();
                if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height) {
                    this.adjustmentPass = true;
                    this.onLayout();
                    return true;
                }
            }

            delete this.adjustmentPass;
        },

        // private
        isValidParent : function(item, target, position) {
            // Note: Box layouts do not care about order within the innerCt element because it's an absolutely positioning layout
            // We only care whether the item is a direct child of the innerCt element.
            var itemEl = item.el ? item.el.dom : Ext.getDom(item);
            return (itemEl && this.innerCt && itemEl.parentNode === this.innerCt.dom) || false;
        },

        // Overridden method from AbstractContainer.
        // Used in the base AbstractLayout.beforeLayout method to render all items into.
        getRenderTarget: function() {
            if (!this.innerCt) {
                // the innerCt prevents wrapping and shuffling while the container is resizing
                this.innerCt = this.getTarget().createChild({
                    cls: this.innerCls,
                    role: 'presentation'
                });
                this.padding = Ext.util.Format.parseBox(this.padding);
            }
            return this.innerCt;
        },

        // private
        renderItem: function(item, target) {
            this.callParent(arguments);
            var me = this,
                itemEl = item.getEl(),
                style = itemEl.dom.style,
                margins = item.margins || item.margin;

            // Parse the item's margin/margins specification
            if (margins) {
                if (Ext.isString(margins) || Ext.isNumber(margins)) {
                    margins = Ext.util.Format.parseBox(margins);
                } else {
                    Ext.applyIf(margins, {top: 0, right: 0, bottom: 0, left: 0});
                }
            } else {
                margins = Ext.apply({}, me.defaultMargins);
            }

            // Add any before/after CSS margins to the configured margins, and zero the CSS margins
            margins.top    += itemEl.getMargin('t');
            margins.right  += itemEl.getMargin('r');
            margins.bottom += itemEl.getMargin('b');
            margins.left   += itemEl.getMargin('l');
            style.marginTop = style.marginRight = style.marginBottom = style.marginLeft = '0';

            // Item must reference calculated margins.
            item.margins = margins;
        },

        /**
         * @private
         */
        destroy: function() {
            Ext.destroy(this.overflowHandler);
            this.callParent(arguments);
        }
    });