    /**
     * Given a component hierarchy of this:
     *
     *      {
     *          xtype: 'panel',
     *          id: 'ContainerA',
     *          layout: 'hbox',
     *          renderTo: Ext.getBody(),
     *          items: [
     *              {
     *                  id: 'ContainerB',
     *                  xtype: 'container',
     *                  items: [
     *                      { id: 'ComponentA' }
     *                  ]
     *              }
     *          ]
     *      }
     *
     * The rendering of the above proceeds roughly like this:
     *
     *  - ContainerA's initComponent calls #render passing the `renderTo` property as the
     *    container argument.
     *  - `render` calls the `getRenderTree` method to get a complete {@link Ext.DomHelper} spec.
     *  - `getRenderTree` fires the "beforerender" event and calls the #beforeRender
     *    method. Its result is obtained by calling #getElConfig.
     *  - The #getElConfig method uses the `renderTpl` and its render data as the content
     *    of the `autoEl` described element.
     *  - The result of `getRenderTree` is passed to {@link Ext.DomHelper#append}.
     *  - The `renderTpl` contains calls to render things like docked items, container items
     *    and raw markup (such as the `html` or `tpl` config properties). These calls are to
     *    methods added to the {@link Ext.XTemplate} instance by #setupRenderTpl.
     *  - The #setupRenderTpl method adds methods such as `renderItems`, `renderContent`, etc.
     *    to the template. These are directed to "doRenderItems", "doRenderContent" etc..
     *  - The #setupRenderTpl calls traverse from components to their {@link Ext.layout.Layout}
     *    object.
     *  - When a container is rendered, it also has a `renderTpl`. This is processed when the
     *    `renderContainer` method is called in the component's `renderTpl`. This call goes to
     *    Ext.layout.container.Container#doRenderContainer. This method repeats this
     *    process for all components in the container.
     *  - After the top-most component's markup is generated and placed in to the DOM, the next
     *    step is to link elements to their components and finish calling the component methods
     *    `onRender` and `afterRender` as well as fire the corresponding events.
     *  - The first step in this is to call #finishRender. This method descends the
     *    component hierarchy and calls `onRender` and fires the `render` event. These calls
     *    are delivered top-down to approximate the timing of these calls/events from previous
     *    versions.
     *  - During the pass, the component's `el` is set. Likewise, the `renderSelectors` and
     *    `childEls` are applied to capture references to the component's elements.
     *  - These calls are also made on the {@link Ext.layout.container.Container} layout to
     *    capture its elements. Both of these classes use {@link Ext.util.ElementContainer} to
     *    handle `childEls` processing.
     *  - Once this is complete, a similar pass is made by calling #finishAfterRender.
     *    This call also descends the component hierarchy, but this time the calls are made in
     *    a bottom-up order to `afterRender`.
     *
     * @private
     */
    Ext.define('Ext.util.Renderable', {
        requires: [
            'Ext.dom.Element'
        ],

        frameCls: Ext.baseCSSPrefix + 'frame',

        frameIdRegex: /[\-]frame\d+[TMB][LCR]$/,

        frameElementCls: {
            tl: [],
            tc: [],
            tr: [],
            ml: [],
            mc: [],
            mr: [],
            bl: [],
            bc: [],
            br: []
        },

        frameElNames: ['TL','TC','TR','ML','MC','MR','BL','BC','BR'],

        frameTpl: [
            '{%this.renderDockedItems(out,values,0);%}',
            '<tpl if="top">',
                '<tpl if="left"><div id="{fgid}TL" class="{frameCls}-tl {baseCls}-tl {baseCls}-{ui}-tl<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tl</tpl>" style="background-position: {tl}; padding-left: {frameWidth}px" role="presentation"></tpl>',
                    '<tpl if="right"><div id="{fgid}TR" class="{frameCls}-tr {baseCls}-tr {baseCls}-{ui}-tr<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tr</tpl>" style="background-position: {tr}; padding-right: {frameWidth}px" role="presentation"></tpl>',
                        '<div id="{fgid}TC" class="{frameCls}-tc {baseCls}-tc {baseCls}-{ui}-tc<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tc</tpl>" style="background-position: {tc}; height: {frameWidth}px" role="presentation"></div>',
                    '<tpl if="right"></div></tpl>',
                '<tpl if="left"></div></tpl>',
            '</tpl>',
            '<tpl if="left"><div id="{fgid}ML" class="{frameCls}-ml {baseCls}-ml {baseCls}-{ui}-ml<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-ml</tpl>" style="background-position: {ml}; padding-left: {frameWidth}px" role="presentation"></tpl>',
                '<tpl if="right"><div id="{fgid}MR" class="{frameCls}-mr {baseCls}-mr {baseCls}-{ui}-mr<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mr</tpl>" style="background-position: {mr}; padding-right: {frameWidth}px" role="presentation"></tpl>',
                    '<div id="{fgid}MC" class="{frameCls}-mc {baseCls}-mc {baseCls}-{ui}-mc<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mc</tpl>" role="presentation">',
                        '{%this.applyRenderTpl(out, values)%}',
                    '</div>',
                '<tpl if="right"></div></tpl>',
            '<tpl if="left"></div></tpl>',
            '<tpl if="bottom">',
                '<tpl if="left"><div id="{fgid}BL" class="{frameCls}-bl {baseCls}-bl {baseCls}-{ui}-bl<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bl</tpl>" style="background-position: {bl}; padding-left: {frameWidth}px" role="presentation"></tpl>',
                    '<tpl if="right"><div id="{fgid}BR" class="{frameCls}-br {baseCls}-br {baseCls}-{ui}-br<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-br</tpl>" style="background-position: {br}; padding-right: {frameWidth}px" role="presentation"></tpl>',
                        '<div id="{fgid}BC" class="{frameCls}-bc {baseCls}-bc {baseCls}-{ui}-bc<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bc</tpl>" style="background-position: {bc}; height: {frameWidth}px" role="presentation"></div>',
                    '<tpl if="right"></div></tpl>',
                '<tpl if="left"></div></tpl>',
            '</tpl>',
            '{%this.renderDockedItems(out,values,1);%}'
        ],

        frameTableTpl: [
            '{%this.renderDockedItems(out,values,0);%}',
            '<table><tbody>',
                '<tpl if="top">',
                    '<tr>',
                        '<tpl if="left"><td id="{fgid}TL" class="{frameCls}-tl {baseCls}-tl {baseCls}-{ui}-tl<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tl</tpl>" style="background-position: {tl}; padding-left:{frameWidth}px" role="presentation"></td></tpl>',
                        '<td id="{fgid}TC" class="{frameCls}-tc {baseCls}-tc {baseCls}-{ui}-tc<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tc</tpl>" style="background-position: {tc}; height: {frameWidth}px" role="presentation"></td>',
                        '<tpl if="right"><td id="{fgid}TR" class="{frameCls}-tr {baseCls}-tr {baseCls}-{ui}-tr<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tr</tpl>" style="background-position: {tr}; padding-left: {frameWidth}px" role="presentation"></td></tpl>',
                    '</tr>',
                '</tpl>',
                '<tr>',
                    '<tpl if="left"><td id="{fgid}ML" class="{frameCls}-ml {baseCls}-ml {baseCls}-{ui}-ml<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-ml</tpl>" style="background-position: {ml}; padding-left: {frameWidth}px" role="presentation"></td></tpl>',
                    '<td id="{fgid}MC" class="{frameCls}-mc {baseCls}-mc {baseCls}-{ui}-mc<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mc</tpl>" style="background-position: 0 0;" role="presentation">',
                        '{%this.applyRenderTpl(out, values)%}',
                    '</td>',
                    '<tpl if="right"><td id="{fgid}MR" class="{frameCls}-mr {baseCls}-mr {baseCls}-{ui}-mr<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mr</tpl>" style="background-position: {mr}; padding-left: {frameWidth}px" role="presentation"></td></tpl>',
                '</tr>',
                '<tpl if="bottom">',
                    '<tr>',
                        '<tpl if="left"><td id="{fgid}BL" class="{frameCls}-bl {baseCls}-bl {baseCls}-{ui}-bl<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bl</tpl>" style="background-position: {bl}; padding-left: {frameWidth}px" role="presentation"></td></tpl>',
                        '<td id="{fgid}BC" class="{frameCls}-bc {baseCls}-bc {baseCls}-{ui}-bc<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bc</tpl>" style="background-position: {bc}; height: {frameWidth}px" role="presentation"></td>',
                        '<tpl if="right"><td id="{fgid}BR" class="{frameCls}-br {baseCls}-br {baseCls}-{ui}-br<tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-br</tpl>" style="background-position: {br}; padding-left: {frameWidth}px" role="presentation"></td></tpl>',
                    '</tr>',
                '</tpl>',
            '</tbody></table>',
            '{%this.renderDockedItems(out,values,1);%}'
        ],

        /**
         * Allows addition of behavior after rendering is complete. At this stage the Component’s Element
         * will have been styled according to the configuration, will have had any configured CSS class
         * names added, and will be in the configured visibility and the configured enable state.
         *
         * @template
         * @protected
         */
        afterRender : function() {
            var me = this,
                data = {},
                protoEl = me.protoEl,
                target = me.getTargetEl(),
                item;

            me.finishRenderChildren();

            if (me.styleHtmlContent) {
                target.addCls(me.styleHtmlCls);
            }

            protoEl.writeTo(data);

            // Here we apply any styles that were set on the protoEl during the rendering phase
            // A majority of times this will not happen, but we still need to handle it

            item = data.removed;
            if (item) {
                target.removeCls(item);
            }

            item = data.cls;
            if (item.length) {
                target.addCls(item);
            }

            item = data.style;
            if (data.style) {
                target.setStyle(item);
            }

            me.protoEl = null;

            // If this is the outermost Container, lay it out as soon as it is rendered.
            if (!me.ownerCt) {
                me.updateLayout();
            }
        },

        afterFirstLayout : function(width, height) {
            var me = this,
                hasX = Ext.isDefined(me.x),
                hasY = Ext.isDefined(me.y),
                pos, xy;

            // For floaters, calculate x and y if they aren't defined by aligning
            // the sized element to the center of either the container or the ownerCt
            if (me.floating && (!hasX || !hasY)) {
                if (me.floatParent) {
                    pos = me.floatParent.getTargetEl().getViewRegion();
                    xy = me.el.getAlignToXY(me.floatParent.getTargetEl(), 'c-c');
                    pos.left = xy[0] - pos.left;
                    pos.top =  xy[1] - pos.top;
                } else {
                    xy = me.el.getAlignToXY(me.container, 'c-c');
                    pos = me.container.translatePoints(xy[0], xy[1]);
                }
                me.x = hasX ? me.x : pos.left;
                me.y = hasY ? me.y : pos.top;
                hasX = hasY = true;
            }

            if (hasX || hasY) {
                me.setPosition(me.x, me.y);
            }
            me.onBoxReady(width, height);
            if (me.hasListeners.boxready) {
                me.fireEvent('boxready', me, width, height);
            }
        },

        onBoxReady: Ext.emptyFn,

        /**
         * Sets references to elements inside the component. This applies {@link Ext.AbstractComponent#cfg-renderSelectors renderSelectors}
         * as well as {@link Ext.AbstractComponent#cfg-childEls childEls}.
         * @private
         */
        applyRenderSelectors: function() {
            var me = this,
                selectors = me.renderSelectors,
                el = me.el,
                dom = el.dom,
                selector;

            me.applyChildEls(el);

            // We still support renderSelectors. There are a few places in the framework that
            // need them and they are a documented part of the API. In fact, we support mixing
            // childEls and renderSelectors (no reason not to).
            if (selectors) {
                for (selector in selectors) {
                    if (selectors.hasOwnProperty(selector) && selectors[selector]) {
                        me[selector] = Ext.get(Ext.DomQuery.selectNode(selectors[selector], dom));
                    }
                }
            }
        },

        beforeRender: function () {
            var me = this,
                target = me.getTargetEl(),
                layout = me.getComponentLayout();

            // Just before rendering, set the frame flag if we are an always-framed component like Window or Tip.
            me.frame = me.frame || me.alwaysFramed;

            if (!layout.initialized) {
                layout.initLayout();
            }

            // Attempt to set overflow style prior to render if the targetEl can be accessed.
            // If the targetEl does not exist yet, this will take place in finishRender
            if (target) {
                target.setStyle(me.getOverflowStyle());
                me.overflowStyleSet = true;
            }

            me.setUI(me.ui);

            if (me.disabled) {
                // pass silent so the event doesn't fire the first time.
                me.disable(true);
            }
        },

        /**
         * @private
         * Called from the selected frame generation template to insert this Component's inner structure inside the framing structure.
         *
         * When framing is used, a selected frame generation template is used as the primary template of the #getElConfig instead
         * of the configured {@link Ext.AbstractComponent#renderTpl renderTpl}. The renderTpl is invoked by this method which is injected into the framing template.
         */
        doApplyRenderTpl: function(out, values) {
            // Careful! This method is bolted on to the frameTpl so all we get for context is
            // the renderData! The "this" pointer is the frameTpl instance!

            var me = values.$comp,
                tpl;

            // Don't do this if the component is already rendered:
            if (!me.rendered) {
                tpl = me.initRenderTpl();
                tpl.applyOut(values.renderData, out);
            }
        },

        /**
         * Handles autoRender.
         * Floating Components may have an ownerCt. If they are asking to be constrained, constrain them within that
         * ownerCt, and have their z-index managed locally. Floating Components are always rendered to document.body
         */
        doAutoRender: function() {
            var me = this;
            if (!me.rendered) {
                if (me.floating) {
                    me.render(document.body);
                } else {
                    me.render(Ext.isBoolean(me.autoRender) ? Ext.getBody() : me.autoRender);
                }
            }
        },

        doRenderContent: function (out, renderData) {
            // Careful! This method is bolted on to the renderTpl so all we get for context is
            // the renderData! The "this" pointer is the renderTpl instance!

            var me = renderData.$comp;

            if (me.html) {
                Ext.DomHelper.generateMarkup(me.html, out);
                delete me.html;
            }

            if (me.tpl) {
                // Make sure this.tpl is an instantiated XTemplate
                if (!me.tpl.isTemplate) {
                    me.tpl = new Ext.XTemplate(me.tpl);
                }

                if (me.data) {
                    //me.tpl[me.tplWriteMode](target, me.data);
                    me.tpl.applyOut(me.data, out);
                    delete me.data;
                }
            }
        },

        doRenderFramingDockedItems: function (out, renderData, after) {
            // Careful! This method is bolted on to the frameTpl so all we get for context is
            // the renderData! The "this" pointer is the frameTpl instance!

            var me = renderData.$comp;

            // Most components don't have dockedItems, so check for doRenderDockedItems on the
            // component (also, don't do this if the component is already rendered):
            if (!me.rendered && me.doRenderDockedItems) {
                // The "renderData" property is placed in scope for the renderTpl, but we don't
                // want to render docked items at that level in addition to the framing level:
                renderData.renderData.$skipDockedItems = true;

                // doRenderDockedItems requires the $comp property on renderData, but this is
                // set on the frameTpl's renderData as well:
                me.doRenderDockedItems.call(this, out, renderData, after);
            }
        },

        /**
         * This method visits the rendered component tree in a "top-down" order. That is, this
         * code runs on a parent component before running on a child. This method calls the
         * {@link #onRender} method of each component.
         * @param {Number} containerIdx The index into the Container items of this Component.
         *
         * @private
         */
        finishRender: function(containerIdx) {
            var me = this,
                tpl, data, contentEl, el, pre, hide;

            // We are typically called w/me.el==null as a child of some ownerCt that is being
            // rendered. We are also called by render for a normal component (w/o a configured
            // me.el). In this case, render sets me.el and me.rendering (indirectly). Lastly
            // we are also called on a component (like a Viewport) that has a configured me.el
            // (body for a Viewport) when render is called. In this case, it is not flagged as
            // "me.rendering" yet becasue it does not produce a renderTree. We use this to know
            // not to regen the renderTpl.

            if (!me.el || me.$pid) {
                if (me.container) {
                    el = me.container.getById(me.id, true);
                } else {
                    el = Ext.getDom(me.id);
                }

                if (!me.el) {
                    // Typical case: we produced the el during render
                    me.wrapPrimaryEl(el);
                } else {
                    // We were configured with an el and created a proxy, so now we can swap
                    // the proxy for me.el:
                    delete me.$pid;

                    if (!me.el.dom) {
                        // make sure me.el is an Element
                        me.wrapPrimaryEl(me.el);
                    }
                    el.parentNode.insertBefore(me.el.dom, el);
                    Ext.removeNode(el); // remove placeholder el
                    // TODO - what about class/style?
                }
            } else if (!me.rendering) {
                // We were configured with an el and then told to render (e.g., Viewport). We
                // need to generate the proper DOM. Insert first because the layout system
                // insists that child Component elements indices match the Component indices.
                tpl = me.initRenderTpl();
                if (tpl) {
                    data = me.initRenderData();
                    tpl.insertFirst(me.getTargetEl(), data);
                }
            }
            // else we are rendering

            if (!me.container) {
                // top-level rendered components will already have me.container set up
                me.container = Ext.get(me.el.dom.parentNode);
            }

            if (me.ctCls) {
                me.container.addCls(me.ctCls);
            }

            // Sets the rendered flag and clears the redering flag
            me.onRender(me.container, containerIdx);

            // If we could not access a target protoEl in bewforeRender, we have to set the overflow styles here.
            if (!me.overflowStyleSet) {
                me.getTargetEl().setStyle(me.getOverflowStyle());
            }

            // Tell the encapsulating element to hide itself in the way the Component is configured to hide
            // This means DISPLAY, VISIBILITY or OFFSETS.
            me.el.setVisibilityMode(Ext.Element[me.hideMode.toUpperCase()]);

            if (me.overCls) {
                me.el.hover(me.addOverCls, me.removeOverCls, me);
            }

            if (me.hasListeners.render) {
                me.fireEvent('render', me);
            }

            if (me.contentEl) {
                pre = Ext.baseCSSPrefix;
                hide = pre + 'hide-';
                contentEl = Ext.get(me.contentEl);
                contentEl.removeCls([pre+'hidden', hide+'display', hide+'offsets', hide+'nosize']);
                me.getTargetEl().appendChild(contentEl.dom);
            }

            me.afterRender(); // this can cause a layout
            if (me.hasListeners.afterrender) {
                me.fireEvent('afterrender', me);
            }
            me.initEvents();

            if (me.hidden) {
                // Hiding during the render process should not perform any ancillary
                // actions that the full hide process does; It is not hiding, it begins in a hidden state.'
                // So just make the element hidden according to the configured hideMode
                me.el.hide();
            }
        },

        finishRenderChildren: function () {
            var layout = this.getComponentLayout();

            layout.finishRender();
        },

        getElConfig : function() {
            var me = this,
                autoEl = me.autoEl,
                frameInfo = me.getFrameInfo(),
                config = {
                    tag: 'div',
                    tpl: frameInfo ? me.initFramingTpl(frameInfo.table) : me.initRenderTpl()
                },
                i, frameElNames, len, suffix, frameGenId;

            me.initStyles(me.protoEl);
            me.protoEl.writeTo(config);
            me.protoEl.flush();

            if (Ext.isString(autoEl)) {
                config.tag = autoEl;
            } else {
                Ext.apply(config, autoEl); // harmless if !autoEl
            }

            // It's important to assign the id here as an autoEl.id could have been (wrongly) applied and this would get things out of sync
            config.id = me.id;

            if (config.tpl) {
                // Use the framingTpl as the main content creating template. It will call out to this.applyRenderTpl(out, values)
                if (frameInfo) {
                    frameElNames = me.frameElNames;
                    len = frameElNames.length;
                    frameGenId = me.id + '-frame1';

                    me.frameGenId = 1;
                    config.tplData = Ext.apply({}, {
                        $comp:      me,
                        fgid:       frameGenId,
                        ui:         me.ui,
                        uiCls:      me.uiCls,
                        frameCls:   me.frameCls,
                        baseCls:    me.baseCls,
                        frameWidth: frameInfo.maxWidth,
                        top:        !!frameInfo.top,
                        left:       !!frameInfo.left,
                        right:      !!frameInfo.right,
                        bottom:     !!frameInfo.bottom,
                        renderData: me.initRenderData()
                    }, me.getFramePositions(frameInfo));

                    // Add the childEls for each of the frame elements
                    for (i = 0; i < len; i++) {
                        suffix = frameElNames[i];
                        me.addChildEls({ name: 'frame' + suffix, id: frameGenId + suffix });
                    }

                    // Panel must have a frameBody
                    me.addChildEls({
                        name: 'frameBody',
                        id: frameGenId + 'MC'
                    });
                } else {
                    config.tplData = me.initRenderData();
                }
            }

            return config;
        },

        // Create the framingTpl from the string.
        // Poke in a reference to applyRenderTpl(frameInfo, out)
        initFramingTpl: function(table) {
            var tpl = table ? this.getTpl('frameTableTpl') : this.getTpl('frameTpl');

            if (tpl && !tpl.applyRenderTpl) {
                this.setupFramingTpl(tpl);
            }

            return tpl;
        },

        /**
         * @private
         * Inject a reference to the function which applies the render template into the framing template. The framing template
         * wraps the content.
         */
        setupFramingTpl: function(frameTpl) {
            frameTpl.applyRenderTpl = this.doApplyRenderTpl;
            frameTpl.renderDockedItems = this.doRenderFramingDockedItems;
        },

        /**
         * This function takes the position argument passed to onRender and returns a
         * DOM element that you can use in the insertBefore.
         * @param {String/Number/Ext.dom.Element/HTMLElement} position Index, element id or element you want
         * to put this component before.
         * @return {HTMLElement} DOM element that you can use in the insertBefore
         */
        getInsertPosition: function(position) {
            // Convert the position to an element to insert before
            if (position !== undefined) {
                if (Ext.isNumber(position)) {
                    position = this.container.dom.childNodes[position];
                }
                else {
                    position = Ext.getDom(position);
                }
            }

            return position;
        },

        getRenderTree: function() {
            var me = this;

            if (!me.hasListeners.beforerender || me.fireEvent('beforerender', me) !== false) {
                me.beforeRender();

                // Flag to let the layout's finishRenderItems and afterFinishRenderItems
                // know which items to process
                me.rendering = true;

                if (me.el) {
                    // Since we are producing a render tree, we produce a "proxy el" that will
                    // sit in the rendered DOM precisely where me.el belongs. We replace the
                    // proxy el in the finishRender phase.
                    return {
                        tag: 'div',
                        id: (me.$pid = Ext.id())
                    };
                }

                return me.getElConfig();
            }

            return null;
        },

        initContainer: function(container) {
            var me = this;

            // If you render a component specifying the el, we get the container
            // of the el, and make sure we dont move the el around in the dom
            // during the render
            if (!container && me.el) {
                container = me.el.dom.parentNode;
                me.allowDomMove = false;
            }
            me.container = container.dom ? container : Ext.get(container);

            return me.container;
        },

        /**
         * Initialized the renderData to be used when rendering the renderTpl.
         * @return {Object} Object with keys and values that are going to be applied to the renderTpl
         * @private
         */
        initRenderData: function() {
            var me = this;

            return Ext.apply({
                $comp: me,
                id: me.id,
                ui: me.ui,
                uiCls: me.uiCls,
                baseCls: me.baseCls,
                componentCls: me.componentCls,
                frame: me.frame
            }, me.renderData);
        },

        /**
         * Initializes the renderTpl.
         * @return {Ext.XTemplate} The renderTpl XTemplate instance.
         * @private
         */
        initRenderTpl: function() {
            var tpl = this.getTpl('renderTpl');

            if (tpl && !tpl.renderContent) {
                this.setupRenderTpl(tpl);
            }

            return tpl;
        },

        /**
         * Template method called when this Component's DOM structure is created.
         *
         * At this point, this Component's (and all descendants') DOM structure *exists* but it has not
         * been layed out (positioned and sized).
         *
         * Subclasses which override this to gain access to the structure at render time should
         * call the parent class's method before attempting to access any child elements of the Component.
         *
         * @param {Ext.core.Element} parentNode The parent Element in which this Component's encapsulating element is contained.
         * @param {Number} containerIdx The index within the parent Container's child collection of this Component.
         *
         * @template
         * @protected
         */
        onRender: function(parentNode, containerIdx) {
            var me = this,
                x = me.x,
                y = me.y,
                lastBox, width, height,
                el = me.el,
                body = Ext.getBody().dom;

            // Wrap this Component in a reset wraper if necessary
            if (Ext.scopeResetCSS && !me.ownerCt) {
                // If this component's el is the body element, we add the reset class to the html tag
                if (el.dom === body) {
                    el.parent().addCls(Ext.resetCls);
                }
                // Otherwise, we ensure that there is a wrapper which has the reset class
                else {
                    // Floaters rendered into the body can all be bumped into the common reset element
                    if (me.floating && me.el.dom.parentNode === body) {
                        Ext.resetElement.appendChild(me.el);
                    }
                    // Else we wrap this element in an element that adds the reset class.
                    else {
                        // Wrap this Component's DOM with a reset structure as determined in EventManager's initExtCss closure.
                        me.resetEl = el.wrap(Ext.resetElementSpec, false, Ext.supports.CSS3LinearGradient ? undefined : '*');
                    }
                }
            }

            me.applyRenderSelectors();

            // Flag set on getRenderTree to flag to the layout's postprocessing routine that
            // the Component is in the process of being rendered and needs postprocessing.
            delete me.rendering;

            me.rendered = true;

            // We need to remember these to avoid writing them during the initial layout:
            lastBox = null;

            if (x !== undefined) {
                lastBox = lastBox || {};
                lastBox.x = x;
            }
            if (y !== undefined) {
                lastBox = lastBox || {};
                lastBox.y = y;
            }
            // Framed components need their width/height to apply to the frame, which is
            // best handled in layout at present.
            // If we're using the content box model, we also cannot assign initial sizes since we do not know the border widths to subtract
            if (!me.getFrameInfo() && Ext.isBorderBox) {
                width = me.width;
                height = me.height;

                if (typeof width == 'number') {
                    lastBox = lastBox || {};
                    lastBox.width = width;
                }
                if (typeof height == 'number') {
                    lastBox = lastBox || {};
                    lastBox.height = height;
                }
            }

            me.lastBox = me.el.lastBox = lastBox;
        },

        /**
         * Renders the Component into the passed HTML element.
         *
         * **If you are using a {@link Ext.container.Container Container} object to house this
         * Component, then do not use the render method.**
         *
         * A Container's child Components are rendered by that Container's
         * {@link Ext.container.Container#layout layout} manager when the Container is first rendered.
         *
         * If the Container is already rendered when a new child Component is added, you may need to call
         * the Container's {@link Ext.container.Container#doLayout doLayout} to refresh the view which
         * causes any unrendered child Components to be rendered. This is required so that you can add
         * multiple child components if needed while only refreshing the layout once.
         *
         * When creating complex UIs, it is important to remember that sizing and positioning
         * of child items is the responsibility of the Container's {@link Ext.container.Container#layout layout}
         * manager.  If you expect child items to be sized in response to user interactions, you must
         * configure the Container with a layout manager which creates and manages the type of layout you
         * have in mind.
         *
         * **Omitting the Container's {@link Ext.Container#layout layout} config means that a basic
         * layout manager is used which does nothing but render child components sequentially into the
         * Container. No sizing or positioning will be performed in this situation.**
         *
         * @param {Ext.Element/HTMLElement/String} [container] The element this Component should be
         * rendered into. If it is being created from existing markup, this should be omitted.
         * @param {String/Number} [position] The element ID or DOM node index within the container **before**
         * which this component will be inserted (defaults to appending to the end of the container)
         */
        render: function(container, position) {
            var me = this,
                el = me.el && (me.el = Ext.get(me.el)), // ensure me.el is wrapped
                vetoed,
                tree,
                nextSibling;

            Ext.suspendLayouts();

            container = me.initContainer(container);

            nextSibling = me.getInsertPosition(position);

            if (!el) {
                tree = me.getRenderTree();
                if (me.ownerLayout && me.ownerLayout.transformItemRenderTree) {
                    tree = me.ownerLayout.transformItemRenderTree(tree);
                }

                // tree will be null if a beforerender listener returns false
                if (tree) {
                    if (nextSibling) {
                        el = Ext.DomHelper.insertBefore(nextSibling, tree);
                    } else {
                        el = Ext.DomHelper.append(container, tree);
                    }

                    me.wrapPrimaryEl(el);
                }
            } else {
                if (!me.hasListeners.beforerender || me.fireEvent('beforerender', me) !== false) {
                    // Set configured styles on pre-rendered Component's element
                    me.initStyles(el);
                    if (me.allowDomMove !== false) {
                        //debugger; // TODO
                        if (nextSibling) {
                            container.dom.insertBefore(el.dom, nextSibling);
                        } else {
                            container.dom.appendChild(el.dom);
                        }
                    }
                } else {
                    vetoed = true;
                }
            }

            if (el && !vetoed) {
                me.finishRender(position);
            }

            Ext.resumeLayouts(!container.isDetachedBody);
        },

        /**
         * Ensures that this component is attached to `document.body`. If the component was
         * rendered to {@link Ext#getDetachedBody}, then it will be appended to `document.body`.
         * Any configured position is also restored.
         * @param {Boolean} [runLayout=false] True to run the component's layout.
         */
        ensureAttachedToBody: function (runLayout) {
            var comp = this,
                body;

            while (comp.ownerCt) {
                comp = comp.ownerCt;
            }

            if (comp.container.isDetachedBody) {
                comp.container = body = Ext.resetElement;
                body.appendChild(comp.el.dom);
                if (runLayout) {
                    comp.updateLayout();
                }
                if (typeof comp.x == 'number' || typeof comp.y == 'number') {
                    comp.setPosition(comp.x, comp.y);
                }
            }
        },

        setupRenderTpl: function (renderTpl) {
            renderTpl.renderBody = renderTpl.renderContent = this.doRenderContent;
        },

        wrapPrimaryEl: function (dom) {
            this.el = Ext.get(dom, true);
        },

        /**
         * @private
         */
        initFrame : function() {
            if (Ext.supports.CSS3BorderRadius || !this.frame) {
                return;
            }

            var me = this,
                frameInfo = me.getFrameInfo(),
                frameWidth, frameTpl, frameGenId,
                i,
                frameElNames = me.frameElNames,
                len = frameElNames.length,
                suffix;

            if (frameInfo) {
                frameWidth = frameInfo.maxWidth;
                frameTpl = me.getFrameTpl(frameInfo.table);

                // since we render id's into the markup and id's NEED to be unique, we have a
                // simple strategy for numbering their generations.
                me.frameGenId = frameGenId = (me.frameGenId || 0) + 1;
                frameGenId = me.id + '-frame' + frameGenId;

                // Here we render the frameTpl to this component. This inserts the 9point div or the table framing.
                frameTpl.insertFirst(me.el, Ext.apply({
                    $comp:      me,
                    fgid:       frameGenId,
                    ui:         me.ui,
                    uiCls:      me.uiCls,
                    frameCls:   me.frameCls,
                    baseCls:    me.baseCls,
                    frameWidth: frameWidth,
                    top:        !!frameInfo.top,
                    left:       !!frameInfo.left,
                    right:      !!frameInfo.right,
                    bottom:     !!frameInfo.bottom
                }, me.getFramePositions(frameInfo)));

                // The frameBody is returned in getTargetEl, so that layouts render items to the correct target.
                me.frameBody = me.el.down('.' + me.frameCls + '-mc');

                // Clean out the childEls for the old frame elements (the majority of the els)
                me.removeChildEls(function (c) {
                    return c.id && me.frameIdRegex.test(c.id);
                });

                // Grab references to the childEls for each of the new frame elements
                for (i = 0; i < len; i++) {
                    suffix = frameElNames[i];
                    me['frame' + suffix] = me.el.getById(frameGenId + suffix);
                }
            }
        },

        updateFrame: function() {
            if (Ext.supports.CSS3BorderRadius || !this.frame) {
                return;
            }

            var me = this,
                wasTable = this.frameSize && this.frameSize.table,
                oldFrameTL = this.frameTL,
                oldFrameBL = this.frameBL,
                oldFrameML = this.frameML,
                oldFrameMC = this.frameMC,
                newMCClassName;

            this.initFrame();

            if (oldFrameMC) {
                if (me.frame) {

                    // Store the class names set on the new MC
                    newMCClassName = this.frameMC.dom.className;

                    // Framing elements have been selected in initFrame, no need to run applyRenderSelectors
                    // Replace the new mc with the old mc
                    oldFrameMC.insertAfter(this.frameMC);
                    this.frameMC.remove();

                    // Restore the reference to the old frame mc as the framebody
                    this.frameBody = this.frameMC = oldFrameMC;

                    // Apply the new mc classes to the old mc element
                    oldFrameMC.dom.className = newMCClassName;

                    // Remove the old framing
                    if (wasTable) {
                        me.el.query('> table')[1].remove();
                    }
                    else {
                        if (oldFrameTL) {
                            oldFrameTL.remove();
                        }
                        if (oldFrameBL) {
                            oldFrameBL.remove();
                        }
                        if (oldFrameML) {
                            oldFrameML.remove();
                        }
                    }
                }
            }
            else if (me.frame) {
                this.applyRenderSelectors();
            }
        },

        /**
         * @private
         * On render, reads an encoded style attribute, "background-position" from the style of this Component's element.
         * This information is memoized based upon the CSS class name of this Component's element.
         * Because child Components are rendered as textual HTML as part of the topmost Container, a dummy div is inserted
         * into the document to receive the document element's CSS class name, and therefore style attributes.
         */
        getFrameInfo: function() {
            // If native framing can be used, or this component is not going to be framed, then do not attempt to read CSS framing info.
            if (Ext.supports.CSS3BorderRadius || !this.frame) {
                return false;
            }

            var me = this,
                frameInfoCache = me.frameInfoCache,
                el = me.el || me.protoEl,
                cls = el.dom ? el.dom.className : el.classList.join(' '),
                frameInfo = frameInfoCache[cls],
                styleEl, left, top, info;

            if (frameInfo == null) {
                // Get the singleton frame style proxy with our el class name stamped into it.
                styleEl = Ext.fly(me.getStyleProxy(cls), 'frame-style-el');
                left = styleEl.getStyle('background-position-x');
                top = styleEl.getStyle('background-position-y');

                // Some browsers don't support background-position-x and y, so for those
                // browsers let's split background-position into two parts.
                if (!left && !top) {
                    info = styleEl.getStyle('background-position').split(' ');
                    left = info[0];
                    top = info[1];
                }

                frameInfo = me.calculateFrame(left, top);

                if (frameInfo) {
                    // Just to be sure we set the background image of the el to none.
                    el.setStyle('background-image', 'none');
                }

                //<debug error>
                // This happens when you set frame: true explicitly without using the x-frame mixin in sass.
                // This way IE can't figure out what sizes to use and thus framing can't work.
                if (me.frame === true && !frameInfo) {
                    Ext.log.error('You have set frame: true explicity on this component (' + me.getXType() + ') and it ' +
                            'does not have any framing defined in the CSS template. In this case IE cannot figure out ' +
                            'what sizes to use and thus framing on this component will be disabled.');
                }
                //</debug>

                frameInfoCache[cls] = frameInfo;
            }

            me.frame = !!frameInfo;
            me.frameSize = frameInfo;

            return frameInfo;
        },

        calculateFrame: function(left, top){
            // We actually pass a string in the form of '[type][tl][tr]px [direction][br][bl]px' as
            // the background position of this.el from the CSS to indicate to IE that this component needs
            // framing. We parse it here.
            if (!(parseInt(left, 10) >= 1000000 && parseInt(top, 10) >= 1000000)) {
                return false;
            }
            var max = Math.max,
                tl = parseInt(left.substr(3, 2), 10),
                tr = parseInt(left.substr(5, 2), 10),
                br = parseInt(top.substr(3, 2), 10),
                bl = parseInt(top.substr(5, 2), 10),
                frameInfo = {
                    // Table markup starts with 110, div markup with 100.
                    table: left.substr(0, 3) == '110',

                    // Determine if we are dealing with a horizontal or vertical component
                    vertical: top.substr(0, 3) == '110',

                    // Get and parse the different border radius sizes
                    top:    max(tl, tr),
                    right:  max(tr, br),
                    bottom: max(bl, br),
                    left:   max(tl, bl)
                };

            frameInfo.maxWidth = max(frameInfo.top, frameInfo.right, frameInfo.bottom, frameInfo.left);
            frameInfo.width = frameInfo.left + frameInfo.right;
            frameInfo.height = frameInfo.top + frameInfo.bottom;
            return frameInfo;
        },

        /**
         * @private
         * Returns an offscreen div with the same class name as the element this is being rendered.
         * This is because child item rendering takes place in a detached div which, being not part of the document, has no styling.
         */
        getStyleProxy: function(cls) {
            var result = this.styleProxyEl || (Ext.AbstractComponent.prototype.styleProxyEl = Ext.resetElement.createChild({
                    style: {
                        position: 'absolute',
                        top: '-10000px'
                    }
                }, null, true));

            result.className = cls;
            return result;
        },

        getFramePositions: function(frameInfo) {
            var me = this,
                frameWidth = frameInfo.maxWidth,
                dock = me.dock,
                positions, tc, bc, ml, mr;

            if (frameInfo.vertical) {
                tc = '0 -' + (frameWidth * 0) + 'px';
                bc = '0 -' + (frameWidth * 1) + 'px';

                if (dock && dock == "right") {
                    tc = 'right -' + (frameWidth * 0) + 'px';
                    bc = 'right -' + (frameWidth * 1) + 'px';
                }

                positions = {
                    tl: '0 -' + (frameWidth * 0) + 'px',
                    tr: '0 -' + (frameWidth * 1) + 'px',
                    bl: '0 -' + (frameWidth * 2) + 'px',
                    br: '0 -' + (frameWidth * 3) + 'px',

                    ml: '-' + (frameWidth * 1) + 'px 0',
                    mr: 'right 0',

                    tc: tc,
                    bc: bc
                };
            } else {
                ml = '-' + (frameWidth * 0) + 'px 0';
                mr = 'right 0';

                if (dock && dock == "bottom") {
                    ml = 'left bottom';
                    mr = 'right bottom';
                }

                positions = {
                    tl: '0 -' + (frameWidth * 2) + 'px',
                    tr: 'right -' + (frameWidth * 3) + 'px',
                    bl: '0 -' + (frameWidth * 4) + 'px',
                    br: 'right -' + (frameWidth * 5) + 'px',

                    ml: ml,
                    mr: mr,

                    tc: '0 -' + (frameWidth * 0) + 'px',
                    bc: '0 -' + (frameWidth * 1) + 'px'
                };
            }

            return positions;
        },

        /**
         * @private
         */
        getFrameTpl : function(table) {
            return this.getTpl(table ? 'frameTableTpl' : 'frameTpl');
        },

        // Cache the frame information object so as not to cause style recalculations
        frameInfoCache: {}
    });