    /**
     * @class Ext.Element
     */
    Ext.applyIf(Ext.Element, {
        unitRe: /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
        camelRe: /(-[a-z])/gi,
        opacityRe: /alpha\(opacity=(.*)\)/i,
        cssRe: /([a-z0-9-]+)\s*:\s*([^;\s]+(?:\s*[^;\s]+)*);?/gi,
        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'},

        // Reference the prototype's version of the method. Signatures are identical.
        addUnits : Ext.Element.prototype.addUnits,

        /**
         * 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 (Ext.isObject(box)) {
                return {
                    top: box.top || 0,
                    right: box.right || 0,
                    bottom: box.bottom || 0,
                    left: box.left || 0
                };
            } else {
                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:
         * <ul>
         *  <li>border-width -> borderWidth</li>
         *  <li>padding-top -> paddingTop</li>
         * </ul>
         * @static
         * @param {String} prop The property to normalize
         * @return {String} The normalized string
         */
        normalize : function(prop) {
            if (prop == 'float') {
                prop = Ext.supports.Float ? 'cssFloat' : 'styleFloat';
            }
            return this.propertyCache[prop] || (this.propertyCache[prop] = prop.replace(this.camelRe, this.camelReplaceFn));
        },

        /**
         * Retrieves the document height
         * @static
         * @return {Number} documentHeight
         */
        getDocumentHeight: function() {
            return Math.max(!Ext.isStrict ? document.body.scrollHeight : document.documentElement.scrollHeight, this.getViewportHeight());
        },

        /**
         * Retrieves the document width
         * @static
         * @return {Number} documentWidth
         */
        getDocumentWidth: function() {
            return Math.max(!Ext.isStrict ? document.body.scrollWidth : document.documentElement.scrollWidth, this.getViewportWidth());
        },

        /**
         * Retrieves the viewport height of the window.
         * @static
         * @return {Number} viewportHeight
         */
        getViewportHeight: function(){
            return window.innerHeight;
        },

        /**
         * Retrieves the viewport width of the window.
         * @static
         * @return {Number} viewportWidth
         */
        getViewportWidth : function() {
            return window.innerWidth;
        },

        /**
         * Retrieves the viewport size of the window.
         * @static
         * @return {Object} object containing width and height properties
         */
        getViewSize : function() {
            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.
         * @static
         * @return {String} Orientation of window: 'portrait' or 'landscape'
         */
        getOrientation : function() {
            if (Ext.supports.OrientationChange) {
                return (window.orientation == 0) ? 'portrait' : 'landscape';
            }

            return (window.innerHeight > window.innerWidth) ? 'portrait' : 'landscape';
        },

        /**
         * 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.
         * <p>
         * The sample code below would return an object with 2 properties, one
         * for background-color and one for color.</p>
         * <pre><code>
    var css = 'background-color: red;color: blue; ';
    console.log(Ext.Element.parseStyles(css));
         * </code></pre>
         * @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;
        }
    });