    /*!
     * Ext JS Library 3.3.0
     * Copyright(c) 2006-2010 Ext JS, Inc.
     * licensing@extjs.com
     * http://www.extjs.com/license
     */
    /**
     * @class Ext.Element
     */
    Ext.Element.addMethods(
        function() {
            var VISIBILITY      = "visibility",
                DISPLAY         = "display",
                HIDDEN          = "hidden",
                NONE            = "none",
                XMASKED         = "x-masked",
                XMASKEDRELATIVE = "x-masked-relative",
                data            = Ext.Element.data;

            return {
                /**
                 * Checks whether the element is currently visible using both visibility and display properties.
                 * @param {Boolean} deep (optional) True to walk the dom and see if parent elements are hidden (defaults to false)
                 * @return {Boolean} True if the element is currently visible, else false
                 */
                isVisible : function(deep) {
                    var vis = !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE),
                        p   = this.dom.parentNode;

                    if (deep !== true || !vis) {
                        return vis;
                    }

                    while (p && !(/^body/i.test(p.tagName))) {
                        if (!Ext.fly(p, '_isVisible').isVisible()) {
                            return false;
                        }
                        p = p.parentNode;
                    }
                    return true;
                },

                /**
                 * Returns true if display is not "none"
                 * @return {Boolean}
                 */
                isDisplayed : function() {
                    return !this.isStyle(DISPLAY, NONE);
                },

                /**
                 * Convenience method for setVisibilityMode(Element.DISPLAY)
                 * @param {String} display (optional) What to set display to when visible
                 * @return {Ext.Element} this
                 */
                enableDisplayMode : function(display) {
                    this.setVisibilityMode(Ext.Element.DISPLAY);

                    if (!Ext.isEmpty(display)) {
                        data(this.dom, 'originalDisplay', display);
                    }

                    return this;
                },

                /**
                 * Puts a mask over this element to disable user interaction. Requires core.css.
                 * This method can only be applied to elements which accept child nodes.
                 * @param {String} msg (optional) A message to display in the mask
                 * @param {String} msgCls (optional) A css class to apply to the msg element
                 * @return {Element} The mask element
                 */
                mask : function(msg, msgCls) {
                    var me  = this,
                        dom = me.dom,
                        dh  = Ext.DomHelper,
                        EXTELMASKMSG = "ext-el-mask-msg",
                        el,
                        mask;

                    if (!(/^body/i.test(dom.tagName) && me.getStyle('position') == 'static')) {
                        me.addClass(XMASKEDRELATIVE);
                    }
                    if (el = data(dom, 'maskMsg')) {
                        el.remove();
                    }
                    if (el = data(dom, 'mask')) {
                        el.remove();
                    }

                    mask = dh.append(dom, {cls : "ext-el-mask"}, true);
                    data(dom, 'mask', mask);

                    me.addClass(XMASKED);
                    mask.setDisplayed(true);

                    if (typeof msg == 'string') {
                        var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true);
                        data(dom, 'maskMsg', mm);
                        mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG;
                        mm.dom.firstChild.innerHTML = msg;
                        mm.setDisplayed(true);
                        mm.center(me);
                    }

                    // ie will not expand full height automatically
                    if (Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto') {
                        mask.setSize(undefined, me.getHeight());
                    }

                    return mask;
                },

                /**
                 * Removes a previously applied mask.
                 */
                unmask : function() {
                    var me      = this,
                        dom     = me.dom,
                        mask    = data(dom, 'mask'),
                        maskMsg = data(dom, 'maskMsg');

                    if (mask) {
                        if (maskMsg) {
                            maskMsg.remove();
                            data(dom, 'maskMsg', undefined);
                        }

                        mask.remove();
                        data(dom, 'mask', undefined);
                        me.removeClass([XMASKED, XMASKEDRELATIVE]);
                    }
                },

                /**
                 * Returns true if this element is masked
                 * @return {Boolean}
                 */
                isMasked : function() {
                    var m = data(this.dom, 'mask');
                    return m && m.isVisible();
                },

                /**
                 * Creates an iframe shim for this element to keep selects and other windowed objects from
                 * showing through.
                 * @return {Ext.Element} The new shim element
                 */
                createShim : function() {
                    var el = document.createElement('iframe'),
                        shim;

                    el.frameBorder = '0';
                    el.className = 'ext-shim';
                    el.src = Ext.SSL_SECURE_URL;
                    shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
                    shim.autoBoxAdjust = false;
                    return shim;
                }
            };
        }()
    );