    /**
     * This is the layout style of choice for creating structural layouts in a multi-column format where the width of each
     * column can be specified as a percentage or fixed width, but the height is allowed to vary based on the content. This
     * class is intended to be extended or created via the layout:'column' {@link Ext.container.Container#layout} config,
     * and should generally not need to be created directly via the new keyword.
     *
     * ColumnLayout does not have any direct config options (other than inherited ones), but it does support a specific
     * config property of `columnWidth` that can be included in the config of any panel added to it. The layout will use
     * the columnWidth (if present) or width of each panel during layout to determine how to size each panel. If width or
     * columnWidth is not specified for a given panel, its width will default to the panel's width (or auto).
     *
     * The width property is always evaluated as pixels, and must be a number greater than or equal to 1. The columnWidth
     * property is always evaluated as a percentage, and must be a decimal value greater than 0 and less than 1 (e.g., .25).
     *
     * The basic rules for specifying column widths are pretty simple. The logic makes two passes through the set of
     * contained panels. During the first layout pass, all panels that either have a fixed width or none specified (auto)
     * are skipped, but their widths are subtracted from the overall container width.
     *
     * During the second pass, all panels with columnWidths are assigned pixel widths in proportion to their percentages
     * based on the total **remaining** container width. In other words, percentage width panels are designed to fill
     * the space left over by all the fixed-width and/or auto-width panels. Because of this, while you can specify any
     * number of columns with different percentages, the columnWidths must always add up to 1 (or 100%) when added
     * together, otherwise your layout may not render as expected.
     *
     *     @example
     *     // All columns are percentages -- they must add up to 1
     *     Ext.create('Ext.panel.Panel', {
     *         title: 'Column Layout - Percentage Only',
     *         width: 350,
     *         height: 250,
     *         layout:'column',
     *         items: [{
     *             title: 'Column 1',
     *             columnWidth: 0.25
     *         },{
     *             title: 'Column 2',
     *             columnWidth: 0.55
     *         },{
     *             title: 'Column 3',
     *             columnWidth: 0.20
     *         }],
     *         renderTo: Ext.getBody()
     *     });
     *
     *     // Mix of width and columnWidth -- all columnWidth values must add up
     *     // to 1. The first column will take up exactly 120px, and the last two
     *     // columns will fill the remaining container width.
     *
     *     Ext.create('Ext.Panel', {
     *         title: 'Column Layout - Mixed',
     *         width: 350,
     *         height: 250,
     *         layout:'column',
     *         items: [{
     *             title: 'Column 1',
     *             width: 120
     *         },{
     *             title: 'Column 2',
     *             columnWidth: 0.7
     *         },{
     *             title: 'Column 3',
     *             columnWidth: 0.3
     *         }],
     *         renderTo: Ext.getBody()
     *     });
     */
    Ext.define('Ext.layout.container.Column', {

        extend: 'Ext.layout.container.Container',
        alias: ['layout.column'],
        alternateClassName: 'Ext.layout.ColumnLayout',

        type: 'column',

        itemCls: Ext.baseCSSPrefix + 'column',

        targetCls: Ext.baseCSSPrefix + 'column-layout-ct',

        // Columns with a columnWidth have their width managed.
        columnWidthSizePolicy: {
            setsWidth: 1,
            setsHeight: 0
        },

        childEls: [
            'innerCt'
        ],

        manageOverflow: 2,

        renderTpl: [
            '<div id="{ownerId}-innerCt" class="',Ext.baseCSSPrefix,'column-inner">',
                '{%this.renderBody(out,values)%}',
                '<div class="',Ext.baseCSSPrefix,'clear"></div>',
            '</div>',
            '{%this.renderPadder(out,values)%}'
        ],

        getItemSizePolicy: function (item) {
            if (item.columnWidth) {
                return this.columnWidthSizePolicy;
            }
            return this.autoSizePolicy;
        },

        beginLayout: function() {
            this.callParent(arguments);
            this.innerCt.dom.style.width = '';
        },

        calculate: function (ownerContext) {
            var me = this,
                containerSize = me.getContainerSize(ownerContext),
                state = ownerContext.state;

            if (state.calculatedColumns || (state.calculatedColumns = me.calculateColumns(ownerContext))) {
                if (me.calculateHeights(ownerContext)) {
                    me.calculateOverflow(ownerContext, containerSize);
                    return;
                }
            }

            me.done = false;
        },

        calculateColumns: function (ownerContext) {
            var me = this,
                containerSize = me.getContainerSize(ownerContext),
                innerCtContext = ownerContext.getEl('innerCt', me),
                items = ownerContext.childItems,
                len = items.length,
                contentWidth = 0,
                blocked, availableWidth, i, itemContext, itemMarginWidth, itemWidth;

            // Can never decide upon necessity of vertical scrollbar (and therefore, narrower
            // content width) until the component layout has published a height for the target
            // element.
            if (!ownerContext.heightModel.shrinkWrap && !ownerContext.targetContext.hasProp('height')) {
                return false;
            }

            // No parallel measurement, cannot lay out boxes.
            if (!containerSize.gotWidth) { //\\ TODO: Deal with target padding width
                ownerContext.targetContext.block(me, 'width');
                blocked = true;
            } else {
                availableWidth = containerSize.width;

                innerCtContext.setWidth(availableWidth);
            }

            // we need the widths of the columns we don't manage to proceed so we block on them
            // if they are not ready...
            for (i = 0; i < len; ++i) {
                itemContext = items[i];

                // this is needed below for non-calculated columns, but is also needed in the
                // next loop for calculated columns... this way we only call getMarginInfo in
                // this loop and use the marginInfo property in the next...
                itemMarginWidth = itemContext.getMarginInfo().width;

                if (!itemContext.widthModel.calculated) {
                    itemWidth = itemContext.getProp('width');
                    if (typeof itemWidth != 'number') {
                        itemContext.block(me, 'width');
                        blocked = true;
                    }

                    contentWidth += itemWidth + itemMarginWidth;
                }
            }

            if (!blocked) {
                availableWidth = (availableWidth < contentWidth) ? 0 : availableWidth - contentWidth;

                for (i = 0; i < len; ++i) {
                    itemContext = items[i];
                    if (itemContext.widthModel.calculated) {
                        itemMarginWidth = itemContext.marginInfo.width; // always set by above loop
                        itemWidth = itemContext.target.columnWidth;
                        itemWidth = Math.floor(itemWidth * availableWidth) - itemMarginWidth;
                        itemWidth = itemContext.setWidth(itemWidth); // constrains to min/maxWidth
                        contentWidth += itemWidth + itemMarginWidth;
                    }
                }

                ownerContext.setContentWidth(contentWidth);
            }

            // we registered all the values that block this calculation, so abort now if blocked...
            return !blocked;
        },

        calculateHeights: function (ownerContext) {
            var me = this,
                items = ownerContext.childItems,
                len = items.length,
                blocked, i, itemContext;

            // in order for innerCt to have the proper height, all the items must have height
            // correct in the DOM...
            blocked = false;
            for (i = 0; i < len; ++i) {
                itemContext = items[i];

                if (!itemContext.hasDomProp('height')) {
                    itemContext.domBlock(me, 'height');
                    blocked = true;
                }
            }

            if (!blocked) {
                ownerContext.setContentHeight(me.innerCt.getHeight() + ownerContext.targetContext.getPaddingInfo().height);
            }

            return !blocked;
        },

        finishedLayout: function (ownerContext) {
            var bc = ownerContext.bodyContext;

            // Owner may not have a body - this seems to only be needed for Panels.
            if (bc && (Ext.isIE6 || Ext.isIE7 || Ext.isIEQuirks)) {
                // Fix for https://sencha.jira.com/browse/EXTJSIV-4979
                bc.el.repaint();
            }

            this.callParent(arguments);
        },

        getRenderTarget : function() {
            return this.innerCt;
        }
    });