    /**
     * @class Ext.dom.Element
     */
    Ext.dom.Element.addStatics({
        unitRe: /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
        camelRe: /(-[a-z])/gi,
        cssRe: /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,
        opacityRe: /alpha\(opacity=(.*)\)/i,
        propertyCache: {},
        defaultUnit: "px",
        borders: {l: 'border-left-width', r: 'border-right-width', t: 'border-top-width', b: 'border-bottom-width'},
        paddings: {l: 'padding-left', r: 'padding-right', t: 'padding-top', b: 'padding-bottom'},
        margins: {l: 'margin-left', r: 'margin-right', t: 'margin-top', b: 'margin-bottom'},

        /**
         * Test if size has a unit, otherwise appends the passed unit string, or the default for this Element.
         * @param size {Object} The size to set
         * @param units {String} The units to append to a numeric size value
         * @private
         * @static
         */
        addUnits: function(size, units) {
            // Most common case first: Size is set to a number
            if (Ext.isNumber(size)) {
                return size + (units || this.defaultUnit || 'px');
            }

            // Size set to a value which means "auto"
            if (size === "" || size == "auto" || size === undefined || size === null) {
                return size || '';
            }

            // Otherwise, warn if it's not a valid CSS measurement
            if (!this.unitRe.test(size)) {
                //<debug>
                if (Ext.isDefined(Ext.global.console)) {
                    Ext.global.console.warn("Warning, size detected as NaN on Element.addUnits.");
                }
                //</debug>
                return size || '';
            }
            return size;
        },

        /**
         * @static
         * @private
         */
        isAncestor: function(p, c) {
            var ret = false;

            p = Ext.getDom(p);
            c = Ext.getDom(c);
            if (p && c) {
                if (p.contains) {
                    return p.contains(c);
                } else if (p.compareDocumentPosition) {
                    return !!(p.compareDocumentPosition(c) & 16);
                } else {
                    while ((c = c.parentNode)) {
                        ret = c == p || ret;
                    }
                }
            }
            return ret;
        },

        /**
         * Parses a number or string representing margin sizes into an object. Supports CSS-style margin declarations
         * (e.g. 10, "10", "10 10", "10 10 10" and "10 10 10 10" are all valid options and would return the same result)
         * @static
         * @param {Number/String} box The encoded margins
         * @return {Object} An object with margin sizes for top, right, bottom and left
         */
        parseBox: function(box) {
            if (typeof box != 'string') {
                box = box.toString();
            }

            var parts = box.split(' '),
                ln = parts.length;

            if (ln == 1) {
                parts[1] = parts[2] = parts[3] = parts[0];
            }
            else if (ln == 2) {
                parts[2] = parts[0];
                parts[3] = parts[1];
            }
            else if (ln == 3) {
                parts[3] = parts[1];
            }

            return {
                top: parseFloat(parts[0]) || 0,
                right: parseFloat(parts[1]) || 0,
                bottom: parseFloat(parts[2]) || 0,
                left: parseFloat(parts[3]) || 0
            };
        },

        /**
         * Parses a number or string representing margin sizes into an object. Supports CSS-style margin declarations
         * (e.g. 10, "10", "10 10", "10 10 10" and "10 10 10 10" are all valid options and would return the same result)
         * @static
         * @param {Number/String} box The encoded margins
         * @param {String} units The type of units to add
         * @return {String} An string with unitized (px if units is not specified) metrics for top, right, bottom and left
         */
        unitizeBox: function(box, units) {
            var a = this.addUnits,
                b = this.parseBox(box);

            return a(b.top, units) + ' ' +
                a(b.right, units) + ' ' +
                a(b.bottom, units) + ' ' +
                a(b.left, units);

        },

        // private
        camelReplaceFn: function(m, a) {
            return a.charAt(1).toUpperCase();
        },

        /**
         * Normalizes CSS property keys from dash delimited to camel case JavaScript Syntax.
         * For example:
         *
         * - border-width -> borderWidth
         * - padding-top -> paddingTop
         *
         * @static
         * @param {String} prop The property to normalize
         * @return {String} The normalized string
         */
        normalize: function(prop) {
            // TODO: Mobile optimization?
    //        if (prop == 'float') {
    //            prop = Ext.supports.Float ? 'cssFloat' : 'styleFloat';
    //        }
            return this.propertyCache[prop] || (this.propertyCache[prop] = prop.replace(this.camelRe, this.camelReplaceFn));
        },

        /**
         * Returns the top Element that is located at the passed coordinates
         * @static
         * @param {Number} x The x coordinate
         * @param {Number} y The y coordinate
         * @return {String} The found Element
         */
        fromPoint: function(x, y) {
            return Ext.get(document.elementFromPoint(x, y));
        },

        /**
         * Converts a CSS string into an object with a property for each style.
         *
         * The sample code below would return an object with 2 properties, one
         * for background-color and one for color.
         *
         *     var css = 'background-color: red;color: blue; ';
         *     console.log(Ext.dom.Element.parseStyles(css));
         *
         * @static
         * @param {String} styles A CSS string
         * @return {Object} styles
         */
        parseStyles: function(styles) {
            var out = {},
                cssRe = this.cssRe,
                matches;

            if (styles) {
                // Since we're using the g flag on the regex, we need to set the lastIndex.
                // This automatically happens on some implementations, but not others, see:
                // http://stackoverflow.com/questions/2645273/javascript-regular-expression-literal-persists-between-function-calls
                // http://blog.stevenlevithan.com/archives/fixing-javascript-regexp
                cssRe.lastIndex = 0;
                while ((matches = cssRe.exec(styles))) {
                    out[matches[1]] = matches[2];
                }
            }
            return out;
        }
    });

    //<deprecated product=touch since=2.0>
    Ext.dom.Element.addStatics({
        /**
         * Serializes a DOM form into a url encoded string
         * @deprecated 2.0.0 This method is no longer supported, please see {@link Ext.form.Panel#getValues} instead
         * @param {Object} form The form
         * @return {String} The url encoded form
         */
        serializeForm: function(form) {
            var fElements = form.elements || (document.forms[form] || Ext.getDom(form)).elements,
                hasSubmit = false,
                encoder = encodeURIComponent,
                name,
                data = '',
                type,
                hasValue;

            Ext.each(fElements, function(element) {
                name = element.name;
                type = element.type;

                if (!element.disabled && name) {
                    if (/select-(one|multiple)/i.test(type)) {
                        Ext.each(element.options, function(opt) {
                            if (opt.selected) {
                                hasValue = opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified;
                                data += Ext.String.format("{0}={1}&", encoder(name), encoder(hasValue ? opt.value : opt.text));
                            }
                        });
                    } else if (!(/file|undefined|reset|button/i.test(type))) {
                        if (!(/radio|checkbox/i.test(type) && !element.checked) && !(type == 'submit' && hasSubmit)) {
                            data += encoder(name) + '=' + encoder(element.value) + '&';
                            hasSubmit = /submit/i.test(type);
                        }
                    }
                }
            });

            return data.substr(0, data.length - 1);
        },

        /**
         * Retrieves the document height
         * @deprecated 2.0.0 This method is no longer supported, please use {@link Ext.Viewport#getWindowHeight} instead
         * @static
         * @return {Number} documentHeight
         */
        getDocumentHeight: function() {
            //<debug warn>
            Ext.Logger.deprecate("Ext.Element.getDocumentHeight() is no longer supported. " +
                "Please use Ext.Viewport#getWindowHeight() instead", this);
            //</debug>
            return Math.max(!Ext.isStrict ? document.body.scrollHeight : document.documentElement.scrollHeight, this.getViewportHeight());
        },

        /**
         * Retrieves the document width
         * @deprecated 2.0.0 This method is no longer supported, please use {@link Ext.Viewport#getWindowWidth} instead
         * @static
         * @return {Number} documentWidth
         */
        getDocumentWidth: function() {
            //<debug warn>
            Ext.Logger.deprecate("Ext.Element.getDocumentWidth() is no longer supported. " +
                "Please use Ext.Viewport#getWindowWidth() instead", this);
            //</debug>
            return Math.max(!Ext.isStrict ? document.body.scrollWidth : document.documentElement.scrollWidth, this.getViewportWidth());
        },

        /**
         * Retrieves the viewport height of the window.
         * @deprecated 2.0.0 This method is no longer supported, please use {@link Ext.Viewport#getWindowHeight} instead
         * @static
         * @return {Number} viewportHeight
         */
        getViewportHeight: function() {
            //<debug warn>
            Ext.Logger.deprecate("Ext.Element.getDocumentHeight() is no longer supported. " +
                "Please use Ext.Viewport#getWindowHeight() instead", this);
            //</debug>
            return window.innerHeight;
        },

        /**
         * Retrieves the viewport width of the window.
         * @deprecated 2.0.0 This method is no longer supported, please use {@link Ext.Viewport#getWindowWidth} instead
         * @static
         * @return {Number} viewportWidth
         */
        getViewportWidth: function() {
            //<debug warn>
            Ext.Logger.deprecate("Ext.Element.getDocumentWidth() is no longer supported. " +
                "Please use Ext.Viewport#getWindowWidth() instead", this);
            //</debug>
            return window.innerWidth;
        },

        /**
         * Retrieves the viewport size of the window.
         * @deprecated 2.0.0 This method is no longer supported, please use {@link Ext.Viewport#getSize} instead
         * @static
         * @return {Object} object containing width and height properties
         */
        getViewSize: function() {
            //<debug warn>
            Ext.Logger.deprecate("Ext.Element.getViewSize() is no longer supported. " +
                "Please use Ext.Viewport#getSize() instead", this);
            //</debug>
            return {
                width: window.innerWidth,
                height: window.innerHeight
            };
        },

        /**
         * Retrieves the current orientation of the window. This is calculated by
         * determing if the height is greater than the width.
         * @deprecated 2.0.0 This method is no longer supported, please use {@link Ext.Viewport#getOrientation} instead
         * @static
         * @return {String} Orientation of window: 'portrait' or 'landscape'
         */
        getOrientation: function() {
            //<debug warn>
            Ext.Logger.deprecate("Ext.Element.getOrientation() is no longer supported. " +
                "Please use Ext.Viewport#getOrientation() instead", this);
            //</debug>
            if (Ext.supports.OrientationChange) {
                return (window.orientation == 0) ? 'portrait' : 'landscape';
            }

            return (window.innerHeight > window.innerWidth) ? 'portrait' : 'landscape';
        }
    });
    //</deprecated>