Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / ext-all-debug.js
index 674494a..8fc6dc0 100644 (file)
@@ -1,9 +1,23 @@
+/*
+
+This file is part of Ext JS 4
+
+Copyright (c) 2011 Sencha Inc
+
+Contact:  http://www.sencha.com/contact
+
+GNU General Public License Usage
+This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file.  Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
+
+If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
+
+*/
 
 
 (function() {
     var global = this,
         objectPrototype = Object.prototype,
-        toString = Object.prototype.toString,
+        toString = objectPrototype.toString,
         enumerables = true,
         enumerablesTest = { toString: 1 },
         i;
                     };
                 }
 
-                if (!superclass) {
-                    Ext.Error.raise({
-                        sourceClass: 'Ext',
-                        sourceMethod: 'extend',
-                        msg: 'Attempting to extend from a class which has not been loaded on the page.'
-                    });
-                }
 
                 
                 var F = function() {},
                 return 'object';
             }
 
-            Ext.Error.raise({
-                sourceClass: 'Ext',
-                sourceMethod: 'typeOf',
-                msg: 'Failed to determine the type of the specified value "' + value + '". This is most likely a bug.'
-            });
         },
 
         
         
         isObject: (toString.call(null) === '[object Object]') ?
         function(value) {
-            return value !== null && value !== undefined && toString.call(value) === '[object Object]' && value.nodeType === undefined;
+            
+            return value !== null && value !== undefined && toString.call(value) === '[object Object]' && value.ownerDocument === undefined;
         } :
         function(value) {
             return toString.call(value) === '[object Object]';
 
         
         isElement: function(value) {
-            return value ? value.nodeType !== undefined : false;
+            return value ? value.nodeType === 1 : false;
         },
 
         
                 var i = 0;
 
                 do {
-                    uniqueGlobalNamespace = 'ExtSandbox' + (++i);
+                    uniqueGlobalNamespace = 'ExtBox' + (++i);
                 } while (Ext.global[uniqueGlobalNamespace] !== undefined);
 
                 Ext.global[uniqueGlobalNamespace] = Ext;
 (function() {
 
 
-var version = '4.0.0', Version;
+var version = '4.0.7', Version;
     Ext.Version = Version = Ext.extend(Object, {
 
         
@@ -589,9 +592,10 @@ Ext.String = {
     escapeRegexRe: /([-.*+?^${}()|[\]\/\\])/g,
 
     /**
-     * Convert certain characters (&, <, >, and ') to their HTML character equivalents for literal display in web pages.
+     * Convert certain characters (&, <, >, and ") to their HTML character equivalents for literal display in web pages.
      * @param {String} value The string to encode
      * @return {String} The encoded text
+     * @method
      */
     htmlEncode: (function() {
         var entities = {
@@ -614,7 +618,12 @@ Ext.String = {
         };
     })(),
 
-    
+    /**
+     * Convert certain characters (&, <, >, and ") from their HTML character equivalents.
+     * @param {String} value The string to decode
+     * @return {String} The decoded text
+     * @method
+     */
     htmlDecode: (function() {
         var entities = {
             '&amp;': '&',
@@ -705,6 +714,14 @@ Ext.String = {
         return format.replace(Ext.String.formatRe, function(m, i) {
             return args[i];
         });
+    },
+
+    
+    repeat: function(pattern, count, sep) {
+        for (var buf = [], i = count; i--; ) {
+            buf.push(pattern);
+        }
+        return buf.join(sep || '');
     }
 };
 
@@ -729,6 +746,26 @@ Ext.Number = {
     },
 
     
+    snap : function(value, increment, minValue, maxValue) {
+        var newValue = value,
+            m;
+
+        if (!(increment && value)) {
+            return value;
+        }
+        m = value % increment;
+        if (m !== 0) {
+            newValue -= m;
+            if (m * 2 >= increment) {
+                newValue += increment;
+            } else if (m * 2 < -increment) {
+                newValue -= increment;
+            }
+        }
+        return Ext.Number.constrain(newValue, minValue,  maxValue);
+    },
+
+    
     toFixed: function(value, precision) {
         if (isToFixedBroken) {
             precision = precision || 0;
@@ -760,6 +797,34 @@ Ext.num = function() {
 
     var arrayPrototype = Array.prototype,
         slice = arrayPrototype.slice,
+        supportsSplice = function () {
+            var array = [],
+                lengthBefore,
+                j = 20;
+
+            if (!array.splice) {
+                return false;
+            }
+
+            
+            
+
+            while (j--) {
+                array.push("A");
+            }
+
+            array.splice(15, 0, "F", "F", "F", "F", "F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F","F");
+
+            lengthBefore = array.length; 
+            array.splice(13, 0, "XXX"); 
+
+            if (lengthBefore+1 != array.length) {
+                return false;
+            }
+            
+
+            return true;
+        }(),
         supportsForEach = 'forEach' in arrayPrototype,
         supportsMap = 'map' in arrayPrototype,
         supportsIndexOf = 'indexOf' in arrayPrototype,
@@ -772,6 +837,7 @@ Ext.num = function() {
         }(),
         supportsSliceOnNodeList = true,
         ExtArray;
+
     try {
         
         if (typeof document !== 'undefined') {
@@ -781,6 +847,99 @@ Ext.num = function() {
         supportsSliceOnNodeList = false;
     }
 
+    function fixArrayIndex (array, index) {
+        return (index < 0) ? Math.max(0, array.length + index)
+                           : Math.min(array.length, index);
+    }
+
+    
+    function replaceSim (array, index, removeCount, insert) {
+        var add = insert ? insert.length : 0,
+            length = array.length,
+            pos = fixArrayIndex(array, index);
+
+        
+        if (pos === length) {
+            if (add) {
+                array.push.apply(array, insert);
+            }
+        } else {
+            var remove = Math.min(removeCount, length - pos),
+                tailOldPos = pos + remove,
+                tailNewPos = tailOldPos + add - remove,
+                tailCount = length - tailOldPos,
+                lengthAfterRemove = length - remove,
+                i;
+
+            if (tailNewPos < tailOldPos) { 
+                for (i = 0; i < tailCount; ++i) {
+                    array[tailNewPos+i] = array[tailOldPos+i];
+                }
+            } else if (tailNewPos > tailOldPos) { 
+                for (i = tailCount; i--; ) {
+                    array[tailNewPos+i] = array[tailOldPos+i];
+                }
+            } 
+
+            if (add && pos === lengthAfterRemove) {
+                array.length = lengthAfterRemove; 
+                array.push.apply(array, insert);
+            } else {
+                array.length = lengthAfterRemove + add; 
+                for (i = 0; i < add; ++i) {
+                    array[pos+i] = insert[i];
+                }
+            }
+        }
+
+        return array;
+    }
+
+    function replaceNative (array, index, removeCount, insert) {
+        if (insert && insert.length) {
+            if (index < array.length) {
+                array.splice.apply(array, [index, removeCount].concat(insert));
+            } else {
+                array.push.apply(array, insert);
+            }
+        } else {
+            array.splice(index, removeCount);
+        }
+        return array;
+    }
+
+    function eraseSim (array, index, removeCount) {
+        return replaceSim(array, index, removeCount);
+    }
+
+    function eraseNative (array, index, removeCount) {
+        array.splice(index, removeCount);
+        return array;
+    }
+
+    function spliceSim (array, index, removeCount) {
+        var pos = fixArrayIndex(array, index),
+            removed = array.slice(index, fixArrayIndex(array, pos+removeCount));
+
+        if (arguments.length < 4) {
+            replaceSim(array, pos, removeCount);
+        } else {
+            replaceSim(array, pos, removeCount, slice.call(arguments, 3));
+        }
+
+        return removed;
+    }
+
+    function spliceNative (array) {
+        return array.splice.apply(array, slice.call(arguments, 1));
+    }
+
+    var erase = supportsSplice ? eraseNative : eraseSim,
+        replace = supportsSplice ? replaceNative : replaceSim,
+        splice = supportsSplice ? spliceNative : spliceSim;
+
+    
+
     ExtArray = Ext.Array = {
         
         each: function(array, fn, scope, reverse) {
@@ -915,9 +1074,6 @@ Ext.num = function() {
 
         
         every: function(array, fn, scope) {
-            if (!fn) {
-                Ext.Error.raise('Ext.Array.every must have a callback function passed as second argument.');
-            }
             if (supportsEvery) {
                 return array.every(fn, scope);
             }
@@ -936,9 +1092,6 @@ Ext.num = function() {
 
         
         some: function(array, fn, scope) {
-            if (!fn) {
-                Ext.Error.raise('Ext.Array.some must have a callback function passed as second argument.');
-            }
             if (supportsSome) {
                 return array.some(fn, scope);
             }
@@ -1032,7 +1185,7 @@ Ext.num = function() {
             var index = ExtArray.indexOf(array, item);
 
             if (index !== -1) {
-                array.splice(index, 1);
+                erase(array, index, 1);
             }
 
             return array;
@@ -1081,8 +1234,8 @@ Ext.num = function() {
                 }
             }
 
-            minArray = Ext.Array.unique(minArray);
-            arrays.splice(x, 1);
+            minArray = ExtArray.unique(minArray);
+            erase(arrays, x, 1);
 
             
             
@@ -1116,7 +1269,7 @@ Ext.num = function() {
             for (i = 0,lnB = arrayB.length; i < lnB; i++) {
                 for (j = 0; j < ln; j++) {
                     if (clone[j] === arrayB[i]) {
-                        clone.splice(j, 1);
+                        erase(clone, j, 1);
                         j--;
                         ln--;
                     }
@@ -1127,6 +1280,26 @@ Ext.num = function() {
         },
 
         
+        
+        slice: ([1,2].slice(1, undefined).length ?
+            function (array, begin, end) {
+                return slice.call(array, begin, end);
+            } :
+            
+            function (array, begin, end) {
+                
+                
+                if (typeof begin === 'undefined') {
+                    return slice.call(array);
+                }
+                if (typeof end === 'undefined') {
+                    return slice.call(array, begin);
+                }
+                return slice.call(array, begin, end);
+            }
+        ),
+
+        
         sort: function(array, sortFn) {
             if (supportsSort) {
                 if (sortFn) {
@@ -1249,48 +1422,61 @@ Ext.num = function() {
             }
 
             return sum;
-        }
+        },
+
+
+        
+        erase: erase,
+
+        
+        insert: function (array, index, items) {
+            return replace(array, index, 0, items);
+        },
 
+        
+        replace: replace,
+
+        
+        splice: splice
     };
 
     
-    Ext.each = Ext.Array.each;
+    Ext.each = ExtArray.each;
 
     
-    Ext.Array.union = Ext.Array.merge;
+    ExtArray.union = ExtArray.merge;
 
     
-    Ext.min = Ext.Array.min;
+    Ext.min = ExtArray.min;
 
     
-    Ext.max = Ext.Array.max;
+    Ext.max = ExtArray.max;
 
     
-    Ext.sum = Ext.Array.sum;
+    Ext.sum = ExtArray.sum;
 
     
-    Ext.mean = Ext.Array.mean;
+    Ext.mean = ExtArray.mean;
 
     
-    Ext.flatten = Ext.Array.flatten;
+    Ext.flatten = ExtArray.flatten;
 
     
-    Ext.clean = Ext.Array.clean;
+    Ext.clean = ExtArray.clean;
 
     
-    Ext.unique = Ext.Array.unique;
+    Ext.unique = ExtArray.unique;
 
     
-    Ext.pluck = Ext.Array.pluck;
+    Ext.pluck = ExtArray.pluck;
 
     
     Ext.toArray = function() {
         return ExtArray.toArray.apply(ExtArray, arguments);
-    }
+    };
 })();
 
 
-
 Ext.Function = {
 
     
@@ -1325,22 +1511,27 @@ Ext.Function = {
         };
     },
 
-   
+    
     bind: function(fn, scope, args, appendArgs) {
+        if (arguments.length === 2) {
+            return function() {
+                return fn.apply(scope, arguments);
+            }
+        }
+
         var method = fn,
-            applyArgs;
+            slice = Array.prototype.slice;
 
         return function() {
             var callArgs = args || arguments;
 
             if (appendArgs === true) {
-                callArgs = Array.prototype.slice.call(arguments, 0);
+                callArgs = slice.call(arguments, 0);
                 callArgs = callArgs.concat(args);
             }
-            else if (Ext.isNumber(appendArgs)) {
-                callArgs = Array.prototype.slice.call(arguments, 0); 
-                applyArgs = [appendArgs, 0].concat(args); 
-                Array.prototype.splice.apply(callArgs, applyArgs); 
+            else if (typeof appendArgs == 'number') {
+                callArgs = slice.call(arguments, 0); 
+                Ext.Array.insert(callArgs, appendArgs, args);
             }
 
             return method.apply(scope || window, callArgs);
@@ -1426,7 +1617,7 @@ Ext.Function = {
             return function() {
                 var me = this;
                 if (timerId) {
-                    clearInterval(timerId);
+                    clearTimeout(timerId);
                     timerId = null;
                 }
                 timerId = setTimeout(function(){
@@ -1454,6 +1645,28 @@ Ext.Function = {
                 timer = setTimeout(execute, interval - elapsed);
             }
         };
+    },
+
+    
+    interceptBefore: function(object, methodName, fn) {
+        var method = object[methodName] || Ext.emptyFn;
+
+        return object[methodName] = function() {
+            var ret = fn.apply(this, arguments);
+            method.apply(this, arguments);
+
+            return ret;
+        };
+    },
+
+    
+    interceptAfter: function(object, methodName, fn) {
+        var method = object[methodName] || Ext.emptyFn;
+
+        return object[methodName] = function() {
+            method.apply(this, arguments);
+            return fn.apply(this, arguments);
+        };
     }
 };
 
@@ -1577,15 +1790,6 @@ var ExtObject = Ext.Object = {
                     matchedKeys = name.match(/(\[):?([^\]]*)\]/g);
                     matchedName = name.match(/^([^\[]+)/);
 
-                    if (!matchedName) {
-                        Ext.Error.raise({
-                            sourceClass: "Ext.Object",
-                            sourceMethod: "fromQueryString",
-                            queryString: queryString,
-                            recursive: recursive,
-                            msg: 'Malformed query string given, failed parsing name from "' + part + '"'
-                        });
-                    }
 
                     name = matchedName[0];
                     keys = [];
@@ -2638,6 +2842,7 @@ var Base = Ext.Base = function() {};
         },
 
         
+        
         initConfig: function(config) {
             if (!this.$configInited) {
                 this.config = Ext.Object.merge({}, this.config || {}, config || {});
@@ -2667,6 +2872,7 @@ var Base = Ext.Base = function() {};
 
             return this;
         }),
+        
 
         
         callParent: function(args) {
@@ -2674,13 +2880,6 @@ var Base = Ext.Base = function() {};
                 parentClass, methodName;
 
             if (!method.$owner) {
-                if (!method.caller) {
-                    Ext.Error.raise({
-                        sourceClass: Ext.getClassName(this),
-                        sourceMethod: "callParent",
-                        msg: "Attempting to call a protected method from the public scope, which is not allowed"
-                    });
-                }
 
                 method = method.caller;
             }
@@ -2688,14 +2887,6 @@ var Base = Ext.Base = function() {};
             parentClass = method.$owner.superclass;
             methodName = method.$name;
 
-            if (!(methodName in parentClass)) {
-                Ext.Error.raise({
-                    sourceClass: Ext.getClassName(this),
-                    sourceMethod: methodName,
-                    msg: "this.callParent() was called but there's no such method (" + methodName +
-                         ") found in the parent class (" + (Ext.getClassName(parentClass) || 'Object') + ")"
-                 });
-            }
 
             return parentClass[methodName].apply(this, args || []);
         },
@@ -2717,22 +2908,6 @@ var Base = Ext.Base = function() {};
         callOverridden: function(args) {
             var method = this.callOverridden.caller;
 
-            if (!method.$owner) {
-                Ext.Error.raise({
-                    sourceClass: Ext.getClassName(this),
-                    sourceMethod: "callOverridden",
-                    msg: "Attempting to call a protected method from the public scope, which is not allowed"
-                });
-            }
-
-            if (!method.$previous) {
-                Ext.Error.raise({
-                    sourceClass: Ext.getClassName(this),
-                    sourceMethod: "callOverridden",
-                    msg: "this.callOverridden was called in '" + method.$name +
-                         "' but this method has never been overridden"
-                 });
-            }
 
             return method.$previous.apply(this, args || []);
         },
@@ -2748,20 +2923,20 @@ var Base = Ext.Base = function() {};
         },
 
         
-        own: flexSetter(function(name, value) {
-            if (typeof value === 'function') {
+        own: function(name, value) {
+            if (typeof value == 'function') {
                 this.ownMethod(name, value);
             }
             else {
                 this.prototype[name] = value;
             }
-        }),
+        },
 
         
         ownMethod: function(name, fn) {
             var originalFn;
 
-            if (fn.$owner !== undefined && fn !== Ext.emptyFn) {
+            if (typeof fn.$owner !== 'undefined' && fn !== Ext.emptyFn) {
                 originalFn = fn;
 
                 fn = function() {
@@ -2769,11 +2944,6 @@ var Base = Ext.Base = function() {};
                 };
             }
 
-            var className;
-            className = Ext.getClassName(this);
-            if (className) {
-                fn.displayName = className + '#' + name;
-            }
             fn.$owner = this;
             fn.$name = name;
 
@@ -2792,10 +2962,41 @@ var Base = Ext.Base = function() {};
         },
 
         
+        addInheritableStatics: function(members) {
+            var inheritableStatics,
+                hasInheritableStatics,
+                prototype = this.prototype,
+                name, member;
+
+            inheritableStatics = prototype.$inheritableStatics;
+            hasInheritableStatics = prototype.$hasInheritableStatics;
+
+            if (!inheritableStatics) {
+                inheritableStatics = prototype.$inheritableStatics = [];
+                hasInheritableStatics = prototype.$hasInheritableStatics = {};
+            }
+
+
+            for (name in members) {
+                if (members.hasOwnProperty(name)) {
+                    member = members[name];
+                    this[name] = member;
+
+                    if (!hasInheritableStatics[name]) {
+                        hasInheritableStatics[name] = true;
+                        inheritableStatics.push(name);
+                    }
+                }
+            }
+
+            return this;
+        },
+
+        
         implement: function(members) {
             var prototype = this.prototype,
-                name, i, member, previous;
-            var className = Ext.getClassName(this);
+                enumerables = Ext.enumerables,
+                name, i, member;
             for (name in members) {
                 if (members.hasOwnProperty(name)) {
                     member = members[name];
@@ -2803,18 +3004,13 @@ var Base = Ext.Base = function() {};
                     if (typeof member === 'function') {
                         member.$owner = this;
                         member.$name = name;
-                        if (className) {
-                            member.displayName = className + '#' + name;
-                        }
                     }
 
                     prototype[name] = member;
                 }
             }
 
-            if (Ext.enumerables) {
-                var enumerables = Ext.enumerables;
-
+            if (enumerables) {
                 for (i = enumerables.length; i--;) {
                     name = enumerables[i];
 
@@ -2847,8 +3043,28 @@ var Base = Ext.Base = function() {};
         
         override: function(members) {
             var prototype = this.prototype,
+                enumerables = Ext.enumerables,
                 name, i, member, previous;
 
+            if (arguments.length === 2) {
+                name = members;
+                member = arguments[1];
+
+                if (typeof member == 'function') {
+                    if (typeof prototype[name] == 'function') {
+                        previous = prototype[name];
+                        member.$previous = previous;
+                    }
+
+                    this.ownMethod(name, member);
+                }
+                else {
+                    prototype[name] = member;
+                }
+
+                return this;
+            }
+
             for (name in members) {
                 if (members.hasOwnProperty(name)) {
                     member = members[name];
@@ -2867,14 +3083,12 @@ var Base = Ext.Base = function() {};
                 }
             }
 
-            if (Ext.enumerables) {
-                var enumerables = Ext.enumerables;
-
+            if (enumerables) {
                 for (i = enumerables.length; i--;) {
                     name = enumerables[i];
 
                     if (members.hasOwnProperty(name)) {
-                        if (prototype[name] !== undefined) {
+                        if (typeof prototype[name] !== 'undefined') {
                             previous = prototype[name];
                             members[name].$previous = previous;
                         }
@@ -2888,40 +3102,53 @@ var Base = Ext.Base = function() {};
         },
 
         
-        mixin: flexSetter(function(name, cls) {
+        
+        mixin: function(name, cls) {
             var mixin = cls.prototype,
                 my = this.prototype,
-                i, fn;
+                key, fn;
 
-            for (i in mixin) {
-                if (mixin.hasOwnProperty(i)) {
-                    if (my[i] === undefined) {
-                        if (typeof mixin[i] === 'function') {
-                            fn = mixin[i];
+            for (key in mixin) {
+                if (mixin.hasOwnProperty(key)) {
+                    if (typeof my[key] === 'undefined' && key !== 'mixins' && key !== 'mixinId') {
+                        if (typeof mixin[key] === 'function') {
+                            fn = mixin[key];
 
-                            if (fn.$owner === undefined) {
-                                this.ownMethod(i, fn);
+                            if (typeof fn.$owner === 'undefined') {
+                                this.ownMethod(key, fn);
                             }
                             else {
-                                my[i] = fn;
+                                my[key] = fn;
                             }
                         }
                         else {
-                            my[i] = mixin[i];
+                            my[key] = mixin[key];
                         }
                     }
-                    else if (i === 'config' && my.config && mixin.config) {
+                    
+                    else if (key === 'config' && my.config && mixin.config) {
                         Ext.Object.merge(my.config, mixin.config);
                     }
+                    
                 }
             }
 
-            if (my.mixins === undefined) {
-                my.mixins = {};
+            if (typeof mixin.onClassMixedIn !== 'undefined') {
+                mixin.onClassMixedIn.call(cls, this);
+            }
+
+            if (!my.hasOwnProperty('mixins')) {
+                if ('mixins' in my) {
+                    my.mixins = Ext.Object.merge({}, my.mixins);
+                }
+                else {
+                    my.mixins = {};
+                }
             }
 
             my.mixins[name] = mixin;
-        }),
+        },
+        
 
         
         getName: function() {
@@ -2930,7 +3157,9 @@ var Base = Ext.Base = function() {};
 
         
         createAlias: flexSetter(function(alias, origin) {
-            this.prototype[alias] = this.prototype[origin];
+            this.prototype[alias] = function() {
+                return this[origin].apply(this, arguments);
+            }
         })
     });
 
@@ -2952,7 +3181,7 @@ var Base = Ext.Base = function() {};
 
     
     Ext.Class = Class = function(newClass, classData, onClassCreated) {
-        if (typeof newClass !== 'function') {
+        if (typeof newClass != 'function') {
             onClassCreated = classData;
             classData = newClass;
             newClass = function() {
@@ -2968,7 +3197,7 @@ var Base = Ext.Base = function() {};
             registeredPreprocessors = Class.getPreprocessors(),
             index = 0,
             preprocessors = [],
-            preprocessor, preprocessors, staticPropertyName, process, i, j, ln;
+            preprocessor, staticPropertyName, process, i, j, ln;
 
         for (i = 0, ln = baseStaticProperties.length; i < ln; i++) {
             staticPropertyName = baseStaticProperties[i];
@@ -2980,7 +3209,7 @@ var Base = Ext.Base = function() {};
         for (j = 0, ln = preprocessorStack.length; j < ln; j++) {
             preprocessor = preprocessorStack[j];
 
-            if (typeof preprocessor === 'string') {
+            if (typeof preprocessor == 'string') {
                 preprocessor = registeredPreprocessors[preprocessor];
 
                 if (!preprocessor.always) {
@@ -2997,7 +3226,7 @@ var Base = Ext.Base = function() {};
             }
         }
 
-        classData.onClassCreated = onClassCreated;
+        classData.onClassCreated = onClassCreated || Ext.emptyFn;
 
         classData.onBeforeClassCreated = function(cls, data) {
             onClassCreated = data.onClassCreated;
@@ -3007,9 +3236,7 @@ var Base = Ext.Base = function() {};
 
             cls.implement(data);
 
-            if (onClassCreated) {
-                onClassCreated.call(cls, cls);
-            }
+            onClassCreated.call(cls, cls);
         };
 
         process = function(cls, data) {
@@ -3072,7 +3299,7 @@ var Base = Ext.Base = function() {};
             var defaultPreprocessors = this.defaultPreprocessors,
                 index;
 
-            if (typeof offset === 'string') {
+            if (typeof offset == 'string') {
                 if (offset === 'first') {
                     defaultPreprocessors.unshift(name);
 
@@ -3090,13 +3317,14 @@ var Base = Ext.Base = function() {};
             index = Ext.Array.indexOf(defaultPreprocessors, relativeName);
 
             if (index !== -1) {
-                defaultPreprocessors.splice(Math.max(0, index + offset), 0, name);
+                Ext.Array.splice(defaultPreprocessors, Math.max(0, index + offset), 0, name);
             }
 
             return this;
         }
     });
 
+    
     Class.registerPreprocessor('extend', function(cls, data) {
         var extend = data.extend,
             base = Ext.Base,
@@ -3132,6 +3360,7 @@ var Base = Ext.Base = function() {};
         delete data.extend;
 
         
+        
         parentStatics = parentPrototype.$inheritableStatics;
 
         if (parentStatics) {
@@ -3143,15 +3372,19 @@ var Base = Ext.Base = function() {};
                 }
             }
         }
+        
 
         
+        
         if (parentPrototype.config) {
             clsPrototype.config = Ext.Object.merge({}, parentPrototype.config);
         }
         else {
             clsPrototype.config = {};
         }
+        
 
+        
         if (clsPrototype.$onExtended) {
             clsPrototype.$onExtended.call(cls, cls, data);
         }
@@ -3160,50 +3393,30 @@ var Base = Ext.Base = function() {};
             clsPrototype.$onExtended = data.onClassExtended;
             delete data.onClassExtended;
         }
+        
 
     }, true);
 
+    
+    
     Class.registerPreprocessor('statics', function(cls, data) {
-        var statics = data.statics,
-            name;
-
-        for (name in statics) {
-            if (statics.hasOwnProperty(name)) {
-                cls[name] = statics[name];
-            }
-        }
+        cls.addStatics(data.statics);
 
         delete data.statics;
     });
+    
 
+    
+    
     Class.registerPreprocessor('inheritableStatics', function(cls, data) {
-        var statics = data.inheritableStatics,
-            inheritableStatics,
-            prototype = cls.prototype,
-            name;
-
-        inheritableStatics = prototype.$inheritableStatics;
-
-        if (!inheritableStatics) {
-            inheritableStatics = prototype.$inheritableStatics = [];
-        }
-
-        for (name in statics) {
-            if (statics.hasOwnProperty(name)) {
-                cls[name] = statics[name];
-                inheritableStatics.push(name);
-            }
-        }
+        cls.addInheritableStatics(data.inheritableStatics);
 
         delete data.inheritableStatics;
     });
+    
 
-    Class.registerPreprocessor('mixins', function(cls, data) {
-        cls.mixin(data.mixins);
-
-        delete data.mixins;
-    });
-
+    
+    
     Class.registerPreprocessor('config', function(cls, data) {
         var prototype = cls.prototype;
 
@@ -3224,7 +3437,7 @@ var Base = Ext.Base = function() {};
                 data[setter] = function(val) {
                     var ret = this[apply].call(this, val, this[pName]);
 
-                    if (ret !== undefined) {
+                    if (typeof ret != 'undefined') {
                         this[pName] = ret;
                     }
 
@@ -3242,10 +3455,55 @@ var Base = Ext.Base = function() {};
         Ext.Object.merge(prototype.config, data.config);
         delete data.config;
     });
+    
 
-    Class.setDefaultPreprocessors(['extend', 'statics', 'inheritableStatics', 'mixins', 'config']);
+    
+    
+    Class.registerPreprocessor('mixins', function(cls, data) {
+        var mixins = data.mixins,
+            name, mixin, i, ln;
+
+        delete data.mixins;
+
+        Ext.Function.interceptBefore(data, 'onClassCreated', function(cls) {
+            if (mixins instanceof Array) {
+                for (i = 0,ln = mixins.length; i < ln; i++) {
+                    mixin = mixins[i];
+                    name = mixin.prototype.mixinId || mixin.$className;
+
+                    cls.mixin(name, mixin);
+                }
+            }
+            else {
+                for (name in mixins) {
+                    if (mixins.hasOwnProperty(name)) {
+                        cls.mixin(name, mixins[name]);
+                    }
+                }
+            }
+        });
+    });
 
     
+
+    Class.setDefaultPreprocessors([
+        'extend'
+        
+        ,'statics'
+        
+        
+        ,'inheritableStatics'
+        
+        
+        ,'config'
+        
+        
+        ,'mixins'
+        
+    ]);
+
+    
+    
     Ext.extend = function(subclass, superclass, members) {
         if (arguments.length === 2 && Ext.isObject(superclass)) {
             members = superclass;
@@ -3260,7 +3518,21 @@ var Base = Ext.Base = function() {};
         }
 
         members.extend = superclass;
-        members.preprocessors = ['extend', 'mixins', 'config', 'statics'];
+        members.preprocessors = [
+            'extend'
+            
+            ,'statics'
+            
+            
+            ,'inheritableStatics'
+            
+            
+            ,'mixins'
+            
+            
+            ,'config'
+            
+        ];
 
         if (subclass) {
             cls = new Class(subclass, members);
@@ -3279,6 +3551,7 @@ var Base = Ext.Base = function() {};
 
         return cls;
     };
+    
 
 })();
 
@@ -3317,20 +3590,11 @@ var Base = Ext.Base = function() {};
         
         instantiators: [],
 
-        
-        instantiationCounts: {},
 
         
         isCreated: function(className) {
             var i, ln, part, root, parts;
 
-            if (typeof className !== 'string' || className.length < 1) {
-                Ext.Error.raise({
-                    sourceClass: "Ext.ClassManager",
-                    sourceMethod: "exist",
-                    msg: "Invalid classname, must be a string and must not be empty"
-                });
-            }
 
             if (this.classes.hasOwnProperty(className) || this.existCache.hasOwnProperty(className)) {
                 return true;
@@ -3362,13 +3626,6 @@ var Base = Ext.Base = function() {};
 
         
         parseNamespace: function(namespace) {
-            if (typeof namespace !== 'string') {
-                Ext.Error.raise({
-                    sourceClass: "Ext.ClassManager",
-                    sourceMethod: "parseNamespace",
-                    msg: "Invalid namespace, must be a string"
-                });
-            }
 
             var cache = this.namespaceParseCache;
 
@@ -3415,10 +3672,11 @@ var Base = Ext.Base = function() {};
         setNamespace: function(name, value) {
             var root = Ext.global,
                 parts = this.parseNamespace(name),
-                leaf = parts.pop(),
-                i, ln, part;
+                ln = parts.length - 1,
+                leaf = parts[ln],
+                i, part;
 
-            for (i = 0, ln = parts.length; i < ln; i++) {
+            for (i = 0; i < ln; i++) {
                 part = parts[i];
 
                 if (typeof part !== 'string') {
@@ -3516,10 +3774,6 @@ var Base = Ext.Base = function() {};
             }
 
             if (alias && aliasToNameMap[alias] !== className) {
-                if (aliasToNameMap.hasOwnProperty(alias) && Ext.isDefined(Ext.global.console)) {
-                    Ext.global.console.log("[Ext.ClassManager] Overriding existing alias: '" + alias + "' " +
-                        "of: '" + aliasToNameMap[alias] + "' with: '" + className + "'. Be sure it's intentional.");
-                }
 
                 aliasToNameMap[alias] = className;
             }
@@ -3569,13 +3823,6 @@ var Base = Ext.Base = function() {};
         create: function(className, data, createdFn) {
             var manager = this;
 
-            if (typeof className !== 'string') {
-                Ext.Error.raise({
-                    sourceClass: "Ext",
-                    sourceMethod: "define",
-                    msg: "Invalid class name '" + className + "' specified, must be a non-empty string"
-                });
-            }
 
             data.$className = className;
 
@@ -3584,7 +3831,7 @@ var Base = Ext.Base = function() {};
                     registeredPostprocessors = manager.postprocessors,
                     index = 0,
                     postprocessors = [],
-                    postprocessor, postprocessors, process, i, ln;
+                    postprocessor, process, i, ln;
 
                 delete data.postprocessors;
 
@@ -3641,18 +3888,7 @@ var Base = Ext.Base = function() {};
             if (!className) {
                 className = this.maps.aliasToName[alias];
 
-                if (!className) {
-                    Ext.Error.raise({
-                        sourceClass: "Ext",
-                        sourceMethod: "createByAlias",
-                        msg: "Cannot create an instance of unrecognized alias: " + alias
-                    });
-                }
 
-                if (Ext.global.console) {
-                    Ext.global.console.warn("[Ext.Loader] Synchronously loading '" + className + "'; consider adding " +
-                         "Ext.require('" + alias + "') above Ext.onReady");
-                }
 
                 Ext.syncRequire(className);
             }
@@ -3670,13 +3906,6 @@ var Base = Ext.Base = function() {};
                 possibleName, cls;
 
             if (typeof name !== 'function') {
-                if ((typeof name !== 'string' || name.length < 1)) {
-                    Ext.Error.raise({
-                        sourceClass: "Ext",
-                        sourceMethod: "create",
-                        msg: "Invalid class name or alias '" + name + "' specified, must be a non-empty string"
-                    });
-                }
 
                 cls = this.get(name);
             }
@@ -3708,37 +3937,13 @@ var Base = Ext.Base = function() {};
 
             
             if (!cls) {
-                if (Ext.global.console) {
-                    Ext.global.console.warn("[Ext.Loader] Synchronously loading '" + name + "'; consider adding " +
-                         "Ext.require('" + ((possibleName) ? alias : name) + "') above Ext.onReady");
-                }
 
                 Ext.syncRequire(name);
 
                 cls = this.get(name);
             }
 
-            if (!cls) {
-                Ext.Error.raise({
-                    sourceClass: "Ext",
-                    sourceMethod: "create",
-                    msg: "Cannot create an instance of unrecognized class name / alias: " + alias
-                });
-            }
-
-            if (typeof cls !== 'function') {
-                Ext.Error.raise({
-                    sourceClass: "Ext",
-                    sourceMethod: "create",
-                    msg: "'" + name + "' is a singleton and cannot be instantiated"
-                });
-            }
-
-            if (!this.instantiationCounts[name]) {
-                this.instantiationCounts[name] = 0;
-            }
 
-            this.instantiationCounts[name]++;
 
             return this.getInstantiator(args.length)(cls, args);
         },
@@ -3814,7 +4019,7 @@ var Base = Ext.Base = function() {};
             index = Ext.Array.indexOf(defaultPostprocessors, relativeName);
 
             if (index !== -1) {
-                defaultPostprocessors.splice(Math.max(0, index + offset), 0, name);
+                Ext.Array.splice(defaultPostprocessors, Math.max(0, index + offset), 0, name);
             }
 
             return this;
@@ -3826,13 +4031,6 @@ var Base = Ext.Base = function() {};
                 names = [],
                 name, alias, aliases, possibleName, regex, i, ln;
 
-            if (typeof expression !== 'string' || expression.length < 1) {
-                Ext.Error.raise({
-                    sourceClass: "Ext.ClassManager",
-                    sourceMethod: "getNamesByExpression",
-                    msg: "Expression " + expression + " is invalid, must be a non-empty string"
-                });
-            }
 
             if (expression.indexOf('*') !== -1) {
                 expression = expression.replace(/\*/g, '(.*?)');
@@ -3878,46 +4076,30 @@ var Base = Ext.Base = function() {};
         }
     };
 
+    var defaultPostprocessors = Manager.defaultPostprocessors;
+    
+
+    
     Manager.registerPostprocessor('alias', function(name, cls, data) {
         var aliases = data.alias,
-            widgetPrefix = 'widget.',
-            i, ln, alias;
+            i, ln;
 
-        if (!(aliases instanceof Array)) {
-            aliases = [aliases];
-        }
+        delete data.alias;
 
         for (i = 0, ln = aliases.length; i < ln; i++) {
             alias = aliases[i];
 
-            if (typeof alias !== 'string') {
-                Ext.Error.raise({
-                    sourceClass: "Ext",
-                    sourceMethod: "define",
-                    msg: "Invalid alias of: '" + alias + "' for class: '" + name + "'; must be a valid string"
-                });
-            }
-
             this.setAlias(cls, alias);
         }
-
-        
-        for (i = 0, ln = aliases.length; i < ln; i++) {
-            alias = aliases[i];
-
-            if (alias.substring(0, widgetPrefix.length) === widgetPrefix) {
-                
-                cls.xtype = cls.$xtype = alias.substring(widgetPrefix.length);
-                break;
-            }
-        }
     });
 
+    
     Manager.registerPostprocessor('singleton', function(name, cls, data, fn) {
         fn.call(this, name, new cls(), data);
         return false;
     });
 
+    
     Manager.registerPostprocessor('alternateClassName', function(name, cls, data) {
         var alternates = data.alternateClassName,
             i, ln, alternate;
@@ -3929,13 +4111,6 @@ var Base = Ext.Base = function() {};
         for (i = 0, ln = alternates.length; i < ln; i++) {
             alternate = alternates[i];
 
-            if (typeof alternate !== 'string') {
-                Ext.Error.raise({
-                    sourceClass: "Ext",
-                    sourceMethod: "define",
-                    msg: "Invalid alternate of: '" + alternate + "' for class: '" + name + "'; must be a valid string"
-                });
-            }
 
             this.set(alternate, cls);
         }
@@ -3999,7 +4174,71 @@ var Base = Ext.Base = function() {};
         createByAlias: alias(Manager, 'instantiateByAlias'),
 
         
-        define: alias(Manager, 'create'),
+        
+        
+        define: function (className, data, createdFn) {
+            if (!data.override) {
+                return Manager.create.apply(Manager, arguments);
+            }
+
+            var requires = data.requires,
+                uses = data.uses,
+                overrideName = className;
+
+            className = data.override;
+
+            
+            data = Ext.apply({}, data);
+            delete data.requires;
+            delete data.uses;
+            delete data.override;
+
+            
+            if (typeof requires == 'string') {
+                requires = [ className, requires ];
+            } else if (requires) {
+                requires = requires.slice(0);
+                requires.unshift(className);
+            } else {
+                requires = [ className ];
+            }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+            return Manager.create(overrideName, {
+                    requires: requires,
+                    uses: uses,
+                    isPartial: true,
+                    constructor: function () {
+                    }
+                }, function () {
+                    var cls = Manager.get(className);
+                    if (cls.override) { 
+                        cls.override(data);
+                    } else { 
+                        cls.self.override(data);
+                    }
+
+                    if (createdFn) {
+                        
+                        
+                        
+                        createdFn.call(cls);
+                    }
+                });
+        },
 
         
         getClassName: alias(Manager, 'getName'),
@@ -4028,6 +4267,7 @@ var Base = Ext.Base = function() {};
         namespace: alias(Manager, 'createNamespaces')
     });
 
+    
     Ext.createWidget = Ext.widget;
 
     
@@ -4036,14 +4276,62 @@ var Base = Ext.Base = function() {};
     Class.registerPreprocessor('className', function(cls, data) {
         if (data.$className) {
             cls.$className = data.$className;
-            cls.displayName = cls.$className;
         }
     }, true);
 
     Class.setDefaultPreprocessorPosition('className', 'first');
 
-})(Ext.Class, Ext.Function.alias);
+    Class.registerPreprocessor('xtype', function(cls, data) {
+        var xtypes = Ext.Array.from(data.xtype),
+            widgetPrefix = 'widget.',
+            aliases = Ext.Array.from(data.alias),
+            i, ln, xtype;
+
+        data.xtype = xtypes[0];
+        data.xtypes = xtypes;
+
+        aliases = data.alias = Ext.Array.from(data.alias);
+
+        for (i = 0,ln = xtypes.length; i < ln; i++) {
+            xtype = xtypes[i];
+
+
+            aliases.push(widgetPrefix + xtype);
+        }
+
+        data.alias = aliases;
+    });
+
+    Class.setDefaultPreprocessorPosition('xtype', 'last');
+
+    Class.registerPreprocessor('alias', function(cls, data) {
+        var aliases = Ext.Array.from(data.alias),
+            xtypes = Ext.Array.from(data.xtypes),
+            widgetPrefix = 'widget.',
+            widgetPrefixLength = widgetPrefix.length,
+            i, ln, alias, xtype;
+
+        for (i = 0, ln = aliases.length; i < ln; i++) {
+            alias = aliases[i];
+
 
+            if (alias.substring(0, widgetPrefixLength) === widgetPrefix) {
+                xtype = alias.substring(widgetPrefixLength);
+                Ext.Array.include(xtypes, xtype);
+
+                if (!cls.xtype) {
+                    cls.xtype = data.xtype = xtype;
+                }
+            }
+        }
+
+        data.alias = aliases;
+        data.xtypes = xtypes;
+    });
+
+    Class.setDefaultPreprocessorPosition('alias', 'last');
+
+})(Ext.Class, Ext.Function.alias);
 
 
 (function(Manager, Class, flexSetter, alias) {
@@ -4203,7 +4491,7 @@ var Base = Ext.Base = function() {};
                     do {
                         if (Manager.isCreated(requires[j])) {
                             
-                            requires.splice(j, 1);
+                            Ext.Array.erase(requires, j, 1);
                         }
                         else {
                             j++;
@@ -4211,7 +4499,7 @@ var Base = Ext.Base = function() {};
                     } while (j < requires.length);
 
                     if (item.requires.length === 0) {
-                        this.queue.splice(i, 1);
+                        Ext.Array.erase(this.queue, i, 1);
                         item.callback.call(item.scope);
                         this.refreshQueue();
                         break;
@@ -4459,48 +4747,7 @@ var Base = Ext.Base = function() {};
                 this.refreshQueue();
             }
 
-            if (this.numPendingFiles <= 1) {
-                window.status = "Finished loading all dependencies, onReady fired!";
-            }
-            else {
-                window.status = "Loading dependencies, " + this.numPendingFiles + " files left...";
-            }
-
-            if (!this.syncModeEnabled && this.numPendingFiles === 0 && this.isLoading && !this.hasFileLoadError) {
-                var queue = this.queue,
-                    requires,
-                    i, ln, j, subLn, missingClasses = [], missingPaths = [];
-
-                for (i = 0, ln = queue.length; i < ln; i++) {
-                    requires = queue[i].requires;
-
-                    for (j = 0, subLn = requires.length; j < ln; j++) {
-                        if (this.isFileLoaded[requires[j]]) {
-                            missingClasses.push(requires[j]);
-                        }
-                    }
-                }
-
-                if (missingClasses.length < 1) {
-                    return;
-                }
-
-                missingClasses = Ext.Array.filter(missingClasses, function(item) {
-                    return !this.requiresMap.hasOwnProperty(item);
-                }, this);
-
-                for (i = 0,ln = missingClasses.length; i < ln; i++) {
-                    missingPaths.push(this.classNameToFilePathMap[missingClasses[i]]);
-                }
 
-                Ext.Error.raise({
-                    sourceClass: "Ext.Loader",
-                    sourceMethod: "onFileLoaded",
-                    msg: "The following classes are not declared even if their files have been " +
-                            "loaded: '" + missingClasses.join("', '") + "'. Please check the source code of their " +
-                            "corresponding files for possible typos: '" + missingPaths.join("', '") + "'"
-                });
-            }
         },
 
         
@@ -4508,13 +4755,6 @@ var Base = Ext.Base = function() {};
             this.numPendingFiles--;
             this.hasFileLoadError = true;
 
-            Ext.Error.raise({
-                sourceClass: "Ext.Loader",
-                classToLoad: className,
-                loadPath: filePath,
-                loadingType: isSynchronous ? 'synchronous' : 'async',
-                msg: errorMessage
-            });
         },
 
         
@@ -4612,6 +4852,7 @@ var Base = Ext.Base = function() {};
         Loader.onReady(fn, scope, true, options);
     };
 
+    
     Class.registerPreprocessor('loader', function(cls, data, continueFn) {
         var me = this,
             dependencies = [],
@@ -4638,7 +4879,7 @@ var Base = Ext.Base = function() {};
                         }
                     }
                 }
-                else {
+                else if (typeof propertyValue != 'function') {
                     for (j in propertyValue) {
                         if (propertyValue.hasOwnProperty(j)) {
                             value = propertyValue[j];
@@ -4657,37 +4898,6 @@ var Base = Ext.Base = function() {};
             return;
         }
 
-        var deadlockPath = [],
-            requiresMap = Loader.requiresMap,
-            detectDeadlock;
-
-        
-
-        if (className) {
-            requiresMap[className] = dependencies;
-
-            detectDeadlock = function(cls) {
-                deadlockPath.push(cls);
-
-                if (requiresMap[cls]) {
-                    if (Ext.Array.contains(requiresMap[cls], className)) {
-                        Ext.Error.raise({
-                            sourceClass: "Ext.Loader",
-                            msg: "Deadlock detected while loading dependencies! '" + className + "' and '" +
-                                deadlockPath[1] + "' " + "mutually require each other. Path: " +
-                                deadlockPath.join(' -> ') + " -> " + deadlockPath[0]
-                        });
-                    }
-
-                    for (i = 0, ln = requiresMap[cls].length; i < ln; i++) {
-                        detectDeadlock(requiresMap[cls][i]);
-                    }
-                }
-            };
-
-            detectDeadlock(className);
-        }
-
 
         Loader.require(dependencies, function() {
             for (i = 0, ln = dependencyProperties.length; i < ln; i++) {
@@ -4708,7 +4918,7 @@ var Base = Ext.Base = function() {};
                             }
                         }
                     }
-                    else {
+                    else if (typeof propertyValue != 'function') {
                         for (var k in propertyValue) {
                             if (propertyValue.hasOwnProperty(k)) {
                                 value = propertyValue[k];
@@ -4730,6 +4940,7 @@ var Base = Ext.Base = function() {};
 
     Class.setDefaultPreprocessorPosition('loader', 'after', 'className');
 
+    
     Manager.registerPostprocessor('uses', function(name, cls, data) {
         var uses = Ext.Array.from(data.uses),
             items = [],
@@ -4757,6 +4968,9 @@ Ext.Error = Ext.extend(Error, {
         ignore: false,
 
         
+        
+
+        
         raise: function(err){
             err = err || {};
             if (Ext.isString(err)) {
@@ -4775,28 +4989,15 @@ Ext.Error = Ext.extend(Error, {
             }
 
             if (Ext.Error.handle(err) !== true) {
-                var global = Ext.global,
-                    con = global.console,
-                    msg = Ext.Error.prototype.toString.call(err),
-                    noConsoleMsg = 'An uncaught error was raised: "' + msg + 
-                        '". Use Firebug or Webkit console for additional details.';
-
-                if (con) {
-                    if (con.dir) {
-                        con.warn('An uncaught error was raised with the following data:');
-                        con.dir(err);
-                    }
-                    else {
-                        con.warn(noConsoleMsg);
-                    }
-                    if (con.error) {
-                        con.error(msg);
-                    }
-                }
-                else if (global.alert){
-                    global.alert(noConsoleMsg);
-                }
-                
+                var msg = Ext.Error.prototype.toString.call(err);
+
+                Ext.log({
+                    msg: msg,
+                    level: 'error',
+                    dump: err,
+                    stack: true
+                });
+
                 throw new Ext.Error(err);
             }
         },
@@ -4808,11 +5009,20 @@ Ext.Error = Ext.extend(Error, {
     },
 
     
+    name: 'Ext.Error',
+
+    
     constructor: function(config){
         if (Ext.isString(config)) {
             config = { msg: config };
         }
-        Ext.apply(this, config);
+
+        var me = this;
+
+        Ext.apply(me, config);
+
+        me.message = me.message || me.msg; 
+        
     },
 
     
@@ -4829,6 +5039,9 @@ Ext.Error = Ext.extend(Error, {
 
 
 
+
+
+
 Ext.JSON = new(function() {
     var useHasOwn = !! {}.hasOwnProperty,
     isNative = function() {
@@ -4914,7 +5127,7 @@ Ext.JSON = new(function() {
 
     
     this.encodeDate = function(o) {
-        return '"' + o.getFullYear() + "-" 
+        return '"' + o.getFullYear() + "-"
         + pad(o.getMonth() + 1) + "-"
         + pad(o.getDate()) + "T"
         + pad(o.getHours()) + ":"
@@ -4952,7 +5165,7 @@ Ext.JSON = new(function() {
                 Ext.Error.raise({
                     sourceClass: "Ext.JSON",
                     sourceMethod: "decode",
-                    msg: "You're trying to decode and invalid JSON String: " + json
+                    msg: "You're trying to decode an invalid JSON String: " + json
                 });
             }
         };
@@ -4970,8 +5183,6 @@ Ext.apply(Ext, {
     userAgent: navigator.userAgent.toLowerCase(),
     cache: {},
     idSeed: 1000,
-    BLANK_IMAGE_URL : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
-    isStrict: document.compatMode == "CSS1Compat",
     windowId: 'ext-window',
     documentId: 'ext-document',
 
@@ -4986,15 +5197,23 @@ Ext.apply(Ext, {
 
     
     id: function(el, prefix) {
+        var me = this,
+            sandboxPrefix = '';
         el = Ext.getDom(el, true) || {};
         if (el === document) {
-            el.id = this.documentId;
+            el.id = me.documentId;
         }
         else if (el === window) {
-            el.id = this.windowId;
+            el.id = me.windowId;
         }
         if (!el.id) {
-            el.id = (prefix || "ext-gen") + (++Ext.idSeed);
+            if (me.isSandboxed) {
+                if (!me.uniqueGlobalNamespace) {
+                    me.getUniqueGlobalNamespace();
+                }
+                sandboxPrefix = me.uniqueGlobalNamespace + '-';
+            }
+            el.id = sandboxPrefix + (prefix || "ext-gen") + (++Ext.idSeed);
         }
         return el.id;
     },
@@ -5091,10 +5310,17 @@ Ext.ns = Ext.namespace;
 
 window.undefined = window.undefined;
 
+
 (function(){
+
     var check = function(regex){
             return regex.test(Ext.userAgent);
         },
+        isStrict = document.compatMode == "CSS1Compat",
+        version = function (is, regex) {
+            var m;
+            return (is && (m = regex.exec(Ext.userAgent))) ? parseFloat(m[1]) : 0;
+        },
         docMode = document.documentMode,
         isOpera = check(/opera/),
         isOpera10_5 = isOpera && check(/version\/10\.5/),
@@ -5104,6 +5330,7 @@ window.undefined = window.undefined;
         isSafari2 = isSafari && check(/applewebkit\/4/), 
         isSafari3 = isSafari && check(/version\/3/),
         isSafari4 = isSafari && check(/version\/4/),
+        isSafari5 = isSafari && check(/version\/5/),
         isIE = !isOpera && check(/msie/),
         isIE7 = isIE && (check(/msie 7/) || docMode == 7),
         isIE8 = isIE && (check(/msie 8/) && docMode != 7 && docMode != 9 || docMode == 8),
@@ -5112,23 +5339,32 @@ window.undefined = window.undefined;
         isGecko = !isWebKit && check(/gecko/),
         isGecko3 = isGecko && check(/rv:1\.9/),
         isGecko4 = isGecko && check(/rv:2\.0/),
+        isGecko5 = isGecko && check(/rv:5\./),
         isFF3_0 = isGecko3 && check(/rv:1\.9\.0/),
         isFF3_5 = isGecko3 && check(/rv:1\.9\.1/),
         isFF3_6 = isGecko3 && check(/rv:1\.9\.2/),
         isWindows = check(/windows|win32/),
         isMac = check(/macintosh|mac os x/),
         isLinux = check(/linux/),
-        scrollWidth = null;
+        scrollbarSize = null,
+        chromeVersion = version(true, /\bchrome\/(\d+\.\d+)/),
+        firefoxVersion = version(true, /\bfirefox\/(\d+\.\d+)/),
+        ieVersion = version(isIE, /msie (\d+\.\d+)/),
+        operaVersion = version(isOpera, /version\/(\d+\.\d+)/),
+        safariVersion = version(isSafari, /version\/(\d+\.\d+)/),
+        webKitVersion = version(isWebKit, /webkit\/(\d+\.\d+)/),
+        isSecure = /^https/i.test(window.location.protocol);
 
     
     try {
         document.execCommand("BackgroundImageCache", false, true);
     } catch(e) {}
 
-    Ext.setVersion('extjs', '4.0.0');
+
+    Ext.setVersion('extjs', '4.0.7');
     Ext.apply(Ext, {
         
-        SSL_SECURE_URL : Ext.isSecure && isIE ? 'javascript:""' : 'about:blank',
+        SSL_SECURE_URL : isSecure && isIE ? 'javascript:""' : 'about:blank',
 
         
 
@@ -5187,6 +5423,10 @@ window.undefined = window.undefined;
             }
         },
 
+        isStrict: isStrict,
+
+        isIEQuirks: isIE && !isStrict,
+
         
         isOpera : isOpera,
 
@@ -5209,6 +5449,9 @@ window.undefined = window.undefined;
         isSafari4 : isSafari4,
 
         
+        isSafari5 : isSafari5,
+
+        
         isSafari2 : isSafari2,
 
         
@@ -5236,15 +5479,24 @@ window.undefined = window.undefined;
         isGecko4 : isGecko4,
 
         
+        isGecko5 : isGecko5,
 
-        isFF3_0 : isFF3_0,
         
+        isFF3_0 : isFF3_0,
 
+        
         isFF3_5 : isFF3_5,
+
         
         isFF3_6 : isFF3_6,
 
         
+        isFF4 : 4 <= firefoxVersion && firefoxVersion < 5,
+
+        
+        isFF5 : 5 <= firefoxVersion && firefoxVersion < 6,
+
+        
         isLinux : isLinux,
 
         
@@ -5254,7 +5506,28 @@ window.undefined = window.undefined;
         isMac : isMac,
 
         
-        BLANK_IMAGE_URL : (isIE6 || isIE7) ? 'http:/' + '/www.sencha.com/s.gif' : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
+        chromeVersion: chromeVersion,
+
+        
+        firefoxVersion: firefoxVersion,
+
+        
+        ieVersion: ieVersion,
+
+        
+        operaVersion: operaVersion,
+
+        
+        safariVersion: safariVersion,
+
+        
+        webKitVersion: webKitVersion,
+
+        
+        isSecure: isSecure,
+
+        
+        BLANK_IMAGE_URL : (isIE6 || isIE7) ? '/' + '/www.sencha.com/s.gif' : 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
 
         
         value : function(v, defaultValue, allowBlank){
@@ -5291,27 +5564,37 @@ window.undefined = window.undefined;
         },
 
         
-        getScrollBarWidth: function(force){
+        getScrollbarSize: function (force) {
             if(!Ext.isReady){
                 return 0;
             }
 
-            if(force === true || scrollWidth === null){
+            if(force === true || scrollbarSize === null){
                 
                 
                 
-                var cssClass = Ext.isIE9 ? '' : Ext.baseCSSPrefix + 'hide-offsets';
+                var cssClass = Ext.isIE9 ? '' : Ext.baseCSSPrefix + 'hide-offsets',
                     
-                var div = Ext.getBody().createChild('<div class="' + cssClass + '" style="width:100px;height:50px;overflow:hidden;"><div style="height:200px;"></div></div>'),
-                    child = div.child('div', true);
-                var w1 = child.offsetWidth;
+                    div = Ext.getBody().createChild('<div class="' + cssClass + '" style="width:100px;height:50px;overflow:hidden;"><div style="height:200px;"></div></div>'),
+                    child = div.child('div', true),
+                    w1 = child.offsetWidth;
+
                 div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll');
-                var w2 = child.offsetWidth;
+
+                var w2 = child.offsetWidth, width = w1 - w2;
                 div.remove();
+
                 
-                scrollWidth = w1 - w2 + 2;
+                scrollbarSize = { width: width, height: width };
             }
-            return scrollWidth;
+
+            return scrollbarSize;
+        },
+
+        
+        getScrollBarWidth: function(force){
+            var size = Ext.getScrollbarSize(force);
+            return size.width + 2; 
         },
 
         
@@ -5328,7 +5611,7 @@ window.undefined = window.undefined;
         },
 
         
-        destroyMembers : function(o, arg1, arg2, etc){
+        destroyMembers : function(o){
             for (var i = 1, a = arguments, len = a.length; i < len; i++) {
                 Ext.destroy(o[a[i]]);
                 delete o[a[i]];
@@ -5336,6 +5619,10 @@ window.undefined = window.undefined;
         },
 
         
+        log :
+            Ext.emptyFn,
+
+        
         partition : function(arr, truth){
             var ret = [[],[]];
             Ext.each(arr, function(v, i, a) {
@@ -5485,7 +5772,7 @@ Ext.application = function(config) {
             for (; i < decimals; i++) {
                 format += '0';
             }
-            v = UtilFormat.number(v, format); 
+            v = UtilFormat.number(v, format);
             if ((end || UtilFormat.currencyAtEnd) === true) {
                 return Ext.String.format("{0}{1}{2}", negativeSign, v, currencySign || UtilFormat.currencySign);
             } else {
@@ -5555,8 +5842,7 @@ Ext.application = function(config) {
         },
 
         
-        number:
-            function(v, formatString) {
+        number: function(v, formatString) {
             if (!formatString) {
                 return v;
             }
@@ -5593,13 +5879,6 @@ Ext.application = function(config) {
             if (1 < psplit.length) {
                 v = v.toFixed(psplit[1].length);
             } else if(2 < psplit.length) {
-                Ext.Error.raise({
-                    sourceClass: "Ext.util.Format",
-                    sourceMethod: "number",
-                    value: v,
-                    formatString: formatString,
-                    msg: "Invalid number format, should have no more than 1 decimal"
-                });
             } else {
                 v = v.toFixed(0);
             }
@@ -5634,6 +5913,11 @@ Ext.application = function(config) {
                 }
             }
 
+            if (neg) {
+                
+                neg = fnum.replace(/[^1-9]/g, '') !== '';
+            }
+
             return (neg ? '-' : '') + formatString.replace(/[\d,?\.?]+/, fnum);
         },
 
@@ -5982,12 +6266,33 @@ Ext.supports = {
         
         {
             identity: 'RightMargin',
-            fn: function(doc, div, view) {
-                view = doc.defaultView;
+            fn: function(doc, div) {
+                var view = doc.defaultView;
                 return !(view && view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px');
             }
         },
+
+        
+        {
+            identity: 'DisplayChangeInputSelectionBug',
+            fn: function() {
+                var webKitVersion = Ext.webKitVersion;
+                
+                return 0 < webKitVersion && webKitVersion < 533;
+            }
+        },
+
         
+        {
+            identity: 'DisplayChangeTextAreaSelectionBug',
+            fn: function() {
+                var webKitVersion = Ext.webKitVersion;
+
+                
+                return 0 < webKitVersion && webKitVersion < 534.24;
+            }
+        },
+
         
         {
             identity: 'TransparentColor',
@@ -6189,8 +6494,16 @@ Ext.supports = {
                 
                 return range && !!range.createContextualFragment;
             }
-        }
+        },
+
         
+        {
+            identity: 'WindowOnError',
+            fn: function () {
+                
+                return Ext.isIE || Ext.isGecko || Ext.webKitVersion >= 534.16; 
+            }
+        }
     ]
 };
 
@@ -6199,7 +6512,7 @@ Ext.supports = {
 
 
 Ext.ns('Ext.core');
-Ext.core.DomHelper = function(){
+Ext.core.DomHelper = Ext.DomHelper = function(){
     var tempTableEl = null,
         emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i,
         tableRe = /^table|tbody|tr|td$/i,
@@ -6231,11 +6544,11 @@ Ext.core.DomHelper = function(){
                 (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el);
             }
         } else {
-            newNode = Ext.core.DomHelper.insertHtml(pos, el, Ext.core.DomHelper.createHtml(o));
+            newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o));
         }
         return returnElement ? Ext.get(newNode, true) : newNode;
     }
-    
+
     function createDom(o, parentNode){
         var el,
             doc = document,
@@ -6268,7 +6581,7 @@ Ext.core.DomHelper = function(){
                     }
                 }
             }
-            Ext.core.DomHelper.applyStyles(el, o.style);
+            Ext.DomHelper.applyStyles(el, o.style);
 
             if ((cn = o.children || o.cn)) {
                 createDom(cn, el);
@@ -6383,14 +6696,14 @@ Ext.core.DomHelper = function(){
         el.insertBefore(node, before);
         return node;
     }
+
     
-       
     function createContextualFragment(html){
         var div = document.createElement("div"),
             fragment = document.createDocumentFragment(),
             i = 0,
             length, childNodes;
-        
+
         div.innerHTML = html;
         childNodes = div.childNodes;
         length = childNodes.length;
@@ -6401,7 +6714,7 @@ Ext.core.DomHelper = function(){
 
         return fragment;
     }
-    
+
     pub = {
         
         markup : function(o){
@@ -6416,7 +6729,7 @@ Ext.core.DomHelper = function(){
                     styles = styles.call();
                 }
                 if (typeof styles == "string") {
-                    styles = Ext.core.Element.parseStyles(styles);
+                    styles = Ext.Element.parseStyles(styles);
                 }
                 if (typeof styles == "object") {
                     el.setStyle(styles);
@@ -6438,13 +6751,13 @@ Ext.core.DomHelper = function(){
             
             hash[beforebegin] = ['BeforeBegin', 'previousSibling'];
             hash[afterend] = ['AfterEnd', 'nextSibling'];
-            
+
             
             if (el.insertAdjacentHTML) {
                 if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
                     return rs;
                 }
-                
+
                 
                 hash[afterbegin] = ['AfterBegin', 'firstChild'];
                 hash[beforeend] = ['BeforeEnd', 'lastChild'];
@@ -6456,7 +6769,7 @@ Ext.core.DomHelper = function(){
             } else {
                 
                 if (Ext.isTextNode(el)) {
-                    where = where === 'afterbegin' ? 'beforebegin' : where; 
+                    where = where === 'afterbegin' ? 'beforebegin' : where;
                     where = where === 'beforeend' ? 'afterend' : where;
                 }
                 range = Ext.supports.CreateContextualFragment ? el.ownerDocument.createRange() : undefined;
@@ -6479,7 +6792,7 @@ Ext.core.DomHelper = function(){
                         } else {
                             frag = createContextualFragment(html);
                         }
-                        
+
                         if(where == afterbegin){
                             el.insertBefore(frag, el.firstChild);
                         }else{
@@ -6491,13 +6804,6 @@ Ext.core.DomHelper = function(){
                     return el[rangeEl];
                 }
             }
-            Ext.Error.raise({
-                sourceClass: 'Ext.core.DomHelper',
-                sourceMethod: 'insertHtml',
-                htmlToInsert: html,
-                targetElement: el,
-                msg: 'Illegal insertion point reached: "' + where + '"'
-            });
         },
 
         
@@ -6528,16 +6834,16 @@ Ext.core.DomHelper = function(){
         },
 
         createHtml : createHtml,
-        
+
         
         createDom: createDom,
-        
+
         
         useDom : false,
-        
+
         
         createTemplate : function(o){
-            var html = Ext.core.DomHelper.createHtml(o);
+            var html = Ext.DomHelper.createHtml(o);
             return Ext.create('Ext.Template', html);
         }
     };
@@ -6559,6 +6865,7 @@ Ext.core.DomQuery = Ext.DomQuery = function(){
         tagTokenRe = /^(#)?([\w-\*]+)/,
         nthRe = /(\d*)n\+?(\d*)/,
         nthRe2 = /\D/,
+        startIdRe = /^\s*\#/,
         
     
     
@@ -6976,11 +7283,6 @@ Ext.core.DomQuery = Ext.DomQuery = function(){
                     }
                     
                     if(!matched){
-                        Ext.Error.raise({
-                            sourceClass: 'Ext.DomQuery',
-                            sourceMethod: 'compile',
-                            msg: 'Error parsing selector. Parsing failed at "' + path + '"'
-                        });
                     }
                 }
                 if(modeMatch[1]){
@@ -7014,11 +7316,6 @@ Ext.core.DomQuery = Ext.DomQuery = function(){
                 if(!cache[subPath]){
                     cache[subPath] = Ext.DomQuery.compile(subPath);
                     if(!cache[subPath]){
-                        Ext.Error.raise({
-                            sourceClass: 'Ext.DomQuery',
-                            sourceMethod: 'jsSelect',
-                            msg: subPath + ' is not a valid selector'
-                        });
                     }
                 }
                 var result = cache[subPath](root);
@@ -7039,15 +7336,26 @@ Ext.core.DomQuery = Ext.DomQuery = function(){
             var docEl = (el ? el.ownerDocument || el : 0).documentElement;
             return docEl ? docEl.nodeName !== "HTML" : false;
         },
+
         
         select : document.querySelectorAll ? function(path, root, type) {
             root = root || document;
-            if (!Ext.DomQuery.isXml(root)) {
-            try {
-                var cs = root.querySelectorAll(path);
-                return Ext.Array.toArray(cs);
-            }
-            catch (ex) {}
+            
+            if (!Ext.DomQuery.isXml(root) && !(Ext.isSafari3 && !Ext.isStrict)) { 
+                try {
+                    
+                    var isDocumentRoot = root.nodeType === 9,
+                        _path = path,
+                        _root = root;
+
+                    if (!isDocumentRoot && path.indexOf(',') === -1 && !startIdRe.test(path)) {
+                        _path = '#' + Ext.id(root) + ' ' + path;
+                        _root = root.parentNode;
+                    }
+                    return Ext.Array.toArray(_root.querySelectorAll(_path));
+                }
+                catch (e) {
+                }
             }
             return Ext.DomQuery.jsSelect.call(this, path, root, type);
         } : function(path, root, type) {
@@ -7366,8 +7674,8 @@ Ext.query = Ext.DomQuery.select;
         this.id = id || Ext.id(dom);
     };
 
-    var DH = Ext.core.DomHelper,
-    El = Ext.core.Element;
+    var DH = Ext.DomHelper,
+    El = Ext.Element;
 
 
     El.prototype = {
@@ -7514,15 +7822,12 @@ Ext.query = Ext.DomQuery.select;
             }
 
             
-            if (size === "" || size == "auto" || size === undefined || size === null) {
+            if (size === "" || size == "auto" || size == null) {
                 return size || '';
             }
 
             
             if (!unitPattern.test(size)) {
-                if (Ext.isDefined(Ext.global.console)) {
-                    Ext.global.console.warn("Warning, size detected as NaN on Element.addUnits.");
-                }
                 return size || '';
             }
             return size;
@@ -7554,7 +7859,7 @@ Ext.query = Ext.DomQuery.select;
 
         
         contains: function(el) {
-            return ! el ? false: Ext.core.Element.isAncestor(this.dom, el.dom ? el.dom: el);
+            return ! el ? false: Ext.Element.isAncestor(this.dom, el.dom ? el.dom: el);
         },
 
         
@@ -7681,6 +7986,31 @@ Ext.query = Ext.DomQuery.select;
         return null;
     };
 
+    
+    ep.getById = (!Ext.isIE6 && !Ext.isIE7 && !Ext.isIE8) ? El.get :
+        function (id) {
+            var dom = this.dom,
+                cached, el, ret;
+
+            if (dom) {
+                el = dom.all[id];
+                if (el) {
+                    
+                    
+                    cached = EC[id];
+                    if (cached && cached.el) {
+                        ret = cached.el;
+                        ret.dom = el;
+                    } else {
+                        ret = El.addToCache(new El(el));
+                    }
+                    return ret;
+                }
+            }
+
+            return El.get(id);
+        };
+
     El.addToCache = function(el, id) {
         if (el) {
             id = id || el.id;
@@ -7812,7 +8142,7 @@ Ext.query = Ext.DomQuery.select;
 })();
 
 
-Ext.core.Element.addMethods({
+Ext.Element.addMethods({
     
     findParent : function(simpleSelector, maxDepth, returnEl) {
         var p = this.dom,
@@ -7834,7 +8164,7 @@ Ext.core.Element.addMethods({
         }
         return null;
     },
-    
+
     
     findParentNode : function(simpleSelector, maxDepth, returnEl) {
         var p = Ext.fly(this.dom.parentNode, '_internal');
@@ -7848,7 +8178,7 @@ Ext.core.Element.addMethods({
 
     
     select : function(selector) {
-        return Ext.core.Element.select(selector, false,  this.dom);
+        return Ext.Element.select(selector, false,  this.dom);
     },
 
     
@@ -7904,7 +8234,7 @@ Ext.core.Element.addMethods({
         if (!this.dom) {
             return null;
         }
-        
+
         var n = this.dom[start];
         while (n) {
             if (n.nodeType == 1 && (!selector || Ext.DomQuery.is(n, selector))) {
@@ -7917,7 +8247,7 @@ Ext.core.Element.addMethods({
 });
 
 
-Ext.core.Element.addMethods({
+Ext.Element.addMethods({
     
     appendChild : function(el) {
         return Ext.get(el).appendTo(this);
@@ -7982,9 +8312,9 @@ Ext.core.Element.addMethods({
             }
         }else{
             if (isAfter && !me.dom.nextSibling) {
-                rt = Ext.core.DomHelper.append(me.dom.parentNode, el, !returnDom);
+                rt = Ext.DomHelper.append(me.dom.parentNode, el, !returnDom);
             } else {
-                rt = Ext.core.DomHelper[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
+                rt = Ext.DomHelper[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
             }
         }
         return rt;
@@ -8006,13 +8336,13 @@ Ext.core.Element.addMethods({
             el = Ext.get(el);
             me.dom.parentNode.insertBefore(el, me.dom);
         }else{
-            el = Ext.core.DomHelper.insertBefore(me.dom, el);
+            el = Ext.DomHelper.insertBefore(me.dom, el);
         }
         
         delete Ext.cache[me.id];
         Ext.removeNode(me.dom);      
         me.id = Ext.id(me.dom = el);
-        Ext.core.Element.addToCache(me.isFlyweight ? new Ext.core.Element(me.dom) : me);     
+        Ext.Element.addToCache(me.isFlyweight ? new Ext.Element(me.dom) : me);     
         return me;
     },
     
@@ -8020,16 +8350,16 @@ Ext.core.Element.addMethods({
     createChild : function(config, insertBefore, returnDom) {
         config = config || {tag:'div'};
         if (insertBefore) {
-            return Ext.core.DomHelper.insertBefore(insertBefore, config, returnDom !== true);
+            return Ext.DomHelper.insertBefore(insertBefore, config, returnDom !== true);
         }
         else {
-            return Ext.core.DomHelper[!this.dom.firstChild ? 'insertFirst' : 'append'](this.dom, config,  returnDom !== true);
+            return Ext.DomHelper[!this.dom.firstChild ? 'insertFirst' : 'append'](this.dom, config,  returnDom !== true);
         }
     },
 
     
     wrap : function(config, returnDom) {
-        var newEl = Ext.core.DomHelper.insertBefore(this.dom, config || {tag: "div"}, !returnDom),
+        var newEl = Ext.DomHelper.insertBefore(this.dom, config || {tag: "div"}, !returnDom),
             d = newEl.dom || newEl;
 
         d.appendChild(this.dom);
@@ -8038,16 +8368,16 @@ Ext.core.Element.addMethods({
 
     
     insertHtml : function(where, html, returnEl) {
-        var el = Ext.core.DomHelper.insertHtml(where, this.dom, html);
+        var el = Ext.DomHelper.insertHtml(where, this.dom, html);
         return returnEl ? Ext.get(el) : el;
     }
 });
 
 
 (function(){
-    Ext.core.Element.boxMarkup = '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div><div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div><div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';
     
-    var supports = Ext.supports,
+    var ELEMENT = Ext.Element,
+        supports = Ext.supports,
         view = document.defaultView,
         opacityRe = /alpha\(opacity=(.*)\)/i,
         trimRe = /^\s+|\s+$/g,
@@ -8074,16 +8404,26 @@ Ext.core.Element.addMethods({
         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},
-        data = Ext.core.Element.data;
+        data = ELEMENT.data;
+
+    ELEMENT.boxMarkup = '<div class="{0}-tl"><div class="{0}-tr"><div class="{0}-tc"></div></div></div><div class="{0}-ml"><div class="{0}-mr"><div class="{0}-mc"></div></div></div><div class="{0}-bl"><div class="{0}-br"><div class="{0}-bc"></div></div></div>';
+
+    
+    
+    ELEMENT.inheritedProps = {
+        fontSize: 1,
+        fontStyle: 1,
+        opacity: 1
+    };
+
+    Ext.override(ELEMENT, {
 
-    Ext.override(Ext.core.Element, {
-        
         
         
         adjustWidth : function(width) {
             var me = this,
                 isNum = (typeof width == 'number');
-                
+
             if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
                width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
             }
@@ -8094,7 +8434,7 @@ Ext.core.Element.addMethods({
         adjustHeight : function(height) {
             var me = this,
                 isNum = (typeof height == "number");
-                
+
             if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
                height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
             }
@@ -8108,11 +8448,11 @@ Ext.core.Element.addMethods({
                 cls = [],
                 space = ((me.dom.className.replace(trimRe, '') == '') ? "" : " "),
                 i, len, v;
-            if (!Ext.isDefined(className)) {
+            if (className === undefined) {
                 return me;
             }
             
-            if (!Ext.isArray(className)) {
+            if (Object.prototype.toString.call(className) !== '[object Array]') {
                 if (typeof className === 'string') {
                     className = className.replace(trimRe, '').split(spacesRe);
                     if (className.length === 1) {
@@ -8142,10 +8482,10 @@ Ext.core.Element.addMethods({
         removeCls : function(className){
             var me = this,
                 i, idx, len, cls, elClasses;
-            if (!Ext.isDefined(className)) {
+            if (className === undefined) {
                 return me;
             }
-            if (!Ext.isArray(className)){
+            if (Object.prototype.toString.call(className) !== '[object Array]') {
                 className = className.replace(trimRe, '').split(spacesRe);
             }
             if (me.dom && me.dom.className) {
@@ -8156,7 +8496,7 @@ Ext.core.Element.addMethods({
                         cls = cls.replace(trimRe, '');
                         idx = Ext.Array.indexOf(elClasses, cls);
                         if (idx != -1) {
-                            elClasses.splice(idx, 1);
+                            Ext.Array.erase(elClasses, idx, 1);
                         }
                     }
                 }
@@ -8219,56 +8559,83 @@ Ext.core.Element.addMethods({
         },
 
         
-        getStyle : function(){
+        getStyle : function() {
             return view && view.getComputedStyle ?
                 function(prop){
                     var el = this.dom,
-                        v, cs, out, display;
+                        v, cs, out, display, cleaner;
 
                     if(el == document){
                         return null;
                     }
-                    prop = Ext.core.Element.normalize(prop);
+                    prop = ELEMENT.normalize(prop);
                     out = (v = el.style[prop]) ? v :
                            (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
-                           
+
                     
                     
                     if(prop == 'marginRight' && out != '0px' && !supports.RightMargin){
+                        cleaner = ELEMENT.getRightMarginFixCleaner(el);
                         display = this.getStyle('display');
                         el.style.display = 'inline-block';
                         out = view.getComputedStyle(el, '').marginRight;
                         el.style.display = display;
+                        cleaner();
                     }
-                    
+
                     if(prop == 'backgroundColor' && out == 'rgba(0, 0, 0, 0)' && !supports.TransparentColor){
                         out = 'transparent';
                     }
                     return out;
                 } :
-                function(prop){
+                function (prop) {
                     var el = this.dom,
                         m, cs;
 
                     if (el == document) {
                         return null;
                     }
-                    
-                    if (prop == 'opacity') {
-                        if (el.style.filter.match) {
-                            m = el.style.filter.match(opacityRe);
-                            if(m){
-                                var fv = parseFloat(m[1]);
-                                if(!isNaN(fv)){
-                                    return fv ? fv / 100 : 0;
+                    prop = ELEMENT.normalize(prop);
+
+                    do {
+                        if (prop == 'opacity') {
+                            if (el.style.filter.match) {
+                                m = el.style.filter.match(opacityRe);
+                                if(m){
+                                    var fv = parseFloat(m[1]);
+                                    if(!isNaN(fv)){
+                                        return fv ? fv / 100 : 0;
+                                    }
                                 }
                             }
+                            return 1;
                         }
-                        return 1;
-                    }
-                    prop = Ext.core.Element.normalize(prop);
-                    return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
-                };
+
+                        
+                        
+                        if (!Ext.isIE6) {
+                            return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
+                        }
+
+                        try {
+                            return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
+                        } catch (e) {
+                            
+                            
+                        }
+
+                        if (!ELEMENT.inheritedProps[prop]) {
+                            break;
+                        }
+
+                        el = el.parentNode;
+                        
+                        
+                        
+                    } while (el);
+
+                    return null;
+                }
         }(),
 
         
@@ -8300,8 +8667,7 @@ Ext.core.Element.addMethods({
             if (!me.dom) {
                 return me;
             }
-
-            if (!Ext.isObject(prop)) {
+            if (typeof prop === 'string') {
                 tmp = {};
                 tmp[prop] = value;
                 prop = tmp;
@@ -8313,7 +8679,7 @@ Ext.core.Element.addMethods({
                         me.setOpacity(value);
                     }
                     else {
-                        me.dom.style[Ext.core.Element.normalize(style)] = value;
+                        me.dom.style[ELEMENT.normalize(style)] = value;
                     }
                 }
             }
@@ -8375,7 +8741,7 @@ Ext.core.Element.addMethods({
             }
             return this;
         },
-        
+
         
         adjustDirect2DDimension: function(dimension) {
             var me = this,
@@ -8385,7 +8751,7 @@ Ext.core.Element.addMethods({
                 inlinePosition = dom.style['position'],
                 originIndex = dimension === 'width' ? 0 : 1,
                 floating;
-                
+
             if (display === 'inline') {
                 dom.style['display'] = 'inline-block';
             }
@@ -8395,16 +8761,16 @@ Ext.core.Element.addMethods({
             
             
             floating = (parseFloat(me.getStyle(dimension)) || parseFloat(dom.currentStyle.msTransformOrigin.split(' ')[originIndex]) * 2) % 1;
-            
+
             dom.style['position'] = inlinePosition;
-            
+
             if (display === 'inline') {
                 dom.style['display'] = inlineDisplay;
             }
 
             return floating;
         },
-        
+
         
         getHeight: function(contentHeight, preciseHeight) {
             var me = this,
@@ -8448,7 +8814,7 @@ Ext.core.Element.addMethods({
             }
             return height;
         },
-                
+
         
         getWidth: function(contentWidth, preciseWidth) {
             var me = this,
@@ -8463,7 +8829,7 @@ Ext.core.Element.addMethods({
                 overflow = style.overflow;
                 me.setStyle({overflow: 'hidden'});
             }
-            
+
             
             if (Ext.isOpera10_5) {
                 if (dom.parentNode.currentStyle.position === 'relative') {
@@ -8473,7 +8839,7 @@ Ext.core.Element.addMethods({
                     dom.parentNode.style.position = parentPosition;
                 }
                 width = Math.max(width || 0, dom.offsetWidth);
-            
+
             
             
             
@@ -8499,11 +8865,11 @@ Ext.core.Element.addMethods({
                     width++;
                 }
             }
-            
+
             if (contentWidth) {
                 width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
             }
-            
+
             if (Ext.isIEQuirks) {
                 me.setStyle({ overflow: overflow});
             }
@@ -8592,14 +8958,14 @@ Ext.core.Element.addMethods({
             if(data(dom, ISCLIPPED)){
                 data(dom, ISCLIPPED, false);
                 clip = data(dom, ORIGINALCLIP);
-                if(o.o){
-                    me.setStyle(OVERFLOW, o.o);
+                if(clip.o){
+                    me.setStyle(OVERFLOW, clip.o);
                 }
-                if(o.x){
-                    me.setStyle(OVERFLOWX, o.x);
+                if(clip.x){
+                    me.setStyle(OVERFLOWX, clip.x);
                 }
-                if(o.y){
-                    me.setStyle(OVERFLOWY, o.y);
+                if(clip.y){
+                    me.setStyle(OVERFLOWY, clip.y);
                 }
             }
             return me;
@@ -8623,10 +8989,10 @@ Ext.core.Element.addMethods({
         },
 
         margins : margins,
-        
+
         
         applyStyles : function(style){
-            Ext.core.DomHelper.applyStyles(this.dom, style);
+            Ext.DomHelper.applyStyles(this.dom, style);
             return this;
         },
 
@@ -8635,7 +9001,7 @@ Ext.core.Element.addMethods({
             var styles = {},
                 len = arguments.length,
                 i = 0, style;
-                
+
             for(; i < len; ++i) {
                 style = arguments[i];
                 styles[style] = this.getStyle(style);
@@ -8646,7 +9012,7 @@ Ext.core.Element.addMethods({
        
         boxWrap : function(cls){
             cls = cls || Ext.baseCSSPrefix + 'box';
-            var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + Ext.String.format(Ext.core.Element.boxMarkup, cls) + "</div>"));
+            var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + Ext.String.format(ELEMENT.boxMarkup, cls) + "</div>"));
             Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
             return el;
         },
@@ -8654,18 +9020,24 @@ Ext.core.Element.addMethods({
         
         setSize : function(width, height, animate){
             var me = this;
-            if (Ext.isObject(width)){ 
+            if (Ext.isObject(width)) { 
+                animate = height;
                 height = width.height;
                 width = width.width;
             }
             width = me.adjustWidth(width);
             height = me.adjustHeight(height);
             if(!animate || !me.anim){
+                
+                
+                if (!Ext.isIEQuirks && (Ext.isIE6 || Ext.isIE7)) {
+                    me.dom.offsetTop;
+                }
                 me.dom.style.width = me.addUnits(width);
                 me.dom.style.height = me.addUnits(height);
             }
             else {
-                if (!Ext.isObject(animate)) {
+                if (animate === true) {
                     animate = {};
                 }
                 me.animate(Ext.applyIf({
@@ -8695,7 +9067,7 @@ Ext.core.Element.addMethods({
         getComputedWidth : function(){
             var me = this,
                 w = Math.max(me.dom.offsetWidth, me.dom.clientWidth);
-                
+
             if(!w){
                 w = parseFloat(me.getStyle('width')) || 0;
                 if(!me.isBorderBox()){
@@ -8763,8 +9135,8 @@ Ext.core.Element.addMethods({
             
             if (isDoc) {
                 ret = {
-                    width : Ext.core.Element.getViewWidth(),
-                    height : Ext.core.Element.getViewHeight()
+                    width : ELEMENT.getViewWidth(),
+                    height : ELEMENT.getViewHeight()
                 };
 
             
@@ -8801,8 +9173,8 @@ Ext.core.Element.addMethods({
             
             if (isDoc) {
                 return {
-                    width : Ext.core.Element.getViewWidth(),
-                    height : Ext.core.Element.getViewHeight()
+                    width : ELEMENT.getViewWidth(),
+                    height : ELEMENT.getViewHeight()
                 };
             }
             
@@ -8839,14 +9211,28 @@ Ext.core.Element.addMethods({
         },
 
         
+        selectable : function() {
+            var me = this;
+            me.dom.unselectable = "off";
+            
+            me.on('selectstart', function (e) {
+                e.stopPropagation();
+                return true;
+            });
+            me.applyStyles("-moz-user-select: text; -khtml-user-select: text;");
+            me.removeCls(Ext.baseCSSPrefix + 'unselectable');
+            return me;
+        },
+
+        
         unselectable : function(){
             var me = this;
             me.dom.unselectable = "on";
 
             me.swallowEvent("selectstart", true);
-            me.applyStyles("-moz-user-select:none;-khtml-user-select:none;");
+            me.applyStyles("-moz-user-select:-moz-none;-khtml-user-select:none;");
             me.addCls(Ext.baseCSSPrefix + 'unselectable');
-            
+
             return me;
         },
 
@@ -8870,21 +9256,21 @@ Ext.core.Element.addMethods({
 })();
 
 
-Ext.core.Element.VISIBILITY = 1;
+Ext.Element.VISIBILITY = 1;
 
-Ext.core.Element.DISPLAY = 2;
+Ext.Element.DISPLAY = 2;
 
 
-Ext.core.Element.OFFSETS = 3;
+Ext.Element.OFFSETS = 3;
 
 
-Ext.core.Element.ASCLASS = 4;
+Ext.Element.ASCLASS = 4;
 
 
-Ext.core.Element.visibilityCls = Ext.baseCSSPrefix + 'hide-nosize';
+Ext.Element.visibilityCls = Ext.baseCSSPrefix + 'hide-nosize';
 
-Ext.core.Element.addMethods(function(){
-    var El = Ext.core.Element,
+Ext.Element.addMethods(function(){
+    var El = Ext.Element,
         OPACITY = "opacity",
         VISIBILITY = "visibility",
         DISPLAY = "display",
@@ -9088,7 +9474,7 @@ Ext.core.Element.addMethods(function(){
     };
 }());
 
-Ext.applyIf(Ext.core.Element.prototype, {
+Ext.applyIf(Ext.Element.prototype, {
     
     animate: function(config) {
         var me = this;
@@ -9166,7 +9552,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
     },
 
     
-    slideIn: function(anchor, obj, slideOut) { 
+    slideIn: function(anchor, obj, slideOut) {
         var me = this,
             elStyle = me.dom.style,
             beforeAnim, wrapAnim;
@@ -9184,13 +9570,13 @@ Ext.applyIf(Ext.core.Element.prototype, {
             }
 
             box = me.getBox();
-            if ((anchor == 't' || anchor == 'b') && box.height == 0) {
+            if ((anchor == 't' || anchor == 'b') && box.height === 0) {
                 box.height = me.dom.scrollHeight;
             }
-            else if ((anchor == 'l' || anchor == 'r') && box.width == 0) {
+            else if ((anchor == 'l' || anchor == 'r') && box.width === 0) {
                 box.width = me.dom.scrollWidth;
             }
-            
+
             position = me.getPositioning();
             me.setSize(box.width, box.height);
 
@@ -9354,7 +9740,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
                     if (obj.useDisplay) {
                         me.setDisplayed(false);
                     } else {
-                        me.hide();   
+                        me.hide();
                     }
                 }
                 else {
@@ -9362,7 +9748,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
                     me.setPositioning(position);
                 }
                 if (wrap.dom) {
-                    wrap.dom.parentNode.insertBefore(me.dom, wrap.dom); 
+                    wrap.dom.parentNode.insertBefore(me.dom, wrap.dom);
                     wrap.remove();
                 }
                 me.setSize(box.width, box.height);
@@ -9392,14 +9778,13 @@ Ext.applyIf(Ext.core.Element.prototype, {
         return me;
     },
 
-    
+
     
     slideOut: function(anchor, o) {
         return this.slideIn(anchor, o, true);
     },
 
     
-
     puff: function(obj) {
         var me = this,
             beforeAnim;
@@ -9431,7 +9816,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
                     } else {
                         me.hide();
                     }
-                    me.clearOpacity();  
+                    me.clearOpacity();
                     me.setPositioning(position);
                     me.setStyle({fontSize: fontSize});
                 }
@@ -9454,7 +9839,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
     switchOff: function(obj) {
         var me = this,
             beforeAnim;
-        
+
         obj = Ext.applyIf(obj || {}, {
             easing: 'ease-in',
             duration: 500,
@@ -9494,7 +9879,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
                     me.setDisplayed(false);
                 } else {
                     me.hide();
-                }  
+                }
                 me.clearOpacity();
                 me.setPositioning(position);
                 me.setSize(size);
@@ -9512,7 +9897,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
         return me;
     },
 
-   
+    
     frame : function(color, count, obj){
         var me = this,
             beforeAnim;
@@ -9638,7 +10023,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
         return me;
     },
 
-     
+    
     highlight: function(color, o) {
         var me = this,
             dom = me.dom,
@@ -9649,7 +10034,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
         lns = o.listeners || {};
         attr = o.attr || 'backgroundColor';
         from[attr] = color || 'ffff9c';
-        
+
         if (!o.to) {
             to = {};
             to[attr] = o.endColor || me.getColor(attr, 'ffffff', '');
@@ -9657,14 +10042,14 @@ Ext.applyIf(Ext.core.Element.prototype, {
         else {
             to = o.to;
         }
-        
+
         
         o.listeners = Ext.apply(Ext.apply({}, lns), {
             beforeanimate: function() {
                 restore = dom.style[attr];
                 me.clearOpacity();
                 me.show();
-                
+
                 event = lns.beforeanimate;
                 if (event) {
                     fn = event.fn || event;
@@ -9675,7 +10060,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
                 if (dom) {
                     dom.style[attr] = restore;
                 }
-                
+
                 event = lns.afteranimate;
                 if (event) {
                     fn = event.fn || event;
@@ -9702,7 +10087,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
         return me;
     },
 
-   
+    
     fadeIn: function(o) {
         this.animate(Ext.apply({}, o, {
             opacity: 1
@@ -9710,7 +10095,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
         return this;
     },
 
-   
+    
     fadeOut: function(o) {
         this.animate(Ext.apply({}, o, {
             opacity: 0
@@ -9718,7 +10103,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
         return this;
     },
 
-   
+    
     scale: function(w, h, o) {
         this.animate(Ext.apply({}, o, {
             width: w,
@@ -9727,7 +10112,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
         return this;
     },
 
-   
+    
     shift: function(config) {
         this.animate(config);
         return this;
@@ -9735,7 +10120,7 @@ Ext.applyIf(Ext.core.Element.prototype, {
 });
 
 
-Ext.applyIf(Ext.core.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,
@@ -9747,7 +10132,7 @@ Ext.applyIf(Ext.core.Element, {
     margins: {l: 'margin-left', r: 'margin-right', t: 'margin-top', b: 'margin-bottom'},
 
     
-    addUnits : Ext.core.Element.prototype.addUnits,
+    addUnits : Ext.Element.prototype.addUnits,
 
     
     parseBox : function(box) {
@@ -9878,7 +10263,7 @@ Ext.CompositeElementLite = function(els, root){
     
     this.elements = [];
     this.add(els, root);
-    this.el = new Ext.core.Element.Flyweight();
+    this.el = new Ext.Element.Flyweight();
 };
 
 Ext.CompositeElementLite.prototype = {
@@ -9910,7 +10295,7 @@ Ext.CompositeElementLite.prototype = {
             return this;
         }
         if(typeof els == "string"){
-            els = Ext.core.Element.selectorFunction(els, root);
+            els = Ext.Element.selectorFunction(els, root);
         }else if(els.isComposite){
             els = els.elements;
         }else if(!Ext.isIterable(els)){
@@ -9933,7 +10318,7 @@ Ext.CompositeElementLite.prototype = {
         for(i = 0; i < len; i++) {
             e = els[i];
             if(e){
-                Ext.core.Element.prototype[fn].apply(me.getElement(e), args);
+                Ext.Element.prototype[fn].apply(me.getElement(e), args);
             }
         }
         return me;
@@ -10005,7 +10390,7 @@ Ext.CompositeElementLite.prototype = {
                 els[els.length] = me.transformElement(el);
             }
         });
-        
+
         me.elements = els;
         return me;
     },
@@ -10026,7 +10411,7 @@ Ext.CompositeElementLite.prototype = {
                 d.parentNode.insertBefore(replacement, d);
                 Ext.removeNode(d);
             }
-            this.elements.splice(index, 1, replacement);
+            Ext.Array.splice(this.elements, index, 1, replacement);
         }
         return this;
     },
@@ -10042,7 +10427,7 @@ Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addLi
 
 Ext.CompositeElementLite.importElementMethods = function() {
     var fnName,
-        ElProto = Ext.core.Element.prototype,
+        ElProto = Ext.Element.prototype,
         CelProto = Ext.CompositeElementLite.prototype;
 
     for (fnName in ElProto) {
@@ -10060,29 +10445,22 @@ Ext.CompositeElementLite.importElementMethods = function() {
 Ext.CompositeElementLite.importElementMethods();
 
 if(Ext.DomQuery){
-    Ext.core.Element.selectorFunction = Ext.DomQuery.select;
+    Ext.Element.selectorFunction = Ext.DomQuery.select;
 }
 
 
-Ext.core.Element.select = function(selector, root){
+Ext.Element.select = function(selector, root){
     var els;
     if(typeof selector == "string"){
-        els = Ext.core.Element.selectorFunction(selector, root);
+        els = Ext.Element.selectorFunction(selector, root);
     }else if(selector.length !== undefined){
         els = selector;
     }else{
-        Ext.Error.raise({
-            sourceClass: "Ext.core.Element",
-            sourceMethod: "select",
-            selector: selector,
-            root: root,
-            msg: "Invalid selector specified: " + selector
-        });
     }
     return new Ext.CompositeElementLite(els);
 };
 
-Ext.select = Ext.core.Element.select;
+Ext.select = Ext.Element.select;
 
 
 Ext.util.DelayedTask = function(fn, scope, args) {
@@ -10153,13 +10531,6 @@ Ext.require('Ext.util.DelayedTask', function() {
                     listener;
                     scope = scope || me.observable;
 
-                if (!fn) {
-                    Ext.Error.raise({
-                        sourceClass: Ext.getClassName(this.observable),
-                        sourceMethod: "addListener",
-                        msg: "The specified callback function is undefined"
-                    });
-                }
 
                 if (!me.isListening(fn, scope)) {
                     listener = me.createListener(fn, scope, options);
@@ -10251,7 +10622,7 @@ Ext.require('Ext.util.DelayedTask', function() {
                     }
 
                     
-                    me.listeners.splice(index, 1);
+                    Ext.Array.erase(me.listeners, index, 1);
                     return true;
                 }
 
@@ -10322,6 +10693,7 @@ Ext.EventManager = {
 
         if(window.attachEvent){
             
+            
             if (window != top) {
                 return false;
             }
@@ -10426,9 +10798,9 @@ Ext.EventManager = {
     getId : function(element) {
         var skipGarbageCollection = false,
             id;
-    
+
         element = Ext.getDom(element);
-    
+
         if (element === document || element === window) {
             id = element === document ? Ext.documentId : Ext.windowId;
         }
@@ -10439,9 +10811,9 @@ Ext.EventManager = {
         if (element && (element.getElementById || element.navigator)) {
             skipGarbageCollection = true;
         }
-    
+
         if (!Ext.cache[id]){
-            Ext.core.Element.addToCache(new Ext.core.Element(element), id);
+            Ext.Element.addToCache(new Ext.Element(element), id);
             if (skipGarbageCollection) {
                 Ext.cache[id].skipGarbageCollection = true;
             }
@@ -10519,7 +10891,7 @@ Ext.EventManager = {
     
     addListener: function(element, eventName, fn, scope, options){
         
-        if (Ext.isObject(eventName)) {
+        if (typeof eventName !== 'string') {
             this.prepareListenerConfig(element, eventName);
             return;
         }
@@ -10528,24 +10900,6 @@ Ext.EventManager = {
             bind,
             wrap;
 
-        if (!dom){
-            Ext.Error.raise({
-                sourceClass: 'Ext.EventManager',
-                sourceMethod: 'addListener',
-                targetElement: element,
-                eventName: eventName,
-                msg: 'Error adding "' + eventName + '\" listener for nonexistent element "' + element + '"'
-            });
-        }
-        if (!fn) {
-            Ext.Error.raise({
-                sourceClass: 'Ext.EventManager',
-                sourceMethod: 'addListener',
-                targetElement: element,
-                eventName: eventName,
-                msg: 'Error adding "' + eventName + '\" listener. The handler function is undefined.'
-            });
-        }
 
         
         options = options || {};
@@ -10575,7 +10929,7 @@ Ext.EventManager = {
     
     removeListener : function(element, eventName, fn, scope) {
         
-        if (Ext.isObject(eventName)) {
+        if (typeof eventName !== 'string') {
             this.prepareListenerConfig(element, eventName, true);
             return;
         }
@@ -10619,7 +10973,7 @@ Ext.EventManager = {
                 }
 
                 
-                cache.splice(i, 1);
+                Ext.Array.erase(cache, i, 1);
             }
         }
     },
@@ -10662,83 +11016,94 @@ Ext.EventManager = {
 
     
     createListenerWrap : function(dom, ename, fn, scope, options) {
-        options = !Ext.isObject(options) ? {} : options;
+        options = options || {};
 
-        var f = ['if(!Ext) {return;}'],
-            gen;
+        var f, gen;
 
-        if(options.buffer || options.delay || options.freezeEvent) {
-            f.push('e = new Ext.EventObjectImpl(e, ' + (options.freezeEvent ? 'true' : 'false' ) + ');');
-        } else {
-            f.push('e = Ext.EventObject.setEvent(e);');
-        }
+        return function wrap(e, args) {
+            
+            if (!gen) {
+                f = ['if(!Ext) {return;}'];
 
-        if (options.delegate) {
-            f.push('var t = e.getTarget("' + options.delegate + '", this);');
-            f.push('if(!t) {return;}');
-        } else {
-            f.push('var t = e.target;');
-        }
+                if(options.buffer || options.delay || options.freezeEvent) {
+                    f.push('e = new Ext.EventObjectImpl(e, ' + (options.freezeEvent ? 'true' : 'false' ) + ');');
+                } else {
+                    f.push('e = Ext.EventObject.setEvent(e);');
+                }
 
-        if (options.target) {
-            f.push('if(e.target !== options.target) {return;}');
-        }
+                if (options.delegate) {
+                    f.push('var t = e.getTarget("' + options.delegate + '", this);');
+                    f.push('if(!t) {return;}');
+                } else {
+                    f.push('var t = e.target;');
+                }
 
-        if(options.stopEvent) {
-            f.push('e.stopEvent();');
-        } else {
-            if(options.preventDefault) {
-                f.push('e.preventDefault();');
-            }
-            if(options.stopPropagation) {
-                f.push('e.stopPropagation();');
-            }
-        }
+                if (options.target) {
+                    f.push('if(e.target !== options.target) {return;}');
+                }
 
-        if(options.normalized === false) {
-            f.push('e = e.browserEvent;');
-        }
+                if(options.stopEvent) {
+                    f.push('e.stopEvent();');
+                } else {
+                    if(options.preventDefault) {
+                        f.push('e.preventDefault();');
+                    }
+                    if(options.stopPropagation) {
+                        f.push('e.stopPropagation();');
+                    }
+                }
 
-        if(options.buffer) {
-            f.push('(wrap.task && clearTimeout(wrap.task));');
-            f.push('wrap.task = setTimeout(function(){');
-        }
+                if(options.normalized === false) {
+                    f.push('e = e.browserEvent;');
+                }
 
-        if(options.delay) {
-            f.push('wrap.tasks = wrap.tasks || [];');
-            f.push('wrap.tasks.push(setTimeout(function(){');
-        }
+                if(options.buffer) {
+                    f.push('(wrap.task && clearTimeout(wrap.task));');
+                    f.push('wrap.task = setTimeout(function(){');
+                }
 
-        
-        f.push('fn.call(scope || dom, e, t, options);');
+                if(options.delay) {
+                    f.push('wrap.tasks = wrap.tasks || [];');
+                    f.push('wrap.tasks.push(setTimeout(function(){');
+                }
 
-        if(options.single) {
-            f.push('Ext.EventManager.removeListener(dom, ename, fn, scope);');
-        }
+                
+                f.push('fn.call(scope || dom, e, t, options);');
 
-        if(options.delay) {
-            f.push('}, ' + options.delay + '));');
-        }
+                if(options.single) {
+                    f.push('Ext.EventManager.removeListener(dom, ename, fn, scope);');
+                }
 
-        if(options.buffer) {
-            f.push('}, ' + options.buffer + ');');
-        }
+                if(options.delay) {
+                    f.push('}, ' + options.delay + '));');
+                }
 
-        gen = Ext.functionFactory('e', 'options', 'fn', 'scope', 'ename', 'dom', 'wrap', 'args', f.join('\n'));
+                if(options.buffer) {
+                    f.push('}, ' + options.buffer + ');');
+                }
+
+                gen = Ext.functionFactory('e', 'options', 'fn', 'scope', 'ename', 'dom', 'wrap', 'args', f.join('\n'));
+            }
 
-        return function wrap(e, args) {
             gen.call(dom, e, options, fn, scope, ename, dom, wrap, args);
         };
     },
 
     
     getEventListenerCache : function(element, eventName) {
+        if (!element) {
+            return [];
+        }
+
         var eventCache = this.getElementEventCache(element);
         return eventCache[eventName] || (eventCache[eventName] = []);
     },
 
     
     getElementEventCache : function(element) {
+        if (!element) {
+            return {};
+        }
         var elementCache = Ext.cache[this.getId(element)];
         return elementCache.events || (elementCache.events = {});
     },
@@ -10864,8 +11229,8 @@ Ext.EventManager = {
     
     fireResize: function(){
         var me = this,
-            w = Ext.core.Element.getViewWidth(),
-            h = Ext.core.Element.getViewHeight();
+            w = Ext.Element.getViewWidth(),
+            h = Ext.Element.getViewHeight();
 
          
          if(me.curHeight != h || me.curWidth != w){
@@ -10953,7 +11318,7 @@ Ext.EventManager.un = Ext.EventManager.removeListener;
         
         var bd = document.body || document.getElementsByTagName('body')[0],
             baseCSSPrefix = Ext.baseCSSPrefix,
-            cls = [],
+            cls = [baseCSSPrefix + 'body'],
             htmlCls = [],
             html;
 
@@ -10963,66 +11328,107 @@ Ext.EventManager.un = Ext.EventManager.removeListener;
 
         html = bd.parentNode;
 
+        function add (c) {
+            cls.push(baseCSSPrefix + c);
+        }
+
         
         if (Ext.isIE) {
-            cls.push(baseCSSPrefix + 'ie');
-        }
-        if (Ext.isIE6) {
-            cls.push(baseCSSPrefix + 'ie6');
-        }
-        if (Ext.isIE7) {
-            cls.push(baseCSSPrefix + 'ie7');
-        }
-        if (Ext.isIE8) {
-            cls.push(baseCSSPrefix + 'ie8');
-        }
-        if (Ext.isIE9) {
-            cls.push(baseCSSPrefix + 'ie9');
+            add('ie');
+
+            
+            
+            
+            
+            
+            
+            
+            
+            
+            
+            
+            if (Ext.isIE6) {
+                add('ie6');
+            } else { 
+                add('ie7p');
+
+                if (Ext.isIE7) {
+                    add('ie7');
+                } else {
+                    add('ie8p');
+
+                    if (Ext.isIE8) {
+                        add('ie8');
+                    } else {
+                        add('ie9p');
+
+                        if (Ext.isIE9) {
+                            add('ie9');
+                        }
+                    }
+                }
+            }
+
+            if (Ext.isIE6 || Ext.isIE7) {
+                add('ie7m');
+            }
+            if (Ext.isIE6 || Ext.isIE7 || Ext.isIE8) {
+                add('ie8m');
+            }
+            if (Ext.isIE7 || Ext.isIE8) {
+                add('ie78');
+            }
         }
         if (Ext.isGecko) {
-            cls.push(baseCSSPrefix + 'gecko');
-        }
-        if (Ext.isGecko3) {
-            cls.push(baseCSSPrefix + 'gecko3');
-        }
-        if (Ext.isGecko4) {
-            cls.push(baseCSSPrefix + 'gecko4');
+            add('gecko');
+            if (Ext.isGecko3) {
+                add('gecko3');
+            }
+            if (Ext.isGecko4) {
+                add('gecko4');
+            }
+            if (Ext.isGecko5) {
+                add('gecko5');
+            }
         }
         if (Ext.isOpera) {
-            cls.push(baseCSSPrefix + 'opera');
+            add('opera');
         }
         if (Ext.isWebKit) {
-            cls.push(baseCSSPrefix + 'webkit');
+            add('webkit');
         }
         if (Ext.isSafari) {
-            cls.push(baseCSSPrefix + 'safari');
-        }
-        if (Ext.isSafari2) {
-            cls.push(baseCSSPrefix + 'safari2');
-        }
-        if (Ext.isSafari3) {
-            cls.push(baseCSSPrefix + 'safari3');
-        }
-        if (Ext.isSafari4) {
-            cls.push(baseCSSPrefix + 'safari4');
+            add('safari');
+            if (Ext.isSafari2) {
+                add('safari2');
+            }
+            if (Ext.isSafari3) {
+                add('safari3');
+            }
+            if (Ext.isSafari4) {
+                add('safari4');
+            }
+            if (Ext.isSafari5) {
+                add('safari5');
+            }
         }
         if (Ext.isChrome) {
-            cls.push(baseCSSPrefix + 'chrome');
+            add('chrome');
         }
         if (Ext.isMac) {
-            cls.push(baseCSSPrefix + 'mac');
+            add('mac');
         }
         if (Ext.isLinux) {
-            cls.push(baseCSSPrefix + 'linux');
+            add('linux');
         }
         if (!Ext.supports.CSS3BorderRadius) {
-            cls.push(baseCSSPrefix + 'nbr');
+            add('nbr');
         }
         if (!Ext.supports.CSS3LinearGradient) {
-            cls.push(baseCSSPrefix + 'nlg');
+            add('nlg');
         }
         if (!Ext.scopeResetCSS) {
-            cls.push(baseCSSPrefix + 'reset');
+            add('reset');
         }
 
         
@@ -11037,9 +11443,6 @@ Ext.EventManager.un = Ext.EventManager.removeListener;
             htmlCls.push(baseCSSPrefix + (Ext.isBorderBox ? 'border-box' : 'strict'));
             if (!Ext.isStrict) {
                 htmlCls.push(baseCSSPrefix + 'quirks');
-                if (Ext.isIE && !Ext.isStrict) {
-                    Ext.isIEQuirks = true;
-                }
             }
             Ext.fly(html, '_internal').addCls(htmlCls);
         }
@@ -11229,6 +11632,44 @@ Ext.define('Ext.EventObjectImpl', {
     F11: 122,
     
     F12: 123,
+    
+    WHEEL_SCALE: (function () {
+        var scale;
+
+        if (Ext.isGecko) {
+            
+            scale = 3;
+        } else if (Ext.isMac) {
+            
+            
+            
+
+            if (Ext.isSafari && Ext.webKitVersion >= 532.0) {
+                
+                
+                
+                
+                
+                
+                scale = 120;
+            } else {
+                
+                
+                scale = 12;
+            }
+
+            
+            
+            
+            
+            scale *= 3;
+        } else {
+            
+            scale = 120;
+        }
+
+        return scale;
+    })(),
 
     
     clickRe: /(dbl)?click/,
@@ -11357,17 +11798,17 @@ Ext.define('Ext.EventObjectImpl', {
     getPageY: function(){
         return this.getY();
     },
-    
+
     
     getX: function() {
         return this.getXY()[0];
-    },    
-    
+    },
+
     
     getY: function() {
         return this.getXY()[1];
     },
-        
+
     
     getXY: function() {
         if (!this.xy) {
@@ -11394,16 +11835,58 @@ Ext.define('Ext.EventObjectImpl', {
     },
 
     
-    getWheelDelta : function(){
-        var event = this.browserEvent,
-            delta = 0;
+    correctWheelDelta : function (delta) {
+        var scale = this.WHEEL_SCALE,
+            ret = Math.round(delta / scale);
+
+        if (!ret && delta) {
+            ret = (delta < 0) ? -1 : 1; 
+        }
+
+        return ret;
+    },
+
+    
+    getWheelDeltas : function () {
+        var me = this,
+            event = me.browserEvent,
+            dx = 0, dy = 0; 
+
+        if (Ext.isDefined(event.wheelDeltaX)) { 
+            dx = event.wheelDeltaX;
+            dy = event.wheelDeltaY;
+        } else if (event.wheelDelta) { 
+            dy = event.wheelDelta;
+        } else if (event.detail) { 
+            dy = -event.detail; 
+
+            
+            
+            if (dy > 100) {
+                dy = 3;
+            } else if (dy < -100) {
+                dy = -3;
+            }
 
-        if (event.wheelDelta) { 
-            delta = event.wheelDelta / 120;
-        } else if (event.detail){ 
-            delta = -event.detail / 3;
+            
+            
+            if (Ext.isDefined(event.axis) && event.axis === event.HORIZONTAL_AXIS) {
+                dx = dy;
+                dy = 0;
+            }
         }
-        return delta;
+
+        return {
+            x: me.correctWheelDelta(dx),
+            y: me.correctWheelDelta(dy)
+        };
+    },
+
+    
+    getWheelDelta : function(){
+        var deltas = this.getWheelDeltas();
+
+        return deltas.y;
     },
 
     
@@ -11524,7 +12007,7 @@ Ext.define('Ext.EventObjectImpl', {
 
                     return target;
                 }
-            }
+            };
         } else if (document.createEventObject) { 
             var crazyIEButtons = { 0: 1, 1: 4, 2: 2 };
 
@@ -11652,7 +12135,6 @@ Ext.define('Ext.EventObjectImpl', {
         }
 
         function cannotInject (target, srcEvent) {
-            
         }
 
         return function (target) {
@@ -11675,16 +12157,37 @@ Ext.EventObject = new Ext.EventObjectImpl();
 
 (function(){
     var doc = document,
+        activeElement = null,
         isCSS1 = doc.compatMode == "CSS1Compat",
-        ELEMENT = Ext.core.Element,
+        ELEMENT = Ext.Element,
         fly = function(el){
             if (!_fly) {
-                _fly = new Ext.core.Element.Flyweight();
+                _fly = new Ext.Element.Flyweight();
             }
             _fly.dom = el;
             return _fly;
         }, _fly;
 
+    
+    
+    
+    if (!('activeElement' in doc) && doc.addEventListener) {
+        doc.addEventListener('focus',
+            function (ev) {
+                if (ev && ev.target) {
+                    activeElement = (ev.target == doc) ? null : ev.target;
+                }
+            }, true);
+    }
+
+    
+    function makeSelectionRestoreFn (activeEl, start, end) {
+        return function () {
+            activeEl.selectionStart = start;
+            activeEl.selectionEnd = end;
+        };
+    }
+
     Ext.apply(ELEMENT, {
         isAncestor : function(p, c) {
             var ret = false;
@@ -11705,6 +12208,43 @@ Ext.EventObject = new Ext.EventObjectImpl();
             return ret;
         },
 
+        
+        getActiveElement: function () {
+            return doc.activeElement || activeElement;
+        },
+
+        
+        getRightMarginFixCleaner: function (target) {
+            var supports = Ext.supports,
+                hasInputBug = supports.DisplayChangeInputSelectionBug,
+                hasTextAreaBug = supports.DisplayChangeTextAreaSelectionBug;
+
+            if (hasInputBug || hasTextAreaBug) {
+                var activeEl = doc.activeElement || activeElement, 
+                    tag = activeEl && activeEl.tagName,
+                    start,
+                    end;
+
+                if ((hasTextAreaBug && tag == 'TEXTAREA') ||
+                    (hasInputBug && tag == 'INPUT' && activeEl.type == 'text')) {
+                    if (ELEMENT.isAncestor(target, activeEl)) {
+                        start = activeEl.selectionStart;
+                        end = activeEl.selectionEnd;
+
+                        if (Ext.isNumber(start) && Ext.isNumber(end)) { 
+                            
+                            
+                            
+                            
+                            return makeSelectionRestoreFn(activeEl, start, end);
+                        }
+                    }
+                }
+            }
+
+            return Ext.emptyFn; 
+        },
+
         getViewWidth : function(full) {
             return full ? ELEMENT.getDocumentWidth() : ELEMENT.getViewportWidth();
         },
@@ -11740,6 +12280,17 @@ Ext.EventObject = new Ext.EventObjectImpl();
             return ELEMENT.getXY(el)[0];
         },
 
+        getOffsetParent: function (el) {
+            el = Ext.getDom(el);
+            try {
+                
+                return el.offsetParent;
+            } catch (e) {
+                var body = document.body; 
+                return (el == body) ? null : body;
+            }
+        },
+
         getXY : function(el) {
             var p,
                 pe,
@@ -11752,7 +12303,7 @@ Ext.EventObject = new Ext.EventObjectImpl();
                 scroll,
                 hasAbsolute,
                 bd = (doc.body || doc.documentElement),
-                ret = [0,0];
+                ret;
 
             el = Ext.getDom(el);
 
@@ -11760,13 +12311,17 @@ Ext.EventObject = new Ext.EventObjectImpl();
                 hasAbsolute = fly(el).isStyle("position", "absolute");
 
                 if (el.getBoundingClientRect) {
-                    b = el.getBoundingClientRect();
-                    scroll = fly(document).getScroll();
-                    ret = [Math.round(b.left + scroll.left), Math.round(b.top + scroll.top)];
-                } else {
-                    p = el;
+                    try {
+                        b = el.getBoundingClientRect();
+                        scroll = fly(document).getScroll();
+                        ret = [ Math.round(b.left + scroll.left), Math.round(b.top + scroll.top) ];
+                    } catch (e) {
+                        
+                    }
+                }
 
-                    while (p) {
+                if (!ret) {
+                    for (p = el; p; p = ELEMENT.getOffsetParent(p)) {
                         pe = fly(p);
                         x += p.offsetLeft;
                         y += p.offsetTop;
@@ -11782,7 +12337,6 @@ Ext.EventObject = new Ext.EventObjectImpl();
                                 y += bt;
                             }
                         }
-                        p = p.offsetParent;
                     }
 
                     if (Ext.isSafari && hasAbsolute) {
@@ -11807,7 +12361,7 @@ Ext.EventObject = new Ext.EventObjectImpl();
                     ret = [x,y];
                 }
             }
-            return ret;
+            return ret || [0,0];
         },
 
         setXY : function(el, xy) {
@@ -11851,7 +12405,7 @@ Ext.EventObject = new Ext.EventObjectImpl();
                         Ext.each(element.options, function(opt){
                             if (opt.selected) {
                                 hasValue = opt.hasAttribute ? opt.hasAttribute('value') : opt.getAttributeNode('value').specified;
-                                data += String.format("{0}={1}&", encoder(name), encoder(hasValue ? opt.value : opt.text));
+                                data += Ext.String.format("{0}={1}&", encoder(name), encoder(hasValue ? opt.value : opt.text));
                             }
                         });
                     } else if (!(/file|undefined|reset|button/i.test(type))) {
@@ -11869,207 +12423,232 @@ Ext.EventObject = new Ext.EventObjectImpl();
 
 
 
-Ext.core.Element.addMethods({
+Ext.Element.addMethods((function(){
+    var focusRe = /button|input|textarea|select|object/;
+    return {
+        
+        monitorMouseLeave: function(delay, handler, scope) {
+            var me = this,
+                timer,
+                listeners = {
+                    mouseleave: function(e) {
+                        timer = setTimeout(Ext.Function.bind(handler, scope||me, [e]), delay);
+                    },
+                    mouseenter: function() {
+                        clearTimeout(timer);
+                    },
+                    freezeEvent: true
+                };
 
-    
-    monitorMouseLeave: function(delay, handler, scope) {
-        var me = this,
-            timer,
-            listeners = {
-                mouseleave: function(e) {
-                    timer = setTimeout(Ext.Function.bind(handler, scope||me, [e]), delay);
-                },
-                mouseenter: function() {
-                    clearTimeout(timer);
-                },
-                freezeEvent: true
-            };
+            me.on(listeners);
+            return listeners;
+        },
 
-        me.on(listeners);
-        return listeners;
-    },
+        
+        swallowEvent : function(eventName, preventDefault) {
+            var me = this;
+            function fn(e) {
+                e.stopPropagation();
+                if (preventDefault) {
+                    e.preventDefault();
+                }
+            }
 
-    
-    swallowEvent : function(eventName, preventDefault) {
-        var me = this;
-        function fn(e) {
-            e.stopPropagation();
-            if (preventDefault) {
-                e.preventDefault();
+            if (Ext.isArray(eventName)) {
+                Ext.each(eventName, function(e) {
+                     me.on(e, fn);
+                });
+                return me;
             }
-        }
-        
-        if (Ext.isArray(eventName)) {
-            Ext.each(eventName, function(e) {
-                 me.on(e, fn);
-            });
+            me.on(eventName, fn);
             return me;
-        }
-        me.on(eventName, fn);
-        return me;
-    },
+        },
 
-    
-    relayEvent : function(eventName, observable) {
-        this.on(eventName, function(e) {
-            observable.fireEvent(eventName, e);
-        });
-    },
+        
+        relayEvent : function(eventName, observable) {
+            this.on(eventName, function(e) {
+                observable.fireEvent(eventName, e);
+            });
+        },
 
+        
+        clean : function(forceReclean) {
+            var me  = this,
+                dom = me.dom,
+                n   = dom.firstChild,
+                nx,
+                ni  = -1;
     
-    clean : function(forceReclean) {
-        var me  = this,
-            dom = me.dom,
-            n   = dom.firstChild,
-            nx,
-            ni  = -1;
-
-        if (Ext.core.Element.data(dom, 'isCleaned') && forceReclean !== true) {
-            return me;
-        }
+            if (Ext.Element.data(dom, 'isCleaned') && forceReclean !== true) {
+                return me;
+            }
 
-        while (n) {
-            nx = n.nextSibling;
-            if (n.nodeType == 3) {
-                
-                if (!(/\S/.test(n.nodeValue))) {
-                    dom.removeChild(n);
-                
-                } else if (nx && nx.nodeType == 3) {
-                    n.appendData(Ext.String.trim(nx.data));
-                    dom.removeChild(nx);
-                    nx = n.nextSibling;
+            while (n) {
+                nx = n.nextSibling;
+                if (n.nodeType == 3) {
+                    
+                    if (!(/\S/.test(n.nodeValue))) {
+                        dom.removeChild(n);
+                    
+                    } else if (nx && nx.nodeType == 3) {
+                        n.appendData(Ext.String.trim(nx.data));
+                        dom.removeChild(nx);
+                        nx = n.nextSibling;
+                        n.nodeIndex = ++ni;
+                    }
+                } else {
+                    
+                    Ext.fly(n).clean();
                     n.nodeIndex = ++ni;
                 }
-            } else {
-                
-                Ext.fly(n).clean();
-                n.nodeIndex = ++ni;
+                n = nx;
             }
-            n = nx;
-        }
 
-        Ext.core.Element.data(dom, 'isCleaned', true);
-        return me;
-    },
+            Ext.Element.data(dom, 'isCleaned', true);
+            return me;
+        },
 
-    
-    load : function(options) {
-        this.getLoader().load(options);
-        return this;
-    },
+        
+        load : function(options) {
+            this.getLoader().load(options);
+            return this;
+        },
 
+        
+        getLoader : function() {
+            var dom = this.dom,
+                data = Ext.Element.data,
+                loader = data(dom, 'loader');
     
-    getLoader : function() {
-        var dom = this.dom,
-            data = Ext.core.Element.data,
-            loader = data(dom, 'loader');
-            
-        if (!loader) {
-            loader = Ext.create('Ext.ElementLoader', {
-                target: this
-            });
-            data(dom, 'loader', loader);
-        }
-        return loader;
-    },
+            if (!loader) {
+                loader = Ext.create('Ext.ElementLoader', {
+                    target: this
+                });
+                data(dom, 'loader', loader);
+            }
+            return loader;
+        },
 
-    
-    update : function(html, loadScripts, callback) {
-        var me = this,
-            id,
-            dom,
-            interval;
-            
-        if (!me.dom) {
-            return me;
-        }
-        html = html || '';
-        dom = me.dom;
+        
+        update : function(html, loadScripts, callback) {
+            var me = this,
+                id,
+                dom,
+                interval;
 
-        if (loadScripts !== true) {
-            dom.innerHTML = html;
-            Ext.callback(callback, me);
-            return me;
-        }
+            if (!me.dom) {
+                return me;
+            }
+            html = html || '';
+            dom = me.dom;
 
-        id  = Ext.id();
-        html += '<span id="' + id + '"></span>';
-
-        interval = setInterval(function(){
-            if (!document.getElementById(id)) {
-                return false;    
-            }
-            clearInterval(interval);
-            var DOC    = document,
-                hd     = DOC.getElementsByTagName("head")[0],
-                re     = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
-                srcRe  = /\ssrc=([\'\"])(.*?)\1/i,
-                typeRe = /\stype=([\'\"])(.*?)\1/i,
-                match,
-                attrs,
-                srcMatch,
-                typeMatch,
-                el,
-                s;
+            if (loadScripts !== true) {
+                dom.innerHTML = html;
+                Ext.callback(callback, me);
+                return me;
+            }
 
-            while ((match = re.exec(html))) {
-                attrs = match[1];
-                srcMatch = attrs ? attrs.match(srcRe) : false;
-                if (srcMatch && srcMatch[2]) {
-                   s = DOC.createElement("script");
-                   s.src = srcMatch[2];
-                   typeMatch = attrs.match(typeRe);
-                   if (typeMatch && typeMatch[2]) {
-                       s.type = typeMatch[2];
-                   }
-                   hd.appendChild(s);
-                } else if (match[2] && match[2].length > 0) {
-                    if (window.execScript) {
-                       window.execScript(match[2]);
-                    } else {
-                       window.eval(match[2]);
+            id  = Ext.id();
+            html += '<span id="' + id + '"></span>';
+
+            interval = setInterval(function(){
+                if (!document.getElementById(id)) {
+                    return false;
+                }
+                clearInterval(interval);
+                var DOC    = document,
+                    hd     = DOC.getElementsByTagName("head")[0],
+                    re     = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
+                    srcRe  = /\ssrc=([\'\"])(.*?)\1/i,
+                    typeRe = /\stype=([\'\"])(.*?)\1/i,
+                    match,
+                    attrs,
+                    srcMatch,
+                    typeMatch,
+                    el,
+                    s;
+
+                while ((match = re.exec(html))) {
+                    attrs = match[1];
+                    srcMatch = attrs ? attrs.match(srcRe) : false;
+                    if (srcMatch && srcMatch[2]) {
+                       s = DOC.createElement("script");
+                       s.src = srcMatch[2];
+                       typeMatch = attrs.match(typeRe);
+                       if (typeMatch && typeMatch[2]) {
+                           s.type = typeMatch[2];
+                       }
+                       hd.appendChild(s);
+                    } else if (match[2] && match[2].length > 0) {
+                        if (window.execScript) {
+                           window.execScript(match[2]);
+                        } else {
+                           window.eval(match[2]);
+                        }
                     }
                 }
-            }
-            
-            el = DOC.getElementById(id);
-            if (el) {
-                Ext.removeNode(el);
-            }
-            Ext.callback(callback, me);
-        }, 20);
-        dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, '');
-        return me;
-    },
 
-    
-    removeAllListeners : function() {
-        this.removeAnchor();
-        Ext.EventManager.removeAll(this.dom);
-        return this;
-    },
+                el = DOC.getElementById(id);
+                if (el) {
+                    Ext.removeNode(el);
+                }
+                Ext.callback(callback, me);
+            }, 20);
+            dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, '');
+            return me;
+        },
 
+        
+        removeAllListeners : function() {
+            this.removeAnchor();
+            Ext.EventManager.removeAll(this.dom);
+            return this;
+        },
     
-    createProxy : function(config, renderTo, matchBox) {
-        config = (typeof config == 'object') ? config : {tag : "div", cls: config};
+        
+        getScopeParent: function(){
+            var parent = this.dom.parentNode;
+            return Ext.scopeResetCSS ? parent.parentNode : parent;
+        },
 
-        var me = this,
-            proxy = renderTo ? Ext.core.DomHelper.append(renderTo, config, true) :
-                               Ext.core.DomHelper.insertBefore(me.dom, config, true);
+        
+        createProxy : function(config, renderTo, matchBox) {
+            config = (typeof config == 'object') ? config : {tag : "div", cls: config};
 
-        proxy.setVisibilityMode(Ext.core.Element.DISPLAY);
-        proxy.hide();
-        if (matchBox && me.setBox && me.getBox) { 
-           proxy.setBox(me.getBox());
-        }
-        return proxy;
-    }
-});
-Ext.core.Element.prototype.clearListeners = Ext.core.Element.prototype.removeAllListeners;
+            var me = this,
+                proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :
+                                   Ext.DomHelper.insertBefore(me.dom, config, true);
+
+            proxy.setVisibilityMode(Ext.Element.DISPLAY);
+            proxy.hide();
+            if (matchBox && me.setBox && me.getBox) { 
+               proxy.setBox(me.getBox());
+            }
+            return proxy;
+        },
+    
+        
+        focusable: function(){
+            var dom = this.dom,
+                nodeName = dom.nodeName.toLowerCase(),
+                canFocus = false,
+                hasTabIndex = !isNaN(dom.tabIndex);
+            
+            if (!dom.disabled) {
+                if (focusRe.test(nodeName)) {
+                    canFocus = true;
+                } else {
+                    canFocus = nodeName == 'a' ? dom.href || hasTabIndex : hasTabIndex;
+                }
+            }
+            return canFocus && this.isVisible(true);
+        }    
+    };
+})());
+Ext.Element.prototype.clearListeners = Ext.Element.prototype.removeAllListeners;
 
 
-Ext.core.Element.addMethods({
+Ext.Element.addMethods({
     
     getAnchorXY : function(anchor, local, s){
         
@@ -12079,8 +12658,8 @@ Ext.core.Element.addMethods({
 
         var me = this,
             vp = me.dom == document.body || me.dom == document,
-            w = s.width || vp ? Ext.core.Element.getViewWidth() : me.getWidth(),
-            h = s.height || vp ? Ext.core.Element.getViewHeight() : me.getHeight(),
+            w = s.width || vp ? Ext.Element.getViewWidth() : me.getWidth(),
+            h = s.height || vp ? Ext.Element.getViewHeight() : me.getHeight(),
             xy,
             r = Math.round,
             o = me.getXY(),
@@ -12148,7 +12727,7 @@ Ext.core.Element.addMethods({
 
     
     getAnchor : function(){
-        var data = Ext.core.Element.data,
+        var data = Ext.Element.data,
             dom = this.dom;
             if (!dom) {
                 return;
@@ -12169,11 +12748,6 @@ Ext.core.Element.addMethods({
 
         el = Ext.get(el);
         if(!el || !el.dom){
-            Ext.Error.raise({
-                sourceClass: 'Ext.core.Element',
-                sourceMethod: 'getAlignVector',
-                msg: 'Attempted to align an element that doesn\'t exist'
-            });
         }
 
         elRegion = el.getRegion();
@@ -12184,11 +12758,6 @@ Ext.core.Element.addMethods({
         el = Ext.get(el);
 
         if(!el || !el.dom){
-            Ext.Error.raise({
-                sourceClass: 'Ext.core.Element',
-                sourceMethod: 'getAlignToXY',
-                msg: 'Attempted to align an element that doesn\'t exist'
-            });
         }
 
         o = o || [0,0];
@@ -12204,8 +12773,8 @@ Ext.core.Element.addMethods({
             w,
             h,
             r,
-            dw = Ext.core.Element.getViewWidth() -10, 
-            dh = Ext.core.Element.getViewHeight()-10, 
+            dw = Ext.Element.getViewWidth() -10, 
+            dh = Ext.Element.getViewHeight()-10, 
             p1y,
             p1x,
             p2y,
@@ -12223,14 +12792,6 @@ Ext.core.Element.addMethods({
             m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);
 
         if(!m){
-            Ext.Error.raise({
-                sourceClass: 'Ext.core.Element',
-                sourceMethod: 'getAlignToXY',
-                el: el,
-                position: p,
-                offset: o,
-                msg: 'Attemmpted to align an element with an invalid position: "' + p + '"'
-            });
         }
 
         p1 = m[1];
@@ -12350,7 +12911,7 @@ Ext.core.Element.addMethods({
 
 (function(){
 
-var ELEMENT = Ext.core.Element,
+var ELEMENT = Ext.Element,
     LEFT = "left",
     RIGHT = "right",
     TOP = "top",
@@ -12361,7 +12922,7 @@ var ELEMENT = Ext.core.Element,
     AUTO = "auto",
     ZINDEX = "z-index";
 
-Ext.override(Ext.core.Element, {
+Ext.override(Ext.Element, {
     
     getX : function(){
         return ELEMENT.getX(this.dom);
@@ -12658,14 +13219,14 @@ Ext.override(Ext.core.Element, {
         var me = this,
             isBody = me.dom === document.body,
             scroll, pos, top, left, width, height;
-            
+
         
         if (isBody) {
             scroll = me.getScroll();
             left = scroll.left;
             top = scroll.top;
-            width = Ext.core.Element.getViewportWidth();
-            height = Ext.core.Element.getViewportHeight();
+            width = Ext.Element.getViewportWidth();
+            height = Ext.Element.getViewportHeight();
         }
         else {
             pos = me.getXY();
@@ -12683,8 +13244,8 @@ Ext.override(Ext.core.Element, {
         var me = this,
             el = me.dom,
             isDoc = el === document.body,
-            w = isDoc ? Ext.core.Element.getViewWidth()  : el.offsetWidth,
-            h = isDoc ? Ext.core.Element.getViewHeight() : el.offsetHeight,
+            w = isDoc ? Ext.Element.getViewWidth()  : el.offsetWidth,
+            h = isDoc ? Ext.Element.getViewHeight() : el.offsetHeight,
             xy = me.getXY(),
             t = xy[1],
             r = xy[0] + w,
@@ -12736,7 +13297,7 @@ Ext.override(Ext.core.Element, {
 })();
 
 
-Ext.override(Ext.core.Element, {
+Ext.override(Ext.Element, {
     
     isScrollable : function(){
         var dom = this.dom;
@@ -12870,7 +13431,7 @@ Ext.override(Ext.core.Element, {
     }
 });
 
-Ext.core.Element.addMethods(
+Ext.Element.addMethods(
     function() {
         var VISIBILITY      = "visibility",
             DISPLAY         = "display",
@@ -12878,7 +13439,7 @@ Ext.core.Element.addMethods(
             NONE            = "none",
             XMASKED         = Ext.baseCSSPrefix + "masked",
             XMASKEDRELATIVE = Ext.baseCSSPrefix + "masked-relative",
-            data            = Ext.core.Element.data;
+            data            = Ext.Element.data;
 
         return {
             
@@ -12906,7 +13467,7 @@ Ext.core.Element.addMethods(
 
             
             enableDisplayMode : function(display) {
-                this.setVisibilityMode(Ext.core.Element.DISPLAY);
+                this.setVisibilityMode(Ext.Element.DISPLAY);
 
                 if (!Ext.isEmpty(display)) {
                     data(this.dom, 'originalDisplay', display);
@@ -12920,7 +13481,7 @@ Ext.core.Element.addMethods(
                 var me  = this,
                     dom = me.dom,
                     setExpression = dom.style.setExpression,
-                    dh  = Ext.core.DomHelper,
+                    dh  = Ext.DomHelper,
                     EXTELMASKMSG = Ext.baseCSSPrefix + "mask-msg",
                     el,
                     mask;
@@ -13026,7 +13587,7 @@ Ext.core.Element.addMethods(
     }()
 );
 
-Ext.core.Element.addMethods({
+Ext.Element.addMethods({
     
     addKeyListener : function(key, fn, scope){
         var config;
@@ -13066,7 +13627,7 @@ Ext.apply(Ext.CompositeElementLite.prototype, {
             return this;
         }
         if(typeof els == "string"){
-            els = Ext.core.Element.selectorFunction(els, root);
+            els = Ext.Element.selectorFunction(els, root);
         }
         var yels = this.elements;
         Ext.each(els, function(e) {
@@ -13104,7 +13665,7 @@ Ext.apply(Ext.CompositeElementLite.prototype, {
                         Ext.removeNode(el);
                     }
                 }
-                els.splice(val, 1);
+                Ext.Array.erase(els, val, 1);
             }
         });
         return this;
@@ -13113,53 +13674,38 @@ Ext.apply(Ext.CompositeElementLite.prototype, {
 
 
 Ext.CompositeElement = Ext.extend(Ext.CompositeElementLite, {
-    
+
     constructor : function(els, root){
         this.elements = [];
         this.add(els, root);
     },
-    
+
     
     getElement : function(el){
         
         return el;
     },
-    
+
     
     transformElement : function(el){
         return Ext.get(el);
     }
-
-    
-
-    
-
-    
 });
 
 
-Ext.core.Element.select = function(selector, unique, root){
+Ext.Element.select = function(selector, unique, root){
     var els;
     if(typeof selector == "string"){
-        els = Ext.core.Element.selectorFunction(selector, root);
+        els = Ext.Element.selectorFunction(selector, root);
     }else if(selector.length !== undefined){
         els = selector;
     }else{
-        Ext.Error.raise({
-            sourceClass: "Ext.core.Element",
-            sourceMethod: "select",
-            selector: selector,
-            unique: unique,
-            root: root,
-            msg: "Invalid selector specified: " + selector
-        });
     }
     return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);
 };
 
 
-Ext.select = Ext.core.Element.select;
-
+Ext.select = Ext.Element.select;
 
 
 
@@ -13218,7 +13764,7 @@ Ext.define('Ext.util.Observable', {
     },
 
     
-    eventOptionsRe : /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate|element|vertical|horizontal)$/,
+    eventOptionsRe : /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate|element|vertical|horizontal|freezeEvent)$/,
 
     
     addManagedListener : function(item, ename, fn, scope, options) {
@@ -13226,7 +13772,7 @@ Ext.define('Ext.util.Observable', {
             managedListeners = me.managedListeners = me.managedListeners || [],
             config;
 
-        if (Ext.isObject(ename)) {
+        if (typeof ename !== 'string') {
             options = ename;
             for (ename in options) {
                 if (options.hasOwnProperty(ename)) {
@@ -13251,16 +13797,15 @@ Ext.define('Ext.util.Observable', {
     },
 
     
-     removeManagedListener : function(item, ename, fn, scope) {
+    removeManagedListener : function(item, ename, fn, scope) {
         var me = this,
             options,
             config,
             managedListeners,
-            managedListener,
             length,
             i;
 
-        if (Ext.isObject(ename)) {
+        if (typeof ename !== 'string') {
             options = ename;
             for (ename in options) {
                 if (options.hasOwnProperty(ename)) {
@@ -13273,56 +13818,64 @@ Ext.define('Ext.util.Observable', {
         }
 
         managedListeners = me.managedListeners ? me.managedListeners.slice() : [];
-        length = managedListeners.length;
 
-        for (i = 0; i < length; i++) {
-            managedListener = managedListeners[i];
-            if (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope)) {
-                Ext.Array.remove(me.managedListeners, managedListener);
-                item.un(managedListener.ename, managedListener.fn, managedListener.scope);
-            }
+        for (i = 0, length = managedListeners.length; i < length; i++) {
+            me.removeManagedListenerItem(false, managedListeners[i], item, ename, fn, scope);
         }
     },
 
     
-    fireEvent: function() {
-        var me = this,
-            args = Ext.Array.toArray(arguments),
-            ename = args[0].toLowerCase(),
-            ret = true,
-            event = me.events[ename],
-            queue = me.eventQueue,
-            parent;
+    fireEvent: function(eventName) {
+        var name = eventName.toLowerCase(),
+            events = this.events,
+            event = events && events[name],
+            bubbles = event && event.bubble;
 
-        if (me.eventsSuspended === true) {
-            if (queue) {
-                queue.push(args);
-            }
-        } else if (event && Ext.isObject(event) && event.bubble) {
-            if (event.fire.apply(event, args.slice(1)) === false) {
-                return false;
-            }
-            parent = me.getBubbleTarget && me.getBubbleTarget();
-            if (parent && parent.isObservable) {
-                if (!parent.events[ename] || !Ext.isObject(parent.events[ename]) || !parent.events[ename].bubble) {
-                    parent.enableBubble(ename);
+        return this.continueFireEvent(name, Ext.Array.slice(arguments, 1), bubbles);
+    },
+
+    
+    continueFireEvent: function(eventName, args, bubbles) {
+        var target = this,
+            queue, event,
+            ret = true;
+
+        do {
+            if (target.eventsSuspended === true) {
+                if ((queue = target.eventQueue)) {
+                    queue.push([eventName, args, bubbles]);
+                }
+                return ret;
+            } else {
+                event = target.events[eventName];
+                
+                
+                if (event && event != true) {
+                    if ((ret = event.fire.apply(event, args)) === false) {
+                        break;
+                    }
                 }
-                return parent.fireEvent.apply(parent, args);
             }
-        } else if (event && Ext.isObject(event)) {
-            args.shift();
-            ret = event.fire.apply(event, args);
-        }
+        } while (bubbles && (target = target.getBubbleParent()));
         return ret;
     },
 
     
+    getBubbleParent: function(){
+        var me = this, parent = me.getBubbleTarget && me.getBubbleTarget();
+        if (parent && parent.isObservable) {
+            return parent;
+        }
+        return null;
+    },
+
+    
     addListener: function(ename, fn, scope, options) {
         var me = this,
             config,
             event;
 
-        if (Ext.isObject(ename)) {
+        if (typeof ename !== 'string') {
             options = ename;
             for (ename in options) {
                 if (options.hasOwnProperty(ename)) {
@@ -13351,7 +13904,7 @@ Ext.define('Ext.util.Observable', {
             event,
             options;
 
-        if (Ext.isObject(ename)) {
+        if (typeof ename !== 'string') {
             options = ename;
             for (ename in options) {
                 if (options.hasOwnProperty(ename)) {
@@ -13364,7 +13917,7 @@ Ext.define('Ext.util.Observable', {
         } else {
             ename = ename.toLowerCase();
             event = me.events[ename];
-            if (event.isEvent) {
+            if (event && event.isEvent) {
                 event.removeListener(fn, scope);
             }
         }
@@ -13388,43 +13941,43 @@ Ext.define('Ext.util.Observable', {
         this.clearManagedListeners();
     },
 
-    purgeListeners : function() {
-        console.warn('Observable: purgeListeners has been deprecated. Please use clearListeners.');
-        return this.clearListeners.apply(this, arguments);
-    },
 
     
     clearManagedListeners : function() {
         var managedListeners = this.managedListeners || [],
             i = 0,
-            len = managedListeners.length,
-            managedListener;
+            len = managedListeners.length;
 
         for (; i < len; i++) {
-            managedListener = managedListeners[i];
-            managedListener.item.un(managedListener.ename, managedListener.fn, managedListener.scope);
+            this.removeManagedListenerItem(true, managedListeners[i]);
         }
 
         this.managedListeners = [];
     },
 
-    purgeManagedListeners : function() {
-        console.warn('Observable: purgeManagedListeners has been deprecated. Please use clearManagedListeners.');
-        return this.clearManagedListeners.apply(this, arguments);
+    
+    removeManagedListenerItem: function(isClear, managedListener, item, ename, fn, scope){
+        if (isClear || (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope))) {
+            managedListener.item.un(managedListener.ename, managedListener.fn, managedListener.scope);
+            if (!isClear) {
+                Ext.Array.remove(this.managedListeners, managedListener);
+            }
+        }
     },
 
+
     
     addEvents: function(o) {
         var me = this,
             args,
             len,
             i;
-            
+
             me.events = me.events || {};
         if (Ext.isString(o)) {
             args = arguments;
             i = args.length;
-            
+
             while (i--) {
                 me.events[args[i]] = me.events[args[i]] || true;
             }
@@ -13450,15 +14003,16 @@ Ext.define('Ext.util.Observable', {
     
     resumeEvents: function() {
         var me = this,
-            queued = me.eventQueue || [];
+            queued = me.eventQueue;
 
         me.eventsSuspended = false;
         delete me.eventQueue;
 
-        Ext.each(queued,
-        function(e) {
-            me.fireEvent.apply(me, e);
-        });
+        if (queued) {
+            Ext.each(queued, function(e) {
+                me.continueFireEvent.apply(me, e);
+            });
+        }
     },
 
     
@@ -13504,14 +14058,15 @@ Ext.define('Ext.util.Observable', {
         }
     }
 }, function() {
-    
-
-    
 
     this.createAlias({
+        
         on: 'addListener',
+        
         un: 'removeListener',
+        
         mon: 'addManagedListener',
+        
         mun: 'removeManagedListener'
     });
 
@@ -13611,13 +14166,13 @@ Ext.define('Ext.util.Observable', {
                     i, len;
                 for(i = 0, len = e.before.length; i < len; i++){
                     if(e.before[i].fn == fn && e.before[i].scope == scope){
-                        e.before.splice(i, 1);
+                        Ext.Array.erase(e.before, i, 1);
                         return;
                     }
                 }
                 for(i = 0, len = e.after.length; i < len; i++){
                     if(e.after[i].fn == fn && e.after[i].scope == scope){
-                        e.after.splice(i, 1);
+                        Ext.Array.erase(e.after, i, 1);
                         return;
                     }
                 }
@@ -13675,6 +14230,7 @@ Ext.define('Ext.util.Animate', {
     
     stopAnimation: function() {
         Ext.fx.Manager.stopAnimation(this.id);
+        return this;
     },
 
     
@@ -13682,6 +14238,7 @@ Ext.define('Ext.util.Animate', {
         Ext.fx.Manager.setFxDefaults(this.id, {
             concurrent: true
         });
+        return this;
     },
 
     
@@ -13689,6 +14246,7 @@ Ext.define('Ext.util.Animate', {
         Ext.fx.Manager.setFxDefaults(this.id, {
             concurrent: false
         });
+        return this;
     },
 
     
@@ -13698,11 +14256,13 @@ Ext.define('Ext.util.Animate', {
     getActiveAnimation: function() {
         return Ext.fx.Manager.getActiveAnimation(this.id);
     }
+}, function(){
+    
+    Ext.applyIf(Ext.Element.prototype, this.prototype);
+    
+    Ext.CompositeElementLite.importElementMethods();
 });
 
-
-Ext.applyIf(Ext.core.Element.prototype, Ext.util.Animate.prototype);
-
 Ext.define('Ext.state.Provider', {
     mixins: {
         observable: 'Ext.util.Observable'
@@ -13835,504 +14395,6 @@ Ext.define('Ext.state.Provider', {
     }
 });
 
-Ext.define('Ext.util.HashMap', {
-
-    
-
-    mixins: {
-        observable: 'Ext.util.Observable'
-    },
-
-    constructor: function(config) {
-        var me = this;
-
-        me.addEvents(
-            
-            'add',
-            
-            'clear',
-            
-            'remove',
-            
-            'replace'
-        );
-
-        me.mixins.observable.constructor.call(me, config);
-        me.clear(true);
-    },
-
-    
-    getCount: function() {
-        return this.length;
-    },
-
-    
-    getData: function(key, value) {
-        
-        if (value === undefined) {
-            value = key;
-            key = this.getKey(value);
-        }
-
-        return [key, value];
-    },
-
-    
-    getKey: function(o) {
-        return o.id;
-    },
-
-    
-    add: function(key, value) {
-        var me = this,
-            data;
-
-        if (arguments.length === 1) {
-            value = key;
-            key = me.getKey(value);
-        }
-
-        if (me.containsKey(key)) {
-            me.replace(key, value);
-        }
-
-        data = me.getData(key, value);
-        key = data[0];
-        value = data[1];
-        me.map[key] = value;
-        ++me.length;
-        me.fireEvent('add', me, key, value);
-        return value;
-    },
-
-    
-    replace: function(key, value) {
-        var me = this,
-            map = me.map,
-            old;
-
-        if (!me.containsKey(key)) {
-            me.add(key, value);
-        }
-        old = map[key];
-        map[key] = value;
-        me.fireEvent('replace', me, key, value, old);
-        return value;
-    },
-
-    
-    remove: function(o) {
-        var key = this.findKey(o);
-        if (key !== undefined) {
-            return this.removeAtKey(key);
-        }
-        return false;
-    },
-
-    
-    removeAtKey: function(key) {
-        var me = this,
-            value;
-
-        if (me.containsKey(key)) {
-            value = me.map[key];
-            delete me.map[key];
-            --me.length;
-            me.fireEvent('remove', me, key, value);
-            return true;
-        }
-        return false;
-    },
-
-    
-    get: function(key) {
-        return this.map[key];
-    },
-
-    
-    clear: function( initial) {
-        var me = this;
-        me.map = {};
-        me.length = 0;
-        if (initial !== true) {
-            me.fireEvent('clear', me);
-        }
-        return me;
-    },
-
-    
-    containsKey: function(key) {
-        return this.map[key] !== undefined;
-    },
-
-    
-    contains: function(value) {
-        return this.containsKey(this.findKey(value));
-    },
-
-    
-    getKeys: function() {
-        return this.getArray(true);
-    },
-
-    
-    getValues: function() {
-        return this.getArray(false);
-    },
-
-    
-    getArray: function(isKey) {
-        var arr = [],
-            key,
-            map = this.map;
-        for (key in map) {
-            if (map.hasOwnProperty(key)) {
-                arr.push(isKey ? key: map[key]);
-            }
-        }
-        return arr;
-    },
-
-    
-    each: function(fn, scope) {
-        
-        var items = Ext.apply({}, this.map),
-            key,
-            length = this.length;
-
-        scope = scope || this;
-        for (key in items) {
-            if (items.hasOwnProperty(key)) {
-                if (fn.call(scope, key, items[key], length) === false) {
-                    break;
-                }
-            }
-        }
-        return this;
-    },
-
-    
-    clone: function() {
-        var hash = new this.self(),
-            map = this.map,
-            key;
-
-        hash.suspendEvents();
-        for (key in map) {
-            if (map.hasOwnProperty(key)) {
-                hash.add(key, map[key]);
-            }
-        }
-        hash.resumeEvents();
-        return hash;
-    },
-
-    
-    findKey: function(value) {
-        var key,
-            map = this.map;
-
-        for (key in map) {
-            if (map.hasOwnProperty(key) && map[key] === value) {
-                return key;
-            }
-        }
-        return undefined;
-    }
-});
-
-
-
-Ext.define('Ext.Template', {
-
-    
-
-    requires: ['Ext.core.DomHelper', 'Ext.util.Format'],
-
-    statics: {
-        
-        from: function(el, config) {
-            el = Ext.getDom(el);
-            return new this(el.value || el.innerHTML, config || '');
-        }
-    },
-
-    
-
-    constructor: function(html) {
-        var me = this,
-            args = arguments,
-            buffer = [],
-            i = 0,
-            length = args.length,
-            value;
-
-        me.initialConfig = {};
-
-        if (length > 1) {
-            for (; i < length; i++) {
-                value = args[i];
-                if (typeof value == 'object') {
-                    Ext.apply(me.initialConfig, value);
-                    Ext.apply(me, value);
-                } else {
-                    buffer.push(value);
-                }
-            }
-            html = buffer.join('');
-        } else {
-            if (Ext.isArray(html)) {
-                buffer.push(html.join(''));
-            } else {
-                buffer.push(html);
-            }
-        }
-
-        
-        me.html = buffer.join('');
-
-        if (me.compiled) {
-            me.compile();
-        }
-    },
-    isTemplate: true,
-    
-    disableFormats: false,
-
-    re: /\{([\w\-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
-    
-    applyTemplate: function(values) {
-        var me = this,
-            useFormat = me.disableFormats !== true,
-            fm = Ext.util.Format,
-            tpl = me;
-
-        if (me.compiled) {
-            return me.compiled(values);
-        }
-        function fn(m, name, format, args) {
-            if (format && useFormat) {
-                if (args) {
-                    args = [values[name]].concat(Ext.functionFactory('return ['+ args +'];')());
-                } else {
-                    args = [values[name]];
-                }
-                if (format.substr(0, 5) == "this.") {
-                    return tpl[format.substr(5)].apply(tpl, args);
-                }
-                else {
-                    return fm[format].apply(fm, args);
-                }
-            }
-            else {
-                return values[name] !== undefined ? values[name] : "";
-            }
-        }
-        return me.html.replace(me.re, fn);
-    },
-
-    
-    set: function(html, compile) {
-        var me = this;
-        me.html = html;
-        me.compiled = null;
-        return compile ? me.compile() : me;
-    },
-
-    compileARe: /\\/g,
-    compileBRe: /(\r\n|\n)/g,
-    compileCRe: /'/g,
-    /**
-     * Compiles the template into an internal function, eliminating the RegEx overhead.
-     * @return {Ext.Template} this
-     * @hide repeat doc
-     */
-    compile: function() {
-        var me = this,
-            fm = Ext.util.Format,
-            useFormat = me.disableFormats !== true,
-            body, bodyReturn;
-
-        function fn(m, name, format, args) {
-            if (format && useFormat) {
-                args = args ? ',' + args: "";
-                if (format.substr(0, 5) != "this.") {
-                    format = "fm." + format + '(';
-                }
-                else {
-                    format = 'this.' + format.substr(5) + '(';
-                }
-            }
-            else {
-                args = '';
-                format = "(values['" + name + "'] == undefined ? '' : ";
-            }
-            return "'," + format + "values['" + name + "']" + args + ") ,'";
-        }
-
-        bodyReturn = me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn);
-        body = "this.compiled = function(values){ return ['" + bodyReturn + "'].join('');};";
-        eval(body);
-        return me;
-    },
-
-    /**
-     * Applies the supplied values to the template and inserts the new node(s) as the first child of el.
-     * @param {Mixed} el The context element
-     * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
-     * @param {Boolean} returnElement (optional) true to return a Ext.core.Element (defaults to undefined)
-     * @return {HTMLElement/Ext.core.Element} The new node or Element
-     */
-    insertFirst: function(el, values, returnElement) {
-        return this.doInsert('afterBegin', el, values, returnElement);
-    },
-
-    /**
-     * Applies the supplied values to the template and inserts the new node(s) before el.
-     * @param {Mixed} el The context element
-     * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
-     * @param {Boolean} returnElement (optional) true to return a Ext.core.Element (defaults to undefined)
-     * @return {HTMLElement/Ext.core.Element} The new node or Element
-     */
-    insertBefore: function(el, values, returnElement) {
-        return this.doInsert('beforeBegin', el, values, returnElement);
-    },
-
-    /**
-     * Applies the supplied values to the template and inserts the new node(s) after el.
-     * @param {Mixed} el The context element
-     * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
-     * @param {Boolean} returnElement (optional) true to return a Ext.core.Element (defaults to undefined)
-     * @return {HTMLElement/Ext.core.Element} The new node or Element
-     */
-    insertAfter: function(el, values, returnElement) {
-        return this.doInsert('afterEnd', el, values, returnElement);
-    },
-
-    /**
-     * Applies the supplied <code>values</code> to the template and appends
-     * the new node(s) to the specified <code>el</code>.
-     * <p>For example usage {@link #Template see the constructor}.</p>
-     * @param {Mixed} el The context element
-     * @param {Object/Array} values
-     * The template values. Can be an array if the params are numeric (i.e. <code>{0}</code>)
-     * or an object (i.e. <code>{foo: 'bar'}</code>).
-     * @param {Boolean} returnElement (optional) true to return an Ext.core.Element (defaults to undefined)
-     * @return {HTMLElement/Ext.core.Element} The new node or Element
-     */
-    append: function(el, values, returnElement) {
-        return this.doInsert('beforeEnd', el, values, returnElement);
-    },
-
-    doInsert: function(where, el, values, returnEl) {
-        el = Ext.getDom(el);
-        var newNode = Ext.core.DomHelper.insertHtml(where, el, this.applyTemplate(values));
-        return returnEl ? Ext.get(newNode, true) : newNode;
-    },
-
-    /**
-     * Applies the supplied values to the template and overwrites the content of el with the new node(s).
-     * @param {Mixed} el The context element
-     * @param {Object/Array} values The template values. Can be an array if your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
-     * @param {Boolean} returnElement (optional) true to return a Ext.core.Element (defaults to undefined)
-     * @return {HTMLElement/Ext.core.Element} The new node or Element
-     */
-    overwrite: function(el, values, returnElement) {
-        el = Ext.getDom(el);
-        el.innerHTML = this.applyTemplate(values);
-        return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
-    }
-}, function() {
-
-    /**
-     * Alias for {@link #applyTemplate}
-     * Returns an HTML fragment of this template with the specified <code>values</code> applied.
-     * @param {Object/Array} values
-     * The template values. Can be an array if the params are numeric (i.e. <code>{0}</code>)
-     * or an object (i.e. <code>{foo: 'bar'}</code>).
-     * @return {String} The HTML fragment
-     * @member Ext.Template
-     * @method apply
-     */
-    this.createAlias('apply', 'applyTemplate');
-});
-
-/**
- * @class Ext.ComponentQuery
- * @extends Object
- *
- * Provides searching of Components within Ext.ComponentManager (globally) or a specific
- * Ext.container.Container on the document with a similar syntax to a CSS selector.
- *
- * Components can be retrieved by using their {@link Ext.Component xtype} with an optional . prefix
-<ul>
-    <li>component or .component</li>
-    <li>gridpanel or .gridpanel</li>
-</ul>
- *
- * An itemId or id must be prefixed with a #
-<ul>
-    <li>#myContainer</li>
-</ul>
- *
- *
- * Attributes must be wrapped in brackets
-<ul>
-    <li>component[autoScroll]</li>
-    <li>panel[title="Test"]</li>
-</ul>
- *
- * Member expressions from candidate Components may be tested. If the expression returns a <i>truthy</i> value,
- * the candidate Component will be included in the query:<pre><code>
-var disabledFields = myFormPanel.query("{isDisabled()}");
-</code></pre>
- *
- * Pseudo classes may be used to filter results in the same way as in {@link Ext.DomQuery DomQuery}:<code><pre>
-// Function receives array and returns a filtered array.
-Ext.ComponentQuery.pseudos.invalid = function(items) {
-    var i = 0, l = items.length, c, result = [];
-    for (; i < l; i++) {
-        if (!(c = items[i]).isValid()) {
-            result.push(c);
-        }
-    }
-    return result;
-};
-
-var invalidFields = myFormPanel.query('field:invalid');
-if (invalidFields.length) {
-    invalidFields[0].getEl().scrollIntoView(myFormPanel.body);
-    for (var i = 0, l = invalidFields.length; i < l; i++) {
-        invalidFields[i].getEl().frame("red");
-    }
-}
-</pre></code>
- * <p>
- * Default pseudos include:<br />
- * - not
- * </p>
- *
- * Queries return an array of components.
- * Here are some example queries.
-<pre><code>
-    // retrieve all Ext.Panels in the document by xtype
-    var panelsArray = Ext.ComponentQuery.query('panel');
-
-    // retrieve all Ext.Panels within the container with an id myCt
-    var panelsWithinmyCt = Ext.ComponentQuery.query('#myCt panel');
-
-    // retrieve all direct children which are Ext.Panels within myCt
-    var directChildPanel = Ext.ComponentQuery.query('#myCt > panel');
-
-    // retrieve all gridpanels and listviews
-    var gridsAndLists = Ext.ComponentQuery.query('gridpanel, listview');
-</code></pre>
-
-For easy access to queries based from a particular Container see the {@link Ext.container.Container#query},
-{@link Ext.container.Container#down} and {@link Ext.container.Container#child} methods. Also see
-{@link Ext.Component#up}.
- * @singleton
- */
 Ext.define('Ext.ComponentQuery', {
     singleton: true,
     uses: ['Ext.ComponentManager']
@@ -14340,8 +14402,8 @@ Ext.define('Ext.ComponentQuery', {
 
     var cq = this,
 
-        // A function source code pattern with a placeholder which accepts an expression which yields a truth value when applied
-        // as a member on each item in the passed array.
+        
+        
         filterFnPattern = [
             'var r = [],',
                 'i = 0,',
@@ -14358,9 +14420,9 @@ Ext.define('Ext.ComponentQuery', {
         ].join(''),
 
         filterItems = function(items, operation) {
-            // Argument list for the operation is [ itemsArray, operationArg1, operationArg2...]
-            // The operation's method loops over each item in the candidate array and
-            // returns an array of items which match its criteria
+            
+            
+            
             return operation.method.apply(this, [ items ].concat(operation.args));
         },
 
@@ -14394,7 +14456,7 @@ Ext.define('Ext.ComponentQuery', {
             return result;
         },
 
-        // Filters the passed candidate array and returns only items which match the passed xtype
+        
         filterByXType = function(items, xtype, shallow) {
             if (xtype === '*') {
                 return items.slice();
@@ -14414,7 +14476,7 @@ Ext.define('Ext.ComponentQuery', {
             }
         },
 
-        // Filters the passed candidate array and returns only items which have the passed className
+        
         filterByClassName = function(items, className) {
             var EA = Ext.Array,
                 result = [],
@@ -14430,7 +14492,7 @@ Ext.define('Ext.ComponentQuery', {
             return result;
         },
 
-        // Filters the passed candidate array and returns only items which have the specified property match
+        
         filterByAttribute = function(items, property, operator, value) {
             var result = [],
                 i = 0,
@@ -14445,7 +14507,7 @@ Ext.define('Ext.ComponentQuery', {
             return result;
         },
 
-        // Filters the passed candidate array and returns only items which have the specified itemId or id
+        
         filterById = function(items, id) {
             var result = [],
                 i = 0,
@@ -14460,62 +14522,56 @@ Ext.define('Ext.ComponentQuery', {
             return result;
         },
 
-        // Filters the passed candidate array and returns only items which the named pseudo class matcher filters in
+        
         filterByPseudo = function(items, name, value) {
             return cq.pseudos[name](items, value);
         },
 
-        // Determines leading mode
-        // > for direct child, and ^ to switch to ownerCt axis
+        
+        
         modeRe = /^(\s?([>\^])\s?|\s|$)/,
 
-        // Matches a token with possibly (true|false) appended for the "shallow" parameter
+        
         tokenRe = /^(#)?([\w\-]+|\*)(?:\((true|false)\))?/,
 
         matchers = [{
-            // Checks for .xtype with possibly (true|false) appended for the "shallow" parameter
+            
             re: /^\.([\w\-]+)(?:\((true|false)\))?/,
             method: filterByXType
         },{
-            // checks for [attribute=value]
+            
             re: /^(?:[\[](?:@)?([\w\-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]])/,
             method: filterByAttribute
         }, {
-            // checks for #cmpItemId
+            
             re: /^#([\w\-]+)/,
             method: filterById
         }, {
-            // checks for :<pseudo_class>(<selector>)
+            
             re: /^\:([\w\-]+)(?:\(((?:\{[^\}]+\})|(?:(?!\{)[^\s>\/]*?(?!\})))\))?/,
             method: filterByPseudo
         }, {
-            // checks for {<member_expression>}
+            
             re: /^(?:\{([^\}]+)\})/,
             method: filterFnPattern
         }];
 
-    /**
-     * @class Ext.ComponentQuery.Query
-     * @extends Object
-     * @private
-     */
+    
+    
     cq.Query = Ext.extend(Object, {
         constructor: function(cfg) {
             cfg = cfg || {};
             Ext.apply(this, cfg);
         },
 
-        /**
-         * @private
-         * Executes this Query upon the selected root.
-         * The root provides the initial source of candidate Component matches which are progressively
-         * filtered by iterating through this Query's operations cache.
-         * If no root is provided, all registered Components are searched via the ComponentManager.
-         * root may be a Container who's descendant Components are filtered
-         * root may be a Component with an implementation of getRefItems which provides some nested Components such as the
-         * docked items within a Panel.
-         * root may be an array of candidate Components to filter using this Query.
-         */
+        
+        
+        
+        
+        
+        
+        
+        
         execute : function(root) {
             var operations = this.operations,
                 i = 0,
@@ -14523,26 +14579,26 @@ Ext.define('Ext.ComponentQuery', {
                 operation,
                 workingItems;
 
-            // no root, use all Components in the document
+            
             if (!root) {
                 workingItems = Ext.ComponentManager.all.getArray();
             }
-            // Root is a candidate Array
+            
             else if (Ext.isArray(root)) {
                 workingItems = root;
             }
 
-            // We are going to loop over our operations and take care of them
-            // one by one.
+            
+            
             for (; i < length; i++) {
                 operation = operations[i];
 
-                // The mode operation requires some custom handling.
-                // All other operations essentially filter down our current
-                // working items, while mode replaces our current working
-                // items by getting children from each one of our current
-                // working items. The type of mode determines the type of
-                // children we get. (e.g. > only gets direct children)
+                
+                
+                
+                
+                
+                
                 if (operation.mode === '^') {
                     workingItems = getAncestors(workingItems || [root]);
                 }
@@ -14553,8 +14609,8 @@ Ext.define('Ext.ComponentQuery', {
                     workingItems = filterItems(workingItems || getItems([root]), operation);
                 }
 
-                // If this is the last operation, it means our current working
-                // items are the final matched items. Thus return them!
+                
+                
                 if (i === length -1) {
                     return workingItems;
                 }
@@ -14586,10 +14642,10 @@ Ext.define('Ext.ComponentQuery', {
 
     Ext.apply(this, {
 
-        // private cache of selectors and matching ComponentQuery.Query objects
+        
         cache: {},
 
-        // private cache of pseudo class filter functions
+        
         pseudos: {
             not: function(components, selector){
                 var CQ = Ext.ComponentQuery,
@@ -14606,22 +14662,13 @@ Ext.define('Ext.ComponentQuery', {
                     }
                 }
                 return results;
+            },
+            last: function(components) {
+                return components[components.length - 1];
             }
         },
 
-        /**
-         * <p>Returns an array of matched Components from within the passed root object.</p>
-         * <p>This method filters returned Components in a similar way to how CSS selector based DOM
-         * queries work using a textual selector string.</p>
-         * <p>See class summary for details.</p>
-         * @param selector The selector string to filter returned Components
-         * @param root <p>The Container within which to perform the query. If omitted, all Components
-         * within the document are included in the search.</p>
-         * <p>This parameter may also be an array of Components to filter according to the selector.</p>
-         * @returns {Array} The matched Components.
-         * @member Ext.ComponentQuery
-         * @method query
-         */
+        
         query: function(selector, root) {
             var selectors = selector.split(','),
                 length = selectors.length,
@@ -14640,8 +14687,8 @@ Ext.define('Ext.ComponentQuery', {
                 results = results.concat(query.execute(root));
             }
 
-            // multiple selectors, potential to find duplicates
-            // lets filter them out.
+            
+            
             if (length > 1) {
                 resultsLn = results.length;
                 for (i = 0; i < resultsLn; i++) {
@@ -14656,14 +14703,7 @@ Ext.define('Ext.ComponentQuery', {
             return results;
         },
 
-        /**
-         * Tests whether the passed Component matches the selector string.
-         * @param component The Component to test
-         * @param selector The selector string to test against.
-         * @return {Boolean} True if the Component matches the selector.
-         * @member Ext.ComponentQuery
-         * @method query
-         */
+        
         is: function(component, selector) {
             if (!selector) {
                 return true;
@@ -14685,35 +14725,35 @@ Ext.define('Ext.ComponentQuery', {
                 selectorMatch,
                 i, matcher, method;
 
-            // We are going to parse the beginning of the selector over and
-            // over again, slicing off the selector any portions we converted into an
-            // operation, until it is an empty string.
+            
+            
+            
             while (selector && lastSelector !== selector) {
                 lastSelector = selector;
 
-                // First we check if we are dealing with a token like #, * or an xtype
+                
                 tokenMatch = selector.match(tokenRe);
 
                 if (tokenMatch) {
                     matchedChar = tokenMatch[1];
 
-                    // If the token is prefixed with a # we push a filterById operation to our stack
+                    
                     if (matchedChar === '#') {
                         operations.push({
                             method: filterById,
                             args: [Ext.String.trim(tokenMatch[2])]
                         });
                     }
-                    // If the token is prefixed with a . we push a filterByClassName operation to our stack
-                    // FIXME: Not enabled yet. just needs \. adding to the tokenRe prefix
+                    
+                    
                     else if (matchedChar === '.') {
                         operations.push({
                             method: filterByClassName,
                             args: [Ext.String.trim(tokenMatch[2])]
                         });
                     }
-                    // If the token is a * or an xtype string, we push a filterByXType
-                    // operation to the stack.
+                    
+                    
                     else {
                         operations.push({
                             method: filterByXType,
@@ -14721,49 +14761,45 @@ Ext.define('Ext.ComponentQuery', {
                         });
                     }
 
-                    // Now we slice of the part we just converted into an operation
+                    
                     selector = selector.replace(tokenMatch[0], '');
                 }
 
-                // If the next part of the query is not a space or > or ^, it means we
-                // are going to check for more things that our current selection
-                // has to comply to.
+                
+                
+                
                 while (!(modeMatch = selector.match(modeRe))) {
-                    // Lets loop over each type of matcher and execute it
-                    // on our current selector.
+                    
+                    
                     for (i = 0; selector && i < length; i++) {
                         matcher = matchers[i];
                         selectorMatch = selector.match(matcher.re);
                         method = matcher.method;
 
-                        // If we have a match, add an operation with the method
-                        // associated with this matcher, and pass the regular
-                        // expression matches are arguments to the operation.
+                        
+                        
+                        
                         if (selectorMatch) {
                             operations.push({
                                 method: Ext.isString(matcher.method)
-                                    // Turn a string method into a function by formatting the string with our selector matche expression
-                                    // A new method is created for different match expressions, eg {id=='textfield-1024'}
-                                    // Every expression may be different in different selectors.
+                                    
+                                    
+                                    
                                     ? Ext.functionFactory('items', Ext.String.format.apply(Ext.String, [method].concat(selectorMatch.slice(1))))
                                     : matcher.method,
                                 args: selectorMatch.slice(1)
                             });
                             selector = selector.replace(selectorMatch[0], '');
-                            break; // Break on match
-                        }
-                        // Exhausted all matches: It's an error
-                        if (i === (length - 1)) {
-                            Ext.Error.raise('Invalid ComponentQuery selector: "' + arguments[0] + '"');
+                            break; 
                         }
                     }
                 }
 
-                // Now we are going to check for a mode change. This means a space
-                // or a > to determine if we are going to select all the children
-                // of the currently matched items, or a ^ if we are going to use the
-                // ownerCt axis as the candidate source.
-                if (modeMatch[1]) { // Assignment, and test for truthiness!
+                
+                
+                
+                
+                if (modeMatch[1]) { 
                     operations.push({
                         mode: modeMatch[2]||modeMatch[1]
                     });
@@ -14771,3254 +14807,2295 @@ Ext.define('Ext.ComponentQuery', {
                 }
             }
 
-            //  Now that we have all our operations in an array, we are going
-            // to create a new Query using these operations.
+            
+            
             return new cq.Query({
                 operations: operations
             });
         }
     });
 });
-/**
- * @class Ext.util.Filter
- * @extends Object
- * <p>Represents a filter that can be applied to a {@link Ext.util.MixedCollection MixedCollection}. Can either simply
- * filter on a property/value pair or pass in a filter function with custom logic. Filters are always used in the context
- * of MixedCollections, though {@link Ext.data.Store Store}s frequently create them when filtering and searching on their
- * records. Example usage:</p>
-<pre><code>
-//set up a fictional MixedCollection containing a few people to filter on
-var allNames = new Ext.util.MixedCollection();
-allNames.addAll([
-    {id: 1, name: 'Ed',    age: 25},
-    {id: 2, name: 'Jamie', age: 37},
-    {id: 3, name: 'Abe',   age: 32},
-    {id: 4, name: 'Aaron', age: 26},
-    {id: 5, name: 'David', age: 32}
-]);
-
-var ageFilter = new Ext.util.Filter({
-    property: 'age',
-    value   : 32
-});
-
-var longNameFilter = new Ext.util.Filter({
-    filterFn: function(item) {
-        return item.name.length > 4;
-    }
-});
-
-//a new MixedCollection with the 3 names longer than 4 characters
-var longNames = allNames.filter(longNameFilter);
-
-//a new MixedCollection with the 2 people of age 24:
-var youngFolk = allNames.filter(ageFilter);
-</code></pre>
- * @constructor
- * @param {Object} config Config object
- */
-Ext.define('Ext.util.Filter', {
 
-    /* Begin Definitions */
+Ext.define('Ext.util.HashMap', {
+    mixins: {
+        observable: 'Ext.util.Observable'
+    },
 
-    /* End Definitions */
-    /**
-     * @cfg {String} property The property to filter on. Required unless a {@link #filter} is passed
-     */
-    
-    /**
-     * @cfg {Function} filterFn A custom filter function which is passed each item in the {@link Ext.util.MixedCollection} 
-     * in turn. Should return true to accept each item or false to reject it
-     */
-    
-    /**
-     * @cfg {Boolean} anyMatch True to allow any match - no regex start/end line anchors will be added. Defaults to false
-     */
-    anyMatch: false,
     
-    /**
-     * @cfg {Boolean} exactMatch True to force exact match (^ and $ characters added to the regex). Defaults to false.
-     * Ignored if anyMatch is true.
-     */
-    exactMatch: false,
-    
-    /**
-     * @cfg {Boolean} caseSensitive True to make the regex case sensitive (adds 'i' switch to regex). Defaults to false.
-     */
-    caseSensitive: false,
-    
-    /**
-     * @cfg {String} root Optional root property. This is mostly useful when filtering a Store, in which case we set the
-     * root to 'data' to make the filter pull the {@link #property} out of the data object of each item
-     */
+
     
     constructor: function(config) {
-        Ext.apply(this, config);
-        
-        //we're aliasing filter to filterFn mostly for API cleanliness reasons, despite the fact it dirties the code here.
-        //Ext.util.Sorter takes a sorterFn property but allows .sort to be called - we do the same here
-        this.filter = this.filter || this.filterFn;
+        config = config || {};
         
-        if (this.filter == undefined) {
-            if (this.property == undefined || this.value == undefined) {
-                // Commented this out temporarily because it stops us using string ids in models. TODO: Remove this once
-                // Model has been updated to allow string ids
-                
-                // Ext.Error.raise("A Filter requires either a property or a filterFn to be set");
-            } else {
-                this.filter = this.createFilterFn();
-            }
+        var me = this,
+            keyFn = config.keyFn;
+
+        me.addEvents(
+            
+            'add',
+            
+            'clear',
             
-            this.filterFn = this.filter;
+            'remove',
+            
+            'replace'
+        );
+
+        me.mixins.observable.constructor.call(me, config);
+        me.clear(true);
+        
+        if (keyFn) {
+            me.getKey = keyFn;
         }
     },
+
     
-    /**
-     * @private
-     * Creates a filter function for the configured property/value/anyMatch/caseSensitive options for this Filter
-     */
-    createFilterFn: function() {
-        var me       = this,
-            matcher  = me.createValueMatcher(),
-            property = me.property;
+    getCount: function() {
+        return this.length;
+    },
+
+    
+    getData: function(key, value) {
         
-        return function(item) {
-            return matcher.test(me.getRoot.call(me, item)[property]);
-        };
+        if (value === undefined) {
+            value = key;
+            key = this.getKey(value);
+        }
+
+        return [key, value];
     },
+
     
-    /**
-     * @private
-     * Returns the root property of the given item, based on the configured {@link #root} property
-     * @param {Object} item The item
-     * @return {Object} The root property of the object
-     */
-    getRoot: function(item) {
-        return this.root == undefined ? item : item[this.root];
+    getKey: function(o) {
+        return o.id;
     },
+
     
-    /**
-     * @private
-     * Returns a regular expression based on the given value and matching options
-     */
-    createValueMatcher : function() {
-        var me            = this,
-            value         = me.value,
-            anyMatch      = me.anyMatch,
-            exactMatch    = me.exactMatch,
-            caseSensitive = me.caseSensitive,
-            escapeRe      = Ext.String.escapeRegex;
-        
-        if (!value.exec) { // not a regex
-            value = String(value);
+    add: function(key, value) {
+        var me = this,
+            data;
 
-            if (anyMatch === true) {
-                value = escapeRe(value);
-            } else {
-                value = '^' + escapeRe(value);
-                if (exactMatch === true) {
-                    value += '$';
-                }
-            }
-            value = new RegExp(value, caseSensitive ? '' : 'i');
-         }
-         
-         return value;
-    }
-});
-/**
- * @class Ext.util.Sorter
- * @extends Object
- * Represents a single sorter that can be applied to a Store
- */
-Ext.define('Ext.util.Sorter', {
+        if (arguments.length === 1) {
+            value = key;
+            key = me.getKey(value);
+        }
+
+        if (me.containsKey(key)) {
+            return me.replace(key, value);
+        }
+
+        data = me.getData(key, value);
+        key = data[0];
+        value = data[1];
+        me.map[key] = value;
+        ++me.length;
+        me.fireEvent('add', me, key, value);
+        return value;
+    },
 
-    /**
-     * @cfg {String} property The property to sort by. Required unless {@link #sorter} is provided
-     */
     
-    /**
-     * @cfg {Function} sorterFn A specific sorter function to execute. Can be passed instead of {@link #property}
-     */
+    replace: function(key, value) {
+        var me = this,
+            map = me.map,
+            old;
+
+        if (!me.containsKey(key)) {
+            me.add(key, value);
+        }
+        old = map[key];
+        map[key] = value;
+        me.fireEvent('replace', me, key, value, old);
+        return value;
+    },
+
     
-    /**
-     * @cfg {String} root Optional root property. This is mostly useful when sorting a Store, in which case we set the
-     * root to 'data' to make the filter pull the {@link #property} out of the data object of each item
-     */
+    remove: function(o) {
+        var key = this.findKey(o);
+        if (key !== undefined) {
+            return this.removeAtKey(key);
+        }
+        return false;
+    },
+
     
-    /**
-     * @cfg {Function} transform A function that will be run on each value before
-     * it is compared in the sorter. The function will receive a single argument,
-     * the value.
-     */
+    removeAtKey: function(key) {
+        var me = this,
+            value;
+
+        if (me.containsKey(key)) {
+            value = me.map[key];
+            delete me.map[key];
+            --me.length;
+            me.fireEvent('remove', me, key, value);
+            return true;
+        }
+        return false;
+    },
+
     
-    /**
-     * @cfg {String} direction The direction to sort by. Defaults to ASC
-     */
-    direction: "ASC",
+    get: function(key) {
+        return this.map[key];
+    },
+
     
-    constructor: function(config) {
+    clear: function( initial) {
         var me = this;
-        
-        Ext.apply(me, config);
-        
-        if (me.property == undefined && me.sorterFn == undefined) {
-            Ext.Error.raise("A Sorter requires either a property or a sorter function");
+        me.map = {};
+        me.length = 0;
+        if (initial !== true) {
+            me.fireEvent('clear', me);
         }
-        
-        me.updateSortFunction();
+        return me;
     },
+
     
-    /**
-     * @private
-     * Creates and returns a function which sorts an array by the given property and direction
-     * @return {Function} A function which sorts by the property/direction combination provided
-     */
-    createSortFunction: function(sorterFn) {
-        var me        = this,
-            property  = me.property,
-            direction = me.direction || "ASC",
-            modifier  = direction.toUpperCase() == "DESC" ? -1 : 1;
-        
-        //create a comparison function. Takes 2 objects, returns 1 if object 1 is greater,
-        //-1 if object 2 is greater or 0 if they are equal
-        return function(o1, o2) {
-            return modifier * sorterFn.call(me, o1, o2);
-        };
+    containsKey: function(key) {
+        return this.map[key] !== undefined;
     },
+
     
-    /**
-     * @private
-     * Basic default sorter function that just compares the defined property of each object
-     */
-    defaultSorterFn: function(o1, o2) {
-        var me = this,
-            transform = me.transform,
-            v1 = me.getRoot(o1)[me.property],
-            v2 = me.getRoot(o2)[me.property];
-            
-        if (transform) {
-            v1 = transform(v1);
-            v2 = transform(v2);
-        }
+    contains: function(value) {
+        return this.containsKey(this.findKey(value));
+    },
 
-        return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
+    
+    getKeys: function() {
+        return this.getArray(true);
     },
+
     
-    /**
-     * @private
-     * Returns the root property of the given item, based on the configured {@link #root} property
-     * @param {Object} item The item
-     * @return {Object} The root property of the object
-     */
-    getRoot: function(item) {
-        return this.root == undefined ? item : item[this.root];
+    getValues: function() {
+        return this.getArray(false);
     },
+
     
-    // @TODO: Add docs for these three methods
-    setDirection: function(direction) {
-        var me = this;
-        me.direction = direction;
-        me.updateSortFunction();
+    getArray: function(isKey) {
+        var arr = [],
+            key,
+            map = this.map;
+        for (key in map) {
+            if (map.hasOwnProperty(key)) {
+                arr.push(isKey ? key: map[key]);
+            }
+        }
+        return arr;
     },
+
     
-    toggle: function() {
-        var me = this;
-        me.direction = Ext.String.toggle(me.direction, "ASC", "DESC");
-        me.updateSortFunction();
+    each: function(fn, scope) {
+        
+        var items = Ext.apply({}, this.map),
+            key,
+            length = this.length;
+
+        scope = scope || this;
+        for (key in items) {
+            if (items.hasOwnProperty(key)) {
+                if (fn.call(scope, key, items[key], length) === false) {
+                    break;
+                }
+            }
+        }
+        return this;
     },
+
     
-    updateSortFunction: function() {
-        var me = this;
-        me.sort = me.createSortFunction(me.sorterFn || me.defaultSorterFn);
-    }
-});
-/**
- * @class Ext.ElementLoader
- * A class used to load remote content to an Element. Sample usage:
- * <pre><code>
-Ext.get('el').load({
-    url: 'myPage.php',
-    scripts: true,
-    params: {
-        id: 1
+    clone: function() {
+        var hash = new this.self(),
+            map = this.map,
+            key;
+
+        hash.suspendEvents();
+        for (key in map) {
+            if (map.hasOwnProperty(key)) {
+                hash.add(key, map[key]);
+            }
+        }
+        hash.resumeEvents();
+        return hash;
+    },
+
+    
+    findKey: function(value) {
+        var key,
+            map = this.map;
+
+        for (key in map) {
+            if (map.hasOwnProperty(key) && map[key] === value) {
+                return key;
+            }
+        }
+        return undefined;
     }
 });
- * </code></pre>
- * <p>
- * In general this class will not be instanced directly, rather the {@link Ext.core.Element#load} method
- * will be used.
- * </p>
- */
-Ext.define('Ext.ElementLoader', {
 
-    /* Begin Definitions */
 
-    mixins: {
-        observable: 'Ext.util.Observable'
+Ext.define('Ext.state.Manager', {
+    singleton: true,
+    requires: ['Ext.state.Provider'],
+    constructor: function() {
+        this.provider = Ext.create('Ext.state.Provider');
+    },
+    
+    
+    
+    setProvider : function(stateProvider){
+        this.provider = stateProvider;
     },
 
-    uses: [
-        'Ext.data.Connection',
-        'Ext.Ajax'
-    ],
     
-    statics: {
-        Renderer: {
-            Html: function(loader, response, active){
-                loader.getTarget().update(response.responseText, active.scripts === true);
-                return true;
-            }
-        }     
+    get : function(key, defaultValue){
+        return this.provider.get(key, defaultValue);
     },
 
-    /* End Definitions */
+    
+     set : function(key, value){
+        this.provider.set(key, value);
+    },
 
-    /**
-     * @cfg {String} url The url to retrieve the content from. Defaults to <tt>null</tt>.
-     */
-    url: null,
+    
+    clear : function(key){
+        this.provider.clear(key);
+    },
 
-    /**
-     * @cfg {Object} params Any params to be attached to the Ajax request. These parameters will
-     * be overridden by any params in the load options. Defaults to <tt>null</tt>.
-     */
-    params: null,
+    
+    getProvider : function(){
+        return this.provider;
+    }
+});
 
-    /**
-     * @cfg {Object} baseParams Params that will be attached to every request. These parameters
-     * will not be overridden by any params in the load options. Defaults to <tt>null</tt>.
-     */
-    baseParams: null,
+Ext.define('Ext.state.Stateful', {
 
-    /**
-     * @cfg {Boolean/Object} autoLoad True to have the loader make a request as soon as it is created. Defaults to <tt>false</tt>.
-     * This argument can also be a set of options that will be passed to {@link #load} is called.
-     */
-    autoLoad: false,
+    
 
-    /**
-     * @cfg {Mixed} target The target element for the loader. It can be the DOM element, the id or an Ext.Element.
-     */
-    target: null,
+   mixins: {
+        observable: 'Ext.util.Observable'
+    },
 
-    /**
-     * @cfg {Mixed} loadMask True or a string to show when the element is loading.
-     */
-    loadMask: false,
+    requires: ['Ext.state.Manager'],
 
-    /**
-     * @cfg {Object} ajaxOptions Any additional options to be passed to the request, for example timeout or headers. Defaults to <tt>null</tt>.
-     */
-    ajaxOptions: null,
     
-    /**
-     * @cfg {Boolean} scripts True to parse any inline script tags in the response.
-     */
-    scripts: false,
 
-    /**
-     * @cfg {Function} success A function to be called when a load request is successful.
-     */
+    
+    stateful: true,
 
-    /**
-     * @cfg {Function} failure A function to be called when a load request fails.
-     */
+    
 
-    /**
-     * @cfg {Object} scope The scope to execute the {@link #success} and {@link #failure} functions in.
-     */
     
-    /**
-     * @cfg {Function} renderer A custom function to render the content to the element. The passed parameters
-     * are
-     * <ul>
-     * <li>The loader</li>
-     * <li>The response</li>
-     * <li>The active request</li>
-     * </ul>
-     */
 
-    isLoader: true,
+    
+    saveDelay: 100,
+
+    autoGenIdRe: /^((\w+-)|(ext-comp-))\d{4,}$/i,
 
     constructor: function(config) {
-        var me = this,
-            autoLoad;
-        
+        var me = this;
+
         config = config || {};
-        Ext.apply(me, config);
-        me.setTarget(me.target);
-        me.addEvents(
-            /**
-             * @event beforeload
-             * Fires before a load request is made to the server.
-             * Returning false from an event listener can prevent the load
-             * from occurring.
-             * @param {Ext.ElementLoader} this
-             * @param {Object} options The options passed to the request
-             */
-            'beforeload',
+        if (Ext.isDefined(config.stateful)) {
+            me.stateful = config.stateful;
+        }
+        if (Ext.isDefined(config.saveDelay)) {
+            me.saveDelay = config.saveDelay;
+        }
+        me.stateId = me.stateId || config.stateId;
 
-            /**
-             * @event exception
-             * Fires after an unsuccessful load.
-             * @param {Ext.ElementLoader} this
-             * @param {Object} response The response from the server
-             * @param {Object} options The options passed to the request
-             */
-            'exception',
+        if (!me.stateEvents) {
+            me.stateEvents = [];
+        }
+        if (config.stateEvents) {
+            me.stateEvents.concat(config.stateEvents);
+        }
+        this.addEvents(
+            
+            'beforestaterestore',
 
-            /**
-             * @event exception
-             * Fires after a successful load.
-             * @param {Ext.ElementLoader} this
-             * @param {Object} response The response from the server
-             * @param {Object} options The options passed to the request
-             */
-            'load'
-        );
+            
+            'staterestore',
 
-        // don't pass config because we have already applied it.
-        me.mixins.observable.constructor.call(me);
+            
+            'beforestatesave',
 
-        if (me.autoLoad) {
-            autoLoad = me.autoLoad;
-            if (autoLoad === true) {
-                autoLoad = {};
-            }
-            me.load(autoLoad);
+            
+            'statesave'
+        );
+        me.mixins.observable.constructor.call(me);
+        if (me.stateful !== false) {
+            me.initStateEvents();
+            me.initState();
         }
     },
 
-    /**
-     * Set an {Ext.Element} as the target of this loader. Note that if the target is changed,
-     * any active requests will be aborted.
-     * @param {Mixed} target The element
-     */
-    setTarget: function(target){
-        var me = this;
-        target = Ext.get(target);
-        if (me.target && me.target != target) {
-            me.abort();
-        }
-        me.target = target;
+    
+    initStateEvents: function() {
+        this.addStateEvents(this.stateEvents);
     },
 
-    /**
-     * Get the target of this loader.
-     * @return {Ext.Component} target The target, null if none exists.
-     */
-    getTarget: function(){
-        return this.target || null;
+    
+    addStateEvents: function(events){
+        if (!Ext.isArray(events)) {
+            events = [events];
+        }
+
+        var me = this,
+            i = 0,
+            len = events.length;
+
+        for (; i < len; ++i) {
+            me.on(events[i], me.onStateChange, me);
+        }
     },
 
-    /**
-     * Aborts the active load request
-     */
-    abort: function(){
-        var active = this.active;
-        if (active !== undefined) {
-            Ext.Ajax.abort(active.request);
-            if (active.mask) {
-                this.removeMask();
+    
+    onStateChange: function(){
+        var me = this,
+            delay = me.saveDelay;
+
+        if (delay > 0) {
+            if (!me.stateTask) {
+                me.stateTask = Ext.create('Ext.util.DelayedTask', me.saveState, me);
             }
-            delete this.active;
+            me.stateTask.delay(me.saveDelay);
+        } else {
+            me.saveState();
         }
     },
+
     
-    /**
-     * Remove the mask on the target
-     * @private
-     */
-    removeMask: function(){
-        this.target.unmask();
+    saveState: function() {
+        var me = this,
+            id,
+            state;
+
+        if (me.stateful !== false) {
+            id = me.getStateId();
+            if (id) {
+                state = me.getState();
+                if (me.fireEvent('beforestatesave', me, state) !== false) {
+                    Ext.state.Manager.set(id, state);
+                    me.fireEvent('statesave', me, state);
+                }
+            }
+        }
     },
+
     
-    /**
-     * Add the mask on the target
-     * @private
-     * @param {Mixed} mask The mask configuration
-     */
-    addMask: function(mask){
-        this.target.mask(mask === true ? null : mask);
+    getState: function(){
+        return null;
     },
 
-    /**
-     * Load new data from the server.
-     * @param {Object} options The options for the request. They can be any configuration option that can be specified for
-     * the class, with the exception of the target option. Note that any options passed to the method will override any
-     * class defaults.
-     */
-    load: function(options) {
-        if (!this.target) {
-            Ext.Error.raise('A valid target is required when loading content');
+    
+    applyState: function(state) {
+        if (state) {
+            Ext.apply(this, state);
         }
+    },
 
-        options = Ext.apply({}, options);
-
+    
+    getStateId: function() {
         var me = this,
-            target = me.target,
-            mask = Ext.isDefined(options.loadMask) ? options.loadMask : me.loadMask,
-            params = Ext.apply({}, options.params),
-            ajaxOptions = Ext.apply({}, options.ajaxOptions),
-            callback = options.callback || me.callback,
-            scope = options.scope || me.scope || me,
-            request;
+            id = me.stateId;
 
-        Ext.applyIf(ajaxOptions, me.ajaxOptions);
-        Ext.applyIf(options, ajaxOptions);
+        if (!id) {
+            id = me.autoGenIdRe.test(String(me.id)) ? null : me.id;
+        }
+        return id;
+    },
 
-        Ext.applyIf(params, me.params);
-        Ext.apply(params, me.baseParams);
+    
+    initState: function(){
+        var me = this,
+            id = me.getStateId(),
+            state;
 
-        Ext.applyIf(options, {
-            url: me.url
-        });
+        if (me.stateful !== false) {
+            if (id) {
+                state = Ext.state.Manager.get(id);
+                if (state) {
+                    state = Ext.apply({}, state);
+                    if (me.fireEvent('beforestaterestore', me, state) !== false) {
+                        me.applyState(state);
+                        me.fireEvent('staterestore', me, state);
+                    }
+                }
+            }
+        }
+    },
+
+    
+    savePropToState: function (propName, state, stateName) {
+        var me = this,
+            value = me[propName],
+            config = me.initialConfig;
 
-        if (!options.url) {
-            Ext.Error.raise('You must specify the URL from which content should be loaded');
+        if (me.hasOwnProperty(propName)) {
+            if (!config || config[propName] !== value) {
+                if (state) {
+                    state[stateName || propName] = value;
+                }
+                return true;
+            }
         }
+        return false;
+    },
 
-        Ext.apply(options, {
-            scope: me,
-            params: params,
-            callback: me.onComplete
+    savePropsToState: function (propNames, state) {
+        var me = this;
+        Ext.each(propNames, function (propName) {
+            me.savePropToState(propName, state);
         });
+        return state;
+    },
 
-        if (me.fireEvent('beforeload', me, options) === false) {
-            return;
+    
+    destroy: function(){
+        var task = this.stateTask;
+        if (task) {
+            task.cancel();
         }
+        this.clearListeners();
 
-        if (mask) {
-            me.addMask(mask);
-        }
+    }
+
+});
+
+
+Ext.define('Ext.AbstractManager', {
 
-        request = Ext.Ajax.request(options);
-        me.active = {
-            request: request,
-            options: options,
-            mask: mask,
-            scope: scope,
-            callback: callback,
-            success: options.success || me.success,
-            failure: options.failure || me.failure,
-            renderer: options.renderer || me.renderer,
-            scripts: Ext.isDefined(options.scripts) ? options.scripts : me.scripts
-        };
-        me.setOptions(me.active, options);
-    },
     
-    /**
-     * Set any additional options on the active request
-     * @private
-     * @param {Object} active The active request
-     * @param {Object} options The initial options
-     */
-    setOptions: Ext.emptyFn,
 
-    /**
-     * Parse the response after the request completes
-     * @private
-     * @param {Object} options Ajax options
-     * @param {Boolean} success Success status of the request
-     * @param {Object} response The response object
-     */
-    onComplete: function(options, success, response) {
-        var me = this,
-            active = me.active,
-            scope = active.scope,
-            renderer = me.getRenderer(active.renderer);
+    requires: ['Ext.util.HashMap'],
 
+    
 
-        if (success) {
-            success = renderer.call(me, me, response, active);
-        }
+    typeName: 'type',
 
-        if (success) {
-            Ext.callback(active.success, scope, [me, response, options]);
-            me.fireEvent('load', me, response, options);
-        } else {
-            Ext.callback(active.failure, scope, [me, response, options]);
-            me.fireEvent('exception', me, response, options);
-        }
-        Ext.callback(active.callback, scope, [me, success, response, options]);
+    constructor: function(config) {
+        Ext.apply(this, config || {});
 
-        if (active.mask) {
-            me.removeMask();
-        }
+        
+        this.all = Ext.create('Ext.util.HashMap');
 
-        delete me.active;
+        this.types = {};
     },
 
-    /**
-     * Gets the renderer to use
-     * @private
-     * @param {String/Function} renderer The renderer to use
-     * @return {Function} A rendering function to use.
-     */
-    getRenderer: function(renderer){
-        if (Ext.isFunction(renderer)) {
-            return renderer;
-        }
-        return this.statics().Renderer.Html;
-    },
     
-    /**
-     * Automatically refreshes the content over a specified period.
-     * @param {Number} interval The interval to refresh in ms.
-     * @param {Object} options (optional) The options to pass to the load method. See {@link #load}
-     */
-    startAutoRefresh: function(interval, options){
-        var me = this;
-        me.stopAutoRefresh();
-        me.autoRefresh = setInterval(function(){
-            me.load(options);
-        }, interval);
+    get : function(id) {
+        return this.all.get(id);
     },
+
     
-    /**
-     * Clears any auto refresh. See {@link #startAutoRefresh}.
-     */
-    stopAutoRefresh: function(){
-        clearInterval(this.autoRefresh);
-        delete this.autoRefresh;
+    register: function(item) {
+        this.all.add(item);
     },
+
     
-    /**
-     * Checks whether the loader is automatically refreshing. See {@link #startAutoRefresh}.
-     * @return {Boolean} True if the loader is automatically refreshing
-     */
-    isAutoRefreshing: function(){
-        return Ext.isDefined(this.autoRefresh);
+    unregister: function(item) {
+        this.all.remove(item);
     },
 
-    /**
-     * Destroys the loader. Any active requests will be aborted.
-     */
-    destroy: function(){
-        var me = this;
-        me.stopAutoRefresh();
-        delete me.target;
-        me.abort();
-        me.clearListeners();
-    }
-});
-
-/**
- * @class Ext.layout.Layout
- * @extends Object
- * @private
- * Base Layout class - extended by ComponentLayout and ContainerLayout
- */
+    
+    registerType : function(type, cls) {
+        this.types[type] = cls;
+        cls[this.typeName] = type;
+    },
 
-Ext.define('Ext.layout.Layout', {
+    
+    isRegistered : function(type){
+        return this.types[type] !== undefined;
+    },
 
-    /* Begin Definitions */
+    
+    create: function(config, defaultType) {
+        var type        = config[this.typeName] || config.type || defaultType,
+            Constructor = this.types[type];
 
-    /* End Definitions */
 
-    isLayout: true,
-    initialized: false,
+        return new Constructor(config);
+    },
 
-    statics: {
-        create: function(layout, defaultType) {
-            var type;
-            if (layout instanceof Ext.layout.Layout) {
-                return Ext.createByAlias('layout.' + layout);
-            } else {
-                if (Ext.isObject(layout)) {
-                    type = layout.type;
-                }
-                else {
-                    type = layout || defaultType;
-                    layout = {};
+    
+    onAvailable : function(id, fn, scope){
+        var all = this.all,
+            item;
+        
+        if (all.containsKey(id)) {
+            item = all.get(id);
+            fn.call(scope || item, item);
+        } else {
+            all.on('add', function(map, key, item){
+                if (key == id) {
+                    fn.call(scope || item, item);
+                    all.un('add', fn, scope);
                 }
-                return Ext.createByAlias('layout.' + type, layout || {});
-            }
+            });
         }
     },
-
-    constructor : function(config) {
-        this.id = Ext.id(null, this.type + '-');
-        Ext.apply(this, config);
+    
+    
+    each: function(fn, scope){
+        this.all.each(fn, scope || this);    
     },
+    
+    
+    getCount: function(){
+        return this.all.getCount();
+    }
+});
 
-    /**
-     * @private
-     */
-    layout : function() {
-        var me = this;
-        me.layoutBusy = true;
-        me.initLayout();
 
-        if (me.beforeLayout.apply(me, arguments) !== false) {
-            me.layoutCancelled = false;
-            me.onLayout.apply(me, arguments);
-            me.childrenChanged = false;
-            me.owner.needsLayout = false;
-            me.layoutBusy = false;
-            me.afterLayout.apply(me, arguments);
+Ext.define('Ext.ComponentManager', {
+    extend: 'Ext.AbstractManager',
+    alternateClassName: 'Ext.ComponentMgr',
+    
+    singleton: true,
+    
+    typeName: 'xtype',
+    
+    
+    create: function(component, defaultType){
+        if (component instanceof Ext.AbstractComponent) {
+            return component;
+        }
+        else if (Ext.isString(component)) {
+            return Ext.createByAlias('widget.' + component);
         }
         else {
-            me.layoutCancelled = true;
+            var type = component.xtype || defaultType,
+                config = component;
+            
+            return Ext.createByAlias('widget.' + type, config);
         }
-        me.layoutBusy = false;
-        me.doOwnerCtLayouts();
     },
 
-    beforeLayout : function() {
-        this.renderItems(this.getLayoutItems(), this.getRenderTarget());
-        return true;
-    },
+    registerType: function(type, cls) {
+        this.types[type] = cls;
+        cls[this.typeName] = type;
+        cls.prototype[this.typeName] = type;
+    }
+});
 
-    /**
-     * @private
-     * Iterates over all passed items, ensuring they are rendered.  If the items are already rendered,
-     * also determines if the items are in the proper place dom.
-     */
-    renderItems : function(items, target) {
-        var ln = items.length,
-            i = 0,
-            item;
+Ext.define('Ext.AbstractComponent', {
 
-        for (; i < ln; i++) {
-            item = items[i];
-            if (item && !item.rendered) {
-                this.renderItem(item, target, i);
-            }
-            else if (!this.isValidParent(item, target, i)) {
-                this.moveItem(item, target, i);
-            }
-        }
-    },
+    
+    requires: [
+        'Ext.ComponentQuery',
+        'Ext.ComponentManager'
+    ],
 
-    // @private - Validates item is in the proper place in the dom.
-    isValidParent : function(item, target, position) {
-        var dom = item.el ? item.el.dom : Ext.getDom(item);
-        if (dom && target && target.dom) {
-            if (Ext.isNumber(position) && dom !== target.dom.childNodes[position]) {
-                return false;
-            }
-            return (dom.parentNode == (target.dom || target));
-        }
-        return false;
+    mixins: {
+        observable: 'Ext.util.Observable',
+        animate: 'Ext.util.Animate',
+        state: 'Ext.state.Stateful'
     },
 
-    /**
-     * @private
-     * Renders the given Component into the target Element.
-     * @param {Ext.Component} item The Component to render
-     * @param {Ext.core.Element} target The target Element
-     * @param {Number} position The position within the target to render the item to
-     */
-    renderItem : function(item, target, position) {
-        if (!item.rendered) {
-            item.render(target, position);
-            this.configureItem(item);
-            this.childrenChanged = true;
-        }
-    },
+    
+    
+    uses: [
+        'Ext.PluginManager',
+        'Ext.ComponentManager',
+        'Ext.Element',
+        'Ext.DomHelper',
+        'Ext.XTemplate',
+        'Ext.ComponentQuery',
+        'Ext.ComponentLoader',
+        'Ext.EventManager',
+        'Ext.layout.Layout',
+        'Ext.layout.component.Auto',
+        'Ext.LoadMask',
+        'Ext.ZIndexManager'
+    ],
 
-    /**
-     * @private
-     * Moved Component to the provided target instead.
-     */
-    moveItem : function(item, target, position) {
-        // Make sure target is a dom element
-        target = target.dom || target;
-        if (typeof position == 'number') {
-            position = target.childNodes[position];
-        }
-        target.insertBefore(item.el.dom, position || null);
-        item.container = Ext.get(target);
-        this.configureItem(item);
-        this.childrenChanged = true;
+    statics: {
+        AUTO_ID: 1000
     },
 
-    /**
-     * @private
-     * Adds the layout's targetCls if necessary and sets
-     * initialized flag when complete.
-     */
-    initLayout : function() {
-        if (!this.initialized && !Ext.isEmpty(this.targetCls)) {
-            this.getTarget().addCls(this.targetCls);
-        }
-        this.initialized = true;
-    },
+    
 
-    // @private Sets the layout owner
-    setOwner : function(owner) {
-        this.owner = owner;
-    },
+    isComponent: true,
 
-    // @private - Returns empty array
-    getLayoutItems : function() {
-        return [];
+    getAutoId: function() {
+        return ++Ext.AbstractComponent.AUTO_ID;
     },
 
-    /**
-     * @private
-     * Applies itemCls
-     */
-    configureItem: function(item) {
-        var me = this,
-            el = item.el,
-            owner = me.owner;
-            
-        if (me.itemCls) {
-            el.addCls(me.itemCls);
-        }
-        if (owner.itemCls) {
-            el.addCls(owner.itemCls);
-        }
-    },
+
     
-    // Placeholder empty functions for subclasses to extend
-    onLayout : Ext.emptyFn,
-    afterLayout : Ext.emptyFn,
-    onRemove : Ext.emptyFn,
-    onDestroy : Ext.emptyFn,
-    doOwnerCtLayouts : Ext.emptyFn,
 
-    /**
-     * @private
-     * Removes itemCls
-     */
-    afterRemove : function(item) {
-        var me = this,
-            el = item.el,
-            owner = me.owner;
-            
-        if (item.rendered) {
-            if (me.itemCls) {
-                el.removeCls(me.itemCls);
-            }
-            if (owner.itemCls) {
-                el.removeCls(owner.itemCls);
-            }
-        }
-    },
+    
 
-    /*
-     * Destroys this layout. This is a template method that is empty by default, but should be implemented
-     * by subclasses that require explicit destruction to purge event handlers or remove DOM nodes.
-     * @protected
-     */
-    destroy : function() {
-        if (!Ext.isEmpty(this.targetCls)) {
-            var target = this.getTarget();
-            if (target) {
-                target.removeCls(this.targetCls);
-            }
-        }
-        this.onDestroy();
-    }
-});
-/**
- * @class Ext.layout.component.Component
- * @extends Ext.layout.Layout
- * @private
- * <p>This class is intended to be extended or created via the <tt><b>{@link Ext.Component#componentLayout layout}</b></tt>
- * configuration property.  See <tt><b>{@link Ext.Component#componentLayout}</b></tt> for additional details.</p>
- */
+    
 
-Ext.define('Ext.layout.component.Component', {
+    
 
-    /* Begin Definitions */
+    
 
-    extend: 'Ext.layout.Layout',
+    
 
-    /* End Definitions */
+    
+    renderTpl: null,
 
-    type: 'component',
+    
 
-    monitorChildren: true,
+    
 
-    initLayout : function() {
-        var me = this,
-            owner = me.owner,
-            ownerEl = owner.el;
+    
 
-        if (!me.initialized) {
-            if (owner.frameSize) {
-                me.frameSize = owner.frameSize;
-            }
-            else {
-                owner.frameSize = me.frameSize = {
-                    top: 0,
-                    left: 0,
-                    bottom: 0,
-                    right: 0
-                }; 
-            }
-        }
-        me.callParent(arguments);
-    },
+    
 
-    beforeLayout : function(width, height, isSetSize, layoutOwner) {
-        this.callParent(arguments);
+    
 
-        var me = this,
-            owner = me.owner,
-            ownerCt = owner.ownerCt,
-            layout = owner.layout,
-            isVisible = owner.isVisible(true),
-            ownerElChild = owner.el.child,
-            layoutCollection;
+    
 
-        /**
-        * Do not layout calculatedSized components for fixedLayouts unless the ownerCt == layoutOwner
-        * fixedLayouts means layouts which are never auto/auto in the sizing that comes from their ownerCt.
-        * Currently 3 layouts MAY be auto/auto (Auto, Border, and Box)
-        * The reason for not allowing component layouts is to stop component layouts from things such as Updater and
-        * form Validation.
-        */
-        if (!isSetSize && !(Ext.isNumber(width) && Ext.isNumber(height)) && ownerCt && ownerCt.layout && ownerCt.layout.fixedLayout && ownerCt != layoutOwner) {
-            me.doContainerLayout();
-            return false;
-        }
+    
 
-        // If an ownerCt is hidden, add my reference onto the layoutOnShow stack.  Set the needsLayout flag.
-        // If the owner itself is a directly hidden floater, set the needsLayout object on that for when it is shown.
-        if (!isVisible && (owner.hiddenAncestor || owner.floating)) {
-            if (owner.hiddenAncestor) {
-                layoutCollection = owner.hiddenAncestor.layoutOnShow;
-                layoutCollection.remove(owner);
-                layoutCollection.add(owner);
-            }
-            owner.needsLayout = {
-                width: width,
-                height: height,
-                isSetSize: false
-            };
-        }
+    
 
-        if (isVisible && this.needsLayout(width, height)) {
-            me.rawWidth = width;
-            me.rawHeight = height;
-            return owner.beforeComponentLayout(width, height, isSetSize, layoutOwner);
-        }
-        else {
-            return false;
-        }
-    },
+    
 
-    /**
-    * Check if the new size is different from the current size and only
-    * trigger a layout if it is necessary.
-    * @param {Mixed} width The new width to set.
-    * @param {Mixed} height The new height to set.
-    */
-    needsLayout : function(width, height) {
-        this.lastComponentSize = this.lastComponentSize || {
-            width: -Infinity,
-            height: -Infinity
-        };
-        return (this.childrenChanged || this.lastComponentSize.width !== width || this.lastComponentSize.height !== height);
-    },
+    
 
-    /**
-    * Set the size of any element supporting undefined, null, and values.
-    * @param {Mixed} width The new width to set.
-    * @param {Mixed} height The new height to set.
-    */
-    setElementSize: function(el, width, height) {
-        if (width !== undefined && height !== undefined) {
-            el.setSize(width, height);
-        }
-        else if (height !== undefined) {
-            el.setHeight(height);
-        }
-        else if (width !== undefined) {
-            el.setWidth(width);
-        }
-    },
+    
+    tplWriteMode: 'overwrite',
 
-    /**
-     * Returns the owner component's resize element.
-     * @return {Ext.core.Element}
-     */
-     getTarget : function() {
-         return this.owner.el;
-     },
+    
+    baseCls: Ext.baseCSSPrefix + 'component',
 
-    /**
-     * <p>Returns the element into which rendering must take place. Defaults to the owner Component's encapsulating element.</p>
-     * May be overridden in Component layout managers which implement an inner element.
-     * @return {Ext.core.Element}
-     */
-    getRenderTarget : function() {
-        return this.owner.el;
-    },
+    
 
-    /**
-    * Set the size of the target element.
-    * @param {Mixed} width The new width to set.
-    * @param {Mixed} height The new height to set.
-    */
-    setTargetSize : function(width, height) {
-        var me = this;
-        me.setElementSize(me.owner.el, width, height);
+    
 
-        if (me.owner.frameBody) {
-            var targetInfo = me.getTargetInfo(),
-                padding = targetInfo.padding,
-                border = targetInfo.border,
-                frameSize = me.frameSize;
+    
 
-            me.setElementSize(me.owner.frameBody,
-                Ext.isNumber(width) ? (width - frameSize.left - frameSize.right - padding.left - padding.right - border.left - border.right) : width,
-                Ext.isNumber(height) ? (height - frameSize.top - frameSize.bottom - padding.top - padding.bottom - border.top - border.bottom) : height
-            );
-        }
+    
+    disabledCls: Ext.baseCSSPrefix + 'item-disabled',
 
-        me.autoSized = {
-            width: !Ext.isNumber(width),
-            height: !Ext.isNumber(height)
-        };
+    
+    ui: 'default',
 
-        me.lastComponentSize = {
-            width: width,
-            height: height
-        };
-    },
+    
+    uiCls: [],
 
-    getTargetInfo : function() {
-        if (!this.targetInfo) {
-            var target = this.getTarget(),
-                body = this.owner.getTargetEl();
+    
 
-            this.targetInfo = {
-                padding: {
-                    top: target.getPadding('t'),
-                    right: target.getPadding('r'),
-                    bottom: target.getPadding('b'),
-                    left: target.getPadding('l')
-                },
-                border: {
-                    top: target.getBorderWidth('t'),
-                    right: target.getBorderWidth('r'),
-                    bottom: target.getBorderWidth('b'),
-                    left: target.getBorderWidth('l')
-                },
-                bodyMargin: {
-                    top: body.getMargin('t'),
-                    right: body.getMargin('r'),
-                    bottom: body.getMargin('b'),
-                    left: body.getMargin('l')
-                } 
-            };
-        }
-        return this.targetInfo;
-    },
+    
 
-    // Start laying out UP the ownerCt's layout when flagged to do so.
-    doOwnerCtLayouts: function() {
-        var owner = this.owner,
-            ownerCt = owner.ownerCt,
-            ownerCtComponentLayout, ownerCtContainerLayout;
+    
 
-        if (!ownerCt) {
-            return;
-        }
+    
 
-        ownerCtComponentLayout = ownerCt.componentLayout;
-        ownerCtContainerLayout = ownerCt.layout;
+    
 
-        if (!owner.floating && ownerCtComponentLayout && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) {
-            if (!ownerCt.suspendLayout && ownerCtContainerLayout && !ownerCtContainerLayout.layoutBusy) {
-                // AutoContainer Layout and Dock with auto in some dimension
-                if (ownerCtContainerLayout.bindToOwnerCtComponent === true) {
-                    ownerCt.doComponentLayout();
-                }
-                // Box Layouts
-                else if (ownerCtContainerLayout.bindToOwnerCtContainer === true) {
-                    ownerCtContainerLayout.layout();
-                }
-            }
-        }
-    },
+    
 
-    doContainerLayout: function() {
-        var me = this,
-            owner = me.owner,
-            ownerCt = owner.ownerCt,
-            layout = owner.layout,
-            ownerCtComponentLayout;
+    
+    hidden: false,
 
-        // Run the container layout if it exists (layout for child items)
-        // **Unless automatic laying out is suspended, or the layout is currently running**
-        if (!owner.suspendLayout && layout && layout.isLayout && !layout.layoutBusy) {
-            layout.layout();
-        }
+    
+    disabled: false,
 
-        // Tell the ownerCt that it's child has changed and can be re-layed by ignoring the lastComponentSize cache.
-        if (ownerCt && ownerCt.componentLayout) {
-            ownerCtComponentLayout = ownerCt.componentLayout;
-            if (!owner.floating && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) {
-                ownerCtComponentLayout.childrenChanged = true;
-            }
-        }
-    },
+    
 
-    afterLayout : function(width, height, isSetSize, layoutOwner) {
-        this.doContainerLayout();
-        this.owner.afterComponentLayout(width, height, isSetSize, layoutOwner);
-    }
-});
+    
+    draggable: false,
 
-/**
- * @class Ext.state.Manager
- * This is the global state manager. By default all components that are "state aware" check this class
- * for state information if you don't pass them a custom state provider. In order for this class
- * to be useful, it must be initialized with a provider when your application initializes. Example usage:
- <pre><code>
-// in your initialization function
-init : function(){
-   Ext.state.Manager.setProvider(new Ext.state.CookieProvider());
-   var win = new Window(...);
-   win.restoreState();
-}
- </code></pre>
- * This class passes on calls from components to the underlying {@link Ext.state.Provider} so that
- * there is a common interface that can be used without needing to refer to a specific provider instance
- * in every component.
- * @singleton
- * @docauthor Evan Trimboli <evan@sencha.com>
- */
-Ext.define('Ext.state.Manager', {
-    singleton: true,
-    requires: ['Ext.state.Provider'],
-    constructor: function() {
-        this.provider = Ext.create('Ext.state.Provider');
-    },
     
+    floating: false,
+
     
-    /**
-     * Configures the default state provider for your application
-     * @param {Provider} stateProvider The state provider to set
-     */
-    setProvider : function(stateProvider){
-        this.provider = stateProvider;
-    },
+    hideMode: 'display',
 
-    /**
-     * Returns the current value for a key
-     * @param {String} name The key name
-     * @param {Mixed} defaultValue The default value to return if the key lookup does not match
-     * @return {Mixed} The state data
-     */
-    get : function(key, defaultValue){
-        return this.provider.get(key, defaultValue);
-    },
+    
 
-    /**
-     * Sets the value for a key
-     * @param {String} name The key name
-     * @param {Mixed} value The state data
-     */
-     set : function(key, value){
-        this.provider.set(key, value);
-    },
+    
 
-    /**
-     * Clears a value from the state
-     * @param {String} name The key name
-     */
-    clear : function(key){
-        this.provider.clear(key);
-    },
+    
+    styleHtmlContent: false,
 
-    /**
-     * Gets the currently configured state provider
-     * @return {Provider} The state provider
-     */
-    getProvider : function(){
-        return this.provider;
-    }
-});
-/**
- * @class Ext.state.Stateful
- * A mixin for being able to save the state of an object to an underlying 
- * {@link Ext.state.Provider}.
- */
-Ext.define('Ext.state.Stateful', {
     
-    /* Begin Definitions */
-   
-   mixins: {
-        observable: 'Ext.util.Observable'
-    },
+    styleHtmlCls: Ext.baseCSSPrefix + 'html',
+
     
-    requires: ['Ext.state.Manager'],
     
-    /* End Definitions */
     
-    /**
-     * @cfg {Boolean} stateful
-     * <p>A flag which causes the object to attempt to restore the state of
-     * internal properties from a saved state on startup. The object must have
-     * a <code>{@link #stateId}</code> for state to be managed. 
-     * Auto-generated ids are not guaranteed to be stable across page loads and 
-     * cannot be relied upon to save and restore the same state for a object.<p>
-     * <p>For state saving to work, the state manager's provider must have been
-     * set to an implementation of {@link Ext.state.Provider} which overrides the
-     * {@link Ext.state.Provider#set set} and {@link Ext.state.Provider#get get}
-     * methods to save and recall name/value pairs. A built-in implementation,
-     * {@link Ext.state.CookieProvider} is available.</p>
-     * <p>To set the state provider for the current page:</p>
-     * <pre><code>
-Ext.state.Manager.setProvider(new Ext.state.CookieProvider({
-    expires: new Date(new Date().getTime()+(1000*60*60*24*7)), //7 days from now
-}));
-     * </code></pre>
-     * <p>A stateful object attempts to save state when one of the events
-     * listed in the <code>{@link #stateEvents}</code> configuration fires.</p>
-     * <p>To save state, a stateful object first serializes its state by
-     * calling <b><code>{@link #getState}</code></b>. By default, this function does
-     * nothing. The developer must provide an implementation which returns an
-     * object hash which represents the restorable state of the object.</p>
-     * <p>The value yielded by getState is passed to {@link Ext.state.Manager#set}
-     * which uses the configured {@link Ext.state.Provider} to save the object
-     * keyed by the <code>{@link stateId}</code></p>.
-     * <p>During construction, a stateful object attempts to <i>restore</i>
-     * its state by calling {@link Ext.state.Manager#get} passing the
-     * <code>{@link #stateId}</code></p>
-     * <p>The resulting object is passed to <b><code>{@link #applyState}</code></b>.
-     * The default implementation of <code>{@link #applyState}</code> simply copies
-     * properties into the object, but a developer may override this to support
-     * more behaviour.</p>
-     * <p>You can perform extra processing on state save and restore by attaching
-     * handlers to the {@link #beforestaterestore}, {@link #staterestore},
-     * {@link #beforestatesave} and {@link #statesave} events.</p>
-     */
-    stateful: true,
     
-    /**
-     * @cfg {String} stateId
-     * The unique id for this object to use for state management purposes.
-     * <p>See {@link #stateful} for an explanation of saving and restoring state.</p>
-     */
+
     
-    /**
-     * @cfg {Array} stateEvents
-     * <p>An array of events that, when fired, should trigger this object to
-     * save its state (defaults to none). <code>stateEvents</code> may be any type
-     * of event supported by this object, including browser or custom events
-     * (e.g., <tt>['click', 'customerchange']</tt>).</p>
-     * <p>See <code>{@link #stateful}</code> for an explanation of saving and
-     * restoring object state.</p>
-     */
+
     
-    /**
-     * @cfg {Number} saveBuffer A buffer to be applied if many state events are fired within
-     * a short period. Defaults to 100.
-     */
-    saveDelay: 100,
+    autoShow: false,
+
     
-    autoGenIdRe: /^((\w+-)|(ext-comp-))\d{4,}$/i,
+    autoRender: false,
+
+    needsLayout: false,
+
     
-    constructor: function(config) {
-        var me = this;
-        
+    allowDomMove: true,
+
+    
+
+    
+    rendered: false,
+
+    
+    componentLayoutCounter: 0,
+
+    weight: 0,
+
+    trimRe: /^\s+|\s+$/g,
+    spacesRe: /\s+/,
+
+
+    
+    maskOnDisable: true,
+
+    
+    constructor : function(config) {
+        var me = this,
+            i, len;
+
         config = config || {};
-        if (Ext.isDefined(config.stateful)) {
-            me.stateful = config.stateful;
-        }
-        if (Ext.isDefined(config.saveDelay)) {
-            me.saveDelay = config.saveDelay;
+        me.initialConfig = config;
+        Ext.apply(me, config);
+
+        me.addEvents(
+            
+            'beforeactivate',
+            
+            'activate',
+            
+            'beforedeactivate',
+            
+            'deactivate',
+            
+            'added',
+            
+            'disable',
+            
+            'enable',
+            
+            'beforeshow',
+            
+            'show',
+            
+            'beforehide',
+            
+            'hide',
+            
+            'removed',
+            
+            'beforerender',
+            
+            'render',
+            
+            'afterrender',
+            
+            'beforedestroy',
+            
+            'destroy',
+            
+            'resize',
+            
+            'move'
+        );
+
+        me.getId();
+
+        me.mons = [];
+        me.additionalCls = [];
+        me.renderData = me.renderData || {};
+        me.renderSelectors = me.renderSelectors || {};
+
+        if (me.plugins) {
+            me.plugins = [].concat(me.plugins);
+            me.constructPlugins();
         }
-        me.stateId = config.stateId;
+
+        me.initComponent();
+
         
-        if (!me.stateEvents) {
-            me.stateEvents = [];
-        }
-        if (config.stateEvents) {
-            me.stateEvents.concat(config.stateEvents);
+        Ext.ComponentManager.register(me);
+
+        
+        me.mixins.observable.constructor.call(me);
+        me.mixins.state.constructor.call(me, config);
+
+        
+        this.addStateEvents('resize');
+
+        
+        if (me.plugins) {
+            me.plugins = [].concat(me.plugins);
+            for (i = 0, len = me.plugins.length; i < len; i++) {
+                me.plugins[i] = me.initPlugin(me.plugins[i]);
+            }
         }
-        this.addEvents(
-            /**
-             * @event beforestaterestore
-             * Fires before the state of the object is restored. Return false from an event handler to stop the restore.
-             * @param {Ext.state.Stateful} this
-             * @param {Object} state The hash of state values returned from the StateProvider. If this
-             * event is not vetoed, then the state object is passed to <b><tt>applyState</tt></b>. By default,
-             * that simply copies property values into this object. The method maybe overriden to
-             * provide custom state restoration.
-             */
-            'beforestaterestore',
+
+        me.loader = me.getLoader();
+
+        if (me.renderTo) {
+            me.render(me.renderTo);
             
-            /**
-             * @event staterestore
-             * Fires after the state of the object is restored.
-             * @param {Ext.state.Stateful} this
-             * @param {Object} state The hash of state values returned from the StateProvider. This is passed
-             * to <b><tt>applyState</tt></b>. By default, that simply copies property values into this
-             * object. The method maybe overriden to provide custom state restoration.
-             */
-            'staterestore',
             
-            /**
-             * @event beforestatesave
-             * Fires before the state of the object is saved to the configured state provider. Return false to stop the save.
-             * @param {Ext.state.Stateful} this
-             * @param {Object} state The hash of state values. This is determined by calling
-             * <b><tt>getState()</tt></b> on the object. This method must be provided by the
-             * developer to return whetever representation of state is required, by default, Ext.state.Stateful
-             * has a null implementation.
-             */
-            'beforestatesave',
             
-            /**
-             * @event statesave
-             * Fires after the state of the object is saved to the configured state provider.
-             * @param {Ext.state.Stateful} this
-             * @param {Object} state The hash of state values. This is determined by calling
-             * <b><tt>getState()</tt></b> on the object. This method must be provided by the
-             * developer to return whetever representation of state is required, by default, Ext.state.Stateful
-             * has a null implementation.
-             */
-            'statesave'
-        );
-        me.mixins.observable.constructor.call(me);
-        if (me.stateful !== false) {
-            me.initStateEvents();
-            me.initState();
         }
-    },
-    
-    /**
-     * Initializes any state events for this object.
-     * @private
-     */
-    initStateEvents: function() {
-        this.addStateEvents(this.stateEvents);
-    },
-    
-    /**
-     * Add events that will trigger the state to be saved.
-     * @param {String/Array} events The event name or an array of event names.
-     */
-    addStateEvents: function(events){
-        if (!Ext.isArray(events)) {
-            events = [events];
+
+        if (me.autoShow) {
+            me.show();
         }
+
+    },
+
+    initComponent: function () {
         
-        var me = this,
-            i = 0,
-            len = events.length;
-            
-        for (; i < len; ++i) {
-            me.on(events[i], me.onStateChange, me);
-        }
+        
+        this.constructPlugins();
     },
+
     
-    /**
-     * This method is called when any of the {@link #stateEvents} are fired.
-     * @private
-     */
-    onStateChange: function(){
+    getState: function() {
         var me = this,
-            delay = me.saveDelay;
+            layout = me.ownerCt ? (me.shadowOwnerCt || me.ownerCt).getLayout() : null,
+            state = {
+                collapsed: me.collapsed
+            },
+            width = me.width,
+            height = me.height,
+            cm = me.collapseMemento,
+            anchors;
+
         
-        if (delay > 0) {
-            if (!me.stateTask) {
-                me.stateTask = Ext.create('Ext.util.DelayedTask', me.saveState, me);
+        
+        if (me.collapsed && cm) {
+            if (Ext.isDefined(cm.data.width)) {
+                width = cm.width;
+            }
+            if (Ext.isDefined(cm.data.height)) {
+                height = cm.height;
             }
-            me.stateTask.delay(me.saveDelay);
-        } else {
-            me.saveState();
         }
-    },
-    
-    /**
-     * Saves the state of the object to the persistence store.
-     * @private
-     */
-    saveState: function() {
-        var me = this,
-            id,
-            state;
+
         
-        if (me.stateful !== false) {
-            id = me.getStateId();
-            if (id) {
-                state = me.getState();
-                if (me.fireEvent('beforestatesave', me, state) !== false) {
-                    Ext.state.Manager.set(id, state);
-                    me.fireEvent('statesave', me, state);
-                }
+        if (layout && me.flex) {
+            state.flex = me.flex;
+            if (layout.perpendicularPrefix) {
+                state[layout.perpendicularPrefix] = me['get' + layout.perpendicularPrefixCap]();
+            } else {
             }
         }
-    },
-    
-    /**
-     * Gets the current state of the object. By default this function returns null,
-     * it should be overridden in subclasses to implement methods for getting the state.
-     * @return {Object} The current state
-     */
-    getState: function(){
-        return null;    
-    },
-    
-    /**
-     * Applies the state to the object. This should be overridden in subclasses to do
-     * more complex state operations. By default it applies the state properties onto
-     * the current object.
-     * @param {Object} state The state
-     */
-    applyState: function(state) {
-        if (state) {
-            Ext.apply(this, state);
-        }
-    },
-    
-    /**
-     * Gets the state id for this object.
-     * @return {String} The state id, null if not found.
-     */
-    getStateId: function() {
-        var me = this,
-            id = me.stateId;
         
-        if (!id) {
-            id = me.autoGenIdRe.test(String(me.id)) ? null : me.id;
-        }
-        return id;
-    },
-    
-    /**
-     * Initializes the state of the object upon construction.
-     * @private
-     */
-    initState: function(){
-        var me = this,
-            id = me.getStateId(),
-            state;
-            
-        if (me.stateful !== false) {
-            if (id) {
-                state = Ext.state.Manager.get(id);
-                if (state) {
-                    state = Ext.apply({}, state);
-                    if (me.fireEvent('beforestaterestore', me, state) !== false) {
-                        me.applyState(state);
-                        me.fireEvent('staterestore', me, state);
-                    }
+        else if (layout && me.anchor) {
+            state.anchor = me.anchor;
+            anchors = me.anchor.split(' ').concat(null);
+            if (!anchors[0]) {
+                if (me.width) {
+                    state.width = width;
+                }
+            }
+            if (!anchors[1]) {
+                if (me.height) {
+                    state.height = height;
                 }
             }
         }
-    },
-    
-    /**
-     * Destroys this stateful object.
-     */
-    destroy: function(){
-        var task = this.stateTask;
-        if (task) {
-            task.cancel();
-        }
-        this.clearListeners();
         
-    }
-    
-});
-
-/**
- * @class Ext.AbstractManager
- * @extends Object
- * @ignore
- * Base Manager class
- */
+        else {
+            if (me.width) {
+                state.width = width;
+            }
+            if (me.height) {
+                state.height = height;
+            }
+        }
 
-Ext.define('Ext.AbstractManager', {
+        
+        if (state.width == me.initialConfig.width) {
+            delete state.width;
+        }
+        if (state.height == me.initialConfig.height) {
+            delete state.height;
+        }
 
-    /* Begin Definitions */
+        
+        if (layout && layout.align && (layout.align.indexOf('stretch') !== -1)) {
+            delete state[layout.perpendicularPrefix];
+        }
+        return state;
+    },
 
-    requires: ['Ext.util.HashMap'],
+    show: Ext.emptyFn,
 
-    /* End Definitions */
+    animate: function(animObj) {
+        var me = this,
+            to;
 
-    typeName: 'type',
+        animObj = animObj || {};
+        to = animObj.to || {};
 
-    constructor: function(config) {
-        Ext.apply(this, config || {});
+        if (Ext.fx.Manager.hasFxBlock(me.id)) {
+            return me;
+        }
+        
+        if (!animObj.dynamic && (to.height || to.width)) {
+            var curWidth = me.getWidth(),
+                w = curWidth,
+                curHeight = me.getHeight(),
+                h = curHeight,
+                needsResize = false;
 
-        /**
-         * Contains all of the items currently managed
-         * @property all
-         * @type Ext.util.MixedCollection
-         */
-        this.all = Ext.create('Ext.util.HashMap');
+            if (to.height && to.height > curHeight) {
+                h = to.height;
+                needsResize = true;
+            }
+            if (to.width && to.width > curWidth) {
+                w = to.width;
+                needsResize = true;
+            }
 
-        this.types = {};
-    },
+            
+            
+            
+            if (needsResize) {
+                var clearWidth = !Ext.isNumber(me.width),
+                    clearHeight = !Ext.isNumber(me.height);
 
-    /**
-     * Returns an item by id.
-     * For additional details see {@link Ext.util.HashMap#get}.
-     * @param {String} id The id of the item
-     * @return {Mixed} The item, <code>undefined</code> if not found.
-     */
-    get : function(id) {
-        return this.all.get(id);
-    },
-
-    /**
-     * Registers an item to be managed
-     * @param {Mixed} item The item to register
-     */
-    register: function(item) {
-        this.all.add(item);
-    },
-
-    /**
-     * Unregisters an item by removing it from this manager
-     * @param {Mixed} item The item to unregister
-     */
-    unregister: function(item) {
-        this.all.remove(item);
-    },
-
-    /**
-     * <p>Registers a new item constructor, keyed by a type key.
-     * @param {String} type The mnemonic string by which the class may be looked up.
-     * @param {Constructor} cls The new instance class.
-     */
-    registerType : function(type, cls) {
-        this.types[type] = cls;
-        cls[this.typeName] = type;
+                me.componentLayout.childrenChanged = true;
+                me.setSize(w, h, me.ownerCt);
+                me.el.setSize(curWidth, curHeight);
+                if (clearWidth) {
+                    delete me.width;
+                }
+                if (clearHeight) {
+                    delete me.height;
+                }
+            }
+        }
+        return me.mixins.animate.animate.apply(me, arguments);
     },
 
-    /**
-     * Checks if an item type is registered.
-     * @param {String} type The mnemonic string by which the class may be looked up
-     * @return {Boolean} Whether the type is registered.
-     */
-    isRegistered : function(type){
-        return this.types[type] !== undefined;
+    
+    findLayoutController: function() {
+        return this.findParentBy(function(c) {
+            
+            
+            return !c.ownerCt || (c.layout.layoutBusy && !c.ownerCt.layout.layoutBusy);
+        });
     },
 
-    /**
-     * Creates and returns an instance of whatever this manager manages, based on the supplied type and config object
-     * @param {Object} config The config object
-     * @param {String} defaultType If no type is discovered in the config object, we fall back to this type
-     * @return {Mixed} The instance of whatever this manager is managing
-     */
-    create: function(config, defaultType) {
-        var type        = config[this.typeName] || config.type || defaultType,
-            Constructor = this.types[type];
-
-        if (Constructor == undefined) {
-            Ext.Error.raise("The '" + type + "' type has not been registered with this manager");
+    onShow : function() {
+        
+        var needsLayout = this.needsLayout;
+        if (Ext.isObject(needsLayout)) {
+            this.doComponentLayout(needsLayout.width, needsLayout.height, needsLayout.isSetSize, needsLayout.ownerCt);
         }
-
-        return new Constructor(config);
     },
 
-    /**
-     * Registers a function that will be called when an item with the specified id is added to the manager. This will happen on instantiation.
-     * @param {String} id The item id
-     * @param {Function} fn The callback function. Called with a single parameter, the item.
-     * @param {Object} scope The scope (<code>this</code> reference) in which the callback is executed. Defaults to the item.
-     */
-    onAvailable : function(id, fn, scope){
-        var all = this.all,
-            item;
-        
-        if (all.containsKey(id)) {
-            item = all.get(id);
-            fn.call(scope || item, item);
-        } else {
-            all.on('add', function(map, key, item){
-                if (key == id) {
-                    fn.call(scope || item, item);
-                    all.un('add', fn, scope);
-                }
+    constructPlugin: function(plugin) {
+        if (plugin.ptype && typeof plugin.init != 'function') {
+            plugin.cmp = this;
+            plugin = Ext.PluginManager.create(plugin);
+        }
+        else if (typeof plugin == 'string') {
+            plugin = Ext.PluginManager.create({
+                ptype: plugin,
+                cmp: this
             });
         }
+        return plugin;
     },
+
     
-    /**
-     * Executes the specified function once for each item in the collection.
-     * Returning false from the function will cease iteration.
-     * 
-     * The paramaters passed to the function are:
-     * <div class="mdetail-params"><ul>
-     * <li><b>key</b> : String<p class="sub-desc">The key of the item</p></li>
-     * <li><b>value</b> : Number<p class="sub-desc">The value of the item</p></li>
-     * <li><b>length</b> : Number<p class="sub-desc">The total number of items in the collection</p></li>
-     * </ul></div>
-     * @param {Object} fn The function to execute.
-     * @param {Object} scope The scope to execute in. Defaults to <tt>this</tt>.
-     */
-    each: function(fn, scope){
-        this.all.each(fn, scope || this);    
+    constructPlugins: function() {
+        var me = this,
+            plugins = me.plugins,
+            i, len;
+
+        if (plugins) {
+            for (i = 0, len = plugins.length; i < len; i++) {
+                
+                plugins[i] = me.constructPlugin(plugins[i]);
+            }
+        }
     },
-    
-    /**
-     * Gets the number of items in the collection.
-     * @return {Number} The number of items in the collection.
-     */
-    getCount: function(){
-        return this.all.getCount();
-    }
-});
 
-/**
- * @class Ext.PluginManager
- * @extends Ext.AbstractManager
- * <p>Provides a registry of available Plugin <i>classes</i> indexed by a mnemonic code known as the Plugin's ptype.
- * The <code>{@link Ext.Component#xtype xtype}</code> provides a way to avoid instantiating child Components
- * when creating a full, nested config object for a complete Ext page.</p>
- * <p>A child Component may be specified simply as a <i>config object</i>
- * as long as the correct <code>{@link Ext.Component#xtype xtype}</code> is specified so that if and when the Component
- * needs rendering, the correct type can be looked up for lazy instantiation.</p>
- * <p>For a list of all available <code>{@link Ext.Component#xtype xtypes}</code>, see {@link Ext.Component}.</p>
- * @singleton
- */
-Ext.define('Ext.PluginManager', {
-    extend: 'Ext.AbstractManager',
-    alternateClassName: 'Ext.PluginMgr',
-    singleton: true,
-    typeName: 'ptype',
+    
+    initPlugin : function(plugin) {
+        plugin.init(this);
 
-    /**
-     * Creates a new Plugin from the specified config object using the
-     * config object's ptype to determine the class to instantiate.
-     * @param {Object} config A configuration object for the Plugin you wish to create.
-     * @param {Constructor} defaultType The constructor to provide the default Plugin type if
-     * the config object does not contain a <code>ptype</code>. (Optional if the config contains a <code>ptype</code>).
-     * @return {Ext.Component} The newly instantiated Plugin.
-     */
-    //create: function(plugin, defaultType) {
-    //    if (plugin instanceof this) {
-    //        return plugin;
-    //    } else {
-    //        var type, config = {};
-    //
-    //        if (Ext.isString(plugin)) {
-    //            type = plugin;
-    //        }
-    //        else {
-    //            type = plugin[this.typeName] || defaultType;
-    //            config = plugin;
-    //        }
-    //
-    //        return Ext.createByAlias('plugin.' + type, config);
-    //    }
-    //},
+        return plugin;
+    },
 
-    create : function(config, defaultType){
-        if (config.init) {
-            return config;
+    
+    doAutoRender: function() {
+        var me = this;
+        if (me.floating) {
+            me.render(document.body);
         } else {
-            return Ext.createByAlias('plugin.' + (config.ptype || defaultType), config);
+            me.render(Ext.isBoolean(me.autoRender) ? Ext.getBody() : me.autoRender);
         }
-        
-        // Prior system supported Singleton plugins.
-        //var PluginCls = this.types[config.ptype || defaultType];
-        //if (PluginCls.init) {
-        //    return PluginCls;
-        //} else {
-        //    return new PluginCls(config);
-        //}
     },
 
-    /**
-     * Returns all plugins registered with the given type. Here, 'type' refers to the type of plugin, not its ptype.
-     * @param {String} type The type to search for
-     * @param {Boolean} defaultsOnly True to only return plugins of this type where the plugin's isDefault property is truthy
-     * @return {Array} All matching plugins
-     */
-    findByType: function(type, defaultsOnly) {
-        var matches = [],
-            types   = this.types;
-
-        for (var name in types) {
-            if (!types.hasOwnProperty(name)) {
-                continue;
-            }
-            var item = types[name];
-
-            if (item.type == type && (!defaultsOnly || (defaultsOnly === true && item.isDefault))) {
-                matches.push(item);
-            }
-        }
+    
+    render : function(container, position) {
+        var me = this;
 
-        return matches;
-    }
-}, function() {    
-    /**
-     * Shorthand for {@link Ext.PluginManager#registerType}
-     * @param {String} ptype The ptype mnemonic string by which the Plugin class
-     * may be looked up.
-     * @param {Constructor} cls The new Plugin class.
-     * @member Ext
-     * @method preg
-     */
-    Ext.preg = function() {
-        return Ext.PluginManager.registerType.apply(Ext.PluginManager, arguments);
-    };
-});
+        if (!me.rendered && me.fireEvent('beforerender', me) !== false) {
 
-/**
- * @class Ext.ComponentManager
- * @extends Ext.AbstractManager
- * <p>Provides a registry of all Components (instances of {@link Ext.Component} or any subclass
- * thereof) on a page so that they can be easily accessed by {@link Ext.Component component}
- * {@link Ext.Component#id id} (see {@link #get}, or the convenience method {@link Ext#getCmp Ext.getCmp}).</p>
- * <p>This object also provides a registry of available Component <i>classes</i>
- * indexed by a mnemonic code known as the Component's {@link Ext.Component#xtype xtype}.
- * The <code>xtype</code> provides a way to avoid instantiating child Components
- * when creating a full, nested config object for a complete Ext page.</p>
- * <p>A child Component may be specified simply as a <i>config object</i>
- * as long as the correct <code>{@link Ext.Component#xtype xtype}</code> is specified so that if and when the Component
- * needs rendering, the correct type can be looked up for lazy instantiation.</p>
- * <p>For a list of all available <code>{@link Ext.Component#xtype xtypes}</code>, see {@link Ext.Component}.</p>
- * @singleton
- */
-Ext.define('Ext.ComponentManager', {
-    extend: 'Ext.AbstractManager',
-    alternateClassName: 'Ext.ComponentMgr',
-    
-    singleton: true,
-    
-    typeName: 'xtype',
-    
-    /**
-     * Creates a new Component from the specified config object using the
-     * config object's xtype to determine the class to instantiate.
-     * @param {Object} config A configuration object for the Component you wish to create.
-     * @param {Constructor} defaultType The constructor to provide the default Component type if
-     * the config object does not contain a <code>xtype</code>. (Optional if the config contains a <code>xtype</code>).
-     * @return {Ext.Component} The newly instantiated Component.
-     */
-    create: function(component, defaultType){
-        if (component instanceof Ext.AbstractComponent) {
-            return component;
-        }
-        else if (Ext.isString(component)) {
-            return Ext.createByAlias('widget.' + component);
-        }
-        else {
-            var type = component.xtype || defaultType,
-                config = component;
             
-            return Ext.createByAlias('widget.' + type, config);
-        }
-    },
-
-    registerType: function(type, cls) {
-        this.types[type] = cls;
-        cls[this.typeName] = type;
-        cls.prototype[this.typeName] = type;
-    }
-});
-/**
- * @class Ext.XTemplate
- * @extends Ext.Template
- * <p>A template class that supports advanced functionality like:<div class="mdetail-params"><ul>
- * <li>Autofilling arrays using templates and sub-templates</li>
- * <li>Conditional processing with basic comparison operators</li>
- * <li>Basic math function support</li>
- * <li>Execute arbitrary inline code with special built-in template variables</li>
- * <li>Custom member functions</li>
- * <li>Many special tags and built-in operators that aren't defined as part of
- * the API, but are supported in the templates that can be created</li>
- * </ul></div></p>
- * <p>XTemplate provides the templating mechanism built into:<div class="mdetail-params"><ul>
- * <li>{@link Ext.view.View}</li>
- * </ul></div></p>
- *
- * The {@link Ext.Template} describes
- * the acceptable parameters to pass to the constructor. The following
- * examples demonstrate all of the supported features.</p>
- *
- * <div class="mdetail-params"><ul>
- *
- * <li><b><u>Sample Data</u></b>
- * <div class="sub-desc">
- * <p>This is the data object used for reference in each code example:</p>
- * <pre><code>
-var data = {
-name: 'Tommy Maintz',
-title: 'Lead Developer',
-company: 'Sencha Inc.',
-email: 'tommy@sencha.com',
-address: '5 Cups Drive',
-city: 'Palo Alto',
-state: 'CA',
-zip: '44102',
-drinks: ['Coffee', 'Soda', 'Water'],
-kids: [{
-        name: 'Joshua',
-        age:3
-    },{
-        name: 'Matthew',
-        age:2
-    },{
-        name: 'Solomon',
-        age:0
-}]
-};
- </code></pre>
- * </div>
- * </li>
- *
- *
- * <li><b><u>Auto filling of arrays</u></b>
- * <div class="sub-desc">
- * <p>The <b><tt>tpl</tt></b> tag and the <b><tt>for</tt></b> operator are used
- * to process the provided data object:
- * <ul>
- * <li>If the value specified in <tt>for</tt> is an array, it will auto-fill,
- * repeating the template block inside the <tt>tpl</tt> tag for each item in the
- * array.</li>
- * <li>If <tt>for="."</tt> is specified, the data object provided is examined.</li>
- * <li>While processing an array, the special variable <tt>{#}</tt>
- * will provide the current array index + 1 (starts at 1, not 0).</li>
- * </ul>
- * </p>
- * <pre><code>
-&lt;tpl <b>for</b>=".">...&lt;/tpl>       // loop through array at root node
-&lt;tpl <b>for</b>="foo">...&lt;/tpl>     // loop through array at foo node
-&lt;tpl <b>for</b>="foo.bar">...&lt;/tpl> // loop through array at foo.bar node
- </code></pre>
- * Using the sample data above:
- * <pre><code>
-var tpl = new Ext.XTemplate(
-    '&lt;p>Kids: ',
-    '&lt;tpl <b>for</b>=".">',       // process the data.kids node
-        '&lt;p>{#}. {name}&lt;/p>',  // use current array index to autonumber
-    '&lt;/tpl>&lt;/p>'
-);
-tpl.overwrite(panel.body, data.kids); // pass the kids property of the data object
- </code></pre>
- * <p>An example illustrating how the <b><tt>for</tt></b> property can be leveraged
- * to access specified members of the provided data object to populate the template:</p>
- * <pre><code>
-var tpl = new Ext.XTemplate(
-    '&lt;p>Name: {name}&lt;/p>',
-    '&lt;p>Title: {title}&lt;/p>',
-    '&lt;p>Company: {company}&lt;/p>',
-    '&lt;p>Kids: ',
-    '&lt;tpl <b>for="kids"</b>>',     // interrogate the kids property within the data
-        '&lt;p>{name}&lt;/p>',
-    '&lt;/tpl>&lt;/p>'
-);
-tpl.overwrite(panel.body, data);  // pass the root node of the data object
- </code></pre>
- * <p>Flat arrays that contain values (and not objects) can be auto-rendered
- * using the special <b><tt>{.}</tt></b> variable inside a loop.  This variable
- * will represent the value of the array at the current index:</p>
- * <pre><code>
-var tpl = new Ext.XTemplate(
-    '&lt;p>{name}\&#39;s favorite beverages:&lt;/p>',
-    '&lt;tpl for="drinks">',
-        '&lt;div> - {.}&lt;/div>',
-    '&lt;/tpl>'
-);
-tpl.overwrite(panel.body, data);
- </code></pre>
- * <p>When processing a sub-template, for example while looping through a child array,
- * you can access the parent object's members via the <b><tt>parent</tt></b> object:</p>
- * <pre><code>
-var tpl = new Ext.XTemplate(
-    '&lt;p>Name: {name}&lt;/p>',
-    '&lt;p>Kids: ',
-    '&lt;tpl for="kids">',
-        '&lt;tpl if="age &amp;gt; 1">',
-            '&lt;p>{name}&lt;/p>',
-            '&lt;p>Dad: {<b>parent</b>.name}&lt;/p>',
-        '&lt;/tpl>',
-    '&lt;/tpl>&lt;/p>'
-);
-tpl.overwrite(panel.body, data);
- </code></pre>
- * </div>
- * </li>
- *
- *
- * <li><b><u>Conditional processing with basic comparison operators</u></b>
- * <div class="sub-desc">
- * <p>The <b><tt>tpl</tt></b> tag and the <b><tt>if</tt></b> operator are used
- * to provide conditional checks for deciding whether or not to render specific
- * parts of the template. Notes:<div class="sub-desc"><ul>
- * <li>Double quotes must be encoded if used within the conditional</li>
- * <li>There is no <tt>else</tt> operator &mdash; if needed, two opposite
- * <tt>if</tt> statements should be used.</li>
- * </ul></div>
- * <pre><code>
-&lt;tpl if="age &gt; 1 &amp;&amp; age &lt; 10">Child&lt;/tpl>
-&lt;tpl if="age >= 10 && age < 18">Teenager&lt;/tpl>
-&lt;tpl <b>if</b>="this.isGirl(name)">...&lt;/tpl>
-&lt;tpl <b>if</b>="id==\'download\'">...&lt;/tpl>
-&lt;tpl <b>if</b>="needsIcon">&lt;img src="{icon}" class="{iconCls}"/>&lt;/tpl>
-// no good:
-&lt;tpl if="name == "Tommy"">Hello&lt;/tpl>
-// encode &#34; if it is part of the condition, e.g.
-&lt;tpl if="name == &#38;quot;Tommy&#38;quot;">Hello&lt;/tpl>
- * </code></pre>
- * Using the sample data above:
- * <pre><code>
-var tpl = new Ext.XTemplate(
-    '&lt;p>Name: {name}&lt;/p>',
-    '&lt;p>Kids: ',
-    '&lt;tpl for="kids">',
-        '&lt;tpl if="age &amp;gt; 1">',
-            '&lt;p>{name}&lt;/p>',
-        '&lt;/tpl>',
-    '&lt;/tpl>&lt;/p>'
-);
-tpl.overwrite(panel.body, data);
- </code></pre>
- * </div>
- * </li>
- *
- *
- * <li><b><u>Basic math support</u></b>
- * <div class="sub-desc">
- * <p>The following basic math operators may be applied directly on numeric
- * data values:</p><pre>
- * + - * /
- * </pre>
- * For example:
- * <pre><code>
-var tpl = new Ext.XTemplate(
-    '&lt;p>Name: {name}&lt;/p>',
-    '&lt;p>Kids: ',
-    '&lt;tpl for="kids">',
-        '&lt;tpl if="age &amp;gt; 1">',  // <-- Note that the &gt; is encoded
-            '&lt;p>{#}: {name}&lt;/p>',  // <-- Auto-number each item
-            '&lt;p>In 5 Years: {age+5}&lt;/p>',  // <-- Basic math
-            '&lt;p>Dad: {parent.name}&lt;/p>',
-        '&lt;/tpl>',
-    '&lt;/tpl>&lt;/p>'
-);
-tpl.overwrite(panel.body, data);
- </code></pre>
- * </div>
- * </li>
- *
- *
- * <li><b><u>Execute arbitrary inline code with special built-in template variables</u></b>
- * <div class="sub-desc">
- * <p>Anything between <code>{[ ... ]}</code> is considered code to be executed
- * in the scope of the template. There are some special variables available in that code:
- * <ul>
- * <li><b><tt>values</tt></b>: The values in the current scope. If you are using
- * scope changing sub-templates, you can change what <tt>values</tt> is.</li>
- * <li><b><tt>parent</tt></b>: The scope (values) of the ancestor template.</li>
- * <li><b><tt>xindex</tt></b>: If you are in a looping template, the index of the
- * loop you are in (1-based).</li>
- * <li><b><tt>xcount</tt></b>: If you are in a looping template, the total length
- * of the array you are looping.</li>
- * </ul>
- * This example demonstrates basic row striping using an inline code block and the
- * <tt>xindex</tt> variable:</p>
- * <pre><code>
-var tpl = new Ext.XTemplate(
-    '&lt;p>Name: {name}&lt;/p>',
-    '&lt;p>Company: {[values.company.toUpperCase() + ", " + values.title]}&lt;/p>',
-    '&lt;p>Kids: ',
-    '&lt;tpl for="kids">',
-        '&lt;div class="{[xindex % 2 === 0 ? "even" : "odd"]}">',
-        '{name}',
-        '&lt;/div>',
-    '&lt;/tpl>&lt;/p>'
- );
-tpl.overwrite(panel.body, data);
- </code></pre>
- * </div>
- * </li>
- *
- * <li><b><u>Template member functions</u></b>
- * <div class="sub-desc">
- * <p>One or more member functions can be specified in a configuration
- * object passed into the XTemplate constructor for more complex processing:</p>
- * <pre><code>
-var tpl = new Ext.XTemplate(
-    '&lt;p>Name: {name}&lt;/p>',
-    '&lt;p>Kids: ',
-    '&lt;tpl for="kids">',
-        '&lt;tpl if="this.isGirl(name)">',
-            '&lt;p>Girl: {name} - {age}&lt;/p>',
-        '&lt;/tpl>',
-         // use opposite if statement to simulate 'else' processing:
-        '&lt;tpl if="this.isGirl(name) == false">',
-            '&lt;p>Boy: {name} - {age}&lt;/p>',
-        '&lt;/tpl>',
-        '&lt;tpl if="this.isBaby(age)">',
-            '&lt;p>{name} is a baby!&lt;/p>',
-        '&lt;/tpl>',
-    '&lt;/tpl>&lt;/p>',
-    {
-        // XTemplate configuration:
-        compiled: true,
-        // member functions:
-        isGirl: function(name){
-           return name == 'Sara Grace';
-        },
-        isBaby: function(age){
-           return age < 1;
-        }
-    }
-);
-tpl.overwrite(panel.body, data);
- </code></pre>
- * </div>
- * </li>
- *
- * </ul></div>
- *
- * @param {Mixed} config
- */
+            
+            me.rendering = true;
 
-Ext.define('Ext.XTemplate', {
+            
+            
+            if (me.el) {
+                me.el = Ext.get(me.el);
+            }
 
-    /* Begin Definitions */
+            
+            if (me.floating) {
+                me.onFloatRender();
+            }
 
-    extend: 'Ext.Template',
+            container = me.initContainer(container);
 
-    statics: {
-        /**
-         * Creates a template from the passed element's value (<i>display:none</i> textarea, preferred) or innerHTML.
-         * @param {String/HTMLElement} el A DOM element or its id
-         * @return {Ext.Template} The created template
-         * @static
-         */
-        from: function(el, config) {
-            el = Ext.getDom(el);
-            return new this(el.value || el.innerHTML, config || {});
-        }
-    },
+            me.onRender(container, position);
 
-    
+            
+            
+            me.el.setVisibilityMode(Ext.Element[me.hideMode.toUpperCase()]);
 
-    argsRe: /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
-    nameRe: /^<tpl\b[^>]*?for="(.*?)"/,
-    ifRe: /^<tpl\b[^>]*?if="(.*?)"/,
-    execRe: /^<tpl\b[^>]*?exec="(.*?)"/,
-    constructor: function() {
-        this.callParent(arguments);
+            if (me.overCls) {
+                me.el.hover(me.addOverCls, me.removeOverCls, me);
+            }
 
-        var me = this,
-            html = me.html,
-            argsRe = me.argsRe,
-            nameRe = me.nameRe,
-            ifRe = me.ifRe,
-            execRe = me.execRe,
-            id = 0,
-            tpls = [],
-            VALUES = 'values',
-            PARENT = 'parent',
-            XINDEX = 'xindex',
-            XCOUNT = 'xcount',
-            RETURN = 'return ',
-            WITHVALUES = 'with(values){ ',
-            m, matchName, matchIf, matchExec, exp, fn, exec, name, i;
+            me.fireEvent('render', me);
 
-        html = ['<tpl>', html, '</tpl>'].join('');
+            me.initContent();
 
-        while ((m = html.match(argsRe))) {
-            exp = null;
-            fn = null;
-            exec = null;
-            matchName = m[0].match(nameRe);
-            matchIf = m[0].match(ifRe);
-            matchExec = m[0].match(execRe);
+            me.afterRender(container);
+            me.fireEvent('afterrender', me);
 
-            exp = matchIf ? matchIf[1] : null;
-            if (exp) {
-                fn = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + 'try{' + RETURN + Ext.String.htmlDecode(exp) + ';}catch(e){return;}}');
-            }
+            me.initEvents();
 
-            exp = matchExec ? matchExec[1] : null;
-            if (exp) {
-                exec = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + Ext.String.htmlDecode(exp) + ';}');
+            if (me.hidden) {
+                
+                
+                
+                me.el.hide();
             }
 
-            name = matchName ? matchName[1] : null;
-            if (name) {
-                if (name === '.') {
-                    name = VALUES;
-                } else if (name === '..') {
-                    name = PARENT;
-                }
-                name = Ext.functionFactory(VALUES, PARENT, 'try{' + WITHVALUES + RETURN + name + ';}}catch(e){return;}');
+            if (me.disabled) {
+                
+                me.disable(true);
             }
 
-            tpls.push({
-                id: id,
-                target: name,
-                exec: exec,
-                test: fn,
-                body: m[1] || ''
-            });
-
-            html = html.replace(m[0], '{xtpl' + id + '}');
-            id = id + 1;
-        }
-
-        for (i = tpls.length - 1; i >= 0; --i) {
-            me.compileTpl(tpls[i]);
+            
+            delete me.rendering;
         }
-        me.master = tpls[tpls.length - 1];
-        me.tpls = tpls;
-    },
-
-    
-    applySubTemplate: function(id, values, parent, xindex, xcount) {
-        var me = this, t = me.tpls[id];
-        return t.compiled.call(me, values, parent, xindex, xcount);
+        return me;
     },
-    
-    codeRe: /\{\[((?:\\\]|.|\n)*?)\]\}/g,
-
-    re: /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\/]\s?[\d\.\+\-\*\/\(\)]+)?\}/g,
 
     
-    compileTpl: function(tpl) {
-        var fm = Ext.util.Format,
-            me = this,
-            useFormat = me.disableFormats !== true,
-            body, bodyReturn, evaluatedFn;
+    onRender : function(container, position) {
+        var me = this,
+            el = me.el,
+            styles = me.initStyles(),
+            renderTpl, renderData, i;
 
-        function fn(m, name, format, args, math) {
-            var v;
-            
-            
-            if (name.substr(0, 4) == 'xtpl') {
-                return "',this.applySubTemplate(" + name.substr(4) + ", values, parent, xindex, xcount),'";
-            }
-            
-            if (name == '.') {
-                
-                v = 'Ext.Array.indexOf(["string", "number", "boolean"], typeof values) > -1 || Ext.isDate(values) ? values : ""';
-            }
+        position = me.getInsertPosition(position);
 
-            
-            else if (name == '#') {
-                v = 'xindex';
+        if (!el) {
+            if (position) {
+                el = Ext.DomHelper.insertBefore(position, me.getElConfig(), true);
             }
-            else if (name.substr(0, 7) == "parent.") {
-                v = name;
+            else {
+                el = Ext.DomHelper.append(container, me.getElConfig(), true);
             }
-            
-            else if (name.indexOf('.') != -1) {
-                v = "values." + name;
+        }
+        else if (me.allowDomMove !== false) {
+            if (position) {
+                container.dom.insertBefore(el.dom, position);
+            } else {
+                container.dom.appendChild(el.dom);
             }
+        }
 
+        if (Ext.scopeResetCSS && !me.ownerCt) {
             
-            else {
-                v = "values['" + name + "']";
-            }
-            if (math) {
-                v = '(' + v + math + ')';
-            }
-            if (format && useFormat) {
-                args = args ? ',' + args : "";
-                if (format.substr(0, 5) != "this.") {
-                    format = "fm." + format + '(';
-                }
-                else {
-                    format = 'this.' + format.substr(5) + '(';
-                }
+            if (el.dom == Ext.getBody().dom) {
+                el.parent().addCls(Ext.baseCSSPrefix + 'reset');
             }
             else {
-                args = '';
-                format = "(" + v + " === undefined ? '' : ";
+                
+                me.resetEl = el.wrap({
+                    cls: Ext.baseCSSPrefix + 'reset'
+                });
             }
-            return "'," + format + v + args + "),'";
-        }
-
-        function codeFn(m, code) {
-            
-            return "',(" + code.replace(me.compileARe, "'") + "),'";
         }
 
-        bodyReturn = tpl.body.replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn).replace(me.codeRe, codeFn);
-        body = "evaluatedFn = function(values, parent, xindex, xcount){return ['" + bodyReturn + "'].join('');};";
-        eval(body);
+        me.setUI(me.ui);
 
-        tpl.compiled = function(values, parent, xindex, xcount) {
-            var vs,
-                length,
-                buffer,
-                i;
+        el.addCls(me.initCls());
+        el.setStyle(styles);
 
-            if (tpl.test && !tpl.test.call(me, values, parent, xindex, xcount)) {
-                return '';
-            }
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
 
-            vs = tpl.target ? tpl.target.call(me, values, parent) : values;
-            if (!vs) {
-               return '';
-            }
+        me.el = el;
 
-            parent = tpl.target ? values : parent;
-            if (tpl.target && Ext.isArray(vs)) {
-                buffer = [];
-                length = vs.length;
-                if (tpl.exec) {
-                    for (i = 0; i < length; i++) {
-                        buffer[buffer.length] = evaluatedFn.call(me, vs[i], parent, i + 1, length);
-                        tpl.exec.call(me, vs[i], parent, i + 1, length);
-                    }
-                } else {
-                    for (i = 0; i < length; i++) {
-                        buffer[buffer.length] = evaluatedFn.call(me, vs[i], parent, i + 1, length);
-                    }
-                }
-                return buffer.join('');
-            }
+        me.initFrame();
 
-            if (tpl.exec) {
-                tpl.exec.call(me, vs, parent, xindex, xcount);
-            }
-            return evaluatedFn.call(me, vs, parent, xindex, xcount);
-        };
+        renderTpl = me.initRenderTpl();
+        if (renderTpl) {
+            renderData = me.initRenderData();
+            renderTpl.append(me.getTargetEl(), renderData);
+        }
 
-        return this;
-    },
+        me.applyRenderSelectors();
 
-    
-    applyTemplate: function(values) {
-        return this.master.compiled.call(this, values, {}, 1, 1);
+        me.rendered = true;
     },
 
     
-    compile: function() {
-        return this;
-    }
-}, function() {
-    
-    this.createAlias('apply', 'applyTemplate');
-});
-
-
-Ext.define('Ext.util.AbstractMixedCollection', {
-    requires: ['Ext.util.Filter'],
-    
-    mixins: {
-        observable: 'Ext.util.Observable'
-    },
-
-    constructor: function(allowFunctions, keyFn) {
-        var me = this;
+    afterRender : function() {
+        var me = this,
+            pos,
+            xy;
 
-        me.items = [];
-        me.map = {};
-        me.keys = [];
-        me.length = 0;
+        me.getComponentLayout();
 
-        me.addEvents(
+        
+        
+        
+        if (me.collapsed || (!me.ownerCt || (me.height || me.width))) {
+            me.setSize(me.width, me.height);
+        } else {
             
-            'clear',
-
             
-            'add',
-
             
-            'replace',
-
             
-            'remove'
-        );
-
-        me.allowFunctions = allowFunctions === true;
-
-        if (keyFn) {
-            me.getKey = keyFn;
+            me.renderChildren();
         }
 
-        me.mixins.observable.constructor.call(me);
-    },
-    
-    
-    allowFunctions : false,
-
-    
-    add : function(key, obj){
-        var me = this,
-            myObj = obj,
-            myKey = key,
-            old;
+        
+        
+        if (me.floating && (me.x === undefined || me.y === undefined)) {
+            if (me.floatParent) {
+                xy = me.el.getAlignToXY(me.floatParent.getTargetEl(), 'c-c');
+                pos = me.floatParent.getTargetEl().translatePoints(xy[0], xy[1]);
+            } else {
+                xy = me.el.getAlignToXY(me.container, 'c-c');
+                pos = me.container.translatePoints(xy[0], xy[1]);
+            }
+            me.x = me.x === undefined ? pos.left: me.x;
+            me.y = me.y === undefined ? pos.top: me.y;
+        }
 
-        if (arguments.length == 1) {
-            myObj = myKey;
-            myKey = me.getKey(myObj);
+        if (Ext.isDefined(me.x) || Ext.isDefined(me.y)) {
+            me.setPosition(me.x, me.y);
         }
-        if (typeof myKey != 'undefined' && myKey !== null) {
-            old = me.map[myKey];
-            if (typeof old != 'undefined') {
-                return me.replace(myKey, myObj);
-            }
-            me.map[myKey] = myObj;
+
+        if (me.styleHtmlContent) {
+            me.getTargetEl().addCls(me.styleHtmlCls);
         }
-        me.length++;
-        me.items.push(myObj);
-        me.keys.push(myKey);
-        me.fireEvent('add', me.length - 1, myObj, myKey);
-        return myObj;
     },
 
     
-    getKey : function(o){
-         return o.id;
+    registerFloatingItem: function(cmp) {
+        var me = this;
+        if (!me.floatingItems) {
+            me.floatingItems = Ext.create('Ext.ZIndexManager', me);
+        }
+        me.floatingItems.register(cmp);
     },
 
-    
-    replace : function(key, o){
+    renderChildren: function () {
         var me = this,
-            old,
-            index;
+            layout = me.getComponentLayout();
 
-        if (arguments.length == 1) {
-            o = arguments[0];
-            key = me.getKey(o);
-        }
-        old = me.map[key];
-        if (typeof key == 'undefined' || key === null || typeof old == 'undefined') {
-             return me.add(key, o);
-        }
-        index = me.indexOfKey(key);
-        me.items[index] = o;
-        me.map[key] = o;
-        me.fireEvent('replace', key, old, o);
-        return o;
+        me.suspendLayout = true;
+        layout.renderChildren();
+        delete me.suspendLayout;
     },
 
-    
-    addAll : function(objs){
-        var me = this,
-            i = 0,
-            args,
-            len,
-            key;
+    frameCls: Ext.baseCSSPrefix + 'frame',
 
-        if (arguments.length > 1 || Ext.isArray(objs)) {
-            args = arguments.length > 1 ? arguments : objs;
-            for (len = args.length; i < len; i++) {
-                me.add(args[i]);
-            }
-        } else {
-            for (key in objs) {
-                if (objs.hasOwnProperty(key)) {
-                    if (me.allowFunctions || typeof objs[key] != 'function') {
-                        me.add(key, objs[key]);
-                    }
-                }
-            }
-        }
+    frameIdRegex: /[-]frame\d+[TMB][LCR]$/,
+
+    frameElementCls: {
+        tl: [],
+        tc: [],
+        tr: [],
+        ml: [],
+        mc: [],
+        mr: [],
+        bl: [],
+        bc: [],
+        br: []
     },
 
-    
-    each : function(fn, scope){
-        var items = [].concat(this.items), 
-            i = 0,
-            len = items.length,
-            item;
+    frameTpl: [
+        '<tpl if="top">',
+            '<tpl if="left"><div id="{fgid}TL" class="{frameCls}-tl {baseCls}-tl {baseCls}-{ui}-tl<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tl</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tr</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tc</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-ml</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mr</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mc</tpl></tpl>" role="presentation"></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bl</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-br</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bc</tpl></tpl>" style="background-position: {bc}; height: {frameWidth}px" role="presentation"></div>',
+                '<tpl if="right"></div></tpl>',
+            '<tpl if="left"></div></tpl>',
+        '</tpl>'
+    ],
 
-        for (; i < len; i++) {
-            item = items[i];
-            if (fn.call(scope || item, item, i, len) === false) {
-                break;
-            }
-        }
-    },
+    frameTableTpl: [
+        '<table><tbody>',
+            '<tpl if="top">',
+                '<tr>',
+                    '<tpl if="left"><td id="{fgid}TL" class="{frameCls}-tl {baseCls}-tl {baseCls}-{ui}-tl<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tl</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tc</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tr</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-ml</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mc</tpl></tpl>" style="background-position: 0 0;" role="presentation"></td>',
+                '<tpl if="right"><td id="{fgid}MR" class="{frameCls}-mr {baseCls}-mr {baseCls}-{ui}-mr<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mr</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bl</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bc</tpl></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 if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-br</tpl></tpl>" style="background-position: {br}; padding-left: {frameWidth}px" role="presentation"></td></tpl>',
+                '</tr>',
+            '</tpl>',
+        '</tbody></table>'
+    ],
 
     
-    eachKey : function(fn, scope){
-        var keys = this.keys,
-            items = this.items,
-            i = 0,
-            len = keys.length;
-
-        for (; i < len; i++) {
-            fn.call(scope || window, keys[i], items[i], i, len);
+    initFrame : function() {
+        if (Ext.supports.CSS3BorderRadius) {
+            return false;
         }
-    },
 
-    
-    findBy : function(fn, scope) {
-        var keys = this.keys,
-            items = this.items,
-            i = 0,
-            len = items.length;
+        var me = this,
+            frameInfo = me.getFrameInfo(),
+            frameWidth = frameInfo.width,
+            frameTpl = me.getFrameTpl(frameInfo.table),
+            frameGenId;
 
-        for (; i < len; i++) {
-            if (fn.call(scope || window, items[i], keys[i])) {
-                return items[i];
-            }
+        if (me.frame) {
+            
+            
+            me.frameGenId = frameGenId = (me.frameGenId || 0) + 1;
+            frameGenId = me.id + '-frame' + frameGenId;
+
+            
+            frameTpl.insertFirst(me.el, Ext.apply({}, {
+                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)));
+
+            
+            me.frameBody = me.el.down('.' + me.frameCls + '-mc');
+
+            
+            me.removeChildEls(function (c) {
+                return c.id && me.frameIdRegex.test(c.id);
+            });
+
+            
+            Ext.each(['TL','TC','TR','ML','MC','MR','BL','BC','BR'], function (suffix) {
+                me.childEls.push({ name: 'frame' + suffix, id: frameGenId + suffix });
+            });
         }
-        return null;
     },
 
-    find : function() {
-        if (Ext.isDefined(Ext.global.console)) {
-            Ext.global.console.warn('Ext.util.MixedCollection: find has been deprecated. Use findBy instead.');
+    updateFrame: function() {
+        if (Ext.supports.CSS3BorderRadius) {
+            return false;
         }
-        return this.findBy.apply(this, arguments);
-    },
 
-    
-    insert : function(index, key, obj){
         var me = this,
-            myKey = key,
-            myObj = obj;
+            wasTable = this.frameSize && this.frameSize.table,
+            oldFrameTL = this.frameTL,
+            oldFrameBL = this.frameBL,
+            oldFrameML = this.frameML,
+            oldFrameMC = this.frameMC,
+            newMCClassName;
 
-        if (arguments.length == 2) {
-            myObj = myKey;
-            myKey = me.getKey(myObj);
+        this.initFrame();
+
+        if (oldFrameMC) {
+            if (me.frame) {
+                
+                delete me.frameTL;
+                delete me.frameTC;
+                delete me.frameTR;
+                delete me.frameML;
+                delete me.frameMC;
+                delete me.frameMR;
+                delete me.frameBL;
+                delete me.frameBC;
+                delete me.frameBR;
+                this.applyRenderSelectors();
+
+                
+                newMCClassName = this.frameMC.dom.className;
+
+                
+                oldFrameMC.insertAfter(this.frameMC);
+                this.frameMC.remove();
+
+                
+                this.frameBody = this.frameMC = oldFrameMC;
+
+                
+                oldFrameMC.dom.className = newMCClassName;
+
+                
+                if (wasTable) {
+                    me.el.query('> table')[1].remove();
+                }
+                else {
+                    if (oldFrameTL) {
+                        oldFrameTL.remove();
+                    }
+                    if (oldFrameBL) {
+                        oldFrameBL.remove();
+                    }
+                    oldFrameML.remove();
+                }
+            }
+            else {
+                
+
+            }
         }
-        if (me.containsKey(myKey)) {
-            me.suspendEvents();
-            me.removeAtKey(myKey);
-            me.resumeEvents();
+        else if (me.frame) {
+            this.applyRenderSelectors();
         }
-        if (index >= me.length) {
-            return me.add(myKey, myObj);
+    },
+
+    getFrameInfo: function() {
+        if (Ext.supports.CSS3BorderRadius) {
+            return false;
         }
-        me.length++;
-        me.items.splice(index, 0, myObj);
-        if (typeof myKey != 'undefined' && myKey !== null) {
-            me.map[myKey] = myObj;
+
+        var me = this,
+            left = me.el.getStyle('background-position-x'),
+            top = me.el.getStyle('background-position-y'),
+            info, frameInfo = false, max;
+
+        
+        
+        if (!left && !top) {
+            info = me.el.getStyle('background-position').split(' ');
+            left = info[0];
+            top = info[1];
         }
-        me.keys.splice(index, 0, myKey);
-        me.fireEvent('add', index, myObj, myKey);
-        return myObj;
-    },
 
-    
-    remove : function(o){
-        return this.removeAt(this.indexOf(o));
-    },
+        
+        
+        
+        if (parseInt(left, 10) >= 1000000 && parseInt(top, 10) >= 1000000) {
+            max = Math.max;
 
-    
-    removeAll : function(items){
-        Ext.each(items || [], function(item) {
-            this.remove(item);
-        }, this);
+            frameInfo = {
+                
+                table: left.substr(0, 3) == '110',
 
-        return this;
-    },
+                
+                vertical: top.substr(0, 3) == '110',
 
-    
-    removeAt : function(index){
-        var me = this,
-            o,
-            key;
+                
+                top:    max(left.substr(3, 2), left.substr(5, 2)),
+                right:  max(left.substr(5, 2), top.substr(3, 2)),
+                bottom: max(top.substr(3, 2), top.substr(5, 2)),
+                left:   max(top.substr(5, 2), left.substr(3, 2))
+            };
 
-        if (index < me.length && index >= 0) {
-            me.length--;
-            o = me.items[index];
-            me.items.splice(index, 1);
-            key = me.keys[index];
-            if (typeof key != 'undefined') {
-                delete me.map[key];
-            }
-            me.keys.splice(index, 1);
-            me.fireEvent('remove', o, key);
-            return o;
-        }
-        return false;
-    },
+            frameInfo.width = max(frameInfo.top, frameInfo.right, frameInfo.bottom, frameInfo.left);
 
-    
-    removeAtKey : function(key){
-        return this.removeAt(this.indexOfKey(key));
-    },
+            
+            me.el.setStyle('background-image', 'none');
+        }
 
-    
-    getCount : function(){
-        return this.length;
-    },
+        
+        
+        if (me.frame === true && !frameInfo) {
+        }
 
-    
-    indexOf : function(o){
-        return Ext.Array.indexOf(this.items, o);
-    },
+        me.frame = me.frame || !!frameInfo;
+        me.frameSize = frameInfo || false;
 
-    
-    indexOfKey : function(key){
-        return Ext.Array.indexOf(this.keys, key);
+        return frameInfo;
     },
 
-    
-    get : function(key) {
+    getFramePositions: function(frameInfo) {
         var me = this,
-            mk = me.map[key],
-            item = mk !== undefined ? mk : (typeof key == 'number') ? me.items[key] : undefined;
-        return typeof item != 'function' || me.allowFunctions ? item : null; 
-    },
+            frameWidth = frameInfo.width,
+            dock = me.dock,
+            positions, tc, bc, ml, mr;
 
-    
-    getAt : function(index) {
-        return this.items[index];
-    },
+        if (frameInfo.vertical) {
+            tc = '0 -' + (frameWidth * 0) + 'px';
+            bc = '0 -' + (frameWidth * 1) + 'px';
 
-    
-    getByKey : function(key) {
-        return this.map[key];
-    },
+            if (dock && dock == "right") {
+                tc = 'right -' + (frameWidth * 0) + 'px';
+                bc = 'right -' + (frameWidth * 1) + 'px';
+            }
 
-    
-    contains : function(o){
-        return Ext.Array.contains(this.items, o);
-    },
+            positions = {
+                tl: '0 -' + (frameWidth * 0) + 'px',
+                tr: '0 -' + (frameWidth * 1) + 'px',
+                bl: '0 -' + (frameWidth * 2) + 'px',
+                br: '0 -' + (frameWidth * 3) + 'px',
 
-    
-    containsKey : function(key){
-        return typeof this.map[key] != 'undefined';
-    },
+                ml: '-' + (frameWidth * 1) + 'px 0',
+                mr: 'right 0',
 
-    
-    clear : function(){
-        var me = this;
+                tc: tc,
+                bc: bc
+            };
+        } else {
+            ml = '-' + (frameWidth * 0) + 'px 0';
+            mr = 'right 0';
 
-        me.length = 0;
-        me.items = [];
-        me.keys = [];
-        me.map = {};
-        me.fireEvent('clear');
-    },
+            if (dock && dock == "bottom") {
+                ml = 'left bottom';
+                mr = 'right bottom';
+            }
 
-    
-    first : function() {
-        return this.items[0];
+            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;
     },
 
     
-    last : function() {
-        return this.items[this.length - 1];
+    getFrameTpl : function(table) {
+        return table ? this.getTpl('frameTableTpl') : this.getTpl('frameTpl');
     },
 
     
-    sum: function(property, root, start, end) {
-        var values = this.extractValues(property, root),
-            length = values.length,
-            sum    = 0,
-            i;
+    initCls: function() {
+        var me = this,
+            cls = [];
 
-        start = start || 0;
-        end   = (end || end === 0) ? end : length - 1;
+        cls.push(me.baseCls);
 
-        for (i = start; i <= end; i++) {
-            sum += values[i];
+        if (Ext.isDefined(me.cmpCls)) {
+            if (Ext.isDefined(Ext.global.console)) {
+                Ext.global.console.warn('Ext.Component: cmpCls has been deprecated. Please use componentCls.');
+            }
+            me.componentCls = me.cmpCls;
+            delete me.cmpCls;
         }
 
-        return sum;
+        if (me.componentCls) {
+            cls.push(me.componentCls);
+        } else {
+            me.componentCls = me.baseCls;
+        }
+        if (me.cls) {
+            cls.push(me.cls);
+            delete me.cls;
+        }
+
+        return cls.concat(me.additionalCls);
     },
 
     
-    collect: function(property, root, allowNull) {
-        var values = this.extractValues(property, root),
-            length = values.length,
-            hits   = {},
-            unique = [],
-            value, strValue, i;
+    setUI: function(ui) {
+        var me = this,
+            oldUICls = Ext.Array.clone(me.uiCls),
+            newUICls = [],
+            classes = [],
+            cls,
+            i;
 
-        for (i = 0; i < length; i++) {
-            value = values[i];
-            strValue = String(value);
+        
+        for (i = 0; i < oldUICls.length; i++) {
+            cls = oldUICls[i];
 
-            if ((allowNull || !Ext.isEmpty(value)) && !hits[strValue]) {
-                hits[strValue] = true;
-                unique.push(value);
-            }
+            classes = classes.concat(me.removeClsWithUI(cls, true));
+            newUICls.push(cls);
         }
 
-        return unique;
-    },
+        if (classes.length) {
+            me.removeCls(classes);
+        }
 
-    
-    extractValues: function(property, root) {
-        var values = this.items;
+        
+        me.removeUIFromElement();
 
-        if (root) {
-            values = Ext.Array.pluck(values, root);
+        
+        me.ui = ui;
+
+        
+        me.addUIToElement();
+
+        
+        classes = [];
+        for (i = 0; i < newUICls.length; i++) {
+            cls = newUICls[i];
+            classes = classes.concat(me.addClsWithUI(cls, true));
         }
 
-        return Ext.Array.pluck(values, property);
+        if (classes.length) {
+            me.addCls(classes);
+        }
     },
 
     
-    getRange : function(start, end){
+    addClsWithUI: function(cls, skip) {
         var me = this,
-            items = me.items,
-            range = [],
+            classes = [],
             i;
 
-        if (items.length < 1) {
-            return range;
+        if (!Ext.isArray(cls)) {
+            cls = [cls];
         }
 
-        start = start || 0;
-        end = Math.min(typeof end == 'undefined' ? me.length - 1 : end, me.length - 1);
-        if (start <= end) {
-            for (i = start; i <= end; i++) {
-                range[range.length] = items[i];
-            }
-        } else {
-            for (i = start; i >= end; i--) {
-                range[range.length] = items[i];
+        for (i = 0; i < cls.length; i++) {
+            if (cls[i] && !me.hasUICls(cls[i])) {
+                me.uiCls = Ext.Array.clone(me.uiCls);
+                me.uiCls.push(cls[i]);
+
+                classes = classes.concat(me.addUIClsToElement(cls[i]));
             }
         }
-        return range;
+
+        if (skip !== true) {
+            me.addCls(classes);
+        }
+
+        return classes;
     },
 
     
-    filter : function(property, value, anyMatch, caseSensitive) {
-        var filters = [],
-            filterFn;
+    removeClsWithUI: function(cls, skip) {
+        var me = this,
+            classes = [],
+            i;
 
-        
-        if (Ext.isString(property)) {
-            filters.push(Ext.create('Ext.util.Filter', {
-                property     : property,
-                value        : value,
-                anyMatch     : anyMatch,
-                caseSensitive: caseSensitive
-            }));
-        } else if (Ext.isArray(property) || property instanceof Ext.util.Filter) {
-            filters = filters.concat(property);
+        if (!Ext.isArray(cls)) {
+            cls = [cls];
         }
 
-        
-        
-        filterFn = function(record) {
-            var isMatch = true,
-                length = filters.length,
-                i;
-
-            for (i = 0; i < length; i++) {
-                var filter = filters[i],
-                    fn     = filter.filterFn,
-                    scope  = filter.scope;
+        for (i = 0; i < cls.length; i++) {
+            if (cls[i] && me.hasUICls(cls[i])) {
+                me.uiCls = Ext.Array.remove(me.uiCls, cls[i]);
 
-                isMatch = isMatch && fn.call(scope, record);
+                classes = classes.concat(me.removeUIClsFromElement(cls[i]));
             }
+        }
 
-            return isMatch;
-        };
+        if (skip !== true) {
+            me.removeCls(classes);
+        }
 
-        return this.filterBy(filterFn);
+        return classes;
     },
 
     
-    filterBy : function(fn, scope) {
+    hasUICls: function(cls) {
         var me = this,
-            newMC  = new this.self(),
-            keys   = me.keys,
-            items  = me.items,
-            length = items.length,
-            i;
+            uiCls = me.uiCls || [];
 
-        newMC.getKey = me.getKey;
+        return Ext.Array.contains(uiCls, cls);
+    },
 
-        for (i = 0; i < length; i++) {
-            if (fn.call(scope || me, items[i], keys[i])) {
-                newMC.add(keys[i], items[i]);
+    
+    addUIClsToElement: function(cls, force) {
+        var me = this,
+            result = [],
+            frameElementCls = me.frameElementCls;
+
+        result.push(Ext.baseCSSPrefix + cls);
+        result.push(me.baseCls + '-' + cls);
+        result.push(me.baseCls + '-' + me.ui + '-' + cls);
+
+        if (!force && me.frame && !Ext.supports.CSS3BorderRadius) {
+            
+            var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'],
+                classes, i, j, el;
+
+            
+            for (i = 0; i < els.length; i++) {
+                el = me['frame' + els[i].toUpperCase()];
+                classes = [me.baseCls + '-' + me.ui + '-' + els[i], me.baseCls + '-' + me.ui + '-' + cls + '-' + els[i]];
+                if (el && el.dom) {
+                    el.addCls(classes);
+                } else {
+                    for (j = 0; j < classes.length; j++) {
+                        if (Ext.Array.indexOf(frameElementCls[els[i]], classes[j]) == -1) {
+                            frameElementCls[els[i]].push(classes[j]);
+                        }
+                    }
+                }
             }
         }
 
-        return newMC;
-    },
+        me.frameElementCls = frameElementCls;
 
-    
-    findIndex : function(property, value, start, anyMatch, caseSensitive){
-        if(Ext.isEmpty(value, false)){
-            return -1;
-        }
-        value = this.createValueMatcher(value, anyMatch, caseSensitive);
-        return this.findIndexBy(function(o){
-            return o && value.test(o[property]);
-        }, null, start);
+        return result;
     },
 
     
-    findIndexBy : function(fn, scope, start){
+    removeUIClsFromElement: function(cls, force) {
         var me = this,
-            keys = me.keys,
-            items = me.items,
-            i = start || 0,
-            len = items.length;
+            result = [],
+            frameElementCls = me.frameElementCls;
 
-        for (; i < len; i++) {
-            if (fn.call(scope || me, items[i], keys[i])) {
-                return i;
+        result.push(Ext.baseCSSPrefix + cls);
+        result.push(me.baseCls + '-' + cls);
+        result.push(me.baseCls + '-' + me.ui + '-' + cls);
+
+        if (!force && me.frame && !Ext.supports.CSS3BorderRadius) {
+            
+            var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'],
+                i, el;
+            cls = me.baseCls + '-' + me.ui + '-' + cls + '-' + els[i];
+            
+            for (i = 0; i < els.length; i++) {
+                el = me['frame' + els[i].toUpperCase()];
+                if (el && el.dom) {
+                    el.removeCls(cls);
+                } else {
+                    Ext.Array.remove(frameElementCls[els[i]], cls);
+                }
             }
         }
-        return -1;
+
+        me.frameElementCls = frameElementCls;
+
+        return result;
     },
 
     
-    createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) {
-        if (!value.exec) { 
-            var er = Ext.String.escapeRegex;
-            value = String(value);
+    addUIToElement: function(force) {
+        var me = this,
+            frameElementCls = me.frameElementCls;
 
-            if (anyMatch === true) {
-                value = er(value);
-            } else {
-                value = '^' + er(value);
-                if (exactMatch === true) {
-                    value += '$';
+        me.addCls(me.baseCls + '-' + me.ui);
+
+        if (me.frame && !Ext.supports.CSS3BorderRadius) {
+            
+            var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'],
+                i, el, cls;
+
+            
+            for (i = 0; i < els.length; i++) {
+                el = me['frame' + els[i].toUpperCase()];
+                cls = me.baseCls + '-' + me.ui + '-' + els[i];
+                if (el) {
+                    el.addCls(cls);
+                } else {
+                    if (!Ext.Array.contains(frameElementCls[els[i]], cls)) {
+                        frameElementCls[els[i]].push(cls);
+                    }
                 }
             }
-            value = new RegExp(value, caseSensitive ? '' : 'i');
         }
-        return value;
     },
 
     
-    clone : function() {
+    removeUIFromElement: function() {
         var me = this,
-            copy = new this.self(),
-            keys = me.keys,
-            items = me.items,
-            i = 0,
-            len = items.length;
+            frameElementCls = me.frameElementCls;
 
-        for(; i < len; i++){
-            copy.add(keys[i], items[i]);
-        }
-        copy.getKey = me.getKey;
-        return copy;
-    }
-});
+        me.removeCls(me.baseCls + '-' + me.ui);
 
+        if (me.frame && !Ext.supports.CSS3BorderRadius) {
+            
+            var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'],
+                i, j, el, cls;
 
-Ext.define("Ext.util.Sortable", {
-    
-    isSortable: true,
-    
-    
-    defaultSortDirection: "ASC",
-    
-    requires: [
-        'Ext.util.Sorter'
-    ],
+            
+            for (i = 0; i < els.length; i++) {
+                el = me['frame' + els[i].toUpperCase()];
+                cls = me.baseCls + '-' + me.ui + '-' + els[i];
 
-        
-    sortRoot: null,
-    
-    
-    initSortable: function() {
-        var me = this,
-            sorters = me.sorters;
-        
-        
-        me.sorters = Ext.create('Ext.util.AbstractMixedCollection', false, function(item) {
-            return item.id || item.property;
-        });
-        
-        if (sorters) {
-            me.sorters.addAll(me.decodeSorters(sorters));
+                if (el) {
+                    el.removeCls(cls);
+                } else {
+                    Ext.Array.remove(frameElementCls[els[i]], cls);
+                }
+            }
         }
     },
 
-    
-    sort: function(sorters, direction, where, doSort) {
-        var me = this,
-            sorter, sorterFn,
-            newSorters;
-        
-        if (Ext.isArray(sorters)) {
-            doSort = where;
-            where = direction;
-            newSorters = sorters;
-        }
-        else if (Ext.isObject(sorters)) {
-            doSort = where;
-            where = direction;
-            newSorters = [sorters];
+    getElConfig : function() {
+        if (Ext.isString(this.autoEl)) {
+            this.autoEl = {
+                tag: this.autoEl
+            };
         }
-        else if (Ext.isString(sorters)) {
-            sorter = me.sorters.get(sorters);
 
-            if (!sorter) {
-                sorter = {
-                    property : sorters,
-                    direction: direction
-                };
-                newSorters = [sorter];
-            }
-            else if (direction === undefined) {
-                sorter.toggle();
-            }
-            else {
-                sorter.setDirection(direction);
-            }
-        }
+        var result = this.autoEl || {tag: 'div'};
+        result.id = this.id;
+        return result;
+    },
+
+    
+    getInsertPosition: function(position) {
         
-        if (newSorters && newSorters.length) {
-            newSorters = me.decodeSorters(newSorters);
-            if (Ext.isString(where)) {
-                if (where === 'prepend') {
-                    sorters = me.sorters.clone().items;
-                    
-                    me.sorters.clear();
-                    me.sorters.addAll(newSorters);
-                    me.sorters.addAll(sorters);
-                }
-                else {
-                    me.sorters.addAll(newSorters);
-                }
+        if (position !== undefined) {
+            if (Ext.isNumber(position)) {
+                position = this.container.dom.childNodes[position];
             }
             else {
-                me.sorters.clear();
-                me.sorters.addAll(newSorters);
-            }
-            
-            if (doSort !== false) {
-                me.onBeforeSort(newSorters);
+                position = Ext.getDom(position);
             }
         }
-        
-        if (doSort !== false) {
-            sorters = me.sorters.items;
-            if (sorters.length) {
-                
-                sorterFn = function(r1, r2) {
-                    var result = sorters[0].sort(r1, r2),
-                        length = sorters.length,
-                        i;
 
-                        
-                        for (i = 1; i < length; i++) {
-                            result = result || sorters[i].sort.call(this, r1, r2);
-                        }
+        return position;
+    },
 
-                    return result;
-                };
+    
+    initContainer: function(container) {
+        var me = this;
 
-                me.doSort(sorterFn);                
-            }
-        }
         
-        return sorters;
-    },
-    
-    onBeforeSort: Ext.emptyFn,
         
-    
-    decodeSorters: function(sorters) {
-        if (!Ext.isArray(sorters)) {
-            if (sorters === undefined) {
-                sorters = [];
-            } else {
-                sorters = [sorters];
-            }
+        
+        if (!container && me.el) {
+            container = me.el.dom.parentNode;
+            me.allowDomMove = false;
         }
 
-        var length = sorters.length,
-            Sorter = Ext.util.Sorter,
-            fields = this.model ? this.model.prototype.fields : null,
-            field,
-            config, i;
+        me.container = Ext.get(container);
 
-        for (i = 0; i < length; i++) {
-            config = sorters[i];
+        if (me.ctCls) {
+            me.container.addCls(me.ctCls);
+        }
 
-            if (!(config instanceof Sorter)) {
-                if (Ext.isString(config)) {
-                    config = {
-                        property: config
-                    };
-                }
-                
-                Ext.applyIf(config, {
-                    root     : this.sortRoot,
-                    direction: "ASC"
-                });
+        return me.container;
+    },
 
-                
-                if (config.fn) {
-                    config.sorterFn = config.fn;
-                }
+    
+    initRenderData: function() {
+        var me = this;
 
-                
-                if (typeof config == 'function') {
-                    config = {
-                        sorterFn: config
-                    };
-                }
+        return Ext.applyIf(me.renderData, {
+            id: me.id,
+            ui: me.ui,
+            uiCls: me.uiCls,
+            baseCls: me.baseCls,
+            componentCls: me.componentCls,
+            frame: me.frame
+        });
+    },
 
-                
-                if (fields && !config.transform) {
-                    field = fields.get(config.property);
-                    config.transform = field ? field.sortType : undefined;
-                }
-                sorters[i] = Ext.create('Ext.util.Sorter', config);
+    
+    getTpl: function(name) {
+        var me = this,
+            prototype = me.self.prototype,
+            ownerPrototype,
+            tpl;
+
+        if (me.hasOwnProperty(name)) {
+            tpl = me[name];
+            if (tpl && !(tpl instanceof Ext.XTemplate)) {
+                me[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', tpl);
             }
+
+            return me[name];
         }
 
-        return sorters;
-    },
-    
-    getSorters: function() {
-        return this.sorters.items;
-    },
-    
-    
-    getSortState : function() {
-        return this.sortInfo;
-    }
-});
+        if (!(prototype[name] instanceof Ext.XTemplate)) {
+            ownerPrototype = prototype;
 
-Ext.define('Ext.util.MixedCollection', {
-    extend: 'Ext.util.AbstractMixedCollection',
-    mixins: {
-        sortable: 'Ext.util.Sortable'
-    },
+            do {
+                if (ownerPrototype.hasOwnProperty(name)) {
+                    tpl = ownerPrototype[name];
+                    if (tpl && !(tpl instanceof Ext.XTemplate)) {
+                        ownerPrototype[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', tpl);
+                        break;
+                    }
+                }
 
-    constructor: function() {
-        var me = this;
-        me.callParent(arguments);
-        me.addEvents('sort');
-        me.mixins.sortable.initSortable.call(me);
+                ownerPrototype = ownerPrototype.superclass;
+            } while (ownerPrototype);
+        }
+
+        return prototype[name];
     },
 
-    doSort: function(sorterFn) {
-        this.sortBy(sorterFn);
+    
+    initRenderTpl: function() {
+        return this.getTpl('renderTpl');
     },
 
     
-    _sort : function(property, dir, fn){
-        var me = this,
-            i, len,
-            dsc   = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
+    initStyles: function() {
+        var style = {},
+            me = this,
+            Element = Ext.Element;
 
-            
-            c     = [],
-            keys  = me.keys,
-            items = me.items;
+        if (Ext.isString(me.style)) {
+            style = Element.parseStyles(me.style);
+        } else {
+            style = Ext.apply({}, me.style);
+        }
 
         
-        fn = fn || function(a, b) {
-            return a - b;
-        };
-
         
-        for(i = 0, len = items.length; i < len; i++){
-            c[c.length] = {
-                key  : keys[i],
-                value: items[i],
-                index: i
-            };
+        if (me.padding !== undefined) {
+            style.padding = Element.unitizeBox((me.padding === true) ? 5 : me.padding);
         }
 
-        
-        Ext.Array.sort(c, function(a, b){
-            var v = fn(a[property], b[property]) * dsc;
-            if(v === 0){
-                v = (a.index < b.index ? -1 : 1);
-            }
-            return v;
-        });
-
-        
-        for(i = 0, len = c.length; i < len; i++){
-            items[i] = c[i].value;
-            keys[i]  = c[i].key;
+        if (me.margin !== undefined) {
+            style.margin = Element.unitizeBox((me.margin === true) ? 5 : me.margin);
         }
 
-        me.fireEvent('sort', me);
+        delete me.style;
+        return style;
     },
 
     
-    sortBy: function(sorterFn) {
-        var me     = this,
-            items  = me.items,
-            keys   = me.keys,
-            length = items.length,
-            temp   = [],
-            i;
+    initContent: function() {
+        var me = this,
+            target = me.getTargetEl(),
+            contentEl,
+            pre;
 
-        
-        for (i = 0; i < length; i++) {
-            temp[i] = {
-                key  : keys[i],
-                value: items[i],
-                index: i
-            };
+        if (me.html) {
+            target.update(Ext.DomHelper.markup(me.html));
+            delete me.html;
         }
 
-        Ext.Array.sort(temp, function(a, b) {
-            var v = sorterFn(a.value, b.value);
-            if (v === 0) {
-                v = (a.index < b.index ? -1 : 1);
+        if (me.contentEl) {
+            contentEl = Ext.get(me.contentEl);
+            pre = Ext.baseCSSPrefix;
+            contentEl.removeCls([pre + 'hidden', pre + 'hide-display', pre + 'hide-offsets', pre + 'hide-nosize']);
+            target.appendChild(contentEl.dom);
+        }
+
+        if (me.tpl) {
+            
+            if (!me.tpl.isTemplate) {
+                me.tpl = Ext.create('Ext.XTemplate', me.tpl);
             }
 
-            return v;
-        });
+            if (me.data) {
+                me.tpl[me.tplWriteMode](target, me.data);
+                delete me.data;
+            }
+        }
+    },
 
-        
-        for (i = 0; i < length; i++) {
-            items[i] = temp[i].value;
-            keys[i]  = temp[i].key;
+    
+    initEvents : function() {
+        var me = this,
+            afterRenderEvents = me.afterRenderEvents,
+            el,
+            property,
+            fn = function(listeners){
+                me.mon(el, listeners);
+            };
+        if (afterRenderEvents) {
+            for (property in afterRenderEvents) {
+                if (afterRenderEvents.hasOwnProperty(property)) {
+                    el = me[property];
+                    if (el && el.on) {
+                        Ext.each(afterRenderEvents[property], fn);
+                    }
+                }
+            }
         }
-        
-        me.fireEvent('sort', me, items, keys);
     },
 
     
-    reorder: function(mapping) {
+    addChildEls: function () {
         var me = this,
-            items = me.items,
-            index = 0,
-            length = items.length,
-            order = [],
-            remaining = [],
-            oldIndex;
+            childEls = me.childEls || (me.childEls = []);
 
-        me.suspendEvents();
+        childEls.push.apply(childEls, arguments);
+    },
 
-        
-        for (oldIndex in mapping) {
-            order[mapping[oldIndex]] = items[oldIndex];
-        }
+    
+    removeChildEls: function (testFn) {
+        var me = this,
+            old = me.childEls,
+            keepers = (me.childEls = []),
+            n, i, cel;
 
-        for (index = 0; index < length; index++) {
-            if (mapping[index] == undefined) {
-                remaining.push(items[index]);
+        for (i = 0, n = old.length; i < n; ++i) {
+            cel = old[i];
+            if (!testFn(cel)) {
+                keepers.push(cel);
             }
         }
+    },
 
-        for (index = 0; index < length; index++) {
-            if (order[index] == undefined) {
-                order[index] = remaining.shift();
+    
+    applyRenderSelectors: function() {
+        var me = this,
+            childEls = me.childEls,
+            selectors = me.renderSelectors,
+            el = me.el,
+            dom = el.dom,
+            baseId, childName, childId, i, selector;
+
+        if (childEls) {
+            baseId = me.id + '-';
+            for (i = childEls.length; i--; ) {
+                childName = childId = childEls[i];
+                if (typeof(childName) != 'string') {
+                    childId = childName.id || (baseId + childName.itemId);
+                    childName = childName.name;
+                } else {
+                    childId = baseId + childId;
+                }
+
+                
+                
+                me[childName] = el.getById(childId);
             }
         }
 
-        me.clear();
-        me.addAll(order);
-
-        me.resumeEvents();
-        me.fireEvent('sort', me);
+        
+        
+        
+        if (selectors) {
+            for (selector in selectors) {
+                if (selectors.hasOwnProperty(selector) && selectors[selector]) {
+                    me[selector] = Ext.get(Ext.DomQuery.selectNode(selectors[selector], dom));
+                }
+            }
+        }
     },
 
     
-    sortByKey : function(dir, fn){
-        this._sort('key', dir, fn || function(a, b){
-            var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
-            return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
-        });
-    }
-});
-
-
-Ext.define('Ext.data.StoreManager', {
-    extend: 'Ext.util.MixedCollection',
-    alternateClassName: ['Ext.StoreMgr', 'Ext.data.StoreMgr', 'Ext.StoreManager'],
-    singleton: true,
-    uses: ['Ext.data.ArrayStore'],
-    
-    
+    is: function(selector) {
+        return Ext.ComponentQuery.is(this, selector);
+    },
 
     
-    register : function() {
-        for (var i = 0, s; (s = arguments[i]); i++) {
-            this.add(s);
+    up: function(selector) {
+        var result = this.ownerCt;
+        if (selector) {
+            for (; result; result = result.ownerCt) {
+                if (Ext.ComponentQuery.is(result, selector)) {
+                    return result;
+                }
+            }
         }
+        return result;
     },
 
     
-    unregister : function() {
-        for (var i = 0, s; (s = arguments[i]); i++) {
-            this.remove(this.lookup(s));
+    nextSibling: function(selector) {
+        var o = this.ownerCt, it, last, idx, c;
+        if (o) {
+            it = o.items;
+            idx = it.indexOf(this) + 1;
+            if (idx) {
+                if (selector) {
+                    for (last = it.getCount(); idx < last; idx++) {
+                        if ((c = it.getAt(idx)).is(selector)) {
+                            return c;
+                        }
+                    }
+                } else {
+                    if (idx < it.getCount()) {
+                        return it.getAt(idx);
+                    }
+                }
+            }
         }
+        return null;
     },
 
     
-    lookup : function(store) {
-        
-        if (Ext.isArray(store)) {
-            var fields = ['field1'], 
-                expand = !Ext.isArray(store[0]),
-                data = store,
-                i,
-                len;
-                
-            if(expand){
-                data = [];
-                for (i = 0, len = store.length; i < len; ++i) {
-                    data.push([store[i]]);
-                }
-            } else {
-                for(i = 2, len = store[0].length; i <= len; ++i){
-                    fields.push('field' + i);
+    previousSibling: function(selector) {
+        var o = this.ownerCt, it, idx, c;
+        if (o) {
+            it = o.items;
+            idx = it.indexOf(this);
+            if (idx != -1) {
+                if (selector) {
+                    for (--idx; idx >= 0; idx--) {
+                        if ((c = it.getAt(idx)).is(selector)) {
+                            return c;
+                        }
+                    }
+                } else {
+                    if (idx) {
+                        return it.getAt(--idx);
+                    }
                 }
             }
-            return Ext.create('Ext.data.ArrayStore', {
-                data  : data,
-                fields: fields,
-                autoDestroy: true,
-                autoCreated: true,
-                expanded: expand
-            });
-        }
-        
-        if (Ext.isString(store)) {
-            
-            return this.get(store);
-        } else {
-            
-            return Ext.data.AbstractStore.create(store);
         }
+        return null;
     },
 
     
-    getKey : function(o) {
-         return o.storeId;
-    }
-}, function() {    
-    
-    Ext.regStore = function(name, config) {
-        var store;
+    previousNode: function(selector, includeSelf) {
+        var node = this,
+            result,
+            it, len, i;
 
-        if (Ext.isObject(name)) {
-            config = name;
-        } else {
-            config.storeId = name;
+        
+        if (includeSelf && node.is(selector)) {
+            return node;
         }
 
-        if (config instanceof Ext.data.Store) {
-            store = config;
-        } else {
-            store = Ext.create('Ext.data.Store', config);
+        result = this.prev(selector);
+        if (result) {
+            return result;
         }
 
-        return Ext.data.StoreManager.register(store);
-    };
+        if (node.ownerCt) {
+            for (it = node.ownerCt.items.items, i = Ext.Array.indexOf(it, node) - 1; i > -1; i--) {
+                if (it[i].query) {
+                    result = it[i].query(selector);
+                    result = result[result.length - 1];
+                    if (result) {
+                        return result;
+                    }
+                }
+            }
+            return node.ownerCt.previousNode(selector, true);
+        }
+    },
 
     
-    Ext.getStore = function(name) {
-        return Ext.data.StoreManager.lookup(name);
-    };
-});
+    nextNode: function(selector, includeSelf) {
+        var node = this,
+            result,
+            it, len, i;
 
+        
+        if (includeSelf && node.is(selector)) {
+            return node;
+        }
 
+        result = this.next(selector);
+        if (result) {
+            return result;
+        }
 
-Ext.define('Ext.LoadMask', {
+        if (node.ownerCt) {
+            for (it = node.ownerCt.items, i = it.indexOf(node) + 1, it = it.items, len = it.length; i < len; i++) {
+                if (it[i].down) {
+                    result = it[i].down(selector);
+                    if (result) {
+                        return result;
+                    }
+                }
+            }
+            return node.ownerCt.nextNode(selector);
+        }
+    },
 
     
-
-    mixins: {
-        observable: 'Ext.util.Observable'
+    getId : function() {
+        return this.id || (this.id = 'ext-comp-' + (this.getAutoId()));
     },
 
-    requires: ['Ext.data.StoreManager'],
+    getItemId : function() {
+        return this.itemId || this.id;
+    },
 
     
+    getEl : function() {
+        return this.el;
+    },
 
     
+    getTargetEl: function() {
+        return this.frameBody || this.el;
+    },
 
     
-    msg : 'Loading...',
-    
-    msgCls : Ext.baseCSSPrefix + 'mask-loading',
-    
-    
-    useMsg: true,
+    isXType: function(xtype, shallow) {
+        
+        if (Ext.isFunction(xtype)) {
+            xtype = xtype.xtype;
+            
+        } else if (Ext.isObject(xtype)) {
+            xtype = xtype.statics().xtype;
+            
+        }
+
+        return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1: this.self.xtype == xtype;
+    },
 
     
-    disabled: false,
+    getXTypes: function() {
+        var self = this.self,
+            xtypes, parentPrototype, parentXtypes;
 
-    constructor : function(el, config) {
-        var me = this;
+        if (!self.xtypes) {
+            xtypes = [];
+            parentPrototype = this;
 
-        if (el.isComponent) {
-            me.bindComponent(el);
-        } else {
-            me.el = Ext.get(el);
-        }
-        Ext.apply(me, config);
+            while (parentPrototype) {
+                parentXtypes = parentPrototype.xtypes;
 
-        me.addEvents('beforeshow', 'show', 'hide');
-        if (me.store) {
-            me.bindStore(me.store, true);
+                if (parentXtypes !== undefined) {
+                    xtypes.unshift.apply(xtypes, parentXtypes);
+                }
+
+                parentPrototype = parentPrototype.superclass;
+            }
+
+            self.xtypeChain = xtypes;
+            self.xtypes = xtypes.join('/');
         }
-        me.mixins.observable.constructor.call(me, config);
+
+        return self.xtypes;
     },
 
-    bindComponent: function(comp) {
-        var me = this,
-            listeners = {
-                resize: me.onComponentResize,
-                scope: me
-            };
+    
+    update : function(htmlOrData, loadScripts, cb) {
+        var me = this;
 
-        if (comp.el) {
-            me.onComponentRender(comp);
+        if (me.tpl && !Ext.isString(htmlOrData)) {
+            me.data = htmlOrData;
+            if (me.rendered) {
+                me.tpl[me.tplWriteMode](me.getTargetEl(), htmlOrData || {});
+            }
         } else {
-            listeners.render = {
-                fn: me.onComponentRender,
-                scope: me,
-                single: true
-            };
+            me.html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData;
+            if (me.rendered) {
+                me.getTargetEl().update(me.html, loadScripts, cb);
+            }
+        }
+
+        if (me.rendered) {
+            me.doComponentLayout();
         }
-        me.mon(comp, listeners);
     },
 
     
-    onComponentRender: function(comp) {
-        this.el = comp.getContentTarget();
+    setVisible : function(visible) {
+        return this[visible ? 'show': 'hide']();
     },
 
     
-    onComponentResize: function(comp, w, h) {
-        this.el.isMasked();
+    isVisible: function(deep) {
+        var me = this,
+            child = me,
+            visible = !me.hidden,
+            ancestor = me.ownerCt;
+
+        
+        me.hiddenAncestor = false;
+        if (me.destroyed) {
+            return false;
+        }
+
+        if (deep && visible && me.rendered && ancestor) {
+            while (ancestor) {
+                
+                
+                
+                
+                if (ancestor.hidden || (ancestor.collapsed &&
+                        !(ancestor.getDockedItems && Ext.Array.contains(ancestor.getDockedItems(), child)))) {
+                    
+                    me.hiddenAncestor = ancestor;
+                    visible = false;
+                    break;
+                }
+                child = ancestor;
+                ancestor = ancestor.ownerCt;
+            }
+        }
+        return visible;
     },
 
     
-    bindStore : function(store, initial) {
+    enable: function(silent) {
         var me = this;
 
-        if (!initial && me.store) {
-            me.mun(me.store, {
-                scope: me,
-                beforeload: me.onBeforeLoad,
-                load: me.onLoad,
-                exception: me.onLoad
-            });
-            if(!store) {
-                me.store = null;
-            }
+        if (me.rendered) {
+            me.el.removeCls(me.disabledCls);
+            me.el.dom.disabled = false;
+            me.onEnable();
         }
-        if (store) {
-            store = Ext.data.StoreManager.lookup(store);
-            me.mon(store, {
-                scope: me,
-                beforeload: me.onBeforeLoad,
-                load: me.onLoad,
-                exception: me.onLoad
-            });
 
+        me.disabled = false;
+
+        if (silent !== true) {
+            me.fireEvent('enable', me);
         }
-        me.store = store;
-        if (store && store.isLoading()) {
-            me.onBeforeLoad();
-        }
+
+        return me;
     },
 
     
-    disable : function() {
+    disable: function(silent) {
         var me = this;
 
-       me.disabled = true;
-       if (me.loading) {
-           me.onLoad();
-       }
+        if (me.rendered) {
+            me.el.addCls(me.disabledCls);
+            me.el.dom.disabled = true;
+            me.onDisable();
+        }
+
+        me.disabled = true;
+
+        if (silent !== true) {
+            me.fireEvent('disable', me);
+        }
+
+        return me;
     },
 
     
-    enable : function() {
-        this.disabled = false;
+    onEnable: function() {
+        if (this.maskOnDisable) {
+            this.el.unmask();
+        }
+    },
+
+    
+    onDisable : function() {
+        if (this.maskOnDisable) {
+            this.el.mask();
+        }
     },
 
     
@@ -18027,6897 +17104,7994 @@ Ext.define('Ext.LoadMask', {
     },
 
     
-    onLoad : function() {
-        var me = this;
+    setDisabled : function(disabled) {
+        return this[disabled ? 'disable': 'enable']();
+    },
 
-        me.loading = false;
-        me.el.unmask();
-        me.fireEvent('hide', me, me.el, me.store);
+    
+    isHidden : function() {
+        return this.hidden;
     },
 
     
-    onBeforeLoad : function() {
+    addCls : function(className) {
         var me = this;
-
-        if (!me.disabled && !me.loading && me.fireEvent('beforeshow', me, me.el, me.store) !== false) {
-            if (me.useMsg) {
-                me.el.mask(me.msg, me.msgCls, false);
-            } else {
-                me.el.mask();
-            }
-            
-            me.fireEvent('show', me, me.el, me.store);
-            me.loading = true;
+        if (!className) {
+            return me;
+        }
+        if (!Ext.isArray(className)){
+            className = className.replace(me.trimRe, '').split(me.spacesRe);
+        }
+        if (me.rendered) {
+            me.el.addCls(className);
+        }
+        else {
+            me.additionalCls = Ext.Array.unique(me.additionalCls.concat(className));
         }
+        return me;
     },
 
     
-    show: function() {
-        this.onBeforeLoad();
+    addClass : function() {
+        return this.addCls.apply(this, arguments);
     },
 
     
-    hide: function() {
-        this.onLoad();
+    removeCls : function(className) {
+        var me = this;
+
+        if (!className) {
+            return me;
+        }
+        if (!Ext.isArray(className)){
+            className = className.replace(me.trimRe, '').split(me.spacesRe);
+        }
+        if (me.rendered) {
+            me.el.removeCls(className);
+        }
+        else if (me.additionalCls.length) {
+            Ext.each(className, function(cls) {
+                Ext.Array.remove(me.additionalCls, cls);
+            });
+        }
+        return me;
     },
 
-    
-    destroy : function() {
-        this.hide();
-        this.clearListeners();
-    }
-});
 
+    addOverCls: function() {
+        var me = this;
+        if (!me.disabled) {
+            me.el.addCls(me.overCls);
+        }
+    },
 
-Ext.define('Ext.ComponentLoader', {
+    removeOverCls: function() {
+        this.el.removeCls(this.overCls);
+    },
 
-    
-    
-    extend: 'Ext.ElementLoader',
+    addListener : function(element, listeners, scope, options) {
+        var me = this,
+            fn,
+            option;
 
-    statics: {
-        Renderer: {
-            Data: function(loader, response, active){
-                var success = true;
-                try {
-                    loader.getTarget().update(Ext.decode(response.responseText));
-                } catch (e) {
-                    success = false;
-                }
-                return success;
-            },
+        if (Ext.isString(element) && (Ext.isObject(listeners) || options && options.element)) {
+            if (options.element) {
+                fn = listeners;
 
-            Component: function(loader, response, active){
-                var success = true,
-                    target = loader.getTarget(),
-                    items = [];
+                listeners = {};
+                listeners[element] = fn;
+                element = options.element;
+                if (scope) {
+                    listeners.scope = scope;
+                }
 
-                if (!target.isContainer) {
-                    Ext.Error.raise({
-                        target: target,
-                        msg: 'Components can only be loaded into a container'
-                    });
+                for (option in options) {
+                    if (options.hasOwnProperty(option)) {
+                        if (me.eventOptionsRe.test(option)) {
+                            listeners[option] = options[option];
+                        }
+                    }
                 }
+            }
 
-                try {
-                    items = Ext.decode(response.responseText);
-                } catch (e) {
-                    success = false;
+            
+            
+            if (me[element] && me[element].on) {
+                me.mon(me[element], listeners);
+            } else {
+                me.afterRenderEvents = me.afterRenderEvents || {};
+                if (!me.afterRenderEvents[element]) {
+                    me.afterRenderEvents[element] = [];
                 }
+                me.afterRenderEvents[element].push(listeners);
+            }
+        }
 
-                if (success) {
-                    if (active.removeAll) {
-                        target.removeAll();
+        return me.mixins.observable.addListener.apply(me, arguments);
+    },
+
+    
+    removeManagedListenerItem: function(isClear, managedListener, item, ename, fn, scope){
+        var me = this,
+            element = managedListener.options ? managedListener.options.element : null;
+
+        if (element) {
+            element = me[element];
+            if (element && element.un) {
+                if (isClear || (managedListener.item === item && managedListener.ename === ename && (!fn || managedListener.fn === fn) && (!scope || managedListener.scope === scope))) {
+                    element.un(managedListener.ename, managedListener.fn, managedListener.scope);
+                    if (!isClear) {
+                        Ext.Array.remove(me.managedListeners, managedListener);
                     }
-                    target.add(items);
                 }
-                return success;
             }
+        } else {
+            return me.mixins.observable.removeManagedListenerItem.apply(me, arguments);
         }
     },
 
     
+    getBubbleTarget : function() {
+        return this.ownerCt;
+    },
 
     
-    target: null,
+    isFloating : function() {
+        return this.floating;
+    },
 
     
-    loadMask: false,
-    
-    
+    isDraggable : function() {
+        return !!this.draggable;
+    },
 
     
-    renderer: 'html',
-
-    
-    setTarget: function(target){
-        var me = this;
-        
-        if (Ext.isString(target)) {
-            target = Ext.getCmp(target);
-        }
-
-        if (me.target && me.target != target) {
-            me.abort();
-        }
-        me.target = target;
+    isDroppable : function() {
+        return !!this.droppable;
     },
+
     
-    
-    removeMask: function(){
-        this.target.setLoading(false);
+    onAdded : function(container, pos) {
+        this.ownerCt = container;
+        this.fireEvent('added', this, container, pos);
     },
+
     
-    
-    addMask: function(mask){
-        this.target.setLoading(mask);
+    onRemoved : function() {
+        var me = this;
+
+        me.fireEvent('removed', me, me.ownerCt);
+        delete me.ownerCt;
     },
 
     
+    beforeDestroy : Ext.emptyFn,
     
-    setOptions: function(active, options){
-        active.removeAll = Ext.isDefined(options.removeAll) ? options.removeAll : this.removeAll;
-    },
+    
+    onResize : Ext.emptyFn,
 
     
-    getRenderer: function(renderer){
-        if (Ext.isFunction(renderer)) {
-            return renderer;
+    setSize : function(width, height) {
+        var me = this,
+            layoutCollection;
+
+        
+        if (Ext.isObject(width)) {
+            height = width.height;
+            width  = width.width;
         }
 
-        var renderers = this.statics().Renderer;
-        switch (renderer) {
-            case 'component':
-                return renderers.Component;
-            case 'data':
-                return renderers.Data;
-            default:
-                return Ext.ElementLoader.Renderer.Html;
+        
+        if (Ext.isNumber(width)) {
+            width = Ext.Number.constrain(width, me.minWidth, me.maxWidth);
+        }
+        if (Ext.isNumber(height)) {
+            height = Ext.Number.constrain(height, me.minHeight, me.maxHeight);
         }
-    }
-});
 
+        if (!me.rendered || !me.isVisible()) {
+            
+            if (me.hiddenAncestor) {
+                layoutCollection = me.hiddenAncestor.layoutOnShow;
+                layoutCollection.remove(me);
+                layoutCollection.add(me);
+            }
+            me.needsLayout = {
+                width: width,
+                height: height,
+                isSetSize: true
+            };
+            if (!me.rendered) {
+                me.width  = (width !== undefined) ? width : me.width;
+                me.height = (height !== undefined) ? height : me.height;
+            }
+            return me;
+        }
+        me.doComponentLayout(width, height, true);
 
+        return me;
+    },
 
-Ext.define('Ext.layout.component.Auto', {
+    isFixedWidth: function() {
+        var me = this,
+            layoutManagedWidth = me.layoutManagedWidth;
 
-    
+        if (Ext.isDefined(me.width) || layoutManagedWidth == 1) {
+            return true;
+        }
+        if (layoutManagedWidth == 2) {
+            return false;
+        }
+        return (me.ownerCt && me.ownerCt.isFixedWidth());
+    },
 
-    alias: 'layout.autocomponent',
+    isFixedHeight: function() {
+        var me = this,
+            layoutManagedHeight = me.layoutManagedHeight;
 
-    extend: 'Ext.layout.component.Component',
+        if (Ext.isDefined(me.height) || layoutManagedHeight == 1) {
+            return true;
+        }
+        if (layoutManagedHeight == 2) {
+            return false;
+        }
+        return (me.ownerCt && me.ownerCt.isFixedHeight());
+    },
 
-    
+    setCalculatedSize : function(width, height, callingContainer) {
+        var me = this,
+            layoutCollection;
 
-    type: 'autocomponent',
+        
+        if (Ext.isObject(width)) {
+            callingContainer = width.ownerCt;
+            height = width.height;
+            width  = width.width;
+        }
 
-    onLayout : function(width, height) {
-        this.setTargetSize(width, height);
-    }
-});
+        
+        if (Ext.isNumber(width)) {
+            width = Ext.Number.constrain(width, me.minWidth, me.maxWidth);
+        }
+        if (Ext.isNumber(height)) {
+            height = Ext.Number.constrain(height, me.minHeight, me.maxHeight);
+        }
 
+        if (!me.rendered || !me.isVisible()) {
+            
+            if (me.hiddenAncestor) {
+                layoutCollection = me.hiddenAncestor.layoutOnShow;
+                layoutCollection.remove(me);
+                layoutCollection.add(me);
+            }
+            me.needsLayout = {
+                width: width,
+                height: height,
+                isSetSize: false,
+                ownerCt: callingContainer
+            };
+            return me;
+        }
+        me.doComponentLayout(width, height, false, callingContainer);
 
-Ext.define('Ext.AbstractComponent', {
+        return me;
+    },
 
     
+    doComponentLayout : function(width, height, isSetSize, callingContainer) {
+        var me = this,
+            componentLayout = me.getComponentLayout(),
+            lastComponentSize = componentLayout.lastComponentSize || {
+                width: undefined,
+                height: undefined
+            };
 
-    mixins: {
-        observable: 'Ext.util.Observable',
-        animate: 'Ext.util.Animate',
-        state: 'Ext.state.Stateful'
-    },
+        
+        
+        
+        if (me.rendered && componentLayout) {
+            
+            if (!Ext.isDefined(width)) {
+                if (me.isFixedWidth()) {
+                    width = Ext.isDefined(me.width) ? me.width : lastComponentSize.width;
+                }
+            }
+            
+            if (!Ext.isDefined(height)) {
+                if (me.isFixedHeight()) {
+                    height = Ext.isDefined(me.height) ? me.height : lastComponentSize.height;
+                }
+            }
 
-    requires: [
-        'Ext.PluginManager',
-        'Ext.ComponentManager',
-        'Ext.core.Element',
-        'Ext.core.DomHelper',
-        'Ext.XTemplate',
-        'Ext.ComponentQuery',
-        'Ext.LoadMask',
-        'Ext.ComponentLoader',
-        'Ext.EventManager',
-        'Ext.layout.Layout',
-        'Ext.layout.component.Auto'
-    ],
+            if (isSetSize) {
+                me.width = width;
+                me.height = height;
+            }
 
-    
-    
-    uses: [
-        'Ext.ZIndexManager'
-    ],
+            componentLayout.layout(width, height, isSetSize, callingContainer);
+        }
 
-    statics: {
-        AUTO_ID: 1000
+        return me;
     },
 
     
+    forceComponentLayout: function () {
+        this.doComponentLayout();
+    },
 
-    isComponent: true,
+    
+    setComponentLayout : function(layout) {
+        var currentLayout = this.componentLayout;
+        if (currentLayout && currentLayout.isLayout && currentLayout != layout) {
+            currentLayout.setOwner(null);
+        }
+        this.componentLayout = layout;
+        layout.setOwner(this);
+    },
 
-    getAutoId: function() {
-        return ++Ext.AbstractComponent.AUTO_ID;
+    getComponentLayout : function() {
+        var me = this;
+
+        if (!me.componentLayout || !me.componentLayout.isLayout) {
+            me.setComponentLayout(Ext.layout.Layout.create(me.componentLayout, 'autocomponent'));
+        }
+        return me.componentLayout;
     },
 
     
+    afterComponentLayout: function(width, height, isSetSize, callingContainer) {
+        var me = this,
+            layout = me.componentLayout,
+            oldSize = me.preLayoutSize;
 
-    
+        ++me.componentLayoutCounter;
+        if (!oldSize || ((width !== oldSize.width) || (height !== oldSize.height))) {
+            me.fireEvent('resize', me, width, height);
+        }
+    },
 
     
+    beforeComponentLayout: function(width, height, isSetSize, callingContainer) {
+        this.preLayoutSize = this.componentLayout.lastComponentSize;
+        return true;
+    },
 
     
+    setPosition : function(x, y) {
+        var me = this;
 
-    
-    renderTpl: null,
+        if (Ext.isObject(x)) {
+            y = x.y;
+            x = x.x;
+        }
 
-    
+        if (!me.rendered) {
+            return me;
+        }
 
-    
+        if (x !== undefined || y !== undefined) {
+            me.el.setBox(x, y);
+            me.onPosition(x, y);
+            me.fireEvent('move', me, x, y);
+        }
+        return me;
+    },
 
     
+    onPosition: Ext.emptyFn,
 
     
+    setWidth : function(width) {
+        return this.setSize(width);
+    },
 
     
+    setHeight : function(height) {
+        return this.setSize(undefined, height);
+    },
 
     
+    getSize : function() {
+        return this.el.getSize();
+    },
 
     
+    getWidth : function() {
+        return this.el.getWidth();
+    },
 
     
-    tplWriteMode: 'overwrite',
+    getHeight : function() {
+        return this.el.getHeight();
+    },
 
     
-    baseCls: Ext.baseCSSPrefix + 'component',
+    getLoader: function(){
+        var me = this,
+            autoLoad = me.autoLoad ? (Ext.isObject(me.autoLoad) ? me.autoLoad : {url: me.autoLoad}) : null,
+            loader = me.loader || autoLoad;
 
-    
+        if (loader) {
+            if (!loader.isLoader) {
+                me.loader = Ext.create('Ext.ComponentLoader', Ext.apply({
+                    target: me,
+                    autoLoad: autoLoad
+                }, loader));
+            } else {
+                loader.setTarget(me);
+            }
+            return me.loader;
 
-    
+        }
+        return null;
+    },
 
     
+    setLoading : function(load, targetEl) {
+        var me = this,
+            config;
 
-    
-    disabledCls: Ext.baseCSSPrefix + 'item-disabled',
+        if (me.rendered) {
+            if (load !== false && !me.collapsed) {
+                if (Ext.isObject(load)) {
+                    config = load;
+                }
+                else if (Ext.isString(load)) {
+                    config = {msg: load};
+                }
+                else {
+                    config = {};
+                }
+                me.loadMask = me.loadMask || Ext.create('Ext.LoadMask', targetEl ? me.getTargetEl() : me.el, config);
+                me.loadMask.show();
+            } else if (me.loadMask) {
+                Ext.destroy(me.loadMask);
+                me.loadMask = null;
+            }
+        }
 
-    
-    ui: 'default',
-    
-    
-    uiCls: [],
-    
-    
+        return me.loadMask;
+    },
 
     
+    setDocked : function(dock, layoutParent) {
+        var me = this;
 
-    
+        me.dock = dock;
+        if (layoutParent && me.ownerCt && me.rendered) {
+            me.ownerCt.doComponentLayout();
+        }
+        return me;
+    },
 
-    
+    onDestroy : function() {
+        var me = this;
 
-    
+        if (me.monitorResize && Ext.EventManager.resizeEvent) {
+            Ext.EventManager.resizeEvent.removeListener(me.setSize, me);
+        }
+        
+        Ext.destroy(
+            me.componentLayout,
+            me.loadMask,
+            me.floatingItems
+        );
+    },
 
     
+    cleanElementRefs: function(){
+        var me = this,
+            i = 0,
+            childEls = me.childEls,
+            selectors = me.renderSelectors,
+            selector,
+            name,
+            len;
 
-    
-    hidden: false,
+        if (me.rendered) {
+            if (childEls) {
+                for (len = childEls.length; i < len; ++i) {
+                    name = childEls[i];
+                    if (typeof(name) != 'string') {
+                        name = name.name;
+                    }
+                    delete me[name];
+                }
+            }
 
-    
-    disabled: false,
+            if (selectors) {
+                for (selector in selectors) {
+                    if (selectors.hasOwnProperty(selector)) {
+                        delete me[selector];
+                    }
+                }
+            }
+        }
+        delete me.rendered;
+        delete me.el;
+        delete me.frameBody;
+    },
 
     
+    destroy : function() {
+        var me = this;
 
-    
-    draggable: false,
+        if (!me.isDestroyed) {
+            if (me.fireEvent('beforedestroy', me) !== false) {
+                me.destroying = true;
+                me.beforeDestroy();
 
-    
-    floating: false,
+                if (me.floating) {
+                    delete me.floatParent;
+                    
+                    
+                    if (me.zIndexManager) {
+                        me.zIndexManager.unregister(me);
+                    }
+                } else if (me.ownerCt && me.ownerCt.remove) {
+                    me.ownerCt.remove(me, false);
+                }
 
-    
-    hideMode: 'display',
+                me.onDestroy();
 
-    
+                
+                Ext.destroy(me.plugins);
 
-    
+                if (me.rendered) {
+                    me.el.remove();
+                }
 
-    
-    styleHtmlContent: false,
+                me.fireEvent('destroy', me);
+                Ext.ComponentManager.unregister(me);
+
+                me.mixins.state.destroy.call(me);
+
+                me.clearListeners();
+                
+                me.cleanElementRefs();
+                me.destroying = false;
+                me.isDestroyed = true;
+            }
+        }
+    },
 
     
-    styleHtmlCls: Ext.baseCSSPrefix + 'html',
+    getPlugin: function(pluginId) {
+        var i = 0,
+            plugins = this.plugins,
+            ln = plugins.length;
+        for (; i < ln; i++) {
+            if (plugins[i].pluginId === pluginId) {
+                return plugins[i];
+            }
+        }
+    },
 
     
+    isDescendantOf: function(container) {
+        return !!this.findParentBy(function(p){
+            return p === container;
+        });
+    }
+}, function() {
+    this.createAlias({
+        on: 'addListener',
+        prev: 'previousSibling',
+        next: 'nextSibling'
+    });
+});
+
+
+Ext.define('Ext.AbstractPlugin', {
+    disabled: false,
+
+    constructor: function(config) {
+        Ext.apply(this, config);
+    },
+
+    getCmp: function() {
+        return this.cmp;
+    },
+
     
+    init: Ext.emptyFn,
+
     
+    destroy: Ext.emptyFn,
+
     
+    enable: function() {
+        this.disabled = false;
+    },
 
     
+    disable: function() {
+        this.disabled = true;
+    }
+});
 
-     
-     allowDomMove: true,
+Ext.define('Ext.data.Connection', {
+    mixins: {
+        observable: 'Ext.util.Observable'
+    },
 
-     
-     autoShow: false,
+    statics: {
+        requestId: 0
+    },
 
-    
-     autoRender: false,
+    url: null,
+    async: true,
+    method: null,
+    username: '',
+    password: '',
 
-     needsLayout: false,
+    
+    disableCaching: true,
 
     
+    withCredentials: false,
 
     
-    rendered: false,
+    cors: false,
 
-    weight: 0,
+    
+    disableCachingParam: '_dc',
 
-    trimRe: /^\s+|\s+$/g,
-    spacesRe: /\s+/,
     
+    timeout : 30000,
+
     
-         
-    maskOnDisable: true,
 
-    constructor : function(config) {
-        var me = this,
-            i, len;
+    useDefaultHeader : true,
+    defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8',
+    useDefaultXhrHeader : true,
+    defaultXhrHeader : 'XMLHttpRequest',
 
+    constructor : function(config) {
         config = config || {};
-        me.initialConfig = config;
-        Ext.apply(me, config);
+        Ext.apply(this, config);
 
-        me.addEvents(
-            
-             'beforeactivate',
-            
-             'activate',
-            
-             'beforedeactivate',
-            
-             'deactivate',
-            
-             'added',
-            
-             'disable',
-            
-             'enable',
-            
-             'beforeshow',
-            
-             'show',
-            
-             'beforehide',
-            
-             'hide',
-            
-             'removed',
-            
-             'beforerender',
-            
-             'render',
-            
-             'afterrender',
-            
-             'beforedestroy',
+        this.addEvents(
             
-             'destroy',
+            'beforerequest',
             
-             'resize',
+            'requestcomplete',
             
-             'move'
+            'requestexception'
         );
+        this.requests = {};
+        this.mixins.observable.constructor.call(this);
+    },
 
-        me.getId();
+    
+    request : function(options) {
+        options = options || {};
+        var me = this,
+            scope = options.scope || window,
+            username = options.username || me.username,
+            password = options.password || me.password || '',
+            async,
+            requestOptions,
+            request,
+            headers,
+            xhr;
 
-        me.mons = [];
-        me.additionalCls = [];
-        me.renderData = me.renderData || {};
-        me.renderSelectors = me.renderSelectors || {};
+        if (me.fireEvent('beforerequest', me, options) !== false) {
 
-        if (me.plugins) {
-            me.plugins = [].concat(me.plugins);
-            for (i = 0, len = me.plugins.length; i < len; i++) {
-                me.plugins[i] = me.constructPlugin(me.plugins[i]);
-            }
-        }
-        
-        me.initComponent();
+            requestOptions = me.setOptions(options, scope);
 
-        
-        Ext.ComponentManager.register(me);
+            if (this.isFormUpload(options) === true) {
+                this.upload(options.form, requestOptions.url, requestOptions.data, options);
+                return null;
+            }
 
-        
-        me.mixins.observable.constructor.call(me);
-        me.mixins.state.constructor.call(me, config);
+            
+            if (options.autoAbort === true || me.autoAbort) {
+                me.abort();
+            }
 
-        
-        if (me.plugins) {
-            me.plugins = [].concat(me.plugins);
-            for (i = 0, len = me.plugins.length; i < len; i++) {
-                me.plugins[i] = me.initPlugin(me.plugins[i]);
+            
+
+            if ((options.cors === true || me.cors === true) && Ext.isIe && Ext.ieVersion >= 8) {
+                xhr = new XDomainRequest();
+            } else {
+                xhr = this.getXhrInstance();
             }
-        }
 
-        me.loader = me.getLoader();
+            async = options.async !== false ? (options.async || me.async) : false;
 
-        if (me.renderTo) {
-            me.render(me.renderTo);
-        }
+            
+            if (username) {
+                xhr.open(requestOptions.method, requestOptions.url, async, username, password);
+            } else {
+                xhr.open(requestOptions.method, requestOptions.url, async);
+            }
 
-        if (me.autoShow) {
-            me.show();
-        }
-        
-        if (Ext.isDefined(me.disabledClass)) {
-            if (Ext.isDefined(Ext.global.console)) {
-                Ext.global.console.warn('Ext.Component: disabledClass has been deprecated. Please use disabledCls.');
+            if (options.withCredentials === true || me.withCredentials === true) {
+                xhr.withCredentials = true;
+            }
+
+            headers = me.setupHeaders(xhr, options, requestOptions.data, requestOptions.params);
+
+            
+            request = {
+                id: ++Ext.data.Connection.requestId,
+                xhr: xhr,
+                headers: headers,
+                options: options,
+                async: async,
+                timeout: setTimeout(function() {
+                    request.timedout = true;
+                    me.abort(request);
+                }, options.timeout || me.timeout)
+            };
+            me.requests[request.id] = request;
+            me.latestId = request.id;
+            
+            if (async) {
+                xhr.onreadystatechange = Ext.Function.bind(me.onStateChange, me, [request]);
+            }
+
+            
+            xhr.send(requestOptions.data);
+            if (!async) {
+                return this.onComplete(request);
             }
-            me.disabledCls = me.disabledClass;
-            delete me.disabledClass;
+            return request;
+        } else {
+            Ext.callback(options.callback, options.scope, [options, undefined, undefined]);
+            return null;
         }
     },
 
-    initComponent: Ext.emptyFn,
+    
+    upload: function(form, url, params, options) {
+        form = Ext.getDom(form);
+        options = options || {};
 
-    show: Ext.emptyFn,
+        var id = Ext.id(),
+                frame = document.createElement('iframe'),
+                hiddens = [],
+                encoding = 'multipart/form-data',
+                buf = {
+                    target: form.target,
+                    method: form.method,
+                    encoding: form.encoding,
+                    enctype: form.enctype,
+                    action: form.action
+                }, hiddenItem;
 
-    animate: function(animObj) {
-        var me = this,
-            to;
+        
+        Ext.fly(frame).set({
+            id: id,
+            name: id,
+            cls: Ext.baseCSSPrefix + 'hide-display',
+            src: Ext.SSL_SECURE_URL
+        });
 
-        animObj = animObj || {};
-        to = animObj.to || {};
+        document.body.appendChild(frame);
 
-        if (Ext.fx.Manager.hasFxBlock(me.id)) {
-            return me;
+        
+        if (document.frames) {
+           document.frames[id].name = id;
         }
+
+        Ext.fly(form).set({
+            target: id,
+            method: 'POST',
+            enctype: encoding,
+            encoding: encoding,
+            action: url || buf.action
+        });
+
         
-        if (!animObj.dynamic && (to.height || to.width)) {
-            var curWidth = me.getWidth(),
-                w = curWidth,
-                curHeight = me.getHeight(),
-                h = curHeight,
-                needsResize = false;
+        if (params) {
+            Ext.iterate(Ext.Object.fromQueryString(params), function(name, value){
+                hiddenItem = document.createElement('input');
+                Ext.fly(hiddenItem).set({
+                    type: 'hidden',
+                    value: value,
+                    name: name
+                });
+                form.appendChild(hiddenItem);
+                hiddens.push(hiddenItem);
+            });
+        }
 
-            if (to.height && to.height > curHeight) {
-                h = to.height;
-                needsResize = true;
-            }
-            if (to.width && to.width > curWidth) {
-                w = to.width;
-                needsResize = true;
-            }
+        Ext.fly(frame).on('load', Ext.Function.bind(this.onUploadComplete, this, [frame, options]), null, {single: true});
+        form.submit();
 
+        Ext.fly(form).set(buf);
+        Ext.each(hiddens, function(h) {
+            Ext.removeNode(h);
+        });
+    },
+
+    
+    onUploadComplete: function(frame, options) {
+        var me = this,
             
-            
-            
-            if (needsResize) {
-                var clearWidth = !Ext.isNumber(me.width),
-                    clearHeight = !Ext.isNumber(me.height);
+            response = {
+                responseText: '',
+                responseXML: null
+            }, doc, firstChild;
 
-                me.componentLayout.childrenChanged = true;
-                me.setSize(w, h, me.ownerCt);
-                me.el.setSize(curWidth, curHeight);
-                if (clearWidth) {
-                    delete me.width;
-                }
-                if (clearHeight) {
-                    delete me.height;
+        try {
+            doc = frame.contentWindow.document || frame.contentDocument || window.frames[frame.id].document;
+            if (doc) {
+                if (doc.body) {
+                    if (/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)) { 
+                        response.responseText = firstChild.value;
+                    } else {
+                        response.responseText = doc.body.innerHTML;
+                    }
                 }
+                
+                response.responseXML = doc.XMLDocument || doc;
             }
+        } catch (e) {
         }
-        return me.mixins.animate.animate.apply(me, arguments);
+
+        me.fireEvent('requestcomplete', me, response, options);
+
+        Ext.callback(options.success, options.scope, [response, options]);
+        Ext.callback(options.callback, options.scope, [options, true, response]);
+
+        setTimeout(function(){
+            Ext.removeNode(frame);
+        }, 100);
     },
 
     
-    findLayoutController: function() {
-        return this.findParentBy(function(c) {
-            
-            
-            return !c.ownerCt || (c.layout.layoutBusy && !c.ownerCt.layout.layoutBusy);
-        });
+    isFormUpload: function(options){
+        var form = this.getForm(options);
+        if (form) {
+            return (options.isUpload || (/multipart\/form-data/i).test(form.getAttribute('enctype')));
+        }
+        return false;
     },
 
-    onShow : function() {
-        
-        var needsLayout = this.needsLayout;
-        if (Ext.isObject(needsLayout)) {
-            this.doComponentLayout(needsLayout.width, needsLayout.height, needsLayout.isSetSize, needsLayout.ownerCt);
-        }
+    
+    getForm: function(options){
+        return Ext.getDom(options.form) || null;
     },
 
-    constructPlugin: function(plugin) {
-        if (plugin.ptype && typeof plugin.init != 'function') {
-            plugin.cmp = this;
-            plugin = Ext.PluginManager.create(plugin);
+    
+    setOptions: function(options, scope){
+        var me =  this,
+            params = options.params || {},
+            extraParams = me.extraParams,
+            urlParams = options.urlParams,
+            url = options.url || me.url,
+            jsonData = options.jsonData,
+            method,
+            disableCache,
+            data;
+
+
+        
+        if (Ext.isFunction(params)) {
+            params = params.call(scope, options);
         }
-        else if (typeof plugin == 'string') {
-            plugin = Ext.PluginManager.create({
-                ptype: plugin,
-                cmp: this
-            });
+
+        
+        if (Ext.isFunction(url)) {
+            url = url.call(scope, options);
         }
-        return plugin;
-    },
 
+        url = this.setupUrl(options, url);
 
-    
-    initPlugin : function(plugin) {
-        plugin.init(this);
 
-        return plugin;
-    },
+        
+        data = options.rawData || options.xmlData || jsonData || null;
+        if (jsonData && !Ext.isPrimitive(jsonData)) {
+            data = Ext.encode(data);
+        }
 
-    
-    doAutoRender: function() {
-        var me = this;
-        if (me.floating) {
-            me.render(document.body);
-        } else {
-            me.render(Ext.isBoolean(me.autoRender) ? Ext.getBody() : me.autoRender);
+        
+        if (Ext.isObject(params)) {
+            params = Ext.Object.toQueryString(params);
         }
-    },
 
-    
-    render : function(container, position) {
-        var me = this;
+        if (Ext.isObject(extraParams)) {
+            extraParams = Ext.Object.toQueryString(extraParams);
+        }
 
-        if (!me.rendered && me.fireEvent('beforerender', me) !== false) {
-            
-            
-            if (me.el) {
-                me.el = Ext.get(me.el);
-            }
+        params = params + ((extraParams) ? ((params) ? '&' : '') + extraParams : '');
 
-            
-            if (me.floating) {
-                me.onFloatRender();
-            }
+        urlParams = Ext.isObject(urlParams) ? Ext.Object.toQueryString(urlParams) : urlParams;
 
-            container = me.initContainer(container);
+        params = this.setupParams(options, params);
 
-            me.onRender(container, position);
+        
+        method = (options.method || me.method || ((params || data) ? 'POST' : 'GET')).toUpperCase();
+        this.setupMethod(options, method);
 
-            
-            
-            me.el.setVisibilityMode(Ext.core.Element[me.hideMode.toUpperCase()]);
 
-            if (me.overCls) {
-                me.el.hover(me.addOverCls, me.removeOverCls, me);
-            }
+        disableCache = options.disableCaching !== false ? (options.disableCaching || me.disableCaching) : false;
+        
+        if (method === 'GET' && disableCache) {
+            url = Ext.urlAppend(url, (options.disableCachingParam || me.disableCachingParam) + '=' + (new Date().getTime()));
+        }
 
-            me.fireEvent('render', me);
+        
+        if ((method == 'GET' || data) && params) {
+            url = Ext.urlAppend(url, params);
+            params = null;
+        }
 
-            me.initContent();
+        
+        if (urlParams) {
+            url = Ext.urlAppend(url, urlParams);
+        }
 
-            me.afterRender(container);
-            me.fireEvent('afterrender', me);
+        return {
+            url: url,
+            method: method,
+            data: data || params || null
+        };
+    },
 
-            me.initEvents();
+    
+    setupUrl: function(options, url){
+        var form = this.getForm(options);
+        if (form) {
+            url = url || form.action;
+        }
+        return url;
+    },
 
-            if (me.hidden) {
-                
-                
-                
-                me.el.hide();
-            }
 
-            if (me.disabled) {
-                
-                me.disable(true);
-            }
+    
+    setupParams: function(options, params) {
+        var form = this.getForm(options),
+            serializedForm;
+        if (form && !this.isFormUpload(options)) {
+            serializedForm = Ext.Element.serializeForm(form);
+            params = params ? (params + '&' + serializedForm) : serializedForm;
         }
-        return me;
+        return params;
     },
 
     
-    onRender : function(container, position) {
-        var me = this,
-            el = me.el,
-            cls = me.initCls(),
-            styles = me.initStyles(),
-            renderTpl, renderData, i;
+    setupMethod: function(options, method){
+        if (this.isFormUpload(options)) {
+            return 'POST';
+        }
+        return method;
+    },
 
-        position = me.getInsertPosition(position);
+    
+    setupHeaders: function(xhr, options, data, params){
+        var me = this,
+            headers = Ext.apply({}, options.headers || {}, me.defaultHeaders || {}),
+            contentType = me.defaultPostHeader,
+            jsonData = options.jsonData,
+            xmlData = options.xmlData,
+            key,
+            header;
 
-        if (!el) {
-            if (position) {
-                el = Ext.core.DomHelper.insertBefore(position, me.getElConfig(), true);
-            }
-            else {
-                el = Ext.core.DomHelper.append(container, me.getElConfig(), true);
+        if (!headers['Content-Type'] && (data || params)) {
+            if (data) {
+                if (options.rawData) {
+                    contentType = 'text/plain';
+                } else {
+                    if (xmlData && Ext.isDefined(xmlData)) {
+                        contentType = 'text/xml';
+                    } else if (jsonData && Ext.isDefined(jsonData)) {
+                        contentType = 'application/json';
+                    }
+                }
             }
+            headers['Content-Type'] = contentType;
         }
-        else if (me.allowDomMove !== false) {
-            if (position) {
-                container.dom.insertBefore(el.dom, position);
-            } else {
-                container.dom.appendChild(el.dom);
-            }
+
+        if (me.useDefaultXhrHeader && !headers['X-Requested-With']) {
+            headers['X-Requested-With'] = me.defaultXhrHeader;
         }
+        
+        try{
+            for (key in headers) {
+                if (headers.hasOwnProperty(key)) {
+                    header = headers[key];
+                    xhr.setRequestHeader(key, header);
+                }
 
-        if (Ext.scopeResetCSS && !me.ownerCt) {
-            
-            if (el.dom == Ext.getBody().dom) {
-                el.parent().addCls(Ext.baseCSSPrefix + 'reset');
-            }
-            else {
-                
-                me.resetEl = el.wrap({
-                    cls: Ext.baseCSSPrefix + 'reset'
-                });
             }
+        } catch(e) {
+            me.fireEvent('exception', key, header);
         }
+        return headers;
+    },
 
-        el.addCls(cls);
-        el.setStyle(styles);
-
-        
-        
-        
-        
-        
-        
-        
-        
-        
-        
+    
+    getXhrInstance: (function(){
+        var options = [function(){
+            return new XMLHttpRequest();
+        }, function(){
+            return new ActiveXObject('MSXML2.XMLHTTP.3.0');
+        }, function(){
+            return new ActiveXObject('MSXML2.XMLHTTP');
+        }, function(){
+            return new ActiveXObject('Microsoft.XMLHTTP');
+        }], i = 0,
+            len = options.length,
+            xhr;
 
-        me.el = el;
-        
-        me.rendered = true;
-        me.addUIToElement(true);
-        
-        for (i = 0; i < me.uiCls.length; i++) {
-            me.addUIClsToElement(me.uiCls[i], true);
+        for(; i < len; ++i) {
+            try{
+                xhr = options[i];
+                xhr();
+                break;
+            }catch(e){}
         }
-        me.rendered = false;
-        me.initFrame();
+        return xhr;
+    })(),
 
-        renderTpl = me.initRenderTpl();
-        if (renderTpl) {
-            renderData = me.initRenderData();
-            renderTpl.append(me.getTargetEl(), renderData);
+    
+    isLoading : function(request) {
+        if (!request) {
+            request = this.getLatest();
+        }
+        if (!(request && request.xhr)) {
+            return false;
         }
-
-        me.applyRenderSelectors();
-        
-        me.rendered = true;
         
-        me.setUI(me.ui);
+        var state = request.xhr.readyState;
+        return !(state === 0 || state == 4);
     },
 
     
-    afterRender : function() {
-        var me = this,
-            pos,
-            xy;
-
-        me.getComponentLayout();
-
+    abort : function(request) {
+        var me = this;
         
-        if (!me.ownerCt || (me.height || me.width)) {
-            me.setSize(me.width, me.height);
+        if (!request) {
+            request = me.getLatest();
         }
 
+        if (request && me.isLoading(request)) {
+            
+            request.xhr.onreadystatechange = null;
+            request.xhr.abort();
+            me.clearTimeout(request);
+            if (!request.timedout) {
+                request.aborted = true;
+            }
+            me.onComplete(request);
+            me.cleanup(request);
+        }
+    },
+    
+    
+    abortAll: function(){
+        var requests = this.requests,
+            id;
         
-        
-        if (me.floating && (me.x === undefined || me.y === undefined)) {
-            if (me.floatParent) {
-                xy = me.el.getAlignToXY(me.floatParent.getTargetEl(), 'c-c');
-                pos = me.floatParent.getTargetEl().translatePoints(xy[0], xy[1]);
-            } else {
-                xy = me.el.getAlignToXY(me.container, 'c-c');
-                pos = me.container.translatePoints(xy[0], xy[1]);
+        for (id in requests) {
+            if (requests.hasOwnProperty(id)) {
+                this.abort(requests[id]);
             }
-            me.x = me.x === undefined ? pos.left: me.x;
-            me.y = me.y === undefined ? pos.top: me.y;
         }
-
-        if (Ext.isDefined(me.x) || Ext.isDefined(me.y)) {
-            me.setPosition(me.x, me.y);
+    },
+    
+    
+    getLatest: function(){
+        var id = this.latestId,
+            request;
+            
+        if (id) {
+            request = this.requests[id];
         }
+        return request || null;
+    },
 
-        if (me.styleHtmlContent) {
-            me.getTargetEl().addCls(me.styleHtmlCls);
+    
+    onStateChange : function(request) {
+        if (request.xhr.readyState == 4) {
+            this.clearTimeout(request);
+            this.onComplete(request);
+            this.cleanup(request);
         }
     },
 
-    frameCls: Ext.baseCSSPrefix + 'frame',
+    
+    clearTimeout: function(request){
+        clearTimeout(request.timeout);
+        delete request.timeout;
+    },
 
-    frameTpl: [
-        '<tpl if="top">',
-            '<tpl if="left"><div class="{frameCls}-tl {baseCls}-tl {baseCls}-{ui}-tl<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tl</tpl></tpl>" style="background-position: {tl}; padding-left: {frameWidth}px" role="presentation"></tpl>',
-                '<tpl if="right"><div class="{frameCls}-tr {baseCls}-tr {baseCls}-{ui}-tr<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tr</tpl></tpl>" style="background-position: {tr}; padding-right: {frameWidth}px" role="presentation"></tpl>',
-                    '<div class="{frameCls}-tc {baseCls}-tc {baseCls}-{ui}-tc<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tc</tpl></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 class="{frameCls}-ml {baseCls}-ml {baseCls}-{ui}-ml<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-ml</tpl></tpl>" style="background-position: {ml}; padding-left: {frameWidth}px" role="presentation"></tpl>',
-            '<tpl if="right"><div class="{frameCls}-mr {baseCls}-mr {baseCls}-{ui}-mr<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mr</tpl></tpl>" style="background-position: {mr}; padding-right: {frameWidth}px" role="presentation"></tpl>',
-                '<div class="{frameCls}-mc {baseCls}-mc {baseCls}-{ui}-mc<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mc</tpl></tpl>" role="presentation"></div>',
-            '<tpl if="right"></div></tpl>',
-        '<tpl if="left"></div></tpl>',
-        '<tpl if="bottom">',
-            '<tpl if="left"><div class="{frameCls}-bl {baseCls}-bl {baseCls}-{ui}-bl<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bl</tpl></tpl>" style="background-position: {bl}; padding-left: {frameWidth}px" role="presentation"></tpl>',
-                '<tpl if="right"><div class="{frameCls}-br {baseCls}-br {baseCls}-{ui}-br<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-br</tpl></tpl>" style="background-position: {br}; padding-right: {frameWidth}px" role="presentation"></tpl>',
-                    '<div class="{frameCls}-bc {baseCls}-bc {baseCls}-{ui}-bc<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bc</tpl></tpl>" style="background-position: {bc}; height: {frameWidth}px" role="presentation"></div>',
-                '<tpl if="right"></div></tpl>',
-            '<tpl if="left"></div></tpl>',
-        '</tpl>'
-    ],
+    
+    cleanup: function(request){
+        request.xhr = null;
+        delete request.xhr;
+    },
+
+    
+    onComplete : function(request) {
+        var me = this,
+            options = request.options,
+            result,
+            success,
+            response;
+
+        try {
+            result = me.parseStatus(request.xhr.status);
+        } catch (e) {
+            
+            result = {
+                success : false,
+                isException : false
+            };
+        }
+        success = result.success;
+
+        if (success) {
+            response = me.createResponse(request);
+            me.fireEvent('requestcomplete', me, response, options);
+            Ext.callback(options.success, options.scope, [response, options]);
+        } else {
+            if (result.isException || request.aborted || request.timedout) {
+                response = me.createException(request);
+            } else {
+                response = me.createResponse(request);
+            }
+            me.fireEvent('requestexception', me, response, options);
+            Ext.callback(options.failure, options.scope, [response, options]);
+        }
+        Ext.callback(options.callback, options.scope, [options, success, response]);
+        delete me.requests[request.id];
+        return response;
+    },
 
-    frameTableTpl: [
-        '<table><tbody>',
-            '<tpl if="top">',
-                '<tr>',
-                    '<tpl if="left"><td class="{frameCls}-tl {baseCls}-tl {baseCls}-{ui}-tl<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tl</tpl></tpl>" style="background-position: {tl}; padding-left:{frameWidth}px" role="presentation"></td></tpl>',
-                    '<td class="{frameCls}-tc {baseCls}-tc {baseCls}-{ui}-tc<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tc</tpl></tpl>" style="background-position: {tc}; height: {frameWidth}px" role="presentation"></td>',
-                    '<tpl if="right"><td class="{frameCls}-tr {baseCls}-tr {baseCls}-{ui}-tr<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-tr</tpl></tpl>" style="background-position: {tr}; padding-left: {frameWidth}px" role="presentation"></td></tpl>',
-                '</tr>',
-            '</tpl>',
-            '<tr>',
-                '<tpl if="left"><td class="{frameCls}-ml {baseCls}-ml {baseCls}-{ui}-ml<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-ml</tpl></tpl>" style="background-position: {ml}; padding-left: {frameWidth}px" role="presentation"></td></tpl>',
-                '<td class="{frameCls}-mc {baseCls}-mc {baseCls}-{ui}-mc<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mc</tpl></tpl>" style="background-position: 0 0;" role="presentation"></td>',
-                '<tpl if="right"><td class="{frameCls}-mr {baseCls}-mr {baseCls}-{ui}-mr<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-mr</tpl></tpl>" style="background-position: {mr}; padding-left: {frameWidth}px" role="presentation"></td></tpl>',
-            '</tr>',
-            '<tpl if="bottom">',
-                '<tr>',
-                    '<tpl if="left"><td class="{frameCls}-bl {baseCls}-bl {baseCls}-{ui}-bl<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bl</tpl></tpl>" style="background-position: {bl}; padding-left: {frameWidth}px" role="presentation"></td></tpl>',
-                    '<td class="{frameCls}-bc {baseCls}-bc {baseCls}-{ui}-bc<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-bc</tpl></tpl>" style="background-position: {bc}; height: {frameWidth}px" role="presentation"></td>',
-                    '<tpl if="right"><td class="{frameCls}-br {baseCls}-br {baseCls}-{ui}-br<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-{parent.ui}-{.}-br</tpl></tpl>" style="background-position: {br}; padding-left: {frameWidth}px" role="presentation"></td></tpl>',
-                '</tr>',
-            '</tpl>',
-        '</tbody></table>'
-    ],
     
+    parseStatus: function(status) {
+        
+        status = status == 1223 ? 204 : status;
+
+        var success = (status >= 200 && status < 300) || status == 304,
+            isException = false;
+
+        if (!success) {
+            switch (status) {
+                case 12002:
+                case 12029:
+                case 12030:
+                case 12031:
+                case 12152:
+                case 13030:
+                    isException = true;
+                    break;
+            }
+        }
+        return {
+            success: success,
+            isException: isException
+        };
+    },
+
     
-    initFrame : function() {
-        if (Ext.supports.CSS3BorderRadius) {
-            return false;
+    createResponse : function(request) {
+        var xhr = request.xhr,
+            headers = {},
+            lines = xhr.getAllResponseHeaders().replace(/\r\n/g, '\n').split('\n'),
+            count = lines.length,
+            line, index, key, value, response;
+
+        while (count--) {
+            line = lines[count];
+            index = line.indexOf(':');
+            if(index >= 0) {
+                key = line.substr(0, index).toLowerCase();
+                if (line.charAt(index + 1) == ' ') {
+                    ++index;
+                }
+                headers[key] = line.substr(index + 1);
+            }
         }
+
+        request.xhr = null;
+        delete request.xhr;
+
+        response = {
+            request: request,
+            requestId : request.id,
+            status : xhr.status,
+            statusText : xhr.statusText,
+            getResponseHeader : function(header){ return headers[header.toLowerCase()]; },
+            getAllResponseHeaders : function(){ return headers; },
+            responseText : xhr.responseText,
+            responseXML : xhr.responseXML
+        };
+
         
+        
+        xhr = null;
+        return response;
+    },
+
+    
+    createException : function(request) {
+        return {
+            request : request,
+            requestId : request.id,
+            status : request.aborted ? -1 : 0,
+            statusText : request.aborted ? 'transaction aborted' : 'communication failure',
+            aborted: request.aborted,
+            timedout: request.timedout
+        };
+    }
+});
+
+
+Ext.define('Ext.Ajax', {
+    extend: 'Ext.data.Connection',
+    singleton: true,
+
+    
+    
+    
+    
+    
+    
+
+    
+
+    
+    
+    
+    
+    
+    
+
+    
+    autoAbort : false
+});
+
+Ext.define('Ext.ElementLoader', {
+
+    
+
+    mixins: {
+        observable: 'Ext.util.Observable'
+    },
+
+    uses: [
+        'Ext.data.Connection',
+        'Ext.Ajax'
+    ],
+
+    statics: {
+        Renderer: {
+            Html: function(loader, response, active){
+                loader.getTarget().update(response.responseText, active.scripts === true);
+                return true;
+            }
+        }
+    },
+
+    
+
+    
+    url: null,
+
+    
+    params: null,
+
+    
+    baseParams: null,
+
+    
+    autoLoad: false,
+
+    
+    target: null,
+
+    
+    loadMask: false,
+
+    
+    ajaxOptions: null,
+
+    
+    scripts: false,
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    isLoader: true,
+
+    constructor: function(config) {
         var me = this,
-            frameInfo = me.getFrameInfo(),
-            frameWidth = frameInfo.width,
-            frameTpl = me.getFrameTpl(frameInfo.table);
-                        
-        if (me.frame) {
-            
-            frameTpl.insertFirst(me.el, Ext.apply({}, {
-                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)));
+            autoLoad;
 
+        config = config || {};
+        Ext.apply(me, config);
+        me.setTarget(me.target);
+        me.addEvents(
             
-            me.frameBody = me.el.down('.' + me.frameCls + '-mc');
+            'beforeload',
+
             
+            'exception',
+
             
-            Ext.apply(me.renderSelectors, {
-                frameTL: '.' + me.baseCls + '-tl',
-                frameTC: '.' + me.baseCls + '-tc',
-                frameTR: '.' + me.baseCls + '-tr',
-                frameML: '.' + me.baseCls + '-ml',
-                frameMC: '.' + me.baseCls + '-mc',
-                frameMR: '.' + me.baseCls + '-mr',
-                frameBL: '.' + me.baseCls + '-bl',
-                frameBC: '.' + me.baseCls + '-bc',
-                frameBR: '.' + me.baseCls + '-br'
-            });
+            'load'
+        );
+
+        
+        me.mixins.observable.constructor.call(me);
+
+        if (me.autoLoad) {
+            autoLoad = me.autoLoad;
+            if (autoLoad === true) {
+                autoLoad = {};
+            }
+            me.load(autoLoad);
         }
     },
+
     
-    updateFrame: function() {
-        if (Ext.supports.CSS3BorderRadius) {
-            return false;
+    setTarget: function(target){
+        var me = this;
+        target = Ext.get(target);
+        if (me.target && me.target != target) {
+            me.abort();
         }
-        
+        me.target = target;
+    },
+
+    
+    getTarget: function(){
+        return this.target || null;
+    },
+
+    
+    abort: function(){
+        var active = this.active;
+        if (active !== undefined) {
+            Ext.Ajax.abort(active.request);
+            if (active.mask) {
+                this.removeMask();
+            }
+            delete this.active;
+        }
+    },
+
+    
+    removeMask: function(){
+        this.target.unmask();
+    },
+
+    
+    addMask: function(mask){
+        this.target.mask(mask === true ? null : mask);
+    },
+
+    
+    load: function(options) {
+
+        options = Ext.apply({}, options);
+
         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) {                
-                
-                delete me.frameTL;
-                delete me.frameTC;
-                delete me.frameTR;
-                delete me.frameML;
-                delete me.frameMC;
-                delete me.frameMR;
-                delete me.frameBL;
-                delete me.frameBC;
-                delete me.frameBR;    
-                this.applyRenderSelectors();
-                
-                
-                newMCClassName = this.frameMC.dom.className;
-                
-                
-                oldFrameMC.insertAfter(this.frameMC);
-                this.frameMC.remove();
-                
-                
-                this.frameBody = this.frameMC = oldFrameMC;
-                
-                
-                oldFrameMC.dom.className = newMCClassName;
-                
-                
-                if (wasTable) {
-                    me.el.query('> table')[1].remove();
-                }                                
-                else {
-                    if (oldFrameTL) {
-                        oldFrameTL.remove();
-                    }
-                    if (oldFrameBL) {
-                        oldFrameBL.remove();
+            target = me.target,
+            mask = Ext.isDefined(options.loadMask) ? options.loadMask : me.loadMask,
+            params = Ext.apply({}, options.params),
+            ajaxOptions = Ext.apply({}, options.ajaxOptions),
+            callback = options.callback || me.callback,
+            scope = options.scope || me.scope || me,
+            request;
+
+        Ext.applyIf(ajaxOptions, me.ajaxOptions);
+        Ext.applyIf(options, ajaxOptions);
+
+        Ext.applyIf(params, me.params);
+        Ext.apply(params, me.baseParams);
+
+        Ext.applyIf(options, {
+            url: me.url
+        });
+
+
+        Ext.apply(options, {
+            scope: me,
+            params: params,
+            callback: me.onComplete
+        });
+
+        if (me.fireEvent('beforeload', me, options) === false) {
+            return;
+        }
+
+        if (mask) {
+            me.addMask(mask);
+        }
+
+        request = Ext.Ajax.request(options);
+        me.active = {
+            request: request,
+            options: options,
+            mask: mask,
+            scope: scope,
+            callback: callback,
+            success: options.success || me.success,
+            failure: options.failure || me.failure,
+            renderer: options.renderer || me.renderer,
+            scripts: Ext.isDefined(options.scripts) ? options.scripts : me.scripts
+        };
+        me.setOptions(me.active, options);
+    },
+
+    
+    setOptions: Ext.emptyFn,
+
+    
+    onComplete: function(options, success, response) {
+        var me = this,
+            active = me.active,
+            scope = active.scope,
+            renderer = me.getRenderer(active.renderer);
+
+
+        if (success) {
+            success = renderer.call(me, me, response, active);
+        }
+
+        if (success) {
+            Ext.callback(active.success, scope, [me, response, options]);
+            me.fireEvent('load', me, response, options);
+        } else {
+            Ext.callback(active.failure, scope, [me, response, options]);
+            me.fireEvent('exception', me, response, options);
+        }
+        Ext.callback(active.callback, scope, [me, success, response, options]);
+
+        if (active.mask) {
+            me.removeMask();
+        }
+
+        delete me.active;
+    },
+
+    
+    getRenderer: function(renderer){
+        if (Ext.isFunction(renderer)) {
+            return renderer;
+        }
+        return this.statics().Renderer.Html;
+    },
+
+    
+    startAutoRefresh: function(interval, options){
+        var me = this;
+        me.stopAutoRefresh();
+        me.autoRefresh = setInterval(function(){
+            me.load(options);
+        }, interval);
+    },
+
+    
+    stopAutoRefresh: function(){
+        clearInterval(this.autoRefresh);
+        delete this.autoRefresh;
+    },
+
+    
+    isAutoRefreshing: function(){
+        return Ext.isDefined(this.autoRefresh);
+    },
+
+    
+    destroy: function(){
+        var me = this;
+        me.stopAutoRefresh();
+        delete me.target;
+        me.abort();
+        me.clearListeners();
+    }
+});
+
+
+Ext.define('Ext.ComponentLoader', {
+
+    
+
+    extend: 'Ext.ElementLoader',
+
+    statics: {
+        Renderer: {
+            Data: function(loader, response, active){
+                var success = true;
+                try {
+                    loader.getTarget().update(Ext.decode(response.responseText));
+                } catch (e) {
+                    success = false;
+                }
+                return success;
+            },
+
+            Component: function(loader, response, active){
+                var success = true,
+                    target = loader.getTarget(),
+                    items = [];
+
+
+                try {
+                    items = Ext.decode(response.responseText);
+                } catch (e) {
+                    success = false;
+                }
+
+                if (success) {
+                    if (active.removeAll) {
+                        target.removeAll();
                     }
-                    oldFrameML.remove();
+                    target.add(items);
                 }
-            }
-            else {
-                
-                
+                return success;
             }
         }
-        else if (me.frame) {
-            this.applyRenderSelectors();
+    },
+
+    
+
+    
+    target: null,
+
+    
+    loadMask: false,
+
+    
+
+    
+    renderer: 'html',
+
+    
+    setTarget: function(target){
+        var me = this;
+
+        if (Ext.isString(target)) {
+            target = Ext.getCmp(target);
         }
+
+        if (me.target && me.target != target) {
+            me.abort();
+        }
+        me.target = target;
     },
+
     
-    getFrameInfo: function() {
-        if (Ext.supports.CSS3BorderRadius) {
-            return false;
+    removeMask: function(){
+        this.target.setLoading(false);
+    },
+
+    
+    addMask: function(mask){
+        this.target.setLoading(mask);
+    },
+
+    
+
+    setOptions: function(active, options){
+        active.removeAll = Ext.isDefined(options.removeAll) ? options.removeAll : this.removeAll;
+    },
+
+    
+    getRenderer: function(renderer){
+        if (Ext.isFunction(renderer)) {
+            return renderer;
         }
-        
-        var me = this,
-            left = me.el.getStyle('background-position-x'),
-            top = me.el.getStyle('background-position-y'),
-            info, frameInfo = false, max;
 
-        
-        
-        if (!left && !top) {
-            info = me.el.getStyle('background-position').split(' ');
-            left = info[0];
-            top = info[1];
+        var renderers = this.statics().Renderer;
+        switch (renderer) {
+            case 'component':
+                return renderers.Component;
+            case 'data':
+                return renderers.Data;
+            default:
+                return Ext.ElementLoader.Renderer.Html;
         }
-        
-        
-        
-        
-        if (parseInt(left, 10) >= 1000000 && parseInt(top, 10) >= 1000000) {
-            max = Math.max;
-            
-            frameInfo = {
-                
-                table: left.substr(0, 3) == '110',
-                
-                
-                vertical: top.substr(0, 3) == '110',
-                
-                
-                top:    max(left.substr(3, 2), left.substr(5, 2)),
-                right:  max(left.substr(5, 2), top.substr(3, 2)),
-                bottom: max(top.substr(3, 2), top.substr(5, 2)),
-                left:   max(top.substr(5, 2), left.substr(3, 2))
-            };
-            
-            frameInfo.width = max(frameInfo.top, frameInfo.right, frameInfo.bottom, frameInfo.left);
+    }
+});
 
-            
-            me.el.setStyle('background-image', 'none');
-        }        
-        
-        
-        
-        if (me.frame === true && !frameInfo) {
-            Ext.Error.raise("You have set frame: true explicity on this component while it doesn't have any " +
-                            "framing defined in the CSS template. In this case IE can't figure out what sizes " +
-                            "to use and thus framing on this component will be disabled.");
+
+Ext.define('Ext.data.Association', {
+    
+
+    
+
+    
+    primaryKey: 'id',
+
+    
+    
+    
+
+    defaultReaderType: 'json',
+
+    statics: {
+        create: function(association){
+            if (!association.isAssociation) {
+                if (Ext.isString(association)) {
+                    association = {
+                        type: association
+                    };
+                }
+
+                switch (association.type) {
+                    case 'belongsTo':
+                        return Ext.create('Ext.data.BelongsToAssociation', association);
+                    case 'hasMany':
+                        return Ext.create('Ext.data.HasManyAssociation', association);
+                    
+
+
+                    default:
+                }
+            }
+            return association;
         }
+    },
+
+    
+    constructor: function(config) {
+        Ext.apply(this, config);
+
+        var types           = Ext.ModelManager.types,
+            ownerName       = config.ownerModel,
+            associatedName  = config.associatedModel,
+            ownerModel      = types[ownerName],
+            associatedModel = types[associatedName],
+            ownerProto;
+
+
+        this.ownerModel = ownerModel;
+        this.associatedModel = associatedModel;
+
         
-        me.frame = me.frame || !!frameInfo;
-        me.frameSize = frameInfo || false;
+
         
-        return frameInfo;
+
+        Ext.applyIf(this, {
+            ownerName : ownerName,
+            associatedName: associatedName
+        });
     },
+
     
-    getFramePositions: function(frameInfo) {
+    getReader: function(){
         var me = this,
-            frameWidth = frameInfo.width,
-            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';
+            reader = me.reader,
+            model = me.associatedModel;
+
+        if (reader) {
+            if (Ext.isString(reader)) {
+                reader = {
+                    type: reader
+                };
             }
-            
-            positions = {
-                tl: '0 -' + (frameWidth * 0) + 'px',
-                tr: '0 -' + (frameWidth * 1) + 'px',
-                bl: '0 -' + (frameWidth * 2) + 'px',
-                br: '0 -' + (frameWidth * 3) + 'px',
+            if (reader.isReader) {
+                reader.setModel(model);
+            } else {
+                Ext.applyIf(reader, {
+                    model: model,
+                    type : me.defaultReaderType
+                });
+            }
+            me.reader = Ext.createByAlias('reader.' + reader.type, reader);
+        }
+        return me.reader || null;
+    }
+});
 
-                ml: '-' + (frameWidth * 1) + 'px 0',
-                mr: 'right 0',
 
-                tc: tc,
-                bc: bc
-            };
+Ext.define('Ext.ModelManager', {
+    extend: 'Ext.AbstractManager',
+    alternateClassName: 'Ext.ModelMgr',
+    requires: ['Ext.data.Association'],
+
+    singleton: true,
+
+    typeName: 'mtype',
+
+    
+    associationStack: [],
+
+    
+    registerType: function(name, config) {
+        var proto = config.prototype,
+            model;
+        if (proto && proto.isModel) {
+            
+            model = config;
         } else {
-            ml = '-' + (frameWidth * 0) + 'px 0';
-            mr = 'right 0';
             
-            if (dock && dock == "bottom") {
-                ml = 'left bottom';
-                mr = 'right bottom';
+            if (!config.extend) {
+                config.extend = 'Ext.data.Model';
             }
-            
-            positions = {
-                tl: '0 -' + (frameWidth * 2) + 'px',
-                tr: 'right -' + (frameWidth * 3) + 'px',
-                bl: '0 -' + (frameWidth * 4) + 'px',
-                br: 'right -' + (frameWidth * 5) + 'px',
+            model = Ext.define(name, config);
+        }
+        this.types[name] = model;
+        return model;
+    },
 
-                ml: ml,
-                mr: mr,
+    
+    onModelDefined: function(model) {
+        var stack  = this.associationStack,
+            length = stack.length,
+            create = [],
+            association, i, created;
 
-                tc: '0 -' + (frameWidth * 0) + 'px',
-                bc: '0 -' + (frameWidth * 1) + 'px'
-            };
+        for (i = 0; i < length; i++) {
+            association = stack[i];
+
+            if (association.associatedModel == model.modelName) {
+                create.push(association);
+            }
         }
-        
-        return positions;
+
+        for (i = 0, length = create.length; i < length; i++) {
+            created = create[i];
+            this.types[created.ownerModel].prototype.associations.add(Ext.data.Association.create(created));
+            Ext.Array.remove(stack, created);
+        }
+    },
+
+    
+    registerDeferredAssociation: function(association){
+        this.associationStack.push(association);
+    },
+
+    
+    getModel: function(id) {
+        var model = id;
+        if (typeof model == 'string') {
+            model = this.types[model];
+        }
+        return model;
     },
+
+    
+    create: function(config, name, id) {
+        var con = typeof name == 'function' ? name : this.types[name || config.name];
+
+        return new con(config, id);
+    }
+}, function() {
+
+    
+    Ext.regModel = function() {
+        return this.ModelManager.registerType.apply(this.ModelManager, arguments);
+    };
+});
+
+
+Ext.define('Ext.PluginManager', {
+    extend: 'Ext.AbstractManager',
+    alternateClassName: 'Ext.PluginMgr',
+    singleton: true,
+    typeName: 'ptype',
+
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
+    
     
     
-    getFrameTpl : function(table) {
-        return table ? this.getTpl('frameTableTpl') : this.getTpl('frameTpl');
-    },
-
     
-    initCls: function() {
-        var me = this,
-            cls = [];
-
-        cls.push(me.baseCls);
-
-        if (Ext.isDefined(me.cmpCls)) {
-            if (Ext.isDefined(Ext.global.console)) {
-                Ext.global.console.warn('Ext.Component: cmpCls has been deprecated. Please use componentCls.');
-            }
-            me.componentCls = me.cmpCls;
-            delete me.cmpCls;
-        }
 
-        if (me.componentCls) {
-            cls.push(me.componentCls);
+    create : function(config, defaultType){
+        if (config.init) {
+            return config;
         } else {
-            me.componentCls = me.baseCls;
-        }
-        if (me.cls) {
-            cls.push(me.cls);
-            delete me.cls;
+            return Ext.createByAlias('plugin.' + (config.ptype || defaultType), config);
         }
 
-        return cls.concat(me.additionalCls);
-    },
-    
-    
-    setUI: function(ui) {
-        var me = this,
-            oldUICls = Ext.Array.clone(me.uiCls),
-            newUICls = [],
-            cls,
-            i;
-        
-        
-        for (i = 0; i < oldUICls.length; i++) {
-            cls = oldUICls[i];
-            
-            me.removeClsWithUI(cls);
-            newUICls.push(cls);
-        }
-        
         
-        me.removeUIFromElement();
         
         
-        me.ui = ui;
         
         
-        me.addUIToElement();
         
         
-        for (i = 0; i < newUICls.length; i++) {
-            cls = newUICls[i];
-            
-            me.addClsWithUI(cls);
-        }
     },
+
     
-    
-    addClsWithUI: function(cls) {
-        var me = this,
-            i;
-        
-        if (!Ext.isArray(cls)) {
-            cls = [cls];
-        }
-        
-        for (i = 0; i < cls.length; i++) {
-            if (cls[i] && !me.hasUICls(cls[i])) {
-                me.uiCls = Ext.Array.clone(me.uiCls);
-                me.uiCls.push(cls[i]);
-                me.addUIClsToElement(cls[i]);
+    findByType: function(type, defaultsOnly) {
+        var matches = [],
+            types   = this.types;
+
+        for (var name in types) {
+            if (!types.hasOwnProperty(name)) {
+                continue;
+            }
+            var item = types[name];
+
+            if (item.type == type && (!defaultsOnly || (defaultsOnly === true && item.isDefault))) {
+                matches.push(item);
             }
         }
-    },
+
+        return matches;
+    }
+}, function() {
     
+    Ext.preg = function() {
+        return Ext.PluginManager.registerType.apply(Ext.PluginManager, arguments);
+    };
+});
+
+
+Ext.define('Ext.Template', {
+
     
-    removeClsWithUI: function(cls) {
-        var me = this,
-            i;
-        
-        if (!Ext.isArray(cls)) {
-            cls = [cls];
-        }
+
+    requires: ['Ext.DomHelper', 'Ext.util.Format'],
+
+    inheritableStatics: {
         
-        for (i = 0; i < cls.length; i++) {
-            if (cls[i] && me.hasUICls(cls[i])) {
-                me.uiCls = Ext.Array.remove(me.uiCls, cls[i]);
-                me.removeUIClsFromElement(cls[i]);
-            }
+        from: function(el, config) {
+            el = Ext.getDom(el);
+            return new this(el.value || el.innerHTML, config || '');
         }
     },
+
     
+
     
-    hasUICls: function(cls) {
+    constructor: function(html) {
         var me = this,
-            uiCls = me.uiCls || [];
-        
-        return Ext.Array.contains(uiCls, cls);
-    },
-    
-    
-    addUIClsToElement: function(cls, force) {
-        var me = this;
-        
-        me.addCls(Ext.baseCSSPrefix + cls);
-        me.addCls(me.baseCls + '-' + cls);
-        me.addCls(me.baseCls + '-' + me.ui + '-' + cls);
-        
-        if (!force && me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) {
-            
-            var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'],
-                i, el;
-            
-            
-            for (i = 0; i < els.length; i++) {
-                el = me['frame' + els[i].toUpperCase()];
-                
-                if (el && el.dom) {
-                    el.addCls(me.baseCls + '-' + me.ui + '-' + els[i]);
-                    el.addCls(me.baseCls + '-' + me.ui + '-' + cls + '-' + els[i]);
+            args = arguments,
+            buffer = [],
+            i = 0,
+            length = args.length,
+            value;
+
+        me.initialConfig = {};
+
+        if (length > 1) {
+            for (; i < length; i++) {
+                value = args[i];
+                if (typeof value == 'object') {
+                    Ext.apply(me.initialConfig, value);
+                    Ext.apply(me, value);
+                } else {
+                    buffer.push(value);
                 }
             }
-        }
-    },
-    
-    
-    removeUIClsFromElement: function(cls, force) {
-        var me = this;
-        
-        me.removeCls(Ext.baseCSSPrefix + cls);
-        me.removeCls(me.baseCls + '-' + cls);
-        me.removeCls(me.baseCls + '-' + me.ui + '-' + cls);
-        
-        if (!force &&me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) {
-            
-            var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'],
-                i, el;
-            
-            
-            for (i = 0; i < els.length; i++) {
-                el = me['frame' + els[i].toUpperCase()];
-                if (el && el.dom) {
-                    el.removeCls(me.baseCls + '-' + me.ui + '-' + cls + '-' + els[i]);
-                }
+            html = buffer.join('');
+        } else {
+            if (Ext.isArray(html)) {
+                buffer.push(html.join(''));
+            } else {
+                buffer.push(html);
             }
         }
-    },
-    
-    
-    addUIToElement: function(force) {
-        var me = this;
-        
-        me.addCls(me.baseCls + '-' + me.ui);
+
         
-        if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) {
-            
-            var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'],
-                i, el;
-            
-            
-            for (i = 0; i < els.length; i++) {
-                el = me['frame' + els[i].toUpperCase()];
-                
-                if (el) {
-                    el.addCls(me.baseCls + '-' + me.ui + '-' + els[i]);
-                }
-            }
+        me.html = buffer.join('');
+
+        if (me.compiled) {
+            me.compile();
         }
     },
+
+    isTemplate: true,
+
     
+
     
-    removeUIFromElement: function() {
-        var me = this;
-        
-        me.removeCls(me.baseCls + '-' + me.ui);
-        
-        if (me.rendered && me.frame && !Ext.supports.CSS3BorderRadius) {
-            
-            var els = ['tl', 'tc', 'tr', 'ml', 'mc', 'mr', 'bl', 'bc', 'br'],
-                i, el;
-            
-            
-            for (i = 0; i < els.length; i++) {
-                el = me['frame' + els[i].toUpperCase()];
-                if (el) {
-                    el.removeCls(me.baseCls + '-' + me.ui + '-' + els[i]);
+    disableFormats: false,
+
+    re: /\{([\w\-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
+
+    
+    applyTemplate: function(values) {
+        var me = this,
+            useFormat = me.disableFormats !== true,
+            fm = Ext.util.Format,
+            tpl = me;
+
+        if (me.compiled) {
+            return me.compiled(values);
+        }
+        function fn(m, name, format, args) {
+            if (format && useFormat) {
+                if (args) {
+                    args = [values[name]].concat(Ext.functionFactory('return ['+ args +'];')());
+                } else {
+                    args = [values[name]];
+                }
+                if (format.substr(0, 5) == "this.") {
+                    return tpl[format.substr(5)].apply(tpl, args);
+                }
+                else {
+                    return fm[format].apply(fm, args);
                 }
             }
+            else {
+                return values[name] !== undefined ? values[name] : "";
+            }
         }
+        return me.html.replace(me.re, fn);
     },
+
     
-    getElConfig : function() {
-        var result = this.autoEl || {tag: 'div'};
-        result.id = this.id;
-        return result;
+    set: function(html, compile) {
+        var me = this;
+        me.html = html;
+        me.compiled = null;
+        return compile ? me.compile() : me;
     },
 
-    
-    getInsertPosition: function(position) {
-        
-        if (position !== undefined) {
-            if (Ext.isNumber(position)) {
-                position = this.container.dom.childNodes[position];
+    compileARe: /\\/g,
+    compileBRe: /(\r\n|\n)/g,
+    compileCRe: /'/g,
+
+    /**
+     * Compiles the template into an internal function, eliminating the RegEx overhead.
+     * @return {Ext.Template} this
+     */
+    compile: function() {
+        var me = this,
+            fm = Ext.util.Format,
+            useFormat = me.disableFormats !== true,
+            body, bodyReturn;
+
+        function fn(m, name, format, args) {
+            if (format && useFormat) {
+                args = args ? ',' + args: "";
+                if (format.substr(0, 5) != "this.") {
+                    format = "fm." + format + '(';
+                }
+                else {
+                    format = 'this.' + format.substr(5) + '(';
+                }
             }
             else {
-                position = Ext.getDom(position);
+                args = '';
+                format = "(values['" + name + "'] == undefined ? '' : ";
             }
+            return "'," + format + "values['" + name + "']" + args + ") ,'";
         }
 
-        return position;
+        bodyReturn = me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn);
+        body = "this.compiled = function(values){ return ['" + bodyReturn + "'].join('');};";
+        eval(body);
+        return me;
     },
 
-    
-    initContainer: function(container) {
-        var me = this;
+    /**
+     * Applies the supplied values to the template and inserts the new node(s) as the first child of el.
+     *
+     * @param {String/HTMLElement/Ext.Element} el The context element
+     * @param {Object/Array} values The template values. See {@link #applyTemplate} for details.
+     * @param {Boolean} returnElement (optional) true to return a Ext.Element.
+     * @return {HTMLElement/Ext.Element} The new node or Element
+     */
+    insertFirst: function(el, values, returnElement) {
+        return this.doInsert('afterBegin', el, values, returnElement);
+    },
 
-        
-        
-        
-        if (!container && me.el) {
-            container = me.el.dom.parentNode;
-            me.allowDomMove = false;
-        }
+    /**
+     * Applies the supplied values to the template and inserts the new node(s) before el.
+     *
+     * @param {String/HTMLElement/Ext.Element} el The context element
+     * @param {Object/Array} values The template values. See {@link #applyTemplate} for details.
+     * @param {Boolean} returnElement (optional) true to return a Ext.Element.
+     * @return {HTMLElement/Ext.Element} The new node or Element
+     */
+    insertBefore: function(el, values, returnElement) {
+        return this.doInsert('beforeBegin', el, values, returnElement);
+    },
 
-        me.container = Ext.get(container);
+    /**
+     * Applies the supplied values to the template and inserts the new node(s) after el.
+     *
+     * @param {String/HTMLElement/Ext.Element} el The context element
+     * @param {Object/Array} values The template values. See {@link #applyTemplate} for details.
+     * @param {Boolean} returnElement (optional) true to return a Ext.Element.
+     * @return {HTMLElement/Ext.Element} The new node or Element
+     */
+    insertAfter: function(el, values, returnElement) {
+        return this.doInsert('afterEnd', el, values, returnElement);
+    },
 
-        if (me.ctCls) {
-            me.container.addCls(me.ctCls);
-        }
+    /**
+     * Applies the supplied `values` to the template and appends the new node(s) to the specified `el`.
+     *
+     * For example usage see {@link Ext.Template Ext.Template class docs}.
+     *
+     * @param {String/HTMLElement/Ext.Element} el The context element
+     * @param {Object/Array} values The template values. See {@link #applyTemplate} for details.
+     * @param {Boolean} returnElement (optional) true to return an Ext.Element.
+     * @return {HTMLElement/Ext.Element} The new node or Element
+     */
+    append: function(el, values, returnElement) {
+        return this.doInsert('beforeEnd', el, values, returnElement);
+    },
 
-        return me.container;
+    doInsert: function(where, el, values, returnEl) {
+        el = Ext.getDom(el);
+        var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
+        return returnEl ? Ext.get(newNode, true) : newNode;
     },
 
-    
-    initRenderData: function() {
-        var me = this;
+    /**
+     * Applies the supplied values to the template and overwrites the content of el with the new node(s).
+     *
+     * @param {String/HTMLElement/Ext.Element} el The context element
+     * @param {Object/Array} values The template values. See {@link #applyTemplate} for details.
+     * @param {Boolean} returnElement (optional) true to return a Ext.Element.
+     * @return {HTMLElement/Ext.Element} The new node or Element
+     */
+    overwrite: function(el, values, returnElement) {
+        el = Ext.getDom(el);
+        el.innerHTML = this.applyTemplate(values);
+        return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
+    }
+}, function() {
 
-        return Ext.applyIf(me.renderData, {
-            ui: me.ui,
-            uiCls: me.uiCls,
-            baseCls: me.baseCls,
-            componentCls: me.componentCls,
-            frame: me.frame
-        });
-    },
+    /**
+     * @method apply
+     * @member Ext.Template
+     * Alias for {@link #applyTemplate}.
+     * @alias Ext.Template#applyTemplate
+     */
+    this.createAlias('apply', 'applyTemplate');
+});
 
-    
-    getTpl: function(name) {
-        var prototype = this.self.prototype,
-            ownerPrototype;
+/**
+ * A template class that supports advanced functionality like:
+ *
+ * - Autofilling arrays using templates and sub-templates
+ * - Conditional processing with basic comparison operators
+ * - Basic math function support
+ * - Execute arbitrary inline code with special built-in template variables
+ * - Custom member functions
+ * - Many special tags and built-in operators that aren't defined as part of the API, but are supported in the templates that can be created
+ *
+ * XTemplate provides the templating mechanism built into:
+ *
+ * - {@link Ext.view.View}
+ *
+ * The {@link Ext.Template} describes the acceptable parameters to pass to the constructor. The following examples
+ * demonstrate all of the supported features.
+ *
+ * # Sample Data
+ *
+ * This is the data object used for reference in each code example:
+ *
+ *     var data = {
+ *         name: 'Tommy Maintz',
+ *         title: 'Lead Developer',
+ *         company: 'Sencha Inc.',
+ *         email: 'tommy@sencha.com',
+ *         address: '5 Cups Drive',
+ *         city: 'Palo Alto',
+ *         state: 'CA',
+ *         zip: '44102',
+ *         drinks: ['Coffee', 'Soda', 'Water'],
+ *         kids: [
+ *             {
+ *                 name: 'Joshua',
+ *                 age:3
+ *             },
+ *             {
+ *                 name: 'Matthew',
+ *                 age:2
+ *             },
+ *             {
+ *                 name: 'Solomon',
+ *                 age:0
+ *             }
+ *         ]
+ *     };
+ *
+ * # Auto filling of arrays
+ *
+ * The **tpl** tag and the **for** operator are used to process the provided data object:
+ *
+ * - If the value specified in for is an array, it will auto-fill, repeating the template block inside the tpl
+ *   tag for each item in the array.
+ * - If for="." is specified, the data object provided is examined.
+ * - While processing an array, the special variable {#} will provide the current array index + 1 (starts at 1, not 0).
+ *
+ * Examples:
+ *
+ *     <tpl for=".">...</tpl>       // loop through array at root node
+ *     <tpl for="foo">...</tpl>     // loop through array at foo node
+ *     <tpl for="foo.bar">...</tpl> // loop through array at foo.bar node
+ *
+ * Using the sample data above:
+ *
+ *     var tpl = new Ext.XTemplate(
+ *         '<p>Kids: ',
+ *         '<tpl for=".">',       // process the data.kids node
+ *             '<p>{#}. {name}</p>',  // use current array index to autonumber
+ *         '</tpl></p>'
+ *     );
+ *     tpl.overwrite(panel.body, data.kids); // pass the kids property of the data object
+ *
+ * An example illustrating how the **for** property can be leveraged to access specified members of the provided data
+ * object to populate the template:
+ *
+ *     var tpl = new Ext.XTemplate(
+ *         '<p>Name: {name}</p>',
+ *         '<p>Title: {title}</p>',
+ *         '<p>Company: {company}</p>',
+ *         '<p>Kids: ',
+ *         '<tpl for="kids">',     // interrogate the kids property within the data
+ *             '<p>{name}</p>',
+ *         '</tpl></p>'
+ *     );
+ *     tpl.overwrite(panel.body, data);  // pass the root node of the data object
+ *
+ * Flat arrays that contain values (and not objects) can be auto-rendered using the special **`{.}`** variable inside a
+ * loop. This variable will represent the value of the array at the current index:
+ *
+ *     var tpl = new Ext.XTemplate(
+ *         '<p>{name}\'s favorite beverages:</p>',
+ *         '<tpl for="drinks">',
+ *             '<div> - {.}</div>',
+ *         '</tpl>'
+ *     );
+ *     tpl.overwrite(panel.body, data);
+ *
+ * When processing a sub-template, for example while looping through a child array, you can access the parent object's
+ * members via the **parent** object:
+ *
+ *     var tpl = new Ext.XTemplate(
+ *         '<p>Name: {name}</p>',
+ *         '<p>Kids: ',
+ *         '<tpl for="kids">',
+ *             '<tpl if="age &gt; 1">',
+ *                 '<p>{name}</p>',
+ *                 '<p>Dad: {parent.name}</p>',
+ *             '</tpl>',
+ *         '</tpl></p>'
+ *     );
+ *     tpl.overwrite(panel.body, data);
+ *
+ * # Conditional processing with basic comparison operators
+ *
+ * The **tpl** tag and the **if** operator are used to provide conditional checks for deciding whether or not to render
+ * specific parts of the template. Notes:
+ *
+ * - Double quotes must be encoded if used within the conditional
+ * - There is no else operator -- if needed, two opposite if statements should be used.
+ *
+ * Examples:
+ *
+ *     <tpl if="age > 1 && age < 10">Child</tpl>
+ *     <tpl if="age >= 10 && age < 18">Teenager</tpl>
+ *     <tpl if="this.isGirl(name)">...</tpl>
+ *     <tpl if="id==\'download\'">...</tpl>
+ *     <tpl if="needsIcon"><img src="{icon}" class="{iconCls}"/></tpl>
+ *     // no good:
+ *     <tpl if="name == "Tommy"">Hello</tpl>
+ *     // encode " if it is part of the condition, e.g.
+ *     <tpl if="name == &quot;Tommy&quot;">Hello</tpl>
+ *
+ * Using the sample data above:
+ *
+ *     var tpl = new Ext.XTemplate(
+ *         '<p>Name: {name}</p>',
+ *         '<p>Kids: ',
+ *         '<tpl for="kids">',
+ *             '<tpl if="age &gt; 1">',
+ *                 '<p>{name}</p>',
+ *             '</tpl>',
+ *         '</tpl></p>'
+ *     );
+ *     tpl.overwrite(panel.body, data);
+ *
+ * # Basic math support
+ *
+ * The following basic math operators may be applied directly on numeric data values:
+ *
+ *     + - * /
+ *
+ * For example:
+ *
+ *     var tpl = new Ext.XTemplate(
+ *         '<p>Name: {name}</p>',
+ *         '<p>Kids: ',
+ *         '<tpl for="kids">',
+ *             '<tpl if="age &gt; 1">',  // <-- Note that the > is encoded
+ *                 '<p>{#}: {name}</p>',  // <-- Auto-number each item
+ *                 '<p>In 5 Years: {age+5}</p>',  // <-- Basic math
+ *                 '<p>Dad: {parent.name}</p>',
+ *             '</tpl>',
+ *         '</tpl></p>'
+ *     );
+ *     tpl.overwrite(panel.body, data);
+ *
+ * # Execute arbitrary inline code with special built-in template variables
+ *
+ * Anything between `{[ ... ]}` is considered code to be executed in the scope of the template. There are some special
+ * variables available in that code:
+ *
+ * - **values**: The values in the current scope. If you are using scope changing sub-templates,
+ *   you can change what values is.
+ * - **parent**: The scope (values) of the ancestor template.
+ * - **xindex**: If you are in a looping template, the index of the loop you are in (1-based).
+ * - **xcount**: If you are in a looping template, the total length of the array you are looping.
+ *
+ * This example demonstrates basic row striping using an inline code block and the xindex variable:
+ *
+ *     var tpl = new Ext.XTemplate(
+ *         '<p>Name: {name}</p>',
+ *         '<p>Company: {[values.company.toUpperCase() + ", " + values.title]}</p>',
+ *         '<p>Kids: ',
+ *         '<tpl for="kids">',
+ *             '<div class="{[xindex % 2 === 0 ? "even" : "odd"]}">',
+ *             '{name}',
+ *             '</div>',
+ *         '</tpl></p>'
+ *      );
+ *     tpl.overwrite(panel.body, data);
+ *
+ * # Template member functions
+ *
+ * One or more member functions can be specified in a configuration object passed into the XTemplate constructor for
+ * more complex processing:
+ *
+ *     var tpl = new Ext.XTemplate(
+ *         '<p>Name: {name}</p>',
+ *         '<p>Kids: ',
+ *         '<tpl for="kids">',
+ *             '<tpl if="this.isGirl(name)">',
+ *                 '<p>Girl: {name} - {age}</p>',
+ *             '</tpl>',
+ *              // use opposite if statement to simulate 'else' processing:
+ *             '<tpl if="this.isGirl(name) == false">',
+ *                 '<p>Boy: {name} - {age}</p>',
+ *             '</tpl>',
+ *             '<tpl if="this.isBaby(age)">',
+ *                 '<p>{name} is a baby!</p>',
+ *             '</tpl>',
+ *         '</tpl></p>',
+ *         {
+ *             // XTemplate configuration:
+ *             disableFormats: true,
+ *             // member functions:
+ *             isGirl: function(name){
+ *                return name == 'Sara Grace';
+ *             },
+ *             isBaby: function(age){
+ *                return age < 1;
+ *             }
+ *         }
+ *     );
+ *     tpl.overwrite(panel.body, data);
+ */
+Ext.define('Ext.XTemplate', {
 
-        if (this.hasOwnProperty(name)) {
-            if (!(this[name] instanceof Ext.XTemplate)) {
-                this[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', this[name]);
-            }
+    /* Begin Definitions */
 
-            return this[name];
-        }
+    extend: 'Ext.Template',
 
-        if (!(prototype[name] instanceof Ext.XTemplate)) {
-            ownerPrototype = prototype;
+    /* End Definitions */
 
-            do {
-                if (ownerPrototype.hasOwnProperty(name)) {
-                    ownerPrototype[name] = Ext.ClassManager.dynInstantiate('Ext.XTemplate', ownerPrototype[name]);
-                    break;
-                }
+    argsRe: /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
+    nameRe: /^<tpl\b[^>]*?for="(.*?)"/,
+    ifRe: /^<tpl\b[^>]*?if="(.*?)"/,
+    execRe: /^<tpl\b[^>]*?exec="(.*?)"/,
+    constructor: function() {
+        this.callParent(arguments);
 
-                ownerPrototype = ownerPrototype.superclass;
-            } while (ownerPrototype);
-        }
+        var me = this,
+            html = me.html,
+            argsRe = me.argsRe,
+            nameRe = me.nameRe,
+            ifRe = me.ifRe,
+            execRe = me.execRe,
+            id = 0,
+            tpls = [],
+            VALUES = 'values',
+            PARENT = 'parent',
+            XINDEX = 'xindex',
+            XCOUNT = 'xcount',
+            RETURN = 'return ',
+            WITHVALUES = 'with(values){ ',
+            m, matchName, matchIf, matchExec, exp, fn, exec, name, i;
 
-        return prototype[name];
-    },
+        html = ['<tpl>', html, '</tpl>'].join('');
 
-    
-    initRenderTpl: function() {
-        return this.getTpl('renderTpl');
-    },
+        while ((m = html.match(argsRe))) {
+            exp = null;
+            fn = null;
+            exec = null;
+            matchName = m[0].match(nameRe);
+            matchIf = m[0].match(ifRe);
+            matchExec = m[0].match(execRe);
 
-    
-    initStyles: function() {
-        var style = {},
-            me = this,
-            Element = Ext.core.Element;
+            exp = matchIf ? matchIf[1] : null;
+            if (exp) {
+                fn = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + 'try{' + RETURN + Ext.String.htmlDecode(exp) + ';}catch(e){return;}}');
+            }
 
-        if (Ext.isString(me.style)) {
-            style = Element.parseStyles(me.style);
-        } else {
-            style = Ext.apply({}, me.style);
-        }
+            exp = matchExec ? matchExec[1] : null;
+            if (exp) {
+                exec = Ext.functionFactory(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + Ext.String.htmlDecode(exp) + ';}');
+            }
 
-        
-        
-        if (me.padding !== undefined) {
-            style.padding = Element.unitizeBox((me.padding === true) ? 5 : me.padding);
+            name = matchName ? matchName[1] : null;
+            if (name) {
+                if (name === '.') {
+                    name = VALUES;
+                } else if (name === '..') {
+                    name = PARENT;
+                }
+                name = Ext.functionFactory(VALUES, PARENT, 'try{' + WITHVALUES + RETURN + name + ';}}catch(e){return;}');
+            }
+
+            tpls.push({
+                id: id,
+                target: name,
+                exec: exec,
+                test: fn,
+                body: m[1] || ''
+            });
+
+            html = html.replace(m[0], '{xtpl' + id + '}');
+            id = id + 1;
         }
 
-        if (me.margin !== undefined) {
-            style.margin = Element.unitizeBox((me.margin === true) ? 5 : me.margin);
+        for (i = tpls.length - 1; i >= 0; --i) {
+            me.compileTpl(tpls[i]);
         }
+        me.master = tpls[tpls.length - 1];
+        me.tpls = tpls;
+    },
 
-        delete me.style;
-        return style;
+    // @private
+    applySubTemplate: function(id, values, parent, xindex, xcount) {
+        var me = this, t = me.tpls[id];
+        return t.compiled.call(me, values, parent, xindex, xcount);
     },
 
-    
-    initContent: function() {
-        var me = this,
-            target = me.getTargetEl(),
-            contentEl,
-            pre;
+    /**
+     * @cfg {RegExp} codeRe
+     * The regular expression used to match code variables. Default: matches {[expression]}.
+     */
+    codeRe: /\{\[((?:\\\]|.|\n)*?)\]\}/g,
 
-        if (me.html) {
-            target.update(Ext.core.DomHelper.markup(me.html));
-            delete me.html;
-        }
+    /**
+     * @cfg {Boolean} compiled
+     * Only applies to {@link Ext.Template}, XTemplates are compiled automatically.
+     */
 
-        if (me.contentEl) {
-            contentEl = Ext.get(me.contentEl);
-            pre = Ext.baseCSSPrefix;
-            contentEl.removeCls([pre + 'hidden', pre + 'hide-display', pre + 'hide-offsets', pre + 'hide-nosize']);
-            target.appendChild(contentEl.dom);
-        }
+    re: /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\/]\s?[\d\.\+\-\*\/\(\)]+)?\}/g,
 
-        if (me.tpl) {
-            
-            if (!me.tpl.isTemplate) {
-                me.tpl = Ext.create('Ext.XTemplate', me.tpl);
+    // @private
+    compileTpl: function(tpl) {
+        var fm = Ext.util.Format,
+            me = this,
+            useFormat = me.disableFormats !== true,
+            body, bodyReturn, evaluatedFn;
+
+        function fn(m, name, format, args, math) {
+            var v;
+            // name is what is inside the {}
+            // Name begins with xtpl, use a Sub Template
+            if (name.substr(0, 4) == 'xtpl') {
+                return "',this.applySubTemplate(" + name.substr(4) + ", values, parent, xindex, xcount),'";
+            }
+            // name = "." - Just use the values object.
+            if (name == '.') {
+                // filter to not include arrays/objects/nulls
+                v = 'Ext.Array.indexOf(["string", "number", "boolean"], typeof values) > -1 || Ext.isDate(values) ? values : ""';
             }
 
-            if (me.data) {
-                me.tpl[me.tplWriteMode](target, me.data);
-                delete me.data;
+            // name = "#" - Use the xindex
+            else if (name == '#') {
+                v = 'xindex';
+            }
+            else if (name.substr(0, 7) == "parent.") {
+                v = name;
+            }
+            // name has a . in it - Use object literal notation, starting from values
+            else if (name.indexOf('.') != -1) {
+                v = "values." + name;
             }
-        }
-    },
 
-    
-    initEvents : function() {
-        var me = this,
-            afterRenderEvents = me.afterRenderEvents,
-            property, listeners;
-        if (afterRenderEvents) {
-            for (property in afterRenderEvents) {
-                if (afterRenderEvents.hasOwnProperty(property)) {
-                    listeners = afterRenderEvents[property];
-                    if (me[property] && me[property].on) {
-                        me.mon(me[property], listeners);
-                    }
+            // name is a property of values
+            else {
+                v = "values['" + name + "']";
+            }
+            if (math) {
+                v = '(' + v + math + ')';
+            }
+            if (format && useFormat) {
+                args = args ? ',' + args : "";
+                if (format.substr(0, 5) != "this.") {
+                    format = "fm." + format + '(';
+                }
+                else {
+                    format = 'this.' + format.substr(5) + '(';
                 }
             }
+            else {
+                args = '';
+                format = "(" + v + " === undefined ? '' : ";
+            }
+            return "'," + format + v + args + "),'";
         }
-    },
-
-    
-    applyRenderSelectors: function() {
-        var selectors = this.renderSelectors || {},
-            el = this.el.dom,
-            selector;
 
-        for (selector in selectors) {
-            if (selectors.hasOwnProperty(selector) && selectors[selector]) {
-                this[selector] = Ext.get(Ext.DomQuery.selectNode(selectors[selector], el));
-            }
+        function codeFn(m, code) {
+            // Single quotes get escaped when the template is compiled, however we want to undo this when running code.
+            return "',(" + code.replace(me.compileARe, "'") + "),'";
         }
-    },
 
-    
-    is: function(selector) {
-        return Ext.ComponentQuery.is(this, selector);
-    },
+        bodyReturn = tpl.body.replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn).replace(me.codeRe, codeFn);
+        body = "evaluatedFn = function(values, parent, xindex, xcount){return ['" + bodyReturn + "'].join('');};";
+        eval(body);
 
-    
-    up: function(selector) {
-        var result = this.ownerCt;
-        if (selector) {
-            for (; result; result = result.ownerCt) {
-                if (Ext.ComponentQuery.is(result, selector)) {
-                    return result;
-                }
+        tpl.compiled = function(values, parent, xindex, xcount) {
+            var vs,
+                length,
+                buffer,
+                i;
+
+            if (tpl.test && !tpl.test.call(me, values, parent, xindex, xcount)) {
+                return '';
             }
-        }
-        return result;
-    },
 
-    
-    nextSibling: function(selector) {
-        var o = this.ownerCt, it, last, idx, c;
-        if (o) {
-            it = o.items;
-            idx = it.indexOf(this) + 1;
-            if (idx) {
-                if (selector) {
-                    for (last = it.getCount(); idx < last; idx++) {
-                        if ((c = it.getAt(idx)).is(selector)) {
-                            return c;
-                        }
-                    }
-                } else {
-                    if (idx < it.getCount()) {
-                        return it.getAt(idx);
-                    }
-                }
+            vs = tpl.target ? tpl.target.call(me, values, parent) : values;
+            if (!vs) {
+               return '';
             }
-        }
-        return null;
-    },
 
-    
-    previousSibling: function(selector) {
-        var o = this.ownerCt, it, idx, c;
-        if (o) {
-            it = o.items;
-            idx = it.indexOf(this);
-            if (idx != -1) {
-                if (selector) {
-                    for (--idx; idx >= 0; idx--) {
-                        if ((c = it.getAt(idx)).is(selector)) {
-                            return c;
-                        }
+            parent = tpl.target ? values : parent;
+            if (tpl.target && Ext.isArray(vs)) {
+                buffer = [];
+                length = vs.length;
+                if (tpl.exec) {
+                    for (i = 0; i < length; i++) {
+                        buffer[buffer.length] = evaluatedFn.call(me, vs[i], parent, i + 1, length);
+                        tpl.exec.call(me, vs[i], parent, i + 1, length);
                     }
                 } else {
-                    if (idx) {
-                        return it.getAt(--idx);
+                    for (i = 0; i < length; i++) {
+                        buffer[buffer.length] = evaluatedFn.call(me, vs[i], parent, i + 1, length);
                     }
                 }
+                return buffer.join('');
             }
-        }
-        return null;
-    },
-
-    
-    previousNode: function(selector, includeSelf) {
-        var node = this,
-            result,
-            it, len, i;
 
-        
-        if (includeSelf && node.is(selector)) {
-            return node;
-        }
+            if (tpl.exec) {
+                tpl.exec.call(me, vs, parent, xindex, xcount);
+            }
+            return evaluatedFn.call(me, vs, parent, xindex, xcount);
+        };
 
-        result = this.prev(selector);
-        if (result) {
-            return result;
-        }
+        return this;
+    },
 
-        if (node.ownerCt) {
-            for (it = node.ownerCt.items.items, i = Ext.Array.indexOf(it, node) - 1; i > -1; i--) {
-                if (it[i].query) {
-                    result = it[i].query(selector);
-                    result = result[result.length - 1];
-                    if (result) {
-                        return result;
-                    }
-                }
-            }
-            return node.ownerCt.previousNode(selector, true);
-        }
+    // inherit docs from Ext.Template
+    applyTemplate: function(values) {
+        return this.master.compiled.call(this, values, {}, 1, 1);
     },
 
-    
-    nextNode: function(selector, includeSelf) {
-        var node = this,
-            result,
-            it, len, i;
+    /**
+     * Does nothing. XTemplates are compiled automatically, so this function simply returns this.
+     * @return {Ext.XTemplate} this
+     */
+    compile: function() {
+        return this;
+    }
+}, function() {
+    // re-create the alias, inheriting it from Ext.Template doesn't work as intended.
+    this.createAlias('apply', 'applyTemplate');
+});
 
-        
-        if (includeSelf && node.is(selector)) {
-            return node;
-        }
 
-        result = this.next(selector);
-        if (result) {
-            return result;
-        }
+Ext.define('Ext.app.Controller', {
 
-        if (node.ownerCt) {
-            for (it = node.ownerCt.items, i = it.indexOf(node) + 1, it = it.items, len = it.length; i < len; i++) {
-                if (it[i].down) {
-                    result = it[i].down(selector);
-                    if (result) {
-                        return result;
-                    }
-                }
-            }
-            return node.ownerCt.nextNode(selector);
-        }
+    mixins: {
+        observable: 'Ext.util.Observable'
     },
 
     
-    getId : function() {
-        return this.id || (this.id = 'ext-comp-' + (this.getAutoId()));
-    },
-
-    getItemId : function() {
-        return this.itemId || this.id;
-    },
-
     
-    getEl : function() {
-        return this.el;
-    },
-
     
-    getTargetEl: function() {
-        return this.frameBody || this.el;
-    },
 
     
-    isXType: function(xtype, shallow) {
-        
-        if (Ext.isFunction(xtype)) {
-            xtype = xtype.xtype;
-            
-        } else if (Ext.isObject(xtype)) {
-            xtype = xtype.statics().xtype;
-            
-        }
-
-        return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1: this.self.xtype == xtype;
-    },
 
     
-    getXTypes: function() {
-        var self = this.self,
-            xtypes      = [],
-            parentPrototype  = this,
-            xtype;
-
-        if (!self.xtypes) {
-            while (parentPrototype && Ext.getClass(parentPrototype)) {
-                xtype = Ext.getClass(parentPrototype).xtype;
-
-                if (xtype !== undefined) {
-                    xtypes.unshift(xtype);
-                }
-
-                parentPrototype = parentPrototype.superclass;
-            }
-
-            self.xtypeChain = xtypes;
-            self.xtypes = xtypes.join('/');
-        }
 
-        return self.xtypes;
-    },
+    onClassExtended: function(cls, data) {
+        var className = Ext.getClassName(cls),
+            match = className.match(/^(.*)\.controller\./);
 
-    
-    update : function(htmlOrData, loadScripts, cb) {
-        var me = this;
+        if (match !== null) {
+            var namespace = Ext.Loader.getPrefix(className) || match[1],
+                onBeforeClassCreated = data.onBeforeClassCreated,
+                requires = [],
+                modules = ['model', 'view', 'store'],
+                prefix;
 
-        if (me.tpl && !Ext.isString(htmlOrData)) {
-            me.data = htmlOrData;
-            if (me.rendered) {
-                me.tpl[me.tplWriteMode](me.getTargetEl(), htmlOrData || {});
-            }
-        } else {
-            me.html = Ext.isObject(htmlOrData) ? Ext.core.DomHelper.markup(htmlOrData) : htmlOrData;
-            if (me.rendered) {
-                me.getTargetEl().update(me.html, loadScripts, cb);
-            }
-        }
+            data.onBeforeClassCreated = function(cls, data) {
+                var i, ln, module,
+                    items, j, subLn, item;
 
-        if (me.rendered) {
-            me.doComponentLayout();
-        }
-    },
+                for (i = 0,ln = modules.length; i < ln; i++) {
+                    module = modules[i];
 
-    
-    setVisible : function(visible) {
-        return this[visible ? 'show': 'hide']();
-    },
+                    items = Ext.Array.from(data[module + 's']);
 
-    
-    isVisible: function(deep) {
-        var me = this,
-            child = me,
-            visible = !me.hidden,
-            ancestor = me.ownerCt;
+                    for (j = 0,subLn = items.length; j < subLn; j++) {
+                        item = items[j];
 
-        
-        me.hiddenAncestor = false;
-        if (me.destroyed) {
-            return false;
-        }
+                        prefix = Ext.Loader.getPrefix(item);
 
-        if (deep && visible && me.rendered && ancestor) {
-            while (ancestor) {
-                
-                
-                
-                
-                if (ancestor.hidden || (ancestor.collapsed &&
-                        !(ancestor.getDockedItems && Ext.Array.contains(ancestor.getDockedItems(), child)))) {
-                    
-                    me.hiddenAncestor = ancestor;
-                    visible = false;
-                    break;
+                        if (prefix === '' || prefix === item) {
+                            requires.push(namespace + '.' + module + '.' + item);
+                        }
+                        else {
+                            requires.push(item);
+                        }
+                    }
                 }
-                child = ancestor;
-                ancestor = ancestor.ownerCt;
-            }
-        }
-        return visible;
-    },
 
-    
-    enable: function(silent) {
-        var me = this;
-
-        if (me.rendered) {
-            me.el.removeCls(me.disabledCls);
-            me.el.dom.disabled = false;
-            me.onEnable();
-        }
-
-        me.disabled = false;
-
-        if (silent !== true) {
-            me.fireEvent('enable', me);
+                Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this));
+            };
         }
-
-        return me;
     },
 
     
-    disable: function(silent) {
-        var me = this;
-
-        if (me.rendered) {
-            me.el.addCls(me.disabledCls);
-            me.el.dom.disabled = true;
-            me.onDisable();
-        }
-
-        me.disabled = true;
+    constructor: function(config) {
+        this.mixins.observable.constructor.call(this, config);
 
-        if (silent !== true) {
-            me.fireEvent('disable', me);
-        }
+        Ext.apply(this, config || {});
 
-        return me;
-    },
-    
-    
-    onEnable: function() {
-        if (this.maskOnDisable) {
-            this.el.unmask();
-        }        
-    },
+        this.createGetters('model', this.models);
+        this.createGetters('store', this.stores);
+        this.createGetters('view', this.views);
 
-    
-    onDisable : function() {
-        if (this.maskOnDisable) {
-            this.el.mask();
+        if (this.refs) {
+            this.ref(this.refs);
         }
     },
-    
-    
-    isDisabled : function() {
-        return this.disabled;
-    },
-
-    
-    setDisabled : function(disabled) {
-        return this[disabled ? 'disable': 'enable']();
-    },
-
-    
-    isHidden : function() {
-        return this.hidden;
-    },
 
     
-    addCls : function(className) {
-        var me = this;
-        if (!className) {
-            return me;
-        }
-        if (!Ext.isArray(className)){
-            className = className.replace(me.trimRe, '').split(me.spacesRe);
-        }
-        if (me.rendered) {
-            me.el.addCls(className);
-        }
-        else {
-            me.additionalCls = Ext.Array.unique(me.additionalCls.concat(className));
-        }
-        return me;
-    },
+    init: function(application) {},
 
     
-    addClass : function() {
-        return this.addCls.apply(this, arguments);
-    },
+    onLaunch: function(application) {},
 
-    
-    removeCls : function(className) {
-        var me = this;
+    createGetters: function(type, refs) {
+        type = Ext.String.capitalize(type);
+        Ext.Array.each(refs, function(ref) {
+            var fn = 'get',
+                parts = ref.split('.');
 
-        if (!className) {
-            return me;
-        }
-        if (!Ext.isArray(className)){
-            className = className.replace(me.trimRe, '').split(me.spacesRe);
-        }
-        if (me.rendered) {
-            me.el.removeCls(className);
-        }
-        else if (me.additionalCls.length) {
-            Ext.each(className, function(cls) {
-                Ext.Array.remove(me.additionalCls, cls);
+            
+            Ext.Array.each(parts, function(part) {
+                fn += Ext.String.capitalize(part);
             });
-        }
-        return me;
-    },
+            fn += type;
 
-    removeClass : function() {
-        if (Ext.isDefined(Ext.global.console)) {
-            Ext.global.console.warn('Ext.Component: removeClass has been deprecated. Please use removeCls.');
-        }
-        return this.removeCls.apply(this, arguments);
+            if (!this[fn]) {
+                this[fn] = Ext.Function.pass(this['get' + type], [ref], this);
+            }
+            
+            this[fn](ref);
+        },
+        this);
     },
 
-    addOverCls: function() {
+    ref: function(refs) {
         var me = this;
-        if (!me.disabled) {
-            me.el.addCls(me.overCls);
-        }
-    },
-
-    removeOverCls: function() {
-        this.el.removeCls(this.overCls);
+        refs = Ext.Array.from(refs);
+        Ext.Array.each(refs, function(info) {
+            var ref = info.ref,
+                fn = 'get' + Ext.String.capitalize(ref);
+            if (!me[fn]) {
+                me[fn] = Ext.Function.pass(me.getRef, [ref, info], me);
+            }
+        });
     },
 
-    addListener : function(element, listeners, scope, options) {
-        var me = this,
-            fn,
-            option;
+    getRef: function(ref, info, config) {
+        this.refCache = this.refCache || {};
+        info = info || {};
+        config = config || {};
 
-        if (Ext.isString(element) && (Ext.isObject(listeners) || options && options.element)) {
-            if (options.element) {
-                fn = listeners;
+        Ext.apply(info, config);
 
-                listeners = {};
-                listeners[element] = fn;
-                element = options.element;
-                if (scope) {
-                    listeners.scope = scope;
-                }
+        if (info.forceCreate) {
+            return Ext.ComponentManager.create(info, 'component');
+        }
 
-                for (option in options) {
-                    if (options.hasOwnProperty(option)) {
-                        if (me.eventOptionsRe.test(option)) {
-                            listeners[option] = options[option];
-                        }
-                    }
-                }
-            }
+        var me = this,
+            selector = info.selector,
+            cached = me.refCache[ref];
 
-            
-            
-            if (me[element] && me[element].on) {
-                me.mon(me[element], listeners);
-            } else {
-                me.afterRenderEvents = me.afterRenderEvents || {};
-                me.afterRenderEvents[element] = listeners;
+        if (!cached) {
+            me.refCache[ref] = cached = Ext.ComponentQuery.query(info.selector)[0];
+            if (!cached && info.autoCreate) {
+                me.refCache[ref] = cached = Ext.ComponentManager.create(info, 'component');
+            }
+            if (cached) {
+                cached.on('beforedestroy', function() {
+                    me.refCache[ref] = null;
+                });
             }
         }
 
-        return me.mixins.observable.addListener.apply(me, arguments);
+        return cached;
     },
 
     
-
-    
-    getBubbleTarget : function() {
-        return this.ownerCt;
+    control: function(selectors, listeners) {
+        this.application.control(selectors, listeners, this);
     },
 
     
-    isFloating : function() {
-        return this.floating;
+    getController: function(name) {
+        return this.application.getController(name);
     },
 
     
-    isDraggable : function() {
-        return !!this.draggable;
+    getStore: function(name) {
+        return this.application.getStore(name);
     },
 
     
-    isDroppable : function() {
-        return !!this.droppable;
+    getModel: function(model) {
+        return this.application.getModel(model);
     },
 
     
-    onAdded : function(container, pos) {
-        this.ownerCt = container;
-        this.fireEvent('added', this, container, pos);
-    },
+    getView: function(view) {
+        return this.application.getView(view);
+    }
+});
 
-    
-    onRemoved : function() {
-        var me = this;
 
-        me.fireEvent('removed', me, me.ownerCt);
-        delete me.ownerCt;
-    },
+Ext.define('Ext.data.IdGenerator', {
 
-    
-    beforeDestroy : Ext.emptyFn,
-    
-    
-    onResize : Ext.emptyFn,
+    isGenerator: true,
 
     
-    setSize : function(width, height) {
-        var me = this,
-            layoutCollection;
+    constructor: function(config) {
+        var me = this;
 
-        
-        if (Ext.isObject(width)) {
-            height = width.height;
-            width  = width.width;
-        }
+        Ext.apply(me, config);
 
-        
-        if (Ext.isNumber(width)) {
-            width = Ext.Number.constrain(width, me.minWidth, me.maxWidth);
-        }
-        if (Ext.isNumber(height)) {
-            height = Ext.Number.constrain(height, me.minHeight, me.maxHeight);
+        if (me.id) {
+            Ext.data.IdGenerator.all[me.id] = me;
         }
+    },
 
-        if (!me.rendered || !me.isVisible()) {
-            
-            if (me.hiddenAncestor) {
-                layoutCollection = me.hiddenAncestor.layoutOnShow;
-                layoutCollection.remove(me);
-                layoutCollection.add(me);
-            }
-            me.needsLayout = {
-                width: width,
-                height: height,
-                isSetSize: true
-            };
-            if (!me.rendered) {
-                me.width  = (width !== undefined) ? width : me.width;
-                me.height = (height !== undefined) ? height : me.height;
-            }
-            return me;
-        }
-        me.doComponentLayout(width, height, true);
+    
 
-        return me;
+    getRecId: function (rec) {
+        return rec.modelName + '-' + rec.internalId;
     },
 
-    setCalculatedSize : function(width, height, ownerCt) {
-        var me = this,
-            layoutCollection;
+    
 
+    statics: {
         
-        if (Ext.isObject(width)) {
-            ownerCt = width.ownerCt;
-            height = width.height;
-            width  = width.width;
-        }
+        all: {},
 
         
-        if (Ext.isNumber(width)) {
-            width = Ext.Number.constrain(width, me.minWidth, me.maxWidth);
-        }
-        if (Ext.isNumber(height)) {
-            height = Ext.Number.constrain(height, me.minHeight, me.maxHeight);
-        }
+        get: function (config) {
+            var generator,
+                id,
+                type;
 
-        if (!me.rendered || !me.isVisible()) {
-            
-            if (me.hiddenAncestor) {
-                layoutCollection = me.hiddenAncestor.layoutOnShow;
-                layoutCollection.remove(me);
-                layoutCollection.add(me);
+            if (typeof config == 'string') {
+                id = type = config;
+                config = null;
+            } else if (config.isGenerator) {
+                return config;
+            } else {
+                id = config.id || config.type;
+                type = config.type;
             }
-            me.needsLayout = {
-                width: width,
-                height: height,
-                isSetSize: false,
-                ownerCt: ownerCt
-            };
-            return me;
-        }
-        me.doComponentLayout(width, height, false, ownerCt);
-
-        return me;
-    },
 
-    
-    doComponentLayout : function(width, height, isSetSize, ownerCt) {
-        var me = this,
-            componentLayout = me.getComponentLayout();
-
-        
-        
-        
-        if (me.rendered && componentLayout) {
-            width = (width !== undefined) ? width : me.width;
-            height = (height !== undefined) ? height : me.height;
-            if (isSetSize) {
-                me.width = width;
-                me.height = height;
+            generator = this.all[id];
+            if (!generator) {
+                generator = Ext.create('idgen.' + type, config);
             }
 
-            componentLayout.layout(width, height, isSetSize, ownerCt);
+            return generator;
         }
-        return me;
-    },
+    }
+});
 
+
+Ext.define('Ext.data.SortTypes', {
     
-    setComponentLayout : function(layout) {
-        var currentLayout = this.componentLayout;
-        if (currentLayout && currentLayout.isLayout && currentLayout != layout) {
-            currentLayout.setOwner(null);
-        }
-        this.componentLayout = layout;
-        layout.setOwner(this);
+    singleton: true,
+    
+    
+    none : function(s) {
+        return s;
     },
 
-    getComponentLayout : function() {
-        var me = this;
+    
+    stripTagsRE : /<\/?[^>]+>/gi,
 
-        if (!me.componentLayout || !me.componentLayout.isLayout) {
-            me.setComponentLayout(Ext.layout.Layout.create(me.componentLayout, 'autocomponent'));
-        }
-        return me.componentLayout;
+    
+    asText : function(s) {
+        return String(s).replace(this.stripTagsRE, "");
     },
 
     
-    afterComponentLayout: function(width, height, isSetSize, layoutOwner) {
-        this.fireEvent('resize', this, width, height);
+    asUCText : function(s) {
+        return String(s).toUpperCase().replace(this.stripTagsRE, "");
     },
 
     
-    beforeComponentLayout: function(width, height, isSetSize, layoutOwner) {
-        return true;
+    asUCString : function(s) {
+        return String(s).toUpperCase();
     },
 
     
-    setPosition : function(x, y) {
-        var me = this;
-
-        if (Ext.isObject(x)) {
-            y = x.y;
-            x = x.x;
-        }
-
-        if (!me.rendered) {
-            return me;
+    asDate : function(s) {
+        if(!s){
+            return 0;
         }
-
-        if (x !== undefined || y !== undefined) {
-            me.el.setBox(x, y);
-            me.onPosition(x, y);
-            me.fireEvent('move', me, x, y);
+        if(Ext.isDate(s)){
+            return s.getTime();
         }
-        return me;
+        return Date.parse(String(s));
     },
 
     
-    onPosition: Ext.emptyFn,
-
-    
-    setWidth : function(width) {
-        return this.setSize(width);
+    asFloat : function(s) {
+        var val = parseFloat(String(s).replace(/,/g, ""));
+        return isNaN(val) ? 0 : val;
     },
 
     
-    setHeight : function(height) {
-        return this.setSize(undefined, height);
-    },
+    asInt : function(s) {
+        var val = parseInt(String(s).replace(/,/g, ""), 10);
+        return isNaN(val) ? 0 : val;
+    }
+});
 
-    
-    getSize : function() {
-        return this.el.getSize();
-    },
+Ext.define('Ext.util.Filter', {
 
     
-    getWidth : function() {
-        return this.el.getWidth();
-    },
 
     
-    getHeight : function() {
-        return this.el.getHeight();
-    },
-
     
-    getLoader: function(){
-        var me = this,
-            autoLoad = me.autoLoad ? (Ext.isObject(me.autoLoad) ? me.autoLoad : {url: me.autoLoad}) : null,
-            loader = me.loader || autoLoad;
+    
+    
+    
+    
+    anyMatch: false,
+    
+    
+    exactMatch: false,
+    
+    
+    caseSensitive: false,
+    
+    
 
-        if (loader) {
-            if (!loader.isLoader) {
-                me.loader = Ext.create('Ext.ComponentLoader', Ext.apply({
-                    target: me,
-                    autoLoad: autoLoad
-                }, loader));
+    
+    constructor: function(config) {
+        var me = this;
+        Ext.apply(me, config);
+        
+        
+        
+        me.filter = me.filter || me.filterFn;
+        
+        if (me.filter === undefined) {
+            if (me.property === undefined || me.value === undefined) {
+                
+                
+                
+                
             } else {
-                loader.setTarget(me);
+                me.filter = me.createFilterFn();
             }
-            return me.loader;
-
+            
+            me.filterFn = me.filter;
         }
-        return null;
     },
-
     
-    setLoading : function(load, targetEl) {
-        var me = this,
-            config;
+    
+    createFilterFn: function() {
+        var me       = this,
+            matcher  = me.createValueMatcher(),
+            property = me.property;
+        
+        return function(item) {
+            var value = me.getRoot.call(me, item)[property];
+            return matcher === null ? value === null : matcher.test(value);
+        };
+    },
+    
+    
+    getRoot: function(item) {
+        var root = this.root;
+        return root === undefined ? item : item[root];
+    },
+    
+    
+    createValueMatcher : function() {
+        var me            = this,
+            value         = me.value,
+            anyMatch      = me.anyMatch,
+            exactMatch    = me.exactMatch,
+            caseSensitive = me.caseSensitive,
+            escapeRe      = Ext.String.escapeRegex;
+            
+        if (value === null) {
+            return value;
+        }
+        
+        if (!value.exec) { 
+            value = String(value);
 
-        if (me.rendered) {
-            if (load !== false && !me.collapsed) {
-                if (Ext.isObject(load)) {
-                    config = load;
-                }
-                else if (Ext.isString(load)) {
-                    config = {msg: load};
-                }
-                else {
-                    config = {};
+            if (anyMatch === true) {
+                value = escapeRe(value);
+            } else {
+                value = '^' + escapeRe(value);
+                if (exactMatch === true) {
+                    value += '$';
                 }
-                me.loadMask = me.loadMask || Ext.create('Ext.LoadMask', targetEl ? me.getTargetEl() : me.el, config);
-                me.loadMask.show();
-            } else if (me.loadMask) {
-                Ext.destroy(me.loadMask);
-                me.loadMask = null;
             }
-        }
+            value = new RegExp(value, caseSensitive ? '' : 'i');
+         }
+         
+         return value;
+    }
+});
 
-        return me.loadMask;
-    },
+Ext.define('Ext.util.Sorter', {
 
     
-    setDocked : function(dock, layoutParent) {
+    
+    
+    
+    
+    
+    
+    
+    
+    direction: "ASC",
+    
+    constructor: function(config) {
         var me = this;
-
-        me.dock = dock;
-        if (layoutParent && me.ownerCt && me.rendered) {
-            me.ownerCt.doComponentLayout();
-        }
-        return me;
+        
+        Ext.apply(me, config);
+        
+        
+        me.updateSortFunction();
     },
-
-    onDestroy : function() {
-        var me = this;
-
-        if (me.monitorResize && Ext.EventManager.resizeEvent) {
-            Ext.EventManager.resizeEvent.removeListener(me.setSize, me);
-        }
-        Ext.destroy(me.componentLayout, me.loadMask);
+    
+    
+    createSortFunction: function(sorterFn) {
+        var me        = this,
+            property  = me.property,
+            direction = me.direction || "ASC",
+            modifier  = direction.toUpperCase() == "DESC" ? -1 : 1;
+        
+        
+        
+        return function(o1, o2) {
+            return modifier * sorterFn.call(me, o1, o2);
+        };
     },
+    
+    
+    defaultSorterFn: function(o1, o2) {
+        var me = this,
+            transform = me.transform,
+            v1 = me.getRoot(o1)[me.property],
+            v2 = me.getRoot(o2)[me.property];
+            
+        if (transform) {
+            v1 = transform(v1);
+            v2 = transform(v2);
+        }
 
+        return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
+    },
     
-    destroy : function() {
+    
+    getRoot: function(item) {
+        return this.root === undefined ? item : item[this.root];
+    },
+    
+    
+    setDirection: function(direction) {
         var me = this;
-
-        if (!me.isDestroyed) {
-            if (me.fireEvent('beforedestroy', me) !== false) {
-                me.destroying = true;
-                me.beforeDestroy();
-
-                if (me.floating) {
-                    delete me.floatParent;
-                    
-                    
-                    if (me.zIndexManager) {
-                        me.zIndexManager.unregister(me);
-                    }
-                } else if (me.ownerCt && me.ownerCt.remove) {
-                    me.ownerCt.remove(me, false);
-                }
-
-                if (me.rendered) {
-                    me.el.remove();
-                }
-
-                me.onDestroy();
-
-                
-                Ext.destroy(me.plugins);
-
-                Ext.ComponentManager.unregister(me);
-                me.fireEvent('destroy', me);
-
-                me.mixins.state.destroy.call(me);
-
-                me.clearListeners();
-                me.destroying = false;
-                me.isDestroyed = true;
-            }
-        }
+        me.direction = direction;
+        me.updateSortFunction();
     },
-
     
-    getPlugin: function(pluginId) {
-        var i = 0,
-            plugins = this.plugins,
-            ln = plugins.length;
-        for (; i < ln; i++) {
-            if (plugins[i].pluginId === pluginId) {
-                return plugins[i];
-            }
-        }
+    
+    toggle: function() {
+        var me = this;
+        me.direction = Ext.String.toggle(me.direction, "ASC", "DESC");
+        me.updateSortFunction();
     },
     
     
-    isDescendantOf: function(container) {
-        return !!this.findParentBy(function(p){
-            return p === container;
-        });
+    updateSortFunction: function(fn) {
+        var me = this;
+        fn = fn || me.sorterFn || me.defaultSorterFn;
+        me.sort = me.createSortFunction(fn);
     }
-}, function() {
-    this.createAlias({
-        on: 'addListener',
-        prev: 'previousSibling',
-        next: 'nextSibling'
-    });
 });
 
+Ext.define('Ext.data.Operation', {
+    
+    synchronous: true,
 
-Ext.define('Ext.AbstractPlugin', {
-    disabled: false,
     
-    constructor: function(config) {
-        if (!config.cmp && Ext.global.console) {
-            Ext.global.console.warn("Attempted to attach a plugin ");
-        }
-        Ext.apply(this, config);
-    },
+    action: undefined,
+
     
-    getCmp: function() {
-        return this.cmp;
-    },
+    filters: undefined,
 
     
-    init: Ext.emptyFn,
+    sorters: undefined,
 
     
-    destroy: Ext.emptyFn,
+    group: undefined,
 
     
-    enable: function() {
-        this.disabled = false;
-    },
+    start: undefined,
 
     
-    disable: function() {
-        this.disabled = true;
-    }
-});
+    limit: undefined,
 
+    
+    batch: undefined,
 
-Ext.define('Ext.data.Connection', {
-    mixins: {
-        observable: 'Ext.util.Observable'
-    },
+    
+    callback: undefined,
 
-    statics: {
-        requestId: 0
-    },
+    
+    scope: undefined,
 
-    url: null,
-    async: true,
-    method: null,
-    username: '',
-    password: '',
+    
+    started: false,
+
+    
+    running: false,
 
     
-    disableCaching: true,
+    complete: false,
 
     
-    disableCachingParam: '_dc',
+    success: undefined,
 
     
-    timeout : 30000,
+    exception: false,
 
     
+    error: undefined,
 
-    useDefaultHeader : true,
-    defaultPostHeader : 'application/x-www-form-urlencoded; charset=UTF-8',
-    useDefaultXhrHeader : true,
-    defaultXhrHeader : 'XMLHttpRequest',
+    
+    actionCommitRecordsRe: /^(?:create|update)$/i,
 
-    constructor : function(config) {
-        config = config || {};
-        Ext.apply(this, config);
+    
+    actionSkipSyncRe: /^destroy$/i,
 
-        this.addEvents(
-            
-            'beforerequest',
-            
-            'requestcomplete',
-            
-            'requestexception'
-        );
-        this.requests = {};
-        this.mixins.observable.constructor.call(this);
+    
+    constructor: function(config) {
+        Ext.apply(this, config || {});
     },
 
     
-    request : function(options) {
-        options = options || {};
+    commitRecords: function (serverRecords) {
         var me = this,
-            scope = options.scope || window,
-            username = options.username || me.username,
-            password = options.password || me.password || '',
-            async,
-            requestOptions,
-            request,
-            headers,
-            xhr;
-
-        if (me.fireEvent('beforerequest', me, options) !== false) {
-
-            requestOptions = me.setOptions(options, scope);
-
-            if (this.isFormUpload(options) === true) {
-                this.upload(options.form, requestOptions.url, requestOptions.data, options);
-                return null;
-            }
+            mc, index, clientRecords, serverRec, clientRec;
 
-            
-            if (options.autoAbort === true || me.autoAbort) {
-                me.abort();
-            }
-
-            
-            xhr = this.getXhrInstance();
-
-            async = options.async !== false ? (options.async || me.async) : false;
+        if (!me.actionSkipSyncRe.test(me.action)) {
+            clientRecords = me.records;
 
-            
-            if (username) {
-                xhr.open(requestOptions.method, requestOptions.url, async, username, password);
-            } else {
-                xhr.open(requestOptions.method, requestOptions.url, async);
-            }
-
-            headers = me.setupHeaders(xhr, options, requestOptions.data, requestOptions.params);
+            if (clientRecords && clientRecords.length) {
+                mc = Ext.create('Ext.util.MixedCollection', true, function(r) {return r.getId();});
+                mc.addAll(clientRecords);
 
-            
-            request = {
-                id: ++Ext.data.Connection.requestId,
-                xhr: xhr,
-                headers: headers,
-                options: options,
-                async: async,
-                timeout: setTimeout(function() {
-                    request.timedout = true;
-                    me.abort(request);
-                }, options.timeout || me.timeout)
-            };
-            me.requests[request.id] = request;
+                for (index = serverRecords ? serverRecords.length : 0; index--; ) {
+                    serverRec = serverRecords[index];
+                    clientRec = mc.get(serverRec.getId());
 
-            
-            if (async) {
-                xhr.onreadystatechange = Ext.Function.bind(me.onStateChange, me, [request]);
-            }
+                    if (clientRec) {
+                        clientRec.beginEdit();
+                        clientRec.set(serverRec.data);
+                        clientRec.endEdit(true);
+                    }
+                }
 
-            
-            xhr.send(requestOptions.data);
-            if (!async) {
-                return this.onComplete(request);
+                if (me.actionCommitRecordsRe.test(me.action)) {
+                    for (index = clientRecords.length; index--; ) {
+                        clientRecords[index].commit();
+                    }
+                }
             }
-            return request;
-        } else {
-            Ext.callback(options.callback, options.scope, [options, undefined, undefined]);
-            return null;
         }
     },
 
     
-    upload: function(form, url, params, options){
-        form = Ext.getDom(form);
-        options = options || {};
-
-        var id = Ext.id(),
-                frame = document.createElement('iframe'),
-                hiddens = [],
-                encoding = 'multipart/form-data',
-                buf = {
-                    target: form.target,
-                    method: form.method,
-                    encoding: form.encoding,
-                    enctype: form.enctype,
-                    action: form.action
-                }, hiddenItem;
-
-        
-        Ext.fly(frame).set({
-            id: id,
-            name: id,
-            cls: Ext.baseCSSPrefix + 'hide-display',
-            src: Ext.SSL_SECURE_URL
-        });
-
-        document.body.appendChild(frame);
+    setStarted: function() {
+        this.started = true;
+        this.running = true;
+    },
 
-        
-        if (document.frames) {
-           document.frames[id].name = id;
-        }
+    
+    setCompleted: function() {
+        this.complete = true;
+        this.running  = false;
+    },
 
-        Ext.fly(form).set({
-            target: id,
-            method: 'POST',
-            enctype: encoding,
-            encoding: encoding,
-            action: url || buf.action
-        });
+    
+    setSuccessful: function() {
+        this.success = true;
+    },
 
-        
-        if (params) {
-            Ext.iterate(Ext.Object.fromQueryString(params), function(name, value){
-                hiddenItem = document.createElement('input');
-                Ext.fly(hiddenItem).set({
-                    type: 'hidden',
-                    value: value,
-                    name: name
-                });
-                form.appendChild(hiddenItem);
-                hiddens.push(hiddenItem);
-            });
-        }
+    
+    setException: function(error) {
+        this.exception = true;
+        this.success = false;
+        this.running = false;
+        this.error = error;
+    },
 
-        Ext.fly(frame).on('load', Ext.Function.bind(this.onUploadComplete, this, [frame, options]), null, {single: true});
-        form.submit();
+    
+    hasException: function() {
+        return this.exception === true;
+    },
 
-        Ext.fly(form).set(buf);
-        Ext.each(hiddens, function(h) {
-            Ext.removeNode(h);
-        });
+    
+    getError: function() {
+        return this.error;
     },
 
-    onUploadComplete: function(frame, options){
-        var me = this,
-            
-            response = {
-                responseText: '',
-                responseXML: null
-            }, doc, firstChild;
+    
+    getRecords: function() {
+        var resultSet = this.getResultSet();
 
-        try {
-            doc = frame.contentWindow.document || frame.contentDocument || window.frames[id].document;
-            if (doc) {
-                if (doc.body) {
-                    if (/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)) { 
-                        response.responseText = firstChild.value;
-                    } else {
-                        response.responseText = doc.body.innerHTML;
-                    }
-                }
-                
-                response.responseXML = doc.XMLDocument || doc;
-            }
-        } catch (e) {
-        }
+        return (resultSet === undefined ? this.records : resultSet.records);
+    },
 
-        me.fireEvent('requestcomplete', me, response, options);
+    
+    getResultSet: function() {
+        return this.resultSet;
+    },
 
-        Ext.callback(options.success, options.scope, [response, options]);
-        Ext.callback(options.callback, options.scope, [options, true, response]);
+    
+    isStarted: function() {
+        return this.started === true;
+    },
 
-        setTimeout(function(){
-            Ext.removeNode(frame);
-        }, 100);
+    
+    isRunning: function() {
+        return this.running === true;
     },
 
     
-    isFormUpload: function(options){
-        var form = this.getForm(options);
-        if (form) {
-            return (options.isUpload || (/multipart\/form-data/i).test(form.getAttribute('enctype')));
-        }
-        return false;
+    isComplete: function() {
+        return this.complete === true;
     },
 
     
-    getForm: function(options){
-        return Ext.getDom(options.form) || null;
+    wasSuccessful: function() {
+        return this.isComplete() && this.success === true;
     },
 
     
-    setOptions: function(options, scope){
-        var me =  this,
-            params = options.params || {},
-            extraParams = me.extraParams,
-            urlParams = options.urlParams,
-            url = options.url || me.url,
-            jsonData = options.jsonData,
-            method,
-            disableCache,
-            data;
+    setBatch: function(batch) {
+        this.batch = batch;
+    },
 
+    
+    allowWrite: function() {
+        return this.action != 'read';
+    }
+});
 
-        
-        if (Ext.isFunction(params)) {
-            params = params.call(scope, options);
+Ext.define('Ext.data.validations', {
+    singleton: true,
+    
+    
+    presenceMessage: 'must be present',
+    
+    
+    lengthMessage: 'is the wrong length',
+    
+    
+    formatMessage: 'is the wrong format',
+    
+    
+    inclusionMessage: 'is not included in the list of acceptable values',
+    
+    
+    exclusionMessage: 'is not an acceptable value',
+    
+    
+    emailMessage: 'is not a valid email address',
+    
+    
+    emailRe: /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/,
+    
+    
+    presence: function(config, value) {
+        if (value === undefined) {
+            value = config;
         }
-
         
-        if (Ext.isFunction(url)) {
-            url = url.call(scope, options);
-        }
-
-        url = this.setupUrl(options, url);
-
-        if (!url) {
-            Ext.Error.raise({
-                options: options,
-                msg: 'No URL specified'
-            });
-        }
-
         
-        data = options.rawData || options.xmlData || jsonData || null;
-        if (jsonData && !Ext.isPrimitive(jsonData)) {
-            data = Ext.encode(data);
+        return !!value || value === 0;
+    },
+    
+    
+    length: function(config, value) {
+        if (value === undefined || value === null) {
+            return false;
         }
-
         
-        if (Ext.isObject(params)) {
-            params = Ext.Object.toQueryString(params);
+        var length = value.length,
+            min    = config.min,
+            max    = config.max;
+        
+        if ((min && length < min) || (max && length > max)) {
+            return false;
+        } else {
+            return true;
         }
+    },
+    
+    
+    email: function(config, email) {
+        return Ext.data.validations.emailRe.test(email);
+    },
+    
+    
+    format: function(config, value) {
+        return !!(config.matcher && config.matcher.test(value));
+    },
+    
+    
+    inclusion: function(config, value) {
+        return config.list && Ext.Array.indexOf(config.list,value) != -1;
+    },
+    
+    
+    exclusion: function(config, value) {
+        return config.list && Ext.Array.indexOf(config.list,value) == -1;
+    }
+});
 
-        if (Ext.isObject(extraParams)) {
-            extraParams = Ext.Object.toQueryString(extraParams);
-        }
+Ext.define('Ext.data.ResultSet', {
+    
+    loaded: true,
 
-        params = params + ((extraParams) ? ((params) ? '&' : '') + extraParams : '');
+    
+    count: 0,
 
-        urlParams = Ext.isObject(urlParams) ? Ext.Object.toQueryString(urlParams) : urlParams;
+    
+    total: 0,
 
-        params = this.setupParams(options, params);
+    
+    success: false,
 
-        
-        method = (options.method || me.method || ((params || data) ? 'POST' : 'GET')).toUpperCase();
-        this.setupMethod(options, method);
+    
 
+    
+    constructor: function(config) {
+        Ext.apply(this, config);
 
-        disableCache = options.disableCaching !== false ? (options.disableCaching || me.disableCaching) : false;
         
-        if (method === 'GET' && disableCache) {
-            url = Ext.urlAppend(url, (options.disableCachingParam || me.disableCachingParam) + '=' + (new Date().getTime()));
-        }
+        this.totalRecords = this.total;
 
-        
-        if ((method == 'GET' || data) && params) {
-            url = Ext.urlAppend(url, params);
-            params = null;
+        if (config.count === undefined) {
+            this.count = this.records.length;
         }
+    }
+});
 
-        
-        if (urlParams) {
-            url = Ext.urlAppend(url, urlParams);
-        }
+Ext.define('Ext.data.writer.Writer', {
+    alias: 'writer.base',
+    alternateClassName: ['Ext.data.DataWriter', 'Ext.data.Writer'],
+    
+    
+    writeAllFields: true,
+    
+    
+    nameProperty: 'name',
 
-        return {
-            url: url,
-            method: method,
-            data: data || params || null
-        };
+    
+    constructor: function(config) {
+        Ext.apply(this, config);
     },
 
     
-    setupUrl: function(options, url){
-        var form = this.getForm(options);
-        if (form) {
-            url = url || form.action;
+    write: function(request) {
+        var operation = request.operation,
+            records   = operation.records || [],
+            len       = records.length,
+            i         = 0,
+            data      = [];
+
+        for (; i < len; i++) {
+            data.push(this.getRecordData(records[i]));
         }
-        return url;
+        return this.writeRecords(request, data);
     },
 
-
     
-    setupParams: function(options, params) {
-        var form = this.getForm(options),
-            serializedForm;
-        if (form && !this.isFormUpload(options)) {
-            serializedForm = Ext.core.Element.serializeForm(form);
-            params = params ? (params + '&' + serializedForm) : serializedForm;
+    getRecordData: function(record) {
+        var isPhantom = record.phantom === true,
+            writeAll = this.writeAllFields || isPhantom,
+            nameProperty = this.nameProperty,
+            fields = record.fields,
+            data = {},
+            changes,
+            name,
+            field,
+            key;
+        
+        if (writeAll) {
+            fields.each(function(field){
+                if (field.persist) {
+                    name = field[nameProperty] || field.name;
+                    data[name] = record.get(field.name);
+                }
+            });
+        } else {
+            
+            changes = record.getChanges();
+            for (key in changes) {
+                if (changes.hasOwnProperty(key)) {
+                    field = fields.get(key);
+                    name = field[nameProperty] || field.name;
+                    data[name] = changes[key];
+                }
+            }
+            if (!isPhantom) {
+                
+                data[record.idProperty] = record.getId();
+            }
         }
-        return params;
-    },
+        return data;
+    }
+});
+
+
+Ext.define('Ext.util.Floating', {
+
+    uses: ['Ext.Layer', 'Ext.window.Window'],
 
     
-    setupMethod: function(options, method){
-        if (this.isFormUpload(options)) {
-            return 'POST';
+    focusOnToFront: true,
+
+    
+    shadow: 'sides',
+
+    constructor: function(config) {
+        var me = this;
+        
+        me.floating = true;
+        me.el = Ext.create('Ext.Layer', Ext.apply({}, config, {
+            hideMode: me.hideMode,
+            hidden: me.hidden,
+            shadow: Ext.isDefined(me.shadow) ? me.shadow : 'sides',
+            shadowOffset: me.shadowOffset,
+            constrain: false,
+            shim: me.shim === false ? false : undefined
+        }), me.el);
+    },
+
+    onFloatRender: function() {
+        var me = this;
+        me.zIndexParent = me.getZIndexParent();
+        me.setFloatParent(me.ownerCt);
+        delete me.ownerCt;
+
+        if (me.zIndexParent) {
+            me.zIndexParent.registerFloatingItem(me);
+        } else {
+            Ext.WindowManager.register(me);
         }
-        return method;
     },
 
-    
-    setupHeaders: function(xhr, options, data, params){
-        var me = this,
-            headers = Ext.apply({}, options.headers || {}, me.defaultHeaders || {}),
-            contentType = me.defaultPostHeader,
-            jsonData = options.jsonData,
-            xmlData = options.xmlData,
-            key,
-            header;
+    setFloatParent: function(floatParent) {
+        var me = this;
 
-        if (!headers['Content-Type'] && (data || params)) {
-            if (data) {
-                if (options.rawData) {
-                    contentType = 'text/plain';
-                } else {
-                    if (xmlData && Ext.isDefined(xmlData)) {
-                        contentType = 'text/xml';
-                    } else if (jsonData && Ext.isDefined(jsonData)) {
-                        contentType = 'application/json';
-                    }
-                }
-            }
-            headers['Content-Type'] = contentType;
+        
+        if (me.floatParent) {
+            me.mun(me.floatParent, {
+                hide: me.onFloatParentHide,
+                show: me.onFloatParentShow,
+                scope: me
+            });
+        }
+
+        me.floatParent = floatParent;
+
+        
+        if (floatParent) {
+            me.mon(me.floatParent, {
+                hide: me.onFloatParentHide,
+                show: me.onFloatParentShow,
+                scope: me
+            });
         }
 
-        if (me.useDefaultXhrHeader && !headers['X-Requested-With']) {
-            headers['X-Requested-With'] = me.defaultXhrHeader;
-        }
         
-        try{
-            for (key in headers) {
-                if (headers.hasOwnProperty(key)) {
-                    header = headers[key];
-                    xhr.setRequestHeader(key, header);
-                }
-
-            }
-        } catch(e) {
-            me.fireEvent('exception', key, header);
+        
+        if ((me.constrain || me.constrainHeader) && !me.constrainTo) {
+            me.constrainTo = floatParent ? floatParent.getTargetEl() : me.container;
         }
-        return headers;
     },
 
-    
-    getXhrInstance: (function(){
-        var options = [function(){
-            return new XMLHttpRequest();
-        }, function(){
-            return new ActiveXObject('MSXML2.XMLHTTP.3.0');
-        }, function(){
-            return new ActiveXObject('MSXML2.XMLHTTP');
-        }, function(){
-            return new ActiveXObject('Microsoft.XMLHTTP');
-        }], i = 0,
-            len = options.length,
-            xhr;
-
-        for(; i < len; ++i) {
-            try{
-                xhr = options[i];
-                xhr();
-                break;
-            }catch(e){}
+    onFloatParentHide: function() {
+        var me = this;
+        
+        if (me.hideOnParentHide !== false) {
+            me.showOnParentShow = me.isVisible();
+            me.hide();
         }
-        return xhr;
-    })(),
+    },
 
-    
-    isLoading : function(request) {
-        if (!(request && request.xhr)) {
-            return false;
+    onFloatParentShow: function() {
+        if (this.showOnParentShow) {
+            delete this.showOnParentShow;
+            this.show();
         }
-        
-        var state = request.xhr.readyState;
-        return !(state === 0 || state == 4);
     },
 
     
-    abort : function(request) {
-        var me = this,
-            requests = me.requests,
-            id;
+    getZIndexParent: function() {
+        var p = this.ownerCt,
+            c;
 
-        if (request && me.isLoading(request)) {
-            
-            request.xhr.onreadystatechange = null;
-            request.xhr.abort();
-            me.clearTimeout(request);
-            if (!request.timedout) {
-                request.aborted = true;
+        if (p) {
+            while (p) {
+                c = p;
+                p = p.ownerCt;
             }
-            me.onComplete(request);
-            me.cleanup(request);
-        } else if (!request) {
-            for(id in requests) {
-                if (requests.hasOwnProperty(id)) {
-                    me.abort(requests[id]);
-                }
+            if (c.floating) {
+                return c;
             }
         }
     },
 
     
-    onStateChange : function(request) {
-        if (request.xhr.readyState == 4) {
-            this.clearTimeout(request);
-            this.onComplete(request);
-            this.cleanup(request);
+    
+    
+    
+    
+    setZIndex: function(index) {
+        var me = this;
+        me.el.setZIndex(index);
+
+        
+        index += 10;
+
+        
+        
+        if (me.floatingItems) {
+            index = Math.floor(me.floatingItems.setBase(index) / 100) * 100 + 10000;
         }
+        return index;
     },
 
     
-    clearTimeout: function(request){
-        clearTimeout(request.timeout);
-        delete request.timeout;
-    },
+    doConstrain: function(constrainTo) {
+        var me = this,
+            vector = me.getConstrainVector(constrainTo || me.el.getScopeParent()),
+            xy;
 
-    
-    cleanup: function(request){
-        request.xhr = null;
-        delete request.xhr;
+        if (vector) {
+            xy = me.getPosition();
+            xy[0] += vector[0];
+            xy[1] += vector[1];
+            me.setPosition(xy);
+        }
     },
 
+
     
-    onComplete : function(request) {
+    getConstrainVector: function(constrainTo){
         var me = this,
-            options = request.options,
-            result = me.parseStatus(request.xhr.status),
-            success = result.success,
-            response;
+            el;
 
-        if (success) {
-            response = me.createResponse(request);
-            me.fireEvent('requestcomplete', me, response, options);
-            Ext.callback(options.success, options.scope, [response, options]);
-        } else {
-            if (result.isException || request.aborted || request.timedout) {
-                response = me.createException(request);
-            } else {
-                response = me.createResponse(request);
-            }
-            me.fireEvent('requestexception', me, response, options);
-            Ext.callback(options.failure, options.scope, [response, options]);
+        if (me.constrain || me.constrainHeader) {
+            el = me.constrainHeader ? me.header.el : me.el;
+            constrainTo = constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container;
+            return el.getConstrainVector(constrainTo);
         }
-        Ext.callback(options.callback, options.scope, [options, success, response]);
-        delete me.requests[request.id];
-        return response;
     },
 
     
-    parseStatus: function(status) {
-        
-        status = status == 1223 ? 204 : status;
-
-        var success = (status >= 200 && status < 300) || status == 304,
-            isException = false;
-
-        if (!success) {
-            switch (status) {
-                case 12002:
-                case 12029:
-                case 12030:
-                case 12031:
-                case 12152:
-                case 13030:
-                    isException = true;
-                    break;
-            }
+    alignTo: function(element, position, offsets) {
+        if (element.isComponent) {
+            element = element.getEl();
         }
-        return {
-            success: success,
-            isException: isException
-        };
+        var xy = this.el.getAlignToXY(element, position, offsets);
+        this.setPagePosition(xy);
+        return this;
     },
 
     
-    createResponse : function(request) {
-        var xhr = request.xhr,
-            headers = {},
-            lines = xhr.getAllResponseHeaders().replace(/\r\n/g, '\n').split('\n'),
-            count = lines.length,
-            line, index, key, value, response;
+    toFront: function(preventFocus) {
+        var me = this;
 
-        while (count--) {
-            line = lines[count];
-            index = line.indexOf(':');
-            if(index >= 0) {
-                key = line.substr(0, index).toLowerCase();
-                if (line.charAt(index + 1) == ' ') {
-                    ++index;
-                }
-                headers[key] = line.substr(index + 1);
+        
+        
+        if (me.zIndexParent) {
+            me.zIndexParent.toFront(true);
+        }
+        if (me.zIndexManager.bringToFront(me)) {
+            if (!Ext.isDefined(preventFocus)) {
+                preventFocus = !me.focusOnToFront;
+            }
+            if (!preventFocus) {
+                
+                
+                
+                me.focus(false, true);
             }
         }
+        return me;
+    },
 
-        request.xhr = null;
-        delete request.xhr;
-
-        response = {
-            request: request,
-            requestId : request.id,
-            status : xhr.status,
-            statusText : xhr.statusText,
-            getResponseHeader : function(header){ return headers[header.toLowerCase()]; },
-            getAllResponseHeaders : function(){ return headers; },
-            responseText : xhr.responseText,
-            responseXML : xhr.responseXML
-        };
-
-        
+    
+    setActive: function(active, newActive) {
+        var me = this;
         
-        xhr = null;
-        return response;
+        if (active) {
+            if (me.el.shadow && !me.maximized) {
+                me.el.enableShadow(true);
+            }
+            me.fireEvent('activate', me);
+        } else {
+            
+            
+            if ((me instanceof Ext.window.Window) && (newActive instanceof Ext.window.Window)) {
+                me.el.disableShadow();
+            }
+            me.fireEvent('deactivate', me);
+        }
     },
 
     
-    createException : function(request) {
-        return {
-            request : request,
-            requestId : request.id,
-            status : request.aborted ? -1 : 0,
-            statusText : request.aborted ? 'transaction aborted' : 'communication failure',
-            aborted: request.aborted,
-            timedout: request.timedout
-        };
-    }
-});
-
-
-Ext.define('Ext.Ajax', {
-    extend: 'Ext.data.Connection',
-    singleton: true,
+    toBack: function() {
+        this.zIndexManager.sendToBack(this);
+        return this;
+    },
 
     
-    
-    
-    
-    
-    
+    center: function() {
+        var me = this,
+            xy = me.el.getAlignToXY(me.container, 'c-c');
+        me.setPagePosition(xy);
+        return me;
+    },
 
     
+    syncShadow : function(){
+        if (this.floating) {
+            this.el.sync(true);
+        }
+    },
 
     
-    
-    
-    
-    
-    
+    fitContainer: function() {
+        var parent = this.floatParent,
+            container = parent ? parent.getTargetEl() : this.container,
+            size = container.getViewSize(false);
 
-    
-    autoAbort : false
+        this.setSize(size);
+    }
 });
 
-Ext.define('Ext.data.Association', {
-    
-
-    
+Ext.define('Ext.layout.Layout', {
 
     
-    primaryKey: 'id',
 
     
-    
-    
 
-    defaultReaderType: 'json',
+    isLayout: true,
+    initialized: false,
 
     statics: {
-        create: function(association){
-            if (!association.isAssociation) {
-                if (Ext.isString(association)) {
-                    association = {
-                        type: association
-                    };
+        create: function(layout, defaultType) {
+            var type;
+            if (layout instanceof Ext.layout.Layout) {
+                return Ext.createByAlias('layout.' + layout);
+            } else {
+                if (!layout || typeof layout === 'string') {
+                    type = layout || defaultType;
+                    layout = {};                    
                 }
-
-                switch (association.type) {
-                    case 'belongsTo':
-                        return Ext.create('Ext.data.BelongsToAssociation', association);
-                    case 'hasMany':
-                        return Ext.create('Ext.data.HasManyAssociation', association);
-                    
-
-
-                    default:
-                        Ext.Error.raise('Unknown Association type: "' + association.type + '"');
+                else {
+                    type = layout.type || defaultType;
                 }
+                return Ext.createByAlias('layout.' + type, layout || {});
             }
-            return association;
         }
     },
 
-    constructor: function(config) {
+    constructor : function(config) {
+        this.id = Ext.id(null, this.type + '-');
         Ext.apply(this, config);
+    },
 
-        var types           = Ext.ModelManager.types,
-            ownerName       = config.ownerModel,
-            associatedName  = config.associatedModel,
-            ownerModel      = types[ownerName],
-            associatedModel = types[associatedName],
-            ownerProto;
+    
+    layout : function() {
+        var me = this;
+        me.layoutBusy = true;
+        me.initLayout();
 
-        if (ownerModel === undefined) {
-            Ext.Error.raise("The configured ownerModel was not valid (you tried " + ownerName + ")");
+        if (me.beforeLayout.apply(me, arguments) !== false) {
+            me.layoutCancelled = false;
+            me.onLayout.apply(me, arguments);
+            me.childrenChanged = false;
+            me.owner.needsLayout = false;
+            me.layoutBusy = false;
+            me.afterLayout.apply(me, arguments);
         }
-        if (associatedModel === undefined) {
-            Ext.Error.raise("The configured associatedModel was not valid (you tried " + associatedName + ")");
+        else {
+            me.layoutCancelled = true;
         }
+        me.layoutBusy = false;
+        me.doOwnerCtLayouts();
+    },
 
-        this.ownerModel = ownerModel;
-        this.associatedModel = associatedModel;
-
-        
-
-        
+    beforeLayout : function() {
+        this.renderChildren();
+        return true;
+    },
 
-        Ext.applyIf(this, {
-            ownerName : ownerName,
-            associatedName: associatedName
-        });
+    renderChildren: function () {
+        this.renderItems(this.getLayoutItems(), this.getRenderTarget());
     },
 
     
-    getReader: function(){
+    renderItems : function(items, target) {
         var me = this,
-            reader = me.reader,
-            model = me.associatedModel;
+            ln = items.length,
+            i = 0,
+            item;
 
-        if (reader) {
-            if (Ext.isString(reader)) {
-                reader = {
-                    type: reader
-                };
-            }
-            if (reader.isReader) {
-                reader.setModel(model);
+        for (; i < ln; i++) {
+            item = items[i];
+            if (item && !item.rendered) {
+                me.renderItem(item, target, i);
+            } else if (!me.isValidParent(item, target, i)) {
+                me.moveItem(item, target, i);
             } else {
-                Ext.applyIf(reader, {
-                    model: model,
-                    type : me.defaultReaderType
-                });
+                
+                me.configureItem(item);
             }
-            me.reader = Ext.createByAlias('reader.' + reader.type, reader);
         }
-        return me.reader || null;
-    }
-});
-
+    },
 
-Ext.define('Ext.ModelManager', {
-    extend: 'Ext.AbstractManager',
-    alternateClassName: 'Ext.ModelMgr',
-    requires: ['Ext.data.Association'],
-    
-    singleton: true,
-    
-    typeName: 'mtype',
-    
-    
-    associationStack: [],
     
-    
-    registerType: function(name, config) {
-        var proto = config.prototype,
-            model;
-        if (proto && proto.isModel) {
-            
-            model = config;
-        } else {
-            
-            if (!config.extend) {
-                config.extend = 'Ext.data.Model';
+    isValidParent : function(item, target, position) {
+        var dom = item.el ? item.el.dom : Ext.getDom(item);
+        if (dom && target && target.dom) {
+            if (Ext.isNumber(position) && dom !== target.dom.childNodes[position]) {
+                return false;
             }
-            model = Ext.define(name, config);
+            return (dom.parentNode == (target.dom || target));
         }
-        this.types[name] = model;
-        return model;
+        return false;
     },
+
     
-    
-    onModelDefined: function(model) {
-        var stack  = this.associationStack,
-            length = stack.length,
-            create = [],
-            association, i, created;
-        
-        for (i = 0; i < length; i++) {
-            association = stack[i];
-            
-            if (association.associatedModel == model.modelName) {
-                create.push(association);
+    renderItem : function(item, target, position) {
+        var me = this;
+        if (!item.rendered) {
+            if (me.itemCls) {
+                item.addCls(me.itemCls);
             }
+            if (me.owner.itemCls) {
+                item.addCls(me.owner.itemCls);
+            }
+            item.render(target, position);
+            me.configureItem(item);
+            me.childrenChanged = true;
         }
+    },
+
+    
+    moveItem : function(item, target, position) {
         
-        for (i = 0, length = create.length; i < length; i++) {
-            created = create[i];
-            this.types[created.ownerModel].prototype.associations.add(Ext.data.Association.create(created));
-            Ext.Array.remove(stack, created);
+        target = target.dom || target;
+        if (typeof position == 'number') {
+            position = target.childNodes[position];
         }
+        target.insertBefore(item.el.dom, position || null);
+        item.container = Ext.get(target);
+        this.configureItem(item);
+        this.childrenChanged = true;
     },
+
     
-    
-    registerDeferredAssociation: function(association){
-        this.associationStack.push(association);
+    initLayout : function() {
+        var me = this,
+            targetCls = me.targetCls;
+            
+        if (!me.initialized && !Ext.isEmpty(targetCls)) {
+            me.getTarget().addCls(targetCls);
+        }
+        me.initialized = true;
     },
+
     
-    
-    getModel: function(id) {
-        var model = id;
-        if (typeof model == 'string') {
-            model = this.types[model];
-        }
-        return model;
+    setOwner : function(owner) {
+        this.owner = owner;
     },
+
     
+    getLayoutItems : function() {
+        return [];
+    },
+
     
-    create: function(config, name, id) {
-        var con = typeof name == 'function' ? name : this.types[name || config.name];
-        
-        return new con(config, id);
-    }
-}, function() {
+    configureItem: Ext.emptyFn,
     
     
-    Ext.regModel = function() {
-        if (Ext.isDefined(Ext.global.console)) {
-            Ext.global.console.warn('Ext.regModel has been deprecated. Models can now be created by extending Ext.data.Model: Ext.define("MyModel", {extend: "Ext.data.Model", fields: []});.');
-        }
-        return this.ModelManager.registerType.apply(this.ModelManager, arguments);
-    };
-});
+    onLayout : Ext.emptyFn,
+    afterLayout : Ext.emptyFn,
+    onRemove : Ext.emptyFn,
+    onDestroy : Ext.emptyFn,
+    doOwnerCtLayouts : Ext.emptyFn,
 
-  
-Ext.define('Ext.app.Controller', {
     
+    afterRemove : function(item) {
+        var el = item.el,
+            owner = this.owner,
+            itemCls = this.itemCls,
+            ownerCls = owner.itemCls;
+            
+        
+        if (item.rendered && !item.isDestroyed) {
+            if (itemCls) {
+                el.removeCls(itemCls);
+            }
+            if (ownerCls) {
+                el.removeCls(ownerCls);
+            }
+        }
 
-    mixins: {
-        observable: 'Ext.util.Observable'
+        
+        
+        
+        delete item.layoutManagedWidth;
+        delete item.layoutManagedHeight;
     },
 
-    onClassExtended: function(cls, data) {
-        var className = Ext.getClassName(cls),
-            match = className.match(/^(.*)\.controller\./);
-
-        if (match !== null) {
-            var namespace = Ext.Loader.getPrefix(className) || match[1],
-                onBeforeClassCreated = data.onBeforeClassCreated,
-                requires = [],
-                modules = ['model', 'view', 'store'],
-                prefix;
+    
+    destroy : function() {
+        var targetCls = this.targetCls,
+            target;
+        
+        if (!Ext.isEmpty(targetCls)) {
+            target = this.getTarget();
+            if (target) {
+                target.removeCls(targetCls);
+            }
+        }
+        this.onDestroy();
+    }
+});
 
-            data.onBeforeClassCreated = function(cls, data) {
-                var i, ln, module,
-                    items, j, subLn, item;
+Ext.define('Ext.ZIndexManager', {
 
-                for (i = 0,ln = modules.length; i < ln; i++) {
-                    module = modules[i];
+    alternateClassName: 'Ext.WindowGroup',
 
-                    items = Ext.Array.from(data[module + 's']);
+    statics: {
+        zBase : 9000
+    },
 
-                    for (j = 0,subLn = items.length; j < subLn; j++) {
-                        item = items[j];
+    constructor: function(container) {
+        var me = this;
 
-                        prefix = Ext.Loader.getPrefix(item);
+        me.list = {};
+        me.zIndexStack = [];
+        me.front = null;
 
-                        if (prefix === '' || prefix === item) {
-                            requires.push(namespace + '.' + module + '.' + item);
-                        }
-                        else {
-                            requires.push(item);
-                        }
-                    }
-                }
+        if (container) {
 
-                Ext.require(requires, Ext.Function.pass(onBeforeClassCreated, arguments, this));
-            };
+            
+            if (container.isContainer) {
+                container.on('resize', me._onContainerResize, me);
+                me.zseed = Ext.Number.from(container.getEl().getStyle('zIndex'), me.getNextZSeed());
+                
+                me.targetEl = container.getTargetEl();
+                me.container = container;
+            }
+            
+            else {
+                Ext.EventManager.onWindowResize(me._onContainerResize, me);
+                me.zseed = me.getNextZSeed();
+                me.targetEl = Ext.get(container);
+            }
+        }
+        
+        
+        else {
+            Ext.EventManager.onWindowResize(me._onContainerResize, me);
+            me.zseed = me.getNextZSeed();
+            Ext.onDocumentReady(function() {
+                me.targetEl = Ext.getBody();
+            });
         }
     },
 
-    constructor: function(config) {
-        this.mixins.observable.constructor.call(this, config);
-
-        Ext.apply(this, config || {});
-
-        this.createGetters('model', this.models);
-        this.createGetters('store', this.stores);
-        this.createGetters('view', this.views);
+    getNextZSeed: function() {
+        return (Ext.ZIndexManager.zBase += 10000);
+    },
 
-        if (this.refs) {
-            this.ref(this.refs);
-        }
+    setBase: function(baseZIndex) {
+        this.zseed = baseZIndex;
+        return this.assignZIndices();
     },
 
     
-    init: function(application) {},
-    
-    onLaunch: function(application) {},
-
-    createGetters: function(type, refs) {
-        type = Ext.String.capitalize(type);
-        Ext.Array.each(refs, function(ref) {
-            var fn = 'get',
-                parts = ref.split('.');
+    assignZIndices: function() {
+        var a = this.zIndexStack,
+            len = a.length,
+            i = 0,
+            zIndex = this.zseed,
+            comp;
 
-            
-            Ext.Array.each(parts, function(part) {
-                fn += Ext.String.capitalize(part);
-            });
-            fn += type;
+        for (; i < len; i++) {
+            comp = a[i];
+            if (comp && !comp.hidden) {
 
-            if (!this[fn]) {
-                this[fn] = Ext.Function.pass(this['get' + type], [ref], this);
+                
+                
+                
+                
+                
+                
+                
+                zIndex = comp.setZIndex(zIndex);
             }
-            
-            this[fn](ref);
-        },
-        this);
+        }
+        this._activateLast();
+        return zIndex;
     },
 
-    ref: function(refs) {
-        var me = this;
-        refs = Ext.Array.from(refs);
-        Ext.Array.each(refs, function(info) {
-            var ref = info.ref,
-                fn = 'get' + Ext.String.capitalize(ref);
-            if (!me[fn]) {
-                me[fn] = Ext.Function.pass(me.getRef, [ref, info], me);
+    
+    _setActiveChild: function(comp) {
+        if (comp !== this.front) {
+
+            if (this.front) {
+                this.front.setActive(false, comp);
             }
-        });
+            this.front = comp;
+            if (comp) {
+                comp.setActive(true);
+                if (comp.modal) {
+                    this._showModalMask(comp);
+                }
+            }
+        }
     },
 
-    getRef: function(ref, info, config) {
-        this.refCache = this.refCache || {};
-        info = info || {};
-        config = config || {};
+    
+    _activateLast: function(justHidden) {
+        var comp,
+            lastActivated = false,
+            i;
 
-        Ext.apply(info, config);
+        
+        
+        
+        for (i = this.zIndexStack.length-1; i >= 0; --i) {
+            comp = this.zIndexStack[i];
+            if (!comp.hidden) {
+                if (!lastActivated) {
+                    this._setActiveChild(comp);
+                    lastActivated = true;
+                }
 
-        if (info.forceCreate) {
-            return Ext.ComponentManager.create(info, 'component');
+                
+                if (comp.modal) {
+                    this._showModalMask(comp);
+                    return;
+                }
+            }
         }
 
-        var me = this,
-            selector = info.selector,
-            cached = me.refCache[ref];
+        
+        
+        this._hideModalMask();
+        if (!lastActivated) {
+            this._setActiveChild(null);
+        }
+    },
 
-        if (!cached) {
-            me.refCache[ref] = cached = Ext.ComponentQuery.query(info.selector)[0];
-            if (!cached && info.autoCreate) {
-                me.refCache[ref] = cached = Ext.ComponentManager.create(info, 'component');
-            }
-            if (cached) {
-                cached.on('beforedestroy', function() {
-                    me.refCache[ref] = null;
-                });
-            }
+    _showModalMask: function(comp) {
+        var zIndex = comp.el.getStyle('zIndex') - 4,
+            maskTarget = comp.floatParent ? comp.floatParent.getTargetEl() : Ext.get(comp.getEl().dom.parentNode),
+            parentBox;
+        
+        if (!maskTarget) {
+            return;
         }
+        
+        parentBox = maskTarget.getBox();
 
-        return cached;
+        if (!this.mask) {
+            this.mask = Ext.getBody().createChild({
+                cls: Ext.baseCSSPrefix + 'mask'
+            });
+            this.mask.setVisibilityMode(Ext.Element.DISPLAY);
+            this.mask.on('click', this._onMaskClick, this);
+        }
+        if (maskTarget.dom === document.body) {
+            parentBox.height = Ext.Element.getViewHeight();
+        }
+        maskTarget.addCls(Ext.baseCSSPrefix + 'body-masked');
+        this.mask.setBox(parentBox);
+        this.mask.setStyle('zIndex', zIndex);
+        this.mask.show();
     },
 
-    control: function(selectors, listeners) {
-        this.application.control(selectors, listeners, this);
+    _hideModalMask: function() {
+        if (this.mask && this.mask.dom.parentNode) {
+            Ext.get(this.mask.dom.parentNode).removeCls(Ext.baseCSSPrefix + 'body-masked');
+            this.mask.hide();
+        }
     },
 
-    getController: function(name) {
-        return this.application.getController(name);
+    _onMaskClick: function() {
+        if (this.front) {
+            this.front.focus();
+        }
     },
 
-    getStore: function(name) {
-        return this.application.getStore(name);
+    _onContainerResize: function() {
+        if (this.mask && this.mask.isVisible()) {
+            this.mask.setSize(Ext.get(this.mask.dom.parentNode).getViewSize(true));
+        }
     },
 
-    getModel: function(model) {
-        return this.application.getModel(model);
+    
+    register : function(comp) {
+        if (comp.zIndexManager) {
+            comp.zIndexManager.unregister(comp);
+        }
+        comp.zIndexManager = this;
+
+        this.list[comp.id] = comp;
+        this.zIndexStack.push(comp);
+        comp.on('hide', this._activateLast, this);
     },
 
-    getView: function(view) {
-        return this.application.getView(view);
-    }
-});
+    
+    unregister : function(comp) {
+        delete comp.zIndexManager;
+        if (this.list && this.list[comp.id]) {
+            delete this.list[comp.id];
+            comp.un('hide', this._activateLast);
+            Ext.Array.remove(this.zIndexStack, comp);
 
+            
+            this._activateLast(comp);
+        }
+    },
 
-Ext.define('Ext.data.SortTypes', {
-    
-    singleton: true,
-    
     
-    none : function(s) {
-        return s;
+    get : function(id) {
+        return typeof id == "object" ? id : this.list[id];
     },
 
-    
-    stripTagsRE : /<\/?[^>]+>/gi,
+   
+    bringToFront : function(comp) {
+        comp = this.get(comp);
+        if (comp !== this.front) {
+            Ext.Array.remove(this.zIndexStack, comp);
+            this.zIndexStack.push(comp);
+            this.assignZIndices();
+            return true;
+        }
+        if (comp.modal) {
+            this._showModalMask(comp);
+        }
+        return false;
+    },
 
     
-    asText : function(s) {
-        return String(s).replace(this.stripTagsRE, "");
+    sendToBack : function(comp) {
+        comp = this.get(comp);
+        Ext.Array.remove(this.zIndexStack, comp);
+        this.zIndexStack.unshift(comp);
+        this.assignZIndices();
+        return comp;
     },
 
     
-    asUCText : function(s) {
-        return String(s).toUpperCase().replace(this.stripTagsRE, "");
+    hideAll : function() {
+        for (var id in this.list) {
+            if (this.list[id].isComponent && this.list[id].isVisible()) {
+                this.list[id].hide();
+            }
+        }
     },
 
     
-    asUCString : function(s) {
-        return String(s).toUpperCase();
+    hide: function() {
+        var i = 0,
+            ln = this.zIndexStack.length,
+            comp;
+
+        this.tempHidden = [];
+        for (; i < ln; i++) {
+            comp = this.zIndexStack[i];
+            if (comp.isVisible()) {
+                this.tempHidden.push(comp);
+                comp.hide();
+            }
+        }
     },
 
     
-    asDate : function(s) {
-        if(!s){
-            return 0;
-        }
-        if(Ext.isDate(s)){
-            return s.getTime();
+    show: function() {
+        var i = 0,
+            ln = this.tempHidden.length,
+            comp,
+            x,
+            y;
+
+        for (; i < ln; i++) {
+            comp = this.tempHidden[i];
+            x = comp.x;
+            y = comp.y;
+            comp.show();
+            comp.setPosition(x, y);
         }
-        return Date.parse(String(s));
+        delete this.tempHidden;
     },
 
     
-    asFloat : function(s) {
-        var val = parseFloat(String(s).replace(/,/g, ""));
-        return isNaN(val) ? 0 : val;
+    getActive : function() {
+        return this.front;
     },
 
     
-    asInt : function(s) {
-        var val = parseInt(String(s).replace(/,/g, ""), 10);
-        return isNaN(val) ? 0 : val;
-    }
-});
+    getBy : function(fn, scope) {
+        var r = [],
+            i = 0,
+            len = this.zIndexStack.length,
+            comp;
+
+        for (; i < len; i++) {
+            comp = this.zIndexStack[i];
+            if (fn.call(scope||comp, comp) !== false) {
+                r.push(comp);
+            }
+        }
+        return r;
+    },
 
-Ext.define('Ext.data.Errors', {
-    extend: 'Ext.util.MixedCollection',
-    
     
-    isValid: function() {
-        return this.length === 0;
+    each : function(fn, scope) {
+        var comp;
+        for (var id in this.list) {
+            comp = this.list[id];
+            if (comp.isComponent && fn.call(scope || comp, comp) === false) {
+                return;
+            }
+        }
     },
+
     
+    eachBottomUp: function (fn, scope) {
+        var comp,
+            stack = this.zIndexStack,
+            i, n;
+
+        for (i = 0, n = stack.length ; i < n; i++) {
+            comp = stack[i];
+            if (comp.isComponent && fn.call(scope || comp, comp) === false) {
+                return;
+            }
+        }
+    },
+
     
-    getByField: function(fieldName) {
-        var errors = [],
-            error, field, i;
-            
-        for (i = 0; i < this.length; i++) {
-            error = this.items[i];
-            
-            if (error.field == fieldName) {
-                errors.push(error);
+    eachTopDown: function (fn, scope) {
+        var comp,
+            stack = this.zIndexStack,
+            i;
+
+        for (i = stack.length ; i-- > 0; ) {
+            comp = stack[i];
+            if (comp.isComponent && fn.call(scope || comp, comp) === false) {
+                return;
             }
         }
-        
-        return errors;
+    },
+
+    destroy: function() {
+        this.each(function(c) {
+            c.destroy();
+        });
+        delete this.zIndexStack;
+        delete this.list;
+        delete this.container;
+        delete this.targetEl;
     }
+}, function() {
+    
+    Ext.WindowManager = Ext.WindowMgr = new this();
 });
 
 
-Ext.define('Ext.data.Operation', {
-    
-    synchronous: true,
-    
-    
-    action: undefined,
-    
-    
-    filters: undefined,
-    
-    
-    sorters: undefined,
-    
-    
-    group: undefined,
-    
-    
-    start: undefined,
-    
-    
-    limit: undefined,
-    
-    
-    batch: undefined,
-        
-    
-    started: false,
-    
-    
-    running: false,
-    
-    
-    complete: false,
-    
-    
-    success: undefined,
-    
-    
-    exception: false,
-    
+Ext.define('Ext.layout.container.boxOverflow.None', {
     
-    error: undefined,
+    alternateClassName: 'Ext.layout.boxOverflow.None',
     
-    constructor: function(config) {
+    constructor: function(layout, config) {
+        this.layout = layout;
         Ext.apply(this, config || {});
     },
+
+    handleOverflow: Ext.emptyFn,
+
+    clearOverflow: Ext.emptyFn,
     
+    onRemove: Ext.emptyFn,
+
     
-    setStarted: function() {
-        this.started = true;
-        this.running = true;
-    },
-    
-    
-    setCompleted: function() {
-        this.complete = true;
-        this.running  = false;
+    getItem: function(item) {
+        return this.layout.owner.getComponent(item);
     },
     
+    onRemove: Ext.emptyFn
+});
+
+Ext.define('Ext.util.KeyMap', {
+    alternateClassName: 'Ext.KeyMap',
+
     
-    setSuccessful: function() {
-        this.success = true;
+    constructor: function(el, binding, eventName){
+        var me = this;
+
+        Ext.apply(me, {
+            el: Ext.get(el),
+            eventName: eventName || me.eventName,
+            bindings: []
+        });
+        if (binding) {
+            me.addBinding(binding);
+        }
+        me.enable();
     },
+
+    eventName: 'keydown',
+
     
-    
-    setException: function(error) {
-        this.exception = true;
-        this.success = false;
-        this.running = false;
-        this.error = error;
+    addBinding : function(binding){
+        if (Ext.isArray(binding)) {
+            Ext.each(binding, this.addBinding, this);
+            return;
+        }
+
+        var keyCode = binding.key,
+            processed = false,
+            key,
+            keys,
+            keyString,
+            i,
+            len;
+
+        if (Ext.isString(keyCode)) {
+            keys = [];
+            keyString = keyCode.toUpperCase();
+
+            for (i = 0, len = keyString.length; i < len; ++i){
+                keys.push(keyString.charCodeAt(i));
+            }
+            keyCode = keys;
+            processed = true;
+        }
+
+        if (!Ext.isArray(keyCode)) {
+            keyCode = [keyCode];
+        }
+
+        if (!processed) {
+            for (i = 0, len = keyCode.length; i < len; ++i) {
+                key = keyCode[i];
+                if (Ext.isString(key)) {
+                    keyCode[i] = key.toUpperCase().charCodeAt(0);
+                }
+            }
+        }
+
+        this.bindings.push(Ext.apply({
+            keyCode: keyCode
+        }, binding));
     },
+
     
-    
-    hasException: function() {
-        return this.exception === true;
+    handleKeyDown: function(event) {
+        if (this.enabled) { 
+            var bindings = this.bindings,
+                i = 0,
+                len = bindings.length;
+
+            event = this.processEvent(event);
+            for(; i < len; ++i){
+                this.processBinding(bindings[i], event);
+            }
+        }
     },
+
     
-    
-    getError: function() {
-        return this.error;
+    processEvent: function(event){
+        return event;
     },
+
     
-    
-    getRecords: function() {
-        var resultSet = this.getResultSet();
-        
-        return (resultSet === undefined ? this.records : resultSet.records);
+    processBinding: function(binding, event){
+        if (this.checkModifiers(binding, event)) {
+            var key = event.getKey(),
+                handler = binding.fn || binding.handler,
+                scope = binding.scope || this,
+                keyCode = binding.keyCode,
+                defaultEventAction = binding.defaultEventAction,
+                i,
+                len,
+                keydownEvent = new Ext.EventObjectImpl(event);
+
+
+            for (i = 0, len = keyCode.length; i < len; ++i) {
+                if (key === keyCode[i]) {
+                    if (handler.call(scope, key, event) !== true && defaultEventAction) {
+                        keydownEvent[defaultEventAction]();
+                    }
+                    break;
+                }
+            }
+        }
     },
+
     
-    
-    getResultSet: function() {
-        return this.resultSet;
+    checkModifiers: function(binding, e){
+        var keys = ['shift', 'ctrl', 'alt'],
+            i = 0,
+            len = keys.length,
+            val, key;
+
+        for (; i < len; ++i){
+            key = keys[i];
+            val = binding[key];
+            if (!(val === undefined || (val === e[key + 'Key']))) {
+                return false;
+            }
+        }
+        return true;
     },
+
     
-    
-    isStarted: function() {
-        return this.started === true;
+    on: function(key, fn, scope) {
+        var keyCode, shift, ctrl, alt;
+        if (Ext.isObject(key) && !Ext.isArray(key)) {
+            keyCode = key.key;
+            shift = key.shift;
+            ctrl = key.ctrl;
+            alt = key.alt;
+        } else {
+            keyCode = key;
+        }
+        this.addBinding({
+            key: keyCode,
+            shift: shift,
+            ctrl: ctrl,
+            alt: alt,
+            fn: fn,
+            scope: scope
+        });
     },
+
     
-    
-    isRunning: function() {
-        return this.running === true;
+    isEnabled : function(){
+        return this.enabled;
     },
+
     
-    
-    isComplete: function() {
-        return this.complete === true;
+    enable: function(){
+        var me = this;
+        
+        if (!me.enabled) {
+            me.el.on(me.eventName, me.handleKeyDown, me);
+            me.enabled = true;
+        }
     },
+
     
-    
-    wasSuccessful: function() {
-        return this.isComplete() && this.success === true;
+    disable: function(){
+        var me = this;
+        
+        if (me.enabled) {
+            me.el.removeListener(me.eventName, me.handleKeyDown, me);
+            me.enabled = false;
+        }
     },
+
     
-    
-    setBatch: function(batch) {
-        this.batch = batch;
+    setDisabled : function(disabled){
+        if (disabled) {
+            this.disable();
+        } else {
+            this.enable();
+        }
     },
+
     
-    
-    allowWrite: function() {
-        return this.action != 'read';
+    destroy: function(removeEl){
+        var me = this;
+
+        me.bindings = [];
+        me.disable();
+        if (removeEl === true) {
+            me.el.remove();
+        }
+        delete me.el;
     }
 });
 
-Ext.define('Ext.data.validations', {
-    singleton: true,
-    
-    
-    presenceMessage: 'must be present',
-    
+Ext.define('Ext.util.ClickRepeater', {
+    extend: 'Ext.util.Observable',
+
     
-    lengthMessage: 'is the wrong length',
+    constructor : function(el, config){
+        this.el = Ext.get(el);
+        this.el.unselectable();
+
+        Ext.apply(this, config);
+
+        this.addEvents(
+        
+        "mousedown",
+        
+        "click",
+        
+        "mouseup"
+        );
+
+        if(!this.disabled){
+            this.disabled = true;
+            this.enable();
+        }
+
+        
+        if(this.handler){
+            this.on("click", this.handler,  this.scope || this);
+        }
+
+        this.callParent();
+    },
+
     
+
     
-    formatMessage: 'is the wrong format',
+
     
+
     
-    inclusionMessage: 'is not included in the list of acceptable values',
+    interval : 20,
+
     
+    delay: 250,
+
     
-    exclusionMessage: 'is not an acceptable value',
+    preventDefault : true,
     
+    stopDefault : false,
+
+    timer : 0,
+
     
-    presence: function(config, value) {
-        if (value === undefined) {
-            value = config;
+    enable: function(){
+        if(this.disabled){
+            this.el.on('mousedown', this.handleMouseDown, this);
+            if (Ext.isIE){
+                this.el.on('dblclick', this.handleDblClick, this);
+            }
+            if(this.preventDefault || this.stopDefault){
+                this.el.on('click', this.eventOptions, this);
+            }
         }
-        
-        return !!value;
+        this.disabled = false;
     },
+
     
+    disable: function( force){
+        if(force || !this.disabled){
+            clearTimeout(this.timer);
+            if(this.pressedCls){
+                this.el.removeCls(this.pressedCls);
+            }
+            Ext.getDoc().un('mouseup', this.handleMouseUp, this);
+            this.el.removeAllListeners();
+        }
+        this.disabled = true;
+    },
+
     
-    length: function(config, value) {
-        if (value === undefined) {
-            return false;
+    setDisabled: function(disabled){
+        this[disabled ? 'disable' : 'enable']();
+    },
+
+    eventOptions: function(e){
+        if(this.preventDefault){
+            e.preventDefault();
         }
-        
-        var length = value.length,
-            min    = config.min,
-            max    = config.max;
-        
-        if ((min && length < min) || (max && length > max)) {
-            return false;
-        } else {
-            return true;
+        if(this.stopDefault){
+            e.stopEvent();
         }
     },
+
     
-    
-    format: function(config, value) {
-        return !!(config.matcher && config.matcher.test(value));
+    destroy : function() {
+        this.disable(true);
+        Ext.destroy(this.el);
+        this.clearListeners();
     },
-    
-    
-    inclusion: function(config, value) {
-        return config.list && Ext.Array.indexOf(config.list,value) != -1;
+
+    handleDblClick : function(e){
+        clearTimeout(this.timer);
+        this.el.blur();
+
+        this.fireEvent("mousedown", this, e);
+        this.fireEvent("click", this, e);
     },
-    
-    
-    exclusion: function(config, value) {
-        return config.list && Ext.Array.indexOf(config.list,value) == -1;
-    }
-});
 
-Ext.define('Ext.data.ResultSet', {
-    
-    loaded: true,
-    
-    
-    count: 0,
-    
-    
-    total: 0,
-    
-    
-    success: false,
-    
     
+    handleMouseDown : function(e){
+        clearTimeout(this.timer);
+        this.el.blur();
+        if(this.pressedCls){
+            this.el.addCls(this.pressedCls);
+        }
+        this.mousedownTime = new Date();
+
+        Ext.getDoc().on("mouseup", this.handleMouseUp, this);
+        this.el.on("mouseout", this.handleMouseOut, this);
+
+        this.fireEvent("mousedown", this, e);
+        this.fireEvent("click", this, e);
 
-    constructor: function(config) {
-        Ext.apply(this, config);
         
+        if (this.accelerate) {
+            this.delay = 400;
+        }
+
         
-        this.totalRecords = this.total;
         
-        if (config.count === undefined) {
-            this.count = this.records.length;
-        }
-    }
-});
+        e = new Ext.EventObjectImpl(e);
+
+        this.timer =  Ext.defer(this.click, this.delay || this.interval, this, [e]);
+    },
 
-Ext.define('Ext.data.writer.Writer', {
-    alias: 'writer.base',
-    alternateClassName: ['Ext.data.DataWriter', 'Ext.data.Writer'],
-    
-    
-    writeAllFields: true,
-    
     
-    nameProperty: 'name',
+    click : function(e){
+        this.fireEvent("click", this, e);
+        this.timer =  Ext.defer(this.click, this.accelerate ?
+            this.easeOutExpo(Ext.Date.getElapsed(this.mousedownTime),
+                400,
+                -390,
+                12000) :
+            this.interval, this, [e]);
+    },
 
-    constructor: function(config) {
-        Ext.apply(this, config);
+    easeOutExpo : function (t, b, c, d) {
+        return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
     },
 
     
-    write: function(request) {
-        var operation = request.operation,
-            records   = operation.records || [],
-            len       = records.length,
-            i         = 0,
-            data      = [];
+    handleMouseOut : function(){
+        clearTimeout(this.timer);
+        if(this.pressedCls){
+            this.el.removeCls(this.pressedCls);
+        }
+        this.el.on("mouseover", this.handleMouseReturn, this);
+    },
 
-        for (; i < len; i++) {
-            data.push(this.getRecordData(records[i]));
+    
+    handleMouseReturn : function(){
+        this.el.un("mouseover", this.handleMouseReturn, this);
+        if(this.pressedCls){
+            this.el.addCls(this.pressedCls);
         }
-        return this.writeRecords(request, data);
+        this.click();
     },
 
     
-    getRecordData: function(record) {
-        var isPhantom = record.phantom === true,
-            writeAll = this.writeAllFields || isPhantom,
-            nameProperty = this.nameProperty,
-            fields = record.fields,
-            data = {},
-            changes,
-            name,
-            field,
-            key;
-        
-        if (writeAll) {
-            fields.each(function(field){
-                if (field.persist) {
-                    name = field[nameProperty] || field.name;
-                    data[name] = record.get(field.name);
-                }
-            });
-        } else {
-            
-            changes = record.getChanges();
-            for (key in changes) {
-                if (changes.hasOwnProperty(key)) {
-                    field = fields.get(key);
-                    name = field[nameProperty] || field.name;
-                    data[name] = changes[key];
-                }
-            }
-            if (!isPhantom) {
-                
-                data[record.idProperty] = record.getId();
-            }
+    handleMouseUp : function(e){
+        clearTimeout(this.timer);
+        this.el.un("mouseover", this.handleMouseReturn, this);
+        this.el.un("mouseout", this.handleMouseOut, this);
+        Ext.getDoc().un("mouseup", this.handleMouseUp, this);
+        if(this.pressedCls){
+            this.el.removeCls(this.pressedCls);
         }
-        return data;
+        this.fireEvent("mouseup", this, e);
     }
 });
 
 
-Ext.define('Ext.util.Floating', {
-
-    uses: ['Ext.Layer', 'Ext.window.Window'],
+Ext.define('Ext.layout.component.Component', {
 
     
-    focusOnToFront: true,
+
+    extend: 'Ext.layout.Layout',
 
     
-    shadow: 'sides',
 
-    constructor: function(config) {
-        this.floating = true;
-        this.el = Ext.create('Ext.Layer', Ext.apply({}, config, {
-            hideMode: this.hideMode,
-            hidden: this.hidden,
-            shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides',
-            shadowOffset: this.shadowOffset,
-            constrain: false,
-            shim: this.shim === false ? false : undefined
-        }), this.el);
-    },
+    type: 'component',
 
-    onFloatRender: function() {
-        var me = this;
-        me.zIndexParent = me.getZIndexParent();
-        me.setFloatParent(me.ownerCt);
-        delete me.ownerCt;
+    monitorChildren: true,
 
-        if (me.zIndexParent) {
-            me.zIndexParent.registerFloatingItem(me);
-        } else {
-            Ext.WindowManager.register(me);
+    initLayout : function() {
+        var me = this,
+            owner = me.owner,
+            ownerEl = owner.el;
+
+        if (!me.initialized) {
+            if (owner.frameSize) {
+                me.frameSize = owner.frameSize;
+            }
+            else {
+                owner.frameSize = me.frameSize = {
+                    top: 0,
+                    left: 0,
+                    bottom: 0,
+                    right: 0
+                };
+            }
         }
+        me.callParent(arguments);
     },
 
-    setFloatParent: function(floatParent) {
-        var me = this;
+    beforeLayout : function(width, height, isSetSize, callingContainer) {
+        this.callParent(arguments);
 
-        
-        if (me.floatParent) {
-            me.mun(me.floatParent, {
-                hide: me.onFloatParentHide,
-                show: me.onFloatParentShow,
-                scope: me
-            });
-        }
+        var me = this,
+            owner = me.owner,
+            ownerCt = owner.ownerCt,
+            layout = owner.layout,
+            isVisible = owner.isVisible(true),
+            ownerElChild = owner.el.child,
+            layoutCollection;
 
-        me.floatParent = floatParent;
+        
+        me.previousComponentSize = me.lastComponentSize;
 
         
-        if (floatParent) {
-            me.mon(me.floatParent, {
-                hide: me.onFloatParentHide,
-                show: me.onFloatParentShow,
-                scope: me
-            });
+        if (!isSetSize
+            && ((!Ext.isNumber(width) && owner.isFixedWidth()) ||
+                (!Ext.isNumber(height) && owner.isFixedHeight()))
+            
+            && callingContainer && callingContainer !== ownerCt) {
+            
+            me.doContainerLayout();
+            return false;
         }
 
         
         
-        if ((me.constrain || me.constrainHeader) && !me.constrainTo) {
-            me.constrainTo = floatParent ? floatParent.getTargetEl() : me.container;
+        if (!isVisible && (owner.hiddenAncestor || owner.floating)) {
+            if (owner.hiddenAncestor) {
+                layoutCollection = owner.hiddenAncestor.layoutOnShow;
+                layoutCollection.remove(owner);
+                layoutCollection.add(owner);
+            }
+            owner.needsLayout = {
+                width: width,
+                height: height,
+                isSetSize: false
+            };
+        }
+
+        if (isVisible && this.needsLayout(width, height)) {
+            return owner.beforeComponentLayout(width, height, isSetSize, callingContainer);
+        }
+        else {
+            return false;
         }
     },
 
-    onFloatParentHide: function() {
-        this.showOnParentShow = this.isVisible();
-        this.hide();
+    
+    needsLayout : function(width, height) {
+        var me = this,
+            widthBeingChanged,
+            heightBeingChanged;
+            me.lastComponentSize = me.lastComponentSize || {
+                width: -Infinity,
+                height: -Infinity
+            };
+
+        
+        widthBeingChanged  = !Ext.isDefined(width)  || me.lastComponentSize.width  !== width;
+
+        
+        heightBeingChanged = !Ext.isDefined(height) || me.lastComponentSize.height !== height;
+
+
+        
+        return !me.isSizing && (me.childrenChanged || widthBeingChanged || heightBeingChanged);
     },
 
-    onFloatParentShow: function() {
-        if (this.showOnParentShow) {
-            delete this.showOnParentShow;
-            this.show();
+    
+    setElementSize: function(el, width, height) {
+        if (width !== undefined && height !== undefined) {
+            el.setSize(width, height);
+        }
+        else if (height !== undefined) {
+            el.setHeight(height);
+        }
+        else if (width !== undefined) {
+            el.setWidth(width);
         }
     },
 
     
-    getZIndexParent: function() {
-        var p = this.ownerCt,
-            c;
+     getTarget : function() {
+         return this.owner.el;
+     },
 
-        if (p) {
-            while (p) {
-                c = p;
-                p = p.ownerCt;
-            }
-            if (c.floating) {
-                return c;
-            }
-        }
+    
+    getRenderTarget : function() {
+        return this.owner.el;
     },
 
     
-    
-    
-    
-    
-    setZIndex: function(index) {
+    setTargetSize : function(width, height) {
         var me = this;
-        this.el.setZIndex(index);
+        me.setElementSize(me.owner.el, width, height);
 
-        
-        index += 10;
+        if (me.owner.frameBody) {
+            var targetInfo = me.getTargetInfo(),
+                padding = targetInfo.padding,
+                border = targetInfo.border,
+                frameSize = me.frameSize;
 
-        
-        
-        if (me.floatingItems) {
-            index = Math.floor(me.floatingItems.setBase(index) / 100) * 100 + 10000;
+            me.setElementSize(me.owner.frameBody,
+                Ext.isNumber(width) ? (width - frameSize.left - frameSize.right - padding.left - padding.right - border.left - border.right) : width,
+                Ext.isNumber(height) ? (height - frameSize.top - frameSize.bottom - padding.top - padding.bottom - border.top - border.bottom) : height
+            );
         }
-        return index;
-    },
 
-    
-    doConstrain: function(constrainTo) {
-        var me = this,
-            constrainEl,
-            vector,
-            xy;
+        me.autoSized = {
+            width: !Ext.isNumber(width),
+            height: !Ext.isNumber(height)
+        };
 
-        if (me.constrain || me.constrainHeader) {
-            if (me.constrainHeader) {
-                constrainEl = me.header.el;
-            } else {
-                constrainEl = me.el;
-            }
-            vector = constrainEl.getConstrainVector(constrainTo || (me.floatParent && me.floatParent.getTargetEl()) || me.container);
-            if (vector) {
-                xy = me.getPosition();
-                xy[0] += vector[0];
-                xy[1] += vector[1];
-                me.setPosition(xy);
-            }
-        }
+        me.lastComponentSize = {
+            width: width,
+            height: height
+        };
     },
 
-    
-    alignTo: function(element, position, offsets) {
-        if (element.isComponent) {
-            element = element.getEl();
+    getTargetInfo : function() {
+        if (!this.targetInfo) {
+            var target = this.getTarget(),
+                body = this.owner.getTargetEl();
+
+            this.targetInfo = {
+                padding: {
+                    top: target.getPadding('t'),
+                    right: target.getPadding('r'),
+                    bottom: target.getPadding('b'),
+                    left: target.getPadding('l')
+                },
+                border: {
+                    top: target.getBorderWidth('t'),
+                    right: target.getBorderWidth('r'),
+                    bottom: target.getBorderWidth('b'),
+                    left: target.getBorderWidth('l')
+                },
+                bodyMargin: {
+                    top: body.getMargin('t'),
+                    right: body.getMargin('r'),
+                    bottom: body.getMargin('b'),
+                    left: body.getMargin('l')
+                }
+            };
         }
-        var xy = this.el.getAlignToXY(element, position, offsets);
-        this.setPagePosition(xy);
-        return this;
+        return this.targetInfo;
     },
 
     
-    toFront: function(preventFocus) {
-        var me = this;
+    doOwnerCtLayouts: function() {
+        var owner = this.owner,
+            ownerCt = owner.ownerCt,
+            ownerCtComponentLayout, ownerCtContainerLayout,
+            curSize = this.lastComponentSize,
+            prevSize = this.previousComponentSize,
+            widthChange  = (prevSize && curSize && Ext.isNumber(curSize.width )) ? curSize.width  !== prevSize.width  : true,
+            heightChange = (prevSize && curSize && Ext.isNumber(curSize.height)) ? curSize.height !== prevSize.height : true;
 
         
-        
-        if (me.zIndexParent) {
-            me.zIndexParent.toFront(true);
+        if (!ownerCt || (!widthChange && !heightChange)) {
+            return;
         }
-        if (me.zIndexManager.bringToFront(me)) {
-            if (!Ext.isDefined(preventFocus)) {
-                preventFocus = !me.focusOnToFront;
-            }
-            if (!preventFocus) {
-                
+
+        ownerCtComponentLayout = ownerCt.componentLayout;
+        ownerCtContainerLayout = ownerCt.layout;
+
+        if (!owner.floating && ownerCtComponentLayout && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) {
+            if (!ownerCt.suspendLayout && ownerCtContainerLayout && !ownerCtContainerLayout.layoutBusy) {
+
                 
+                if (((widthChange && !ownerCt.isFixedWidth()) || (heightChange && !ownerCt.isFixedHeight()))) {
+                    
+                    this.isSizing = true;
+                    ownerCt.doComponentLayout();
+                    this.isSizing = false;
+                }
                 
-                me.focus(false, true);
+                else if (ownerCtContainerLayout.bindToOwnerCtContainer === true) {
+                    ownerCtContainerLayout.layout();
+                }
             }
         }
-        return me;
     },
 
-    
-    setActive: function(active, newActive) {
-        if (active) {
-            if ((this instanceof Ext.window.Window) && !this.maximized) {
-                this.el.enableShadow(true);
-            }
-            this.fireEvent('activate', this);
-        } else {
-            
-            
-            if ((this instanceof Ext.window.Window) && (newActive instanceof Ext.window.Window)) {
-                this.el.disableShadow();
+    doContainerLayout: function() {
+        var me = this,
+            owner = me.owner,
+            ownerCt = owner.ownerCt,
+            layout = owner.layout,
+            ownerCtComponentLayout;
+
+        
+        
+        if (!owner.suspendLayout && layout && layout.isLayout && !layout.layoutBusy && !layout.isAutoDock) {
+            layout.layout();
+        }
+
+        
+        if (ownerCt && ownerCt.componentLayout) {
+            ownerCtComponentLayout = ownerCt.componentLayout;
+            if (!owner.floating && ownerCtComponentLayout.monitorChildren && !ownerCtComponentLayout.layoutBusy) {
+                ownerCtComponentLayout.childrenChanged = true;
             }
-            this.fireEvent('deactivate', this);
         }
     },
 
-    
-    toBack: function() {
-        this.zIndexManager.sendToBack(this);
-        return this;
+    afterLayout : function(width, height, isSetSize, layoutOwner) {
+        this.doContainerLayout();
+        this.owner.afterComponentLayout(width, height, isSetSize, layoutOwner);
+    }
+});
+
+
+Ext.define('Ext.util.TextMetrics', {
+    statics: {
+        shared: null,
+        
+        measure: function(el, text, fixedWidth){
+            var me = this,
+                shared = me.shared;
+            
+            if(!shared){
+                shared = me.shared = new me(el, fixedWidth);
+            }
+            shared.bind(el);
+            shared.setFixedWidth(fixedWidth || 'auto');
+            return shared.getSize(text);
+        },
+        
+        
+         destroy: function(){
+             var me = this;
+             Ext.destroy(me.shared);
+             me.shared = null;
+         }
     },
+    
+    
+    constructor: function(bindTo, fixedWidth){
+        var measure = this.measure = Ext.getBody().createChild({
+            cls: 'x-textmetrics'
+        });
+        this.el = Ext.get(bindTo);
+        
+        measure.position('absolute');
+        measure.setLeftTop(-1000, -1000);
+        measure.hide();
 
+        if (fixedWidth) {
+           measure.setWidth(fixedWidth);
+        }
+    },
     
-    center: function() {
-        var xy = this.el.getAlignToXY(this.container, 'c-c');
-        this.setPagePosition(xy);
-        return this;
+    
+    getSize: function(text){
+        var measure = this.measure,
+            size;
+        
+        measure.update(text);
+        size = measure.getSize();
+        measure.update('');
+        return size;
     },
-
     
-    syncShadow : function(){
-        if (this.floating) {
-            this.el.sync(true);
-        }
+    
+    bind: function(el){
+        var me = this;
+        
+        me.el = Ext.get(el);
+        me.measure.setStyle(
+            me.el.getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
+        );
     },
-
     
-    fitContainer: function() {
-        var parent = this.floatParent,
-            container = parent ? parent.getTargetEl() : this.container,
-            size = container.getViewSize(false);
-
-        this.setSize(size);
-    }
+    
+     setFixedWidth : function(width){
+         this.measure.setWidth(width);
+     },
+     
+     
+     getWidth : function(text){
+         this.measure.dom.style.width = 'auto';
+         return this.getSize(text).width;
+     },
+     
+     
+     getHeight : function(text){
+         return this.getSize(text).height;
+     },
+     
+     
+     destroy: function(){
+         var me = this;
+         me.measure.remove();
+         delete me.el;
+         delete me.measure;
+     }
+}, function(){
+    Ext.Element.addMethods({
+        
+        getTextWidth : function(text, min, max){
+            return Ext.Number.constrain(Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width, min || 0, max || 1000000);
+        }
+    });
 });
 
 
-Ext.define('Ext.layout.container.AbstractContainer', {
+Ext.define('Ext.layout.container.boxOverflow.Scroller', {
 
     
 
-    extend: 'Ext.layout.Layout',
-
+    extend: 'Ext.layout.container.boxOverflow.None',
+    requires: ['Ext.util.ClickRepeater', 'Ext.Element'],
+    alternateClassName: 'Ext.layout.boxOverflow.Scroller',
+    mixins: {
+        observable: 'Ext.util.Observable'
+    },
     
-
-    type: 'container',
-
-    fixedLayout: true,
-
     
-    managedHeight: true,
+
     
-    managedWidth: true,
+    animateScroll: false,
 
     
-    bindToOwnerCtComponent: false,
+    scrollIncrement: 20,
 
     
-    bindToOwnerCtContainer: false,
+    wheelIncrement: 10,
 
     
+    scrollRepeatInterval: 60,
 
-    isManaged: function(dimension) {
-        dimension = Ext.String.capitalize(dimension);
-        var me = this,
-            child = me,
-            managed = me['managed' + dimension],
-            ancestor = me.owner.ownerCt;
+    
+    scrollDuration: 400,
 
-        if (ancestor && ancestor.layout) {
-            while (ancestor && ancestor.layout) {
-                if (managed === false || ancestor.layout['managed' + dimension] === false) {
-                    managed = false;
-                    break;
-                }
-                ancestor = ancestor.ownerCt;
-            }
-        }
-        return managed;
-    },
+    
 
-    layout: function() {
-        var me = this,
-            owner = me.owner;
-        if (Ext.isNumber(owner.height) || owner.isViewport) {
-            me.managedHeight = false;
-        }
-        if (Ext.isNumber(owner.width) || owner.isViewport) {
-            me.managedWidth = false;
-        }
-        me.callParent(arguments);
-    },
+    
 
     
-    setItemSize: function(item, width, height) {
-        if (Ext.isObject(width)) {
-            height = width.height;
-            width = width.width;
-        }
-        item.setCalculatedSize(width, height, this.owner);
-    },
+    scrollerCls: Ext.baseCSSPrefix + 'box-scroller',
 
     
-    getLayoutItems: function() {
-        return this.owner && this.owner.items && this.owner.items.items || [];
-    },
 
-    afterLayout: function() {
-        this.owner.afterLayout(this);
-    },
     
-     getTarget: function() {
-         return this.owner.getTargetEl();
-     },
     
-     getRenderTarget: function() {
-         return this.owner.getTargetEl();
-     }
-});
-
-
-Ext.define('Ext.ZIndexManager', {
-
-    alternateClassName: 'Ext.WindowGroup',
+    constructor: function(layout, config) {
+        this.layout = layout;
+        Ext.apply(this, config || {});
+        
+        this.addEvents(
+            
+            'scroll'
+        );
+    },
+    
+    initCSSClasses: function() {
+        var me = this,
+        layout = me.layout;
 
-    statics: {
-        zBase : 9000
+        if (!me.CSSinitialized) {
+            me.beforeCtCls = me.beforeCtCls || Ext.baseCSSPrefix + 'box-scroller-' + layout.parallelBefore;
+            me.afterCtCls  = me.afterCtCls  || Ext.baseCSSPrefix + 'box-scroller-' + layout.parallelAfter;
+            me.beforeScrollerCls = me.beforeScrollerCls || Ext.baseCSSPrefix + layout.owner.getXType() + '-scroll-' + layout.parallelBefore;
+            me.afterScrollerCls  = me.afterScrollerCls  || Ext.baseCSSPrefix + layout.owner.getXType() + '-scroll-' + layout.parallelAfter;
+            me.CSSinitializes = true;
+        }
     },
 
-    constructor: function(container) {
-        var me = this;
+    handleOverflow: function(calculations, targetSize) {
+        var me = this,
+            layout = me.layout,
+            methodName = 'get' + layout.parallelPrefixCap,
+            newSize = {};
 
-        me.list = {};
-        me.zIndexStack = [];
-        me.front = null;
+        me.initCSSClasses();
+        me.callParent(arguments);
+        this.createInnerElements();
+        this.showScrollers();
+        newSize[layout.perpendicularPrefix] = targetSize[layout.perpendicularPrefix];
+        newSize[layout.parallelPrefix] = targetSize[layout.parallelPrefix] - (me.beforeCt[methodName]() + me.afterCt[methodName]());
+        return { targetSize: newSize };
+    },
 
-        if (container) {
+    
+    createInnerElements: function() {
+        var me = this,
+            target = me.layout.getRenderTarget();
 
-            
-            if (container.isContainer) {
-                container.on('resize', me._onContainerResize, me);
-                me.zseed = Ext.Number.from(container.getEl().getStyle('zIndex'), me.getNextZSeed());
-                
-                me.targetEl = container.getTargetEl();
-                me.container = container;
-            }
-            
-            else {
-                Ext.EventManager.onWindowResize(me._onContainerResize, me);
-                me.zseed = me.getNextZSeed();
-                me.targetEl = Ext.get(container);
-            }
-        }
         
         
-        else {
-            Ext.EventManager.onWindowResize(me._onContainerResize, me);
-            me.zseed = me.getNextZSeed();
-            Ext.onDocumentReady(function() {
-                me.targetEl = Ext.getBody();
-            });
+        if (!me.beforeCt) {
+            target.addCls(Ext.baseCSSPrefix + me.layout.direction + '-box-overflow-body');
+            me.beforeCt = target.insertSibling({cls: Ext.layout.container.Box.prototype.innerCls + ' ' + me.beforeCtCls}, 'before');
+            me.afterCt  = target.insertSibling({cls: Ext.layout.container.Box.prototype.innerCls + ' ' + me.afterCtCls},  'after');
+            me.createWheelListener();
         }
     },
 
-    getNextZSeed: function() {
-        return (Ext.ZIndexManager.zBase += 10000);
-    },
+    
+    createWheelListener: function() {
+        this.layout.innerCt.on({
+            scope     : this,
+            mousewheel: function(e) {
+                e.stopEvent();
 
-    setBase: function(baseZIndex) {
-        this.zseed = baseZIndex;
-        return this.assignZIndices();
+                this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false);
+            }
+        });
     },
 
     
-    assignZIndices: function() {
-        var a = this.zIndexStack,
-            len = a.length,
-            i = 0,
-            zIndex = this.zseed,
-            comp;
-
-        for (; i < len; i++) {
-            comp = a[i];
-            if (comp && !comp.hidden) {
-
-                
-                
-                
-                
-                
-                
-                
-                zIndex = comp.setZIndex(zIndex);
-            }
-        }
-        this._activateLast();
-        return zIndex;
+    clearOverflow: function() {
+        this.hideScrollers();
     },
 
     
-    _setActiveChild: function(comp) {
-        if (comp != this.front) {
+    showScrollers: function() {
+        this.createScrollers();
+        this.beforeScroller.show();
+        this.afterScroller.show();
+        this.updateScrollButtons();
+        
+        this.layout.owner.addClsWithUI('scroller');
+    },
 
-            if (this.front) {
-                this.front.setActive(false, comp);
-            }
-            this.front = comp;
-            if (comp) {
-                comp.setActive(true);
-                if (comp.modal) {
-                    this._showModalMask(comp.el.getStyle('zIndex') - 4);
-                }
-            }
+    
+    hideScrollers: function() {
+        if (this.beforeScroller != undefined) {
+            this.beforeScroller.hide();
+            this.afterScroller.hide();
+            
+            this.layout.owner.removeClsWithUI('scroller');
         }
     },
 
     
-    _activateLast: function(justHidden) {
-        var comp,
-            lastActivated = false,
-            i;
+    createScrollers: function() {
+        if (!this.beforeScroller && !this.afterScroller) {
+            var before = this.beforeCt.createChild({
+                cls: Ext.String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls)
+            });
 
-        
-        
-        
-        for (i = this.zIndexStack.length-1; i >= 0; --i) {
-            comp = this.zIndexStack[i];
-            if (!comp.hidden) {
-                if (!lastActivated) {
-                    this._setActiveChild(comp);
-                    lastActivated = true;
-                }
+            var after = this.afterCt.createChild({
+                cls: Ext.String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls)
+            });
 
-                
-                if (comp.modal) {
-                    this._showModalMask(comp.el.getStyle('zIndex') - 4);
-                    return;
-                }
-            }
-        }
+            before.addClsOnOver(this.beforeScrollerCls + '-hover');
+            after.addClsOnOver(this.afterScrollerCls + '-hover');
 
-        
-        
-        this._hideModalMask();
-        if (!lastActivated) {
-            this._setActiveChild(null);
-        }
-    },
+            before.setVisibilityMode(Ext.Element.DISPLAY);
+            after.setVisibilityMode(Ext.Element.DISPLAY);
 
-    _showModalMask: function(zIndex) {
-        if (!this.mask) {
-            this.mask = this.targetEl.createChild({
-                cls: Ext.baseCSSPrefix + 'mask'
+            this.beforeRepeater = Ext.create('Ext.util.ClickRepeater', before, {
+                interval: this.scrollRepeatInterval,
+                handler : this.scrollLeft,
+                scope   : this
             });
-            this.mask.setVisibilityMode(Ext.core.Element.DISPLAY);
-            this.mask.on('click', this._onMaskClick, this);
+
+            this.afterRepeater = Ext.create('Ext.util.ClickRepeater', after, {
+                interval: this.scrollRepeatInterval,
+                handler : this.scrollRight,
+                scope   : this
+            });
+
+            
+            this.beforeScroller = before;
+
+            
+            this.afterScroller = after;
         }
-        Ext.getBody().addCls(Ext.baseCSSPrefix + 'body-masked');
-        this.mask.setSize(this.targetEl.getViewSize(true));
-        this.mask.setStyle('zIndex', zIndex);
-        this.mask.show();
     },
 
-    _hideModalMask: function() {
-        if (this.mask) {
-            Ext.getBody().removeCls(Ext.baseCSSPrefix + 'body-masked');
-            this.mask.hide();
-        }
+    
+    destroy: function() {
+        Ext.destroy(this.beforeRepeater, this.afterRepeater, this.beforeScroller, this.afterScroller, this.beforeCt, this.afterCt);
     },
 
-    _onMaskClick: function() {
-        if (this.front) {
-            this.front.focus();
-        }
+    
+    scrollBy: function(delta, animate) {
+        this.scrollTo(this.getScrollPosition() + delta, animate);
     },
 
-    _onContainerResize: function() {
-        if (this.mask && this.mask.isVisible()) {
-            this.mask.setSize(this.targetEl.getViewSize(true));
-        }
+    
+    getScrollAnim: function() {
+        return {
+            duration: this.scrollDuration, 
+            callback: this.updateScrollButtons, 
+            scope   : this
+        };
     },
 
     
-    register : function(comp) {
-        if (comp.zIndexManager) {
-            comp.zIndexManager.unregister(comp);
+    updateScrollButtons: function() {
+        if (this.beforeScroller == undefined || this.afterScroller == undefined) {
+            return;
         }
-        comp.zIndexManager = this;
 
-        this.list[comp.id] = comp;
-        this.zIndexStack.push(comp);
-        comp.on('hide', this._activateLast, this);
+        var beforeMeth = this.atExtremeBefore()  ? 'addCls' : 'removeCls',
+            afterMeth  = this.atExtremeAfter() ? 'addCls' : 'removeCls',
+            beforeCls  = this.beforeScrollerCls + '-disabled',
+            afterCls   = this.afterScrollerCls  + '-disabled';
+        
+        this.beforeScroller[beforeMeth](beforeCls);
+        this.afterScroller[afterMeth](afterCls);
+        this.scrolling = false;
     },
 
     
-    unregister : function(comp) {
-        delete comp.zIndexManager;
-        if (this.list && this.list[comp.id]) {
-            delete this.list[comp.id];
-            comp.un('hide', this._activateLast);
-            Ext.Array.remove(this.zIndexStack, comp);
+    atExtremeBefore: function() {
+        return this.getScrollPosition() === 0;
+    },
 
-            
-            this._activateLast(comp);
-        }
+    
+    scrollLeft: function() {
+        this.scrollBy(-this.scrollIncrement, false);
     },
 
     
-    get : function(id) {
-        return typeof id == "object" ? id : this.list[id];
+    scrollRight: function() {
+        this.scrollBy(this.scrollIncrement, false);
     },
 
-   
-    bringToFront : function(comp) {
-        comp = this.get(comp);
-        if (comp != this.front) {
-            Ext.Array.remove(this.zIndexStack, comp);
-            this.zIndexStack.push(comp);
-            this.assignZIndices();
-            return true;
-        }
-        if (comp.modal) {
-            Ext.getBody().addCls(Ext.baseCSSPrefix + 'body-masked');
-            this.mask.setSize(Ext.core.Element.getViewWidth(true), Ext.core.Element.getViewHeight(true));
-            this.mask.show();
-        }
-        return false;
+    
+    getScrollPosition: function(){
+        var layout = this.layout;
+        return parseInt(layout.innerCt.dom['scroll' + layout.parallelBeforeCap], 10) || 0;
     },
 
     
-    sendToBack : function(comp) {
-        comp = this.get(comp);
-        Ext.Array.remove(this.zIndexStack, comp);
-        this.zIndexStack.unshift(comp);
-        this.assignZIndices();
-        return comp;
+    getMaxScrollPosition: function() {
+        var layout = this.layout;
+        return layout.innerCt.dom['scroll' + layout.parallelPrefixCap] - this.layout.innerCt['get' + layout.parallelPrefixCap]();
     },
 
     
-    hideAll : function() {
-        for (var id in this.list) {
-            if (this.list[id].isComponent && this.list[id].isVisible()) {
-                this.list[id].hide();
-            }
-        }
+    atExtremeAfter: function() {
+        return this.getScrollPosition() >= this.getMaxScrollPosition();
     },
 
     
-    hide: function() {
-        var i = 0,
-            ln = this.zIndexStack.length,
-            comp;
+    scrollTo: function(position, animate) {
+        var me = this,
+            layout = me.layout,
+            oldPosition = me.getScrollPosition(),
+            newPosition = Ext.Number.constrain(position, 0, me.getMaxScrollPosition());
 
-        this.tempHidden = [];
-        for (; i < ln; i++) {
-            comp = this.zIndexStack[i];
-            if (comp.isVisible()) {
-                this.tempHidden.push(comp);
-                comp.hide();
+        if (newPosition != oldPosition && !me.scrolling) {
+            if (animate == undefined) {
+                animate = me.animateScroll;
+            }
+
+            layout.innerCt.scrollTo(layout.parallelBefore, newPosition, animate ? me.getScrollAnim() : false);
+            if (animate) {
+                me.scrolling = true;
+            } else {
+                me.scrolling = false;
+                me.updateScrollButtons();
             }
+            
+            me.fireEvent('scroll', me, newPosition, animate ? me.getScrollAnim() : false);
         }
     },
 
     
-    show: function() {
-        var i = 0,
-            ln = this.tempHidden.length,
-            comp,
-            x,
-            y;
+    scrollToItem: function(item, animate) {
+        var me = this,
+            layout = me.layout,
+            visibility,
+            box,
+            newPos;
 
-        for (; i < ln; i++) {
-            comp = this.tempHidden[i];
-            x = comp.x;
-            y = comp.y;
-            comp.show();
-            comp.setPosition(x, y);
+        item = me.getItem(item);
+        if (item != undefined) {
+            visibility = this.getItemVisibility(item);
+            if (!visibility.fullyVisible) {
+                box  = item.getBox(true, true);
+                newPos = box[layout.parallelPosition];
+                if (visibility.hiddenEnd) {
+                    newPos -= (this.layout.innerCt['get' + layout.parallelPrefixCap]() - box[layout.parallelPrefix]);
+                }
+                this.scrollTo(newPos, animate);
+            }
         }
-        delete this.tempHidden;
     },
 
     
-    getActive : function() {
-        return this.front;
-    },
+    getItemVisibility: function(item) {
+        var me          = this,
+            box         = me.getItem(item).getBox(true, true),
+            layout      = me.layout,
+            itemStart   = box[layout.parallelPosition],
+            itemEnd     = itemStart + box[layout.parallelPrefix],
+            scrollStart = me.getScrollPosition(),
+            scrollEnd   = scrollStart + layout.innerCt['get' + layout.parallelPrefixCap]();
+
+        return {
+            hiddenStart : itemStart < scrollStart,
+            hiddenEnd   : itemEnd > scrollEnd,
+            fullyVisible: itemStart > scrollStart && itemEnd < scrollEnd
+        };
+    }
+});
+
+Ext.define('Ext.util.Offset', {
 
     
-    getBy : function(fn, scope) {
-        var r = [],
-            i = 0,
-            len = this.zIndexStack.length,
-            comp;
 
-        for (; i < len; i++) {
-            comp = this.zIndexStack[i];
-            if (fn.call(scope||comp, comp) !== false) {
-                r.push(comp);
-            }
+    statics: {
+        fromObject: function(obj) {
+            return new this(obj.x, obj.y);
         }
-        return r;
     },
 
     
-    each : function(fn, scope) {
-        var comp;
-        for (var id in this.list) {
-            comp = this.list[id];
-            if (comp.isComponent && fn.call(scope || comp, comp) === false) {
-                return;
-            }
-        }
+
+    constructor: function(x, y) {
+        this.x = (x != null && !isNaN(x)) ? x : 0;
+        this.y = (y != null && !isNaN(y)) ? y : 0;
+
+        return this;
     },
 
-    
-    eachBottomUp: function (fn, scope) {
-        var comp,
-            stack = this.zIndexStack,
-            i, n;
+    copy: function() {
+        return new Ext.util.Offset(this.x, this.y);
+    },
 
-        for (i = 0, n = stack.length ; i < n; i++) {
-            comp = stack[i];
-            if (comp.isComponent && fn.call(scope || comp, comp) === false) {
-                return;
-            }
-        }
+    copyFrom: function(p) {
+        this.x = p.x;
+        this.y = p.y;
     },
 
-    
-    eachTopDown: function (fn, scope) {
-        var comp,
-            stack = this.zIndexStack,
-            i;
+    toString: function() {
+        return "Offset[" + this.x + "," + this.y + "]";
+    },
 
-        for (i = stack.length ; i-- > 0; ) {
-            comp = stack[i];
-            if (comp.isComponent && fn.call(scope || comp, comp) === false) {
-                return;
-            }
+    equals: function(offset) {
+
+        return (this.x == offset.x && this.y == offset.y);
+    },
+
+    round: function(to) {
+        if (!isNaN(to)) {
+            var factor = Math.pow(10, to);
+            this.x = Math.round(this.x * factor) / factor;
+            this.y = Math.round(this.y * factor) / factor;
+        } else {
+            this.x = Math.round(this.x);
+            this.y = Math.round(this.y);
         }
     },
 
-    destroy: function() {
-        delete this.zIndexStack;
-        delete this.list;
-        delete this.container;
-        delete this.targetEl;
+    isZero: function() {
+        return this.x == 0 && this.y == 0;
     }
-}, function() {
-    
-    Ext.WindowManager = Ext.WindowMgr = new this();
 });
 
 
-Ext.define('Ext.layout.container.boxOverflow.None', {
+Ext.define('Ext.util.KeyNav', {
     
-    alternateClassName: 'Ext.layout.boxOverflow.None',
+    alternateClassName: 'Ext.KeyNav',
     
-    constructor: function(layout, config) {
-        this.layout = layout;
-        Ext.apply(this, config || {});
-    },
-
-    handleOverflow: Ext.emptyFn,
-
-    clearOverflow: Ext.emptyFn,
-
+    requires: ['Ext.util.KeyMap'],
     
-    getItem: function(item) {
-        return this.layout.owner.getComponent(item);
-    }
-});
+    statics: {
+        keyOptions: {
+            left: 37,
+            right: 39,
+            up: 38,
+            down: 40,
+            space: 32,
+            pageUp: 33,
+            pageDown: 34,
+            del: 46,
+            backspace: 8,
+            home: 36,
+            end: 35,
+            enter: 13,
+            esc: 27,
+            tab: 9
+        }
+    },
 
-Ext.define('Ext.util.KeyMap', {
-    alternateClassName: 'Ext.KeyMap',
     
-    constructor: function(el, binding, eventName){
-        var me = this;
-        
-        Ext.apply(me, {
-            el: Ext.get(el),
-            eventName: eventName || me.eventName,
-            bindings: []
-        });
-        if (binding) {
-            me.addBinding(binding);
-        }
-        me.enable();
+    constructor: function(el, config){
+        this.setConfig(el, config || {});
     },
     
-    eventName: 'keydown',
-
     
-    addBinding : function(binding){
-        if (Ext.isArray(binding)) {
-            Ext.each(binding, this.addBinding, this);
-            return;
-        }
-        
-        var keyCode = binding.key,
-            processed = false,
-            key,
-            keys,
-            keyString,
-            i,
-            len;
-
-        if (Ext.isString(keyCode)) {
-            keys = [];
-            keyString = keyCode.toLowerCase();
-            
-            for (i = 0, len = keyString.length; i < len; ++i){
-                keys.push(keyString.charCodeAt(i));
-            }
-            keyCode = keys;
-            processed = true;
+    setConfig: function(el, config) {
+        if (this.map) {
+            this.map.destroy();
         }
         
-        if (!Ext.isArray(keyCode)) {
-            keyCode = [keyCode];
-        }
+        var map = Ext.create('Ext.util.KeyMap', el, null, this.getKeyEvent('forceKeyDown' in config ? config.forceKeyDown : this.forceKeyDown)),
+            keys = Ext.util.KeyNav.keyOptions,
+            scope = config.scope || this,
+            key;
         
-        if (!processed) {
-            for (i = 0, len = keyCode.length; i < len; ++i) {
-                key = keyCode[i];
-                if (Ext.isString(key)) {
-                    keyCode[i] = key.toLowerCase().charCodeAt(0);
+        this.map = map;
+        for (key in keys) {
+            if (keys.hasOwnProperty(key)) {
+                if (config[key]) {
+                    map.addBinding({
+                        scope: scope,
+                        key: keys[key],
+                        handler: Ext.Function.bind(this.handleEvent, scope, [config[key]], true),
+                        defaultEventAction: config.defaultEventAction || this.defaultEventAction
+                    });
                 }
             }
         }
         
-        this.bindings.push(Ext.apply({
-            keyCode: keyCode
-        }, binding));
+        map.disable();
+        if (!config.disabled) {
+            map.enable();
+        }
     },
     
     
-    handleKeyDown: function(event) {
-        if (this.enabled) { 
-            var bindings = this.bindings,
-                i = 0,
-                len = bindings.length;
-                
-            event = this.processEvent(event);
-            for(; i < len; ++i){
-                this.processBinding(bindings[i], event);
-            }
-        }
+    handleEvent: function(map, event, handler){
+        return handler.call(this, event);
     },
     
     
-    processEvent: function(event){
-        return event;
-    },
+    disabled: false,
     
     
-    processBinding: function(binding, event){
-        if (this.checkModifiers(binding, event)) {
-            var key = event.getKey(),
-                handler = binding.fn || binding.handler,
-                scope = binding.scope || this,
-                keyCode = binding.keyCode,
-                defaultEventAction = binding.defaultEventAction,
-                i,
-                len,
-                keydownEvent = new Ext.EventObjectImpl(event);
-                
-            
-            for (i = 0, len = keyCode.length; i < len; ++i) {
-                if (key === keyCode[i]) {
-                    if (handler.call(scope, key, event) !== true && defaultEventAction) {
-                        keydownEvent[defaultEventAction]();
-                    }
-                    break;
-                }
-            }
-        }
-    },
+    defaultEventAction: "stopEvent",
     
     
-    checkModifiers: function(binding, e){
-        var keys = ['shift', 'ctrl', 'alt'],
-            i = 0,
-            len = keys.length,
-            val, key;
-            
-        for (; i < len; ++i){
-            key = keys[i];
-            val = binding[key];
-            if (!(val === undefined || (val === e[key + 'Key']))) {
-                return false;
-            }
-        }
-        return true;
-    },
-
+    forceKeyDown: false,
     
-    on: function(key, fn, scope) {
-        var keyCode, shift, ctrl, alt;
-        if (Ext.isObject(key) && !Ext.isArray(key)) {
-            keyCode = key.key;
-            shift = key.shift;
-            ctrl = key.ctrl;
-            alt = key.alt;
-        } else {
-            keyCode = key;
-        }
-        this.addBinding({
-            key: keyCode,
-            shift: shift,
-            ctrl: ctrl,
-            alt: alt,
-            fn: fn,
-            scope: scope
-        });
-    },
-
     
-    isEnabled : function(){
-        return this.enabled;
+    destroy: function(removeEl){
+        this.map.destroy(removeEl);
+        delete this.map;
     },
 
     
-    enable: function(){
-        if(!this.enabled){
-            this.el.on(this.eventName, this.handleKeyDown, this);
-            this.enabled = true;
-        }
+    enable: function() {
+        this.map.enable();
+        this.disabled = false;
     },
 
     
-    disable: function(){
-        if(this.enabled){
-            this.el.removeListener(this.eventName, this.handleKeyDown, this);
-            this.enabled = false;
-        }
+    disable: function() {
+        this.map.disable();
+        this.disabled = true;
     },
-
+    
     
     setDisabled : function(disabled){
-        if (disabled) {
-            this.disable();
-        } else {
-            this.enable();
-        }
+        this.map.setDisabled(disabled);
+        this.disabled = disabled;
     },
     
     
-    destroy: function(removeEl){
-        var me = this;
-        
-        me.bindings = [];
-        me.disable();
-        if (removeEl === true) {
-            me.el.remove();
-        }
-        delete me.el;
+    getKeyEvent: function(forceKeyDown){
+        return (forceKeyDown || Ext.EventManager.useKeyDown) ? 'keydown' : 'keypress';
     }
 });
 
 
-Ext.define('Ext.util.ClickRepeater', {
-    extend: 'Ext.util.Observable',
-
-    constructor : function(el, config){
-        this.el = Ext.get(el);
-        this.el.unselectable();
-
-        Ext.apply(this, config);
-
-        this.addEvents(
-        
-        "mousedown",
-        
-        "click",
-        
-        "mouseup"
-        );
 
-        if(!this.disabled){
-            this.disabled = true;
-            this.enable();
-        }
+Ext.define('Ext.fx.Queue', {
 
-        
-        if(this.handler){
-            this.on("click", this.handler,  this.scope || this);
-        }
+    requires: ['Ext.util.HashMap'],
 
-        this.callParent();
+    constructor: function() {
+        this.targets = Ext.create('Ext.util.HashMap');
+        this.fxQueue = {};
     },
 
     
+    getFxDefaults: function(targetId) {
+        var target = this.targets.get(targetId);
+        if (target) {
+            return target.fxDefaults;
+        }
+        return {};
+    },
 
     
+    setFxDefaults: function(targetId, obj) {
+        var target = this.targets.get(targetId);
+        if (target) {
+            target.fxDefaults = Ext.apply(target.fxDefaults || {}, obj);
+        }
+    },
 
     
+    stopAnimation: function(targetId) {
+        var me = this,
+            queue = me.getFxQueue(targetId),
+            ln = queue.length;
+        while (ln) {
+            queue[ln - 1].end();
+            ln--;
+        }
+    },
 
     
-    interval : 20,
+    getActiveAnimation: function(targetId) {
+        var queue = this.getFxQueue(targetId);
+        return (queue && !!queue.length) ? queue[0] : false;
+    },
 
     
-    delay: 250,
+    hasFxBlock: function(targetId) {
+        var queue = this.getFxQueue(targetId);
+        return queue && queue[0] && queue[0].block;
+    },
 
     
-    preventDefault : true,
-    
-    stopDefault : false,
+    getFxQueue: function(targetId) {
+        if (!targetId) {
+            return false;
+        }
+        var me = this,
+            queue = me.fxQueue[targetId],
+            target = me.targets.get(targetId);
 
-    timer : 0,
+        if (!target) {
+            return false;
+        }
 
-    
-    enable: function(){
-        if(this.disabled){
-            this.el.on('mousedown', this.handleMouseDown, this);
-            if (Ext.isIE){
-                this.el.on('dblclick', this.handleDblClick, this);
-            }
-            if(this.preventDefault || this.stopDefault){
-                this.el.on('click', this.eventOptions, this);
+        if (!queue) {
+            me.fxQueue[targetId] = [];
+            
+            if (target.type != 'element') {
+                target.target.on('destroy', function() {
+                    me.fxQueue[targetId] = [];
+                });
             }
         }
-        this.disabled = false;
+        return me.fxQueue[targetId];
     },
 
     
-    disable: function( force){
-        if(force || !this.disabled){
-            clearTimeout(this.timer);
-            if(this.pressedCls){
-                this.el.removeCls(this.pressedCls);
-            }
-            Ext.getDoc().un('mouseup', this.handleMouseUp, this);
-            this.el.removeAllListeners();
+    queueFx: function(anim) {
+        var me = this,
+            target = anim.target,
+            queue, ln;
+
+        if (!target) {
+            return;
         }
-        this.disabled = true;
-    },
 
-    
-    setDisabled: function(disabled){
-        this[disabled ? 'disable' : 'enable']();
-    },
+        queue = me.getFxQueue(target.getId());
+        ln = queue.length;
 
-    eventOptions: function(e){
-        if(this.preventDefault){
-            e.preventDefault();
+        if (ln) {
+            if (anim.concurrent) {
+                anim.paused = false;
+            }
+            else {
+                queue[ln - 1].on('afteranimate', function() {
+                    anim.paused = false;
+                });
+            }
         }
-        if(this.stopDefault){
-            e.stopEvent();
+        else {
+            anim.paused = false;
         }
-    },
+        anim.on('afteranimate', function() {
+            Ext.Array.remove(queue, anim);
+            if (anim.remove) {
+                if (target.type == 'element') {
+                    var el = Ext.get(target.id);
+                    if (el) {
+                        el.remove();
+                    }
+                }
+            }
+        }, this);
+        queue.push(anim);
+    }
+});
 
-    
-    destroy : function() {
-        this.disable(true);
-        Ext.destroy(this.el);
-        this.clearListeners();
-    },
+Ext.define('Ext.fx.target.Target', {
 
-    handleDblClick : function(e){
-        clearTimeout(this.timer);
-        this.el.blur();
+    isAnimTarget: true,
 
-        this.fireEvent("mousedown", this, e);
-        this.fireEvent("click", this, e);
+    
+    constructor: function(target) {
+        this.target = target;
+        this.id = this.getId();
     },
-
     
-    handleMouseDown : function(e){
-        clearTimeout(this.timer);
-        this.el.blur();
-        if(this.pressedCls){
-            this.el.addCls(this.pressedCls);
-        }
-        this.mousedownTime = new Date();
+    getId: function() {
+        return this.target.id;
+    }
+});
 
-        Ext.getDoc().on("mouseup", this.handleMouseUp, this);
-        this.el.on("mouseout", this.handleMouseOut, this);
 
-        this.fireEvent("mousedown", this, e);
-        this.fireEvent("click", this, e);
 
-        
-        if (this.accelerate) {
-            this.delay = 400;
-        }
+Ext.define('Ext.fx.target.Sprite', {
 
-        
-        
-        e = new Ext.EventObjectImpl(e);
+    
 
-        this.timer =  Ext.defer(this.click, this.delay || this.interval, this, [e]);
-    },
+    extend: 'Ext.fx.target.Target',
 
     
-    click : function(e){
-        this.fireEvent("click", this, e);
-        this.timer =  Ext.defer(this.click, this.accelerate ?
-            this.easeOutExpo(Ext.Date.getElapsed(this.mousedownTime),
-                400,
-                -390,
-                12000) :
-            this.interval, this, [e]);
-    },
 
-    easeOutExpo : function (t, b, c, d) {
-        return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
-    },
+    type: 'draw',
 
-    
-    handleMouseOut : function(){
-        clearTimeout(this.timer);
-        if(this.pressedCls){
-            this.el.removeCls(this.pressedCls);
+    getFromPrim: function(sprite, attr) {
+        var o;
+        if (attr == 'translate') {
+            o = {
+                x: sprite.attr.translation.x || 0,
+                y: sprite.attr.translation.y || 0
+            };
         }
-        this.el.on("mouseover", this.handleMouseReturn, this);
+        else if (attr == 'rotate') {
+            o = {
+                degrees: sprite.attr.rotation.degrees || 0,
+                x: sprite.attr.rotation.x,
+                y: sprite.attr.rotation.y
+            };
+        }
+        else {
+            o = sprite.attr[attr];
+        }
+        return o;
     },
 
-    
-    handleMouseReturn : function(){
-        this.el.un("mouseover", this.handleMouseReturn, this);
-        if(this.pressedCls){
-            this.el.addCls(this.pressedCls);
-        }
-        this.click();
+    getAttr: function(attr, val) {
+        return [[this.target, val != undefined ? val : this.getFromPrim(this.target, attr)]];
     },
 
-    
-    handleMouseUp : function(e){
-        clearTimeout(this.timer);
-        this.el.un("mouseover", this.handleMouseReturn, this);
-        this.el.un("mouseout", this.handleMouseOut, this);
-        Ext.getDoc().un("mouseup", this.handleMouseUp, this);
-        if(this.pressedCls){
-            this.el.removeCls(this.pressedCls);
+    setAttr: function(targetData) {
+        var ln = targetData.length,
+            spriteArr = [],
+            attrs, attr, attrArr, attPtr, spritePtr, idx, value, i, j, x, y, ln2;
+        for (i = 0; i < ln; i++) {
+            attrs = targetData[i].attrs;
+            for (attr in attrs) {
+                attrArr = attrs[attr];
+                ln2 = attrArr.length;
+                for (j = 0; j < ln2; j++) {
+                    spritePtr = attrArr[j][0];
+                    attPtr = attrArr[j][1];
+                    if (attr === 'translate') {
+                        value = {
+                            x: attPtr.x,
+                            y: attPtr.y
+                        };
+                    }
+                    else if (attr === 'rotate') {
+                        x = attPtr.x;
+                        if (isNaN(x)) {
+                            x = null;
+                        }
+                        y = attPtr.y;
+                        if (isNaN(y)) {
+                            y = null;
+                        }
+                        value = {
+                            degrees: attPtr.degrees,
+                            x: x,
+                            y: y
+                        };
+                    }
+                    else if (attr === 'width' || attr === 'height' || attr === 'x' || attr === 'y') {
+                        value = parseFloat(attPtr);
+                    }
+                    else {
+                        value = attPtr;
+                    }
+                    idx = Ext.Array.indexOf(spriteArr, spritePtr);
+                    if (idx == -1) {
+                        spriteArr.push([spritePtr, {}]);
+                        idx = spriteArr.length - 1;
+                    }
+                    spriteArr[idx][1][attr] = value;
+                }
+            }
         }
-        this.fireEvent("mouseup", this, e);
+        ln = spriteArr.length;
+        for (i = 0; i < ln; i++) {
+            spritePtr = spriteArr[i];
+            spritePtr[0].setAttributes(spritePtr[1]);
+        }
+        this.target.redraw();
     }
 });
 
 
-Ext.define('Ext.layout.component.Button', {
+
+Ext.define('Ext.fx.target.CompositeSprite', {
 
     
 
-    alias: ['layout.button'],
+    extend: 'Ext.fx.target.Sprite',
 
-    extend: 'Ext.layout.component.Component',
+    
 
+    getAttr: function(attr, val) {
+        var out = [],
+            target = this.target;
+        target.each(function(sprite) {
+            out.push([sprite, val != undefined ? val : this.getFromPrim(sprite, attr)]);
+        }, this);
+        return out;
+    }
+});
+
+
+Ext.define('Ext.fx.target.Component', {
+
+    
+   
+    extend: 'Ext.fx.target.Target',
+    
     
 
-    type: 'button',
+    type: 'component',
 
-    cellClsRE: /-btn-(tl|br)\b/,
-    htmlRE: /<.*>/,
+    
+    getPropMethod: {
+        top: function() {
+            return this.getPosition(true)[1];
+        },
+        left: function() {
+            return this.getPosition(true)[0];
+        },
+        x: function() {
+            return this.getPosition()[0];
+        },
+        y: function() {
+            return this.getPosition()[1];
+        },
+        height: function() {
+            return this.getHeight();
+        },
+        width: function() {
+            return this.getWidth();
+        },
+        opacity: function() {
+            return this.el.getStyle('opacity');
+        }
+    },
 
-    beforeLayout: function() {
-        return this.callParent(arguments) || this.lastText !== this.owner.text;
+    compMethod: {
+        top: 'setPosition',
+        left: 'setPosition',
+        x: 'setPagePosition',
+        y: 'setPagePosition',
+        height: 'setSize',
+        width: 'setSize',
+        opacity: 'setOpacity'
     },
 
     
-    onLayout: function(width, height) {
-        var me = this,
-            isNum = Ext.isNumber,
-            owner = me.owner,
-            ownerEl = owner.el,
-            btnEl = owner.btnEl,
-            btnInnerEl = owner.btnInnerEl,
-            minWidth = owner.minWidth,
-            maxWidth = owner.maxWidth,
-            ownerWidth, btnFrameWidth, metrics;
-
-        me.getTargetInfo();
-        me.callParent(arguments);
+    getAttr: function(attr, val) {
+        return [[this.target, val !== undefined ? val : this.getPropMethod[attr].call(this.target)]];
+    },
 
-        btnInnerEl.unclip();
-        me.setTargetSize(width, height);
+    setAttr: function(targetData, isFirstFrame, isLastFrame) {
+        var me = this,
+            target = me.target,
+            ln = targetData.length,
+            attrs, attr, o, i, j, meth, targets, left, top, w, h;
+        for (i = 0; i < ln; i++) {
+            attrs = targetData[i].attrs;
+            for (attr in attrs) {
+                targets = attrs[attr].length;
+                meth = {
+                    setPosition: {},
+                    setPagePosition: {},
+                    setSize: {},
+                    setOpacity: {}
+                };
+                for (j = 0; j < targets; j++) {
+                    o = attrs[attr][j];
+                    
+                    
+                    
+                    
+                    meth[me.compMethod[attr]].target = o[0];
+                    meth[me.compMethod[attr]][attr] = o[1];
+                }
+                if (meth.setPosition.target) {
+                    o = meth.setPosition;
+                    left = (o.left === undefined) ? undefined : parseInt(o.left, 10);
+                    top = (o.top === undefined) ? undefined : parseInt(o.top, 10);
+                    o.target.setPosition(left, top);
+                }
+                if (meth.setPagePosition.target) {
+                    o = meth.setPagePosition;
+                    o.target.setPagePosition(o.x, o.y);
+                }
+                if (meth.setSize.target && meth.setSize.target.el) {
+                    o = meth.setSize;
+                    
+                    w = (o.width === undefined) ? o.target.getWidth() : parseInt(o.width, 10);
+                    h = (o.height === undefined) ? o.target.getHeight() : parseInt(o.height, 10);
 
-        if (!isNum(width)) {
-            
-            
-            
-            if (owner.text && Ext.isIE7 && Ext.isStrict && btnEl && btnEl.getWidth() > 20) {
-                btnFrameWidth = me.btnFrameWidth;
-                metrics = Ext.util.TextMetrics.measure(btnInnerEl, owner.text);
-                ownerEl.setWidth(metrics.width + btnFrameWidth + me.adjWidth);
-                btnEl.setWidth(metrics.width + btnFrameWidth);
-                btnInnerEl.setWidth(metrics.width + btnFrameWidth);
-            } else {
-                
-                ownerEl.setWidth(null);
-                btnEl.setWidth(null);
-                btnInnerEl.setWidth(null);
-            }
+                    
+                    
+                    
+                    
+                    
+                    
+                    
+                    if (isLastFrame || me.dynamic) {
+                        o.target.componentLayout.childrenChanged = true;
 
-            
-            if (minWidth || maxWidth) {
-                ownerWidth = ownerEl.getWidth();
-                if (minWidth && (ownerWidth < minWidth)) {
-                    me.setTargetSize(minWidth, height);
+                        
+                        if (me.layoutAnimation) {
+                            o.target.setCalculatedSize(w, h);
+                        } else {
+                            o.target.setSize(w, h);
+                        }
+                    }
+                    else {
+                        o.target.el.setSize(w, h);
+                    }
                 }
-                else if (maxWidth && (ownerWidth > maxWidth)) {
-                    btnInnerEl.clip();
-                    me.setTargetSize(maxWidth, height);
+                if (meth.setOpacity.target) {
+                    o = meth.setOpacity;
+                    o.target.el.setStyle('opacity', o.opacity);
                 }
             }
         }
+    }
+});
 
-        this.lastText = owner.text;
-    },
 
-    setTargetSize: function(width, height) {
-        var me = this,
-            owner = me.owner,
-            isNum = Ext.isNumber,
-            btnInnerEl = owner.btnInnerEl,
-            btnWidth = (isNum(width) ? width - me.adjWidth : width),
-            btnHeight = (isNum(height) ? height - me.adjHeight : height),
-            btnFrameHeight = me.btnFrameHeight,
-            text = owner.getText(),
-            textHeight;
+Ext.define('Ext.fx.CubicBezier', {
 
-        me.callParent(arguments);
-        me.setElementSize(owner.btnEl, btnWidth, btnHeight);
-        me.setElementSize(btnInnerEl, btnWidth, btnHeight);
-        if (isNum(btnHeight)) {
-            btnInnerEl.setStyle('line-height', btnHeight - btnFrameHeight + 'px');
-        }
+    
 
-        
-        
-        
-        
-        
-        if (text && this.htmlRE.test(text)) {
-            btnInnerEl.setStyle('line-height', 'normal');
-            textHeight = Ext.util.TextMetrics.measure(btnInnerEl, text).height;
-            btnInnerEl.setStyle('padding-top', me.btnFrameTop + Math.max(btnInnerEl.getHeight() - btnFrameHeight - textHeight, 0) / 2 + 'px');
-            me.setElementSize(btnInnerEl, btnWidth, btnHeight);
-        }
-    },
+    singleton: true,
 
-    getTargetInfo: function() {
-        var me = this,
-            owner = me.owner,
-            ownerEl = owner.el,
-            frameSize = me.frameSize,
-            frameBody = owner.frameBody,
-            btnWrap = owner.btnWrap,
-            innerEl = owner.btnInnerEl;
+    
 
-        if (!('adjWidth' in me)) {
-            Ext.apply(me, {
-                
-                adjWidth: frameSize.left + frameSize.right + ownerEl.getBorderWidth('lr') + ownerEl.getPadding('lr') +
-                          btnWrap.getPadding('lr') + (frameBody ? frameBody.getFrameWidth('lr') : 0),
-                adjHeight: frameSize.top + frameSize.bottom + ownerEl.getBorderWidth('tb') + ownerEl.getPadding('tb') +
-                           btnWrap.getPadding('tb') + (frameBody ? frameBody.getFrameWidth('tb') : 0),
-                btnFrameWidth: innerEl.getFrameWidth('lr'),
-                btnFrameHeight: innerEl.getFrameWidth('tb'),
-                btnFrameTop: innerEl.getFrameWidth('t')
-            });
+    cubicBezierAtTime: function(t, p1x, p1y, p2x, p2y, duration) {
+        var cx = 3 * p1x,
+            bx = 3 * (p2x - p1x) - cx,
+            ax = 1 - cx - bx,
+            cy = 3 * p1y,
+            by = 3 * (p2y - p1y) - cy,
+            ay = 1 - cy - by;
+        function sampleCurveX(t) {
+            return ((ax * t + bx) * t + cx) * t;
+        }
+        function solve(x, epsilon) {
+            var t = solveCurveX(x, epsilon);
+            return ((ay * t + by) * t + cy) * t;
+        }
+        function solveCurveX(x, epsilon) {
+            var t0, t1, t2, x2, d2, i;
+            for (t2 = x, i = 0; i < 8; i++) {
+                x2 = sampleCurveX(t2) - x;
+                if (Math.abs(x2) < epsilon) {
+                    return t2;
+                }
+                d2 = (3 * ax * t2 + 2 * bx) * t2 + cx;
+                if (Math.abs(d2) < 1e-6) {
+                    break;
+                }
+                t2 = t2 - x2 / d2;
+            }
+            t0 = 0;
+            t1 = 1;
+            t2 = x;
+            if (t2 < t0) {
+                return t0;
+            }
+            if (t2 > t1) {
+                return t1;
+            }
+            while (t0 < t1) {
+                x2 = sampleCurveX(t2);
+                if (Math.abs(x2 - x) < epsilon) {
+                    return t2;
+                }
+                if (x > x2) {
+                    t0 = t2;
+                } else {
+                    t1 = t2;
+                }
+                t2 = (t1 - t0) / 2 + t0;
+            }
+            return t2;
         }
+        return solve(t, 1 / (200 * duration));
+    },
 
-        return me.callParent();
+    cubicBezier: function(x1, y1, x2, y2) {
+        var fn = function(pos) {
+            return Ext.fx.CubicBezier.cubicBezierAtTime(pos, x1, y1, x2, y2, 1);
+        };
+        fn.toCSS3 = function() {
+            return 'cubic-bezier(' + [x1, y1, x2, y2].join(',') + ')';
+        };
+        fn.reverse = function() {
+            return Ext.fx.CubicBezier.cubicBezier(1 - x2, 1 - y2, 1 - x1, 1 - y1);
+        };
+        return fn;
     }
 });
 
-Ext.define('Ext.util.TextMetrics', {
-    statics: {
-        shared: null,
-        
-        measure: function(el, text, fixedWidth){
-            var me = this,
-                shared = me.shared;
-            
-            if(!shared){
-                shared = me.shared = new me(el, fixedWidth);
-            }
-            shared.bind(el);
-            shared.setFixedWidth(fixedWidth || 'auto');
-            return shared.getSize(text);
-        },
-        
-        
-         destroy: function(){
-             var me = this;
-             Ext.destroy(me.shared);
-             me.shared = null;
-         }
-    },
+Ext.define('Ext.draw.Color', {
+
     
+
     
-    constructor: function(bindTo, fixedWidth){
-        var measure = this.measure = Ext.getBody().createChild({
-            cls: 'x-textmetrics'
-        });
-        this.el = Ext.get(bindTo);
-        
-        measure.position('absolute');
-        measure.setLeftTop(-1000, -1000);
-        measure.hide();
 
-        if (fixedWidth) {
-           measure.setWidth(fixedWidth);
-        }
+    colorToHexRe: /(.*?)rgb\((\d+),\s*(\d+),\s*(\d+)\)/,
+    rgbRe: /\s*rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*/,
+    hexRe: /\s*#([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)\s*/,
+
+    
+    lightnessFactor: 0.2,
+
+    
+    constructor : function(red, green, blue) {
+        var me = this,
+            clamp = Ext.Number.constrain;
+        me.r = clamp(red, 0, 255);
+        me.g = clamp(green, 0, 255);
+        me.b = clamp(blue, 0, 255);
     },
+
     
+    getRed: function() {
+        return this.r;
+    },
+
     
-    getSize: function(text){
-        var measure = this.measure,
-            size;
-        
-        measure.update(text);
-        size = measure.getSize();
-        measure.update('');
-        return size;
+    getGreen: function() {
+        return this.g;
     },
+
     
+    getBlue: function() {
+        return this.b;
+    },
+
     
-    bind: function(el){
+    getRGB: function() {
         var me = this;
-        
-        me.el = Ext.get(el);
-        me.measure.setStyle(
-            me.el.getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
-        );
+        return [me.r, me.g, me.b];
     },
+
     
-    
-     setFixedWidth : function(width){
-         this.measure.setWidth(width);
-     },
-     
-     
-     getWidth : function(text){
-         this.measure.dom.style.width = 'auto';
-         return this.getSize(text).width;
-     },
-     
-     
-     getHeight : function(text){
-         return this.getSize(text).height;
-     },
-     
-     
-     destroy: function(){
-         var me = this;
-         me.measure.remove();
-         delete me.el;
-         delete me.measure;
-     }
-}, function(){
-    Ext.core.Element.addMethods({
+    getHSL: function() {
+        var me = this,
+            r = me.r / 255,
+            g = me.g / 255,
+            b = me.b / 255,
+            max = Math.max(r, g, b),
+            min = Math.min(r, g, b),
+            delta = max - min,
+            h,
+            s = 0,
+            l = 0.5 * (max + min);
+
         
-        getTextWidth : function(text, min, max){
-            return Ext.Number.constrain(Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width, min || 0, max || 1000000);
+        if (min != max) {
+            s = (l < 0.5) ? delta / (max + min) : delta / (2 - max - min);
+            if (r == max) {
+                h = 60 * (g - b) / delta;
+            } else if (g == max) {
+                h = 120 + 60 * (b - r) / delta;
+            } else {
+                h = 240 + 60 * (r - g) / delta;
+            }
+            if (h < 0) {
+                h += 360;
+            }
+            if (h >= 360) {
+                h -= 360;
+            }
         }
-    });
-});
-
-
-Ext.define('Ext.layout.container.boxOverflow.Scroller', {
+        return [h, s, l];
+    },
 
     
-
-    extend: 'Ext.layout.container.boxOverflow.None',
-    requires: ['Ext.util.ClickRepeater', 'Ext.core.Element'],
-    alternateClassName: 'Ext.layout.boxOverflow.Scroller',
-    mixins: {
-        observable: 'Ext.util.Observable'
+    getLighter: function(factor) {
+        var hsl = this.getHSL();
+        factor = factor || this.lightnessFactor;
+        hsl[2] = Ext.Number.constrain(hsl[2] + factor, 0, 1);
+        return this.fromHSL(hsl[0], hsl[1], hsl[2]);
     },
-    
-    
 
     
-    animateScroll: false,
+    getDarker: function(factor) {
+        factor = factor || this.lightnessFactor;
+        return this.getLighter(-factor);
+    },
 
     
-    scrollIncrement: 20,
+    toString: function() {
+        var me = this,
+            round = Math.round,
+            r = round(me.r).toString(16),
+            g = round(me.g).toString(16),
+            b = round(me.b).toString(16);
+        r = (r.length == 1) ? '0' + r : r;
+        g = (g.length == 1) ? '0' + g : g;
+        b = (b.length == 1) ? '0' + b : b;
+        return ['#', r, g, b].join('');
+    },
 
     
-    wheelIncrement: 10,
+    toHex: function(color) {
+        if (Ext.isArray(color)) {
+            color = color[0];
+        }
+        if (!Ext.isString(color)) {
+            return '';
+        }
+        if (color.substr(0, 1) === '#') {
+            return color;
+        }
+        var digits = this.colorToHexRe.exec(color);
 
-    
-    scrollRepeatInterval: 60,
+        if (Ext.isArray(digits)) {
+            var red = parseInt(digits[2], 10),
+                green = parseInt(digits[3], 10),
+                blue = parseInt(digits[4], 10),
+                rgb = blue | (green << 8) | (red << 16);
+            return digits[1] + '#' + ("000000" + rgb.toString(16)).slice(-6);
+        }
+        else {
+            return '';
+        }
+    },
 
     
-    scrollDuration: 400,
+    fromString: function(str) {
+        var values, r, g, b,
+            parse = parseInt;
+
+        if ((str.length == 4 || str.length == 7) && str.substr(0, 1) === '#') {
+            values = str.match(this.hexRe);
+            if (values) {
+                r = parse(values[1], 16) >> 0;
+                g = parse(values[2], 16) >> 0;
+                b = parse(values[3], 16) >> 0;
+                if (str.length == 4) {
+                    r += (r * 16);
+                    g += (g * 16);
+                    b += (b * 16);
+                }
+            }
+        }
+        else {
+            values = str.match(this.rgbRe);
+            if (values) {
+                r = values[1];
+                g = values[2];
+                b = values[3];
+            }
+        }
+
+        return (typeof r == 'undefined') ? undefined : Ext.create('Ext.draw.Color', r, g, b);
+    },
 
     
+    getGrayscale: function() {
+        
+        return this.r * 0.3 + this.g * 0.59 + this.b * 0.11;
+    },
 
     
+    fromHSL: function(h, s, l) {
+        var C, X, m, i, rgb = [],
+            abs = Math.abs,
+            floor = Math.floor;
+
+        if (s == 0 || h == null) {
+            
+            rgb = [l, l, l];
+        }
+        else {
+            
+            
+            
+            
+            h /= 60;
+            C = s * (1 - abs(2 * l - 1));
+            X = C * (1 - abs(h - 2 * floor(h / 2) - 1));
+            m = l - C / 2;
+            switch (floor(h)) {
+                case 0:
+                    rgb = [C, X, 0];
+                    break;
+                case 1:
+                    rgb = [X, C, 0];
+                    break;
+                case 2:
+                    rgb = [0, C, X];
+                    break;
+                case 3:
+                    rgb = [0, X, C];
+                    break;
+                case 4:
+                    rgb = [X, 0, C];
+                    break;
+                case 5:
+                    rgb = [C, 0, X];
+                    break;
+            }
+            rgb = [rgb[0] + m, rgb[1] + m, rgb[2] + m];
+        }
+        return Ext.create('Ext.draw.Color', rgb[0] * 255, rgb[1] * 255, rgb[2] * 255);
+    }
+}, function() {
+    var prototype = this.prototype;
 
     
-    scrollerCls: Ext.baseCSSPrefix + 'box-scroller',
+    this.addStatics({
+        fromHSL: function() {
+            return prototype.fromHSL.apply(prototype, arguments);
+        },
+        fromString: function() {
+            return prototype.fromString.apply(prototype, arguments);
+        },
+        toHex: function() {
+            return prototype.toHex.apply(prototype, arguments);
+        }
+    });
+});
+
+
+Ext.define('Ext.dd.StatusProxy', {
+    animRepair: false,
 
     
+    constructor: function(config){
+        Ext.apply(this, config);
+        this.id = this.id || Ext.id();
+        this.proxy = Ext.createWidget('component', {
+            floating: true,
+            stateful: false,
+            id: this.id,
+            html: '<div class="' + Ext.baseCSSPrefix + 'dd-drop-icon"></div>' +
+                  '<div class="' + Ext.baseCSSPrefix + 'dd-drag-ghost"></div>',
+            cls: Ext.baseCSSPrefix + 'dd-drag-proxy ' + this.dropNotAllowed,
+            shadow: !config || config.shadow !== false,
+            renderTo: document.body
+        });
+
+        this.el = this.proxy.el;
+        this.el.show();
+        this.el.setVisibilityMode(Ext.Element.VISIBILITY);
+        this.el.hide();
 
+        this.ghost = Ext.get(this.el.dom.childNodes[1]);
+        this.dropStatus = this.dropNotAllowed;
+    },
     
+    dropAllowed : Ext.baseCSSPrefix + 'dd-drop-ok',
     
-    constructor: function(layout, config) {
-        this.layout = layout;
-        Ext.apply(this, config || {});
-        
-        this.addEvents(
-            
-            'scroll'
-        );
-    },
+    dropNotAllowed : Ext.baseCSSPrefix + 'dd-drop-nodrop',
+
     
-    initCSSClasses: function() {
-        var me = this,
-        layout = me.layout;
+    setStatus : function(cssClass){
+        cssClass = cssClass || this.dropNotAllowed;
+        if(this.dropStatus != cssClass){
+            this.el.replaceCls(this.dropStatus, cssClass);
+            this.dropStatus = cssClass;
+        }
+    },
 
-        if (!me.CSSinitialized) {
-            me.beforeCtCls = me.beforeCtCls || Ext.baseCSSPrefix + 'box-scroller-' + layout.parallelBefore;
-            me.afterCtCls  = me.afterCtCls  || Ext.baseCSSPrefix + 'box-scroller-' + layout.parallelAfter;
-            me.beforeScrollerCls = me.beforeScrollerCls || Ext.baseCSSPrefix + layout.owner.getXType() + '-scroll-' + layout.parallelBefore;
-            me.afterScrollerCls  = me.afterScrollerCls  || Ext.baseCSSPrefix + layout.owner.getXType() + '-scroll-' + layout.parallelAfter;
-            me.CSSinitializes = true;
+    
+    reset : function(clearGhost){
+        this.el.dom.className = Ext.baseCSSPrefix + 'dd-drag-proxy ' + this.dropNotAllowed;
+        this.dropStatus = this.dropNotAllowed;
+        if(clearGhost){
+            this.ghost.update("");
         }
     },
 
-    handleOverflow: function(calculations, targetSize) {
-        var me = this,
-            layout = me.layout,
-            methodName = 'get' + layout.parallelPrefixCap,
-            newSize = {};
+    
+    update : function(html){
+        if(typeof html == "string"){
+            this.ghost.update(html);
+        }else{
+            this.ghost.update("");
+            html.style.margin = "0";
+            this.ghost.dom.appendChild(html);
+        }
+        var el = this.ghost.dom.firstChild;
+        if(el){
+            Ext.fly(el).setStyle('float', 'none');
+        }
+    },
 
-        me.initCSSClasses();
-        me.callParent(arguments);
-        this.createInnerElements();
-        this.showScrollers();
-        newSize[layout.perpendicularPrefix] = targetSize[layout.perpendicularPrefix];
-        newSize[layout.parallelPrefix] = targetSize[layout.parallelPrefix] - (me.beforeCt[methodName]() + me.afterCt[methodName]());
-        return { targetSize: newSize };
+    
+    getEl : function(){
+        return this.el;
     },
 
     
-    createInnerElements: function() {
-        var me = this,
-            target = me.layout.getRenderTarget();
+    getGhost : function(){
+        return this.ghost;
+    },
 
-        
-        
-        if (!me.beforeCt) {
-            target.addCls(Ext.baseCSSPrefix + me.layout.direction + '-box-overflow-body');
-            me.beforeCt = target.insertSibling({cls: Ext.layout.container.Box.prototype.innerCls + ' ' + me.beforeCtCls}, 'before');
-            me.afterCt  = target.insertSibling({cls: Ext.layout.container.Box.prototype.innerCls + ' ' + me.afterCtCls},  'after');
-            me.createWheelListener();
+    
+    hide : function(clear) {
+        this.proxy.hide();
+        if (clear) {
+            this.reset(true);
         }
     },
 
     
-    createWheelListener: function() {
-        this.layout.innerCt.on({
-            scope     : this,
-            mousewheel: function(e) {
-                e.stopEvent();
-
-                this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false);
-            }
-        });
+    stop : function(){
+        if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){
+            this.anim.stop();
+        }
     },
 
     
-    clearOverflow: function() {
-        this.hideScrollers();
+    show : function() {
+        this.proxy.show();
+        this.proxy.toFront();
     },
 
     
-    showScrollers: function() {
-        this.createScrollers();
-        this.beforeScroller.show();
-        this.afterScroller.show();
-        this.updateScrollButtons();
-        
-        this.layout.owner.addClsWithUI('scroller');
+    sync : function(){
+        this.proxy.el.sync();
     },
 
     
-    hideScrollers: function() {
-        if (this.beforeScroller != undefined) {
-            this.beforeScroller.hide();
-            this.afterScroller.hide();
-            
-            this.layout.owner.removeClsWithUI('scroller');
+    repair : function(xy, callback, scope){
+        this.callback = callback;
+        this.scope = scope;
+        if (xy && this.animRepair !== false) {
+            this.el.addCls(Ext.baseCSSPrefix + 'dd-drag-repair');
+            this.el.hideUnders(true);
+            this.anim = this.el.animate({
+                duration: this.repairDuration || 500,
+                easing: 'ease-out',
+                to: {
+                    x: xy[0],
+                    y: xy[1]
+                },
+                stopAnimation: true,
+                callback: this.afterRepair,
+                scope: this
+            });
+        } else {
+            this.afterRepair();
         }
     },
 
     
-    createScrollers: function() {
-        if (!this.beforeScroller && !this.afterScroller) {
-            var before = this.beforeCt.createChild({
-                cls: Ext.String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls)
-            });
-
-            var after = this.afterCt.createChild({
-                cls: Ext.String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls)
-            });
+    afterRepair : function(){
+        this.hide(true);
+        if(typeof this.callback == "function"){
+            this.callback.call(this.scope || this);
+        }
+        this.callback = null;
+        this.scope = null;
+    },
 
-            before.addClsOnOver(this.beforeScrollerCls + '-hover');
-            after.addClsOnOver(this.afterScrollerCls + '-hover');
+    destroy: function(){
+        Ext.destroy(this.ghost, this.proxy, this.el);
+    }
+});
 
-            before.setVisibilityMode(Ext.core.Element.DISPLAY);
-            after.setVisibilityMode(Ext.core.Element.DISPLAY);
+Ext.define('Ext.panel.Proxy', {
 
-            this.beforeRepeater = Ext.create('Ext.util.ClickRepeater', before, {
-                interval: this.scrollRepeatInterval,
-                handler : this.scrollLeft,
-                scope   : this
-            });
+    alternateClassName: 'Ext.dd.PanelProxy',
 
-            this.afterRepeater = Ext.create('Ext.util.ClickRepeater', after, {
-                interval: this.scrollRepeatInterval,
-                handler : this.scrollRight,
-                scope   : this
-            });
+    
+    constructor: function(panel, config){
+        
+        this.panel = panel;
+        this.id = this.panel.id +'-ddproxy';
+        Ext.apply(this, config);
+    },
 
-            
-            this.beforeScroller = before;
+    
+    insertProxy: true,
 
-            
-            this.afterScroller = after;
-        }
-    },
+    
+    setStatus: Ext.emptyFn,
+    reset: Ext.emptyFn,
+    update: Ext.emptyFn,
+    stop: Ext.emptyFn,
+    sync: Ext.emptyFn,
 
     
-    destroy: function() {
-        Ext.destroy(this.beforeRepeater, this.afterRepeater, this.beforeScroller, this.afterScroller, this.beforeCt, this.afterCt);
+    getEl: function(){
+        return this.ghost.el;
     },
 
     
-    scrollBy: function(delta, animate) {
-        this.scrollTo(this.getScrollPosition() + delta, animate);
+    getGhost: function(){
+        return this.ghost;
     },
 
     
-    getScrollAnim: function() {
-        return {
-            duration: this.scrollDuration, 
-            callback: this.updateScrollButtons, 
-            scope   : this
-        };
+    getProxy: function(){
+        return this.proxy;
     },
 
     
-    updateScrollButtons: function() {
-        if (this.beforeScroller == undefined || this.afterScroller == undefined) {
-            return;
-        }
+    hide : function(){
+        if (this.ghost) {
+            if (this.proxy) {
+                this.proxy.remove();
+                delete this.proxy;
+            }
 
-        var beforeMeth = this.atExtremeBefore()  ? 'addCls' : 'removeCls',
-            afterMeth  = this.atExtremeAfter() ? 'addCls' : 'removeCls',
-            beforeCls  = this.beforeScrollerCls + '-disabled',
-            afterCls   = this.afterScrollerCls  + '-disabled';
-        
-        this.beforeScroller[beforeMeth](beforeCls);
-        this.afterScroller[afterMeth](afterCls);
-        this.scrolling = false;
+            
+            this.panel.unghost(null, false);
+            delete this.ghost;
+        }
     },
 
     
-    atExtremeBefore: function() {
-        return this.getScrollPosition() === 0;
+    show: function(){
+        if (!this.ghost) {
+            var panelSize = this.panel.getSize();
+            this.panel.el.setVisibilityMode(Ext.Element.DISPLAY);
+            this.ghost = this.panel.ghost();
+            if (this.insertProxy) {
+                
+                
+                this.proxy = this.panel.el.insertSibling({cls: Ext.baseCSSPrefix + 'panel-dd-spacer'});
+                this.proxy.setSize(panelSize);
+            }
+        }
     },
 
     
-    scrollLeft: function() {
-        this.scrollBy(-this.scrollIncrement, false);
+    repair: function(xy, callback, scope) {
+        this.hide();
+        if (typeof callback == "function") {
+            callback.call(scope || this);
+        }
     },
 
     
-    scrollRight: function() {
-        this.scrollBy(this.scrollIncrement, false);
-    },
+    moveProxy : function(parentNode, before){
+        if (this.proxy) {
+            parentNode.insertBefore(this.proxy.dom, before);
+        }
+    }
+});
+
+
+Ext.define('Ext.layout.component.AbstractDock', {
 
     
-    getScrollPosition: function(){
-        var layout = this.layout;
-        return parseInt(layout.innerCt.dom['scroll' + layout.parallelBeforeCap], 10) || 0;
-    },
+
+    extend: 'Ext.layout.component.Component',
 
     
-    getMaxScrollPosition: function() {
-        var layout = this.layout;
-        return layout.innerCt.dom['scroll' + layout.parallelPrefixCap] - this.layout.innerCt['get' + layout.parallelPrefixCap]();
-    },
+
+    type: 'dock',
 
     
-    atExtremeAfter: function() {
-        return this.getScrollPosition() >= this.getMaxScrollPosition();
+    autoSizing: true,
+
+    beforeLayout: function() {
+        var returnValue = this.callParent(arguments);
+        if (returnValue !== false && (!this.initializedBorders || this.childrenChanged) && (!this.owner.border || this.owner.manageBodyBorders)) {
+            this.handleItemBorders();
+            this.initializedBorders = true;
+        }
+        return returnValue;
     },
+    
+    handleItemBorders: function() {
+        var owner = this.owner,
+            body = owner.body,
+            docked = this.getLayoutItems(),
+            borders = {
+                top: [],
+                right: [],
+                bottom: [],
+                left: []
+            },
+            oldBorders = this.borders,
+            opposites = {
+                top: 'bottom',
+                right: 'left',
+                bottom: 'top',
+                left: 'right'
+            },
+            i, ln, item, dock, side;
+
+        for (i = 0, ln = docked.length; i < ln; i++) {
+            item = docked[i];
+            dock = item.dock;
+            
+            if (item.ignoreBorderManagement) {
+                continue;
+            }
+            
+            if (!borders[dock].satisfied) {
+                borders[dock].push(item);
+                borders[dock].satisfied = true;
+            }
+            
+            if (!borders.top.satisfied && opposites[dock] !== 'top') {
+                borders.top.push(item);
+            }
+            if (!borders.right.satisfied && opposites[dock] !== 'right') {
+                borders.right.push(item);
+            }            
+            if (!borders.bottom.satisfied && opposites[dock] !== 'bottom') {
+                borders.bottom.push(item);
+            }            
+            if (!borders.left.satisfied && opposites[dock] !== 'left') {
+                borders.left.push(item);
+            }
+        }
 
+        if (oldBorders) {
+            for (side in oldBorders) {
+                if (oldBorders.hasOwnProperty(side)) {
+                    ln = oldBorders[side].length;
+                    if (!owner.manageBodyBorders) {
+                        for (i = 0; i < ln; i++) {
+                            oldBorders[side][i].removeCls(Ext.baseCSSPrefix + 'docked-noborder-' + side);
+                        }
+                        if (!oldBorders[side].satisfied && !owner.bodyBorder) {
+                            body.removeCls(Ext.baseCSSPrefix + 'docked-noborder-' + side);                   
+                        }                    
+                    }
+                    else if (oldBorders[side].satisfied) {
+                        body.setStyle('border-' + side + '-width', '');
+                    }
+                }
+            }
+        }
+                
+        for (side in borders) {
+            if (borders.hasOwnProperty(side)) {
+                ln = borders[side].length;
+                if (!owner.manageBodyBorders) {
+                    for (i = 0; i < ln; i++) {
+                        borders[side][i].addCls(Ext.baseCSSPrefix + 'docked-noborder-' + side);
+                    }
+                    if ((!borders[side].satisfied && !owner.bodyBorder) || owner.bodyBorder === false) {
+                        body.addCls(Ext.baseCSSPrefix + 'docked-noborder-' + side);                   
+                    }                    
+                }
+                else if (borders[side].satisfied) {
+                    body.setStyle('border-' + side + '-width', '1px');
+                }
+            }
+        }
+        
+        this.borders = borders;
+    },
     
-    scrollTo: function(position, animate) {
+    
+    onLayout: function(width, height) {
+        if (this.onLayout_running) {
+            return;
+        }
+        this.onLayout_running = true;
         var me = this,
-            layout = me.layout,
-            oldPosition = me.getScrollPosition(),
-            newPosition = Ext.Number.constrain(position, 0, me.getMaxScrollPosition());
+            owner = me.owner,
+            body = owner.body,
+            layout = owner.layout,
+            target = me.getTarget(),
+            autoWidth = false,
+            autoHeight = false,
+            padding, border, frameSize;
 
-        if (newPosition != oldPosition && !me.scrolling) {
-            if (animate == undefined) {
-                animate = me.animateScroll;
+        
+        var info = me.info = {
+            boxes: [],
+            size: {
+                width: width,
+                height: height
+            },
+            bodyBox: {}
+        };
+        
+        delete layout.isAutoDock;
+
+        Ext.applyIf(info, me.getTargetInfo());
+
+        
+        if (owner && owner.ownerCt && owner.ownerCt.layout && owner.ownerCt.layout.isLayout) {
+            if (!Ext.isNumber(owner.height) || !Ext.isNumber(owner.width)) {
+                owner.ownerCt.layout.bindToOwnerCtComponent = true;
+            }
+            else {
+                owner.ownerCt.layout.bindToOwnerCtComponent = false;
             }
+        }
 
-            layout.innerCt.scrollTo(layout.parallelBefore, newPosition, animate ? me.getScrollAnim() : false);
-            if (animate) {
-                me.scrolling = true;
-            } else {
-                me.scrolling = false;
-                me.updateScrollButtons();
+        
+        if (height == null || width == null) {
+            padding = info.padding;
+            border = info.border;
+            frameSize = me.frameSize;
+
+            
+            if ((height == null) && (width == null)) {
+                autoHeight = true;
+                autoWidth = true;
+                me.setTargetSize(null);
+                me.setBodyBox({width: null, height: null});
             }
             
-            me.fireEvent('scroll', me, newPosition, animate ? me.getScrollAnim() : false);
+            else if (height == null) {
+                autoHeight = true;
+                
+                me.setTargetSize(width);
+                me.setBodyBox({width: width - padding.left - border.left - padding.right - border.right - frameSize.left - frameSize.right, height: null});
+            
+            }
+            else {
+                autoWidth = true;
+                
+                me.setTargetSize(null, height);
+                me.setBodyBox({width: null, height: height - padding.top - padding.bottom - border.top - border.bottom - frameSize.top - frameSize.bottom});
+            }
+
+            
+            if (layout && layout.isLayout) {
+                
+                layout.bindToOwnerCtComponent = true;
+                
+                layout.isAutoDock = layout.autoSize !== true;
+                layout.layout();
+
+                
+                
+                
+                
+                
+                
+                
+                
+                
+                
+                
+                
+                info.autoSizedCtLayout = layout.autoSize === true;
+                info.autoHeight = autoHeight;
+                info.autoWidth = autoWidth;
+            }
+
+            
+            
+            
+            
+            
+            me.dockItems();
+            me.setTargetSize(info.size.width, info.size.height);
+        }
+        else {
+            me.setTargetSize(width, height);
+            me.dockItems();
         }
+        me.callParent(arguments);
+        this.onLayout_running = false;
     },
 
     
-    scrollToItem: function(item, animate) {
-        var me = this,
-            layout = me.layout,
-            visibility,
-            box,
-            newPos;
+    dockItems : function() {
+        this.calculateDockBoxes();
 
-        item = me.getItem(item);
-        if (item != undefined) {
-            visibility = this.getItemVisibility(item);
-            if (!visibility.fullyVisible) {
-                box  = item.getBox(true, true);
-                newPos = box[layout.parallelPosition];
-                if (visibility.hiddenEnd) {
-                    newPos -= (this.layout.innerCt['get' + layout.parallelPrefixCap]() - box[layout.parallelPrefix]);
-                }
-                this.scrollTo(newPos, animate);
+        
+        
+        
+        var info = this.info,
+            autoWidth = info.autoWidth,
+            autoHeight = info.autoHeight,
+            boxes = info.boxes,
+            ln = boxes.length,
+            dock, i, item;
+
+        
+        
+        for (i = 0; i < ln; i++) {
+            dock = boxes[i];
+            item = dock.item;
+            item.setPosition(dock.x, dock.y);
+            if ((autoWidth || autoHeight) && item.layout && item.layout.isLayout) {
+                
+                item.layout.bindToOwnerCtComponent = true;
+            }
+        }
+
+        
+        
+        if (!info.autoSizedCtLayout) {
+            if (autoWidth) {
+                info.bodyBox.width = null;
+            }
+            if (autoHeight) {
+                info.bodyBox.height = null;
             }
         }
+
+        
+        
+        this.setBodyBox(info.bodyBox);
     },
 
     
-    getItemVisibility: function(item) {
-        var me          = this,
-            box         = me.getItem(item).getBox(true, true),
-            layout      = me.layout,
-            itemStart   = box[layout.parallelPosition],
-            itemEnd     = itemStart + box[layout.parallelPrefix],
-            scrollStart = me.getScrollPosition(),
-            scrollEnd   = scrollStart + layout.innerCt['get' + layout.parallelPrefixCap]();
+    calculateDockBoxes : function() {
+        if (this.calculateDockBoxes_running) {
+            
+            return;
+        }
+        this.calculateDockBoxes_running = true;
+        
+        
+        
+        var me = this,
+            target = me.getTarget(),
+            items = me.getLayoutItems(),
+            owner = me.owner,
+            bodyEl = owner.body,
+            info = me.info,
+            autoWidth = info.autoWidth,
+            autoHeight = info.autoHeight,
+            size = info.size,
+            ln = items.length,
+            padding = info.padding,
+            border = info.border,
+            frameSize = me.frameSize,
+            item, i, box, rect;
 
-        return {
-            hiddenStart : itemStart < scrollStart,
-            hiddenEnd   : itemEnd > scrollEnd,
-            fullyVisible: itemStart > scrollStart && itemEnd < scrollEnd
+        
+        
+        if (autoHeight) {
+            size.height = bodyEl.getHeight() + padding.top + border.top + padding.bottom + border.bottom + frameSize.top + frameSize.bottom;
+        }
+        else {
+            size.height = target.getHeight();
+        }
+        if (autoWidth) {
+            size.width = bodyEl.getWidth() + padding.left + border.left + padding.right + border.right + frameSize.left + frameSize.right;
+        }
+        else {
+            size.width = target.getWidth();
+        }
+
+        info.bodyBox = {
+            x: padding.left + frameSize.left,
+            y: padding.top + frameSize.top,
+            width: size.width - padding.left - border.left - padding.right - border.right - frameSize.left - frameSize.right,
+            height: size.height - border.top - padding.top - border.bottom - padding.bottom - frameSize.top - frameSize.bottom
         };
-    }
-});
 
-Ext.define('Ext.util.Offset', {
+        
+        for (i = 0; i < ln; i++) {
+            item = items[i];
+            
+            
+            
+            box = me.initBox(item);
 
-    
+            if (autoHeight === true) {
+                box = me.adjustAutoBox(box, i);
+            }
+            else {
+                box = me.adjustSizedBox(box, i);
+            }
 
-    statics: {
-        fromObject: function(obj) {
-            return new this(obj.x, obj.y);
+            
+            
+            
+            info.boxes.push(box);
         }
+        this.calculateDockBoxes_running = false;
     },
 
     
+    adjustSizedBox : function(box, index) {
+        var bodyBox = this.info.bodyBox,
+            frameSize = this.frameSize,
+            info = this.info,
+            padding = info.padding,
+            pos = box.type,
+            border = info.border;
 
-    constructor: function(x, y) {
-        this.x = (x != null && !isNaN(x)) ? x : 0;
-        this.y = (y != null && !isNaN(y)) ? y : 0;
+        switch (pos) {
+            case 'top':
+                box.y = bodyBox.y;
+                break;
 
-        return this;
-    },
+            case 'left':
+                box.x = bodyBox.x;
+                break;
 
-    copy: function() {
-        return new Ext.util.Offset(this.x, this.y);
-    },
+            case 'bottom':
+                box.y = (bodyBox.y + bodyBox.height) - box.height;
+                break;
 
-    copyFrom: function(p) {
-        this.x = p.x;
-        this.y = p.y;
-    },
+            case 'right':
+                box.x = (bodyBox.x + bodyBox.width) - box.width;
+                break;
+        }
 
-    toString: function() {
-        return "Offset[" + this.x + "," + this.y + "]";
+        if (box.ignoreFrame) {
+            if (pos == 'bottom') {
+                box.y += (frameSize.bottom + padding.bottom + border.bottom);
+            }
+            else {
+                box.y -= (frameSize.top + padding.top + border.top);
+            }
+            if (pos == 'right') {
+                box.x += (frameSize.right + padding.right + border.right);
+            }
+            else {
+                box.x -= (frameSize.left + padding.left + border.left);
+            }
+        }
+
+        
+        if (!box.overlay) {
+            switch (pos) {
+                case 'top':
+                    bodyBox.y += box.height;
+                    bodyBox.height -= box.height;
+                    break;
+
+                case 'left':
+                    bodyBox.x += box.width;
+                    bodyBox.width -= box.width;
+                    break;
+
+                case 'bottom':
+                    bodyBox.height -= box.height;
+                    break;
+
+                case 'right':
+                    bodyBox.width -= box.width;
+                    break;
+            }
+        }
+        return box;
     },
 
-    equals: function(offset) {
-        if(!(offset instanceof this.statics())) {
-            Ext.Error.raise('Offset must be an instance of Ext.util.Offset');
+    
+    adjustAutoBox : function (box, index) {
+        var info = this.info,
+            owner = this.owner,
+            bodyBox = info.bodyBox,
+            size = info.size,
+            boxes = info.boxes,
+            boxesLn = boxes.length,
+            pos = box.type,
+            frameSize = this.frameSize,
+            padding = info.padding,
+            border = info.border,
+            autoSizedCtLayout = info.autoSizedCtLayout,
+            ln = (boxesLn < index) ? boxesLn : index,
+            i, adjustBox;
+
+        if (pos == 'top' || pos == 'bottom') {
+            
+            for (i = 0; i < ln; i++) {
+                adjustBox = boxes[i];
+                if (adjustBox.stretched && adjustBox.type == 'left' || adjustBox.type == 'right') {
+                    adjustBox.height += box.height;
+                }
+                else if (adjustBox.type == 'bottom') {
+                    adjustBox.y += box.height;
+                }
+            }
         }
 
-        return (this.x == offset.x && this.y == offset.y);
-    },
+        switch (pos) {
+            case 'top':
+                box.y = bodyBox.y;
+                if (!box.overlay) {
+                    bodyBox.y += box.height;
+                    if (info.autoHeight) {
+                        size.height += box.height;
+                    } else {
+                        bodyBox.height -= box.height;
+                    }
+                }
+                break;
 
-    round: function(to) {
-        if (!isNaN(to)) {
-            var factor = Math.pow(10, to);
-            this.x = Math.round(this.x * factor) / factor;
-            this.y = Math.round(this.y * factor) / factor;
-        } else {
-            this.x = Math.round(this.x);
-            this.y = Math.round(this.y);
-        }
-    },
+            case 'bottom':
+                if (!box.overlay) {
+                    if (info.autoHeight) {
+                        size.height += box.height;
+                    } else {
+                        bodyBox.height -= box.height;
+                    }
+                }
+                box.y = (bodyBox.y + bodyBox.height);
+                break;
 
-    isZero: function() {
-        return this.x == 0 && this.y == 0;
-    }
-});
+            case 'left':
+                box.x = bodyBox.x;
+                if (!box.overlay) {
+                    bodyBox.x += box.width;
+                    if (info.autoWidth) {
+                        size.width += box.width;
+                    } else {
+                        bodyBox.width -= box.width;
+                    }
+                }
+                break;
 
+            case 'right':
+                if (!box.overlay) {
+                    if (info.autoWidth) {
+                        size.width += box.width;
+                    } else {
+                        bodyBox.width -= box.width;
+                    }
+                }
+                box.x = (bodyBox.x + bodyBox.width);
+                break;
+        }
 
-Ext.define('Ext.util.KeyNav', {
-    
-    alternateClassName: 'Ext.KeyNav',
-    
-    requires: ['Ext.util.KeyMap'],
-    
-    statics: {
-        keyOptions: {
-            left: 37,
-            right: 39,
-            up: 38,
-            down: 40,
-            space: 32,
-            pageUp: 33,
-            pageDown: 34,
-            del: 46,
-            backspace: 8,
-            home: 36,
-            end: 35,
-            enter: 13,
-            esc: 27,
-            tab: 9
+        if (box.ignoreFrame) {
+            if (pos == 'bottom') {
+                box.y += (frameSize.bottom + padding.bottom + border.bottom);
+            }
+            else {
+                box.y -= (frameSize.top + padding.top + border.top);
+            }
+            if (pos == 'right') {
+                box.x += (frameSize.right + padding.right + border.right);
+            }
+            else {
+                box.x -= (frameSize.left + padding.left + border.left);
+            }
         }
+        return box;
     },
+
     
-    constructor: function(el, config){
-        this.setConfig(el, config || {});
-    },
-    
-    
-    setConfig: function(el, config) {
-        if (this.map) {
-            this.map.destroy();
-        }
-        
-        var map = Ext.create('Ext.util.KeyMap', el, null, this.getKeyEvent('forceKeyDown' in config ? config.forceKeyDown : this.forceKeyDown)),
-            keys = Ext.util.KeyNav.keyOptions,
-            scope = config.scope || this,
-            key;
+    initBox : function(item) {
+        var me = this,
+            bodyBox = me.info.bodyBox,
+            horizontal = (item.dock == 'top' || item.dock == 'bottom'),
+            owner = me.owner,
+            frameSize = me.frameSize,
+            info = me.info,
+            padding = info.padding,
+            border = info.border,
+            box = {
+                item: item,
+                overlay: item.overlay,
+                type: item.dock,
+                offsets: Ext.Element.parseBox(item.offsets || {}),
+                ignoreFrame: item.ignoreParentFrame
+            };
         
-        this.map = map;
-        for (key in keys) {
-            if (keys.hasOwnProperty(key)) {
-                if (config[key]) {
-                    map.addBinding({
-                        scope: scope,
-                        key: keys[key],
-                        handler: Ext.Function.bind(this.handleEvent, scope, [config[key]], true),
-                        defaultEventAction: config.defaultEventAction || this.defaultEventAction
-                    });
+        if (item.stretch !== false) {
+            box.stretched = true;
+            if (horizontal) {
+                box.x = bodyBox.x + box.offsets.left;
+                box.width = bodyBox.width - (box.offsets.left + box.offsets.right);
+                if (box.ignoreFrame) {
+                    box.width += (frameSize.left + frameSize.right + border.left + border.right + padding.left + padding.right);
+                }
+                item.setCalculatedSize(box.width - item.el.getMargin('lr'), undefined, owner);
+            }
+            else {
+                box.y = bodyBox.y + box.offsets.top;
+                box.height = bodyBox.height - (box.offsets.bottom + box.offsets.top);
+                if (box.ignoreFrame) {
+                    box.height += (frameSize.top + frameSize.bottom + border.top + border.bottom + padding.top + padding.bottom);
+                }
+                item.setCalculatedSize(undefined, box.height - item.el.getMargin('tb'), owner);
+
+                
+                
+                if (!Ext.supports.ComputedStyle) {
+                    item.el.repaint();
                 }
             }
         }
+        else {
+            item.doComponentLayout();
+            box.width = item.getWidth() - (box.offsets.left + box.offsets.right);
+            box.height = item.getHeight() - (box.offsets.bottom + box.offsets.top);
+            box.y += box.offsets.top;
+            if (horizontal) {
+                box.x = (item.align == 'right') ? bodyBox.width - box.width : bodyBox.x;
+                box.x += box.offsets.left;
+            }
+        }
+
         
-        map.disable();
-        if (!config.disabled) {
-            map.enable();
+        
+        if (box.width === undefined) {
+            box.width = item.getWidth() + item.el.getMargin('lr');
+        }
+        if (box.height === undefined) {
+            box.height = item.getHeight() + item.el.getMargin('tb');
         }
-    },
-    
-    
-    handleEvent: function(map, event, handler){
-        return handler.call(this, event);
-    },
-    
-    
-    disabled: false,
-    
-    
-    defaultEventAction: "stopEvent",
-    
-    
-    forceKeyDown: false,
-    
-    
-    destroy: function(removeEl){
-        this.map.destroy(removeEl);
-        delete this.map;
-    },
 
-    
-    enable: function() {
-        this.map.enable();
-        this.disabled = false;
+        return box;
     },
 
     
-    disable: function() {
-        this.map.disable();
-        this.disabled = true;
-    },
-    
-    
-    setDisabled : function(disabled){
-        this.map.setDisabled(disabled);
-        this.disabled = disabled;
+    getLayoutItems : function() {
+        var it = this.owner.getDockedItems(),
+            ln = it.length,
+            i = 0,
+            result = [];
+        for (; i < ln; i++) {
+            if (it[i].isVisible(true)) {
+                result.push(it[i]);
+            }
+        }
+        return result;
     },
-    
-    
-    getKeyEvent: function(forceKeyDown){
-        return (forceKeyDown || Ext.EventManager.useKeyDown) ? 'keydown' : 'keypress';
-    }
-});
-
 
+    
+    renderItems: function(items, target) {
+        var cns = target.dom.childNodes,
+            cnsLn = cns.length,
+            ln = items.length,
+            domLn = 0,
+            i, j, cn, item;
 
-Ext.define('Ext.fx.Queue', {
+        
+        for (i = 0; i < cnsLn; i++) {
+            cn = Ext.get(cns[i]);
+            for (j = 0; j < ln; j++) {
+                item = items[j];
+                if (item.rendered && (cn.id == item.el.id || cn.contains(item.el.id))) {
+                    break;
+                }
+            }
 
-    requires: ['Ext.util.HashMap'],
+            if (j === ln) {
+                domLn++;
+            }
+        }
 
-    constructor: function() {
-        this.targets = Ext.create('Ext.util.HashMap');
-        this.fxQueue = {};
-    },
+        
+        for (i = 0, j = 0; i < ln; i++, j++) {
+            item = items[i];
 
-    
-    getFxDefaults: function(targetId) {
-        var target = this.targets.get(targetId);
-        if (target) {
-            return target.fxDefaults;
-        }
-        return {};
-    },
+            
+            
+            
+            
+            
+            
+            
+            
+            if (i === j && (item.dock === 'right' || item.dock === 'bottom')) {
+                j += domLn;
+            }
 
-    
-    setFxDefaults: function(targetId, obj) {
-        var target = this.targets.get(targetId);
-        if (target) {
-            target.fxDefaults = Ext.apply(target.fxDefaults || {}, obj);
+            
+            if (item && !item.rendered) {
+                this.renderItem(item, target, j);
+            }
+            else if (!this.isValidParent(item, target, j)) {
+                this.moveItem(item, target, j);
+            }
         }
     },
 
     
-    stopAnimation: function(targetId) {
+    setBodyBox : function(box) {
         var me = this,
-            queue = me.getFxQueue(targetId),
-            ln = queue.length;
-        while (ln) {
-            queue[ln - 1].end();
-            ln--;
+            owner = me.owner,
+            body = owner.body,
+            info = me.info,
+            bodyMargin = info.bodyMargin,
+            padding = info.padding,
+            border = info.border,
+            frameSize = me.frameSize;
+        
+        
+        if (owner.collapsed) {
+            return;
+        }
+        
+        if (Ext.isNumber(box.width)) {
+            box.width -= bodyMargin.left + bodyMargin.right;
+        }
+        
+        if (Ext.isNumber(box.height)) {
+            box.height -= bodyMargin.top + bodyMargin.bottom;
+        }
+        
+        me.setElementSize(body, box.width, box.height);
+        if (Ext.isNumber(box.x)) {
+            body.setLeft(box.x - padding.left - frameSize.left);
+        }
+        if (Ext.isNumber(box.y)) {
+            body.setTop(box.y - padding.top - frameSize.top);
         }
     },
 
     
-    getActiveAnimation: function(targetId) {
-        var queue = this.getFxQueue(targetId);
-        return (queue && !!queue.length) ? queue[0] : false;
-    },
-
-    
-    hasFxBlock: function(targetId) {
-        var queue = this.getFxQueue(targetId);
-        return queue && queue[0] && queue[0].block;
+    configureItem : function(item, pos) {
+        this.callParent(arguments);
+        if (item.dock == 'top' || item.dock == 'bottom') {
+            item.layoutManagedWidth = 1;
+            item.layoutManagedHeight = 2;
+        } else {
+            item.layoutManagedWidth = 2;
+            item.layoutManagedHeight = 1;
+        }
+        
+        item.addCls(Ext.baseCSSPrefix + 'docked');
+        item.addClsWithUI('docked-' + item.dock);
     },
 
-    
-    getFxQueue: function(targetId) {
-        if (!targetId) {
-            return false;
+    afterRemove : function(item) {
+        this.callParent(arguments);
+        if (this.itemCls) {
+            item.el.removeCls(this.itemCls + '-' + item.dock);
         }
-        var me = this,
-            queue = me.fxQueue[targetId],
-            target = me.targets.get(targetId);
+        var dom = item.el.dom;
 
-        if (!target) {
-            return false;
+        if (!item.destroying && dom) {
+            dom.parentNode.removeChild(dom);
         }
+        this.childrenChanged = true;
+    }
+});
 
-        if (!queue) {
-            me.fxQueue[targetId] = [];
-            
-            if (target.type != 'element') {
-                target.target.on('destroy', function() {
-                    me.fxQueue[targetId] = [];
-                });
-            }
-        }
-        return me.fxQueue[targetId];
-    },
+Ext.define('Ext.util.Memento', function () {
 
-    
-    queueFx: function(anim) {
-        var me = this,
-            target = anim.target,
-            queue, ln;
+    function captureOne (src, target, prop) {
+        src[prop] = target[prop];
+    }
 
-        if (!target) {
-            return;
+    function removeOne (src, target, prop) {
+        delete src[prop];
+    }
+
+    function restoreOne (src, target, prop) {
+        var value = src[prop];
+        if (value || src.hasOwnProperty(prop)) {
+            restoreValue(target, prop, value);
         }
+    }
 
-        queue = me.getFxQueue(target.getId());
-        ln = queue.length;
+    function restoreValue (target, prop, value) {
+        if (Ext.isDefined(value)) {
+            target[prop] = value;
+        } else {
+            delete target[prop];
+        }
+    }
 
-        if (ln) {
-            if (anim.concurrent) {
-                anim.paused = false;
-            }
-            else {
-                queue[ln - 1].on('afteranimate', function() {
-                    anim.paused = false;
+    function doMany (doOne, src, target, props) {
+        if (src) {
+            if (Ext.isArray(props)) {
+                Ext.each(props, function (prop) {
+                    doOne(src, target, prop);
                 });
+            } else {
+                doOne(src, target, props);
             }
         }
-        else {
-            anim.paused = false;
-        }
-        anim.on('afteranimate', function() {
-            Ext.Array.remove(queue, anim);
-            if (anim.remove) {
-                if (target.type == 'element') {
-                    var el = Ext.get(target.id);
-                    if (el) {
-                        el.remove();
-                    }
-                }
-            }
-        }, this);
-        queue.push(anim);
     }
-});
-
 
-Ext.define('Ext.fx.target.Target', {
+    return {
+        
+        data: null,
 
-    isAnimTarget: true,
+        
+        target: null,
 
-    constructor: function(target) {
-        this.target = target;
-        this.id = this.getId();
-    },
-    
-    getId: function() {
-        return this.target.id;
-    }
-});
+        
+        constructor: function (target, props) {
+            if (target) {
+                this.target = target;
+                if (props) {
+                    this.capture(props);
+                }
+            }
+        },
 
+        
+        capture: function (props, target) {
+            doMany(captureOne, this.data || (this.data = {}), target || this.target, props);
+        },
 
+        
+        remove: function (props) {
+            doMany(removeOne, this.data, null, props);
+        },
 
-Ext.define('Ext.fx.target.Sprite', {
+        
+        restore: function (props, clear, target) {
+            doMany(restoreOne, this.data, target || this.target, props);
+            if (clear !== false) {
+                this.remove(props);
+            }
+        },
 
-    
+        
+        restoreAll: function (clear, target) {
+            var me = this,
+                t = target || this.target;
 
-    extend: 'Ext.fx.target.Target',
+            Ext.Object.each(me.data, function (prop, value) {
+                restoreValue(t, prop, value);
+            });
 
-    
+            if (clear !== false) {
+                delete me.data;
+            }
+        }
+    };
+}());
 
-    type: 'draw',
 
-    getFromPrim: function(sprite, attr) {
-        var o;
-        if (attr == 'translate') {
-            o = {
-                x: sprite.attr.translation.x || 0,
-                y: sprite.attr.translation.y || 0
-            };
-        }
-        else if (attr == 'rotate') {
-            o = {
-                degrees: sprite.attr.rotation.degrees || 0,
-                x: sprite.attr.rotation.x,
-                y: sprite.attr.rotation.y
-            };
-        }
-        else {
-            o = sprite.attr[attr];
-        }
-        return o;
+Ext.define('Ext.app.EventBus', {
+    requires: [
+        'Ext.util.Event'
+    ],
+    mixins: {
+        observable: 'Ext.util.Observable'
     },
 
-    getAttr: function(attr, val) {
-        return [[this.target, val != undefined ? val : this.getFromPrim(this.target, attr)]];
-    },
+    constructor: function() {
+        this.mixins.observable.constructor.call(this);
 
-    setAttr: function(targetData) {
-        var ln = targetData.length,
-            spriteArr = [],
-            attrs, attr, attrArr, attPtr, spritePtr, idx, value, i, j, x, y, ln2;
-        for (i = 0; i < ln; i++) {
-            attrs = targetData[i].attrs;
-            for (attr in attrs) {
-                attrArr = attrs[attr];
-                ln2 = attrArr.length;
-                for (j = 0; j < ln2; j++) {
-                    spritePtr = attrArr[j][0];
-                    attPtr = attrArr[j][1];
-                    if (attr === 'translate') {
-                        value = {
-                            x: attPtr.x,
-                            y: attPtr.y
-                        };
-                    }
-                    else if (attr === 'rotate') {
-                        x = attPtr.x;
-                        if (isNaN(x)) {
-                            x = null;
-                        }
-                        y = attPtr.y;
-                        if (isNaN(y)) {
-                            y = null;
+        this.bus = {};
+
+        var me = this;
+        Ext.override(Ext.Component, {
+            fireEvent: function(ev) {
+                if (Ext.util.Observable.prototype.fireEvent.apply(this, arguments) !== false) {
+                    return me.dispatch.call(me, ev, this, arguments);
+                }
+                return false;
+            }
+        });
+    },
+
+    dispatch: function(ev, target, args) {
+        var bus = this.bus,
+            selectors = bus[ev],
+            selector, controllers, id, events, event, i, ln;
+
+        if (selectors) {
+            
+            for (selector in selectors) {
+                
+                if (target.is(selector)) {
+                    
+                    controllers = selectors[selector];
+                    for (id in controllers) {
+                        
+                        events = controllers[id];
+                        for (i = 0, ln = events.length; i < ln; i++) {
+                            event = events[i];
+                            
+                            if (event.fire.apply(event, Array.prototype.slice.call(args, 1)) === false) {
+                                return false;
+                            };
                         }
-                        value = {
-                            degrees: attPtr.degrees,
-                            x: x,
-                            y: y
-                        };
-                    }
-                    else if (attr === 'width' || attr === 'height' || attr === 'x' || attr === 'y') {
-                        value = parseFloat(attPtr);
-                    }
-                    else {
-                        value = attPtr;
-                    }
-                    idx = Ext.Array.indexOf(spriteArr, spritePtr);
-                    if (idx == -1) {
-                        spriteArr.push([spritePtr, {}]);
-                        idx = spriteArr.length - 1;
                     }
-                    spriteArr[idx][1][attr] = value;
                 }
             }
         }
-        ln = spriteArr.length;
-        for (i = 0; i < ln; i++) {
-            spritePtr = spriteArr[i];
-            spritePtr[0].setAttributes(spritePtr[1]);
-        }
-        this.target.redraw();
-    }
-});
+    },
 
+    control: function(selectors, listeners, controller) {
+        var bus = this.bus,
+            selector, fn;
 
+        if (Ext.isString(selectors)) {
+            selector = selectors;
+            selectors = {};
+            selectors[selector] = listeners;
+            this.control(selectors, null, controller);
+            return;
+        }
 
-Ext.define('Ext.fx.target.CompositeSprite', {
+        Ext.Object.each(selectors, function(selector, listeners) {
+            Ext.Object.each(listeners, function(ev, listener) {
+                var options = {},
+                    scope = controller,
+                    event = Ext.create('Ext.util.Event', controller, ev);
 
-    
+                
+                if (Ext.isObject(listener)) {
+                    options = listener;
+                    listener = options.fn;
+                    scope = options.scope || controller;
+                    delete options.fn;
+                    delete options.scope;
+                }
 
-    extend: 'Ext.fx.target.Sprite',
+                event.addListener(listener, scope, options);
 
-    
+                
+                bus[ev] = bus[ev] || {};
+                bus[ev][selector] = bus[ev][selector] || {};
+                bus[ev][selector][controller.id] = bus[ev][selector][controller.id] || [];
 
-    getAttr: function(attr, val) {
-        var out = [],
-            target = this.target;
-        target.each(function(sprite) {
-            out.push([sprite, val != undefined ? val : this.getFromPrim(sprite, attr)]);
-        }, this);
-        return out;
+                
+                bus[ev][selector][controller.id].push(event);
+            });
+        });
     }
 });
 
+Ext.define('Ext.data.Types', {
+    singleton: true,
+    requires: ['Ext.data.SortTypes']
+}, function() {
+    var st = Ext.data.SortTypes;
 
-Ext.define('Ext.fx.target.Component', {
-
-    
-   
-    extend: 'Ext.fx.target.Target',
-    
-    
-
-    type: 'component',
+    Ext.apply(Ext.data.Types, {
+        
+        stripRe: /[\$,%]/g,
 
-    
-    getPropMethod: {
-        top: function() {
-            return this.getPosition(true)[1];
-        },
-        left: function() {
-            return this.getPosition(true)[0];
-        },
-        x: function() {
-            return this.getPosition()[0];
+        
+        AUTO: {
+            convert: function(v) {
+                return v;
+            },
+            sortType: st.none,
+            type: 'auto'
         },
-        y: function() {
-            return this.getPosition()[1];
+
+        
+        STRING: {
+            convert: function(v) {
+                var defaultValue = this.useNull ? null : '';
+                return (v === undefined || v === null) ? defaultValue : String(v);
+            },
+            sortType: st.asUCString,
+            type: 'string'
         },
-        height: function() {
-            return this.getHeight();
+
+        
+        INT: {
+            convert: function(v) {
+                return v !== undefined && v !== null && v !== '' ?
+                    parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
+            },
+            sortType: st.none,
+            type: 'int'
         },
-        width: function() {
-            return this.getWidth();
+
+        
+        FLOAT: {
+            convert: function(v) {
+                return v !== undefined && v !== null && v !== '' ?
+                    parseFloat(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
+            },
+            sortType: st.none,
+            type: 'float'
         },
-        opacity: function() {
-            return this.el.getStyle('opacity');
-        }
-    },
 
-    compMethod: {
-        top: 'setPosition',
-        left: 'setPosition',
-        x: 'setPagePosition',
-        y: 'setPagePosition',
-        height: 'setSize',
-        width: 'setSize',
-        opacity: 'setOpacity'
-    },
+        
+        BOOL: {
+            convert: function(v) {
+                if (this.useNull && (v === undefined || v === null || v === '')) {
+                    return null;
+                }
+                return v === true || v === 'true' || v == 1;
+            },
+            sortType: st.none,
+            type: 'bool'
+        },
 
-    
-    getAttr: function(attr, val) {
-        return [[this.target, val !== undefined ? val : this.getPropMethod[attr].call(this.target)]];
-    },
+        
+        DATE: {
+            convert: function(v) {
+                var df = this.dateFormat,
+                    parsed;
 
-    setAttr: function(targetData, isFirstFrame, isLastFrame) {
-        var me = this,
-            target = me.target,
-            ln = targetData.length,
-            attrs, attr, o, i, j, meth, targets, left, top, w, h;
-        for (i = 0; i < ln; i++) {
-            attrs = targetData[i].attrs;
-            for (attr in attrs) {
-                targets = attrs[attr].length;
-                meth = {
-                    setPosition: {},
-                    setPagePosition: {},
-                    setSize: {},
-                    setOpacity: {}
-                };
-                for (j = 0; j < targets; j++) {
-                    o = attrs[attr][j];
-                    
-                    
-                    
-                    
-                    meth[me.compMethod[attr]].target = o[0];
-                    meth[me.compMethod[attr]][attr] = o[1];
-                }
-                if (meth.setPosition.target) {
-                    o = meth.setPosition;
-                    left = (o.left === undefined) ? undefined : parseInt(o.left, 10);
-                    top = (o.top === undefined) ? undefined : parseInt(o.top, 10);
-                    o.target.setPosition(left, top);
+                if (!v) {
+                    return null;
                 }
-                if (meth.setPagePosition.target) {
-                    o = meth.setPagePosition;
-                    o.target.setPagePosition(o.x, o.y);
+                if (Ext.isDate(v)) {
+                    return v;
                 }
-                if (meth.setSize.target) {
-                    o = meth.setSize;
-                    
-                    w = (o.width === undefined) ? o.target.getWidth() : parseInt(o.width, 10);
-                    h = (o.height === undefined) ? o.target.getHeight() : parseInt(o.height, 10);
-
-                    
-                    
-                    
-                    
-                    
-                    
-                    
-                    if (isLastFrame || me.dynamic) {
-                        o.target.componentLayout.childrenChanged = true;
-
-                        
-                        if (me.layoutAnimation) {
-                            o.target.setCalculatedSize(w, h);
-                        } else {
-                            o.target.setSize(w, h);
-                        }
+                if (df) {
+                    if (df == 'timestamp') {
+                        return new Date(v*1000);
                     }
-                    else {
-                        o.target.el.setSize(w, h);
+                    if (df == 'time') {
+                        return new Date(parseInt(v, 10));
                     }
+                    return Ext.Date.parse(v, df);
                 }
-                if (meth.setOpacity.target) {
-                    o = meth.setOpacity;
-                    o.target.el.setStyle('opacity', o.opacity);
-                }
-            }
+
+                parsed = Date.parse(v);
+                return parsed ? new Date(parsed) : null;
+            },
+            sortType: st.asDate,
+            type: 'date'
         }
-    }
-});
+    });
 
+    Ext.apply(Ext.data.Types, {
+        
+        BOOLEAN: this.BOOL,
 
-Ext.define('Ext.fx.CubicBezier', {
+        
+        INTEGER: this.INT,
 
-    
+        
+        NUMBER: this.FLOAT
+    });
+});
 
-    singleton: true,
 
+Ext.define('Ext.data.Field', {
+    requires: ['Ext.data.Types', 'Ext.data.SortTypes'],
+    alias: 'data.field',
     
-
-    cubicBezierAtTime: function(t, p1x, p1y, p2x, p2y, duration) {
-        var cx = 3 * p1x,
-            bx = 3 * (p2x - p1x) - cx,
-            ax = 1 - cx - bx,
-            cy = 3 * p1y,
-            by = 3 * (p2y - p1y) - cy,
-            ay = 1 - cy - by;
-        function sampleCurveX(t) {
-            return ((ax * t + bx) * t + cx) * t;
-        }
-        function solve(x, epsilon) {
-            var t = solveCurveX(x, epsilon);
-            return ((ay * t + by) * t + cy) * t;
+    constructor : function(config) {
+        if (Ext.isString(config)) {
+            config = {name: config};
         }
-        function solveCurveX(x, epsilon) {
-            var t0, t1, t2, x2, d2, i;
-            for (t2 = x, i = 0; i < 8; i++) {
-                x2 = sampleCurveX(t2) - x;
-                if (Math.abs(x2) < epsilon) {
-                    return t2;
-                }
-                d2 = (3 * ax * t2 + 2 * bx) * t2 + cx;
-                if (Math.abs(d2) < 1e-6) {
-                    break;
-                }
-                t2 = t2 - x2 / d2;
-            }
-            t0 = 0;
-            t1 = 1;
-            t2 = x;
-            if (t2 < t0) {
-                return t0;
-            }
-            if (t2 > t1) {
-                return t1;
-            }
-            while (t0 < t1) {
-                x2 = sampleCurveX(t2);
-                if (Math.abs(x2 - x) < epsilon) {
-                    return t2;
-                }
-                if (x > x2) {
-                    t0 = t2;
-                } else {
-                    t1 = t2;
-                }
-                t2 = (t1 - t0) / 2 + t0;
+        Ext.apply(this, config);
+        
+        var types = Ext.data.Types,
+            st = this.sortType,
+            t;
+
+        if (this.type) {
+            if (Ext.isString(this.type)) {
+                this.type = types[this.type.toUpperCase()] || types.AUTO;
             }
-            return t2;
+        } else {
+            this.type = types.AUTO;
         }
-        return solve(t, 1 / (200 * duration));
-    },
-
-    cubicBezier: function(x1, y1, x2, y2) {
-        var fn = function(pos) {
-            return Ext.fx.CubicBezier.cubicBezierAtTime(pos, x1, y1, x2, y2, 1);
-        };
-        fn.toCSS3 = function() {
-            return 'cubic-bezier(' + [x1, y1, x2, y2].join(',') + ')';
-        };
-        fn.reverse = function() {
-            return Ext.fx.CubicBezier.cubicBezier(1 - x2, 1 - y2, 1 - x1, 1 - y1);
-        };
-        return fn;
-    }
-});
 
-Ext.define('Ext.draw.Color', {
+        
+        if (Ext.isString(st)) {
+            this.sortType = Ext.data.SortTypes[st];
+        } else if(Ext.isEmpty(st)) {
+            this.sortType = this.type.sortType;
+        }
 
+        if (!this.convert) {
+            this.convert = this.type.convert;
+        }
+    },
+    
+    
+    
+    
     
-
     
 
-    colorToHexRe: /(.*?)rgb\((\d+),\s*(\d+),\s*(\d+)\)/,
-    rgbRe: /\s*rgb\s*\(\s*([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\s*\)\s*/,
-    hexRe: /\s*#([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)([0-9a-fA-F][0-9a-fA-F]?)\s*/,
+    
+    dateFormat: null,
+    
+    
+    useNull: false,
+    
+    
+    defaultValue: "",
 
     
-    lightnessFactor: 0.2,
+    mapping: null,
 
     
-    constructor : function(red, green, blue) {
-        var me = this,
-            clamp = Ext.Number.constrain;
-        me.r = clamp(red, 0, 255);
-        me.g = clamp(green, 0, 255);
-        me.b = clamp(blue, 0, 255);
-    },
+    sortType : null,
 
     
-    getRed: function() {
-        return this.r;
-    },
+    sortDir : "ASC",
 
     
-    getGreen: function() {
-        return this.g;
-    },
+    allowBlank : true,
 
     
-    getBlue: function() {
-        return this.b;
+    persist: true
+});
+
+
+Ext.define('Ext.util.AbstractMixedCollection', {
+    requires: ['Ext.util.Filter'],
+
+    mixins: {
+        observable: 'Ext.util.Observable'
     },
 
-    
-    getRGB: function() {
+    constructor: function(allowFunctions, keyFn) {
         var me = this;
-        return [me.r, me.g, me.b];
-    },
 
-    
-    getHSL: function() {
-        var me = this,
-            r = me.r / 255,
-            g = me.g / 255,
-            b = me.b / 255,
-            max = Math.max(r, g, b),
-            min = Math.min(r, g, b),
-            delta = max - min,
-            h,
-            s = 0,
-            l = 0.5 * (max + min);
+        me.items = [];
+        me.map = {};
+        me.keys = [];
+        me.length = 0;
 
-        
-        if (min != max) {
-            s = (l < 0.5) ? delta / (max + min) : delta / (2 - max - min);
-            if (r == max) {
-                h = 60 * (g - b) / delta;
-            } else if (g == max) {
-                h = 120 + 60 * (b - r) / delta;
-            } else {
-                h = 240 + 60 * (r - g) / delta;
-            }
-            if (h < 0) {
-                h += 360;
-            }
-            if (h >= 360) {
-                h -= 360;
-            }
+        me.addEvents(
+            
+            'clear',
+
+            
+            'add',
+
+            
+            'replace',
+
+            
+            'remove'
+        );
+
+        me.allowFunctions = allowFunctions === true;
+
+        if (keyFn) {
+            me.getKey = keyFn;
         }
-        return [h, s, l];
+
+        me.mixins.observable.constructor.call(me);
     },
 
     
-    getLighter: function(factor) {
-        var hsl = this.getHSL();
-        factor = factor || this.lightnessFactor;
-        hsl[2] = Ext.Number.constrain(hsl[2] + factor, 0, 1);
-        return this.fromHSL(hsl[0], hsl[1], hsl[2]);
-    },
+    allowFunctions : false,
 
     
-    getDarker: function(factor) {
-        factor = factor || this.lightnessFactor;
-        return this.getLighter(-factor);
+    add : function(key, obj){
+        var me = this,
+            myObj = obj,
+            myKey = key,
+            old;
+
+        if (arguments.length == 1) {
+            myObj = myKey;
+            myKey = me.getKey(myObj);
+        }
+        if (typeof myKey != 'undefined' && myKey !== null) {
+            old = me.map[myKey];
+            if (typeof old != 'undefined') {
+                return me.replace(myKey, myObj);
+            }
+            me.map[myKey] = myObj;
+        }
+        me.length++;
+        me.items.push(myObj);
+        me.keys.push(myKey);
+        me.fireEvent('add', me.length - 1, myObj, myKey);
+        return myObj;
     },
 
     
-    toString: function() {
-        var me = this,
-            round = Math.round,
-            r = round(me.r).toString(16),
-            g = round(me.g).toString(16),
-            b = round(me.b).toString(16);
-        r = (r.length == 1) ? '0' + r : r;
-        g = (g.length == 1) ? '0' + g : g;
-        b = (b.length == 1) ? '0' + b : b;
-        return ['#', r, g, b].join('');
+    getKey : function(o){
+         return o.id;
     },
 
     
-    toHex: function(color) {
-        if (Ext.isArray(color)) {
-            color = color[0];
-        }
-        if (!Ext.isString(color)) {
-            return '';
-        }
-        if (color.substr(0, 1) === '#') {
-            return color;
-        }
-        var digits = this.colorToHexRe.exec(color);
+    replace : function(key, o){
+        var me = this,
+            old,
+            index;
 
-        if (Ext.isArray(digits)) {
-            var red = parseInt(digits[2], 10),
-                green = parseInt(digits[3], 10),
-                blue = parseInt(digits[4], 10),
-                rgb = blue | (green << 8) | (red << 16);
-            return digits[1] + '#' + ("000000" + rgb.toString(16)).slice(-6);
+        if (arguments.length == 1) {
+            o = arguments[0];
+            key = me.getKey(o);
         }
-        else {
-            return '';
+        old = me.map[key];
+        if (typeof key == 'undefined' || key === null || typeof old == 'undefined') {
+             return me.add(key, o);
         }
+        index = me.indexOfKey(key);
+        me.items[index] = o;
+        me.map[key] = o;
+        me.fireEvent('replace', key, old, o);
+        return o;
     },
 
     
-    fromString: function(str) {
-        var values, r, g, b,
-            parse = parseInt;
+    addAll : function(objs){
+        var me = this,
+            i = 0,
+            args,
+            len,
+            key;
 
-        if ((str.length == 4 || str.length == 7) && str.substr(0, 1) === '#') {
-            values = str.match(this.hexRe);
-            if (values) {
-                r = parse(values[1], 16) >> 0;
-                g = parse(values[2], 16) >> 0;
-                b = parse(values[3], 16) >> 0;
-                if (str.length == 4) {
-                    r += (r * 16);
-                    g += (g * 16);
-                    b += (b * 16);
-                }
+        if (arguments.length > 1 || Ext.isArray(objs)) {
+            args = arguments.length > 1 ? arguments : objs;
+            for (len = args.length; i < len; i++) {
+                me.add(args[i]);
             }
-        }
-        else {
-            values = str.match(this.rgbRe);
-            if (values) {
-                r = values[1];
-                g = values[2];
-                b = values[3];
+        } else {
+            for (key in objs) {
+                if (objs.hasOwnProperty(key)) {
+                    if (me.allowFunctions || typeof objs[key] != 'function') {
+                        me.add(key, objs[key]);
+                    }
+                }
             }
         }
-
-        return (typeof r == 'undefined') ? undefined : Ext.create('Ext.draw.Color', r, g, b);
-    },
-
-    
-    getGrayscale: function() {
-        
-        return this.r * 0.3 + this.g * 0.59 + this.b * 0.11;
     },
 
     
-    fromHSL: function(h, s, l) {
-        var C, X, m, i, rgb = [],
-            abs = Math.abs,
-            floor = Math.floor;
+    each : function(fn, scope){
+        var items = [].concat(this.items), 
+            i = 0,
+            len = items.length,
+            item;
 
-        if (s == 0 || h == null) {
-            
-            rgb = [l, l, l];
-        }
-        else {
-            
-            
-            
-            
-            h /= 60;
-            C = s * (1 - abs(2 * l - 1));
-            X = C * (1 - abs(h - 2 * floor(h / 2) - 1));
-            m = l - C / 2;
-            switch (floor(h)) {
-                case 0:
-                    rgb = [C, X, 0];
-                    break;
-                case 1:
-                    rgb = [X, C, 0];
-                    break;
-                case 2:
-                    rgb = [0, C, X];
-                    break;
-                case 3:
-                    rgb = [0, X, C];
-                    break;
-                case 4:
-                    rgb = [X, 0, C];
-                    break;
-                case 5:
-                    rgb = [C, 0, X];
-                    break;
+        for (; i < len; i++) {
+            item = items[i];
+            if (fn.call(scope || item, item, i, len) === false) {
+                break;
             }
-            rgb = [rgb[0] + m, rgb[1] + m, rgb[2] + m];
         }
-        return Ext.create('Ext.draw.Color', rgb[0] * 255, rgb[1] * 255, rgb[2] * 255);
-    }
-}, function() {
-    var prototype = this.prototype;
+    },
 
     
-    this.addStatics({
-        fromHSL: function() {
-            return prototype.fromHSL.apply(prototype, arguments);
-        },
-        fromString: function() {
-            return prototype.fromString.apply(prototype, arguments);
-        },
-        toHex: function() {
-            return prototype.toHex.apply(prototype, arguments);
-        }
-    });
-});
-
-
-Ext.define('Ext.dd.StatusProxy', {
-    animRepair: false,
-
-    constructor: function(config){
-        Ext.apply(this, config);
-        this.id = this.id || Ext.id();
-        this.proxy = Ext.createWidget('component', {
-            floating: true,
-            id: this.id,
-            html: '<div class="' + Ext.baseCSSPrefix + 'dd-drop-icon"></div>' +
-                  '<div class="' + Ext.baseCSSPrefix + 'dd-drag-ghost"></div>',
-            cls: Ext.baseCSSPrefix + 'dd-drag-proxy ' + this.dropNotAllowed,
-            shadow: !config || config.shadow !== false,
-            renderTo: document.body
-        });
-
-        this.el = this.proxy.el;
-        this.el.show();
-        this.el.setVisibilityMode(Ext.core.Element.VISIBILITY);
-        this.el.hide();
+    eachKey : function(fn, scope){
+        var keys = this.keys,
+            items = this.items,
+            i = 0,
+            len = keys.length;
 
-        this.ghost = Ext.get(this.el.dom.childNodes[1]);
-        this.dropStatus = this.dropNotAllowed;
+        for (; i < len; i++) {
+            fn.call(scope || window, keys[i], items[i], i, len);
+        }
     },
-    
-    dropAllowed : Ext.baseCSSPrefix + 'dd-drop-ok',
-    
-    dropNotAllowed : Ext.baseCSSPrefix + 'dd-drop-nodrop',
 
     
-    setStatus : function(cssClass){
-        cssClass = cssClass || this.dropNotAllowed;
-        if(this.dropStatus != cssClass){
-            this.el.replaceCls(this.dropStatus, cssClass);
-            this.dropStatus = cssClass;
+    findBy : function(fn, scope) {
+        var keys = this.keys,
+            items = this.items,
+            i = 0,
+            len = items.length;
+
+        for (; i < len; i++) {
+            if (fn.call(scope || window, items[i], keys[i])) {
+                return items[i];
+            }
         }
+        return null;
     },
 
-    
-    reset : function(clearGhost){
-        this.el.dom.className = Ext.baseCSSPrefix + 'dd-drag-proxy ' + this.dropNotAllowed;
-        this.dropStatus = this.dropNotAllowed;
-        if(clearGhost){
-            this.ghost.update("");
+    find : function() {
+        if (Ext.isDefined(Ext.global.console)) {
+            Ext.global.console.warn('Ext.util.MixedCollection: find has been deprecated. Use findBy instead.');
         }
+        return this.findBy.apply(this, arguments);
     },
 
     
-    update : function(html){
-        if(typeof html == "string"){
-            this.ghost.update(html);
-        }else{
-            this.ghost.update("");
-            html.style.margin = "0";
-            this.ghost.dom.appendChild(html);
+    insert : function(index, key, obj){
+        var me = this,
+            myKey = key,
+            myObj = obj;
+
+        if (arguments.length == 2) {
+            myObj = myKey;
+            myKey = me.getKey(myObj);
         }
-        var el = this.ghost.dom.firstChild; 
-        if(el){
-            Ext.fly(el).setStyle('float', 'none');
+        if (me.containsKey(myKey)) {
+            me.suspendEvents();
+            me.removeAtKey(myKey);
+            me.resumeEvents();
+        }
+        if (index >= me.length) {
+            return me.add(myKey, myObj);
+        }
+        me.length++;
+        Ext.Array.splice(me.items, index, 0, myObj);
+        if (typeof myKey != 'undefined' && myKey !== null) {
+            me.map[myKey] = myObj;
         }
+        Ext.Array.splice(me.keys, index, 0, myKey);
+        me.fireEvent('add', index, myObj, myKey);
+        return myObj;
     },
 
     
-    getEl : function(){
-        return this.el;
+    remove : function(o){
+        return this.removeAt(this.indexOf(o));
     },
 
     
-    getGhost : function(){
-        return this.ghost;
-    },
+    removeAll : function(items){
+        Ext.each(items || [], function(item) {
+            this.remove(item);
+        }, this);
 
-    
-    hide : function(clear) {
-        this.proxy.hide();
-        if (clear) {
-            this.reset(true);
-        }
+        return this;
     },
 
     
-    stop : function(){
-        if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){
-            this.anim.stop();
+    removeAt : function(index){
+        var me = this,
+            o,
+            key;
+
+        if (index < me.length && index >= 0) {
+            me.length--;
+            o = me.items[index];
+            Ext.Array.erase(me.items, index, 1);
+            key = me.keys[index];
+            if (typeof key != 'undefined') {
+                delete me.map[key];
+            }
+            Ext.Array.erase(me.keys, index, 1);
+            me.fireEvent('remove', o, key);
+            return o;
         }
+        return false;
     },
 
     
-    show : function() {
-        this.proxy.show();
-        this.proxy.toFront();
+    removeAtKey : function(key){
+        return this.removeAt(this.indexOfKey(key));
     },
 
     
-    sync : function(){
-        this.proxy.el.sync();
+    getCount : function(){
+        return this.length;
     },
 
     
-    repair : function(xy, callback, scope){
-        this.callback = callback;
-        this.scope = scope;
-        if (xy && this.animRepair !== false) {
-            this.el.addCls(Ext.baseCSSPrefix + 'dd-drag-repair');
-            this.el.hideUnders(true);
-            this.anim = this.el.animate({
-                duration: this.repairDuration || 500,
-                easing: 'ease-out',
-                to: {
-                    x: xy[0],
-                    y: xy[1]
-                },
-                stopAnimation: true,
-                callback: this.afterRepair,
-                scope: this
-            });
-        } else {
-            this.afterRepair();
-        }
+    indexOf : function(o){
+        return Ext.Array.indexOf(this.items, o);
     },
 
     
-    afterRepair : function(){
-        this.hide(true);
-        if(typeof this.callback == "function"){
-            this.callback.call(this.scope || this);
-        }
-        this.callback = null;
-        this.scope = null;
+    indexOfKey : function(key){
+        return Ext.Array.indexOf(this.keys, key);
     },
 
-    destroy: function(){
-        Ext.destroy(this.ghost, this.proxy, this.el);
-    }
-});
-
-Ext.define('Ext.panel.Proxy', {
-    
-    alternateClassName: 'Ext.dd.PanelProxy',
     
-    constructor: function(panel, config){
-        
-        this.panel = panel;
-        this.id = this.panel.id +'-ddproxy';
-        Ext.apply(this, config);
+    get : function(key) {
+        var me = this,
+            mk = me.map[key],
+            item = mk !== undefined ? mk : (typeof key == 'number') ? me.items[key] : undefined;
+        return typeof item != 'function' || me.allowFunctions ? item : null; 
     },
 
     
-    insertProxy: true,
-
-    
-    setStatus: Ext.emptyFn,
-    reset: Ext.emptyFn,
-    update: Ext.emptyFn,
-    stop: Ext.emptyFn,
-    sync: Ext.emptyFn,
+    getAt : function(index) {
+        return this.items[index];
+    },
 
     
-    getEl: function(){
-        return this.ghost.el;
+    getByKey : function(key) {
+        return this.map[key];
     },
 
     
-    getGhost: function(){
-        return this.ghost;
+    contains : function(o){
+        return Ext.Array.contains(this.items, o);
     },
 
     
-    getProxy: function(){
-        return this.proxy;
+    containsKey : function(key){
+        return typeof this.map[key] != 'undefined';
     },
 
     
-    hide : function(){
-        if (this.ghost) {
-            if (this.proxy) {
-                this.proxy.remove();
-                delete this.proxy;
-            }
+    clear : function(){
+        var me = this;
 
-            
-            this.panel.unghost(null, false);
-            delete this.ghost;
-        }
+        me.length = 0;
+        me.items = [];
+        me.keys = [];
+        me.map = {};
+        me.fireEvent('clear');
     },
 
     
-    show: function(){
-        if (!this.ghost) {
-            var panelSize = this.panel.getSize();
-            this.panel.el.setVisibilityMode(Ext.core.Element.DISPLAY);
-            this.ghost = this.panel.ghost();
-            if (this.insertProxy) {
-                
-                
-                this.proxy = this.panel.el.insertSibling({cls: Ext.baseCSSPrefix + 'panel-dd-spacer'});
-                this.proxy.setSize(panelSize);
-            }
-        }
+    first : function() {
+        return this.items[0];
     },
 
     
-    repair: function(xy, callback, scope) {
-        this.hide();
-        if (typeof callback == "function") {
-            callback.call(scope || this);
-        }
+    last : function() {
+        return this.items[this.length - 1];
     },
 
     
-    moveProxy : function(parentNode, before){
-        if (this.proxy) {
-            parentNode.insertBefore(this.proxy.dom, before);
-        }
-    }
-});
-
-
-Ext.define('Ext.layout.component.AbstractDock', {
-
-    
-
-    extend: 'Ext.layout.component.Component',
-
-    
-
-    type: 'dock',
+    sum: function(property, root, start, end) {
+        var values = this.extractValues(property, root),
+            length = values.length,
+            sum    = 0,
+            i;
 
-    
-    autoSizing: true,
+        start = start || 0;
+        end   = (end || end === 0) ? end : length - 1;
 
-    beforeLayout: function() {
-        var returnValue = this.callParent(arguments);
-        if (returnValue !== false && (!this.initializedBorders || this.childrenChanged) && (!this.owner.border || this.owner.manageBodyBorders)) {
-            this.handleItemBorders();
-            this.initializedBorders = true;
+        for (i = start; i <= end; i++) {
+            sum += values[i];
         }
-        return returnValue;
-    },
-    
-    handleItemBorders: function() {
-        var owner = this.owner,
-            body = owner.body,
-            docked = this.getLayoutItems(),
-            borders = {
-                top: [],
-                right: [],
-                bottom: [],
-                left: []
-            },
-            oldBorders = this.borders,
-            opposites = {
-                top: 'bottom',
-                right: 'left',
-                bottom: 'top',
-                left: 'right'
-            },
-            i, ln, item, dock, side;
 
-        for (i = 0, ln = docked.length; i < ln; i++) {
-            item = docked[i];
-            dock = item.dock;
-            
-            if (item.ignoreBorderManagement) {
-                continue;
-            }
-            
-            if (!borders[dock].satisfied) {
-                borders[dock].push(item);
-                borders[dock].satisfied = true;
-            }
-            
-            if (!borders.top.satisfied && opposites[dock] !== 'top') {
-                borders.top.push(item);
-            }
-            if (!borders.right.satisfied && opposites[dock] !== 'right') {
-                borders.right.push(item);
-            }            
-            if (!borders.bottom.satisfied && opposites[dock] !== 'bottom') {
-                borders.bottom.push(item);
-            }            
-            if (!borders.left.satisfied && opposites[dock] !== 'left') {
-                borders.left.push(item);
-            }
-        }
+        return sum;
+    },
 
-        if (oldBorders) {
-            for (side in oldBorders) {
-                if (oldBorders.hasOwnProperty(side)) {
-                    ln = oldBorders[side].length;
-                    if (!owner.manageBodyBorders) {
-                        for (i = 0; i < ln; i++) {
-                            oldBorders[side][i].removeCls(Ext.baseCSSPrefix + 'docked-noborder-' + side);
-                        }
-                        if (!oldBorders[side].satisfied && !owner.bodyBorder) {
-                            body.removeCls(Ext.baseCSSPrefix + 'docked-noborder-' + side);                   
-                        }                    
-                    }
-                    else if (oldBorders[side].satisfied) {
-                        body.setStyle('border-' + side + '-width', '');
-                    }
-                }
-            }
-        }
-                
-        for (side in borders) {
-            if (borders.hasOwnProperty(side)) {
-                ln = borders[side].length;
-                if (!owner.manageBodyBorders) {
-                    for (i = 0; i < ln; i++) {
-                        borders[side][i].addCls(Ext.baseCSSPrefix + 'docked-noborder-' + side);
-                    }
-                    if ((!borders[side].satisfied && !owner.bodyBorder) || owner.bodyBorder === false) {
-                        body.addCls(Ext.baseCSSPrefix + 'docked-noborder-' + side);                   
-                    }                    
-                }
-                else if (borders[side].satisfied) {
-                    body.setStyle('border-' + side + '-width', '1px');
-                }
+    
+    collect: function(property, root, allowNull) {
+        var values = this.extractValues(property, root),
+            length = values.length,
+            hits   = {},
+            unique = [],
+            value, strValue, i;
+
+        for (i = 0; i < length; i++) {
+            value = values[i];
+            strValue = String(value);
+
+            if ((allowNull || !Ext.isEmpty(value)) && !hits[strValue]) {
+                hits[strValue] = true;
+                unique.push(value);
             }
         }
-        
-        this.borders = borders;
+
+        return unique;
     },
+
     
+    extractValues: function(property, root) {
+        var values = this.items;
+
+        if (root) {
+            values = Ext.Array.pluck(values, root);
+        }
+
+        return Ext.Array.pluck(values, property);
+    },
+
     
-    onLayout: function(width, height) {
+    getRange : function(start, end){
         var me = this,
-            owner = me.owner,
-            body = owner.body,
-            layout = owner.layout,
-            target = me.getTarget(),
-            autoWidth = false,
-            autoHeight = false,
-            padding, border, frameSize;
-
-        
-        var info = me.info = {
-            boxes: [],
-            size: {
-                width: width,
-                height: height
-            },
-            bodyBox: {}
-        };
+            items = me.items,
+            range = [],
+            i;
 
-        Ext.applyIf(info, me.getTargetInfo());
+        if (items.length < 1) {
+            return range;
+        }
 
-        
-        if (owner && owner.ownerCt && owner.ownerCt.layout && owner.ownerCt.layout.isLayout) {
-            if (!Ext.isNumber(owner.height) || !Ext.isNumber(owner.width)) {
-                owner.ownerCt.layout.bindToOwnerCtComponent = true;
+        start = start || 0;
+        end = Math.min(typeof end == 'undefined' ? me.length - 1 : end, me.length - 1);
+        if (start <= end) {
+            for (i = start; i <= end; i++) {
+                range[range.length] = items[i];
             }
-            else {
-                owner.ownerCt.layout.bindToOwnerCtComponent = false;
+        } else {
+            for (i = start; i >= end; i--) {
+                range[range.length] = items[i];
             }
         }
+        return range;
+    },
+
+    
+    filter : function(property, value, anyMatch, caseSensitive) {
+        var filters = [],
+            filterFn;
 
         
-        if (height === undefined || height === null || width === undefined || width === null) {
-            padding = info.padding;
-            border = info.border;
-            frameSize = me.frameSize;
+        if (Ext.isString(property)) {
+            filters.push(Ext.create('Ext.util.Filter', {
+                property     : property,
+                value        : value,
+                anyMatch     : anyMatch,
+                caseSensitive: caseSensitive
+            }));
+        } else if (Ext.isArray(property) || property instanceof Ext.util.Filter) {
+            filters = filters.concat(property);
+        }
 
-            
-            if ((height === undefined || height === null) && (width === undefined || width === null)) {
-                autoHeight = true;
-                autoWidth = true;
-                me.setTargetSize(null);
-                me.setBodyBox({width: null, height: null});
-            }
-            
-            else if (height === undefined || height === null) {
-                autoHeight = true;
-                
-                me.setTargetSize(width);
-                me.setBodyBox({width: width - padding.left - border.left - padding.right - border.right - frameSize.left - frameSize.right, height: null});
-            
-            }
-            else {
-                autoWidth = true;
-                
-                me.setTargetSize(null, height);
-                me.setBodyBox({width: null, height: height - padding.top - padding.bottom - border.top - border.bottom - frameSize.top - frameSize.bottom});
-            }
+        
+        
+        filterFn = function(record) {
+            var isMatch = true,
+                length = filters.length,
+                i;
 
-            
-            if (layout && layout.isLayout) {
-                
-                layout.bindToOwnerCtComponent = true;
-                layout.layout();
+            for (i = 0; i < length; i++) {
+                var filter = filters[i],
+                    fn     = filter.filterFn,
+                    scope  = filter.scope;
 
-                
-                
-                
-                
-                
-                
-                
-                
-                
-                
-                
-                
-                info.autoSizedCtLayout = layout.autoSize === true;
+                isMatch = isMatch && fn.call(scope, record);
             }
 
-            
-            
-            
-            
-            
-            me.dockItems(autoWidth, autoHeight);
-            me.setTargetSize(info.size.width, info.size.height);
-        }
-        else {
-            me.setTargetSize(width, height);
-            me.dockItems();
-        }
-        me.callParent(arguments);
+            return isMatch;
+        };
+
+        return this.filterBy(filterFn);
     },
 
     
-    dockItems : function(autoWidth, autoHeight) {
-        this.calculateDockBoxes(autoWidth, autoHeight);
+    filterBy : function(fn, scope) {
+        var me = this,
+            newMC  = new this.self(),
+            keys   = me.keys,
+            items  = me.items,
+            length = items.length,
+            i;
 
-        
-        
-        
-        var info = this.info,
-            boxes = info.boxes,
-            ln = boxes.length,
-            dock, i;
+        newMC.getKey = me.getKey;
 
-        
-        
-        for (i = 0; i < ln; i++) {
-            dock = boxes[i];
-            dock.item.setPosition(dock.x, dock.y);
-            if ((autoWidth || autoHeight) && dock.layout && dock.layout.isLayout) {
-                
-                dock.layout.bindToOwnerCtComponent = true;
+        for (i = 0; i < length; i++) {
+            if (fn.call(scope || me, items[i], keys[i])) {
+                newMC.add(keys[i], items[i]);
             }
         }
 
-        
-        
-        if (!info.autoSizedCtLayout) {
-            if (autoWidth) {
-                info.bodyBox.width = null;
-            }
-            if (autoHeight) {
-                info.bodyBox.height = null;
-            }
-        }
+        return newMC;
+    },
 
-        
-        
-        this.setBodyBox(info.bodyBox);
+    
+    findIndex : function(property, value, start, anyMatch, caseSensitive){
+        if(Ext.isEmpty(value, false)){
+            return -1;
+        }
+        value = this.createValueMatcher(value, anyMatch, caseSensitive);
+        return this.findIndexBy(function(o){
+            return o && value.test(o[property]);
+        }, null, start);
     },
 
     
-    calculateDockBoxes : function(autoWidth, autoHeight) {
-        
-        
-        
+    findIndexBy : function(fn, scope, start){
         var me = this,
-            target = me.getTarget(),
-            items = me.getLayoutItems(),
-            owner = me.owner,
-            bodyEl = owner.body,
-            info = me.info,
-            size = info.size,
-            ln = items.length,
-            padding = info.padding,
-            border = info.border,
-            frameSize = me.frameSize,
-            item, i, box, rect;
+            keys = me.keys,
+            items = me.items,
+            i = start || 0,
+            len = items.length;
 
-        
-        
-        if (autoHeight) {
-            size.height = bodyEl.getHeight() + padding.top + border.top + padding.bottom + border.bottom + frameSize.top + frameSize.bottom;
-        }
-        else {
-            size.height = target.getHeight();
-        }
-        if (autoWidth) {
-            size.width = bodyEl.getWidth() + padding.left + border.left + padding.right + border.right + frameSize.left + frameSize.right;
-        }
-        else {
-            size.width = target.getWidth();
+        for (; i < len; i++) {
+            if (fn.call(scope || me, items[i], keys[i])) {
+                return i;
+            }
         }
+        return -1;
+    },
 
-        info.bodyBox = {
-            x: padding.left + frameSize.left,
-            y: padding.top + frameSize.top,
-            width: size.width - padding.left - border.left - padding.right - border.right - frameSize.left - frameSize.right,
-            height: size.height - border.top - padding.top - border.bottom - padding.bottom - frameSize.top - frameSize.bottom
-        };
-
-        
-        for (i = 0; i < ln; i++) {
-            item = items[i];
-            
-            
-            
-            box = me.initBox(item);
+    
+    createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) {
+        if (!value.exec) { 
+            var er = Ext.String.escapeRegex;
+            value = String(value);
 
-            if (autoHeight === true) {
-                box = me.adjustAutoBox(box, i);
-            }
-            else {
-                box = me.adjustSizedBox(box, i);
+            if (anyMatch === true) {
+                value = er(value);
+            } else {
+                value = '^' + er(value);
+                if (exactMatch === true) {
+                    value += '$';
+                }
             }
-
-            
-            
-            
-            info.boxes.push(box);
+            value = new RegExp(value, caseSensitive ? '' : 'i');
         }
+        return value;
     },
 
     
-    adjustSizedBox : function(box, index) {
-        var bodyBox = this.info.bodyBox,
-            frameSize = this.frameSize,
-            info = this.info,
-            padding = info.padding,
-            pos = box.type,
-            border = info.border;
+    clone : function() {
+        var me = this,
+            copy = new this.self(),
+            keys = me.keys,
+            items = me.items,
+            i = 0,
+            len = items.length;
 
-        switch (pos) {
-            case 'top':
-                box.y = bodyBox.y;
-                break;
+        for(; i < len; i++){
+            copy.add(keys[i], items[i]);
+        }
+        copy.getKey = me.getKey;
+        return copy;
+    }
+});
 
-            case 'left':
-                box.x = bodyBox.x;
-                break;
 
-            case 'bottom':
-                box.y = (bodyBox.y + bodyBox.height) - box.height;
-                break;
+Ext.define("Ext.util.Sortable", {
+    
+    isSortable: true,
 
-            case 'right':
-                box.x = (bodyBox.x + bodyBox.width) - box.width;
-                break;
-        }
+    
+    defaultSortDirection: "ASC",
 
-        if (box.ignoreFrame) {
-            if (pos == 'bottom') {
-                box.y += (frameSize.bottom + padding.bottom + border.bottom);
-            }
-            else {
-                box.y -= (frameSize.top + padding.top + border.top);
-            }
-            if (pos == 'right') {
-                box.x += (frameSize.right + padding.right + border.right);
-            }
-            else {
-                box.x -= (frameSize.left + padding.left + border.left);
-            }
-        }
+    requires: [
+        'Ext.util.Sorter'
+    ],
 
-        
-        if (!box.overlay) {
-            switch (pos) {
-                case 'top':
-                    bodyBox.y += box.height;
-                    bodyBox.height -= box.height;
-                    break;
+    
 
-                case 'left':
-                    bodyBox.x += box.width;
-                    bodyBox.width -= box.width;
-                    break;
+    
+    initSortable: function() {
+        var me = this,
+            sorters = me.sorters;
 
-                case 'bottom':
-                    bodyBox.height -= box.height;
-                    break;
+        
+        me.sorters = Ext.create('Ext.util.AbstractMixedCollection', false, function(item) {
+            return item.id || item.property;
+        });
 
-                case 'right':
-                    bodyBox.width -= box.width;
-                    break;
-            }
+        if (sorters) {
+            me.sorters.addAll(me.decodeSorters(sorters));
         }
-        return box;
     },
 
     
-    adjustAutoBox : function (box, index) {
-        var info = this.info,
-            bodyBox = info.bodyBox,
-            size = info.size,
-            boxes = info.boxes,
-            boxesLn = boxes.length,
-            pos = box.type,
-            frameSize = this.frameSize,
-            padding = info.padding,
-            border = info.border,
-            autoSizedCtLayout = info.autoSizedCtLayout,
-            ln = (boxesLn < index) ? boxesLn : index,
-            i, adjustBox;
+    sort: function(sorters, direction, where, doSort) {
+        var me = this,
+            sorter, sorterFn,
+            newSorters;
 
-        if (pos == 'top' || pos == 'bottom') {
-            
-            for (i = 0; i < ln; i++) {
-                adjustBox = boxes[i];
-                if (adjustBox.stretched && adjustBox.type == 'left' || adjustBox.type == 'right') {
-                    adjustBox.height += box.height;
-                }
-                else if (adjustBox.type == 'bottom') {
-                    adjustBox.y += box.height;
-                }
-            }
+        if (Ext.isArray(sorters)) {
+            doSort = where;
+            where = direction;
+            newSorters = sorters;
+        }
+        else if (Ext.isObject(sorters)) {
+            doSort = where;
+            where = direction;
+            newSorters = [sorters];
         }
+        else if (Ext.isString(sorters)) {
+            sorter = me.sorters.get(sorters);
 
-        switch (pos) {
-            case 'top':
-                box.y = bodyBox.y;
-                if (!box.overlay) {
-                    bodyBox.y += box.height;
-                }
-                size.height += box.height;
-                break;
+            if (!sorter) {
+                sorter = {
+                    property : sorters,
+                    direction: direction
+                };
+                newSorters = [sorter];
+            }
+            else if (direction === undefined) {
+                sorter.toggle();
+            }
+            else {
+                sorter.setDirection(direction);
+            }
+        }
 
-            case 'bottom':
-                box.y = (bodyBox.y + bodyBox.height);
-                size.height += box.height;
-                break;
+        if (newSorters && newSorters.length) {
+            newSorters = me.decodeSorters(newSorters);
+            if (Ext.isString(where)) {
+                if (where === 'prepend') {
+                    sorters = me.sorters.clone().items;
 
-            case 'left':
-                box.x = bodyBox.x;
-                if (!box.overlay) {
-                    bodyBox.x += box.width;
-                    if (autoSizedCtLayout) {
-                        size.width += box.width;
-                    } else {
-                        bodyBox.width -= box.width;
-                    }
+                    me.sorters.clear();
+                    me.sorters.addAll(newSorters);
+                    me.sorters.addAll(sorters);
                 }
-                break;
-
-            case 'right':
-                if (!box.overlay) {
-                    if (autoSizedCtLayout) {
-                        size.width += box.width;
-                    } else {
-                        bodyBox.width -= box.width;
-                    }
+                else {
+                    me.sorters.addAll(newSorters);
                 }
-                box.x = (bodyBox.x + bodyBox.width);
-                break;
-        }
-
-        if (box.ignoreFrame) {
-            if (pos == 'bottom') {
-                box.y += (frameSize.bottom + padding.bottom + border.bottom);
             }
             else {
-                box.y -= (frameSize.top + padding.top + border.top);
-            }
-            if (pos == 'right') {
-                box.x += (frameSize.right + padding.right + border.right);
+                me.sorters.clear();
+                me.sorters.addAll(newSorters);
             }
-            else {
-                box.x -= (frameSize.left + padding.left + border.left);
+        }
+
+        if (doSort !== false) {
+            me.onBeforeSort(newSorters);
+            
+            sorters = me.sorters.items;
+            if (sorters.length) {
+                
+                sorterFn = function(r1, r2) {
+                    var result = sorters[0].sort(r1, r2),
+                        length = sorters.length,
+                        i;
+
+                        
+                        for (i = 1; i < length; i++) {
+                            result = result || sorters[i].sort.call(this, r1, r2);
+                        }
+
+                    return result;
+                };
+
+                me.doSort(sorterFn);
             }
         }
-        return box;
+
+        return sorters;
     },
 
+    onBeforeSort: Ext.emptyFn,
+
     
-    initBox : function(item) {
-        var me = this,
-            bodyBox = me.info.bodyBox,
-            horizontal = (item.dock == 'top' || item.dock == 'bottom'),
-            owner = me.owner,
-            frameSize = me.frameSize,
-            info = me.info,
-            padding = info.padding,
-            border = info.border,
-            box = {
-                item: item,
-                overlay: item.overlay,
-                type: item.dock,
-                offsets: Ext.core.Element.parseBox(item.offsets || {}),
-                ignoreFrame: item.ignoreParentFrame
-            };
-        
-        if (item.stretch !== false) {
-            box.stretched = true;
-            if (horizontal) {
-                box.x = bodyBox.x + box.offsets.left;
-                box.width = bodyBox.width - (box.offsets.left + box.offsets.right);
-                if (box.ignoreFrame) {
-                    box.width += (frameSize.left + frameSize.right + border.left + border.right + padding.left + padding.right);
-                }
-                item.setCalculatedSize(box.width - item.el.getMargin('lr'), undefined, owner);
+    decodeSorters: function(sorters) {
+        if (!Ext.isArray(sorters)) {
+            if (sorters === undefined) {
+                sorters = [];
+            } else {
+                sorters = [sorters];
             }
-            else {
-                box.y = bodyBox.y + box.offsets.top;
-                box.height = bodyBox.height - (box.offsets.bottom + box.offsets.top);
-                if (box.ignoreFrame) {
-                    box.height += (frameSize.top + frameSize.bottom + border.top + border.bottom + padding.top + padding.bottom);
+        }
+
+        var length = sorters.length,
+            Sorter = Ext.util.Sorter,
+            fields = this.model ? this.model.prototype.fields : null,
+            field,
+            config, i;
+
+        for (i = 0; i < length; i++) {
+            config = sorters[i];
+
+            if (!(config instanceof Sorter)) {
+                if (Ext.isString(config)) {
+                    config = {
+                        property: config
+                    };
+                }
+
+                Ext.applyIf(config, {
+                    root     : this.sortRoot,
+                    direction: "ASC"
+                });
+
+                
+                if (config.fn) {
+                    config.sorterFn = config.fn;
                 }
-                item.setCalculatedSize(undefined, box.height - item.el.getMargin('tb'), owner);
 
                 
+                if (typeof config == 'function') {
+                    config = {
+                        sorterFn: config
+                    };
+                }
+
                 
-                if (!Ext.supports.ComputedStyle) {
-                    item.el.repaint();
+                if (fields && !config.transform) {
+                    field = fields.get(config.property);
+                    config.transform = field ? field.sortType : undefined;
                 }
-            }
-        }
-        else {
-            item.doComponentLayout();
-            box.width = item.getWidth() - (box.offsets.left + box.offsets.right);
-            box.height = item.getHeight() - (box.offsets.bottom + box.offsets.top);
-            box.y += box.offsets.top;
-            if (horizontal) {
-                box.x = (item.align == 'right') ? bodyBox.width - box.width : bodyBox.x;
-                box.x += box.offsets.left;
+                sorters[i] = Ext.create('Ext.util.Sorter', config);
             }
         }
 
-        
-        
-        if (box.width == undefined) {
-            box.width = item.getWidth() + item.el.getMargin('lr');
-        }
-        if (box.height == undefined) {
-            box.height = item.getHeight() + item.el.getMargin('tb');
-        }
+        return sorters;
+    },
 
-        return box;
+    getSorters: function() {
+        return this.sorters.items;
+    }
+});
+
+Ext.define('Ext.util.MixedCollection', {
+    extend: 'Ext.util.AbstractMixedCollection',
+    mixins: {
+        sortable: 'Ext.util.Sortable'
     },
 
     
-    getLayoutItems : function() {
-        var it = this.owner.getDockedItems(),
-            ln = it.length,
-            i = 0,
-            result = [];
-        for (; i < ln; i++) {
-            if (it[i].isVisible(true)) {
-                result.push(it[i]);
-            }
-        }
-        return result;
+    constructor: function() {
+        var me = this;
+        me.callParent(arguments);
+        me.addEvents('sort');
+        me.mixins.sortable.initSortable.call(me);
+    },
+
+    doSort: function(sorterFn) {
+        this.sortBy(sorterFn);
     },
 
     
-    renderItems: function(items, target) {
-        var cns = target.dom.childNodes,
-            cnsLn = cns.length,
-            ln = items.length,
-            domLn = 0,
-            i, j, cn, item;
+    _sort : function(property, dir, fn){
+        var me = this,
+            i, len,
+            dsc   = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
+
+            
+            c     = [],
+            keys  = me.keys,
+            items = me.items;
 
         
-        for (i = 0; i < cnsLn; i++) {
-            cn = Ext.get(cns[i]);
-            for (j = 0; j < ln; j++) {
-                item = items[j];
-                if (item.rendered && (cn.id == item.el.id || cn.down('#' + item.el.id))) {
-                    break;
-                }
-            }
+        fn = fn || function(a, b) {
+            return a - b;
+        };
 
-            if (j === ln) {
-                domLn++;
-            }
+        
+        for(i = 0, len = items.length; i < len; i++){
+            c[c.length] = {
+                key  : keys[i],
+                value: items[i],
+                index: i
+            };
         }
 
         
-        for (i = 0, j = 0; i < ln; i++, j++) {
-            item = items[i];
-
-            
-            
-            
-            
-            
-            
-            
-            
-            if (i === j && (item.dock === 'right' || item.dock === 'bottom')) {
-                j += domLn;
+        Ext.Array.sort(c, function(a, b){
+            var v = fn(a[property], b[property]) * dsc;
+            if(v === 0){
+                v = (a.index < b.index ? -1 : 1);
             }
+            return v;
+        });
 
-            
-            if (item && !item.rendered) {
-                this.renderItem(item, target, j);
-            }
-            else if (!this.isValidParent(item, target, j)) {
-                this.moveItem(item, target, j);
-            }
+        
+        for(i = 0, len = c.length; i < len; i++){
+            items[i] = c[i].value;
+            keys[i]  = c[i].key;
         }
+
+        me.fireEvent('sort', me);
     },
 
     
-    setBodyBox : function(box) {
-        var me = this,
-            owner = me.owner,
-            body = owner.body,
-            info = me.info,
-            bodyMargin = info.bodyMargin,
-            padding = info.padding,
-            border = info.border,
-            frameSize = me.frameSize;
-        
-        
-        if (owner.collapsed) {
-            return;
-        }
+    sortBy: function(sorterFn) {
+        var me     = this,
+            items  = me.items,
+            keys   = me.keys,
+            length = items.length,
+            temp   = [],
+            i;
+
         
-        if (Ext.isNumber(box.width)) {
-            box.width -= bodyMargin.left + bodyMargin.right;
+        for (i = 0; i < length; i++) {
+            temp[i] = {
+                key  : keys[i],
+                value: items[i],
+                index: i
+            };
         }
+
+        Ext.Array.sort(temp, function(a, b) {
+            var v = sorterFn(a.value, b.value);
+            if (v === 0) {
+                v = (a.index < b.index ? -1 : 1);
+            }
+
+            return v;
+        });
+
         
-        if (Ext.isNumber(box.height)) {
-            box.height -= bodyMargin.top + bodyMargin.bottom;
+        for (i = 0; i < length; i++) {
+            items[i] = temp[i].value;
+            keys[i]  = temp[i].key;
         }
         
-        me.setElementSize(body, box.width, box.height);
-        if (Ext.isNumber(box.x)) {
-            body.setLeft(box.x - padding.left - frameSize.left);
-        }
-        if (Ext.isNumber(box.y)) {
-            body.setTop(box.y - padding.top - frameSize.top);
-        }
+        me.fireEvent('sort', me, items, keys);
     },
 
     
-    configureItem : function(item, pos) {
-        this.callParent(arguments);
-        
-        item.addCls(Ext.baseCSSPrefix + 'docked');
-        item.addClsWithUI('docked-' + item.dock);
-    },
+    reorder: function(mapping) {
+        var me = this,
+            items = me.items,
+            index = 0,
+            length = items.length,
+            order = [],
+            remaining = [],
+            oldIndex;
 
-    afterRemove : function(item) {
-        this.callParent(arguments);
-        if (this.itemCls) {
-            item.el.removeCls(this.itemCls + '-' + item.dock);
-        }
-        var dom = item.el.dom;
+        me.suspendEvents();
 
-        if (!item.destroying && dom) {
-            dom.parentNode.removeChild(dom);
+        
+        for (oldIndex in mapping) {
+            order[mapping[oldIndex]] = items[oldIndex];
         }
-        this.childrenChanged = true;
-    }
-});
 
-Ext.define('Ext.app.EventBus', {
-    requires: [
-        'Ext.util.Event'
-    ],
-    mixins: {
-        observable: 'Ext.util.Observable'
-    },
-    
-    constructor: function() {
-        this.mixins.observable.constructor.call(this);
-        
-        this.bus = {};
-        
-        var me = this;
-        Ext.override(Ext.Component, {
-            fireEvent: function(ev) {
-                if (Ext.util.Observable.prototype.fireEvent.apply(this, arguments) !== false) {
-                    return me.dispatch.call(me, ev, this, arguments);
-                }
-                return false;
+        for (index = 0; index < length; index++) {
+            if (mapping[index] == undefined) {
+                remaining.push(items[index]);
             }
-        });
-    },
+        }
 
-    dispatch: function(ev, target, args) {
-        var bus = this.bus,
-            selectors = bus[ev],
-            selector, controllers, id, events, event, i, ln;
-        
-        if (selectors) {
-            
-            for (selector in selectors) {
-                
-                if (target.is(selector)) {
-                    
-                    controllers = selectors[selector];
-                    for (id in controllers) {
-                        
-                        events = controllers[id];
-                        for (i = 0, ln = events.length; i < ln; i++) {
-                            event = events[i];
-                            
-                            return event.fire.apply(event, Array.prototype.slice.call(args, 1));
-                        }
-                    }
-                }
+        for (index = 0; index < length; index++) {
+            if (order[index] == undefined) {
+                order[index] = remaining.shift();
             }
         }
+
+        me.clear();
+        me.addAll(order);
+
+        me.resumeEvents();
+        me.fireEvent('sort', me);
     },
-    
-    control: function(selectors, listeners, controller) {
-        var bus = this.bus,
-            selector, fn;
-        
-        if (Ext.isString(selectors)) {
-            selector = selectors;
-            selectors = {};
-            selectors[selector] = listeners;
-            this.control(selectors, null, controller);
-            return;
-        }
-    
-        Ext.Object.each(selectors, function(selector, listeners) {
-            Ext.Object.each(listeners, function(ev, listener) {
-                var options = {},   
-                    scope = controller,
-                    event = Ext.create('Ext.util.Event', controller, ev);
-                
-                
-                if (Ext.isObject(listener)) {
-                    options = listener;
-                    listener = options.fn;
-                    scope = options.scope || controller;
-                    delete options.fn;
-                    delete options.scope;
-                }
-                
-                event.addListener(listener, scope, options);
 
-                
-                bus[ev] = bus[ev] || {};
-                bus[ev][selector] = bus[ev][selector] || {};
-                bus[ev][selector][controller.id] = bus[ev][selector][controller.id] || [];            
-                
-                
-                bus[ev][selector][controller.id].push(event);
-            });
+    
+    sortByKey : function(dir, fn){
+        this._sort('key', dir, fn || function(a, b){
+            var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
+            return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
         });
     }
 });
 
-Ext.define('Ext.data.Types', {
-    singleton: true,
-    requires: ['Ext.data.SortTypes']
-}, function() {
-    var st = Ext.data.SortTypes;
-    
-    Ext.apply(Ext.data.Types, {
-        
-        stripRe: /[\$,%]/g,
-        
-        
-        AUTO: {
-            convert: function(v) {
-                return v;
-            },
-            sortType: st.none,
-            type: 'auto'
-        },
 
-        
-        STRING: {
-            convert: function(v) {
-                var defaultValue = this.useNull ? null : '';
-                return (v === undefined || v === null) ? defaultValue : String(v);
-            },
-            sortType: st.asUCString,
-            type: 'string'
-        },
+Ext.define('Ext.data.Errors', {
+    extend: 'Ext.util.MixedCollection',
 
-        
-        INT: {
-            convert: function(v) {
-                return v !== undefined && v !== null && v !== '' ?
-                    parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
-            },
-            sortType: st.none,
-            type: 'int'
-        },
-        
-        
-        FLOAT: {
-            convert: function(v) {
-                return v !== undefined && v !== null && v !== '' ?
-                    parseFloat(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
-            },
-            sortType: st.none,
-            type: 'float'
-        },
-        
-        
-        BOOL: {
-            convert: function(v) {
-                if (this.useNull && v === undefined || v === null || v === '') {
-                    return null;
-                }
-                return v === true || v === 'true' || v == 1;
-            },
-            sortType: st.none,
-            type: 'bool'
-        },
-        
-        
-        DATE: {
-            convert: function(v) {
-                var df = this.dateFormat;
-                if (!v) {
-                    return null;
-                }
-                if (Ext.isDate(v)) {
-                    return v;
-                }
-                if (df) {
-                    if (df == 'timestamp') {
-                        return new Date(v*1000);
-                    }
-                    if (df == 'time') {
-                        return new Date(parseInt(v, 10));
-                    }
-                    return Ext.Date.parse(v, df);
-                }
-                
-                var parsed = Date.parse(v);
-                return parsed ? new Date(parsed) : null;
-            },
-            sortType: st.asDate,
-            type: 'date'
-        }
-    });
     
-    Ext.apply(Ext.data.Types, {
-        
-        BOOLEAN: this.BOOL,
-        
-        
-        INTEGER: this.INT,
-        
-        
-        NUMBER: this.FLOAT    
-    });
-});
-
+    isValid: function() {
+        return this.length === 0;
+    },
 
-Ext.define('Ext.data.Field', {
-    requires: ['Ext.data.Types', 'Ext.data.SortTypes'],
-    alias: 'data.field',
     
-    constructor : function(config) {
-        if (Ext.isString(config)) {
-            config = {name: config};
-        }
-        Ext.apply(this, config);
-        
-        var types = Ext.data.Types,
-            st = this.sortType,
-            t;
+    getByField: function(fieldName) {
+        var errors = [],
+            error, field, i;
 
-        if (this.type) {
-            if (Ext.isString(this.type)) {
-                this.type = types[this.type.toUpperCase()] || types.AUTO;
-            }
-        } else {
-            this.type = types.AUTO;
-        }
+        for (i = 0; i < this.length; i++) {
+            error = this.items[i];
 
-        
-        if (Ext.isString(st)) {
-            this.sortType = Ext.data.SortTypes[st];
-        } else if(Ext.isEmpty(st)) {
-            this.sortType = this.type.sortType;
+            if (error.field == fieldName) {
+                errors.push(error);
+            }
         }
 
-        if (!this.convert) {
-            this.convert = this.type.convert;
-        }
-    },
-    
-    
-    
-    
-    
-    
-    
-    dateFormat: null,
-    
-    
-    useNull: false,
-    
-    
-    defaultValue: "",
-    
-    mapping: null,
-    
-    sortType : null,
-    
-    sortDir : "ASC",
-    
-    allowBlank : true,
-    
-    
-    persist: true
+        return errors;
+    }
 });
 
 
@@ -24943,6 +25117,7 @@ Ext.define('Ext.data.reader.Reader', {
     
     isReader: true,
     
+    
     constructor: function(config) {
         var me = this;
         
@@ -25063,8 +25238,7 @@ Ext.define('Ext.data.reader.Reader', {
             id     = me.getId(node);
 
             
-            record = new Model(values, id);
-            record.raw = node;
+            record = new Model(values, id, node);
             records.push(record);
                 
             if (me.implicitIncludes) {
@@ -25143,7 +25317,6 @@ Ext.define('Ext.data.reader.Reader', {
 
     
     getResponseData: function(response) {
-        Ext.Error.raise("getResponseData must be implemented in the Ext.data.reader.Reader subclass");
     },
 
     
@@ -25254,14 +25427,14 @@ Ext.define('Ext.data.reader.Json', {
     extend: 'Ext.data.reader.Reader',
     alternateClassName: 'Ext.data.JsonReader',
     alias : 'reader.json',
-    
+
     root: '',
+
     
-    
-    
+
     
     useSimpleAccessors: false,
-    
+
     
     readRecords: function(data) {
         
@@ -25276,8 +25449,9 @@ Ext.define('Ext.data.reader.Json', {
 
     
     getResponseData: function(response) {
+        var data;
         try {
-            var data = Ext.decode(response.responseText);
+            data = Ext.decode(response.responseText);
         }
         catch (ex) {
             Ext.Error.raise({
@@ -25287,9 +25461,6 @@ Ext.define('Ext.data.reader.Json', {
                 msg: 'Unable to parse the JSON returned by the server: ' + ex.toString()
             });
         }
-        if (!data) {
-            Ext.Error.raise('JSON object not found');
-        }
 
         return data;
     },
@@ -25297,7 +25468,7 @@ Ext.define('Ext.data.reader.Json', {
     
     buildExtractors : function() {
         var me = this;
-        
+
         me.callParent(arguments);
 
         if (me.root) {
@@ -25308,16 +25479,21 @@ Ext.define('Ext.data.reader.Json', {
             };
         }
     },
-    
+
     
     extractData: function(root) {
         var recordName = this.record,
             data = [],
             length, i;
-        
+
         if (recordName) {
             length = root.length;
             
+            if (!length && Ext.isObject(root)) {
+                length = 1;
+                root = [root];
+            }
+
             for (i = 0; i < length; i++) {
                 data[i] = root[i][recordName];
             }
@@ -25330,7 +25506,7 @@ Ext.define('Ext.data.reader.Json', {
     
     createAccessor: function() {
         var re = /[\[\.]/;
-        
+
         return function(expr) {
             if (Ext.isEmpty(expr)) {
                 return Ext.emptyFn;
@@ -25379,7 +25555,6 @@ Ext.define('Ext.data.writer.Json', {
                 
                 request.params[root] = Ext.encode(data);
             } else {
-                Ext.Error.raise('Must specify a root when using encode');
             }
         } else {
             
@@ -25425,8 +25600,13 @@ Ext.define('Ext.data.proxy.Proxy', {
     
     
     
+    
+    
+    
+    
     isProxy: true,
     
+    
     constructor: function(config) {
         config = config || {};
         
@@ -25579,97 +25759,92 @@ Ext.define('Ext.data.proxy.Server', {
     alias : 'proxy.server',
     alternateClassName: 'Ext.data.ServerProxy',
     uses  : ['Ext.data.Request'],
+
     
-    
-    
-    
-    
-    
-    
+
     
     pageParam: 'page',
-    
+
     
     startParam: 'start',
 
     
     limitParam: 'limit',
-    
+
     
     groupParam: 'group',
-    
+
     
     sortParam: 'sort',
-    
+
     
     filterParam: 'filter',
-    
+
     
     directionParam: 'dir',
-    
+
     
     simpleSortMode: false,
-    
+
     
     noCache : true,
-    
+
     
     cacheString: "_dc",
-    
+
     
     timeout : 30000,
+
     
-    
-    
-    
+
     constructor: function(config) {
         var me = this;
-        
+
         config = config || {};
         this.addEvents(
             
             'exception'
         );
         me.callParent([config]);
-        
+
         
         me.extraParams = config.extraParams || {};
-        
+
         me.api = config.api || {};
-        
+
         
         me.nocache = me.noCache;
     },
-    
+
     
     create: function() {
         return this.doRequest.apply(this, arguments);
     },
-    
+
     read: function() {
         return this.doRequest.apply(this, arguments);
     },
-    
+
     update: function() {
         return this.doRequest.apply(this, arguments);
     },
-    
+
     destroy: function() {
         return this.doRequest.apply(this, arguments);
     },
-    
+
     
     buildRequest: function(operation) {
         var params = Ext.applyIf(operation.params || {}, this.extraParams || {}),
             request;
+
         
-        
-        params = Ext.applyIf(params, this.getParams(params, operation));
-        
+        params = Ext.applyIf(params, this.getParams(operation));
+
         if (operation.id && !params.id) {
             params.id = operation.id;
         }
-        
+
         request = Ext.create('Ext.data.Request', {
             params   : params,
             action   : operation.action,
@@ -25677,51 +25852,33 @@ Ext.define('Ext.data.proxy.Server', {
             operation: operation,
             url      : operation.url
         });
-        
+
         request.url = this.buildUrl(request);
-        
+
         
         operation.request = request;
-        
+
         return request;
     },
-    
+
     
     processResponse: function(success, operation, request, response, callback, scope){
         var me = this,
             reader,
-            result,
-            records,
-            length,
-            mc,
-            record,
-            i;
-            
+            result;
+
         if (success === true) {
             reader = me.getReader();
             result = reader.read(me.extractResponseData(response));
-            records = result.records;
-            length = records.length;
-            
+
             if (result.success !== false) {
-                mc = Ext.create('Ext.util.MixedCollection', true, function(r) {return r.getId();});
-                mc.addAll(operation.records);
-                for (i = 0; i < length; i++) {
-                    record = mc.get(records[i].getId());
-                    
-                    if (record) {
-                        record.beginEdit();
-                        record.set(record.data);
-                        record.endEdit(true);
-                    }
-                }
-                
                 
                 Ext.apply(operation, {
                     response: response,
                     resultSet: result
                 });
-                
+
+                operation.commitRecords(result.records);
                 operation.setCompleted();
                 operation.setSuccessful();
             } else {
@@ -25730,41 +25887,41 @@ Ext.define('Ext.data.proxy.Server', {
             }
         } else {
             me.setException(operation, response);
-            me.fireEvent('exception', this, response, operation);              
+            me.fireEvent('exception', this, response, operation);
         }
-            
+
         
         if (typeof callback == 'function') {
             callback.call(scope || me, operation);
         }
-            
+
         me.afterRequest(request, success);
     },
-    
+
     
     setException: function(operation, response){
         operation.setException({
             status: response.status,
             statusText: response.statusText
-        });     
+        });
     },
-    
+
     
     extractResponseData: function(response){
-        return response; 
+        return response;
     },
-    
+
     
     applyEncoding: function(value){
         return Ext.encode(value);
     },
-    
+
     
     encodeSorters: function(sorters) {
         var min = [],
             length = sorters.length,
             i = 0;
-        
+
         for (; i < length; i++) {
             min[i] = {
                 property : sorters[i].property,
@@ -25772,15 +25929,15 @@ Ext.define('Ext.data.proxy.Server', {
             };
         }
         return this.applyEncoding(min);
-        
+
     },
-    
+
     
     encodeFilters: function(filters) {
         var min = [],
             length = filters.length,
             i = 0;
-        
+
         for (; i < length; i++) {
             min[i] = {
                 property: filters[i].property,
@@ -25789,12 +25946,11 @@ Ext.define('Ext.data.proxy.Server', {
         }
         return this.applyEncoding(min);
     },
+
     
-    
-    getParams: function(params, operation) {
-        params = params || {};
-        
+    getParams: function(operation) {
         var me             = this,
+            params         = {},
             isDef          = Ext.isDefined,
             groupers       = operation.groupers,
             sorters        = operation.sorters,
@@ -25802,34 +25958,34 @@ Ext.define('Ext.data.proxy.Server', {
             page           = operation.page,
             start          = operation.start,
             limit          = operation.limit,
-            
+
             simpleSortMode = me.simpleSortMode,
-            
+
             pageParam      = me.pageParam,
             startParam     = me.startParam,
             limitParam     = me.limitParam,
             groupParam     = me.groupParam,
             sortParam      = me.sortParam,
             filterParam    = me.filterParam,
-            directionParam       = me.directionParam;
-        
+            directionParam = me.directionParam;
+
         if (pageParam && isDef(page)) {
             params[pageParam] = page;
         }
-        
+
         if (startParam && isDef(start)) {
             params[startParam] = start;
         }
-        
+
         if (limitParam && isDef(limit)) {
             params[limitParam] = limit;
         }
-        
+
         if (groupParam && groupers && groupers.length > 0) {
             
             params[groupParam] = me.encodeSorters(groupers);
         }
-        
+
         if (sortParam && sorters && sorters.length > 0) {
             if (simpleSortMode) {
                 params[sortParam] = sorters[0].property;
@@ -25837,45 +25993,41 @@ Ext.define('Ext.data.proxy.Server', {
             } else {
                 params[sortParam] = me.encodeSorters(sorters);
             }
-            
+
         }
-        
+
         if (filterParam && filters && filters.length > 0) {
             params[filterParam] = me.encodeFilters(filters);
         }
-        
+
         return params;
     },
-    
+
     
     buildUrl: function(request) {
         var me = this,
             url = me.getUrl(request);
-        
-        if (!url) {
-            Ext.Error.raise("You are using a ServerProxy but have not supplied it with a url.");
-        }
-        
+
+
         if (me.noCache) {
             url = Ext.urlAppend(url, Ext.String.format("{0}={1}", me.cacheString, Ext.Date.now()));
         }
-        
+
         return url;
     },
-    
+
     
     getUrl: function(request){
         return request.url || this.api[request.action] || this.url;
     },
-    
+
     
     doRequest: function(operation, callback, scope) {
-        Ext.Error.raise("The doRequest function has not been implemented on your Ext.data.proxy.Server subclass. See src/data/ServerProxy.js for details");
     },
-    
+
     
     afterRequest: Ext.emptyFn,
-    
+
     onDestroy: function() {
         Ext.destroy(this.reader, this.writer);
     }
@@ -25942,13 +26094,14 @@ Ext.define('Ext.data.proxy.Ajax', {
 
 Ext.define('Ext.data.Model', {
     alternateClassName: 'Ext.data.Record',
-    
+
     mixins: {
         observable: 'Ext.util.Observable'
     },
 
     requires: [
         'Ext.ModelManager',
+        'Ext.data.IdGenerator',
         'Ext.data.Field',
         'Ext.data.Errors',
         'Ext.data.Operation',
@@ -25971,6 +26124,7 @@ Ext.define('Ext.data.Model', {
                 associations = data.associations || [],
                 belongsTo = data.belongsTo,
                 hasMany = data.hasMany,
+                idgen = data.idgen,
 
                 fieldsMixedCollection = new Ext.util.MixedCollection(false, function(field) {
                     return field.name;
@@ -26009,6 +26163,10 @@ Ext.define('Ext.data.Model', {
 
             data.fields = fieldsMixedCollection;
 
+            if (idgen) {
+                data.idgen = Ext.data.IdGenerator.get(idgen);
+            }
+
             
             
             if (belongsTo) {
@@ -26088,7 +26246,7 @@ Ext.define('Ext.data.Model', {
                 
                 Ext.ModelManager.onModelDefined(cls);
             });
-        }
+        };
     },
 
     inheritableStatics: {
@@ -26156,7 +26314,20 @@ Ext.define('Ext.data.Model', {
             return id;
         }
     },
+
     
+    idgen: {
+        isGenerator: true,
+        type: 'default',
+
+        generate: function () {
+            return null;
+        },
+        getRecId: function (rec) {
+            return rec.modelName + '-' + rec.internalId;
+        }
+    },
+
     
     editing : false,
 
@@ -26164,7 +26335,7 @@ Ext.define('Ext.data.Model', {
     dirty : false,
 
     
-    persistanceProperty: 'data',
+    persistenceProperty: 'data',
 
     evented: false,
     isModel: true,
@@ -26179,30 +26350,51 @@ Ext.define('Ext.data.Model', {
     defaultProxyType: 'ajax',
 
     
+    
+    
+
+    
+
+    
+    
+    
+    
+    
 
-    constructor: function(data, id) {
+    
+
+    
+    constructor: function(data, id, raw) {
         data = data || {};
-        
+
         var me = this,
             fields,
             length,
             field,
             name,
             i,
+            newId,
             isArray = Ext.isArray(data),
             newData = isArray ? {} : null; 
 
         
         me.internalId = (id || id === 0) ? id : Ext.data.Model.id(me);
 
+        
+        me.raw = raw;
+
         Ext.applyIf(me, {
-            data: {}    
+            data: {}
         });
-        
+
         
         me.modified = {};
 
-        me[me.persistanceProperty] = {};
+        
+        if (me.persistanceProperty) {
+            me.persistenceProperty = me.persistanceProperty;
+        }
+        me[me.persistenceProperty] = {};
 
         me.mixins.observable.constructor.call(me);
 
@@ -26214,7 +26406,7 @@ Ext.define('Ext.data.Model', {
             field = fields[i];
             name  = field.name;
 
-            if (isArray){ 
+            if (isArray){
                 
                 
                 newData[name] = data[i];
@@ -26225,41 +26417,47 @@ Ext.define('Ext.data.Model', {
         }
 
         me.set(newData || data);
-        
-        me.dirty = false;
-        me.modified = {};
 
         if (me.getId()) {
             me.phantom = false;
+        } else if (me.phantom) {
+            newId = me.idgen.generate();
+            if (newId !== null) {
+                me.setId(newId);
+            }
         }
 
+        
+        me.dirty = false;
+        me.modified = {};
+
         if (typeof me.init == 'function') {
             me.init();
         }
 
-        me.id = me.modelName + '-' + me.internalId;
-
-        Ext.ModelManager.register(me);
+        me.id = me.idgen.getRecId(me);
     },
-    
+
     
     get: function(field) {
-        return this[this.persistanceProperty][field];
+        return this[this.persistenceProperty][field];
     },
-    
+
     
     set: function(fieldName, value) {
         var me = this,
             fields = me.fields,
             modified = me.modified,
             convertFields = [],
-            field, key, i, currentValue;
+            field, key, i, currentValue, notEditing, count, length;
 
         
         if (arguments.length == 1 && Ext.isObject(fieldName)) {
+            notEditing = !me.editing;
+            count = 0;
             for (key in fieldName) {
                 if (fieldName.hasOwnProperty(key)) {
-                
+
                     
                     
                     field = fields.get(key);
@@ -26267,16 +26465,30 @@ Ext.define('Ext.data.Model', {
                         convertFields.push(key);
                         continue;
                     }
-                    
+
+                    if (!count && notEditing) {
+                        me.beginEdit();
+                    }
+                    ++count;
                     me.set(key, fieldName[key]);
                 }
             }
 
-            for (i = 0; i < convertFields.length; i++) {
-                field = convertFields[i];
-                me.set(field, fieldName[field]);
+            length = convertFields.length;
+            if (length) {
+                if (!count && notEditing) {
+                    me.beginEdit();
+                }
+                count += length;
+                for (i = 0; i < length; i++) {
+                    field = convertFields[i];
+                    me.set(field, fieldName[field]);
+                }
             }
 
+            if (notEditing && count) {
+                me.endEdit();
+            }
         } else {
             if (fields) {
                 field = fields.get(fieldName);
@@ -26286,11 +26498,28 @@ Ext.define('Ext.data.Model', {
                 }
             }
             currentValue = me.get(fieldName);
-            me[me.persistanceProperty][fieldName] = value;
-            
+            me[me.persistenceProperty][fieldName] = value;
+
             if (field && field.persist && !me.isEqual(currentValue, value)) {
-                me.dirty = true;
-                me.modified[fieldName] = currentValue;
+                if (me.isModified(fieldName)) {
+                    if (me.isEqual(modified[fieldName], value)) {
+                        
+                        
+                        delete modified[fieldName];
+                        
+                        
+                        me.dirty = false;
+                        for (key in modified) {
+                            if (modified.hasOwnProperty(key)){
+                                me.dirty = true;
+                                break;
+                            }
+                        }
+                    }
+                } else {
+                    me.dirty = true;
+                    modified[fieldName] = currentValue;
+                }
             }
 
             if (!me.editing) {
@@ -26298,7 +26527,7 @@ Ext.define('Ext.data.Model', {
             }
         }
     },
-    
+
     
     isEqual: function(a, b){
         if (Ext.isDate(a) && Ext.isDate(b)) {
@@ -26306,18 +26535,18 @@ Ext.define('Ext.data.Model', {
         }
         return a === b;
     },
-    
+
     
     beginEdit : function(){
         var me = this;
         if (!me.editing) {
             me.editing = true;
             me.dirtySave = me.dirty;
-            me.dataSave = Ext.apply({}, me[me.persistanceProperty]);
+            me.dataSave = Ext.apply({}, me[me.persistenceProperty]);
             me.modifiedSave = Ext.apply({}, me.modified);
         }
     },
-    
+
     
     cancelEdit : function(){
         var me = this;
@@ -26325,29 +26554,49 @@ Ext.define('Ext.data.Model', {
             me.editing = false;
             
             me.modified = me.modifiedSave;
-            me[me.persistanceProperty] = me.dataSave;
+            me[me.persistenceProperty] = me.dataSave;
             me.dirty = me.dirtySave;
             delete me.modifiedSave;
             delete me.dataSave;
             delete me.dirtySave;
         }
     },
-    
+
     
     endEdit : function(silent){
-        var me = this;
+        var me = this,
+            didChange;
+            
         if (me.editing) {
             me.editing = false;
+            didChange = me.dirty || me.changedWhileEditing();
             delete me.modifiedSave;
             delete me.dataSave;
             delete me.dirtySave;
-            if (silent !== true && me.dirty) {
+            if (silent !== true && didChange) {
                 me.afterEdit();
             }
         }
     },
     
     
+    changedWhileEditing: function(){
+        var me = this,
+            saved = me.dataSave,
+            data = me[me.persistenceProperty],
+            key;
+            
+        for (key in data) {
+            if (data.hasOwnProperty(key)) {
+                if (!me.isEqual(data[key], saved[key])) {
+                    return true;
+                }
+            }
+        }
+        return false; 
+    },
+
+    
     getChanges : function(){
         var modified = this.modified,
             changes  = {},
@@ -26361,17 +26610,17 @@ Ext.define('Ext.data.Model', {
 
         return changes;
     },
-    
+
     
     isModified : function(fieldName) {
         return this.modified.hasOwnProperty(fieldName);
     },
-    
+
     
     setDirty : function() {
         var me = this,
             name;
-        
+
         me.dirty = true;
 
         me.fields.each(function(field) {
@@ -26382,13 +26631,7 @@ Ext.define('Ext.data.Model', {
         }, me);
     },
 
-    markDirty : function() {
-        if (Ext.isDefined(Ext.global.console)) {
-            Ext.global.console.warn('Ext.data.Model: markDirty has been deprecated. Use setDirty instead.');
-        }
-        return this.setDirty.apply(this, arguments);
-    },
-    
+
     
     reject : function(silent) {
         var me = this,
@@ -26398,7 +26641,7 @@ Ext.define('Ext.data.Model', {
         for (field in modified) {
             if (modified.hasOwnProperty(field)) {
                 if (typeof modified[field] != "function") {
-                    me[me.persistanceProperty][field] = modified[field];
+                    me[me.persistenceProperty][field] = modified[field];
                 }
             }
         }
@@ -26415,10 +26658,8 @@ Ext.define('Ext.data.Model', {
     
     commit : function(silent) {
         var me = this;
-        
-        me.dirty = false;
-        me.editing = false;
 
+        me.phantom = me.dirty = me.editing = false;
         me.modified = {};
 
         if (silent !== true) {
@@ -26429,8 +26670,8 @@ Ext.define('Ext.data.Model', {
     
     copy : function(newId) {
         var me = this;
-        
-        return new me.self(Ext.apply({}, me[me.persistanceProperty]), newId || me.internalId);
+
+        return new me.self(Ext.apply({}, me[me.persistenceProperty]), newId || me.internalId);
     },
 
     
@@ -26573,7 +26814,7 @@ Ext.define('Ext.data.Model', {
     },
 
     
-    unjoin: function() {
+    unjoin: function(store) {
         delete this.store;
     },
 
@@ -26669,6 +26910,96 @@ Ext.define('Ext.data.Model', {
 });
 
 
+Ext.define('Ext.data.StoreManager', {
+    extend: 'Ext.util.MixedCollection',
+    alternateClassName: ['Ext.StoreMgr', 'Ext.data.StoreMgr', 'Ext.StoreManager'],
+    singleton: true,
+    uses: ['Ext.data.ArrayStore'],
+    
+    
+
+    
+    register : function() {
+        for (var i = 0, s; (s = arguments[i]); i++) {
+            this.add(s);
+        }
+    },
+
+    
+    unregister : function() {
+        for (var i = 0, s; (s = arguments[i]); i++) {
+            this.remove(this.lookup(s));
+        }
+    },
+
+    
+    lookup : function(store) {
+        
+        if (Ext.isArray(store)) {
+            var fields = ['field1'], 
+                expand = !Ext.isArray(store[0]),
+                data = store,
+                i,
+                len;
+                
+            if(expand){
+                data = [];
+                for (i = 0, len = store.length; i < len; ++i) {
+                    data.push([store[i]]);
+                }
+            } else {
+                for(i = 2, len = store[0].length; i <= len; ++i){
+                    fields.push('field' + i);
+                }
+            }
+            return Ext.create('Ext.data.ArrayStore', {
+                data  : data,
+                fields: fields,
+                autoDestroy: true,
+                autoCreated: true,
+                expanded: expand
+            });
+        }
+        
+        if (Ext.isString(store)) {
+            
+            return this.get(store);
+        } else {
+            
+            return Ext.data.AbstractStore.create(store);
+        }
+    },
+
+    
+    getKey : function(o) {
+         return o.storeId;
+    }
+}, function() {    
+    
+    Ext.regStore = function(name, config) {
+        var store;
+
+        if (Ext.isObject(name)) {
+            config = name;
+        } else {
+            config.storeId = name;
+        }
+
+        if (config instanceof Ext.data.Store) {
+            store = config;
+        } else {
+            store = Ext.create('Ext.data.Store', config);
+        }
+
+        return Ext.data.StoreManager.register(store);
+    };
+
+    
+    Ext.getStore = function(name) {
+        return Ext.data.StoreManager.lookup(name);
+    };
+});
+
 
 Ext.define('Ext.Component', {
 
@@ -26697,7 +27028,13 @@ Ext.define('Ext.Component', {
         DIRECTION_TOP: 'top',
         DIRECTION_RIGHT: 'right',
         DIRECTION_BOTTOM: 'bottom',
-        DIRECTION_LEFT: 'left'
+        DIRECTION_LEFT: 'left',
+
+        VERTICAL_DIRECTION_Re: /^(?:top|bottom)$/,
+
+        
+        
+        INVALID_ID_CHARS_Re: /[\.,\s]/g
     },
 
     
@@ -26717,7 +27054,7 @@ Ext.define('Ext.Component', {
 
     
 
-     
+    
 
     
 
@@ -26740,13 +27077,17 @@ Ext.define('Ext.Component', {
     
     
     
+
+    
     constructor: function(config) {
+        var me = this;
+
         config = config || {};
         if (config.initialConfig) {
 
             
             if (config.isAction) {
-                this.baseAction = config;
+                me.baseAction = config;
             }
             config = config.initialConfig;
             
@@ -26759,18 +27100,21 @@ Ext.define('Ext.Component', {
             };
         }
 
-        this.callParent([config]);
+        me.callParent([config]);
 
         
         
-        if (this.baseAction){
-            this.baseAction.addComponent(this);
+        if (me.baseAction){
+            me.baseAction.addComponent(me);
         }
     },
 
+    
     initComponent: function() {
         var me = this;
 
+        me.callParent();
+
         if (me.listeners) {
             me.on(me.listeners);
             delete me.listeners;
@@ -26787,10 +27131,12 @@ Ext.define('Ext.Component', {
         if (me.floating) {
             me.makeFloating(me.floating);
         } else {
-            me.el.setVisibilityMode(Ext.core.Element[me.hideMode.toUpperCase()]);
+            me.el.setVisibilityMode(Ext.Element[me.hideMode.toUpperCase()]);
         }
 
-        me.setAutoScroll(me.autoScroll);
+        if (Ext.isDefined(me.autoScroll)) {
+            me.setAutoScroll(me.autoScroll);
+        }
         me.callParent();
 
         if (!(me.x && me.y) && (me.pageX || me.pageY)) {
@@ -26840,14 +27186,16 @@ Ext.define('Ext.Component', {
     },
 
     initResizable: function(resizable) {
+        var me = this;
+
         resizable = Ext.apply({
-            target: this,
+            target: me,
             dynamic: false,
-            constrainTo: this.constrainTo,
-            handles: this.resizeHandles
+            constrainTo: me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.el.getScopeParent()),
+            handles: me.resizeHandles
         }, resizable);
-        resizable.target = this;
-        this.resizer = Ext.create('Ext.resizer.Resizer', resizable);
+        resizable.target = me;
+        me.resizer = Ext.create('Ext.resizer.Resizer', resizable);
     },
 
     getDragEl: function() {
@@ -26857,9 +27205,9 @@ Ext.define('Ext.Component', {
     initDraggable: function() {
         var me = this,
             ddConfig = Ext.applyIf({
-                el: this.getDragEl(),
-                constrainTo: me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.el.dom.parentNode)
-            }, this.draggable);
+                el: me.getDragEl(),
+                constrainTo: me.constrain ? (me.constrainTo || (me.floatParent ? me.floatParent.getTargetEl() : me.el.getScopeParent())) : undefined
+            }, me.draggable);
 
         
         if (me.constrain || me.constrainDelegate) {
@@ -26867,7 +27215,7 @@ Ext.define('Ext.Component', {
             ddConfig.constrainDelegate = me.constrainDelegate;
         }
 
-        this.dd = Ext.create('Ext.util.ComponentDragger', this, ddConfig);
+        me.dd = Ext.create('Ext.util.ComponentDragger', me, ddConfig);
     },
 
     
@@ -26935,14 +27283,16 @@ Ext.define('Ext.Component', {
         this.fireEvent('move', this, ax, ay);
     },
 
+    
     showAt: function(x, y, animate) {
-        
-        if (this.floating) {
-            this.setPosition(x, y, animate);
+        var me = this;
+
+        if (me.floating) {
+            me.setPosition(x, y, animate);
         } else {
-            this.setPagePosition(x, y, animate);
+            me.setPagePosition(x, y, animate);
         }
-        this.show();
+        me.show();
     },
 
     
@@ -26976,11 +27326,12 @@ Ext.define('Ext.Component', {
 
     
     getBox : function(local){
-        var pos = this.getPosition(local);
-        var s = this.getSize();
-        s.x = pos[0];
-        s.y = pos[1];
-        return s;
+        var pos = this.getPosition(local),
+            size = this.getSize();
+
+        size.x = pos[0];
+        size.y = pos[1];
+        return size;
     },
 
     
@@ -27000,22 +27351,6 @@ Ext.define('Ext.Component', {
     },
 
     
-    adjustSize: function(w, h) {
-        if (this.autoWidth) {
-            w = 'auto';
-        }
-
-        if (this.autoHeight) {
-            h = 'auto';
-        }
-
-        return {
-            width: w,
-            height: h
-        };
-    },
-
-    
     adjustPosition: function(x, y) {
 
         
@@ -27033,26 +27368,36 @@ Ext.define('Ext.Component', {
 
     
     getPosition: function(local) {
-        var el = this.el,
-            xy;
+        var me = this,
+            el = me.el,
+            xy,
+            o;
 
-        if (local === true) {
+        
+        if ((local === true) || (me.floating && !me.floatParent)) {
             return [el.getLeft(true), el.getTop(true)];
         }
-        xy = this.xy || el.getXY();
+        xy = me.xy || el.getXY();
 
         
-        if (this.floating && this.floatParent) {
-            var o = this.floatParent.getTargetEl().getViewRegion();
+        if (me.floating) {
+            o = me.floatParent.getTargetEl().getViewRegion();
             xy[0] -= o.left;
             xy[1] -= o.top;
         }
         return xy;
     },
 
-    
     getId: function() {
-        return this.id || (this.id = (this.getXType() || 'ext-comp') + '-' + this.getAutoId());
+        var me = this,
+            xtype;
+
+        if (!me.id) {
+            xtype = me.getXType();
+            xtype = xtype ? xtype.replace(Ext.Component.INVALID_ID_CHARS_Re, '-') : 'ext-comp';
+            me.id = xtype + '-' + me.getAutoId();
+        }
+        return me.id;
     },
 
     onEnable: function() {
@@ -27071,30 +27416,32 @@ Ext.define('Ext.Component', {
 
     
     show: function(animateTarget, cb, scope) {
-        if (this.rendered && this.isVisible()) {
-            if (this.toFrontOnShow && this.floating) {
-                this.toFront();
+        var me = this;
+
+        if (me.rendered && me.isVisible()) {
+            if (me.toFrontOnShow && me.floating) {
+                me.toFront();
             }
-        } else if (this.fireEvent('beforeshow', this) !== false) {
-            this.hidden = false;
+        } else if (me.fireEvent('beforeshow', me) !== false) {
+            me.hidden = false;
 
             
-            if (!this.rendered && (this.autoRender || this.floating)) {
-                this.doAutoRender();
+            if (!me.rendered && (me.autoRender || me.floating)) {
+                me.doAutoRender();
             }
-            if (this.rendered) {
-                this.beforeShow();
-                this.onShow.apply(this, arguments);
+            if (me.rendered) {
+                me.beforeShow();
+                me.onShow.apply(me, arguments);
 
                 
                 
-                if (this.ownerCt && !this.floating && !(this.ownerCt.suspendLayout || this.ownerCt.layout.layoutBusy)) {
-                    this.ownerCt.doLayout();
+                if (me.ownerCt && !me.floating && !(me.ownerCt.suspendLayout || me.ownerCt.layout.layoutBusy)) {
+                    me.ownerCt.doLayout();
                 }
-                this.afterShow.apply(this, arguments);
+                me.afterShow.apply(me, arguments);
             }
         }
-        return this;
+        return me;
     },
 
     beforeShow: Ext.emptyFn,
@@ -27104,10 +27451,10 @@ Ext.define('Ext.Component', {
         var me = this;
 
         me.el.show();
-        if (this.floating && this.constrain) {
-            this.doConstrain();
-        }
         me.callParent(arguments);
+        if (me.floating && me.constrain) {
+            me.doConstrain();
+        }
     },
 
     afterShow: function(animateTarget, cb, scope) {
@@ -27128,14 +27475,13 @@ Ext.define('Ext.Component', {
             animateTarget = animateTarget.el ? animateTarget.el : Ext.get(animateTarget);
             toBox = me.el.getBox();
             fromBox = animateTarget.getBox();
-            fromBox.width += 'px';
-            fromBox.height += 'px';
-            toBox.width += 'px';
-            toBox.height += 'px';
             me.el.addCls(Ext.baseCSSPrefix + 'hide-offsets');
             ghostPanel = me.ghost();
             ghostPanel.el.stopAnimation();
 
+            
+            ghostPanel.el.setX(-10000);
+
             ghostPanel.el.animate({
                 from: fromBox,
                 to: toBox,
@@ -27144,43 +27490,46 @@ Ext.define('Ext.Component', {
                         delete ghostPanel.componentLayout.lastComponentSize;
                         me.unghost();
                         me.el.removeCls(Ext.baseCSSPrefix + 'hide-offsets');
-                        if (me.floating) {
-                            me.toFront();
-                        }
-                        Ext.callback(cb, scope || me);
+                        me.onShowComplete(cb, scope);
                     }
                 }
             });
         }
         else {
-            if (me.floating) {
-                me.toFront();
-            }
-            Ext.callback(cb, scope || me);
+            me.onShowComplete(cb, scope);
+        }
+    },
+
+    onShowComplete: function(cb, scope) {
+        var me = this;
+        if (me.floating) {
+            me.toFront();
         }
+        Ext.callback(cb, scope || me);
         me.fireEvent('show', me);
     },
 
     
     hide: function() {
+        var me = this;
 
         
         
-        this.showOnParentShow = false;
+        me.showOnParentShow = false;
 
-        if (!(this.rendered && !this.isVisible()) && this.fireEvent('beforehide', this) !== false) {
-            this.hidden = true;
-            if (this.rendered) {
-                this.onHide.apply(this, arguments);
+        if (!(me.rendered && !me.isVisible()) && me.fireEvent('beforehide', me) !== false) {
+            me.hidden = true;
+            if (me.rendered) {
+                me.onHide.apply(me, arguments);
 
                 
                 
-                if (this.ownerCt && !this.floating && !(this.ownerCt.suspendLayout || this.ownerCt.layout.layoutBusy)) {
-                    this.ownerCt.doLayout();
+                if (me.ownerCt && !me.floating && !(me.ownerCt.suspendLayout || me.ownerCt.layout.layoutBusy)) {
+                    me.ownerCt.doLayout();
                 }
             }
         }
-        return this;
+        return me;
     },
 
     
@@ -27234,6 +27583,7 @@ Ext.define('Ext.Component', {
         if (me.rendered) {
             Ext.destroy(
                 me.proxy,
+                me.proxyWrap,
                 me.resizer
             );
             
@@ -27241,6 +27591,7 @@ Ext.define('Ext.Component', {
                 me.container.remove();
             }
         }
+        delete me.focusTask;
         me.callParent();
     },
 
@@ -27259,7 +27610,10 @@ Ext.define('Ext.Component', {
                 focusEl;
 
         if (delay) {
-            me.focusTask.delay(Ext.isNumber(delay) ? delay: 10, null, me, [selectText, false]);
+            if (!me.focusTask) {
+                me.focusTask = Ext.create('Ext.util.DelayedTask', me.focus);
+            }
+            me.focusTask.delay(Ext.isNumber(delay) ? delay : 10, null, me, [selectText, false]);
             return me;
         }
 
@@ -27333,11 +27687,13 @@ Ext.define('Ext.Component', {
     
     cloneConfig: function(overrides) {
         overrides = overrides || {};
-        var id = overrides.id || Ext.id();
-        var cfg = Ext.applyIf(overrides, this.initialConfig);
+        var id = overrides.id || Ext.id(),
+            cfg = Ext.applyIf(overrides, this.initialConfig),
+            self;
+
         cfg.id = id;
 
-        var self = Ext.getClass(this);
+        self = Ext.getClass(this);
 
         
         return new self(cfg);
@@ -27380,17 +27736,72 @@ Ext.define('Ext.Component', {
     },
 
     getProxy: function() {
-        if (!this.proxy) {
-            this.proxy = this.el.createProxy(Ext.baseCSSPrefix + 'proxy-el', Ext.getBody(), true);
+        var me = this,
+            target;
+
+        if (!me.proxy) {
+            target = Ext.getBody();
+            if (Ext.scopeResetCSS) {
+                me.proxyWrap = target = Ext.getBody().createChild({
+                    cls: Ext.baseCSSPrefix + 'reset'
+                });
+            }
+            me.proxy = me.el.createProxy(Ext.baseCSSPrefix + 'proxy-el', target, true);
         }
-        return this.proxy;
+        return me.proxy;
     }
 
-}, function() {
+});
+
+
+Ext.define('Ext.layout.container.AbstractContainer', {
+
+    
+
+    extend: 'Ext.layout.Layout',
 
     
-    this.prototype.focusTask = Ext.create('Ext.util.DelayedTask', this.prototype.focus);
 
+    type: 'container',
+
+    
+    bindToOwnerCtComponent: false,
+
+    
+    bindToOwnerCtContainer: false,
+
+    
+
+    
+    setItemSize: function(item, width, height) {
+        if (Ext.isObject(width)) {
+            height = width.height;
+            width = width.width;
+        }
+        item.setCalculatedSize(width, height, this.owner);
+    },
+
+    
+    getLayoutItems: function() {
+        return this.owner && this.owner.items && this.owner.items.items || [];
+    },
+
+    
+    beforeLayout: function() {
+        return !this.owner.collapsed && this.callParent(arguments);
+    },
+
+    afterLayout: function() {
+        this.owner.afterLayout(this);
+    },
+    
+     getTarget: function() {
+         return this.owner.getTargetEl();
+     },
+    
+     getRenderTarget: function() {
+         return this.owner.getTargetEl();
+     }
 });
 
 
@@ -27400,14 +27811,14 @@ Ext.define('Ext.layout.container.Container', {
 
     extend: 'Ext.layout.container.AbstractContainer',
     alternateClassName: 'Ext.layout.ContainerLayout',
-    
+
     
 
     layoutItem: function(item, box) {
-        box = box || {};
-        if (item.componentLayout.initialized !== true) {
-            this.setItemSize(item, box.width || item.width || undefined, box.height || item.height || undefined);
-            
+        if (box) {
+            item.doComponentLayout(box.width, box.height);
+        } else {
+            item.doComponentLayout();
         }
     },
 
@@ -27440,11 +27851,6 @@ Ext.define('Ext.layout.container.Container', {
         }
     },
 
-    afterLayout: function() {
-        this.owner.afterLayout(arguments);
-        this.callParent(arguments);
-    },
-
     
     getRenderedItems: function() {
         var me = this,
@@ -27483,7 +27889,6 @@ Ext.define('Ext.layout.container.Container', {
     }
 });
 
-
 Ext.define('Ext.layout.container.Auto', {
 
     
@@ -27496,8 +27901,6 @@ Ext.define('Ext.layout.container.Auto', {
 
     type: 'autocontainer',
 
-    fixedLayout: false,
-
     bindToOwnerCtComponent: true,
 
     
@@ -27524,6 +27927,14 @@ Ext.define('Ext.layout.container.Auto', {
                 me.setItemSize(items[i]);
             }
         }
+    },
+
+    configureItem: function(item) {
+        this.callParent(arguments);
+
+        
+        item.layoutManagedHeight = 2;
+        item.layoutManagedWidth = 2;
     }
 });
 
@@ -27557,11 +27968,14 @@ Ext.define('Ext.container.AbstractContainer', {
 
     isContainer : true,
 
+    
+    layoutCounter : 0,
+
     baseCls: Ext.baseCSSPrefix + 'container',
 
     
     bubbleEvents: ['add', 'remove'],
-    
+
     
     initComponent : function(){
         var me = this;
@@ -27575,11 +27989,7 @@ Ext.define('Ext.container.AbstractContainer', {
             
             'add',
             
-            'remove',
-            
-            'beforecardswitch',
-            
-            'cardswitch'
+            'remove'
         );
 
         
@@ -27611,6 +28021,20 @@ Ext.define('Ext.container.AbstractContainer', {
         this.callParent();
     },
 
+    renderChildren: function () {
+        var me = this,
+            layout = me.getLayout();
+
+        me.callParent();
+        
+
+        if (layout) {
+            me.suspendLayout = true;
+            layout.renderChildren();
+            delete me.suspendLayout;
+        }
+    },
+
     
     setLayout : function(layout) {
         var currentLayout = this.layout;
@@ -27640,7 +28064,7 @@ Ext.define('Ext.container.AbstractContainer', {
 
         if (me.rendered && layout && !me.suspendLayout) {
             
-            if ((!Ext.isNumber(me.width) || !Ext.isNumber(me.height)) && me.componentLayout.type !== 'autocomponent') {
+            if (!me.isFixedWidth() || !me.isFixedHeight()) {
                 
                 if (me.componentLayout.layoutBusy !== true) {
                     me.doComponentLayout();
@@ -27663,6 +28087,7 @@ Ext.define('Ext.container.AbstractContainer', {
 
     
     afterLayout : function(layout) {
+        ++this.layoutCounter;
         this.fireEvent('afterlayout', this, layout);
     },
 
@@ -27698,12 +28123,8 @@ Ext.define('Ext.container.AbstractContainer', {
 
             if (Ext.isString(config)) {
                 config = Ext.ComponentManager.get(config);
-                Ext.applyIf(config, defaults);
-            } else if (!config.isComponent) {
-                Ext.applyIf(config, defaults);
-            } else {
-                Ext.applyIf(config, defaults);
             }
+            Ext.applyIf(config, defaults);
         }
 
         return config;
@@ -27756,11 +28177,8 @@ Ext.define('Ext.container.AbstractContainer', {
             me.suspendLayout = true;
             for (i = 0, ln = items.length; i < ln; i++) {
                 item = items[i];
-                
-                if (!item) {
-                    Ext.Error.raise("Trying to add a null item as a child of Container with itemId/id: " + me.getItemId());
-                }
-                
+
+
                 if (index != -1) {
                     item = me.add(index + i, item);
                 } else {
@@ -27794,15 +28212,6 @@ Ext.define('Ext.container.AbstractContainer', {
         return cmp;
     },
 
-    
-    registerFloatingItem: function(cmp) {
-        var me = this;
-        if (!me.floatingItems) {
-            me.floatingItems = Ext.create('Ext.ZIndexManager', me);
-        }
-        me.floatingItems.register(cmp);
-    },
-
     onAdd : Ext.emptyFn,
     onRemove : Ext.emptyFn,
 
@@ -27827,7 +28236,7 @@ Ext.define('Ext.container.AbstractContainer', {
     
     onBeforeAdd : function(item) {
         var me = this;
-        
+
         if (item.ownerCt) {
             item.ownerCt.remove(item, false);
         }
@@ -27841,9 +28250,6 @@ Ext.define('Ext.container.AbstractContainer', {
     remove : function(comp, autoDestroy) {
         var me = this,
             c = me.getComponent(comp);
-            if (Ext.isDefined(Ext.global.console) && !c) {
-                console.warn("Attempted to remove a component that does not exist. Ext.container.Container: remove takes an argument of the component to remove. cmp.remove() is incorrect usage.");
-            }
 
         if (c && me.fireEvent('beforeremove', me, c) !== false) {
             me.doRemove(c, autoDestroy);
@@ -27903,7 +28309,9 @@ Ext.define('Ext.container.AbstractContainer', {
 
         
         me.suspendLayout = false;
-        me.doLayout();
+        if (len) {
+            me.doLayout();
+        }
         return items;
     },
 
@@ -27975,11 +28383,13 @@ Ext.define('Ext.container.AbstractContainer', {
 
     
     query : function(selector) {
+        selector = selector || '*';
         return Ext.ComponentQuery.query(selector, this);
     },
 
     
     child : function(selector) {
+        selector = selector || '';
         return this.query('> ' + selector)[0] || null;
     },
 
@@ -28013,8 +28423,8 @@ Ext.define('Ext.container.AbstractContainer', {
             }
         }
         layoutCollection.clear();
-    },    
-    
+    },
+
     //@private
 
     
@@ -28022,12 +28432,12 @@ Ext.define('Ext.container.AbstractContainer', {
         Ext.Array.each(this.query('[isFormField]'), function(item) {
             if (item.resetDisable) {
                 item.enable();
-                delete item.resetDisable;             
+                delete item.resetDisable;
             }
         });
         this.callParent();
     },
-    
+
     
     
     onDisable: function() {
@@ -28058,13 +28468,13 @@ Ext.define('Ext.container.AbstractContainer', {
         }
 
         Ext.destroy(
-            me.layout,
-            me.floatingItems
+            me.layout
         );
         me.callParent();
     }
 });
 
+
 Ext.define('Ext.container.Container', {
     extend: 'Ext.container.AbstractContainer',
     alias: 'widget.container',
@@ -28211,10 +28621,16 @@ Ext.define('Ext.menu.Manager', {
     onMouseDown: function(e) {
         var me = this,
             active = me.active,
-            lastShow = me.lastShow;
+            lastShow = me.lastShow,
+            target = e.target;
 
         if (Ext.Date.getElapsed(lastShow) > 50 && active.length > 0 && !e.getTarget('.' + Ext.baseCSSPrefix + 'menu')) {
             me.hideAll();
+            
+            
+            if (Ext.isIE && Ext.fly(target).focusable()) {
+                target.focus();
+            }
         }
     },
 
@@ -28316,6 +28732,140 @@ Ext.define('Ext.menu.Manager', {
     }
 });
 
+Ext.define('Ext.layout.component.Button', {
+
+    
+
+    alias: ['layout.button'],
+
+    extend: 'Ext.layout.component.Component',
+
+    
+
+    type: 'button',
+
+    cellClsRE: /-btn-(tl|br)\b/,
+    htmlRE: /<.*>/,
+
+    beforeLayout: function() {
+        return this.callParent(arguments) || this.lastText !== this.owner.text;
+    },
+
+    
+    onLayout: function(width, height) {
+        var me = this,
+            isNum = Ext.isNumber,
+            owner = me.owner,
+            ownerEl = owner.el,
+            btnEl = owner.btnEl,
+            btnInnerEl = owner.btnInnerEl,
+            btnIconEl = owner.btnIconEl,
+            sizeIconEl = (owner.icon || owner.iconCls) && (owner.iconAlign == "top" || owner.iconAlign == "bottom"),
+            minWidth = owner.minWidth,
+            maxWidth = owner.maxWidth,
+            ownerWidth, btnFrameWidth, metrics;
+
+        me.getTargetInfo();
+        me.callParent(arguments);
+
+        btnInnerEl.unclip();
+        me.setTargetSize(width, height);
+
+        if (!isNum(width)) {
+            
+            
+            
+            if (owner.text && (Ext.isIE6 || Ext.isIE7) && Ext.isStrict && btnEl && btnEl.getWidth() > 20) {
+                btnFrameWidth = me.btnFrameWidth;
+                metrics = Ext.util.TextMetrics.measure(btnInnerEl, owner.text);
+                ownerEl.setWidth(metrics.width + btnFrameWidth + me.adjWidth);
+                btnEl.setWidth(metrics.width + btnFrameWidth);
+                btnInnerEl.setWidth(metrics.width + btnFrameWidth);
+
+                if (sizeIconEl) {
+                    btnIconEl.setWidth(metrics.width + btnFrameWidth);
+                }
+            } else {
+                
+                ownerEl.setWidth(null);
+                btnEl.setWidth(null);
+                btnInnerEl.setWidth(null);
+                btnIconEl.setWidth(null);
+            }
+
+            
+            if (minWidth || maxWidth) {
+                ownerWidth = ownerEl.getWidth();
+                if (minWidth && (ownerWidth < minWidth)) {
+                    me.setTargetSize(minWidth, height);
+                }
+                else if (maxWidth && (ownerWidth > maxWidth)) {
+                    btnInnerEl.clip();
+                    me.setTargetSize(maxWidth, height);
+                }
+            }
+        }
+
+        this.lastText = owner.text;
+    },
+
+    setTargetSize: function(width, height) {
+        var me = this,
+            owner = me.owner,
+            isNum = Ext.isNumber,
+            btnInnerEl = owner.btnInnerEl,
+            btnWidth = (isNum(width) ? width - me.adjWidth : width),
+            btnHeight = (isNum(height) ? height - me.adjHeight : height),
+            btnFrameHeight = me.btnFrameHeight,
+            text = owner.getText(),
+            textHeight;
+
+        me.callParent(arguments);
+        me.setElementSize(owner.btnEl, btnWidth, btnHeight);
+        me.setElementSize(btnInnerEl, btnWidth, btnHeight);
+        if (btnHeight >= 0) {
+            btnInnerEl.setStyle('line-height', btnHeight - btnFrameHeight + 'px');
+        }
+
+        
+        
+        
+        
+        
+        if (text && this.htmlRE.test(text)) {
+            btnInnerEl.setStyle('line-height', 'normal');
+            textHeight = Ext.util.TextMetrics.measure(btnInnerEl, text).height;
+            btnInnerEl.setStyle('padding-top', me.btnFrameTop + Math.max(btnInnerEl.getHeight() - btnFrameHeight - textHeight, 0) / 2 + 'px');
+            me.setElementSize(btnInnerEl, btnWidth, btnHeight);
+        }
+    },
+
+    getTargetInfo: function() {
+        var me = this,
+            owner = me.owner,
+            ownerEl = owner.el,
+            frameSize = me.frameSize,
+            frameBody = owner.frameBody,
+            btnWrap = owner.btnWrap,
+            innerEl = owner.btnInnerEl;
+
+        if (!('adjWidth' in me)) {
+            Ext.apply(me, {
+                
+                adjWidth: frameSize.left + frameSize.right + ownerEl.getBorderWidth('lr') + ownerEl.getPadding('lr') +
+                          btnWrap.getPadding('lr') + (frameBody ? frameBody.getFrameWidth('lr') : 0),
+                adjHeight: frameSize.top + frameSize.bottom + ownerEl.getBorderWidth('tb') + ownerEl.getPadding('tb') +
+                           btnWrap.getPadding('tb') + (frameBody ? frameBody.getFrameWidth('tb') : 0),
+                btnFrameWidth: innerEl.getFrameWidth('lr'),
+                btnFrameHeight: innerEl.getFrameWidth('tb'),
+                btnFrameTop: innerEl.getFrameWidth('t')
+            });
+        }
+
+        return me.callParent();
+    }
+});
+
 Ext.define('Ext.button.Button', {
 
     
@@ -28380,6 +28930,9 @@ Ext.define('Ext.button.Button', {
     menuAlign: 'tl-bl?',
 
     
+    textAlign: 'center',
+
+    
 
     
 
@@ -28388,7 +28941,7 @@ Ext.define('Ext.button.Button', {
 
     
     clickEvent: 'click',
-    
+
     
     preventDefault: true,
 
@@ -28403,42 +28956,54 @@ Ext.define('Ext.button.Button', {
 
     
     pressedCls: 'pressed',
-    
+
     
     overCls: 'over',
-    
+
     
     focusCls: 'focus',
-    
+
     
     menuActiveCls: 'menu-active',
 
+    
+
+    
+
+    
+
     ariaRole: 'button',
 
     
     renderTpl:
-        '<em class="{splitCls}">' +
+        '<em id="{id}-btnWrap" class="{splitCls}">' +
             '<tpl if="href">' +
-                '<a href="{href}" target="{target}"<tpl if="tabIndex"> tabIndex="{tabIndex}"</tpl> role="link">' +
-                    '<span class="{baseCls}-inner">{text}</span>' +
+                '<a id="{id}-btnEl" href="{href}" target="{target}"<tpl if="tabIndex"> tabIndex="{tabIndex}"</tpl> role="link">' +
+                    '<span id="{id}-btnInnerEl" class="{baseCls}-inner">' +
+                        '{text}' +
+                    '</span>' +
+                        '<span id="{id}-btnIconEl" class="{baseCls}-icon"></span>' +
                 '</a>' +
             '</tpl>' +
             '<tpl if="!href">' +
-                '<button type="{type}" hidefocus="true"' +
+                '<button id="{id}-btnEl" type="{type}" hidefocus="true"' +
                     
                     
                     '<tpl if="tabIndex"> tabIndex="{tabIndex}"</tpl> role="button" autocomplete="off">' +
-                    '<span class="{baseCls}-inner" style="{innerSpanStyle}">{text}</span>' +
+                    '<span id="{id}-btnInnerEl" class="{baseCls}-inner" style="{innerSpanStyle}">' +
+                        '{text}' +
+                    '</span>' +
+                    '<span id="{id}-btnIconEl" class="{baseCls}-icon {iconCls}">&#160;</span>' +
                 '</button>' +
             '</tpl>' +
         '</em>' ,
 
     
     scale: 'small',
-    
+
     
     allowedScales: ['small', 'medium', 'large'],
-    
+
     
 
     
@@ -28457,7 +29022,7 @@ Ext.define('Ext.button.Button', {
     
 
     
-     
+
     maskOnDisable: false,
 
     
@@ -28538,15 +29103,16 @@ Ext.define('Ext.button.Button', {
     
     setButtonCls: function() {
         var me = this,
-            el = me.el,
-            cls = [];
+            cls = [],
+            btnIconEl = me.btnIconEl,
+            hide = 'x-hide-display';
 
         if (me.useSetClass) {
             if (!Ext.isEmpty(me.oldCls)) {
                 me.removeClsWithUI(me.oldCls);
                 me.removeClsWithUI(me.pressedCls);
             }
-            
+
             
             if (me.iconCls || me.icon) {
                 if (me.text) {
@@ -28554,32 +29120,35 @@ Ext.define('Ext.button.Button', {
                 } else {
                     cls.push('icon');
                 }
-            } else if (me.text) {
-                cls.push('noicon');
+                if (btnIconEl) {
+                    btnIconEl.removeCls(hide);
+                }
+            } else {
+                if (me.text) {
+                    cls.push('noicon');
+                }
+                if (btnIconEl) {
+                    btnIconEl.addCls(hide);
+                }
             }
-            
+
             me.oldCls = cls;
             me.addClsWithUI(cls);
             me.addClsWithUI(me.pressed ? me.pressedCls : null);
         }
     },
-    
+
     
     onRender: function(ct, position) {
         
         var me = this,
             repeater, btn;
-            
+
         
         Ext.applyIf(me.renderData, me.getTemplateArgs());
 
-        
-        Ext.applyIf(me.renderSelectors, {
-            btnEl  : me.href ? 'a' : 'button',
-            btnWrap: 'em',
-            btnInnerEl: '.' + me.baseCls + '-inner'
-        });
-        
+        me.addChildEls('btnEl', 'btnWrap', 'btnInnerEl', 'btnIconEl');
+
         if (me.scale) {
             me.ui = me.ui + '-' + me.scale;
         }
@@ -28589,7 +29158,7 @@ Ext.define('Ext.button.Button', {
 
         
         if (me.split && me.arrowTooltip) {
-            me.arrowEl.dom[me.tooltipType] = me.arrowTooltip;
+            me.arrowEl.dom.setAttribute(me.getTipAttr(), me.arrowTooltip);
         }
 
         
@@ -28614,6 +29183,10 @@ Ext.define('Ext.button.Button', {
             me.setTooltip(me.tooltip, true);
         }
 
+        if (me.textAlign) {
+            me.setTextAlign(me.textAlign);
+        }
+
         
         if (me.handleMouseEvents) {
             me.mon(btn, {
@@ -28677,6 +29250,7 @@ Ext.define('Ext.button.Button', {
             type     : me.type,
             splitCls : me.getSplitCls(),
             cls      : me.cls,
+            iconCls  : me.iconCls || '',
             text     : me.text || '&#160;',
             tabIndex : me.tabIndex,
             innerSpanStyle: innerSpanStyle
@@ -28685,13 +29259,17 @@ Ext.define('Ext.button.Button', {
 
     
     getHref: function() {
-        var me = this;
-        return me.href ? Ext.urlAppend(me.href, me.params + Ext.Object.toQueryString(Ext.apply(Ext.apply({}, me.baseParams)))) : false;
+        var me = this,
+            params = Ext.apply({}, me.baseParams);
+
+        
+        params = Ext.apply(params, me.params);
+        return me.href ? Ext.urlAppend(me.href, Ext.Object.toQueryString(params)) : false;
     },
 
     
-    setParams: function(p) {
-        this.params = p;
+    setParams: function(params) {
+        this.params = params;
         this.btnEl.dom.href = this.getHref();
     },
 
@@ -28712,14 +29290,16 @@ Ext.define('Ext.button.Button', {
     
     setIconCls: function(cls) {
         var me = this,
-            btnInnerEl = me.btnInnerEl;
-        if (btnInnerEl) {
+            btnIconEl = me.btnIconEl,
+            oldCls = me.iconCls;
+            
+        me.iconCls = cls;
+        if (btnIconEl) {
             
-            btnInnerEl.removeCls(me.iconCls);
-            btnInnerEl.addCls(cls || '');
+            btnIconEl.removeCls(oldCls);
+            btnIconEl.addCls(cls || '');
             me.setButtonCls();
         }
-        me.iconCls = cls;
         return me;
     },
 
@@ -28738,7 +29318,7 @@ Ext.define('Ext.button.Button', {
                 tooltip));
                 me.tooltip = tooltip;
             } else {
-                me.btnEl.dom.setAttribute('data-' + this.tooltipType, tooltip);
+                me.btnEl.dom.setAttribute(me.getTipAttr(), tooltip);
             }
         } else {
             me.tooltip = tooltip;
@@ -28747,10 +29327,27 @@ Ext.define('Ext.button.Button', {
     },
 
     
+    setTextAlign: function(align) {
+        var me = this,
+            btnEl = me.btnEl;
+
+        if (btnEl) {
+            btnEl.removeCls(me.baseCls + '-' + me.textAlign);
+            btnEl.addCls(me.baseCls + '-' + align);
+        }
+        me.textAlign = align;
+        return me;
+    },
+
+    getTipAttr: function(){
+        return this.tooltipType == 'qtip' ? 'data-qtip' : 'title';
+    },
+
+    
     getRefItems: function(deep){
         var menu = this.menu,
             items;
-
+        
         if (menu) {
             items = menu.getRefItems(deep);
             items.unshift(menu);
@@ -28772,9 +29369,10 @@ Ext.define('Ext.button.Button', {
             me.clearTip();
         }
         if (me.menu && me.destroyMenu !== false) {
-            Ext.destroy(me.btnEl, me.btnInnerEl, me.menu);
+            Ext.destroy(me.menu);
         }
-        Ext.destroy(me.repeater);
+        Ext.destroy(me.btnInnerEl, me.repeater);
+        me.callParent();
     },
 
     
@@ -28784,10 +29382,8 @@ Ext.define('Ext.button.Button', {
             me.doc.un('mouseover', me.monitorMouseOver, me);
             me.doc.un('mouseup', me.onMouseUp, me);
             delete me.doc;
-            delete me.btnEl;
-            delete me.btnInnerEl;
             Ext.ButtonToggleManager.unregister(me);
-            
+
             Ext.destroy(me.keyMap);
             delete me.keyMap;
         }
@@ -28816,10 +29412,11 @@ Ext.define('Ext.button.Button', {
     
     setIcon: function(icon) {
         var me = this,
-            btnInnerEl = me.btnInnerEl;
+            iconEl = me.btnIconEl;
+            
         me.icon = icon;
-        if (btnInnerEl) {
-            btnInnerEl.setStyle('background-image', icon ? 'url(' + icon + ')': '');
+        if (iconEl) {
+            iconEl.setStyle('background-image', icon ? 'url(' + icon + ')': '');
             me.setButtonCls();
         }
         return me;
@@ -28833,7 +29430,7 @@ Ext.define('Ext.button.Button', {
     
     toggle: function(state, suppressEvent) {
         var me = this;
-        state = state === undefined ? !me.pressed: !!state;
+        state = state === undefined ? !me.pressed : !!state;
         if (state !== me.pressed) {
             if (me.rendered) {
                 me[state ? 'addClsWithUI': 'removeClsWithUI'](me.pressedCls);
@@ -28847,12 +29444,19 @@ Ext.define('Ext.button.Button', {
         }
         return me;
     },
+    
+    maybeShowMenu: function(){
+        var me = this;
+        if (me.menu && !me.hasVisibleMenu() && !me.ignoreNextClick) {
+            me.showMenu();
+        }
+    },
 
     
     showMenu: function() {
         var me = this;
         if (me.rendered && me.menu) {
-            if (me.tooltip) {
+            if (me.tooltip && me.getTipAttr() != 'title') {
                 Ext.tip.QuickTipManager.getQuickTip().cancelShow(me.btnEl);
             }
             if (me.menu.isVisible()) {
@@ -28893,17 +29497,27 @@ Ext.define('Ext.button.Button', {
             return;
         }
         if (!me.disabled) {
-            if (me.enableToggle && (me.allowDepress !== false || !me.pressed)) {
-                me.toggle();
-            }
-            if (me.menu && !me.hasVisibleMenu() && !me.ignoreNextClick) {
-                me.showMenu();
-            }
-            me.fireEvent('click', me, e);
-            if (me.handler) {
-                me.handler.call(me.scope || me, me, e);
-            }
-            me.onBlur();
+            me.doToggle();
+            me.maybeShowMenu();
+            me.fireHandler(e);
+        }
+    },
+    
+    fireHandler: function(e){
+        var me = this,
+            handler = me.handler;
+            
+        me.fireEvent('click', me, e);
+        if (handler) {
+            handler.call(me.scope || me, me, e);
+        }
+        me.onBlur();
+    },
+    
+    doToggle: function(){
+        var me = this;
+        if (me.enableToggle && (me.allowDepress !== false || !me.pressed)) {
+            me.toggle();
         }
     },
 
@@ -28959,7 +29573,7 @@ Ext.define('Ext.button.Button', {
         var me = this,
             size = me.triggerSize,
             side, sideFirstLetter, undef;
-            
+
         if (size === undef) {
             side = me.arrowAlign;
             sideFirstLetter = side.charAt(0);
@@ -28995,13 +29609,13 @@ Ext.define('Ext.button.Button', {
         delete me.overMenuTrigger;
         me.fireEvent('menutriggerout', me, me.menu, e);
     },
-    
+
     
     enable : function(silent) {
         var me = this;
 
         me.callParent(arguments);
-        
+
         me.removeClsWithUI('disabled');
 
         return me;
@@ -29010,43 +29624,44 @@ Ext.define('Ext.button.Button', {
     
     disable : function(silent) {
         var me = this;
-        
+
         me.callParent(arguments);
-        
+
         me.addClsWithUI('disabled');
+        me.removeClsWithUI(me.overCls);
 
         return me;
     },
-    
+
     
     setScale: function(scale) {
         var me = this,
             ui = me.ui.replace('-' + me.scale, '');
-        
+
         
         if (!Ext.Array.contains(me.allowedScales, scale)) {
             throw('#setScale: scale must be an allowed scale (' + me.allowedScales.join(', ') + ')');
         }
-        
+
         me.scale = scale;
         me.setUI(ui);
     },
-    
+
     
     setUI: function(ui) {
         var me = this;
-        
+
         
         if (me.scale && !ui.match(me.scale)) {
             ui = ui + '-' + me.scale;
         }
-        
+
         me.callParent([ui]);
-        
+
         
         
     },
-    
+
     
     onFocus: function(e) {
         var me = this;
@@ -29145,10 +29760,10 @@ Ext.define('Ext.button.Button', {
     }
 
 }, function() {
-    var groups = {},
-        g, i, l;
+    var groups = {};
 
     function toggleGroup(btn, state) {
+        var g, i, l;
         if (state) {
             g = groups[btn.toggleGroup];
             for (i = 0, l = g.length; i < l; i++) {
@@ -29158,6 +29773,7 @@ Ext.define('Ext.button.Button', {
             }
         }
     }
+
     
     Ext.ButtonToggleManager = {
         register: function(btn) {
@@ -29228,6 +29844,10 @@ Ext.define('Ext.layout.container.boxOverflow.Menu', {
         
         me.menuItems = [];
     },
+    
+    onRemove: function(comp){
+        Ext.Array.remove(this.menuItems, comp);
+    },
 
     handleOverflow: function(calculations, targetSize) {
         var me = this,
@@ -29279,7 +29899,7 @@ Ext.define('Ext.layout.container.boxOverflow.Menu', {
 
     
     hideTrigger: function() {
-        if (this.menuTrigger != undefined) {
+        if (this.menuTrigger !== undefined) {
             this.menuTrigger.hide();
         }
     },
@@ -29405,7 +30025,6 @@ Ext.define('Ext.layout.container.boxOverflow.Menu', {
 
             
             me.menu = Ext.create('Ext.menu.Menu', {
-                hideMode: 'offsets',
                 listeners: {
                     scope: me,
                     beforeshow: me.beforeMenuShow
@@ -29415,7 +30034,7 @@ Ext.define('Ext.layout.container.boxOverflow.Menu', {
             
             me.menuTrigger = Ext.create('Ext.button.Button', {
                 ownerCt : me.layout.owner, 
-                iconCls : Ext.baseCSSPrefix + layout.owner.getXType() + '-more-icon',
+                iconCls : me.layout.owner.menuTriggerCls,
                 ui      : layout.owner instanceof Ext.toolbar.Toolbar ? 'default-toolbar' : 'default',
                 menu    : me.menu,
                 getSplitCls: function() { return '';},
@@ -29454,7 +30073,6 @@ Ext.define('Ext.layout.container.boxOverflow.Menu', {
     }
 });
 
-
 Ext.define('Ext.util.Region', {
 
     
@@ -29695,7 +30313,6 @@ Ext.define('Ext.util.Region', {
         return "Region[" + this.top + "," + this.right + "," + this.bottom + "," + this.left + "]";
     },
 
-
     
     translateBy: function(x, y) {
         if (arguments.length == 1) {
@@ -29741,7 +30358,7 @@ Ext.define('Ext.dd.DragDropManager', {
 
     
     alternateClassName: ['Ext.dd.DragDropMgr', 'Ext.dd.DDM'],
-    
+
     
     ids: {},
 
@@ -29957,7 +30574,7 @@ Ext.define('Ext.dd.DragDropManager', {
             
             this.handleMouseUp(e);
         }
-        
+
         this.currentTarget = e.getTarget();
         this.dragCurrent = oDD;
 
@@ -29993,7 +30610,7 @@ Ext.define('Ext.dd.DragDropManager', {
     
     handleMouseUp: function(e) {
 
-        if(Ext.tip.QuickTipManager){
+        if(Ext.tip && Ext.tip.QuickTipManager){
             Ext.tip.QuickTipManager.ddEnable();
         }
         if (! this.dragCurrent) {
@@ -30297,7 +30914,7 @@ Ext.define('Ext.dd.DragDropManager', {
         var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;
 
         try {
-            pos= Ext.core.Element.getXY(el);
+            pos= Ext.Element.getXY(el);
         } catch (e) { }
 
         if (!pos) {
@@ -30417,22 +31034,25 @@ Ext.define('Ext.dd.DragDropManager', {
 
     
     ElementWrapper: function(el) {
-            
-            this.el = el || null;
-            
-            this.id = this.el && el.id;
-            
-            this.css = this.el && el.style;
-        },
+        
+        this.el = el || null;
+        
+        this.id = this.el && el.id;
+        
+        this.css = this.el && el.style;
+    },
+
+    
+    
 
     
     getPosX: function(el) {
-        return Ext.core.Element.getX(el);
+        return Ext.Element.getX(el);
     },
 
     
     getPosY: function(el) {
-        return Ext.core.Element.getY(el);
+        return Ext.Element.getY(el);
     },
 
     
@@ -30461,7 +31081,7 @@ Ext.define('Ext.dd.DragDropManager', {
             body  = doc.body,
             top   = 0,
             left  = 0;
-            
+
         if (Ext.isGecko4) {
             top  = window.scrollYOffset;
             left = window.scrollXOffset;
@@ -30472,7 +31092,7 @@ Ext.define('Ext.dd.DragDropManager', {
             } else if (body) {
                 top  = body.scrollTop;
                 left = body.scrollLeft;
-            } 
+            }
         }
         return {
             top: top,
@@ -30497,8 +31117,8 @@ Ext.define('Ext.dd.DragDropManager', {
 
     
     moveToEl: function (moveEl, targetEl) {
-        var aCoord = Ext.core.Element.getXY(targetEl);
-        Ext.core.Element.setXY(moveEl, aCoord);
+        var aCoord = Ext.Element.getXY(targetEl);
+        Ext.Element.setXY(moveEl, aCoord);
     },
 
     
@@ -30556,7 +31176,7 @@ Ext.define('Ext.layout.container.Box', {
     alias: ['layout.box'],
     extend: 'Ext.layout.container.Container',
     alternateClassName: 'Ext.layout.BoxLayout',
-    
+
     requires: [
         'Ext.layout.container.boxOverflow.None',
         'Ext.layout.container.boxOverflow.Menu',
@@ -30593,15 +31213,16 @@ Ext.define('Ext.layout.container.Box', {
 
     bindToOwnerCtContainer: true,
 
-    fixedLayout: false,
-    
     
     
     availableSpaceOffset: 0,
-    
+
     
     reserveOffset: true,
+
     
+    shrinkToFit: true,
+
     
     clearInnerCtOnLayout: false,
 
@@ -30636,11 +31257,12 @@ Ext.define('Ext.layout.container.Box', {
     
     getChildBox: function(child) {
         child = child.el || this.owner.getComponent(child).el;
+        var size = child.getBox(false, true);
         return {
-            left: child.getLeft(true),
-            top: child.getTop(true),
-            width: child.getWidth(),
-            height: child.getHeight()
+            left: size.left,
+            top: size.top,
+            width: size.width,
+            height: size.height
         };
     },
 
@@ -30684,6 +31306,8 @@ Ext.define('Ext.layout.container.Box', {
             paddingPerpendicular =  perpendicularOffset + padding[me.perpendicularRightBottom],
             availPerpendicularSize = mmax(0, perpendicularSize - paddingPerpendicular),
 
+            innerCtBorderWidth = me.innerCt.getBorderWidth(me.perpendicularLT + me.perpendicularRB),
+
             isStart = me.pack == 'start',
             isCenter = me.pack == 'center',
             isEnd = me.pack == 'end',
@@ -30699,16 +31323,21 @@ Ext.define('Ext.layout.container.Box', {
             minSizes = [],
             calculatedWidth,
 
-            i, child, childParallel, childPerpendicular, childMargins, childSize, minParallel, tmpObj, shortfall, 
-            tooNarrow, availableSpace, minSize, item, length, itemIndex, box, oldSize, newSize, reduction, diff, 
-            flexedBoxes, remainingSpace, remainingFlex, flexedSize, parallelMargins, calcs, offset, 
+            i, child, childParallel, childPerpendicular, childMargins, childSize, minParallel, tmpObj, shortfall,
+            tooNarrow, availableSpace, minSize, item, length, itemIndex, box, oldSize, newSize, reduction, diff,
+            flexedBoxes, remainingSpace, remainingFlex, flexedSize, parallelMargins, calcs, offset,
             perpendicularMargins, stretchSize;
 
         
         for (i = 0; i < visibleCount; i++) {
             child = visibleItems[i];
             childPerpendicular = child[perpendicularPrefix];
-            me.layoutItem(child);
+            if (!child.flex || !(me.align == 'stretch' || me.align == 'stretchmax')) {
+                if (child.componentLayout.initialized !== true) {
+                    me.layoutItem(child);
+                }
+            }
+
             childMargins = child.margins;
             parallelMargins = childMargins[me.parallelBefore] + childMargins[me.parallelAfter];
 
@@ -30744,14 +31373,20 @@ Ext.define('Ext.layout.container.Box', {
             }
 
             
-            maxSize = mmax(maxSize, childPerpendicular + childMargins[me.perpendicularLeftTop] + childMargins[me.perpendicularRightBottom]);
+            
+            maxSize = mmax(maxSize, mmax(childPerpendicular, child[perpendicularMinString]||0) + childMargins[me.perpendicularLeftTop] + childMargins[me.perpendicularRightBottom]);
 
             tmpObj[parallelPrefix] = childParallel || undefinedValue;
+            tmpObj.dirtySize = child.componentLayout.lastComponentSize ? (tmpObj[parallelPrefix] !== child.componentLayout.lastComponentSize[parallelPrefix]) : false;
             tmpObj[perpendicularPrefix] = childPerpendicular || undefinedValue;
             boxes.push(tmpObj);
         }
-        shortfall = desiredSize - parallelSize;
-        tooNarrow = minimumSize > parallelSize;
+
+        
+        if (!me.autoSize) {
+            shortfall = desiredSize - parallelSize;
+            tooNarrow = minimumSize > parallelSize;
+        }
 
         
         availableSpace = mmax(0, parallelSize - nonFlexSize - paddingParallel - (me.reserveOffset ? me.availableSpaceOffset : 0));
@@ -30779,8 +31414,7 @@ Ext.define('Ext.layout.container.Box', {
                         box = boxes[i];
                         box.dirtySize = box.dirtySize || box[parallelPrefix] != minSize;
                         box[parallelPrefix] = minSize;
-                    }
-                    else {
+                    } else if (me.shrinkToFit) {
                         minSizes.push({
                             minSize: minSize,
                             available: boxes[i][parallelPrefix] - minSize,
@@ -30811,6 +31445,7 @@ Ext.define('Ext.layout.container.Box', {
                     box[parallelPrefix] = newSize;
                     shortfall -= reduction;
                 }
+                tooNarrow = (shortfall > 0);
             }
             else {
                 remainingSpace = availableSpace;
@@ -30900,7 +31535,7 @@ Ext.define('Ext.layout.container.Box', {
                 
                 
                 
-                diff = mmax(availPerpendicularSize, maxSize) - me.innerCt.getBorderWidth(me.perpendicularLT + me.perpendicularRB) - calcs[perpendicularPrefix];
+                diff = mmax(availPerpendicularSize, maxSize) - innerCtBorderWidth - calcs[perpendicularPrefix];
                 if (diff > 0) {
                     calcs[me.perpendicularLeftTop] = perpendicularOffset + Math.round(diff / 2);
                 }
@@ -30924,6 +31559,13 @@ Ext.define('Ext.layout.container.Box', {
         };
     },
 
+    onRemove: function(comp){
+        this.callParent(arguments);
+        if (this.overflowHandler) {
+            this.overflowHandler.onRemove(comp);
+        }
+    },
+
     
     initOverflowHandler: function() {
         var handler = this.overflowHandler;
@@ -30935,7 +31577,7 @@ Ext.define('Ext.layout.container.Box', {
         }
 
         var handlerType = 'None';
-        if (handler && handler.type != undefined) {
+        if (handler && handler.type !== undefined) {
             handlerType = handler.type;
         }
 
@@ -30980,7 +31622,7 @@ Ext.define('Ext.layout.container.Box', {
                 }
 
                 if (results.recalculate) {
-                    items = me.getVisibleItems(owner);
+                    items = me.getVisibleItems();
                     calcs = me.calculateChildBoxes(items, targetSize);
                     boxes = calcs.boxes;
                 }
@@ -30999,6 +31641,8 @@ Ext.define('Ext.layout.container.Box', {
         me.updateChildBoxes(boxes);
         me.handleTargetOverflow(targetSize);
     },
+    
+    animCallback: Ext.emptyFn,
 
     
     updateChildBoxes: function(boxes) {
@@ -31087,6 +31731,7 @@ Ext.define('Ext.layout.container.Box', {
                 
                 length -= 1;
                 if (!length) {
+                    me.animCallback(anim);
                     me.layoutBusy = false;
                     if (Ext.isFunction(animCallback)) {
                         animCallback();
@@ -31231,6 +31876,8 @@ Ext.define('Ext.layout.container.Box', {
         margins.right  += itemEl.getMargin('r');
         margins.bottom += itemEl.getMargin('b');
         margins.left   += itemEl.getMargin('l');
+        margins.height  = margins.top  + margins.bottom;
+        margins.width   = margins.left + margins.right;
         style.marginTop = style.marginRight = style.marginBottom = style.marginLeft = '0';
 
         
@@ -31239,7 +31886,7 @@ Ext.define('Ext.layout.container.Box', {
 
     
     destroy: function() {
-        Ext.destroy(this.overflowHandler);
+        Ext.destroy(this.innerCt, this.overflowHandler);
         this.callParent(arguments);
     }
 });
@@ -31251,7 +31898,7 @@ Ext.define('Ext.layout.container.HBox', {
     alias: ['layout.hbox'],
     extend: 'Ext.layout.container.Box',
     alternateClassName: 'Ext.layout.HBoxLayout',
-    
+
     
 
     
@@ -31284,7 +31931,21 @@ Ext.define('Ext.layout.container.HBox', {
     perpendicularRB: 'b',
     perpendicularLeftTop: 'top',
     perpendicularRightBottom: 'bottom',
-    perpendicularPosition: 'y'
+    perpendicularPosition: 'y',
+    configureItem: function(item) {
+        if (item.flex) {
+            item.layoutManagedWidth = 1;
+        } else {
+            item.layoutManagedWidth = 2;
+        }
+
+        if (this.align === 'stretch' || this.align === 'stretchmax') {
+            item.layoutManagedHeight = 1;
+        } else {
+            item.layoutManagedHeight = 2;
+        }
+        this.callParent(arguments);
+    }
 });
 
 Ext.define('Ext.layout.container.VBox', {
@@ -31294,7 +31955,7 @@ Ext.define('Ext.layout.container.VBox', {
     alias: ['layout.vbox'],
     extend: 'Ext.layout.container.Box',
     alternateClassName: 'Ext.layout.VBoxLayout',
-    
+
     
 
     
@@ -31327,7 +31988,21 @@ Ext.define('Ext.layout.container.VBox', {
     perpendicularRB: 'r',
     perpendicularLeftTop: 'left',
     perpendicularRightBottom: 'right',
-    perpendicularPosition: 'x'
+    perpendicularPosition: 'x',
+    configureItem: function(item) {
+        if (item.flex) {
+            item.layoutManagedHeight = 1;
+        } else {
+            item.layoutManagedHeight = 2;
+        }
+
+        if (this.align === 'stretch' || this.align === 'stretchmax') {
+            item.layoutManagedWidth = 1;
+        } else {
+            item.layoutManagedWidth = 2;
+        }
+        this.callParent(arguments);
+    }
 });
 
 Ext.define('Ext.FocusManager', {
@@ -31619,8 +32294,8 @@ Ext.define('Ext.FocusManager', {
                 ],
                 style: 'top: -100px; left: -100px;'
             });
-            me.focusFrame.setVisibilityMode(Ext.core.Element.DISPLAY);
-            me.focusFrameWidth = me.focusFrame.child('.' + cls + '-top').getHeight();
+            me.focusFrame.setVisibilityMode(Ext.Element.DISPLAY);
+            me.focusFrameWidth = 2;
             me.focusFrame.hide().setLeftTop(0, 0);
         }
     },
@@ -31666,10 +32341,14 @@ Ext.define('Ext.FocusManager', {
 
         if (!me.focusedCmp || !(parent = me.focusedCmp.up(':focusable'))) {
             me.focusEl.focus();
-            return;
+        } else {
+            parent.focus();
         }
 
-        parent.focus();
+        
+        
+        
+        return true;
     },
 
     navigateSiblings: function(e, source, parent) {
@@ -31788,10 +32467,10 @@ Ext.define('Ext.FocusManager', {
                 fl = ff.child(cls + 'left'),
                 fr = ff.child(cls + 'right');
 
-            ft.setWidth(bw - 2).setLeftTop(bl + 1, bt);
-            fb.setWidth(bw - 2).setLeftTop(bl + 1, bt + bh - fw);
-            fl.setHeight(bh - 2).setLeftTop(bl, bt + 1);
-            fr.setHeight(bh - 2).setLeftTop(bl + bw - fw, bt + 1);
+            ft.setWidth(bw).setLeftTop(bl, bt);
+            fb.setWidth(bw).setLeftTop(bl, bt + bh - fw);
+            fl.setHeight(bh - fw - fw).setLeftTop(bl, bt + fw);
+            fr.setHeight(bh - fw - fw).setLeftTop(bl + bw - fw, bt + fw);
 
             ff.show();
         }
@@ -32087,13 +32766,13 @@ Ext.define('Ext.toolbar.Toolbar', {
     ],
     alias: 'widget.toolbar',
     alternateClassName: 'Ext.Toolbar',
-    
+
     isToolbar: true,
     baseCls  : Ext.baseCSSPrefix + 'toolbar',
     ariaRole : 'toolbar',
-    
+
     defaultType: 'button',
-    
+
     
     vertical: false,
 
@@ -32101,12 +32780,15 @@ Ext.define('Ext.toolbar.Toolbar', {
 
     
     enableOverflow: false,
+
     
+    menuTriggerCls: Ext.baseCSSPrefix + 'toolbar-more-icon',
     
-    trackMenus: true,
     
+    trackMenus: true,
+
     itemCls: Ext.baseCSSPrefix + 'toolbar-item',
-    
+
     initComponent: function() {
         var me = this,
             keys;
@@ -32115,7 +32797,7 @@ Ext.define('Ext.toolbar.Toolbar', {
         if (!me.layout && me.enableOverflow) {
             me.layout = { overflowHandler: 'Menu' };
         }
-        
+
         if (me.dock === 'right' || me.dock === 'left') {
             me.vertical = true;
         }
@@ -32124,23 +32806,24 @@ Ext.define('Ext.toolbar.Toolbar', {
             type: me.layout
         } : me.layout || {}, {
             type: me.vertical ? 'vbox' : 'hbox',
-            align: me.vertical ? 'stretchmax' : 'middle'
+            align: me.vertical ? 'stretchmax' : 'middle',
+            clearInnerCtOnLayout: true
         });
-        
+
         if (me.vertical) {
             me.addClsWithUI('vertical');
         }
-        
+
         
         if (me.ui === 'footer') {
             me.ignoreBorderManagement = true;
         }
-        
+
         me.callParent();
 
         
         me.addEvents('overflowchange');
-        
+
         
         keys = me.vertical ? ['up', 'down'] : ['left', 'right'];
         Ext.FocusManager.subscribe(me, {
@@ -32148,6 +32831,21 @@ Ext.define('Ext.toolbar.Toolbar', {
         });
     },
 
+    getRefItems: function(deep) {
+        var me = this,
+            items = me.callParent(arguments),
+            layout = me.layout,
+            handler;
+
+        if (deep && me.enableOverflow) {
+            handler = layout.overflowHandler;
+            if (handler && handler.menu) {
+                items = items.concat(handler.menu.getRefItems(deep));
+            }
+        }
+        return items;
+    },
+
     
 
     
@@ -32190,7 +32888,7 @@ Ext.define('Ext.toolbar.Toolbar', {
             var method = remove ? 'mun' : 'mon',
                 me = this;
 
-            me[method](item, 'menutriggerover', me.onButtonTriggerOver, me);
+            me[method](item, 'mouseover', me.onButtonOver, me);
             me[method](item, 'menushow', me.onButtonMenuShow, me);
             me[method](item, 'menuhide', me.onButtonMenuHide, me);
         }
@@ -32206,12 +32904,12 @@ Ext.define('Ext.toolbar.Toolbar', {
         if (component.is('field') || (component.is('button') && this.ui != 'footer')) {
             component.ui = component.ui + '-toolbar';
         }
-        
+
         
         if (component instanceof Ext.toolbar.Separator) {
             component.setUI((this.vertical) ? 'vertical' : 'horizontal');
         }
-        
+
         this.callParent(arguments);
     },
 
@@ -32232,7 +32930,7 @@ Ext.define('Ext.toolbar.Toolbar', {
     },
 
     
-    onButtonTriggerOver: function(btn){
+    onButtonOver: function(btn){
         if (this.activeMenuBtn && this.activeMenuBtn != btn) {
             this.activeMenuBtn.hideMenu();
             btn.showMenu();
@@ -32263,7 +32961,7 @@ Ext.define('Ext.panel.AbstractPanel', {
 
     extend: 'Ext.container.Container',
 
-    requires: ['Ext.util.MixedCollection', 'Ext.core.Element', 'Ext.toolbar.Toolbar'],
+    requires: ['Ext.util.MixedCollection', 'Ext.Element', 'Ext.toolbar.Toolbar'],
 
     
 
@@ -32273,25 +32971,34 @@ Ext.define('Ext.panel.AbstractPanel', {
     
 
     
+
     
-    
-    
+
     
 
     isPanel: true,
 
     componentLayout: 'dock',
 
-    renderTpl: ['<div class="{baseCls}-body<tpl if="bodyCls"> {bodyCls}</tpl> {baseCls}-body-{ui}<tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-body-{parent.ui}-{.}</tpl></tpl>"<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>></div>'],
+    
+    defaultDockWeights: { top: 1, left: 3, right: 5, bottom: 7 },
+
+    renderTpl: [
+        '<div id="{id}-body" class="{baseCls}-body<tpl if="bodyCls"> {bodyCls}</tpl>',
+            ' {baseCls}-body-{ui}<tpl if="uiCls">',
+                '<tpl for="uiCls"> {parent.baseCls}-body-{parent.ui}-{.}</tpl>',
+            '</tpl>"<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>>',
+        '</div>'
+    ],
 
     
     
-     
+
     border: true,
 
     initComponent : function() {
         var me = this;
-        
+
         me.addEvents(
             
             'bodyresize'
@@ -32301,20 +33008,18 @@ Ext.define('Ext.panel.AbstractPanel', {
             
         );
 
-        Ext.applyIf(me.renderSelectors, {
-            body: '.' + me.baseCls + '-body'
-        });
-        
-        
+        me.addChildEls('body');
+
         
         
+
         if (me.frame && me.border && me.bodyBorder === undefined) {
             me.bodyBorder = false;
         }
         if (me.frame && me.border && (me.bodyBorder === false || me.bodyBorder === 0)) {
             me.manageBodyBorders = true;
         }
-        
+
         me.callParent();
     },
 
@@ -32322,7 +33027,7 @@ Ext.define('Ext.panel.AbstractPanel', {
     initItems : function() {
         var me = this,
             items = me.dockedItems;
-            
+
         me.callParent();
         me.dockedItems = Ext.create('Ext.util.MixedCollection', false, me.getComponentId);
         if (items) {
@@ -32353,7 +33058,7 @@ Ext.define('Ext.panel.AbstractPanel', {
         var me = this,
             bodyStyle = me.bodyStyle,
             styles = [],
-            Element = Ext.core.Element,
+            Element = Ext.Element,
             prop;
 
         if (Ext.isFunction(bodyStyle)) {
@@ -32381,13 +33086,13 @@ Ext.define('Ext.panel.AbstractPanel', {
         delete me.bodyStyle;
         return styles.length ? styles.join(';') : undefined;
     },
-    
+
     
     initBodyCls: function() {
         var me = this,
             cls = '',
             bodyCls = me.bodyCls;
-        
+
         if (bodyCls) {
             Ext.each(bodyCls, function(v) {
                 cls += " " + v;
@@ -32396,7 +33101,7 @@ Ext.define('Ext.panel.AbstractPanel', {
         }
         return cls.length > 0 ? cls : undefined;
     },
-    
+
     
     initRenderData: function() {
         return Ext.applyIf(this.callParent(), {
@@ -32432,7 +33137,10 @@ Ext.define('Ext.panel.AbstractPanel', {
             item.onAdded(me, i);
             me.onDockedAdd(item);
         }
-        if (me.rendered) {
+
+        
+        me.componentLayout.childrenChanged = true;
+        if (me.rendered && !me.suspendLayout) {
             me.doComponentLayout();
         }
         return items;
@@ -32452,7 +33160,7 @@ Ext.define('Ext.panel.AbstractPanel', {
         var me = this,
             layout,
             hasLayout;
-            
+
         if (!me.dockedItems.contains(item)) {
             return item;
         }
@@ -32470,13 +33178,15 @@ Ext.define('Ext.panel.AbstractPanel', {
 
         if (autoDestroy === true || (autoDestroy !== false && me.autoDestroy)) {
             item.destroy();
+        } else if (hasLayout) {
+            
+            layout.afterRemove(item);    
         }
 
-        if (hasLayout && !autoDestroy) {
-            layout.afterRemove(item);
-        }
+
         
-        if (!this.destroying) {
+        me.componentLayout.childrenChanged = true;
+        if (!me.destroying && !me.suspendLayout) {
             me.doComponentLayout();
         }
 
@@ -32486,9 +33196,7 @@ Ext.define('Ext.panel.AbstractPanel', {
     
     getDockedItems : function(cqSelector) {
         var me = this,
-            
-            
-            defaultWeight = { top: 1, left: 3, right: 5, bottom: 7 },
+            defaultWeight = me.defaultDockWeights,
             dockedItems;
 
         if (me.dockedItems && me.dockedItems.items.length) {
@@ -32501,7 +33209,6 @@ Ext.define('Ext.panel.AbstractPanel', {
 
             Ext.Array.sort(dockedItems, function(a, b) {
                 
-                
                 var aw = a.weight || defaultWeight[a.dock],
                     bw = b.weight || defaultWeight[b.dock];
                 if (Ext.isNumber(aw) && Ext.isNumber(bw)) {
@@ -32509,57 +33216,123 @@ Ext.define('Ext.panel.AbstractPanel', {
                 }
                 return 0;
             });
-            
+
             return dockedItems;
         }
         return [];
     },
-    
+
     
     addUIClsToElement: function(cls, force) {
-        var me = this;
-        
-        me.callParent(arguments);
-        
+        var me = this,
+            result = me.callParent(arguments),
+            classes = [Ext.baseCSSPrefix + cls, me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls],
+            array, i;
+
         if (!force && me.rendered) {
-            me.body.addCls(Ext.baseCSSPrefix + cls);
-            me.body.addCls(me.baseCls + '-body-' + cls);
-            me.body.addCls(me.baseCls + '-body-' + me.ui + '-' + cls);
+            if (me.bodyCls) {
+                me.body.addCls(me.bodyCls);
+            } else {
+                me.body.addCls(classes);
+            }
+        } else {
+            if (me.bodyCls) {
+                array = me.bodyCls.split(' ');
+
+                for (i = 0; i < classes.length; i++) {
+                    if (!Ext.Array.contains(array, classes[i])) {
+                        array.push(classes[i]);
+                    }
+                }
+
+                me.bodyCls = array.join(' ');
+            } else {
+                me.bodyCls = classes.join(' ');
+            }
         }
+
+        return result;
     },
-    
+
     
     removeUIClsFromElement: function(cls, force) {
-        var me = this;
-        
-        me.callParent(arguments);
-        
+        var me = this,
+            result = me.callParent(arguments),
+            classes = [Ext.baseCSSPrefix + cls, me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls],
+            array, i;
+
         if (!force && me.rendered) {
-            me.body.removeCls(Ext.baseCSSPrefix + cls);
-            me.body.removeCls(me.baseCls + '-body-' + cls);
-            me.body.removeCls(me.baseCls + '-body-' + me.ui + '-' + cls);
+            if (me.bodyCls) {
+                me.body.removeCls(me.bodyCls);
+            } else {
+                me.body.removeCls(classes);
+            }
+        } else {
+            if (me.bodyCls) {
+                array = me.bodyCls.split(' ');
+
+                for (i = 0; i < classes.length; i++) {
+                    Ext.Array.remove(array, classes[i]);
+                }
+
+                me.bodyCls = array.join(' ');
+            }
         }
+
+        return result;
     },
-    
+
     
     addUIToElement: function(force) {
-        var me = this;
-        
+        var me = this,
+            cls = me.baseCls + '-body-' + me.ui,
+            array;
+
         me.callParent(arguments);
-        
+
         if (!force && me.rendered) {
-            me.body.addCls(me.baseCls + '-body-' + me.ui);
+            if (me.bodyCls) {
+                me.body.addCls(me.bodyCls);
+            } else {
+                me.body.addCls(cls);
+            }
+        } else {
+            if (me.bodyCls) {
+                array = me.bodyCls.split(' ');
+
+                if (!Ext.Array.contains(array, cls)) {
+                    array.push(cls);
+                }
+
+                me.bodyCls = array.join(' ');
+            } else {
+                me.bodyCls = cls;
+            }
         }
     },
-    
+
     
     removeUIFromElement: function() {
-        var me = this;
-        
+        var me = this,
+            cls = me.baseCls + '-body-' + me.ui,
+            array;
+
         me.callParent(arguments);
-        
+
         if (me.rendered) {
-            me.body.removeCls(me.baseCls + '-body-' + me.ui);
+            if (me.bodyCls) {
+                me.body.removeCls(me.bodyCls);
+            } else {
+                me.body.removeCls(cls);
+            }
+        } else {
+            if (me.bodyCls) {
+                array = me.bodyCls.split(' ');
+                Ext.Array.remove(array, cls);
+                me.bodyCls = array.join(' ');
+            } else {
+                me.bodyCls = cls;
+            }
         }
     },
 
@@ -32575,7 +33348,7 @@ Ext.define('Ext.panel.AbstractPanel', {
             ln = dockedItems.length,
             i = 0,
             item;
-        
+
         
         for (; i < ln; i++) {
             item = dockedItems[i];
@@ -32583,11 +33356,11 @@ Ext.define('Ext.panel.AbstractPanel', {
                 break;
             }
         }
+
         
         
         
-        
-        return dockedItems.splice(0, i).concat(items).concat(dockedItems);
+        return Ext.Array.splice(dockedItems, 0, i).concat(items).concat(dockedItems);
     },
 
     beforeDestroy: function(){
@@ -32601,7 +33374,7 @@ Ext.define('Ext.panel.AbstractPanel', {
         }
         this.callParent();
     },
-    
+
     setBorder: function(border) {
         var me = this;
         me.border = (border !== undefined) ? border : true;
@@ -32621,10 +33394,20 @@ Ext.define('Ext.panel.Header', {
     indicateDrag   : false,
     weight         : -1,
 
-    renderTpl: ['<div class="{baseCls}-body<tpl if="bodyCls"> {bodyCls}</tpl><tpl if="uiCls"><tpl for="uiCls"> {parent.baseCls}-body-{parent.ui}-{.}</tpl></tpl>"<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>></div>'],
+    renderTpl: [
+        '<div id="{id}-body" class="{baseCls}-body<tpl if="bodyCls"> {bodyCls}</tpl>',
+        '<tpl if="uiCls">',
+            '<tpl for="uiCls"> {parent.baseCls}-body-{parent.ui}-{.}</tpl>',
+        '</tpl>"',
+        '<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>></div>'],
+
+    
+
+    
 
     initComponent: function() {
         var me = this,
+            ruleStyle,
             rule,
             style,
             titleTextEl,
@@ -32642,9 +33425,7 @@ Ext.define('Ext.panel.Header', {
         me.addClsWithUI(me.orientation);
         me.addClsWithUI(me.dock);
 
-        Ext.applyIf(me.renderSelectors, {
-            body: '.' + me.baseCls + '-body'
-        });
+        me.addChildEls('body');
 
         
         if (!Ext.isEmpty(me.iconCls)) {
@@ -32679,7 +33460,11 @@ Ext.define('Ext.panel.Header', {
             if (Ext.isArray(ui)) {
                 ui = ui[0];
             }
-            rule = Ext.util.CSS.getRule('.' + me.baseCls + '-text-' + ui);
+            ruleStyle = '.' + me.baseCls + '-text-' + ui;
+            if (Ext.scopeResetCSS) {
+                ruleStyle = '.' + Ext.baseCSSPrefix + 'reset ' + ruleStyle;
+            }
+            rule = Ext.util.CSS.getRule(ruleStyle);
             if (rule) {
                 style = rule.style;
             }
@@ -32695,9 +33480,12 @@ Ext.define('Ext.panel.Header', {
                 ariaRole  : 'heading',
                 focusable: false,
                 viewBox: false,
+                flex : 1,
                 autoSize: true,
                 margins: '5 0 0 0',
                 items: [ me.textConfig ],
+                
+                
                 renderSelectors: {
                     textEl: '.' + me.baseCls + '-text'
                 }
@@ -32713,28 +33501,22 @@ Ext.define('Ext.panel.Header', {
                 xtype     : 'component',
                 ariaRole  : 'heading',
                 focusable: false,
-                renderTpl : ['<span class="{cls}-text {cls}-text-{ui}">{title}</span>'],
+                flex : 1,
+                cls: me.baseCls + '-text-container',
+                renderTpl : [
+                    '<span id="{id}-textEl" class="{cls}-text {cls}-text-{ui}">{title}</span>'
+                ],
                 renderData: {
                     title: me.title,
                     cls  : me.baseCls,
                     ui   : me.ui
                 },
-                renderSelectors: {
-                    textEl: '.' + me.baseCls + '-text'
-                }
+                childEls: ['textEl']
             });
         }
         me.items.push(me.titleCmp);
 
         
-        me.items.push({
-            xtype: 'component',
-            html : '&nbsp;',
-            flex : 1,
-            focusable: false
-        });
-
-        
         me.items = me.items.concat(me.tools);
         this.callParent();
     },
@@ -32742,16 +33524,16 @@ Ext.define('Ext.panel.Header', {
     initIconCmp: function() {
         this.iconCmp = Ext.create('Ext.Component', {
             focusable: false,
-            renderTpl : ['<img alt="" src="{blank}" class="{cls}-icon {iconCls}"/>'],
+            renderTpl : [
+                '<img id="{id}-iconEl" alt="" src="{blank}" class="{cls}-icon {iconCls}"/>'
+            ],
             renderData: {
                 blank  : Ext.BLANK_IMAGE_URL,
                 cls    : this.baseCls,
                 iconCls: this.iconCls,
                 orientation: this.orientation
             },
-            renderSelectors: {
-                iconEl: '.' + this.baseCls + '-icon'
-            },
+            childEls: ['iconEl'],
             iconCls: this.iconCls
         });
     },
@@ -32782,36 +33564,90 @@ Ext.define('Ext.panel.Header', {
 
     
     addUIClsToElement: function(cls, force) {
-        var me = this;
-
-        me.callParent(arguments);
+        var me = this,
+            result = me.callParent(arguments),
+            classes = [me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls],
+            array, i;
 
         if (!force && me.rendered) {
-            me.body.addCls(me.baseCls + '-body-' + cls);
-            me.body.addCls(me.baseCls + '-body-' + me.ui + '-' + cls);
+            if (me.bodyCls) {
+                me.body.addCls(me.bodyCls);
+            } else {
+                me.body.addCls(classes);
+            }
+        } else {
+            if (me.bodyCls) {
+                array = me.bodyCls.split(' ');
+
+                for (i = 0; i < classes.length; i++) {
+                    if (!Ext.Array.contains(array, classes[i])) {
+                        array.push(classes[i]);
+                    }
+                }
+
+                me.bodyCls = array.join(' ');
+            } else {
+                me.bodyCls = classes.join(' ');
+            }
         }
+
+        return result;
     },
 
     
     removeUIClsFromElement: function(cls, force) {
-        var me = this;
-
-        me.callParent(arguments);
+        var me = this,
+            result = me.callParent(arguments),
+            classes = [me.baseCls + '-body-' + cls, me.baseCls + '-body-' + me.ui + '-' + cls],
+            array, i;
 
         if (!force && me.rendered) {
-            me.body.removeCls(me.baseCls + '-body-' + cls);
-            me.body.removeCls(me.baseCls + '-body-' + me.ui + '-' + cls);
+            if (me.bodyCls) {
+                me.body.removeCls(me.bodyCls);
+            } else {
+                me.body.removeCls(classes);
+            }
+        } else {
+            if (me.bodyCls) {
+                array = me.bodyCls.split(' ');
+
+                for (i = 0; i < classes.length; i++) {
+                    Ext.Array.remove(array, classes[i]);
+                }
+
+                me.bodyCls = array.join(' ');
+            }
         }
+
+       return result;
     },
 
     
     addUIToElement: function(force) {
-        var me = this;
+        var me = this,
+            array, cls;
 
         me.callParent(arguments);
 
+        cls = me.baseCls + '-body-' + me.ui;
         if (!force && me.rendered) {
-            me.body.addCls(me.baseCls + '-body-' + me.ui);
+            if (me.bodyCls) {
+                me.body.addCls(me.bodyCls);
+            } else {
+                me.body.addCls(cls);
+            }
+        } else {
+            if (me.bodyCls) {
+                array = me.bodyCls.split(' ');
+
+                if (!Ext.Array.contains(array, cls)) {
+                    array.push(cls);
+                }
+
+                me.bodyCls = array.join(' ');
+            } else {
+                me.bodyCls = cls;
+            }
         }
 
         if (!force && me.titleCmp && me.titleCmp.rendered && me.titleCmp.textEl) {
@@ -32821,12 +33657,26 @@ Ext.define('Ext.panel.Header', {
 
     
     removeUIFromElement: function() {
-        var me = this;
+        var me = this,
+            array, cls;
 
         me.callParent(arguments);
 
+        cls = me.baseCls + '-body-' + me.ui;
         if (me.rendered) {
-            me.body.removeCls(me.baseCls + '-body-' + me.ui);
+            if (me.bodyCls) {
+                me.body.removeCls(me.bodyCls);
+            } else {
+                me.body.removeCls(cls);
+            }
+        } else {
+            if (me.bodyCls) {
+                array = me.bodyCls.split(' ');
+                Ext.Array.remove(array, cls);
+                me.bodyCls = array.join(' ');
+            } else {
+                me.bodyCls = cls;
+            }
         }
 
         if (me.titleCmp && me.titleCmp.rendered && me.titleCmp.textEl) {
@@ -32889,19 +33739,20 @@ Ext.define('Ext.panel.Header', {
 
     
     setIconCls: function(cls) {
-        this.iconCls = cls;
-        if (!this.iconCmp) {
-            this.initIconCmp();
-            this.insert(0, this.iconCmp);
-        }
-        else {
-            if (!cls || !cls.length) {
-                this.iconCmp.destroy();
-            }
-            else {
-                var iconCmp = this.iconCmp,
-                    el      = iconCmp.iconEl;
-
+        var me = this,
+            isEmpty = !cls || !cls.length,
+            iconCmp = me.iconCmp,
+            el;
+        
+        me.iconCls = cls;
+        if (!me.iconCmp && !isEmpty) {
+            me.initIconCmp();
+            me.insert(0, me.iconCmp);
+        } else if (iconCmp) {
+            if (isEmpty) {
+                me.iconCmp.destroy();
+            } else {
+                el = iconCmp.iconEl;
                 el.removeCls(iconCmp.iconCls);
                 el.addCls(cls);
                 iconCmp.iconCls = cls;
@@ -33629,7 +34480,6 @@ Ext.require('Ext.fx.CubicBezier', function() {
     });
 });
 
-
 Ext.define('Ext.draw.Draw', {
     
 
@@ -33695,10 +34545,16 @@ Ext.define('Ext.draw.Draw', {
         }
     },
 
+    
     path2string: function () {
         return this.join(",").replace(Ext.draw.Draw.pathToStringRE, "$1");
     },
 
+    
+    pathToString: function(arrayPath) {
+        return arrayPath.join(",").replace(Ext.draw.Draw.pathToStringRE, "$1");
+    },
+
     parsePathString: function (pathString) {
         if (!pathString) {
             return null;
@@ -33717,12 +34573,12 @@ Ext.define('Ext.draw.Draw', {
                     b && params.push(+b);
                 });
                 if (name == "m" && params.length > 2) {
-                    data.push([b].concat(params.splice(0, 2)));
+                    data.push([b].concat(Ext.Array.splice(params, 0, 2)));
                     name = "l";
                     b = (b == "m") ? "l" : "L";
                 }
                 while (params.length >= paramCounts[name]) {
-                    data.push([b].concat(params.splice(0, paramCounts[name])));
+                    data.push([b].concat(Ext.Array.splice(params, 0, paramCounts[name])));
                     if (!paramCounts[name]) {
                         break;
                     }
@@ -33753,10 +34609,7 @@ Ext.define('Ext.draw.Draw', {
 
     pathClone: function(pathArray) {
         var res = [],
-            j,
-            jj,
-            i,
-            ii;
+            j, jj, i, ii;
         if (!this.is(pathArray, "array") || !this.is(pathArray && pathArray[0], "array")) { 
             pathArray = this.parsePathString(pathArray);
         }
@@ -33779,80 +34632,93 @@ Ext.define('Ext.draw.Draw', {
             y = 0,
             mx = 0,
             my = 0,
-            start = 0,
-            i,
-            ii,
-            r,
-            pa,
-            j,
-            jj,
-            k,
-            kk;
-        if (pathArray[0][0] == "M") {
+            i = 0,
+            ln = pathArray.length,
+            r, pathSegment, j, ln2;
+        
+        if (ln && pathArray[0][0] == "M") {
             x = +pathArray[0][1];
             y = +pathArray[0][2];
             mx = x;
             my = y;
-            start++;
+            i++;
             res[0] = ["M", x, y];
         }
-        for (i = start, ii = pathArray.length; i < ii; i++) {
+        for (; i < ln; i++) {
             r = res[i] = [];
-            pa = pathArray[i];
-            if (pa[0] != pa[0].toUpperCase()) {
-                r[0] = pa[0].toUpperCase();
+            pathSegment = pathArray[i];
+            if (pathSegment[0] != pathSegment[0].toUpperCase()) {
+                r[0] = pathSegment[0].toUpperCase();
                 switch (r[0]) {
+                    
                     case "A":
-                        r[1] = pa[1];
-                        r[2] = pa[2];
-                        r[3] = pa[3];
-                        r[4] = pa[4];
-                        r[5] = pa[5];
-                        r[6] = +(pa[6] + x);
-                        r[7] = +(pa[7] + y);
+                        r[1] = pathSegment[1];
+                        r[2] = pathSegment[2];
+                        r[3] = pathSegment[3];
+                        r[4] = pathSegment[4];
+                        r[5] = pathSegment[5];
+                        r[6] = +(pathSegment[6] + x);
+                        r[7] = +(pathSegment[7] + y);
                         break;
+                    
                     case "V":
-                        r[1] = +pa[1] + y;
+                        r[1] = +pathSegment[1] + y;
                         break;
+                    
                     case "H":
-                        r[1] = +pa[1] + x;
+                        r[1] = +pathSegment[1] + x;
                         break;
                     case "M":
-                        mx = +pa[1] + x;
-                        my = +pa[2] + y;
+                    
+                        mx = +pathSegment[1] + x;
+                        my = +pathSegment[2] + y;
                     default:
-                        for (j = 1, jj = pa.length; j < jj; j++) {
-                            r[j] = +pa[j] + ((j % 2) ? x : y);
+                        j = 1;
+                        ln2 = pathSegment.length;
+                        for (; j < ln2; j++) {
+                            r[j] = +pathSegment[j] + ((j % 2) ? x : y);
                         }
                 }
-            } else {
-                for (k = 0, kk = pa.length; k < kk; k++) {
-                    res[i][k] = pa[k];
+            }
+            else {
+                j = 0;
+                ln2 = pathSegment.length;
+                for (; j < ln2; j++) {
+                    res[i][j] = pathSegment[j];
                 }
             }
             switch (r[0]) {
+                
                 case "Z":
                     x = mx;
                     y = my;
                     break;
+                
                 case "H":
                     x = r[1];
                     break;
+                
                 case "V":
                     y = r[1];
                     break;
+                
                 case "M":
-                    mx = res[i][res[i].length - 2];
-                    my = res[i][res[i].length - 1];
+                    pathSegment = res[i];
+                    ln2 = pathSegment.length;
+                    mx = pathSegment[ln2 - 2];
+                    my = pathSegment[ln2 - 1];
                 default:
-                    x = res[i][res[i].length - 2];
-                    y = res[i][res[i].length - 1];
+                    pathSegment = res[i];
+                    ln2 = pathSegment.length;
+                    x = pathSegment[ln2 - 2];
+                    y = pathSegment[ln2 - 1];
             }
         }
         res.toString = this.path2string;
         return res;
     },
 
+    
     pathToRelative: function (pathArray) {
         if (!this.is(pathArray, "array") || !this.is(pathArray && pathArray[0], "array")) {
             pathArray = this.parsePathString(pathArray);
@@ -33942,9 +34808,9 @@ Ext.define('Ext.draw.Draw', {
                     points[i].shift();
                     point = points[i];
                     while (point.length) {
-                        points.splice(i++, 0, ["C"].concat(point.splice(0, 6)));
+                        Ext.Array.splice(points, i++, 0, ["C"].concat(Ext.Array.splice(point, 0, 6)));
                     }
-                    points.splice(i, 1);
+                    Ext.Array.erase(points, i, 1);
                     ln = points.length;
                 }
             seg = points[i];
@@ -33968,15 +34834,15 @@ Ext.define('Ext.draw.Draw', {
                     pp[i].shift();
                     var pi = pp[i];
                     while (pi.length) {
-                        pp.splice(i++, 0, ["C"].concat(pi.splice(0, 6)));
+                        Ext.Array.splice(pp, i++, 0, ["C"].concat(Ext.Array.splice(pi, 0, 6)));
                     }
-                    pp.splice(i, 1);
+                    Ext.Array.erase(pp, i, 1);
                     ii = Math.max(p.length, p2.length || 0);
                 }
             },
             fixM = function (path1, path2, a1, a2, i) {
                 if (path1 && path2 && path1[i][0] == "M" && path2[i][0] != "M") {
-                    path2.splice(i, 0, ["M", a2.x, a2.y]);
+                    Ext.Array.splice(path2, i, 0, ["M", a2.x, a2.y]);
                     a1.bx = 0;
                     a1.by = 0;
                     a1.x = path1[i][1];
@@ -34175,27 +35041,8 @@ Ext.define('Ext.draw.Draw', {
             return newres;
         }
     },
-    
-    rotatePoint: function (x, y, alpha, cx, cy) {
-        if (!alpha) {
-            return {
-                x: x,
-                y: y
-            };
-        }
-        cx = cx || 0;
-        cy = cy || 0;
-        x = x - cx;
-        y = y - cy;
-        alpha = alpha * this.radian;
-        var cos = Math.cos(alpha),
-            sin = Math.sin(alpha);
-        return {
-            x: x * cos - y * sin + cx,
-            y: x * sin + y * cos + cy
-        };
-    },
 
+    
     rotateAndTranslatePath: function (sprite) {
         var alpha = sprite.rotation.degrees,
             cx = sprite.rotation.x,
@@ -34232,7 +35079,28 @@ Ext.define('Ext.draw.Draw', {
         }
         return res;
     },
+
     
+    rotatePoint: function (x, y, alpha, cx, cy) {
+        if (!alpha) {
+            return {
+                x: x,
+                y: y
+            };
+        }
+        cx = cx || 0;
+        cy = cy || 0;
+        x = x - cx;
+        y = y - cy;
+        alpha = alpha * this.radian;
+        var cos = Math.cos(alpha),
+            sin = Math.sin(alpha);
+        return {
+            x: x * cos - y * sin + cx,
+            y: x * sin + y * cos + cy
+        };
+    },
+
     pathDimensions: function (path) {
         if (!path || !(path + "")) {
             return {x: 0, y: 0, width: 0, height: 0};
@@ -34242,13 +35110,10 @@ Ext.define('Ext.draw.Draw', {
             y = 0,
             X = [],
             Y = [],
-            p,
-            i,
-            ii,
-            xmin,
-            ymin,
-            dim;
-        for (i = 0, ii = path.length; i < ii; i++) {
+            i = 0,
+            ln = path.length,
+            p, xmin, ymin, dim;
+        for (; i < ln; i++) {
             p = path[i];
             if (p[0] == "M") {
                 x = p[1];
@@ -34274,42 +35139,50 @@ Ext.define('Ext.draw.Draw', {
             height: Math.max.apply(0, Y) - ymin
         };
     },
-    
+
+    intersectInside: function(path, cp1, cp2) {
+        return (cp2[0] - cp1[0]) * (path[1] - cp1[1]) > (cp2[1] - cp1[1]) * (path[0] - cp1[0]);
+    },
+
+    intersectIntersection: function(s, e, cp1, cp2) {
+        var p = [],
+            dcx = cp1[0] - cp2[0],
+            dcy = cp1[1] - cp2[1],
+            dpx = s[0] - e[0],
+            dpy = s[1] - e[1],
+            n1 = cp1[0] * cp2[1] - cp1[1] * cp2[0],
+            n2 = s[0] * e[1] - s[1] * e[0],
+            n3 = 1 / (dcx * dpy - dcy * dpx);
+
+        p[0] = (n1 * dpx - n2 * dcx) * n3;
+        p[1] = (n1 * dpy - n2 * dcy) * n3;
+        return p;
+    },
+
     intersect: function(subjectPolygon, clipPolygon) {
-        var cp1, cp2, s, e, point;
-        var inside = function(p) {
-            return (cp2[0]-cp1[0]) * (p[1]-cp1[1]) > (cp2[1]-cp1[1]) * (p[0]-cp1[0]);
-        };
-        var intersection = function() {
-            var p = [];
-            var dcx = cp1[0]-cp2[0],
-                dcy = cp1[1]-cp2[1],
-                dpx = s[0]-e[0],
-                dpy = s[1]-e[1],
-                n1 = cp1[0]*cp2[1] - cp1[1]*cp2[0],
-                n2 = s[0]*e[1] - s[1]*e[0],
-                n3 = 1 / (dcx*dpy - dcy*dpx);
-
-            p[0] = (n1*dpx - n2*dcx) * n3;
-            p[1] = (n1*dpy - n2*dcy) * n3;
-            return p;
-        };
-        var outputList = subjectPolygon;
-        cp1 = clipPolygon[clipPolygon.length -1];
-        for (var i = 0, l = clipPolygon.length; i < l; ++i) {
+        var me = this,
+            i = 0,
+            ln = clipPolygon.length,
+            cp1 = clipPolygon[ln - 1],
+            outputList = subjectPolygon,
+            cp2, s, e, point, ln2, inputList, j;
+        for (; i < ln; ++i) {
             cp2 = clipPolygon[i];
-            var inputList = outputList;
+            inputList = outputList;
             outputList = [];
-            s = inputList[inputList.length -1];
-            for (var j = 0, ln = inputList.length; j < ln; j++) {
+            s = inputList[inputList.length - 1];
+            j = 0;
+            ln2 = inputList.length;
+            for (; j < ln2; j++) {
                 e = inputList[j];
-                if (inside(e)) {
-                    if (!inside(s)) {
-                        outputList.push(intersection());
+                if (me.intersectInside(e, cp1, cp2)) {
+                    if (!me.intersectInside(s, cp1, cp2)) {
+                        outputList.push(me.intersectIntersection(s, e, cp1, cp2));
                     }
                     outputList.push(e);
-                } else if (inside(s)) {
-                    outputList.push(intersection());
+                }
+                else if (me.intersectInside(s, cp1, cp2)) {
+                    outputList.push(me.intersectIntersection(s, e, cp1, cp2));
                 }
                 s = e;
             }
@@ -34317,7 +35190,7 @@ Ext.define('Ext.draw.Draw', {
         }
         return outputList;
     },
-    
+
     curveDim: function (p1x, p1y, c1x, c1y, c2x, c2y, p2x, p2y) {
         var a = (c2x - 2 * c1x + p1x) - (p2x - 2 * c2x + c1x),
             b = 2 * (c1x - p1x) - 2 * (c2x - c1x),
@@ -34370,27 +35243,74 @@ Ext.define('Ext.draw.Draw', {
         };
     },
 
-    getAnchors: function (p1x, p1y, p2x, p2y, p3x, p3y, value) {
+    
+    getAnchors: function (prevX, prevY, curX, curY, nextX, nextY, value) {
         value = value || 4;
-        var l = Math.min(Math.sqrt(Math.pow(p1x - p2x, 2) + Math.pow(p1y - p2y, 2)) / value, Math.sqrt(Math.pow(p3x - p2x, 2) + Math.pow(p3y - p2y, 2)) / value),
-            a = Math.atan((p2x - p1x) / Math.abs(p2y - p1y)),
-            b = Math.atan((p3x - p2x) / Math.abs(p2y - p3y)),
-            pi = Math.PI;
-        a = p1y < p2y ? pi - a : a;
-        b = p3y < p2y ? pi - b : b;
-        var alpha = pi / 2 - ((a + b) % (pi * 2)) / 2;
-        alpha > pi / 2 && (alpha -= pi);
-        var dx1 = l * Math.sin(alpha + a),
-            dy1 = l * Math.cos(alpha + a),
-            dx2 = l * Math.sin(alpha + b),
-            dy2 = l * Math.cos(alpha + b),
-            out = {
-                x1: p2x - dx1,
-                y1: p2y + dy1,
-                x2: p2x + dx2,
-                y2: p2y + dy2
-            };
-        return out;
+        var M = Math,
+            PI = M.PI,
+            halfPI = PI / 2,
+            abs = M.abs,
+            sin = M.sin,
+            cos = M.cos,
+            atan = M.atan,
+            control1Length, control2Length, control1Angle, control2Angle,
+            control1X, control1Y, control2X, control2Y, alpha;
+
+        
+        
+        control1Length = (curX - prevX) / value;
+        control2Length = (nextX - curX) / value;
+
+        
+        
+        
+        
+        if ((curY >= prevY && curY >= nextY) || (curY <= prevY && curY <= nextY)) {
+            control1Angle = control2Angle = halfPI;
+        } else {
+            control1Angle = atan((curX - prevX) / abs(curY - prevY));
+            if (prevY < curY) {
+                control1Angle = PI - control1Angle;
+            }
+            control2Angle = atan((nextX - curX) / abs(curY - nextY));
+            if (nextY < curY) {
+                control2Angle = PI - control2Angle;
+            }
+        }
+
+        
+        alpha = halfPI - ((control1Angle + control2Angle) % (PI * 2)) / 2;
+        if (alpha > halfPI) {
+            alpha -= PI;
+        }
+        control1Angle += alpha;
+        control2Angle += alpha;
+
+        
+        control1X = curX - control1Length * sin(control1Angle);
+        control1Y = curY + control1Length * cos(control1Angle);
+        control2X = curX + control2Length * sin(control2Angle);
+        control2Y = curY + control2Length * cos(control2Angle);
+
+        
+        
+        
+        
+        if ((curY > prevY && control1Y < prevY) || (curY < prevY && control1Y > prevY)) {
+            control1X += abs(prevY - control1Y) * (control1X - curX) / (control1Y - curY);
+            control1Y = prevY;
+        }
+        if ((curY > nextY && control2Y < nextY) || (curY < nextY && control2Y > nextY)) {
+            control2X -= abs(nextY - control2Y) * (control2X - curX) / (control2Y - curY);
+            control2Y = nextY;
+        }
+        
+        return {
+            x1: control1X,
+            y1: control1Y,
+            x2: control2X,
+            y2: control2Y
+        };
     },
 
     
@@ -34459,7 +35379,11 @@ Ext.define('Ext.draw.Draw', {
         };
     },
 
+    
     snapEnds: function (from, to, stepsMax) {
+        if (Ext.isDate(from)) {
+            return this.snapEndsByDate(from, to, stepsMax);
+        }
         var step = (to - from) / stepsMax,
             level = Math.floor(Math.log(step) / Math.LN10) + 1,
             m = Math.pow(10, level),
@@ -34497,6 +35421,90 @@ Ext.define('Ext.draw.Draw', {
         };
     },
 
+    
+    snapEndsByDate: function (from, to, stepsMax, lockEnds) {
+        var selectedStep = false, scales = [
+                [Ext.Date.MILLI, [1, 2, 3, 5, 10, 20, 30, 50, 100, 200, 300, 500]],
+                [Ext.Date.SECOND, [1, 2, 3, 5, 10, 15, 30]],
+                [Ext.Date.MINUTE, [1, 2, 3, 5, 10, 20, 30]],
+                [Ext.Date.HOUR, [1, 2, 3, 4, 6, 12]],
+                [Ext.Date.DAY, [1, 2, 3, 7, 14]],
+                [Ext.Date.MONTH, [1, 2, 3, 4, 6]]
+            ], j, yearDiff;
+
+        
+        Ext.each(scales, function(scale, i) {
+            for (j = 0; j < scale[1].length; j++) {
+                if (to < Ext.Date.add(from, scale[0], scale[1][j] * stepsMax)) {
+                    selectedStep = [scale[0], scale[1][j]];
+                    return false;
+                }
+            }
+        });
+        if (!selectedStep) {
+            yearDiff = this.snapEnds(from.getFullYear(), to.getFullYear() + 1, stepsMax, lockEnds);
+            selectedStep = [Date.YEAR, Math.round(yearDiff.step)];
+        }
+        return this.snapEndsByDateAndStep(from, to, selectedStep, lockEnds);
+    },
+
+
+    
+    snapEndsByDateAndStep: function(from, to, step, lockEnds) {
+        var fromStat = [from.getFullYear(), from.getMonth(), from.getDate(),
+                from.getHours(), from.getMinutes(), from.getSeconds(), from.getMilliseconds()],
+            steps = 0, testFrom, testTo;
+        if (lockEnds) {
+            testFrom = from;
+        } else {
+            switch (step[0]) {
+                case Ext.Date.MILLI:
+                    testFrom = new Date(fromStat[0], fromStat[1], fromStat[2], fromStat[3],
+                            fromStat[4], fromStat[5], Math.floor(fromStat[6] / step[1]) * step[1]);
+                    break;
+                case Ext.Date.SECOND:
+                    testFrom = new Date(fromStat[0], fromStat[1], fromStat[2], fromStat[3],
+                            fromStat[4], Math.floor(fromStat[5] / step[1]) * step[1], 0);
+                    break;
+                case Ext.Date.MINUTE:
+                    testFrom = new Date(fromStat[0], fromStat[1], fromStat[2], fromStat[3],
+                            Math.floor(fromStat[4] / step[1]) * step[1], 0, 0);
+                    break;
+                case Ext.Date.HOUR:
+                    testFrom = new Date(fromStat[0], fromStat[1], fromStat[2],
+                            Math.floor(fromStat[3] / step[1]) * step[1], 0, 0, 0);
+                    break;
+                case Ext.Date.DAY:
+                    testFrom = new Date(fromStat[0], fromStat[1],
+                            Math.floor(fromStat[2] - 1 / step[1]) * step[1] + 1, 0, 0, 0, 0);
+                    break;
+                case Ext.Date.MONTH:
+                    testFrom = new Date(fromStat[0], Math.floor(fromStat[1] / step[1]) * step[1], 1, 0, 0, 0, 0);
+                    break;
+                default: 
+                    testFrom = new Date(Math.floor(fromStat[0] / step[1]) * step[1], 0, 1, 0, 0, 0, 0);
+                    break;
+            }
+        }
+
+        testTo = testFrom;
+        
+        while (testTo < to) {
+            testTo = Ext.Date.add(testTo, step[0], step[1]);
+            steps++;
+        }
+
+        if (lockEnds) {
+            testTo = to;
+        }
+        return {
+            from : +testFrom,
+            to : +testTo,
+            step : (testTo - testFrom) / steps,
+            steps : steps
+        };
+    },
+
     sorter: function (a, b) {
         return a.offset - b.offset;
     },
@@ -34578,6 +35586,7 @@ Ext.define('Ext.draw.Draw', {
 });
 
 
+
 Ext.define('Ext.fx.PropertyHandler', {
 
     
@@ -34586,23 +35595,25 @@ Ext.define('Ext.fx.PropertyHandler', {
 
     statics: {
         defaultHandler: {
-            pixelDefaults: ['width', 'height', 'top', 'left'],
+            pixelDefaultsRE: /width|height|top$|bottom$|left$|right$/i,
             unitRE: /^(-?\d*\.?\d*){1}(em|ex|px|in|cm|mm|pt|pc|%)*$/,
+            scrollRE: /^scroll/i,
 
             computeDelta: function(from, end, damper, initial, attr) {
                 damper = (typeof damper == 'number') ? damper : 1;
-                var match = this.unitRE.exec(from),
+                var unitRE = this.unitRE,
+                    match = unitRE.exec(from),
                     start, units;
                 if (match) {
                     from = match[1];
                     units = match[2];
-                    if (!units && Ext.Array.contains(this.pixelDefaults, attr)) {
+                    if (!this.scrollRE.test(attr) && !units && this.pixelDefaultsRE.test(attr)) {
                         units = 'px';
                     }
                 }
                 from = +from || 0;
 
-                match = this.unitRE.exec(end);
+                match = unitRE.exec(end);
                 if (match) {
                     end = match[1];
                     units = match[2] || units;
@@ -34918,6 +35929,11 @@ Ext.define('Ext.fx.Anim', {
     
 
     isAnimation: true,
+
+    
+
+    
+
     
     duration: 250,
 
@@ -34972,7 +35988,9 @@ Ext.define('Ext.fx.Anim', {
 
     
     constructor: function(config) {
-        var me = this;
+        var me = this,
+            curve;
+            
         config = config || {};
         
         if (config.keyframes) {
@@ -34992,8 +36010,8 @@ Ext.define('Ext.fx.Anim', {
         if (!me.easingFn) {
             me.easingFn = String(me.easing).match(me.bezierRE);
             if (me.easingFn && me.easingFn.length == 5) {
-                var curve = me.easingFn;
-                me.easingFn = Ext.fx.cubicBezier(+curve[1], +curve[2], +curve[3], +curve[4]);
+                curve = me.easingFn;
+                me.easingFn = Ext.fx.CubicBezier.cubicBezier(+curve[1], +curve[2], +curve[3], +curve[4]);
             }
         }
         me.id = Ext.id(null, 'ext-anim-');
@@ -35148,15 +36166,16 @@ Ext.enableFx = true;
 
 
 
-
 Ext.define('Ext.dd.DragDrop', {
     requires: ['Ext.dd.DragDropManager'],
+
+    
     constructor: function(id, sGroup, config) {
         if(id) {
             this.init(id, sGroup, config);
         }
     },
-    
+
     
 
     
@@ -35325,10 +36344,10 @@ Ext.define('Ext.dd.DragDrop', {
         var b = Ext.get(this.getEl()).getBox(),
             ce = Ext.get(constrainTo),
             s = ce.getScroll(),
-            c, 
+            c,
             cd = ce.dom;
         if(cd == document.body){
-            c = { x: s.left, y: s.top, width: Ext.core.Element.getViewWidth(), height: Ext.core.Element.getViewHeight()};
+            c = { x: s.left, y: s.top, width: Ext.Element.getViewWidth(), height: Ext.Element.getViewHeight()};
         }else{
             var xy = ce.getXY();
             c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight};
@@ -35372,7 +36391,6 @@ Ext.define('Ext.dd.DragDrop', {
 
     
     initTarget: function(id, sGroup, config) {
-
         
         this.config = config || {};
 
@@ -35429,7 +36447,7 @@ Ext.define('Ext.dd.DragDrop', {
         this.onAvailable();
     },
 
-     
+    
     setPadding: function(iTop, iRight, iBot, iLeft) {
         
         if (!iRight && 0 !== iRight) {
@@ -35452,7 +36470,7 @@ Ext.define('Ext.dd.DragDrop', {
         var dx = diffX || 0;
         var dy = diffY || 0;
 
-        var p = Ext.core.Element.getXY( el );
+        var p = Ext.Element.getXY( el );
 
         this.initPageX = p[0] - dx;
         this.initPageY = p[1] - dy;
@@ -35465,7 +36483,7 @@ Ext.define('Ext.dd.DragDrop', {
 
     
     setStartPosition: function(pos) {
-        var p = pos || Ext.core.Element.getXY( this.getEl() );
+        var p = pos || Ext.Element.getXY( this.getEl() );
         this.deltaSetXY = null;
 
         this.startPageX = p[0];
@@ -35788,6 +36806,8 @@ Ext.define('Ext.dd.DragDrop', {
 Ext.define('Ext.dd.DD', {
     extend: 'Ext.dd.DragDrop',
     requires: ['Ext.dd.DragDropManager'],
+
+    
     constructor: function(id, sGroup, config) {
         if (id) {
             this.init(id, sGroup, config);
@@ -35824,7 +36844,7 @@ Ext.define('Ext.dd.DD', {
         var oCoord = this.getTargetCoord(iPageX, iPageY),
             fly = el.dom ? el : Ext.fly(el, '_dd'),
             elSize = fly.getSize(),
-            EL = Ext.core.Element,
+            EL = Ext.Element,
             vpSize;
 
         if (!this.deltaSetXY) {
@@ -35856,7 +36876,7 @@ Ext.define('Ext.dd.DD', {
             this.lastPageX = iPageX;
             this.lastPageY = iPageY;
         } else {
-            var aCoord = Ext.core.Element.getXY(this.getEl());
+            var aCoord = Ext.Element.getXY(this.getEl());
             this.lastPageX = aCoord[0];
             this.lastPageY = aCoord[1];
         }
@@ -35867,10 +36887,10 @@ Ext.define('Ext.dd.DD', {
 
         if (this.scroll) {
             
-            var clientH = Ext.core.Element.getViewHeight();
+            var clientH = Ext.Element.getViewHeight();
 
             
-            var clientW = Ext.core.Element.getViewWidth();
+            var clientW = Ext.Element.getViewWidth();
 
             
             var st = this.DDMInstance.getScrollTop();
@@ -35997,6 +37017,7 @@ Ext.define('Ext.dd.DDProxy', {
         dragElId: "ygddfdiv"
     },
 
+    
     constructor: function(id, sGroup, config) {
         if (id) {
             this.init(id, sGroup, config);
@@ -36145,7 +37166,6 @@ Ext.define('Ext.dd.DragSource', {
     
 
     
-
     dropAllowed : Ext.baseCSSPrefix + 'dd-drop-ok',
     
     dropNotAllowed : Ext.baseCSSPrefix + 'dd-drop-nodrop',
@@ -36156,6 +37176,7 @@ Ext.define('Ext.dd.DragSource', {
     
     repairHighlightColor: 'c3daf9',
 
+    
     constructor: function(el, config) {
         this.el = Ext.get(el);
         if(!this.dragData){
@@ -36480,7 +37501,8 @@ Ext.define('Ext.panel.Panel', {
         'Ext.util.KeyMap',
         'Ext.panel.DD',
         'Ext.XTemplate',
-        'Ext.layout.component.Dock'
+        'Ext.layout.component.Dock',
+        'Ext.util.Memento'
     ],
     alias: 'widget.panel',
     alternateClassName: 'Ext.Panel',
@@ -36514,6 +37536,8 @@ Ext.define('Ext.panel.Panel', {
     floatable: true,
 
     
+
+    
     collapsible: false,
 
     
@@ -36540,32 +37564,54 @@ Ext.define('Ext.panel.Panel', {
 
     
 
+    
+
+    
 
     initComponent: function() {
         var me = this,
             cls;
 
         me.addEvents(
-        
+
+            
+            'beforeclose',
+
+            
+            "beforeexpand",
+
+            
+            "beforecollapse",
+
+            
+            "expand",
+
+            
+            "collapse",
+
+            
             'titlechange',
-        
+
+            
             'iconchange'
         );
 
+        
+        this.addStateEvents('expand', 'collapse');
+
         if (me.unstyled) {
             me.setUI('plain');
         }
 
         if (me.frame) {
-            me.setUI('default-framed');
+            me.setUI(me.ui + '-framed');
         }
 
-        me.callParent();
-
-        me.collapseDirection = me.collapseDirection || me.headerPosition || Ext.Component.DIRECTION_TOP;
-
         
         me.bridgeToolbars();
+
+        me.callParent();
+        me.collapseDirection = me.collapseDirection || me.headerPosition || Ext.Component.DIRECTION_TOP;
     },
 
     setBorder: function(border) {
@@ -36584,7 +37630,7 @@ Ext.define('Ext.panel.Panel', {
         
         
         
-        
+
         this.callParent(arguments);
     },
 
@@ -36647,11 +37693,12 @@ Ext.define('Ext.panel.Panel', {
 
     bridgeToolbars: function() {
         var me = this,
+            docked = [],
             fbar,
             fbarDefaults,
             minButtonWidth = me.minButtonWidth;
 
-        function initToolbar (toolbar, pos) {
+        function initToolbar (toolbar, pos, useButtonAlign) {
             if (Ext.isArray(toolbar)) {
                 toolbar = {
                     xtype: 'toolbar',
@@ -36665,20 +37712,30 @@ Ext.define('Ext.panel.Panel', {
             if (pos == 'left' || pos == 'right') {
                 toolbar.vertical = true;
             }
+
+            
+            if (useButtonAlign) {
+                toolbar.layout = Ext.applyIf(toolbar.layout || {}, {
+                    
+                    pack: { left:'start', center:'center' }[me.buttonAlign] || 'end'
+                });
+            }
             return toolbar;
         }
 
         
 
         
+
+        
         if (me.tbar) {
-            me.addDocked(initToolbar(me.tbar, 'top'));
+            docked.push(initToolbar(me.tbar, 'top'));
             me.tbar = null;
         }
 
         
         if (me.bbar) {
-            me.addDocked(initToolbar(me.bbar, 'bottom'));
+            docked.push(initToolbar(me.bbar, 'bottom'));
             me.bbar = null;
         }
 
@@ -36690,7 +37747,7 @@ Ext.define('Ext.panel.Panel', {
 
         
         if (me.fbar) {
-            fbar = initToolbar(me.fbar, 'bottom');
+            fbar = initToolbar(me.fbar, 'bottom', true); 
             fbar.ui = 'footer';
 
             
@@ -36706,33 +37763,37 @@ Ext.define('Ext.panel.Panel', {
                 };
             }
 
-            fbar = me.addDocked(fbar)[0];
-            fbar.insert(0, {
-                flex: 1,
-                xtype: 'component',
-                focusable: false
-            });
+            docked.push(fbar);
             me.fbar = null;
         }
 
         
         if (me.lbar) {
-            me.addDocked(initToolbar(me.lbar, 'left'));
+            docked.push(initToolbar(me.lbar, 'left'));
             me.lbar = null;
         }
 
         
         if (me.rbar) {
-            me.addDocked(initToolbar(me.rbar, 'right'));
+            docked.push(initToolbar(me.rbar, 'right'));
             me.rbar = null;
         }
+
+        if (me.dockedItems) {
+            if (!Ext.isArray(me.dockedItems)) {
+                me.dockedItems = [me.dockedItems];
+            }
+            me.dockedItems = me.dockedItems.concat(docked);
+        } else {
+            me.dockedItems = docked;
+        }
     },
 
     
     initTools: function() {
         var me = this;
 
-        me.tools = me.tools || [];
+        me.tools = me.tools ? Ext.Array.clone(me.tools) : [];
 
         
         
@@ -36798,28 +37859,21 @@ Ext.define('Ext.panel.Panel', {
         me.updateHeader();
 
         
+        me.callParent(arguments);
+    },
+
+    afterRender: function() {
+        var me = this;
+
+        me.callParent(arguments);
+
+        
+        
         
         if (me.collapsed) {
             me.collapsed = false;
-            topContainer = me.findLayoutController();
-            if (!me.hidden && topContainer) {
-                topContainer.on({
-                    afterlayout: function() {
-                        me.collapse(null, false, true);
-                    },
-                    single: true
-                });
-            } else {
-                me.afterComponentLayout = function() {
-                    delete me.afterComponentLayout;
-                    Ext.getClass(me).prototype.afterComponentLayout.apply(me, arguments);
-                    me.collapse(null, false, true);
-                };
-            }
+            me.collapse(null, false, true);
         }
-
-        
-        me.callParent(arguments);
     },
 
     
@@ -36883,13 +37937,52 @@ Ext.define('Ext.panel.Panel', {
         return this.body || this.frameBody || this.el;
     },
 
+    
+
+    
+    isVisible: function(deep){
+        var me = this;
+        if (me.collapsed && me.placeholder) {
+            return me.placeholder.isVisible(deep);
+        }
+        return me.callParent(arguments);
+    },
+
+    
+    onHide: function(){
+        var me = this;
+        if (me.collapsed && me.placeholder) {
+            me.placeholder.hide();
+        } else {
+            me.callParent(arguments);
+        }
+    },
+
+    
+    onShow: function(){
+        var me = this;
+        if (me.collapsed && me.placeholder) {
+            
+            me.hidden = true;
+            me.placeholder.show();
+        } else {
+            me.callParent(arguments);
+        }
+    },
+
     addTool: function(tool) {
-        this.tools.push(tool);
-        var header = this.header;
+        var me = this,
+            header = me.header;
+
+        if (Ext.isArray(tool)) {
+            Ext.each(tool, me.addTool, me);
+            return;
+        }
+        me.tools.push(tool);
         if (header) {
             header.addTool(tool);
         }
-        this.updateHeader();
+        me.updateHeader();
     },
 
     getOppositeDirection: function(d) {
@@ -36938,7 +38031,6 @@ Ext.define('Ext.panel.Panel', {
             reExpanderOrientation,
             reExpanderDock,
             getDimension,
-            setDimension,
             collapseDimension;
 
         if (!direction) {
@@ -36961,23 +38053,22 @@ Ext.define('Ext.panel.Panel', {
         switch (direction) {
             case c.DIRECTION_TOP:
             case c.DIRECTION_BOTTOM:
-                me.expandedSize = me.getHeight();
                 reExpanderOrientation = 'horizontal';
                 collapseDimension = 'height';
                 getDimension = 'getHeight';
-                setDimension = 'setHeight';
 
                 
                 
-                
                 for (; i < dockedItemCount; i++) {
                     comp = dockedItems[i];
                     if (comp.isVisible()) {
-                        if (comp.isHeader && (!comp.dock || comp.dock == 'top' || comp.dock == 'bottom')) {
+                        if (comp.isXType('header', true) && (!comp.dock || comp.dock == 'top' || comp.dock == 'bottom')) {
                             reExpander = comp;
                         } else {
                             me.hiddenDocked.push(comp);
                         }
+                    } else if (comp === me.reExpander) {
+                        reExpander = comp;
                     }
                 }
 
@@ -36989,15 +38080,12 @@ Ext.define('Ext.panel.Panel', {
 
             case c.DIRECTION_LEFT:
             case c.DIRECTION_RIGHT:
-                me.expandedSize = me.getWidth();
                 reExpanderOrientation = 'vertical';
                 collapseDimension = 'width';
                 getDimension = 'getWidth';
-                setDimension = 'setWidth';
 
                 
                 
-                
                 for (; i < dockedItemCount; i++) {
                     comp = dockedItems[i];
                     if (comp.isVisible()) {
@@ -37006,6 +38094,8 @@ Ext.define('Ext.panel.Panel', {
                         } else {
                             me.hiddenDocked.push(comp);
                         }
+                    } else if (comp === me.reExpander) {
+                        reExpander = comp;
                     }
                 }
 
@@ -37020,12 +38110,6 @@ Ext.define('Ext.panel.Panel', {
         }
 
         
-        
-        me.setAutoScroll(false);
-        me.suspendLayout = true;
-        me.body.setVisibilityMode(Ext.core.Element.DISPLAY);
-
-        
         if (animate && me.collapseTool) {
             me.collapseTool.disable();
         }
@@ -37037,7 +38121,8 @@ Ext.define('Ext.panel.Panel', {
         
 
         
-        if (reExpander) {
+        if (reExpander && reExpander.rendered) {
+
             
             reExpander.addClsWithUI(me.collapsedCls);
             reExpander.addClsWithUI(me.collapsedCls + '-' + reExpander.dock);
@@ -37046,13 +38131,13 @@ Ext.define('Ext.panel.Panel', {
             }
 
             frameInfo = reExpander.getFrameInfo();
-                        
+
             
             newSize = reExpander[getDimension]() + (frameInfo ? frameInfo[direction] : 0);
 
             
             reExpander.removeClsWithUI(me.collapsedCls);
-            reExpander.removeClsWithUI(me.collapsedCls + '-' + reExpander.dock);              
+            reExpander.removeClsWithUI(me.collapsedCls + '-' + reExpander.dock);
             if (me.border && (!me.frame || (me.frame && Ext.supports.CSS3BorderRadius))) {
                 reExpander.removeClsWithUI(me.collapsedCls + '-border-' + reExpander.dock);
             }
@@ -37075,12 +38160,14 @@ Ext.define('Ext.panel.Panel', {
                 cls: me.baseCls + '-collapsed-placeholder ' + ' ' + Ext.baseCSSPrefix + 'docked ' + me.baseCls + '-' + me.ui + '-collapsed',
                 renderTo: me.el
             };
-            reExpander[(reExpander.orientation == 'horizontal') ? 'tools' : 'items'] = [{
-                xtype: 'tool',
-                type: 'expand-' + me.expandDirection,
-                handler: me.toggleCollapse,
-                scope: me
-            }];
+            if (!me.hideCollapseTool) {
+                reExpander[(reExpander.orientation == 'horizontal') ? 'tools' : 'items'] = [{
+                    xtype: 'tool',
+                    type: 'expand-' + me.expandDirection,
+                    handler: me.toggleCollapse,
+                    scope: me
+                }];
+            }
 
             
             
@@ -37110,12 +38197,21 @@ Ext.define('Ext.panel.Panel', {
         anim.to[collapseDimension] = newSize;
 
         
+        
+        
+        
+        
+        if (!me.collapseMemento) {
+            me.collapseMemento = new Ext.util.Memento(me);
+        }
+        me.collapseMemento.capture(['width', 'height', 'minWidth', 'minHeight', 'layoutManagedHeight', 'layoutManagedWidth']);
+
+        
         me.savedFlex = me.flex;
-        me.savedMinWidth = me.minWidth;
-        me.savedMinHeight = me.minHeight;
         me.minWidth = 0;
         me.minHeight = 0;
         delete me.flex;
+        me.suspendLayout = true;
 
         if (animate) {
             me.animate(anim);
@@ -37134,10 +38230,24 @@ Ext.define('Ext.panel.Panel', {
             i = 0,
             l = me.hiddenDocked.length;
 
-        me.minWidth = me.savedMinWidth;
-        me.minHeight = me.savedMinHeight;
+        me.collapseMemento.restore(['minWidth', 'minHeight']);
+
+        
+        
+        
+        if (Ext.Component.VERTICAL_DIRECTION_Re.test(me.expandDirection)) {
+            me.layoutManagedHeight = 2;
+            me.collapseMemento.restore('width', false);
+        } else {
+            me.layoutManagedWidth = 2;
+            me.collapseMemento.restore('height', false);
+        }
+
+        
+        
+        me.saveScrollTop = me.body.dom.scrollTop;
+        me.body.setStyle('display', 'none');
 
-        me.body.hide();
         for (; i < l; i++) {
             me.hiddenDocked[i].hide();
         }
@@ -37146,9 +38256,18 @@ Ext.define('Ext.panel.Panel', {
             me.reExpander.show();
         }
         me.collapsed = true;
+        me.suspendLayout = false;
 
         if (!internal) {
-            me.doComponentLayout();
+            if (me.ownerCt) {
+                
+                
+                if (animated) {
+                    me.ownerCt.layout.layout();
+                }
+            } else if (me.reExpander.temporary) {
+                me.doComponentLayout();
+            }
         }
 
         if (me.resizer) {
@@ -37171,16 +38290,17 @@ Ext.define('Ext.panel.Panel', {
 
     
     expand: function(animate) {
-        if (!this.collapsed || this.fireEvent('beforeexpand', this, animate) === false) {
+        var me = this;
+        if (!me.collapsed || me.fireEvent('beforeexpand', me, animate) === false) {
             return false;
         }
-        var me = this,
-            i = 0,
+
+        var i = 0,
             l = me.hiddenDocked.length,
             direction = me.expandDirection,
             height = me.getHeight(),
             width = me.getWidth(),
-            pos, anim, satisfyJSLint;
+            pos, anim;
 
         
         if (animate && me.collapseTool) {
@@ -37212,10 +38332,11 @@ Ext.define('Ext.panel.Panel', {
         }
 
         
-        me.collapsed = false;
+        me.body.setStyle('display', '');
+        me.body.dom.scrollTop = me.saveScrollTop;
 
         
-        me.body.show();
+        me.collapsed = false;
 
         
         me.removeClsWithUI(me.collapsedCls);
@@ -37239,7 +38360,11 @@ Ext.define('Ext.panel.Panel', {
         if ((direction == Ext.Component.DIRECTION_TOP) || (direction == Ext.Component.DIRECTION_BOTTOM)) {
 
             
-            if (me.autoHeight) {
+            
+            me.collapseMemento.restore('height', false);
+
+            
+            if (me.height === undefined) {
                 me.setCalculatedSize(me.width, null);
                 anim.to.height = me.getHeight();
 
@@ -37255,7 +38380,7 @@ Ext.define('Ext.panel.Panel', {
             }
             
             else {
-                anim.to.height = me.expandedSize;
+                anim.to.height = me.height;
             }
 
             
@@ -37267,7 +38392,11 @@ Ext.define('Ext.panel.Panel', {
         } else if ((direction == Ext.Component.DIRECTION_LEFT) || (direction == Ext.Component.DIRECTION_RIGHT)) {
 
             
-            if (me.autoWidth) {
+            
+            me.collapseMemento.restore('width', false);
+
+            
+            if (me.width === undefined) {
                 me.setCalculatedSize(null, me.height);
                 anim.to.width = me.getWidth();
 
@@ -37283,7 +38412,7 @@ Ext.define('Ext.panel.Panel', {
             }
             
             else {
-                anim.to.width = me.expandedSize;
+                anim.to.width = me.width;
             }
 
             
@@ -37297,7 +38426,7 @@ Ext.define('Ext.panel.Panel', {
         if (animate) {
             me.animate(anim);
         } else {
-            me.setSize(anim.to.width, anim.to.height);
+            me.setCalculatedSize(anim.to.width, anim.to.height);
             if (anim.to.x) {
                 me.setLeft(anim.to.x);
             }
@@ -37312,7 +38441,6 @@ Ext.define('Ext.panel.Panel', {
 
     afterExpand: function(animated) {
         var me = this;
-        me.setAutoScroll(me.initialConfig.autoScroll);
 
         
         if (me.savedFlex) {
@@ -37323,9 +38451,14 @@ Ext.define('Ext.panel.Panel', {
         }
 
         
-        delete me.suspendLayout;
+        if (me.collapseMemento) {
+            me.collapseMemento.restoreAll();
+        }
+
         if (animated && me.ownerCt) {
-            me.ownerCt.doLayout();
+            
+            
+            Ext.defer(me.ownerCt.doLayout, Ext.isIE6 ? 1 : 0, me);
         }
 
         if (me.resizer) {
@@ -37367,10 +38500,10 @@ Ext.define('Ext.panel.Panel', {
     
     ghostTools : function() {
         var tools = [],
-            origTools = this.initialConfig.tools;
+            headerTools = this.header.query('tool[hidden=false]');
 
-        if (origTools) {
-            Ext.each(origTools, function(tool) {
+        if (headerTools.length) {
+            Ext.each(headerTools, function(tool) {
                 
                 
                 
@@ -37379,8 +38512,7 @@ Ext.define('Ext.panel.Panel', {
                     type: tool.type
                 });
             });
-        }
-        else {
+        } else {
             tools = [{
                 type: 'placeholder'
             }];
@@ -37392,23 +38524,19 @@ Ext.define('Ext.panel.Panel', {
     ghost: function(cls) {
         var me = this,
             ghostPanel = me.ghostPanel,
-            box = me.getBox();
+            box = me.getBox(),
+            header;
 
         if (!ghostPanel) {
             ghostPanel = Ext.create('Ext.panel.Panel', {
-                renderTo: document.body,
+                renderTo: me.floating ? me.el.dom.parentNode : document.body,
                 floating: {
                     shadow: false
                 },
                 frame: Ext.supports.CSS3BorderRadius ? me.frame : false,
-                title: me.title,
                 overlapHeader: me.overlapHeader,
                 headerPosition: me.headerPosition,
-                width: me.getWidth(),
-                height: me.getHeight(),
-                iconCls: me.iconCls,
                 baseCls: me.baseCls,
-                tools: me.ghostTools(),
                 cls: me.baseCls + '-ghost ' + (cls ||'')
             });
             me.ghostPanel = ghostPanel;
@@ -37419,6 +38547,19 @@ Ext.define('Ext.panel.Panel', {
         } else {
             ghostPanel.toFront();
         }
+        header = ghostPanel.header;
+        
+        if (header) {
+            header.suspendLayout = true;
+            Ext.Array.forEach(header.query('tool'), function(tool){
+                header.remove(tool);
+            });
+            header.suspendLayout = false;
+        }
+        ghostPanel.addTool(me.ghostTools());
+        ghostPanel.setTitle(me.title);
+        ghostPanel.setIconCls(me.iconCls);
+
         ghostPanel.el.show();
         ghostPanel.setPosition(box.x, box.y);
         ghostPanel.setSize(box.width, box.height);
@@ -37454,6 +38595,8 @@ Ext.define('Ext.panel.Panel', {
         }
         this.callParent([resizable]);
     }
+}, function(){
+    this.prototype.animCollapse = Ext.enableFx;
 });
 
 
@@ -37562,21 +38705,25 @@ Ext.define('Ext.tip.Tip', {
     focusOnToFront: false,
     componentLayout: 'tip',
 
+    
     closeAction: 'hide',
 
     ariaRole: 'tooltip',
 
     initComponent: function() {
-        this.callParent(arguments);
+        var me = this;
+
+        me.floating = Ext.apply({}, {shadow: me.shadow}, me.self.prototype.floating);
+        me.callParent(arguments);
 
         
-        this.constrain = this.constrain || this.constrainPosition;
+        me.constrain = me.constrain || me.constrainPosition;
     },
 
     
     showAt : function(xy){
         var me = this;
-        this.callParent();
+        this.callParent(arguments);
         
         if (me.isVisible()) {
             me.setPagePosition(xy[0], xy[1]);
@@ -37599,7 +38746,7 @@ Ext.define('Ext.tip.Tip', {
             el: me.getDragEl(),
             delegate: me.header.el,
             constrain: me,
-            constrainTo: me.el.dom.parentNode
+            constrainTo: me.el.getScopeParent()
         };
         
         Ext.Component.prototype.initDraggable.call(me);
@@ -37664,7 +38811,7 @@ Ext.define('Ext.tip.ToolTip', {
 
         me.callParent(arguments);
         zIndex = parseInt(me.el.getZIndex(), 10) || 0;
-        me.anchorEl.setStyle('z-index', zIndex + 1).setVisibilityMode(Ext.core.Element.DISPLAY);
+        me.anchorEl.setStyle('z-index', zIndex + 1).setVisibilityMode(Ext.Element.DISPLAY);
     },
 
     
@@ -37679,10 +38826,10 @@ Ext.define('Ext.tip.ToolTip', {
             me.mun(tg, 'mouseout', me.onTargetOut, me);
             me.mun(tg, 'mousemove', me.onMouseMove, me);
         }
-        
+
         me.target = t;
         if (t) {
-            
+
             me.mon(t, {
                 
                 
@@ -37710,7 +38857,7 @@ Ext.define('Ext.tip.ToolTip', {
                 if (!me.hidden && me.trackMouse) {
                     xy = me.getTargetXY();
                     if (me.constrainPosition) {
-                        xy = me.el.adjustForConstraints(xy, me.el.dom.parentNode);
+                        xy = me.el.adjustForConstraints(xy, me.el.getScopeParent());
                     }
                     me.setPagePosition(xy);
                 }
@@ -37735,8 +38882,8 @@ Ext.define('Ext.tip.ToolTip', {
             me.targetCounter++;
                 var offsets = me.getOffsets(),
                     xy = (me.anchorToTarget && !me.trackMouse) ? me.el.getAlignToXY(me.anchorTarget, me.getAnchorAlign()) : me.targetXY,
-                    dw = Ext.core.Element.getViewWidth() - 5,
-                    dh = Ext.core.Element.getViewHeight() - 5,
+                    dw = Ext.Element.getViewWidth() - 5,
+                    dh = Ext.Element.getViewHeight() - 5,
                     de = document.documentElement,
                     bd = document.body,
                     scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5,
@@ -37818,9 +38965,6 @@ Ext.define('Ext.tip.ToolTip', {
             me.tipAnchor = me.anchor.charAt(0);
         } else {
             m = me.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);
-            if (!m) {
-                Ext.Error.raise('The AnchorTip.defaultAlign value "' + me.defaultAlign + '" is invalid.');
-            }
             me.tipAnchor = m[1].charAt(0);
         }
 
@@ -38151,7 +39295,7 @@ Ext.define('Ext.tip.QuickTip', {
     
     initComponent : function(){
         var me = this;
-        
+
         me.target = me.target || Ext.getDoc();
         me.targets = me.targets || {};
         me.callParent();
@@ -38163,7 +39307,7 @@ Ext.define('Ext.tip.QuickTip', {
             i = 0,
             len = configs.length,
             target, j, targetLen;
-            
+
         for (; i < len; i++) {
             config = configs[i];
             target = config.target;
@@ -38183,12 +39327,12 @@ Ext.define('Ext.tip.QuickTip', {
     unregister : function(el){
         delete this.targets[Ext.id(el)];
     },
-    
+
     
     cancelShow: function(el){
         var me = this,
             activeTarget = me.activeTarget;
-            
+
         el = Ext.get(el).dom;
         if (me.isVisible()) {
             if (activeTarget && activeTarget.el == el) {
@@ -38198,26 +39342,31 @@ Ext.define('Ext.tip.QuickTip', {
             me.clearTimer('show');
         }
     },
+
     
     getTipCfg: function(e) {
         var t = e.getTarget(),
-            ttp, 
+            titleText = t.title,
             cfg;
-        
-        if(this.interceptTitles && t.title && Ext.isString(t.title)){
-            ttp = t.title;
-            t.qtip = ttp;
+
+        if (this.interceptTitles && titleText && Ext.isString(titleText)) {
+            t.qtip = titleText;
             t.removeAttribute("title");
             e.preventDefault();
-        } 
-        else {            
+            return {
+                text: titleText
+            };
+        }
+        else {
             cfg = this.tagConfig;
             t = e.getTarget('[' + cfg.namespace + cfg.attribute + ']');
             if (t) {
-                ttp = t.getAttribute(cfg.namespace + cfg.attribute);
+                return {
+                    target: t,
+                    text: t.getAttribute(cfg.namespace + cfg.attribute)
+                };
             }
         }
-        return ttp;
     },
 
     
@@ -38227,9 +39376,9 @@ Ext.define('Ext.tip.QuickTip', {
             elTarget,
             cfg,
             ns,
-            ttp,
+            tipConfig,
             autoHide;
-        
+
         if (me.disabled) {
             return;
         }
@@ -38242,13 +39391,13 @@ Ext.define('Ext.tip.QuickTip', {
         if(!target || target.nodeType !== 1 || target == document || target == document.body){
             return;
         }
-        
+
         if (me.activeTarget && ((target == me.activeTarget.el) || Ext.fly(me.activeTarget.el).contains(target))) {
             me.clearTimer('hide');
             me.show();
             return;
         }
-        
+
         if (target) {
             Ext.Object.each(me.targets, function(key, value) {
                 var targetEl = Ext.fly(value.target);
@@ -38271,21 +39420,28 @@ Ext.define('Ext.tip.QuickTip', {
 
         elTarget = Ext.get(target);
         cfg = me.tagConfig;
-        ns = cfg.namespace; 
-        ttp = me.getTipCfg(e);
-        
-        if (ttp) {
+        ns = cfg.namespace;
+        tipConfig = me.getTipCfg(e);
+
+        if (tipConfig) {
+
+            
+            
+            if (tipConfig.target) {
+                target = tipConfig.target;
+                elTarget = Ext.get(target);
+            }
             autoHide = elTarget.getAttribute(ns + cfg.hide);
-                 
+
             me.activeTarget = {
                 el: target,
-                text: ttp,
+                text: tipConfig.text,
                 width: +elTarget.getAttribute(ns + cfg.width) || null,
                 autoHide: autoHide != "user" && autoHide !== 'false',
                 title: elTarget.getAttribute(ns + cfg.title),
                 cls: elTarget.getAttribute(ns + cfg.cls),
                 align: elTarget.getAttribute(ns + cfg.align)
-                
+
             };
             me.anchor = elTarget.getAttribute(ns + cfg.anchor);
             if (me.anchor) {
@@ -38298,7 +39454,7 @@ Ext.define('Ext.tip.QuickTip', {
     
     onTargetOut : function(e){
         var me = this;
-        
+
         
         if (me.activeTarget && e.within(me.activeTarget.el) && !me.getTipCfg(e)) {
             return;
@@ -38314,7 +39470,7 @@ Ext.define('Ext.tip.QuickTip', {
     showAt : function(xy){
         var me = this,
             target = me.activeTarget;
-        
+
         if (target) {
             if (!me.rendered) {
                 me.render(Ext.getBody());
@@ -38339,7 +39495,7 @@ Ext.define('Ext.tip.QuickTip', {
             }
 
             me.setWidth(target.width);
-            
+
             if (me.anchor) {
                 me.constrainPosition = false;
             } else if (target.align) { 
@@ -38368,8 +39524,9 @@ Ext.define('Ext.tip.QuickTipManager', function() {
         requires: ['Ext.tip.QuickTip'],
         singleton: true,
         alternateClassName: 'Ext.QuickTips',
+
         
-        init : function(autoRender){
+        init : function (autoRender, config) {
             if (!tip) {
                 if (!Ext.isReady) {
                     Ext.onReady(function(){
@@ -38377,10 +39534,24 @@ Ext.define('Ext.tip.QuickTipManager', function() {
                     });
                     return;
                 }
-                tip = Ext.create('Ext.tip.QuickTip', {
-                    disabled: disabled,
-                    renderTo: autoRender !== false ? document.body : undefined
-                });
+
+                var tipConfig = Ext.apply({ disabled: disabled }, config),
+                    className = tipConfig.className,
+                    xtype = tipConfig.xtype;
+
+                if (className) {
+                    delete tipConfig.className;
+                } else if (xtype) {
+                    className = 'widget.' + xtype;
+                    delete tipConfig.xtype;
+                }
+
+                if (autoRender !== false) {
+                    tipConfig.renderTo = document.body;
+
+                }
+
+                tip = Ext.create(className || 'Ext.tip.QuickTip', tipConfig);
             }
         },
 
@@ -38478,8 +39649,9 @@ Ext.define('Ext.app.Application', {
     appFolder: 'app',
 
     
-    autoCreateViewport: true,
+    autoCreateViewport: false,
 
+    
     constructor: function(config) {
         config = config || {};
         Ext.apply(this, config);
@@ -38498,8 +39670,8 @@ Ext.define('Ext.app.Application', {
 
         this.eventbus = Ext.create('Ext.app.EventBus');
 
-        var controllers = this.controllers,
-            ln = controllers.length,
+        var controllers = Ext.Array.from(this.controllers),
+            ln = controllers && controllers.length,
             i, controller;
 
         this.controllers = Ext.create('Ext.util.MixedCollection');
@@ -38825,7 +39997,7 @@ Ext.define('Ext.draw.CompositeSprite', {
             mouseout: me.onMouseOut,
             click: me.onClick
         });
-        me.callParent(arguments);
+        return me.callParent(arguments);
     },
     
     
@@ -38874,25 +40046,25 @@ Ext.define('Ext.draw.CompositeSprite', {
     },
 
     
-    hide: function(attrs) {
+    hide: function(redraw) {
         var i = 0,
             items = this.items,
             len = this.length;
             
         for (; i < len; i++) {
-            items[i].hide();
+            items[i].hide(redraw);
         }
         return this;
     },
 
     
-    show: function(attrs) {
+    show: function(redraw) {
         var i = 0,
             items = this.items,
             len = this.length;
             
         for (; i < len; i++) {
-            items[i].show();
+            items[i].show(redraw);
         }
         return this;
     },
@@ -38981,21 +40153,20 @@ Ext.define('Ext.draw.CompositeSprite', {
 
 
 
-Ext.define('Ext.layout.component.Draw', {
+Ext.define('Ext.layout.component.Auto', {
 
     
 
-    alias: 'layout.draw',
+    alias: 'layout.autocomponent',
 
-    extend: 'Ext.layout.component.Auto',
+    extend: 'Ext.layout.component.Component',
 
     
 
-    type: 'draw',
+    type: 'autocomponent',
 
     onLayout : function(width, height) {
-        this.owner.surface.setSize(width, height);
-        this.callParent(arguments);
+        this.setTargetSize(width, height);
     }
 });
 
@@ -39031,7 +40202,6 @@ Ext.define('Ext.chart.theme.Theme', {
                     return;
                 }
             }
-            Ext.Error.raise('No theme found named "' + theme + '"');
         }
     }
 }, 
@@ -39135,6 +40305,8 @@ function() {
 
 
 Ext.define('Ext.chart.Mask', {
+    require: ['Ext.chart.MaskLayer'],
+    
     constructor: function(config) {
         var me = this;
 
@@ -39277,12 +40449,7 @@ Ext.define('Ext.chart.Mask', {
                 width: abs(width),
                 height: abs(height)
             };
-            me.mask.updateBox({
-                x: posX - abs(width),
-                y: posY - abs(height),
-                width: abs(width),
-                height: abs(height)
-            });
+            me.mask.updateBox(me.maskSelection);
             me.mask.show();
             me.maskSprite.setAttributes({
                 hidden: true    
@@ -39323,50 +40490,46 @@ Ext.define('Ext.chart.Navigation', {
     constructor: function() {
         this.originalStore = this.store;
     },
-    
+
     
     setZoom: function(zoomConfig) {
         var me = this,
-            store = me.substore || me.store,
+            axes = me.axes,
             bbox = me.chartBBox,
-            len = store.getCount(),
-            from = (zoomConfig.x / bbox.width * len) >> 0,
-            to = Math.ceil(((zoomConfig.x + zoomConfig.width) / bbox.width * len)),
-            recFieldsLen, recFields = [], curField, json = [], obj;
-        
-        store.each(function(rec, i) {
-            if (i < from || i > to) {
-                return;
-            }
-            obj = {};
-            
-            if (!recFields.length) {
-                rec.fields.each(function(f) {
-                    recFields.push(f.name);
-                });
-                recFieldsLen = recFields.length;
-            }
-            
-            for (i = 0; i < recFieldsLen; i++) {
-                curField = recFields[i];
-                obj[curField] = rec.get(curField);
+            xScale = 1 / bbox.width,
+            yScale = 1 / bbox.height,
+            zoomer = {
+                x : zoomConfig.x * xScale,
+                y : zoomConfig.y * yScale,
+                width : zoomConfig.width * xScale,
+                height : zoomConfig.height * yScale
+            };
+        axes.each(function(axis) {
+            var ends = axis.calcEnds();
+            if (axis.position == 'bottom' || axis.position == 'top') {
+                var from = (ends.to - ends.from) * zoomer.x + ends.from,
+                    to = (ends.to - ends.from) * zoomer.width + from;
+                axis.minimum = from;
+                axis.maximum = to;
+            } else {
+                var to = (ends.to - ends.from) * (1 - zoomer.y) + ends.from,
+                    from = to - (ends.to - ends.from) * zoomer.height;
+                axis.minimum = from;
+                axis.maximum = to;
             }
-            json.push(obj);
-        });
-        me.store = me.substore = Ext.create('Ext.data.JsonStore', {
-            fields: recFields,
-            data: json
         });
-        me.redraw(true);
+        me.redraw(false);
     },
 
+    
     restoreZoom: function() {
         this.store = this.substore = this.originalStore;
         this.redraw(true);
     }
-    
+
 });
 
+
 Ext.define('Ext.chart.Shape', {
 
     
@@ -39547,21 +40710,27 @@ Ext.define('Ext.draw.Surface', {
         zIndex: 0
     },
 
+    
+    
+
     container: undefined,
     height: 352,
     width: 512,
     x: 0,
     y: 0,
 
+    
+    orderSpritesByZIndex: true,
+
+
+    
     constructor: function(config) {
         var me = this;
         config = config || {};
         Ext.apply(me, config);
 
         me.domRef = Ext.getDoc().dom;
-        
+
         me.customAttributes = {};
 
         me.addEvents(
@@ -39599,7 +40768,12 @@ Ext.define('Ext.draw.Surface', {
     renderItems: Ext.emptyFn,
 
     
-    setViewBox: Ext.emptyFn,
+    setViewBox: function (x, y, width, height) {
+        if (isFinite(x) && isFinite(y) && isFinite(width) && isFinite(height)) {
+            this.viewBox = {x: x, y: y, width: width, height: height};
+            this.applyViewBox();
+        }
+    },
 
     
     addCls: Ext.emptyFn,
@@ -39627,20 +40801,19 @@ Ext.define('Ext.draw.Surface', {
             this.add(items);
         }
     },
-    
+
     
     initBackground: function(config) {
-        var gradientId, 
-            gradient,
-            backgroundSprite,
-            width = this.width,
-            height = this.height;
+        var me = this,
+            width = me.width,
+            height = me.height,
+            gradientId, gradient, backgroundSprite;
         if (config) {
             if (config.gradient) {
                 gradient = config.gradient;
                 gradientId = gradient.id;
-                this.addGradient(gradient);
-                this.background = this.add({
+                me.addGradient(gradient);
+                me.background = me.add({
                     type: 'rect',
                     x: 0,
                     y: 0,
@@ -39649,7 +40822,7 @@ Ext.define('Ext.draw.Surface', {
                     fill: 'url(#' + gradientId + ')'
                 });
             } else if (config.fill) {
-                this.background = this.add({
+                me.background = me.add({
                     type: 'rect',
                     x: 0,
                     y: 0,
@@ -39658,7 +40831,7 @@ Ext.define('Ext.draw.Surface', {
                     fill: config.fill
                 });
             } else if (config.image) {
-                this.background = this.add({
+                me.background = me.add({
                     type: 'image',
                     x: 0,
                     y: 0,
@@ -39669,7 +40842,7 @@ Ext.define('Ext.draw.Surface', {
             }
         }
     },
-    
+
     
     setSize: function(w, h) {
         if (this.background) {
@@ -39679,6 +40852,7 @@ Ext.define('Ext.draw.Surface', {
                 hidden: false
             }, true);
         }
+        this.applyViewBox();
     },
 
     
@@ -39687,7 +40861,7 @@ Ext.define('Ext.draw.Surface', {
             attrs = {},
             exclude = {},
             sattr = sprite.attr;
-        for (i in sattr) {    
+        for (i in sattr) {
             
             if (this.translateAttrs.hasOwnProperty(i)) {
                 
@@ -39762,28 +40936,45 @@ Ext.define('Ext.draw.Surface', {
             return results;
         }
         sprite = this.prepareItems(args[0], true)[0];
-        this.normalizeSpriteCollection(sprite);
+        this.insertByZIndex(sprite);
         this.onAdd(sprite);
         return sprite;
     },
 
     
-    normalizeSpriteCollection: function(sprite) {
-        var items = this.items,
+    insertByZIndex: function(sprite) {
+        var me = this,
+            sprites = me.items.items,
+            len = sprites.length,
+            ceil = Math.ceil,
             zIndex = sprite.attr.zIndex,
-            idx = items.indexOf(sprite);
+            idx = len,
+            high = idx - 1,
+            low = 0,
+            otherZIndex;
 
-        if (idx < 0 || (idx > 0 && items.getAt(idx - 1).attr.zIndex > zIndex) ||
-                (idx < items.length - 1 && items.getAt(idx + 1).attr.zIndex < zIndex)) {
-            items.removeAt(idx);
-            idx = items.findIndexBy(function(otherSprite) {
-                return otherSprite.attr.zIndex > zIndex;
-            });
-            if (idx < 0) {
-                idx = items.length;
+        if (me.orderSpritesByZIndex && len && zIndex < sprites[high].attr.zIndex) {
+            
+            while (low <= high) {
+                idx = ceil((low + high) / 2);
+                otherZIndex = sprites[idx].attr.zIndex;
+                if (otherZIndex > zIndex) {
+                    high = idx - 1;
+                }
+                else if (otherZIndex < zIndex) {
+                    low = idx + 1;
+                }
+                else {
+                    break;
+                }
+            }
+            
+            while (idx < len && sprites[idx].attr.zIndex <= zIndex) {
+                idx++;
             }
-            items.insert(idx, sprite);
         }
+
+        me.items.insert(idx, sprite);
         return idx;
     },
 
@@ -39834,6 +41025,49 @@ Ext.define('Ext.draw.Surface', {
     onDestroy: Ext.emptyFn,
 
     
+    applyViewBox: function() {
+        var me = this,
+            viewBox = me.viewBox,
+            width = me.width,
+            height = me.height,
+            viewBoxX, viewBoxY, viewBoxWidth, viewBoxHeight,
+            relativeHeight, relativeWidth, size;
+
+        if (viewBox && (width || height)) {
+            viewBoxX = viewBox.x;
+            viewBoxY = viewBox.y;
+            viewBoxWidth = viewBox.width;
+            viewBoxHeight = viewBox.height;
+            relativeHeight = height / viewBoxHeight;
+            relativeWidth = width / viewBoxWidth;
+
+            if (viewBoxWidth * relativeHeight < width) {
+                viewBoxX -= (width - viewBoxWidth * relativeHeight) / 2 / relativeHeight;
+            }
+            if (viewBoxHeight * relativeWidth < height) {
+                viewBoxY -= (height - viewBoxHeight * relativeWidth) / 2 / relativeWidth;
+            }
+
+            size = 1 / Math.min(viewBoxWidth, relativeHeight);
+
+            me.viewBoxShift = {
+                dx: -viewBoxX,
+                dy: -viewBoxY,
+                scale: size
+            };
+        }
+    },
+
+    transformToViewBox: function (x, y) {
+        if (this.viewBoxShift) {
+            var me = this, shift = me.viewBoxShift;
+            return [x * shift.scale - shift.dx, y * shift.scale - shift.dy];
+        } else {
+            return [x, y];
+        }
+    },
+
+    
     applyTransformations: function(sprite) {
             sprite.bbox.transform = 0;
             this.transform(sprite);
@@ -39943,7 +41177,9 @@ Ext.define('Ext.draw.Surface', {
     
     getPathellipse: function (el) {
         var a = el.attr;
-        return this.ellipsePath(a.x, a.y, a.radiusX, a.radiusY);
+        return this.ellipsePath(a.x, a.y,
+                                a.radiusX || (a.width / 2) || 0,
+                                a.radiusY || (a.height / 2) || 0);
     },
 
     
@@ -40006,10 +41242,10 @@ Ext.define('Ext.draw.Surface', {
         }
         return items;
     },
-    
+
     
     setText: Ext.emptyFn,
-    
+
     //@private Creates an item and appends it to the surface. Called
 
     
@@ -40027,6 +41263,25 @@ Ext.define('Ext.draw.Surface', {
     }
 });
 
+
+Ext.define('Ext.layout.component.Draw', {
+
+    
+
+    alias: 'layout.draw',
+
+    extend: 'Ext.layout.component.Auto',
+
+    
+
+    type: 'draw',
+
+    onLayout : function(width, height) {
+        this.owner.surface.setSize(width, height);
+        this.callParent(arguments);
+    }
+});
+
 Ext.define('Ext.draw.Component', {
 
     
@@ -40054,9 +41309,8 @@ Ext.define('Ext.draw.Component', {
 
     
     autoSize: false,
-    
-    
 
+    
     initComponent: function() {
         this.callParent(arguments);
 
@@ -40078,22 +41332,22 @@ Ext.define('Ext.draw.Component', {
             bbox, items, width, height, x, y;
         me.callParent(arguments);
 
-        me.createSurface();
+        if (me.createSurface() !== false) {
+            items = me.surface.items;
 
-        items = me.surface.items;
-
-        if (viewBox || autoSize) {
-            bbox = items.getBBox();
-            width = bbox.width;
-            height = bbox.height;
-            x = bbox.x;
-            y = bbox.y;
-            if (me.viewBox) {
-                me.surface.setViewBox(x, y, width, height);
-            }
-            else {
-                
-                me.autoSizeSurface();
+            if (viewBox || autoSize) {
+                bbox = items.getBBox();
+                width = bbox.width;
+                height = bbox.height;
+                x = bbox.x;
+                y = bbox.y;
+                if (me.viewBox) {
+                    me.surface.setViewBox(x, y, width, height);
+                }
+                else {
+                    
+                    me.autoSizeSurface();
+                }
             }
         }
     },
@@ -40115,6 +41369,7 @@ Ext.define('Ext.draw.Component', {
         }, true);
         if (me.rendered) {
             me.setSize(width, height);
+            me.surface.setSize(width, height);
         }
         else {
             me.surface.setSize(width, height);
@@ -40129,8 +41384,13 @@ Ext.define('Ext.draw.Component', {
                 height: this.height,
                 renderTo: this.el
             }, this.initialConfig));
+        if (!surface) {
+            
+            return false;
+        }
         this.surface = surface;
 
+
         function refire(eventName) {
             return function(e) {
                 this.fireEvent(eventName, e);
@@ -40360,6 +41620,7 @@ Ext.define('Ext.chart.LegendItem', {
     }
 });
 
+
 Ext.define('Ext.chart.Legend', {
 
     
@@ -40406,6 +41667,7 @@ Ext.define('Ext.chart.Legend', {
     
     boxZIndex: 100,
 
+    
     constructor: function(config) {
         var me = this;
         if (config) {
@@ -40414,7 +41676,7 @@ Ext.define('Ext.chart.Legend', {
         me.items = [];
         
         me.isVertical = ("left|right|float".indexOf(me.position) !== -1);
-        
+
         
         me.origX = me.x;
         me.origY = me.y;
@@ -40423,9 +41685,9 @@ Ext.define('Ext.chart.Legend', {
     
     create: function() {
         var me = this;
+        me.createBox();
         me.createItems();
         if (!me.created && me.isDisplayed()) {
-            me.createBox();
             me.created = true;
 
             
@@ -40460,8 +41722,8 @@ Ext.define('Ext.chart.Legend', {
             math = Math,
             mfloor = math.floor,
             mmax = math.max,
-            index = 0, 
-            i = 0, 
+            index = 0,
+            i = 0,
             len = items ? items.length : 0,
             x, y, spacing, item, bbox, height, width;
 
@@ -40487,7 +41749,7 @@ Ext.define('Ext.chart.Legend', {
                     bbox = item.getBBox();
 
                     
-                    width = bbox.width; 
+                    width = bbox.width;
                     height = bbox.height;
 
                     if (i + j === 0) {
@@ -40534,13 +41796,20 @@ Ext.define('Ext.chart.Legend', {
     
     createBox: function() {
         var me = this,
-            box = me.boxSprite = me.chart.surface.add(Ext.apply({
-                type: 'rect',
-                stroke: me.boxStroke,
-                "stroke-width": me.boxStrokeWidth,
-                fill: me.boxFill,
-                zIndex: me.boxZIndex
-            }, me.getBBox()));
+            box;
+
+        if (me.boxSprite) {
+            me.boxSprite.destroy();
+        }
+        
+        box = me.boxSprite = me.chart.surface.add(Ext.apply({
+            type: 'rect',
+            stroke: me.boxStroke,
+            "stroke-width": me.boxStrokeWidth,
+            fill: me.boxFill,
+            zIndex: me.boxZIndex
+        }, me.getBBox()));
+
         box.redraw();
     },
 
@@ -40560,7 +41829,7 @@ Ext.define('Ext.chart.Legend', {
             chartY = chartBBox.y + insets,
             surface = chart.surface,
             mfloor = Math.floor;
-        
+
         if (me.isDisplayed()) {
             
             switch(me.position) {
@@ -40643,10 +41912,17 @@ Ext.define('Ext.chart.Chart', {
 
     
 
+    
+
+    
+
+    
 
     constructor: function(config) {
         var me = this,
             defaultAnim;
+            
+        config = Ext.apply({}, config);
         me.initTheme(config.theme || me.theme);
         if (me.gradients) {
             Ext.apply(config, { gradients: me.gradients });
@@ -40670,6 +41946,10 @@ Ext.define('Ext.chart.Chart', {
         me.mixins.navigation.constructor.call(me, config);
         me.callParent([config]);
     },
+    
+    getChartStore: function(){
+        return this.substore || this.store;    
+    },
 
     initComponent: function() {
         var me = this,
@@ -40946,7 +42226,7 @@ Ext.define('Ext.chart.Chart', {
     
     refresh: function() {
         var me = this;
-        if (me.rendered && me.curWidth != undefined && me.curHeight != undefined) {
+        if (me.rendered && me.curWidth !== undefined && me.curHeight !== undefined) {
             if (me.fireEvent('beforerefresh', me) !== false) {
                 me.redraw();
                 me.fireEvent('refresh', me);
@@ -40959,7 +42239,7 @@ Ext.define('Ext.chart.Chart', {
         var me = this;
         if (!initial && me.store) {
             if (store !== me.store && me.store.autoDestroy) {
-                me.store.destroy();
+                me.store.destroyStore();
             }
             else {
                 me.store.un('datachanged', me.refresh, me);
@@ -41190,7 +42470,7 @@ Ext.define('Ext.chart.Chart', {
 
     
     destroy: function() {
-        this.surface.destroy();
+        Ext.destroy(this.surface);
         this.bindStore(null);
         this.callParent(arguments);
     }
@@ -41237,10 +42517,7 @@ Ext.define('Ext.chart.Highlight', {
             opts = me.highlightCfg,
             surface = me.chart.surface,
             animate = me.chart.animate,
-            p,
-            from,
-            to,
-            pi;
+            p, from, to, pi;
 
         if (!me.highlight || !sprite || sprite._highlighted) {
             return;
@@ -41250,8 +42527,7 @@ Ext.define('Ext.chart.Highlight', {
         }
         sprite._highlighted = true;
         if (!sprite._defaults) {
-            sprite._defaults = Ext.apply(sprite._defaults || {},
-            sprite.attr);
+            sprite._defaults = Ext.apply({}, sprite.attr);
             from = {};
             to = {};
             for (p in opts) {
@@ -41281,6 +42557,7 @@ Ext.define('Ext.chart.Highlight', {
             }
             sprite._from = from;
             sprite._to = to;
+            sprite._endStyle = to;
         }
         if (animate) {
             sprite._anim = Ext.create('Ext.fx.Anim', {
@@ -41306,9 +42583,7 @@ Ext.define('Ext.chart.Highlight', {
             opts = me.highlightCfg,
             animate = me.chart.animate,
             i = 0,
-            obj,
-            p,
-            sprite;
+            obj, p, sprite;
 
         for (; i < len; i++) {
             if (!items[i]) {
@@ -41330,6 +42605,8 @@ Ext.define('Ext.chart.Highlight', {
                     }
                 }
                 if (animate) {
+                    
+                    sprite._endStyle = obj;
                     sprite._anim = Ext.create('Ext.fx.Anim', {
                         target: sprite,
                         to: obj,
@@ -41370,18 +42647,6 @@ Ext.define('Ext.chart.Label', {
     
 
     requires: ['Ext.draw.Color'],
-    
-    
-
-    
-
-    
-
-    
-
-    
-
-    
 
     
 
@@ -41390,7 +42655,7 @@ Ext.define('Ext.chart.Label', {
     //@private a regex to parse url type colors.
 
     colorStringRe: /url\s*\(\s*#([^\/)]+)\s*\)/,
-    
+
     //@private the mixin constructor. Used internally by Series.
 
     constructor: function(config) {
@@ -41419,7 +42684,6 @@ Ext.define('Ext.chart.Label', {
         var me = this,
             chart = me.chart,
             gradients = chart.gradients,
-            gradient,
             items = me.items,
             animate = chart.animate,
             config = me.label,
@@ -41427,86 +42691,111 @@ Ext.define('Ext.chart.Label', {
             color = config.color,
             field = [].concat(config.field),
             group = me.labelsGroup,
+            groupLength = (group || 0) && group.length,
             store = me.chart.store,
             len = store.getCount(),
-            ratio = items.length / len,
-            i, count, j, 
-            k, gradientsCount = (gradients || 0) && gradients.length,
-            colorStopTotal, colorStopIndex, colorStop,
-            item, label, storeItem,
-            sprite, spriteColor, spriteBrightness, labelColor,
+            itemLength = (items || 0) && items.length,
+            ratio = itemLength / len,
+            gradientsCount = (gradients || 0) && gradients.length,
             Color = Ext.draw.Color,
-            colorString;
+            hides = [],
+            gradient, i, count, groupIndex, index, j, k, colorStopTotal, colorStopIndex, colorStop, item, label,
+            storeItem, sprite, spriteColor, spriteBrightness, labelColor, colorString;
 
         if (display == 'none') {
             return;
         }
+        
+        if(itemLength == 0){
+            while(groupLength--)
+                hides.push(groupLength);
+        }else{
+            for (i = 0, count = 0, groupIndex = 0; i < len; i++) {
+                index = 0;
+                for (j = 0; j < ratio; j++) {
+                    item = items[count];
+                    label = group.getAt(groupIndex);
+                    storeItem = store.getAt(i);
+                    
+                    while(this.__excludes && this.__excludes[index] && ratio > 1) {
+                        if(field[j]){
+                            hides.push(groupIndex);
+                        }
+                        index++;
 
-        for (i = 0, count = 0; i < len; i++) {
-            for (j = 0; j < ratio; j++) {
-                item = items[count];
-                label = group.getAt(count);
-                storeItem = store.getAt(i);
-
-                if (!item && label) {
-                    label.hide(true);
-                }
+                    }
 
-                if (item && field[j]) {
-                    if (!label) {
-                        label = me.onCreateLabel(storeItem, item, i, display, j, count);
+                    if (!item && label) {
+                        label.hide(true);
+                        groupIndex++;
                     }
-                    me.onPlaceLabel(label, storeItem, item, i, display, animate, j, count);
 
-                    
-                    if (config.contrast && item.sprite) {
-                        sprite = item.sprite;
-                        colorString = sprite._to && sprite._to.fill || sprite.attr.fill;
-                        spriteColor = Color.fromString(colorString);
+                    if (item && field[j]) {
+                        if (!label) {
+                            label = me.onCreateLabel(storeItem, item, i, display, j, index);
+                        }
+                        me.onPlaceLabel(label, storeItem, item, i, display, animate, j, index);
+                        groupIndex++;
+
                         
-                        if (colorString && !spriteColor) {
-                            colorString = colorString.match(me.colorStringRe)[1];
-                            for (k = 0; k < gradientsCount; k++) {
-                                gradient = gradients[k];
-                                if (gradient.id == colorString) {
-                                    
-                                    colorStop = 0; colorStopTotal = 0;
-                                    for (colorStopIndex in gradient.stops) {
-                                        colorStop++;
-                                        colorStopTotal += Color.fromString(gradient.stops[colorStopIndex].color).getGrayscale();
+                        if (config.contrast && item.sprite) {
+                            sprite = item.sprite;
+                            
+                            if (sprite._endStyle) {
+                                colorString = sprite._endStyle.fill;
+                            }
+                            else if (sprite._to) {
+                                colorString = sprite._to.fill;
+                            }
+                            else {
+                                colorString = sprite.attr.fill;
+                            }
+                            colorString = colorString || sprite.attr.fill;
+
+                            spriteColor = Color.fromString(colorString);
+                            
+                            if (colorString && !spriteColor) {
+                                colorString = colorString.match(me.colorStringRe)[1];
+                                for (k = 0; k < gradientsCount; k++) {
+                                    gradient = gradients[k];
+                                    if (gradient.id == colorString) {
+                                        
+                                        colorStop = 0; colorStopTotal = 0;
+                                        for (colorStopIndex in gradient.stops) {
+                                            colorStop++;
+                                            colorStopTotal += Color.fromString(gradient.stops[colorStopIndex].color).getGrayscale();
+                                        }
+                                        spriteBrightness = (colorStopTotal / colorStop) / 255;
+                                        break;
                                     }
-                                    spriteBrightness = (colorStopTotal / colorStop) / 255;
-                                    break;
                                 }
                             }
+                            else {
+                                spriteBrightness = spriteColor.getGrayscale() / 255;
+                            }
+                            if (label.isOutside) {
+                                spriteBrightness = 1;
+                            }
+                            labelColor = Color.fromString(label.attr.color || label.attr.fill).getHSL();
+                            labelColor[2] = spriteBrightness > 0.5 ? 0.2 : 0.8;
+                            label.setAttributes({
+                                fill: String(Color.fromHSL.apply({}, labelColor))
+                            }, true);
                         }
-                        else {
-                            spriteBrightness = spriteColor.getGrayscale() / 255;
-                        }
-                        labelColor = Color.fromString(label.attr.color || label.attr.fill).getHSL();
-                        
-                        labelColor[2] = spriteBrightness > 0.5? 0.2 : 0.8;
-                        label.setAttributes({
-                            fill: String(Color.fromHSL.apply({}, labelColor))
-                        }, true);
+
                     }
+                    count++;
+                    index++;
                 }
-                count++;
             }
         }
-        me.hideLabels(count);
+        me.hideLabels(hides);
     },
-
-    //@private a method to hide labels.
-
-    hideLabels: function(index) {
-        var labelsGroup = this.labelsGroup, len;
-        if (labelsGroup) {
-            len = labelsGroup.getCount();
-            while (len-->index) {
-                labelsGroup.getAt(len).hide(true);
-            }
-        }
+    hideLabels: function(hides){
+        var labelsGroup = this.labelsGroup,
+            hlen = hides.length;
+        while(hlen--)
+            labelsGroup.getAt(hides[hlen]).hide(true);
     }
 });
 Ext.define('Ext.chart.MaskLayer', {
@@ -41616,7 +42905,10 @@ Ext.define('Ext.chart.Tip', {
                 constrainPosition: false
             });
             me.tooltip = Ext.create('Ext.tip.ToolTip', me.tipConfig);
-            Ext.getBody().on('mousemove', me.tooltip.onMouseMove, me.tooltip);
+            me.chart.surface.on('mousemove', me.tooltip.onMouseMove, me.tooltip);
+            me.chart.surface.on('mouseleave', function() {
+                me.hideTip();
+            });
             if (me.tipConfig.surface) {
                 
                 surface = me.tipConfig.surface;
@@ -41686,6 +42978,7 @@ Ext.define('Ext.chart.axis.Abstract', {
 
     
 
+    
     constructor: function(config) {
         config = config || {};
 
@@ -41741,47 +43034,56 @@ Ext.define('Ext.chart.axis.Axis', {
     
 
     
-    dashSize: 3,
+
+    
+
+    //@private force min/max values from store
+
+    forceMinMax: false,
+
     
+    dashSize: 3,
+
     
     position: 'bottom',
-    
+
     
     skipFirst: false,
-    
+
     
     length: 0,
-    
+
     
     width: 0,
-    
+
     majorTickSteps: false,
 
     
     applyData: Ext.emptyFn,
 
-    
-    calcEnds: function() {
+    getRange: function () {
         var me = this,
+            store = me.chart.getChartStore(),
+            fields = me.fields,
+            ln = fields.length,
             math = Math,
             mmax = math.max,
             mmin = math.min,
-            store = me.chart.substore || me.chart.store,
-            series = me.chart.series.items,
-            fields = me.fields,
-            ln = fields.length,
+            aggregate = false,
             min = isNaN(me.minimum) ? Infinity : me.minimum,
             max = isNaN(me.maximum) ? -Infinity : me.maximum,
-            prevMin = me.prevMin,
-            prevMax = me.prevMax,
-            aggregate = false,
-            total = 0,
+            total = 0, i, l, value, values, rec,
             excludes = [],
-            outfrom, outto,
-            i, l, values, rec, out;
+            series = me.chart.series.items;
 
         
         
+        
+        
+        
+        
+        
+        
         for (i = 0, l = series.length; !aggregate && i < l; i++) {
             aggregate = aggregate || series[i].stacked;
             excludes = series[i].__excludes || excludes;
@@ -41798,8 +43100,8 @@ Ext.define('Ext.chart.axis.Axis', {
                     rec = record.get(fields[i]);
                     values[+(rec > 0)] += math.abs(rec);
                 }
-                max = mmax(max, -values[0], values[1]);
-                min = mmin(min, -values[0], values[1]);
+                max = mmax(max, -values[0], +values[1]);
+                min = mmin(min, -values[0], +values[1]);
             }
             else {
                 for (i = 0; i < ln; i++) {
@@ -41807,8 +43109,8 @@ Ext.define('Ext.chart.axis.Axis', {
                         continue;
                     }
                     value = record.get(fields[i]);
-                    max = mmax(max, value);
-                    min = mmin(min, value);
+                    max = mmax(max, +value);
+                    min = mmin(min, +value);
                 }
             }
         });
@@ -41819,12 +43121,41 @@ Ext.define('Ext.chart.axis.Axis', {
             min = me.prevMin || 0;
         }
         
-        if (min != max && (max != (max >> 0))) {
-            max = (max >> 0) + 1;
+        if (min != max && (max != Math.floor(max))) {
+            max = Math.floor(max) + 1;
+        }
+
+        if (!isNaN(me.minimum)) {
+            min = me.minimum;
         }
+        
+        if (!isNaN(me.maximum)) {
+            max = me.maximum;
+        }
+
+        return {min: min, max: max};
+    },
+
+    
+    calcEnds: function() {
+        var me = this,
+            fields = me.fields,
+            range = me.getRange(),
+            min = range.min,
+            max = range.max,
+            outfrom, outto, out;
+
         out = Ext.draw.Draw.snapEnds(min, max, me.majorTickSteps !== false ?  (me.majorTickSteps +1) : me.steps);
         outfrom = out.from;
         outto = out.to;
+        if (me.forceMinMax) {
+            if (!isNaN(max)) {
+                out.to = max;
+            }
+            if (!isNaN(min)) {
+                out.from = min;
+            }
+        }
         if (!isNaN(me.maximum)) {
             
             
@@ -41835,10 +43166,10 @@ Ext.define('Ext.chart.axis.Axis', {
             
             out.from = me.minimum;
         }
-        
+
         
         out.step = (out.to - out.from) / (outto - outfrom) * out.step;
-        
+
         if (me.adjustMaximumByMajorUnit) {
             out.to += out.step;
         }
@@ -41878,7 +43209,7 @@ Ext.define('Ext.chart.axis.Axis', {
             dashesX,
             dashesY,
             delta;
-        
+
         
         
         
@@ -41898,11 +43229,11 @@ Ext.define('Ext.chart.axis.Axis', {
             path = ["M", x, currentY, "l", length, 0];
             trueLength = length - (gutterX * 2);
         }
-        
+
         delta = trueLength / (steps || 1);
         dashesX = Math.max(subDashesX +1, 0);
         dashesY = Math.max(subDashesY +1, 0);
-        if (me.type == 'Numeric') {
+        if (me.type == 'Numeric' || me.type == 'Time') {
             calcLabels = true;
             me.labels = [stepCalcs.from];
         }
@@ -41985,7 +43316,7 @@ Ext.define('Ext.chart.axis.Axis', {
     
     drawGrid: function() {
         var me = this,
-            surface = me.chart.surface, 
+            surface = me.chart.surface,
             grid = me.grid,
             odd = grid.odd,
             even = grid.even,
@@ -41999,7 +43330,7 @@ Ext.define('Ext.chart.axis.Axis', {
             i = 1,
             path = [], styles, lineWidth, dlineWidth,
             oddPath = [], evenPath = [];
-        
+
         if ((gutter[1] !== 0 && (position == 'left' || position == 'right')) ||
             (gutter[0] !== 0 && (position == 'top' || position == 'bottom'))) {
             i = 0;
@@ -42014,25 +43345,25 @@ Ext.define('Ext.chart.axis.Axis', {
                 lineWidth = (styles.lineWidth || styles['stroke-width'] || 0) / 2;
                 dlineWidth = 2 * lineWidth;
                 if (position == 'left') {
-                    path.push("M", prevPoint[0] + 1 + lineWidth, prevPoint[1] + 0.5 - lineWidth, 
+                    path.push("M", prevPoint[0] + 1 + lineWidth, prevPoint[1] + 0.5 - lineWidth,
                               "L", prevPoint[0] + 1 + width - lineWidth, prevPoint[1] + 0.5 - lineWidth,
                               "L", point[0] + 1 + width - lineWidth, point[1] + 0.5 + lineWidth,
                               "L", point[0] + 1 + lineWidth, point[1] + 0.5 + lineWidth, "Z");
                 }
                 else if (position == 'right') {
-                    path.push("M", prevPoint[0] - lineWidth, prevPoint[1] + 0.5 - lineWidth, 
+                    path.push("M", prevPoint[0] - lineWidth, prevPoint[1] + 0.5 - lineWidth,
                               "L", prevPoint[0] - width + lineWidth, prevPoint[1] + 0.5 - lineWidth,
                               "L", point[0] - width + lineWidth, point[1] + 0.5 + lineWidth,
                               "L", point[0] - lineWidth, point[1] + 0.5 + lineWidth, "Z");
                 }
                 else if (position == 'top') {
-                    path.push("M", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] + 1 + lineWidth, 
+                    path.push("M", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] + 1 + lineWidth,
                               "L", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] + 1 + width - lineWidth,
                               "L", point[0] + 0.5 - lineWidth, point[1] + 1 + width - lineWidth,
                               "L", point[0] + 0.5 - lineWidth, point[1] + 1 + lineWidth, "Z");
                 }
                 else {
-                    path.push("M", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] - lineWidth, 
+                    path.push("M", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] - lineWidth,
                             "L", prevPoint[0] + 0.5 + lineWidth, prevPoint[1] - width + lineWidth,
                             "L", point[0] + 0.5 - lineWidth, point[1] - width + lineWidth,
                             "L", point[0] + 0.5 - lineWidth, point[1] - lineWidth, "Z");
@@ -42071,7 +43402,7 @@ Ext.define('Ext.chart.axis.Axis', {
                         type: 'path',
                         path: evenPath
                     });
-                } 
+                }
                 me.gridEven.setAttributes(Ext.apply({
                     path: evenPath,
                     hidden: false
@@ -42129,8 +43460,8 @@ Ext.define('Ext.chart.axis.Axis', {
         if (me.label.rotation) {
             textLabel.setAttributes({
                 rotation: {
-                    degrees: 0    
-                }    
+                    degrees: 0
+                }
             }, true);
             textLabel._ubbox = textLabel.getBBox();
             textLabel.setAttributes(me.label, true);
@@ -42139,7 +43470,7 @@ Ext.define('Ext.chart.axis.Axis', {
         }
         return textLabel;
     },
-    
+
     rect2pointArray: function(sprite) {
         var surface = this.chart.surface,
             rect = surface.getBBox(sprite, true),
@@ -42155,24 +43486,24 @@ Ext.define('Ext.chart.axis.Axis', {
         
         p1[0] = matrix.x.apply(matrix, p1p);
         p1[1] = matrix.y.apply(matrix, p1p);
-        
+
         p2[0] = matrix.x.apply(matrix, p2p);
         p2[1] = matrix.y.apply(matrix, p2p);
-        
+
         p3[0] = matrix.x.apply(matrix, p3p);
         p3[1] = matrix.y.apply(matrix, p3p);
-        
+
         p4[0] = matrix.x.apply(matrix, p4p);
         p4[1] = matrix.y.apply(matrix, p4p);
         return [p1, p2, p3, p4];
     },
-    
+
     intersect: function(l1, l2) {
         var r1 = this.rect2pointArray(l1),
             r2 = this.rect2pointArray(l2);
         return !!Ext.draw.Draw.intersect(r1, r2).length;
     },
-    
+
     drawHorizontalLabels: function() {
        var  me = this,
             labelConf = me.label,
@@ -42196,8 +43527,8 @@ Ext.define('Ext.chart.axis.Axis', {
         
         point = inflections[0];
         firstLabel = me.getOrCreateLabel(0, me.label.renderer(labels[0]));
-        ratio = Math.abs(Math.sin(labelConf.rotate && (labelConf.rotate.degrees * Math.PI / 180) || 0)) >> 0;
-        
+        ratio = Math.floor(Math.abs(Math.sin(labelConf.rotate && (labelConf.rotate.degrees * Math.PI / 180) || 0)));
+
         for (i = 0; i < ln; i++) {
             point = inflections[i];
             text = me.label.renderer(labels[i]);
@@ -42219,7 +43550,7 @@ Ext.define('Ext.chart.axis.Axis', {
             else {
                 y = point[1] + (me.dashSize * 2) + me.label.padding + (bbox.height / 2);
             }
-            
+
             textLabel.setAttributes({
                 hidden: false,
                 x: x,
@@ -42232,13 +43563,13 @@ Ext.define('Ext.chart.axis.Axis', {
                 textLabel.hide(true);
                 continue;
             }
-            
+
             prevLabel = textLabel;
         }
 
         return maxHeight;
     },
-    
+
     drawVerticalLabels: function() {
         var me = this,
             inflections = me.inflections,
@@ -42262,7 +43593,7 @@ Ext.define('Ext.chart.axis.Axis', {
             text = me.label.renderer(labels[i]);
             textLabel = me.getOrCreateLabel(i, text);
             bbox = textLabel._bbox;
-            
+
             maxWidth = max(maxWidth, bbox.width + me.dashSize + me.label.padding);
             y = point[1];
             if (gutterY < bbox.height / 2) {
@@ -42278,7 +43609,7 @@ Ext.define('Ext.chart.axis.Axis', {
             }
             else {
                 x = point[0] + me.dashSize + me.label.padding + 2;
-            }    
+            }
             textLabel.setAttributes(Ext.apply({
                 hidden: false,
                 x: x,
@@ -42291,7 +43622,7 @@ Ext.define('Ext.chart.axis.Axis', {
             }
             prevLabel = textLabel;
         }
-        
+
         return maxWidth;
     },
 
@@ -42306,7 +43637,7 @@ Ext.define('Ext.chart.axis.Axis', {
             ln, i;
 
         if (position == 'left' || position == 'right') {
-            maxWidth = me.drawVerticalLabels();    
+            maxWidth = me.drawVerticalLabels();
         } else {
             maxHeight = me.drawHorizontalLabels();
         }
@@ -42473,7 +43804,9 @@ Ext.define('Ext.chart.axis.Gauge', {
     extend: 'Ext.chart.axis.Abstract',
 
     
+
     
+
     
 
     
@@ -42542,7 +43875,7 @@ Ext.define('Ext.chart.axis.Gauge', {
             this.drawTitle();
         }
     },
-    
+
     drawTitle: function() {
         var me = this,
             chart = me.chart,
@@ -42550,12 +43883,12 @@ Ext.define('Ext.chart.axis.Gauge', {
             bbox = chart.chartBBox,
             labelSprite = me.titleSprite,
             labelBBox;
-        
+
         if (!labelSprite) {
             me.titleSprite = labelSprite = surface.add({
                 type: 'text',
                 zIndex: 2
-            });    
+            });
         }
         labelSprite.setAttributes(Ext.apply({
             text: me.title
@@ -42645,29 +43978,27 @@ Ext.define('Ext.chart.axis.Numeric', {
     alias: 'axis.numeric',
 
     constructor: function(config) {
-        var me = this, label, f;
+        var me = this,
+            hasLabel = !!(config.label && config.label.renderer),
+            label;
+
         me.callParent([config]);
         label = me.label;
         if (me.roundToDecimal === false) {
             return;
         }
-        if (label.renderer) {
-            f = label.renderer;
-            label.renderer = function(v) {
-                return me.roundToDecimal( f(v), me.decimals );
-            };
-        } else {
+        if (!hasLabel) {
             label.renderer = function(v) {
                 return me.roundToDecimal(v, me.decimals);
             };
         }
     },
-    
+
     roundToDecimal: function(v, dec) {
         var val = Math.pow(10, dec || 0);
-        return ((v * val) >> 0) / val;
+        return Math.floor(v * val) / val;
     },
-    
+
     
     minimum: NaN,
 
@@ -42948,11 +44279,14 @@ Ext.define('Ext.data.AbstractStore', {
     
     
 
+    
+
     sortRoot: 'data',
     
     
     constructor: function(config) {
-        var me = this;
+        var me = this,
+            filters;
         
         me.addEvents(
             
@@ -42972,6 +44306,9 @@ Ext.define('Ext.data.AbstractStore', {
 
             
             'load',
+            
+            
+            'write',
 
             
             'beforesync',
@@ -42980,12 +44317,13 @@ Ext.define('Ext.data.AbstractStore', {
         );
         
         Ext.apply(me, config);
+        
 
         
         me.removed = [];
 
         me.mixins.observable.constructor.apply(me, arguments);
-        me.model = Ext.ModelManager.getModel(config.model || me.model);
+        me.model = Ext.ModelManager.getModel(me.model);
 
         
         Ext.applyIf(me, {
@@ -43004,9 +44342,10 @@ Ext.define('Ext.data.AbstractStore', {
 
             me.implicitModel = true;
         }
+        
 
         
-        me.setProxy(config.proxy || me.proxy || me.model.getProxy());
+        me.setProxy(me.proxy || me.model.getProxy());
 
         if (me.id && !me.storeId) {
             me.storeId = me.id;
@@ -43020,8 +44359,9 @@ Ext.define('Ext.data.AbstractStore', {
         me.mixins.sortable.initSortable.call(me);        
         
         
+        filters = me.decodeFilters(me.filters);
         me.filters = Ext.create('Ext.util.MixedCollection');
-        me.filters.addAll(me.decodeFilters(config.filters));
+        me.filters.addAll(filters);
     },
 
     
@@ -43394,7 +44734,7 @@ Ext.define('Ext.data.AbstractStore', {
 
     
     isLoading: function() {
-        return this.loading;
+        return !!this.loading;
      }
 });
 
@@ -43419,7 +44759,7 @@ Ext.define('Ext.data.Store', {
 
     alias: 'store.store',
 
-    requires: ['Ext.ModelManager', 'Ext.data.Model', 'Ext.util.Grouper'],
+    requires: ['Ext.data.StoreManager', 'Ext.ModelManager', 'Ext.data.Model', 'Ext.util.Grouper'],
     uses: ['Ext.data.proxy.Memory'],
 
     
@@ -43427,11 +44767,9 @@ Ext.define('Ext.data.Store', {
 
     
     remoteFilter: false,
-    
-    
-    remoteGroup : false,
 
     
+    remoteGroup : false,
 
     
 
@@ -43457,35 +44795,53 @@ Ext.define('Ext.data.Store', {
 
     
     sortOnFilter: true,
-    
+
     
     buffered: false,
-    
+
     
     purgePageCount: 5,
 
     isStore: true,
 
+    onClassExtended: function(cls, data) {
+        var model = data.model;
+
+        if (typeof model == 'string') {
+            var onBeforeClassCreated = data.onBeforeClassCreated;
+
+            data.onBeforeClassCreated = function(cls, data) {
+                var me = this;
+
+                Ext.require(model, function() {
+                    onBeforeClassCreated.call(me, cls, data);
+                });
+            };
+        }
+    },
+
     
     constructor: function(config) {
-        config = config || {};
+        
+        config = Ext.Object.merge({}, config);
 
         var me = this,
-            groupers = config.groupers,
+            groupers = config.groupers || me.groupers,
+            groupField = config.groupField || me.groupField,
             proxy,
             data;
-            
+
         if (config.buffered || me.buffered) {
             me.prefetchData = Ext.create('Ext.util.MixedCollection', false, function(record) {
                 return record.index;
             });
             me.pendingRequests = [];
             me.pagesRequested = [];
-            
+
             me.sortOnLoad = false;
             me.filterOnLoad = false;
         }
-            
+
         me.addEvents(
             
             'beforeprefetch',
@@ -43505,21 +44861,22 @@ Ext.define('Ext.data.Store', {
             me.inlineData = data;
             delete config.data;
         }
-        
-        if (!groupers && config.groupField) {
+
+        if (!groupers && groupField) {
             groupers = [{
-                property : config.groupField,
-                direction: config.groupDir
+                property : groupField,
+                direction: config.groupDir || me.groupDir
             }];
         }
         delete config.groupers;
-        
+
         
         me.groupers = Ext.create('Ext.util.MixedCollection');
         me.groupers.addAll(me.decodeGroupers(groupers));
 
         this.callParent([config]);
         
+
         if (me.groupers.items.length) {
             me.sort(me.groupers.items, 'prepend', false);
         }
@@ -43543,11 +44900,14 @@ Ext.define('Ext.data.Store', {
             
         }
     },
-    
+
     onBeforeSort: function() {
-        this.sort(this.groupers.items, 'prepend', false);
+        var groupers = this.groupers;
+        if (groupers.getCount() > 0) {
+            this.sort(groupers.items, 'prepend', false);
+        }
     },
-    
+
     
     decodeGroupers: function(groupers) {
         if (!Ext.isArray(groupers)) {
@@ -43571,7 +44931,7 @@ Ext.define('Ext.data.Store', {
                         property: config
                     };
                 }
-                
+
                 Ext.applyIf(config, {
                     root     : 'data',
                     direction: "ASC"
@@ -43595,13 +44955,14 @@ Ext.define('Ext.data.Store', {
 
         return groupers;
     },
-    
+
     
     group: function(groupers, direction) {
         var me = this,
+            hasNew = false,
             grouper,
             newGroupers;
-            
+
         if (Ext.isArray(groupers)) {
             newGroupers = groupers;
         } else if (Ext.isObject(groupers)) {
@@ -43621,24 +44982,26 @@ Ext.define('Ext.data.Store', {
                 grouper.setDirection(direction);
             }
         }
-        
+
         if (newGroupers && newGroupers.length) {
+            hasNew = true;
             newGroupers = me.decodeGroupers(newGroupers);
             me.groupers.clear();
             me.groupers.addAll(newGroupers);
         }
-        
+
         if (me.remoteGroup) {
             me.load({
                 scope: me,
                 callback: me.fireGroupChange
             });
         } else {
-            me.sort();
-            me.fireEvent('groupchange', me, me.groupers);
+            
+            me.sort(null, null, null, hasNew);
+            me.fireGroupChange();
         }
     },
-    
+
     
     clearGrouping: function(){
         var me = this;
@@ -43657,15 +45020,15 @@ Ext.define('Ext.data.Store', {
             me.fireEvent('groupchange', me, me.groupers);
         }
     },
-    
+
     
     isGrouped: function() {
-        return this.groupers.getCount() > 0;    
+        return this.groupers.getCount() > 0;
     },
-    
+
     
     fireGroupChange: function(){
-        this.fireEvent('groupchange', this, this.groupers);    
+        this.fireEvent('groupchange', this, this.groupers);
     },
 
     
@@ -43785,7 +45148,7 @@ Ext.define('Ext.data.Store', {
             record.set(me.modelDefaults);
             
             records[i] = record;
-            
+
             me.data.insert(index + i, record);
             record.join(me);
 
@@ -43859,11 +45222,11 @@ Ext.define('Ext.data.Store', {
         for (; i < length; i++) {
             record = records[i];
             index = me.data.indexOf(record);
-            
+
             if (me.snapshot) {
                 me.snapshot.remove(record);
             }
-            
+
             if (index > -1) {
                 isPhantom = record.phantom === true;
                 if (!isMove && !isPhantom) {
@@ -43897,7 +45260,7 @@ Ext.define('Ext.data.Store', {
     
     load: function(options) {
         var me = this;
-            
+
         options = options || {};
 
         if (Ext.isFunction(options)) {
@@ -43912,7 +45275,7 @@ Ext.define('Ext.data.Store', {
             start: (me.currentPage - 1) * me.pageSize,
             limit: me.pageSize,
             addRecords: false
-        });      
+        });
 
         return me.callParent([options]);
     },
@@ -43942,7 +45305,7 @@ Ext.define('Ext.data.Store', {
         
         Ext.callback(operation.callback, operation.scope || me, [records, operation, successful]);
     },
-    
+
     
     onCreateRecords: function(records, operation, success) {
         if (success) {
@@ -43980,1425 +45343,2131 @@ Ext.define('Ext.data.Store', {
     },
 
     
-    onUpdateRecords: function(records, operation, success){
-        if (success) {
-            var i = 0,
-                length = records.length,
-                data = this.data,
-                snapshot = this.snapshot,
-                record;
+    onUpdateRecords: function(records, operation, success){
+        if (success) {
+            var i = 0,
+                length = records.length,
+                data = this.data,
+                snapshot = this.snapshot,
+                record;
+
+            for (; i < length; ++i) {
+                record = records[i];
+                data.replace(record);
+                if (snapshot) {
+                    snapshot.replace(record);
+                }
+                record.join(this);
+            }
+        }
+    },
+
+    
+    onDestroyRecords: function(records, operation, success){
+        if (success) {
+            var me = this,
+                i = 0,
+                length = records.length,
+                data = me.data,
+                snapshot = me.snapshot,
+                record;
+
+            for (; i < length; ++i) {
+                record = records[i];
+                record.unjoin(me);
+                data.remove(record);
+                if (snapshot) {
+                    snapshot.remove(record);
+                }
+            }
+            me.removed = [];
+        }
+    },
+
+    
+    getNewRecords: function() {
+        return this.data.filterBy(this.filterNew).items;
+    },
+
+    
+    getUpdatedRecords: function() {
+        return this.data.filterBy(this.filterUpdated).items;
+    },
+
+    
+    filter: function(filters, value) {
+        if (Ext.isString(filters)) {
+            filters = {
+                property: filters,
+                value: value
+            };
+        }
+
+        var me = this,
+            decoded = me.decodeFilters(filters),
+            i = 0,
+            doLocalSort = me.sortOnFilter && !me.remoteSort,
+            length = decoded.length;
+
+        for (; i < length; i++) {
+            me.filters.replace(decoded[i]);
+        }
+
+        if (me.remoteFilter) {
+            
+            me.load();
+        } else {
+            
+            if (me.filters.getCount()) {
+                me.snapshot = me.snapshot || me.data.clone();
+                me.data = me.data.filter(me.filters.items);
+
+                if (doLocalSort) {
+                    me.sort();
+                }
+                
+                if (!doLocalSort || me.sorters.length < 1) {
+                    me.fireEvent('datachanged', me);
+                }
+            }
+        }
+    },
+
+    
+    clearFilter: function(suppressEvent) {
+        var me = this;
+
+        me.filters.clear();
+
+        if (me.remoteFilter) {
+            me.load();
+        } else if (me.isFiltered()) {
+            me.data = me.snapshot.clone();
+            delete me.snapshot;
+
+            if (suppressEvent !== true) {
+                me.fireEvent('datachanged', me);
+            }
+        }
+    },
+
+    
+    isFiltered: function() {
+        var snapshot = this.snapshot;
+        return !! snapshot && snapshot !== this.data;
+    },
+
+    
+    filterBy: function(fn, scope) {
+        var me = this;
+
+        me.snapshot = me.snapshot || me.data.clone();
+        me.data = me.queryBy(fn, scope || me);
+        me.fireEvent('datachanged', me);
+    },
+
+    
+    queryBy: function(fn, scope) {
+        var me = this,
+        data = me.snapshot || me.data;
+        return data.filterBy(fn, scope || me);
+    },
+
+    
+    loadData: function(data, append) {
+        var model = this.model,
+            length = data.length,
+            newData = [],
+            i,
+            record;
+
+        
+        for (i = 0; i < length; i++) {
+            record = data[i];
+
+            if (!(record instanceof Ext.data.Model)) {
+                record = Ext.ModelManager.create(record, model);
+            }
+            newData.push(record);
+        }
+
+        this.loadRecords(newData, {addRecords: append});
+    },
+
+
+    
+    loadRawData : function(data, append) {
+         var me      = this,
+             result  = me.proxy.reader.read(data),
+             records = result.records;
+
+         if (result.success) {
+             me.loadRecords(records, { addRecords: append });
+             me.fireEvent('load', me, records, true);
+         }
+     },
+
+
+    
+    loadRecords: function(records, options) {
+        var me     = this,
+            i      = 0,
+            length = records.length;
+
+        options = options || {};
+
+
+        if (!options.addRecords) {
+            delete me.snapshot;
+            me.clearData();
+        }
+
+        me.data.addAll(records);
+
+        
+        for (; i < length; i++) {
+            if (options.start !== undefined) {
+                records[i].index = options.start + i;
+
+            }
+            records[i].join(me);
+        }
+
+        
+        me.suspendEvents();
+
+        if (me.filterOnLoad && !me.remoteFilter) {
+            me.filter();
+        }
+
+        if (me.sortOnLoad && !me.remoteSort) {
+            me.sort();
+        }
+
+        me.resumeEvents();
+        me.fireEvent('datachanged', me, records);
+    },
+
+    
+    
+    loadPage: function(page, options) {
+        var me = this;
+        options = Ext.apply({}, options);
+
+        me.currentPage = page;
+
+        me.read(Ext.applyIf(options, {
+            page: page,
+            start: (page - 1) * me.pageSize,
+            limit: me.pageSize,
+            addRecords: !me.clearOnPageLoad
+        }));
+    },
+
+    
+    nextPage: function(options) {
+        this.loadPage(this.currentPage + 1, options);
+    },
+
+    
+    previousPage: function(options) {
+        this.loadPage(this.currentPage - 1, options);
+    },
+
+    
+    clearData: function() {
+        var me = this;
+        me.data.each(function(record) {
+            record.unjoin(me);
+        });
+
+        me.data.clear();
+    },
+
+    
+    
+    prefetch: function(options) {
+        var me = this,
+            operation,
+            requestId = me.getRequestId();
+
+        options = options || {};
+
+        Ext.applyIf(options, {
+            action : 'read',
+            filters: me.filters.items,
+            sorters: me.sorters.items,
+            requestId: requestId
+        });
+        me.pendingRequests.push(requestId);
+
+        operation = Ext.create('Ext.data.Operation', options);
+
+        
+        
+        
+        
+        if (me.fireEvent('beforeprefetch', me, operation) !== false) {
+            me.loading = true;
+            me.proxy.read(operation, me.onProxyPrefetch, me);
+        }
+
+        return me;
+    },
+
+    
+    prefetchPage: function(page, options) {
+        var me = this,
+            pageSize = me.pageSize,
+            start = (page - 1) * me.pageSize,
+            end = start + pageSize;
+
+        
+        if (Ext.Array.indexOf(me.pagesRequested, page) === -1 && !me.rangeSatisfied(start, end)) {
+            options = options || {};
+            me.pagesRequested.push(page);
+            Ext.applyIf(options, {
+                page : page,
+                start: start,
+                limit: pageSize,
+                callback: me.onWaitForGuarantee,
+                scope: me
+            });
+
+            me.prefetch(options);
+        }
+
+    },
+
+    
+    getRequestId: function() {
+        this.requestSeed = this.requestSeed || 1;
+        return this.requestSeed++;
+    },
+
+    
+    onProxyPrefetch: function(operation) {
+        var me         = this,
+            resultSet  = operation.getResultSet(),
+            records    = operation.getRecords(),
+
+            successful = operation.wasSuccessful();
+
+        if (resultSet) {
+            me.totalCount = resultSet.total;
+            me.fireEvent('totalcountchange', me.totalCount);
+        }
+
+        if (successful) {
+            me.cacheRecords(records, operation);
+        }
+        Ext.Array.remove(me.pendingRequests, operation.requestId);
+        if (operation.page) {
+            Ext.Array.remove(me.pagesRequested, operation.page);
+        }
+
+        me.loading = false;
+        me.fireEvent('prefetch', me, records, successful, operation);
+
+        
+        if (operation.blocking) {
+            me.fireEvent('load', me, records, successful);
+        }
+
+        
+        Ext.callback(operation.callback, operation.scope || me, [records, operation, successful]);
+    },
+
+    
+    cacheRecords: function(records, operation) {
+        var me     = this,
+            i      = 0,
+            length = records.length,
+            start  = operation ? operation.start : 0;
+
+        if (!Ext.isDefined(me.totalCount)) {
+            me.totalCount = records.length;
+            me.fireEvent('totalcountchange', me.totalCount);
+        }
+
+        for (; i < length; i++) {
+            
+            records[i].index = start + i;
+        }
+
+        me.prefetchData.addAll(records);
+        if (me.purgePageCount) {
+            me.purgeRecords();
+        }
+
+    },
+
+
+    
+    purgeRecords: function() {
+        var me = this,
+            prefetchCount = me.prefetchData.getCount(),
+            purgeCount = me.purgePageCount * me.pageSize,
+            numRecordsToPurge = prefetchCount - purgeCount - 1,
+            i = 0;
+
+        for (; i <= numRecordsToPurge; i++) {
+            me.prefetchData.removeAt(0);
+        }
+    },
+
+    
+    rangeSatisfied: function(start, end) {
+        var me = this,
+            i = start,
+            satisfied = true;
+
+        for (; i < end; i++) {
+            if (!me.prefetchData.getByKey(i)) {
+                satisfied = false;
+                break;
+            }
+        }
+        return satisfied;
+    },
+
+    
+    getPageFromRecordIndex: function(index) {
+        return Math.floor(index / this.pageSize) + 1;
+    },
+
+    
+    onGuaranteedRange: function() {
+        var me = this,
+            totalCount = me.getTotalCount(),
+            start = me.requestStart,
+            end = ((totalCount - 1) < me.requestEnd) ? totalCount - 1 : me.requestEnd,
+            range = [],
+            record,
+            i = start;
+
+        end = Math.max(0, end);
+
+
+        if (start !== me.guaranteedStart && end !== me.guaranteedEnd) {
+            me.guaranteedStart = start;
+            me.guaranteedEnd = end;
+
+            for (; i <= end; i++) {
+                record = me.prefetchData.getByKey(i);
+                if (record) {
+                    range.push(record);
+                }
+            }
+            me.fireEvent('guaranteedrange', range, start, end);
+            if (me.cb) {
+                me.cb.call(me.scope || me, range);
+            }
+        }
+
+        me.unmask();
+    },
+
+    
+    mask: function() {
+        this.masked = true;
+        this.fireEvent('beforeload');
+    },
+
+    
+    unmask: function() {
+        if (this.masked) {
+            this.fireEvent('load');
+        }
+    },
+
+    
+    hasPendingRequests: function() {
+        return this.pendingRequests.length;
+    },
+
+
+    
+    onWaitForGuarantee: function() {
+        if (!this.hasPendingRequests()) {
+            this.onGuaranteedRange();
+        }
+    },
+
+    
+    guaranteeRange: function(start, end, cb, scope) {
+
+        end = (end > this.totalCount) ? this.totalCount - 1 : end;
+
+        var me = this,
+            i = start,
+            prefetchData = me.prefetchData,
+            range = [],
+            startLoaded = !!prefetchData.getByKey(start),
+            endLoaded = !!prefetchData.getByKey(end),
+            startPage = me.getPageFromRecordIndex(start),
+            endPage = me.getPageFromRecordIndex(end);
+
+        me.cb = cb;
+        me.scope = scope;
+
+        me.requestStart = start;
+        me.requestEnd = end;
+        
+        if (!startLoaded || !endLoaded) {
+            
+            if (startPage === endPage) {
+                me.mask();
+                me.prefetchPage(startPage, {
+                    
+                    callback: me.onWaitForGuarantee,
+                    scope: me
+                });
+            
+            } else {
+                me.mask();
+                me.prefetchPage(startPage, {
+                    
+                    callback: me.onWaitForGuarantee,
+                    scope: me
+                });
+                me.prefetchPage(endPage, {
+                    
+                    callback: me.onWaitForGuarantee,
+                    scope: me
+                });
+            }
+        
+        } else {
+            me.onGuaranteedRange();
+        }
+    },
+
+    
+    
+    sort: function() {
+        var me = this,
+            prefetchData = me.prefetchData,
+            sorters,
+            start,
+            end,
+            range;
 
-            for (; i < length; ++i) {
-                record = records[i];
-                data.replace(record);
-                if (snapshot) {
-                    snapshot.replace(record);
+        if (me.buffered) {
+            if (me.remoteSort) {
+                prefetchData.clear();
+                me.callParent(arguments);
+            } else {
+                sorters = me.getSorters();
+                start = me.guaranteedStart;
+                end = me.guaranteedEnd;
+
+                if (sorters.length) {
+                    prefetchData.sort(sorters);
+                    range = prefetchData.getRange();
+                    prefetchData.clear();
+                    me.cacheRecords(range);
+                    delete me.guaranteedStart;
+                    delete me.guaranteedEnd;
+                    me.guaranteeRange(start, end);
                 }
-                record.join(this);
+                me.callParent(arguments);
             }
+        } else {
+            me.callParent(arguments);
         }
     },
 
     
-    onDestroyRecords: function(records, operation, success){
-        if (success) {
-            var me = this,
-                i = 0,
-                length = records.length,
-                data = me.data,
-                snapshot = me.snapshot,
-                record;
-
-            for (; i < length; ++i) {
-                record = records[i];
-                record.unjoin(me);
-                data.remove(record);
-                if (snapshot) {
-                    snapshot.remove(record);
+    
+    
+    doSort: function(sorterFn) {
+        var me = this;
+        if (me.remoteSort) {
+            
+            me.load();
+        } else {
+            me.data.sortBy(sorterFn);
+            if (!me.buffered) {
+                var range = me.getRange(),
+                    ln = range.length,
+                    i  = 0;
+                for (; i < ln; i++) {
+                    range[i].index = i;
                 }
             }
-            me.removed = [];
+            me.fireEvent('datachanged', me);
         }
     },
 
     
-    getNewRecords: function() {
-        return this.data.filterBy(this.filterNew).items;
+    find: function(property, value, start, anyMatch, caseSensitive, exactMatch) {
+        var fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch);
+        return fn ? this.data.findIndexBy(fn, null, start) : -1;
     },
 
     
-    getUpdatedRecords: function() {
-        return this.data.filterBy(this.filterUpdated).items;
+    findRecord: function() {
+        var me = this,
+            index = me.find.apply(me, arguments);
+        return index !== -1 ? me.getAt(index) : null;
     },
 
     
-    filter: function(filters, value) {
-        if (Ext.isString(filters)) {
-            filters = {
-                property: filters,
-                value: value
-            };
+    createFilterFn: function(property, value, anyMatch, caseSensitive, exactMatch) {
+        if (Ext.isEmpty(value)) {
+            return false;
         }
+        value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch);
+        return function(r) {
+            return value.test(r.data[property]);
+        };
+    },
+
+    
+    findExact: function(property, value, start) {
+        return this.data.findIndexBy(function(rec) {
+            return rec.get(property) == value;
+        },
+        this, start);
+    },
+
+    
+    findBy: function(fn, scope, start) {
+        return this.data.findIndexBy(fn, scope, start);
+    },
 
+    
+    collect: function(dataIndex, allowNull, bypassFilter) {
         var me = this,
-            decoded = me.decodeFilters(filters),
-            i = 0,
-            doLocalSort = me.sortOnFilter && !me.remoteSort,
-            length = decoded.length;
+            data = (bypassFilter === true && me.snapshot) ? me.snapshot: me.data;
 
-        for (; i < length; i++) {
-            me.filters.replace(decoded[i]);
-        }
+        return data.collect(dataIndex, 'data', allowNull);
+    },
 
-        if (me.remoteFilter) {
-            
-            me.load();
-        } else {
-            
-            if (me.filters.getCount()) {
-                me.snapshot = me.snapshot || me.data.clone();
-                me.data = me.data.filter(me.filters.items);
+    
+    getCount: function() {
+        return this.data.length || 0;
+    },
 
-                if (doLocalSort) {
-                    me.sort();
-                }
-                
-                if (!doLocalSort || me.sorters.length < 1) {
-                    me.fireEvent('datachanged', me);
-                }
-            }
-        }
+    
+    getTotalCount: function() {
+        return this.totalCount;
     },
 
     
-    clearFilter: function(suppressEvent) {
-        var me = this;
+    getAt: function(index) {
+        return this.data.getAt(index);
+    },
 
-        me.filters.clear();
+    
+    getRange: function(start, end) {
+        return this.data.getRange(start, end);
+    },
 
-        if (me.remoteFilter) {
-            me.load();
-        } else if (me.isFiltered()) {
-            me.data = me.snapshot.clone();
-            delete me.snapshot;
+    
+    getById: function(id) {
+        return (this.snapshot || this.data).findBy(function(record) {
+            return record.getId() === id;
+        });
+    },
 
-            if (suppressEvent !== true) {
-                me.fireEvent('datachanged', me);
-            }
+    
+    indexOf: function(record) {
+        return this.data.indexOf(record);
+    },
+
+
+    
+    indexOfTotal: function(record) {
+        var index = record.index;
+        if (index || index === 0) {
+            return index;
         }
+        return this.indexOf(record);
     },
 
     
-    isFiltered: function() {
-        var snapshot = this.snapshot;
-        return !! snapshot && snapshot !== this.data;
+    indexOfId: function(id) {
+        return this.indexOf(this.getById(id));
     },
 
     
-    filterBy: function(fn, scope) {
+    removeAll: function(silent) {
         var me = this;
 
-        me.snapshot = me.snapshot || me.data.clone();
-        me.data = me.queryBy(fn, scope || me);
-        me.fireEvent('datachanged', me);
+        me.clearData();
+        if (me.snapshot) {
+            me.snapshot.clear();
+        }
+        if (silent !== true) {
+            me.fireEvent('clear', me);
+        }
     },
 
     
-    queryBy: function(fn, scope) {
-        var me = this,
-        data = me.snapshot || me.data;
-        return data.filterBy(fn, scope || me);
-    },
 
     
-    loadData: function(data, append) {
-        var model = this.model,
-            length = data.length,
-            i,
-            record;
-
-        
-        for (i = 0; i < length; i++) {
-            record = data[i];
+    first: function(grouped) {
+        var me = this;
 
-            if (! (record instanceof Ext.data.Model)) {
-                data[i] = Ext.ModelManager.create(record, model);
-            }
+        if (grouped && me.isGrouped()) {
+            return me.aggregate(function(records) {
+                return records.length ? records[0] : undefined;
+            }, me, true);
+        } else {
+            return me.data.first();
         }
+    },
+
+    
+    last: function(grouped) {
+        var me = this;
 
-        this.loadRecords(data, {addRecords: append});
+        if (grouped && me.isGrouped()) {
+            return me.aggregate(function(records) {
+                var len = records.length;
+                return len ? records[len - 1] : undefined;
+            }, me, true);
+        } else {
+            return me.data.last();
+        }
     },
 
     
-    loadRecords: function(records, options) {
-        var me     = this,
-            i      = 0,
-            length = records.length;
+    sum: function(field, grouped) {
+        var me = this;
 
-        options = options || {};
+        if (grouped && me.isGrouped()) {
+            return me.aggregate(me.getSum, me, true, [field]);
+        } else {
+            return me.getSum(me.data.items, field);
+        }
+    },
 
+    
+    getSum: function(records, field) {
+        var total = 0,
+            i = 0,
+            len = records.length;
 
-        if (!options.addRecords) {
-            delete me.snapshot;
-            me.data.clear();
+        for (; i < len; ++i) {
+            total += records[i].get(field);
         }
 
-        me.data.addAll(records);
+        return total;
+    },
 
-        
-        for (; i < length; i++) {
-            if (options.start !== undefined) {
-                records[i].index = options.start + i;
+    
+    count: function(grouped) {
+        var me = this;
 
-            }
-            records[i].join(me);
+        if (grouped && me.isGrouped()) {
+            return me.aggregate(function(records) {
+                return records.length;
+            }, me, true);
+        } else {
+            return me.getCount();
         }
+    },
 
-        
-        me.suspendEvents();
+    
+    min: function(field, grouped) {
+        var me = this;
 
-        if (me.filterOnLoad && !me.remoteFilter) {
-            me.filter();
+        if (grouped && me.isGrouped()) {
+            return me.aggregate(me.getMin, me, true, [field]);
+        } else {
+            return me.getMin(me.data.items, field);
         }
+    },
 
-        if (me.sortOnLoad && !me.remoteSort) {
-            me.sort();
+    
+    getMin: function(records, field){
+        var i = 1,
+            len = records.length,
+            value, min;
+
+        if (len > 0) {
+            min = records[0].get(field);
         }
 
-        me.resumeEvents();
-        me.fireEvent('datachanged', me, records);
+        for (; i < len; ++i) {
+            value = records[i].get(field);
+            if (value < min) {
+                min = value;
+            }
+        }
+        return min;
     },
 
     
-    
-    loadPage: function(page) {
+    max: function(field, grouped) {
         var me = this;
 
-        me.currentPage = page;
-
-        me.read({
-            page: page,
-            start: (page - 1) * me.pageSize,
-            limit: me.pageSize,
-            addRecords: !me.clearOnPageLoad
-        });
+        if (grouped && me.isGrouped()) {
+            return me.aggregate(me.getMax, me, true, [field]);
+        } else {
+            return me.getMax(me.data.items, field);
+        }
     },
 
     
-    nextPage: function() {
-        this.loadPage(this.currentPage + 1);
+    getMax: function(records, field) {
+        var i = 1,
+            len = records.length,
+            value,
+            max;
+
+        if (len > 0) {
+            max = records[0].get(field);
+        }
+
+        for (; i < len; ++i) {
+            value = records[i].get(field);
+            if (value > max) {
+                max = value;
+            }
+        }
+        return max;
     },
 
     
-    previousPage: function() {
-        this.loadPage(this.currentPage - 1);
+    average: function(field, grouped) {
+        var me = this;
+        if (grouped && me.isGrouped()) {
+            return me.aggregate(me.getAverage, me, true, [field]);
+        } else {
+            return me.getAverage(me.data.items, field);
+        }
     },
 
     
-    clearData: function() {
-        this.data.each(function(record) {
-            record.unjoin();
-        });
+    getAverage: function(records, field) {
+        var i = 0,
+            len = records.length,
+            sum = 0;
 
-        this.data.clear();
+        if (records.length > 0) {
+            for (; i < len; ++i) {
+                sum += records[i].get(field);
+            }
+            return sum / len;
+        }
+        return 0;
     },
+
+    
+    aggregate: function(fn, scope, grouped, args) {
+        args = args || [];
+        if (grouped && this.isGrouped()) {
+            var groups = this.getGroups(),
+                i = 0,
+                len = groups.length,
+                out = {},
+                group;
+
+            for (; i < len; ++i) {
+                group = groups[i];
+                out[group.name] = fn.apply(scope || this, [group.children].concat(args));
+            }
+            return out;
+        } else {
+            return fn.apply(scope || this, [this.data.items].concat(args));
+        }
+    }
+}, function() {
     
     
     
-    prefetch: function(options) {
-        var me = this,
-            operation,
-            requestId = me.getRequestId();
+    Ext.regStore('ext-empty-store', {fields: [], proxy: 'proxy'});
+});
 
-        options = options || {};
 
-        Ext.applyIf(options, {
-            action : 'read',
-            filters: me.filters.items,
-            sorters: me.sorters.items,
-            requestId: requestId
+Ext.define('Ext.data.JsonStore',  {
+    extend: 'Ext.data.Store',
+    alias: 'store.json',
+
+    
+    constructor: function(config) {
+        config = config || {};
+
+        Ext.applyIf(config, {
+            proxy: {
+                type  : 'ajax',
+                reader: 'json',
+                writer: 'json'
+            }
         });
-        me.pendingRequests.push(requestId);
 
-        operation = Ext.create('Ext.data.Operation', options);
+        this.callParent([config]);
+    }
+});
+
+
+Ext.define('Ext.chart.axis.Time', {
 
-        
-        
-        
-        
-        if (me.fireEvent('beforeprefetch', me, operation) !== false) {
-            me.loading = true;
-            me.proxy.read(operation, me.onProxyPrefetch, me);
-        }
-        
-        return me;
-    },
-    
-    
-    prefetchPage: function(page, options) {
-        var me = this,
-            pageSize = me.pageSize,
-            start = (page - 1) * me.pageSize,
-            end = start + pageSize;
-        
-        
-        if (Ext.Array.indexOf(me.pagesRequested, page) === -1 && !me.rangeSatisfied(start, end)) {
-            options = options || {};
-            me.pagesRequested.push(page);
-            Ext.applyIf(options, {
-                page : page,
-                start: start,
-                limit: pageSize,
-                callback: me.onWaitForGuarantee,
-                scope: me
-            });
-            
-            me.prefetch(options);
-        }
-        
-    },
-    
     
-    getRequestId: function() {
-        this.requestSeed = this.requestSeed || 1;
-        return this.requestSeed++;
-    },
+
+    extend: 'Ext.chart.axis.Numeric',
+
+    alternateClassName: 'Ext.chart.TimeAxis',
+
+    alias: 'axis.time',
+
+    requires: ['Ext.data.Store', 'Ext.data.JsonStore'],
+
     
+
     
-    onProxyPrefetch: function(operation) {
-        var me         = this,
-            resultSet  = operation.getResultSet(),
-            records    = operation.getRecords(),
-            
-            successful = operation.wasSuccessful();
-        
-        if (resultSet) {
-            me.totalCount = resultSet.total;
-            me.fireEvent('totalcountchange', me.totalCount);
-        }
-        
-        if (successful) {
-            me.cacheRecords(records, operation);
-        }
-        Ext.Array.remove(me.pendingRequests, operation.requestId);
-        if (operation.page) {
-            Ext.Array.remove(me.pagesRequested, operation.page);
-        }
-        
-        me.loading = false;
-        me.fireEvent('prefetch', me, records, successful, operation);
-        
-        
-        if (operation.blocking) {
-            me.fireEvent('load', me, records, successful);
-        }
+    dateFormat: false,
 
-        
-        Ext.callback(operation.callback, operation.scope || me, [records, operation, successful]);
-    },
     
+    fromDate: false,
+
     
-    cacheRecords: function(records, operation) {
-        var me     = this,
-            i      = 0,
-            length = records.length,
-            start  = operation ? operation.start : 0;
-        
-        if (!Ext.isDefined(me.totalCount)) {
-            me.totalCount = records.length;
-            me.fireEvent('totalcountchange', me.totalCount);
-        }
-        
-        for (; i < length; i++) {
-            
-            records[i].index = start + i;
-        }
-        
-        me.prefetchData.addAll(records);
-        if (me.purgePageCount) {
-            me.purgeRecords();
-        }
-        
-    },
+    toDate: false,
+
     
+    step: [Ext.Date.DAY, 1],
     
     
-    purgeRecords: function() {
-        var me = this,
-            prefetchCount = me.prefetchData.getCount(),
-            purgeCount = me.purgePageCount * me.pageSize,
-            numRecordsToPurge = prefetchCount - purgeCount - 1,
-            i = 0;
+    constrain: false,
 
-        for (; i <= numRecordsToPurge; i++) {
-            me.prefetchData.removeAt(0);
-        }
-    },
     
+    roundToDecimal: false,
     
-    rangeSatisfied: function(start, end) {
-        var me = this,
-            i = start,
-            satisfied = true;
-
-        for (; i < end; i++) {
-            if (!me.prefetchData.getByKey(i)) {
-                satisfied = false;
-                if (end - i > me.pageSize) {
-                    Ext.Error.raise("A single page prefetch could never satisfy this request.");
-                }
-                break;
+    constructor: function (config) {
+        var me = this, label, f, df;
+        me.callParent([config]);
+        label = me.label || {};
+        df = this.dateFormat;
+        if (df) {
+            if (label.renderer) {
+                f = label.renderer;
+                label.renderer = function(v) {
+                    v = f(v);
+                    return Ext.Date.format(new Date(f(v)), df);
+                };
+            } else {
+                label.renderer = function(v) {
+                    return Ext.Date.format(new Date(v >> 0), df);
+                };
             }
         }
-        return satisfied;
-    },
-    
-    
-    getPageFromRecordIndex: function(index) {
-        return Math.floor(index / this.pageSize) + 1;
     },
-    
-    
-    onGuaranteedRange: function() {
+
+    doConstrain: function () {
         var me = this,
-            totalCount = me.getTotalCount(),
-            start = me.requestStart,
-            end = ((totalCount - 1) < me.requestEnd) ? totalCount - 1 : me.requestEnd,
-            range = [],
-            record,
-            i = start;
-            
-        if (start > end) {
-            Ext.Error.raise("Start (" + start + ") was greater than end (" + end + ")");
+            store = me.chart.store,
+            data = [],
+            series = me.chart.series.items,
+            math = Math,
+            mmax = math.max,
+            mmin = math.min,
+            fields = me.fields,
+            ln = fields.length,
+            range = me.getRange(),
+            min = range.min, max = range.max, i, l, excludes = [],
+            value, values, rec, data = [];
+        for (i = 0, l = series.length; i < l; i++) {
+            excludes[i] = series[i].__excludes;
         }
-        
-        if (start !== me.guaranteedStart && end !== me.guaranteedEnd) {
-            me.guaranteedStart = start;
-            me.guaranteedEnd = end;
-            
-            for (; i <= end; i++) {
-                record = me.prefetchData.getByKey(i);
-                if (!record) {
-                    Ext.Error.raise("Record was not found and store said it was guaranteed");
+        store.each(function(record) {
+            for (i = 0; i < ln; i++) {
+                if (excludes[i]) {
+                    continue;
                 }
-                range.push(record);
-            }
-            me.fireEvent('guaranteedrange', range, start, end);
-            if (me.cb) {
-                me.cb.call(me.scope || me, range);
+                value = record.get(fields[i]);
+                if (+value < +min) return;
+                if (+value > +max) return;
             }
-        }
-        
-        me.unmask();
+            data.push(record);
+        })
+        me.chart.substore = Ext.create('Ext.data.JsonStore', { model: store.model, data: data });
     },
+
     
+    processView: function () {
+        var me = this;
+        if (me.fromDate) {
+            me.minimum = +me.fromDate;
+        }
+        if (me.toDate) {
+            me.maximum = +me.toDate;
+        }
+        if (me.constrain) {
+            me.doConstrain();
+        }
+     },
+
     
-    mask: function() {
-        this.masked = true;
-        this.fireEvent('beforeload');
+    calcEnds: function() {
+        var me = this, range, step = me.step;
+        if (step) {
+            range = me.getRange();
+            range = Ext.draw.Draw.snapEndsByDateAndStep(new Date(range.min), new Date(range.max), Ext.isNumber(step) ? [Date.MILLI, step]: step);
+            if (me.minimum) {
+                range.from = me.minimum;
+            }
+            if (me.maximum) {
+                range.to = me.maximum;
+            }
+            range.step = (range.to - range.from) / range.steps;
+            return range;
+        } else {
+            return me.callParent(arguments);
+        }
+    }
+ });
+
+
+
+Ext.define('Ext.chart.series.Series', {
+
+    
+
+    mixins: {
+        observable: 'Ext.util.Observable',
+        labels: 'Ext.chart.Label',
+        highlights: 'Ext.chart.Highlight',
+        tips: 'Ext.chart.Tip',
+        callouts: 'Ext.chart.Callout'
     },
+
     
+
     
-    unmask: function() {
-        if (this.masked) {
-            this.fireEvent('load');
-        }
-    },
+
     
+
     
-    hasPendingRequests: function() {
-        return this.pendingRequests.length;
-    },
+    type: null,
+
     
+    title: null,
+
     
+    showInLegend: true,
+
     
-    onWaitForGuarantee: function() {
-        if (!this.hasPendingRequests()) {
-            this.onGuaranteedRange();
-        }
+    renderer: function(sprite, record, attributes, index, store) {
+        return attributes;
     },
+
     
+    shadowAttributes: null,
+
+    //@private triggerdrawlistener flag
+
+    triggerAfterDraw: false,
+
     
-    guaranteeRange: function(start, end, cb, scope) {
-        if (start && end) {
-            if (end - start > this.pageSize) {
-                Ext.Error.raise({
-                    start: start,
-                    end: end,
-                    pageSize: this.pageSize,
-                    msg: "Requested a bigger range than the specified pageSize"
-                });
-            }
+
+    constructor: function(config) {
+        var me = this;
+        if (config) {
+            Ext.apply(me, config);
         }
-        
-        end = (end > this.totalCount) ? this.totalCount - 1 : end;
-        
-        var me = this,
-            i = start,
-            prefetchData = me.prefetchData,
-            range = [],
-            startLoaded = !!prefetchData.getByKey(start),
-            endLoaded = !!prefetchData.getByKey(end),
-            startPage = me.getPageFromRecordIndex(start),
-            endPage = me.getPageFromRecordIndex(end);
-            
-        me.cb = cb;
-        me.scope = scope;
 
-        me.requestStart = start;
-        me.requestEnd = end;
-        
-        if (!startLoaded || !endLoaded) {
-            
-            if (startPage === endPage) {
-                me.mask();
-                me.prefetchPage(startPage, {
-                    
-                    callback: me.onWaitForGuarantee,
-                    scope: me
-                });
+        me.shadowGroups = [];
+
+        me.mixins.labels.constructor.call(me, config);
+        me.mixins.highlights.constructor.call(me, config);
+        me.mixins.tips.constructor.call(me, config);
+        me.mixins.callouts.constructor.call(me, config);
+
+        me.addEvents({
+            scope: me,
+            itemmouseover: true,
+            itemmouseout: true,
+            itemmousedown: true,
+            itemmouseup: true,
+            mouseleave: true,
+            afterdraw: true,
+
             
-            } else {
-                me.mask();
-                me.prefetchPage(startPage, {
-                    
-                    callback: me.onWaitForGuarantee,
-                    scope: me
-                });
-                me.prefetchPage(endPage, {
-                    
-                    callback: me.onWaitForGuarantee,
-                    scope: me
-                });
-            }
-        
-        } else {
-            me.onGuaranteedRange();
-        }
+            titlechange: true
+        });
+
+        me.mixins.observable.constructor.call(me, config);
+
+        me.on({
+            scope: me,
+            itemmouseover: me.onItemMouseOver,
+            itemmouseout: me.onItemMouseOut,
+            mouseleave: me.onMouseLeave
+        });
     },
     
     
+    eachRecord: function(fn, scope) {
+        var chart = this.chart;
+        (chart.substore || chart.store).each(fn, scope);
+    },
+
     
-    sort: function() {
-        var me = this,
-            prefetchData = me.prefetchData,
-            sorters,
-            start,
-            end,
-            range;
-            
-        if (me.buffered) {
-            if (me.remoteSort) {
-                prefetchData.clear();
-                me.callParent(arguments);
-            } else {
-                sorters = me.getSorters();
-                start = me.guaranteedStart;
-                end = me.guaranteedEnd;
-                range;
-                
-                if (sorters.length) {
-                    prefetchData.sort(sorters);
-                    range = prefetchData.getRange();
-                    prefetchData.clear();
-                    me.cacheRecords(range);
-                    delete me.guaranteedStart;
-                    delete me.guaranteedEnd;
-                    me.guaranteeRange(start, end);
-                }
-                me.callParent(arguments);
-            }
-        } else {
-            me.callParent(arguments);
-        }
+    getRecordCount: function() {
+        var chart = this.chart,
+            store = chart.substore || chart.store;
+        return store ? store.getCount() : 0;
     },
 
     
+    isExcluded: function(index) {
+        var excludes = this.__excludes;
+        return !!(excludes && excludes[index]);
+    },
+
     
+    setBBox: function(noGutter) {
+        var me = this,
+            chart = me.chart,
+            chartBBox = chart.chartBBox,
+            gutterX = noGutter ? 0 : chart.maxGutter[0],
+            gutterY = noGutter ? 0 : chart.maxGutter[1],
+            clipBox, bbox;
+
+        clipBox = {
+            x: chartBBox.x,
+            y: chartBBox.y,
+            width: chartBBox.width,
+            height: chartBBox.height
+        };
+        me.clipBox = clipBox;
+
+        bbox = {
+            x: (clipBox.x + gutterX) - (chart.zoom.x * chart.zoom.width),
+            y: (clipBox.y + gutterY) - (chart.zoom.y * chart.zoom.height),
+            width: (clipBox.width - (gutterX * 2)) * chart.zoom.width,
+            height: (clipBox.height - (gutterY * 2)) * chart.zoom.height
+        };
+        me.bbox = bbox;
+    },
+
     
-    doSort: function(sorterFn) {
+    onAnimate: function(sprite, attr) {
         var me = this;
-        if (me.remoteSort) {
-            
-            me.load();
+        sprite.stopAnimation();
+        if (me.triggerAfterDraw) {
+            return sprite.animate(Ext.applyIf(attr, me.chart.animate));
         } else {
-            me.data.sortBy(sorterFn);
-            if (!me.buffered) {
-                var range = me.getRange(),
-                    ln = range.length,
-                    i  = 0;
-                for (; i < ln; i++) {
-                    range[i].index = i;
+            me.triggerAfterDraw = true;
+            return sprite.animate(Ext.apply(Ext.applyIf(attr, me.chart.animate), {
+                listeners: {
+                    'afteranimate': function() {
+                        me.triggerAfterDraw = false;
+                        me.fireEvent('afterrender');
+                    }
                 }
-            }
-            me.fireEvent('datachanged', me);
+            }));
         }
     },
-    
-    
-    find: function(property, value, start, anyMatch, caseSensitive, exactMatch) {
-        var fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch);
-        return fn ? this.data.findIndexBy(fn, null, start) : -1;
-    },
 
     
-    findRecord: function() {
-        var me = this,
-            index = me.find.apply(me, arguments);
-        return index !== -1 ? me.getAt(index) : null;
+    getGutters: function() {
+        return [0, 0];
     },
 
     
-    createFilterFn: function(property, value, anyMatch, caseSensitive, exactMatch) {
-        if (Ext.isEmpty(value)) {
-            return false;
+    onItemMouseOver: function(item) {
+        var me = this;
+        if (item.series === me) {
+            if (me.highlight) {
+                me.highlightItem(item);
+            }
+            if (me.tooltip) {
+                me.showTip(item);
+            }
         }
-        value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch);
-        return function(r) {
-            return value.test(r.data[property]);
-        };
     },
 
     
-    findExact: function(property, value, start) {
-        return this.data.findIndexBy(function(rec) {
-            return rec.get(property) === value;
-        },
-        this, start);
+    onItemMouseOut: function(item) {
+        var me = this;
+        if (item.series === me) {
+            me.unHighlightItem();
+            if (me.tooltip) {
+                me.hideTip(item);
+            }
+        }
     },
 
     
-    findBy: function(fn, scope, start) {
-        return this.data.findIndexBy(fn, scope, start);
+    onMouseLeave: function() {
+        var me = this;
+        me.unHighlightItem();
+        if (me.tooltip) {
+            me.hideTip();
+        }
     },
 
     
-    collect: function(dataIndex, allowNull, bypassFilter) {
+    getItemForPoint: function(x, y) {
+        
+        if (!this.items || !this.items.length || this.seriesIsHidden) {
+            return null;
+        }
         var me = this,
-            data = (bypassFilter === true && me.snapshot) ? me.snapshot: me.data;
+            items = me.items,
+            bbox = me.bbox,
+            item, i, ln;
+        
+        if (!Ext.draw.Draw.withinBox(x, y, bbox)) {
+            return null;
+        }
+        for (i = 0, ln = items.length; i < ln; i++) {
+            if (items[i] && this.isItemInPoint(x, y, items[i], i)) {
+                return items[i];
+            }
+        }
 
-        return data.collect(dataIndex, 'data', allowNull);
+        return null;
     },
 
-    
-    getCount: function() {
-        return this.data.length || 0;
+    isItemInPoint: function(x, y, item, i) {
+        return false;
     },
 
     
-    getTotalCount: function() {
-        return this.totalCount;
-    },
+    hideAll: function() {
+        var me = this,
+            items = me.items,
+            item, len, i, j, l, sprite, shadows;
 
-    
-    getAt: function(index) {
-        return this.data.getAt(index);
-    },
+        me.seriesIsHidden = true;
+        me._prevShowMarkers = me.showMarkers;
 
-    
-    getRange: function(start, end) {
-        return this.data.getRange(start, end);
-    },
+        me.showMarkers = false;
+        
+        me.hideLabels(0);
+        
+        for (i = 0, len = items.length; i < len; i++) {
+            item = items[i];
+            sprite = item.sprite;
+            if (sprite) {
+                sprite.setAttributes({
+                    hidden: true
+                }, true);
+            }
 
-    
-    getById: function(id) {
-        return (this.snapshot || this.data).findBy(function(record) {
-            return record.getId() === id;
-        });
+            if (sprite && sprite.shadows) {
+                shadows = sprite.shadows;
+                for (j = 0, l = shadows.length; j < l; ++j) {
+                    shadows[j].setAttributes({
+                        hidden: true
+                    }, true);
+                }
+            }
+        }
     },
 
     
-    indexOf: function(record) {
-        return this.data.indexOf(record);
+    showAll: function() {
+        var me = this,
+            prevAnimate = me.chart.animate;
+        me.chart.animate = false;
+        me.seriesIsHidden = false;
+        me.showMarkers = me._prevShowMarkers;
+        me.drawSeries();
+        me.chart.animate = prevAnimate;
     },
 
-
     
-    indexOfTotal: function(record) {
-        return record.index || this.indexOf(record);
+    getLegendColor: function(index) {
+        var me = this, fill, stroke;
+        if (me.seriesStyle) {
+            fill = me.seriesStyle.fill;
+            stroke = me.seriesStyle.stroke;
+            if (fill && fill != 'none') {
+                return fill;
+            }
+            return stroke;
+        }
+        return '#000';
     },
 
     
-    indexOfId: function(id) {
-        return this.data.indexOfKey(id);
-    },
-        
-    
-    removeAll: function(silent) {
-        var me = this;
-
-        me.clearData();
-        if (me.snapshot) {
-            me.snapshot.clear();
-        }
-        if (silent !== true) {
-            me.fireEvent('clear', me);
+    visibleInLegend: function(index){
+        var excludes = this.__excludes;
+        if (excludes) {
+            return !excludes[index];
         }
+        return !this.seriesIsHidden;
     },
 
     
+    setTitle: function(index, title) {
+        var me = this,
+            oldTitle = me.title;
 
-    
-    first: function(grouped) {
-        var me = this;
+        if (Ext.isString(index)) {
+            title = index;
+            index = 0;
+        }
 
-        if (grouped && me.isGrouped()) {
-            return me.aggregate(function(records) {
-                return records.length ? records[0] : undefined;
-            }, me, true);
+        if (Ext.isArray(oldTitle)) {
+            oldTitle[index] = title;
         } else {
-            return me.data.first();
+            me.title = title;
         }
-    },
+
+        me.fireEvent('titlechange', title, index);
+    }
+});
+
+
+Ext.define('Ext.chart.series.Cartesian', {
 
     
-    last: function(grouped) {
-        var me = this;
 
-        if (grouped && me.isGrouped()) {
-            return me.aggregate(function(records) {
-                var len = records.length;
-                return len ? records[len - 1] : undefined;
-            }, me, true);
-        } else {
-            return me.data.last();
-        }
-    },
+    extend: 'Ext.chart.series.Series',
+
+    alternateClassName: ['Ext.chart.CartesianSeries', 'Ext.chart.CartesianChart'],
 
     
-    sum: function(field, grouped) {
-        var me = this;
 
-        if (grouped && me.isGrouped()) {
-            return me.aggregate(me.getSum, me, true, [field]);
-        } else {
-            return me.getSum(me.data.items, field);
-        }
-    },
+    
+    xField: null,
 
     
-    getSum: function(records, field) {
-        var total = 0,
-            i = 0,
-            len = records.length;
+    yField: null,
+
+    
+    axis: 'left',
+
+    getLegendLabels: function() {
+        var me = this,
+            labels = [],
+            combinations = me.combinations;
 
-        for (; i < len; ++i) {
-            total += records[i].get(field);
+        Ext.each([].concat(me.yField), function(yField, i) {
+            var title = me.title;
+            
+            labels.push((Ext.isArray(title) ? title[i] : title) || yField);
+        });
+
+        
+        if (combinations) {
+            Ext.each(combinations, function(combo) {
+                var label0 = labels[combo[0]],
+                    label1 = labels[combo[1]];
+                labels[combo[1]] = label0 + ' & ' + label1;
+                labels.splice(combo[0], 1);
+            });
         }
 
-        return total;
+        return labels;
     },
 
     
-    count: function(grouped) {
-        var me = this;
-
-        if (grouped && me.isGrouped()) {
-            return me.aggregate(function(records) {
-                return records.length;
-            }, me, true);
-        } else {
-            return me.getCount();
-        }
+    eachYValue: function(record, fn, scope) {
+        Ext.each(this.getYValueAccessors(), function(accessor, i) {
+            fn.call(scope, accessor(record), i);
+        });
     },
 
     
-    min: function(field, grouped) {
-        var me = this;
-
-        if (grouped && me.isGrouped()) {
-            return me.aggregate(me.getMin, me, true, [field]);
-        } else {
-            return me.getMin(me.data.items, field);
-        }
+    getYValueCount: function() {
+        return this.getYValueAccessors().length;
     },
 
-    
-    getMin: function(records, field){
-        var i = 1,
-            len = records.length,
-            value, min;
+    combine: function(index1, index2) {
+        var me = this,
+            accessors = me.getYValueAccessors(),
+            accessor1 = accessors[index1],
+            accessor2 = accessors[index2];
 
-        if (len > 0) {
-            min = records[0].get(field);
-        }
+        
+        accessors[index2] = function(record) {
+            return accessor1(record) + accessor2(record);
+        };
+        accessors.splice(index1, 1);
 
-        for (; i < len; ++i) {
-            value = records[i].get(field);
-            if (value < min) {
-                min = value;
-            }
+        me.callParent([index1, index2]);
+    },
+
+    clearCombinations: function() {
+        
+        delete this.yValueAccessors;
+        this.callParent();
+    },
+
+    
+    getYValueAccessors: function() {
+        var me = this,
+            accessors = me.yValueAccessors;
+        if (!accessors) {
+            accessors = me.yValueAccessors = [];
+            Ext.each([].concat(me.yField), function(yField) {
+                accessors.push(function(record) {
+                    return record.get(yField);
+                });
+            });
         }
-        return min;
+        return accessors;
     },
 
     
-    max: function(field, grouped) {
-        var me = this;
+    getMinMaxXValues: function() {
+        var me = this,
+            min, max,
+            xField = me.xField;
 
-        if (grouped && me.isGrouped()) {
-            return me.aggregate(me.getMax, me, true, [field]);
+        if (me.getRecordCount() > 0) {
+            min = Infinity;
+            max = -min;
+            me.eachRecord(function(record) {
+                var xValue = record.get(xField);
+                if (xValue > max) {
+                    max = xValue;
+                }
+                if (xValue < min) {
+                    min = xValue;
+                }
+            });
         } else {
-            return me.getMax(me.data.items, field);
+            min = max = 0;
         }
+        return [min, max];
     },
 
     
-    getMax: function(records, field) {
-        var i = 1,
-            len = records.length,
-            value,
-            max;
+    getMinMaxYValues: function() {
+        var me = this,
+            stacked = me.stacked,
+            min, max,
+            positiveTotal, negativeTotal;
 
-        if (len > 0) {
-            max = records[0].get(field);
+        function eachYValueStacked(yValue, i) {
+            if (!me.isExcluded(i)) {
+                if (yValue < 0) {
+                    negativeTotal += yValue;
+                } else {
+                    positiveTotal += yValue;
+                }
+            }
         }
 
-        for (; i < len; ++i) {
-            value = records[i].get(field);
-            if (value > max) {
-                max = value;
+        function eachYValue(yValue, i) {
+            if (!me.isExcluded(i)) {
+                if (yValue > max) {
+                    max = yValue;
+                }
+                if (yValue < min) {
+                    min = yValue;
+                }
             }
         }
-        return max;
-    },
 
-    
-    average: function(field, grouped) {
-        var me = this;
-        if (grouped && me.isGrouped()) {
-            return me.aggregate(me.getAverage, me, true, [field]);
+        if (me.getRecordCount() > 0) {
+            min = Infinity;
+            max = -min;
+            me.eachRecord(function(record) {
+                if (stacked) {
+                    positiveTotal = 0;
+                    negativeTotal = 0;
+                    me.eachYValue(record, eachYValueStacked);
+                    if (positiveTotal > max) {
+                        max = positiveTotal;
+                    }
+                    if (negativeTotal < min) {
+                        min = negativeTotal;
+                    }
+                } else {
+                    me.eachYValue(record, eachYValue);
+                }
+            });
         } else {
-            return me.getAverage(me.data.items, field);
+            min = max = 0;
         }
+        return [min, max];
     },
 
-    
-    getAverage: function(records, field) {
-        var i = 0,
-            len = records.length,
-            sum = 0;
+    getAxesForXAndYFields: function() {
+        var me = this,
+            axes = me.chart.axes,
+            axis = [].concat(me.axis),
+            xAxis, yAxis;
 
-        if (records.length > 0) {
-            for (; i < len; ++i) {
-                sum += records[i].get(field);
+        if (Ext.Array.indexOf(axis, 'top') > -1) {
+            xAxis = 'top';
+        } else if (Ext.Array.indexOf(axis, 'bottom') > -1) {
+            xAxis = 'bottom';
+        } else {
+            if (axes.get('top')) {
+                xAxis = 'top';
+            } else if (axes.get('bottom')) {
+                xAxis = 'bottom';
             }
-            return sum / len;
         }
-        return 0;
-    },
-
-    
-    aggregate: function(fn, scope, grouped, args) {
-        args = args || [];
-        if (grouped && this.isGrouped()) {
-            var groups = this.getGroups(),
-                i = 0,
-                len = groups.length,
-                out = {},
-                group;
 
-            for (; i < len; ++i) {
-                group = groups[i];
-                out[group.name] = fn.apply(scope || this, [group.children].concat(args));
-            }
-            return out;
+        if (Ext.Array.indexOf(axis, 'left') > -1) {
+            yAxis = 'left';
+        } else if (Ext.Array.indexOf(axis, 'right') > -1) {
+            yAxis = 'right';
         } else {
-            return fn.apply(scope || this, [this.data.items].concat(args));
+            if (axes.get('left')) {
+                yAxis = 'left';
+            } else if (axes.get('right')) {
+                yAxis = 'right';
+            }
         }
-    }
-});
 
+        return {
+            xAxis: xAxis,
+            yAxis: yAxis
+        };
+    }
 
-Ext.define('Ext.data.JsonStore',  {
-    extend: 'Ext.data.Store',
-    alias: 'store.json',
-
-    
-    constructor: function(config) {
-        config = config || {};
-
-        Ext.applyIf(config, {
-            proxy: {
-                type  : 'ajax',
-                reader: 'json',
-                writer: 'json'
-            }
-        });
 
-        this.callParent([config]);
-    }
 });
 
 
-Ext.define('Ext.chart.axis.Time', {
+Ext.define('Ext.chart.series.Area', {
 
     
 
-    extend: 'Ext.chart.axis.Category',
-
-    alternateClassName: 'Ext.chart.TimeAxis',
+    extend: 'Ext.chart.series.Cartesian',
 
-    alias: 'axis.time',
+    alias: 'series.area',
 
-    requires: ['Ext.data.Store', 'Ext.data.JsonStore'],
+    requires: ['Ext.chart.axis.Axis', 'Ext.draw.Color', 'Ext.fx.Anim'],
 
     
 
-     
-    calculateByLabelSize: true,
-    
-     
-    dateFormat: false,
-    
-     
-    groupBy: 'year,month,day',
-    
-    
-    aggregateOp: 'sum',
-    
-    
-    fromDate: false,
-    
-    
-    toDate: false,
-    
-    
-    step: [Ext.Date.DAY, 1],
-    
-    
-    constrain: false,
+    type: 'area',
+
     
+    stacked: true,
+
     
-    dateMethods: {
-        'year': function(date) {
-            return date.getFullYear();
-        },
-        'month': function(date) {
-            return date.getMonth() + 1;
-        },
-        'day': function(date) {
-            return date.getDate();
-        },
-        'hour': function(date) {
-            return date.getHours();
-        },
-        'minute': function(date) {
-            return date.getMinutes();
-        },
-        'second': function(date) {
-            return date.getSeconds();
-        },
-        'millisecond': function(date) {
-            return date.getMilliseconds();
+    style: {},
+
+    constructor: function(config) {
+        this.callParent(arguments);
+        var me = this,
+            surface = me.chart.surface,
+            i, l;
+        Ext.apply(me, config, {
+            __excludes: [],
+            highlightCfg: {
+                lineWidth: 3,
+                stroke: '#55c',
+                opacity: 0.8,
+                color: '#f00'
+            }
+        });
+        if (me.highlight) {
+            me.highlightSprite = surface.add({
+                type: 'path',
+                path: ['M', 0, 0],
+                zIndex: 1000,
+                opacity: 0.3,
+                lineWidth: 5,
+                hidden: true,
+                stroke: '#444'
+            });
         }
+        me.group = surface.getGroup(me.seriesId);
     },
+
     
-    
-    aggregateFn: (function() {
-        var etype = (function() {
-            var rgxp = /^\[object\s(.*)\]$/,
-                toString = Object.prototype.toString;
-            return function(e) {
-                return toString.call(e).match(rgxp)[1];
-            };
-        })();
-        return {
-            'sum': function(list) {
-                var i = 0, l = list.length, acum = 0;
-                if (!list.length || etype(list[0]) != 'Number') {
-                    return list[0];
-                }
-                for (; i < l; i++) {
-                    acum += list[i];
-                }
-                return acum;
-            },
-            'max': function(list) {
-                if (!list.length || etype(list[0]) != 'Number') {
-                    return list[0];
-                }
-                return Math.max.apply(Math, list);
-            },
-            'min': function(list) {
-                if (!list.length || etype(list[0]) != 'Number') {
-                    return list[0];
-                }
-                return Math.min.apply(Math, list);
-            },
-            'avg': function(list) {
-                var i = 0, l = list.length, acum = 0;
-                if (!list.length || etype(list[0]) != 'Number') {
-                    return list[0];
+    shrink: function(xValues, yValues, size) {
+        var len = xValues.length,
+            ratio = Math.floor(len / size),
+            i, j,
+            xSum = 0,
+            yCompLen = this.areas.length,
+            ySum = [],
+            xRes = [],
+            yRes = [];
+        
+        for (j = 0; j < yCompLen; ++j) {
+            ySum[j] = 0;
+        }
+        for (i = 0; i < len; ++i) {
+            xSum += xValues[i];
+            for (j = 0; j < yCompLen; ++j) {
+                ySum[j] += yValues[i][j];
+            }
+            if (i % ratio == 0) {
+                
+                xRes.push(xSum/ratio);
+                for (j = 0; j < yCompLen; ++j) {
+                    ySum[j] /= ratio;
                 }
-                for (; i < l; i++) {
-                    acum += list[i];
+                yRes.push(ySum);
+                
+                xSum = 0;
+                for (j = 0, ySum = []; j < yCompLen; ++j) {
+                    ySum[j] = 0;
                 }
-                return acum / l;
             }
+        }
+        return {
+            x: xRes,
+            y: yRes
         };
-    })(),
-    
+    },
+
     
-    constrainDates: function() {
-        var fromDate = Ext.Date.clone(this.fromDate),
-            toDate = Ext.Date.clone(this.toDate),
-            step = this.step,
-            field = this.fields,
-            store = this.chart.store,
-            record, recObj, fieldNames = [],
-            newStore = Ext.create('Ext.data.Store', {
-                model: store.model
-            });
-        
-        var getRecordByDate = (function() {
-            var index = 0, l = store.getCount();
-            return function(date) {
-                var rec, recDate;
-                for (; index < l; index++) {
-                    rec = store.getAt(index);
-                    recDate = rec.get(field);
-                    if (+recDate > +date) {
-                        return false;
-                    } else if (+recDate == +date) {
-                        return rec;
-                    }
-                }
-                return false;
-            };
-        })();
+    getBounds: function() {
+        var me = this,
+            chart = me.chart,
+            store = chart.getChartStore(),
+            areas = [].concat(me.yField),
+            areasLen = areas.length,
+            xValues = [],
+            yValues = [],
+            infinity = Infinity,
+            minX = infinity,
+            minY = infinity,
+            maxX = -infinity,
+            maxY = -infinity,
+            math = Math,
+            mmin = math.min,
+            mmax = math.max,
+            bbox, xScale, yScale, xValue, yValue, areaIndex, acumY, ln, sumValues, clipBox, areaElem;
+
+        me.setBBox();
+        bbox = me.bbox;
+
         
-        if (!this.constrain) {
-            this.chart.filteredStore = this.chart.store;
-            return;
+        if (me.axis) {
+            axis = chart.axes.get(me.axis);
+            if (axis) {
+                out = axis.calcEnds();
+                minY = out.from || axis.prevMin;
+                maxY = mmax(out.to || axis.prevMax, 0);
+            }
         }
 
-        while(+fromDate <= +toDate) {
-            record = getRecordByDate(fromDate);
-            recObj = {};
-            if (record) {
-                newStore.add(record.data);
-            } else {
-                newStore.model.prototype.fields.each(function(f) {
-                    recObj[f.name] = false;
-                });
-                recObj.date = fromDate;
-                newStore.add(recObj);
-            }
-            fromDate = Ext.Date.add(fromDate, step[0], step[1]);
+        if (me.yField && !Ext.isNumber(minY)) {
+            axis = Ext.create('Ext.chart.axis.Axis', {
+                chart: chart,
+                fields: [].concat(me.yField)
+            });
+            out = axis.calcEnds();
+            minY = out.from || axis.prevMin;
+            maxY = mmax(out.to || axis.prevMax, 0);
         }
-         
-        this.chart.filteredStore = newStore;
-    },
-    
-    
-    aggregate: function() {
-        var aggStore = {}, 
-            aggKeys = [], key, value,
-            op = this.aggregateOp,
-            field = this.fields, i,
-            fields = this.groupBy.split(','),
-            curField,
-            recFields = [],
-            recFieldsLen = 0,
-            obj,
-            dates = [],
-            json = [],
-            l = fields.length,
-            dateMethods = this.dateMethods,
-            aggregateFn = this.aggregateFn,
-            store = this.chart.filteredStore || this.chart.store;
-        
-        store.each(function(rec) {
-            
-            if (!recFields.length) {
-                rec.fields.each(function(f) {
-                    recFields.push(f.name);
-                });
-                recFieldsLen = recFields.length;
+
+        if (!Ext.isNumber(minY)) {
+            minY = 0;
+        }
+        if (!Ext.isNumber(maxY)) {
+            maxY = 0;
+        }
+
+        store.each(function(record, i) {
+            xValue = record.get(me.xField);
+            yValue = [];
+            if (typeof xValue != 'number') {
+                xValue = i;
             }
-            
-            value = rec.get(field);
-            
-            for (i = 0; i < l; i++) {
-                if (i == 0) {
-                    key = String(dateMethods[fields[i]](value));
+            xValues.push(xValue);
+            acumY = 0;
+            for (areaIndex = 0; areaIndex < areasLen; areaIndex++) {
+                areaElem = record.get(areas[areaIndex]);
+                if (typeof areaElem == 'number') {
+                    minY = mmin(minY, areaElem);
+                    yValue.push(areaElem);
+                    acumY += areaElem;
+                }
+            }
+            minX = mmin(minX, xValue);
+            maxX = mmax(maxX, xValue);
+            maxY = mmax(maxY, acumY);
+            yValues.push(yValue);
+        }, me);
+
+        xScale = bbox.width / ((maxX - minX) || 1);
+        yScale = bbox.height / ((maxY - minY) || 1);
+
+        ln = xValues.length;
+        if ((ln > bbox.width) && me.areas) {
+            sumValues = me.shrink(xValues, yValues, bbox.width);
+            xValues = sumValues.x;
+            yValues = sumValues.y;
+        }
+
+        return {
+            bbox: bbox,
+            minX: minX,
+            minY: minY,
+            xValues: xValues,
+            yValues: yValues,
+            xScale: xScale,
+            yScale: yScale,
+            areasLen: areasLen
+        };
+    },
+
+    
+    getPaths: function() {
+        var me = this,
+            chart = me.chart,
+            store = chart.getChartStore(),
+            first = true,
+            bounds = me.getBounds(),
+            bbox = bounds.bbox,
+            items = me.items = [],
+            componentPaths = [],
+            componentPath,
+            paths = [],
+            i, ln, x, y, xValue, yValue, acumY, areaIndex, prevAreaIndex, areaElem, path;
+
+        ln = bounds.xValues.length;
+        
+        for (i = 0; i < ln; i++) {
+            xValue = bounds.xValues[i];
+            yValue = bounds.yValues[i];
+            x = bbox.x + (xValue - bounds.minX) * bounds.xScale;
+            acumY = 0;
+            for (areaIndex = 0; areaIndex < bounds.areasLen; areaIndex++) {
+                
+                if (me.__excludes[areaIndex]) {
+                    continue;
+                }
+                if (!componentPaths[areaIndex]) {
+                    componentPaths[areaIndex] = [];
+                }
+                areaElem = yValue[areaIndex];
+                acumY += areaElem;
+                y = bbox.y + bbox.height - (acumY - bounds.minY) * bounds.yScale;
+                if (!paths[areaIndex]) {
+                    paths[areaIndex] = ['M', x, y];
+                    componentPaths[areaIndex].push(['L', x, y]);
                 } else {
-                    key += '||' + dateMethods[fields[i]](value);
+                    paths[areaIndex].push('L', x, y);
+                    componentPaths[areaIndex].push(['L', x, y]);
+                }
+                if (!items[areaIndex]) {
+                    items[areaIndex] = {
+                        pointsUp: [],
+                        pointsDown: [],
+                        series: me
+                    };
                 }
+                items[areaIndex].pointsUp.push([x, y]);
             }
+        }
+
+        
+        for (areaIndex = 0; areaIndex < bounds.areasLen; areaIndex++) {
             
-            if (key in aggStore) {
-                obj = aggStore[key];
-            } else {
-                obj = aggStore[key] = {};
-                aggKeys.push(key);
-                dates.push(value);
+            if (me.__excludes[areaIndex]) {
+                continue;
             }
+            path = paths[areaIndex];
             
-            for (i = 0; i < recFieldsLen; i++) {
-                curField = recFields[i];
-                if (!obj[curField]) {
-                    obj[curField] = [];
-                }
-                if (rec.get(curField) !== undefined) {
-                    obj[curField].push(rec.get(curField));
-                }
+            if (areaIndex == 0 || first) {
+                first = false;
+                path.push('L', x, bbox.y + bbox.height,
+                          'L', bbox.x, bbox.y + bbox.height,
+                          'Z');
             }
-        });
-        
-        for (key in aggStore) {
-            obj = aggStore[key];
-            for (i = 0; i < recFieldsLen; i++) {
-                curField = recFields[i];
-                obj[curField] = aggregateFn[op](obj[curField]);
+            
+            else {
+                componentPath = componentPaths[prevAreaIndex];
+                componentPath.reverse();
+                path.push('L', x, componentPath[0][2]);
+                for (i = 0; i < ln; i++) {
+                    path.push(componentPath[i][0],
+                              componentPath[i][1],
+                              componentPath[i][2]);
+                    items[areaIndex].pointsDown[ln -i -1] = [componentPath[i][1], componentPath[i][2]];
+                }
+                path.push('L', bbox.x, path[2], 'Z');
             }
-            json.push(obj);
+            prevAreaIndex = areaIndex;
         }
-        this.chart.substore = Ext.create('Ext.data.JsonStore', {
-            fields: recFields,
-            data: json
-        });
-        
-        this.dates = dates;
+        return {
+            paths: paths,
+            areasLen: bounds.areasLen
+        };
     },
+
     
-    
-     setLabels: function() {
-        var store = this.chart.substore,
-            fields = this.fields,
-            format = this.dateFormat,
-            labels, i, dates = this.dates,
-            formatFn = Ext.Date.format;
-        this.labels = labels = [];
-        store.each(function(record, i) {
-            if (!format) {
-                labels.push(record.get(fields));
-            } else {
-                labels.push(formatFn(dates[i], format));
-            }
-         }, this);
-     },
+    drawSeries: function() {
+        var me = this,
+            chart = me.chart,
+            store = chart.getChartStore(),
+            surface = chart.surface,
+            animate = chart.animate,
+            group = me.group,
+            endLineStyle = Ext.apply(me.seriesStyle, me.style),
+            colorArrayStyle = me.colorArrayStyle,
+            colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0,
+            areaIndex, areaElem, paths, path, rendererAttributes;
 
-    processView: function() {
-         
-         if (this.constrain) {
-             this.constrainDates();
-             this.aggregate();
-             this.chart.substore = this.chart.filteredStore;
-         } else {
-             this.aggregate();
-         }
-    },
+        me.unHighlightItem();
+        me.cleanHighlights();
 
-     
-     applyData: function() {
-        this.setLabels();
-        var count = this.chart.substore.getCount();
-         return {
-             from: 0,
-             to: count,
-             steps: count - 1,
-             step: 1
-         };
-     }
- });
+        if (!store || !store.getCount()) {
+            return;
+        }
 
+        paths = me.getPaths();
 
+        if (!me.areas) {
+            me.areas = [];
+        }
 
-Ext.define('Ext.chart.series.Series', {
+        for (areaIndex = 0; areaIndex < paths.areasLen; areaIndex++) {
+            
+            if (me.__excludes[areaIndex]) {
+                continue;
+            }
+            if (!me.areas[areaIndex]) {
+                me.items[areaIndex].sprite = me.areas[areaIndex] = surface.add(Ext.apply({}, {
+                    type: 'path',
+                    group: group,
+                    
+                    path: paths.paths[areaIndex],
+                    stroke: endLineStyle.stroke || colorArrayStyle[areaIndex % colorArrayLength],
+                    fill: colorArrayStyle[areaIndex % colorArrayLength]
+                }, endLineStyle || {}));
+            }
+            areaElem = me.areas[areaIndex];
+            path = paths.paths[areaIndex];
+            if (animate) {
+                
+                rendererAttributes = me.renderer(areaElem, false, {
+                    path: path,
+                    
+                    fill: colorArrayStyle[areaIndex % colorArrayLength],
+                    stroke: endLineStyle.stroke || colorArrayStyle[areaIndex % colorArrayLength]
+                }, areaIndex, store);
+                
+                me.animation = me.onAnimate(areaElem, {
+                    to: rendererAttributes
+                });
+            } else {
+                rendererAttributes = me.renderer(areaElem, false, {
+                    path: path,
+                    
+                    hidden: false,
+                    fill: colorArrayStyle[areaIndex % colorArrayLength],
+                    stroke: endLineStyle.stroke || colorArrayStyle[areaIndex % colorArrayLength]
+                }, areaIndex, store);
+                me.areas[areaIndex].setAttributes(rendererAttributes, true);
+            }
+        }
+        me.renderLabels();
+        me.renderCallouts();
+    },
 
     
-
-    mixins: {
-        observable: 'Ext.util.Observable',
-        labels: 'Ext.chart.Label',
-        highlights: 'Ext.chart.Highlight',
-        tips: 'Ext.chart.Tip',
-        callouts: 'Ext.chart.Callout'
+    onAnimate: function(sprite, attr) {
+        sprite.show();
+        return this.callParent(arguments);
     },
 
     
+    onCreateLabel: function(storeItem, item, i, display) {
+        var me = this,
+            group = me.labelsGroup,
+            config = me.label,
+            bbox = me.bbox,
+            endLabelStyle = Ext.apply(config, me.seriesLabelStyle);
 
-    
+        return me.chart.surface.add(Ext.apply({
+            'type': 'text',
+            'text-anchor': 'middle',
+            'group': group,
+            'x': item.point[0],
+            'y': bbox.y + bbox.height / 2
+        }, endLabelStyle || {}));
+    },
 
     
+    onPlaceLabel: function(label, storeItem, item, i, display, animate, index) {
+        var me = this,
+            chart = me.chart,
+            resizing = chart.resizing,
+            config = me.label,
+            format = config.renderer,
+            field = config.field,
+            bbox = me.bbox,
+            x = item.point[0],
+            y = item.point[1],
+            bb, width, height;
 
-    
-    type: null,
+        label.setAttributes({
+            text: format(storeItem.get(field[index])),
+            hidden: true
+        }, true);
 
-    
-    title: null,
+        bb = label.getBBox();
+        width = bb.width / 2;
+        height = bb.height / 2;
 
-    
-    showInLegend: true,
+        x = x - width < bbox.x? bbox.x + width : x;
+        x = (x + width > bbox.x + bbox.width) ? (x - (x + width - bbox.x - bbox.width)) : x;
+        y = y - height < bbox.y? bbox.y + height : y;
+        y = (y + height > bbox.y + bbox.height) ? (y - (y + height - bbox.y - bbox.height)) : y;
 
-    
-    renderer: function(sprite, record, attributes, index, store) {
-        return attributes;
+        if (me.chart.animate && !me.chart.resizing) {
+            label.show(true);
+            me.onAnimate(label, {
+                to: {
+                    x: x,
+                    y: y
+                }
+            });
+        } else {
+            label.setAttributes({
+                x: x,
+                y: y
+            }, true);
+            if (resizing) {
+                me.animation.on('afteranimate', function() {
+                    label.show(true);
+                });
+            } else {
+                label.show(true);
+            }
+        }
     },
 
     
-    shadowAttributes: null,
-    
-    //@private triggerdrawlistener flag
+    onPlaceCallout : function(callout, storeItem, item, i, display, animate, index) {
+        var me = this,
+            chart = me.chart,
+            surface = chart.surface,
+            resizing = chart.resizing,
+            config = me.callouts,
+            items = me.items,
+            prev = (i == 0) ? false : items[i -1].point,
+            next = (i == items.length -1) ? false : items[i +1].point,
+            cur = item.point,
+            dir, norm, normal, a, aprev, anext,
+            bbox = callout.label.getBBox(),
+            offsetFromViz = 30,
+            offsetToSide = 10,
+            offsetBox = 3,
+            boxx, boxy, boxw, boxh,
+            p, clipRect = me.clipRect,
+            x, y;
 
-    triggerAfterDraw: false,
+        
+        if (!prev) {
+            prev = cur;
+        }
+        if (!next) {
+            next = cur;
+        }
+        a = (next[1] - prev[1]) / (next[0] - prev[0]);
+        aprev = (cur[1] - prev[1]) / (cur[0] - prev[0]);
+        anext = (next[1] - cur[1]) / (next[0] - cur[0]);
 
-    
-    
-    constructor: function(config) {
-        var me = this;
-        if (config) {
-            Ext.apply(me, config);
+        norm = Math.sqrt(1 + a * a);
+        dir = [1 / norm, a / norm];
+        normal = [-dir[1], dir[0]];
+
+        
+        if (aprev > 0 && anext < 0 && normal[1] < 0 || aprev < 0 && anext > 0 && normal[1] > 0) {
+            normal[0] *= -1;
+            normal[1] *= -1;
+        } else if (Math.abs(aprev) < Math.abs(anext) && normal[0] < 0 || Math.abs(aprev) > Math.abs(anext) && normal[0] > 0) {
+            normal[0] *= -1;
+            normal[1] *= -1;
         }
+
         
-        me.shadowGroups = [];
+        x = cur[0] + normal[0] * offsetFromViz;
+        y = cur[1] + normal[1] * offsetFromViz;
+
         
-        me.mixins.labels.constructor.call(me, config);
-        me.mixins.highlights.constructor.call(me, config);
-        me.mixins.tips.constructor.call(me, config);
-        me.mixins.callouts.constructor.call(me, config);
+        boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox));
+        boxy = y - bbox.height /2 - offsetBox;
+        boxw = bbox.width + 2 * offsetBox;
+        boxh = bbox.height + 2 * offsetBox;
 
-        me.addEvents({
-            scope: me,
-            itemmouseover: true,
-            itemmouseout: true,
-            itemmousedown: true,
-            itemmouseup: true,
-            mouseleave: true,
-            afterdraw: true,
+        
+        
+        if (boxx < clipRect[0] || (boxx + boxw) > (clipRect[0] + clipRect[2])) {
+            normal[0] *= -1;
+        }
+        if (boxy < clipRect[1] || (boxy + boxh) > (clipRect[1] + clipRect[3])) {
+            normal[1] *= -1;
+        }
 
-            
-            titlechange: true
-        });
+        
+        x = cur[0] + normal[0] * offsetFromViz;
+        y = cur[1] + normal[1] * offsetFromViz;
 
-        me.mixins.observable.constructor.call(me, config);
+        
+        boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox));
+        boxy = y - bbox.height /2 - offsetBox;
+        boxw = bbox.width + 2 * offsetBox;
+        boxh = bbox.height + 2 * offsetBox;
 
-        me.on({
-            scope: me,
-            itemmouseover: me.onItemMouseOver,
-            itemmouseout: me.onItemMouseOut,
-            mouseleave: me.onMouseLeave
-        });
+        
+        callout.lines.setAttributes({
+            path: ["M", cur[0], cur[1], "L", x, y, "Z"]
+        }, true);
+        
+        callout.box.setAttributes({
+            x: boxx,
+            y: boxy,
+            width: boxw,
+            height: boxh
+        }, true);
+        
+        callout.label.setAttributes({
+            x: x + (normal[0] > 0? offsetBox : -(bbox.width + offsetBox)),
+            y: y
+        }, true);
+        for (p in callout) {
+            callout[p].show(true);
+        }
     },
 
-    
-    setBBox: function(noGutter) {
+    isItemInPoint: function(x, y, item, i) {
         var me = this,
-            chart = me.chart,
-            chartBBox = chart.chartBBox,
-            gutterX = noGutter ? 0 : chart.maxGutter[0],
-            gutterY = noGutter ? 0 : chart.maxGutter[1],
-            clipBox, bbox;
-
-        clipBox = {
-            x: chartBBox.x,
-            y: chartBBox.y,
-            width: chartBBox.width,
-            height: chartBBox.height
-        };
-        me.clipBox = clipBox;
-
-        bbox = {
-            x: (clipBox.x + gutterX) - (chart.zoom.x * chart.zoom.width),
-            y: (clipBox.y + gutterY) - (chart.zoom.y * chart.zoom.height),
-            width: (clipBox.width - (gutterX * 2)) * chart.zoom.width,
-            height: (clipBox.height - (gutterY * 2)) * chart.zoom.height
-        };
-        me.bbox = bbox;
-    },
+            pointsUp = item.pointsUp,
+            pointsDown = item.pointsDown,
+            abs = Math.abs,
+            dist = Infinity, p, pln, point;
 
-    
-    onAnimate: function(sprite, attr) {
-        var me = this;
-        sprite.stopAnimation();
-        if (me.triggerAfterDraw) {
-            return sprite.animate(Ext.applyIf(attr, me.chart.animate));
-        } else {
-            me.triggerAfterDraw = true;
-            return sprite.animate(Ext.apply(Ext.applyIf(attr, me.chart.animate), {
-                listeners: {
-                    'afteranimate': function() {
-                        me.triggerAfterDraw = false;
-                        me.fireEvent('afterrender');
-                    }    
-                }    
-            }));
+        for (p = 0, pln = pointsUp.length; p < pln; p++) {
+            point = [pointsUp[p][0], pointsUp[p][1]];
+            if (dist > abs(x - point[0])) {
+                dist = abs(x - point[0]);
+            } else {
+                point = pointsUp[p -1];
+                if (y >= point[1] && (!pointsDown.length || y <= (pointsDown[p -1][1]))) {
+                    item.storeIndex = p -1;
+                    item.storeField = me.yField[i];
+                    item.storeItem = me.chart.store.getAt(p -1);
+                    item._points = pointsDown.length? [point, pointsDown[p -1]] : [point];
+                    return true;
+                } else {
+                    break;
+                }
+            }
         }
-    },
-    
-    
-    getGutters: function() {
-        return [0, 0];
+        return false;
     },
 
     
-    onItemMouseOver: function(item) { 
-        var me = this;
-        if (item.series === me) {
-            if (me.highlight) {
-                me.highlightItem(item);
+    highlightSeries: function() {
+        var area, to, fillColor;
+        if (this._index !== undefined) {
+            area = this.areas[this._index];
+            if (area.__highlightAnim) {
+                area.__highlightAnim.paused = true;
             }
-            if (me.tooltip) {
-                me.showTip(item);
+            area.__highlighted = true;
+            area.__prevOpacity = area.__prevOpacity || area.attr.opacity || 1;
+            area.__prevFill = area.__prevFill || area.attr.fill;
+            area.__prevLineWidth = area.__prevLineWidth || area.attr.lineWidth;
+            fillColor = Ext.draw.Color.fromString(area.__prevFill);
+            to = {
+                lineWidth: (area.__prevLineWidth || 0) + 2
+            };
+            if (fillColor) {
+                to.fill = fillColor.getLighter(0.2).toString();
+            }
+            else {
+                to.opacity = Math.max(area.__prevOpacity - 0.3, 0);
+            }
+            if (this.chart.animate) {
+                area.__highlightAnim = Ext.create('Ext.fx.Anim', Ext.apply({
+                    target: area,
+                    to: to
+                }, this.chart.animate));
+            }
+            else {
+                area.setAttributes(to, true);
             }
         }
     },
 
     
-    onItemMouseOut: function(item) {
-        var me = this;
-        if (item.series === me) {
-            me.unHighlightItem();
-            if (me.tooltip) {
-                me.hideTip(item);
+    unHighlightSeries: function() {
+        var area;
+        if (this._index !== undefined) {
+            area = this.areas[this._index];
+            if (area.__highlightAnim) {
+                area.__highlightAnim.paused = true;
+            }
+            if (area.__highlighted) {
+                area.__highlighted = false;
+                area.__highlightAnim = Ext.create('Ext.fx.Anim', {
+                    target: area,
+                    to: {
+                        fill: area.__prevFill,
+                        opacity: area.__prevOpacity,
+                        lineWidth: area.__prevLineWidth
+                    }
+                });
             }
         }
     },
 
     
-    onMouseLeave: function() {
-        var me = this;
-        me.unHighlightItem();
-        if (me.tooltip) {
-            me.hideTip();
+    highlightItem: function(item) {
+        var me = this,
+            points, path;
+        if (!item) {
+            this.highlightSeries();
+            return;
         }
+        points = item._points;
+        path = points.length == 2? ['M', points[0][0], points[0][1], 'L', points[1][0], points[1][1]]
+                : ['M', points[0][0], points[0][1], 'L', points[0][0], me.bbox.y + me.bbox.height];
+        me.highlightSprite.setAttributes({
+            path: path,
+            hidden: false
+        }, true);
     },
 
     
-    getItemForPoint: function(x, y) {
-        
-        if (!this.items || !this.items.length || this.seriesIsHidden) {
-            return null;
-        }
-        var me = this,
-            items = me.items,
-            bbox = me.bbox,
-            item, i, ln;
-        
-        if (!Ext.draw.Draw.withinBox(x, y, bbox)) {
-            return null;
+    unHighlightItem: function(item) {
+        if (!item) {
+            this.unHighlightSeries();
         }
-        for (i = 0, ln = items.length; i < ln; i++) {
-            if (items[i] && this.isItemInPoint(x, y, items[i], i)) {
-                return items[i];
-            }
+
+        if (this.highlightSprite) {
+            this.highlightSprite.hide(true);
         }
-        
-        return null;
-    },
-    
-    isItemInPoint: function(x, y, item, i) {
-        return false;
     },
 
     
     hideAll: function() {
-        var me = this,
-            items = me.items,
-            item, len, i, sprite;
-
-        me.seriesIsHidden = true;
-        me._prevShowMarkers = me.showMarkers;
-
-        me.showMarkers = false;
-        
-        me.hideLabels(0);
-        
-        for (i = 0, len = items.length; i < len; i++) {
-            item = items[i];
-            sprite = item.sprite;
-            if (sprite) {
-                sprite.setAttributes({
-                    hidden: true
-                }, true);
-            }
+        if (!isNaN(this._index)) {
+            this.__excludes[this._index] = true;
+            this.areas[this._index].hide(true);
+            this.drawSeries();
         }
     },
 
     
     showAll: function() {
-        var me = this,
-            prevAnimate = me.chart.animate;
-        me.chart.animate = false;
-        me.seriesIsHidden = false;
-        me.showMarkers = me._prevShowMarkers;
-        me.drawSeries();
-        me.chart.animate = prevAnimate;
-    },
-    
-    
-    getLegendColor: function(index) {
-        var me = this, fill, stroke;
-        if (me.seriesStyle) {
-            fill = me.seriesStyle.fill;
-            stroke = me.seriesStyle.stroke;
-            if (fill && fill != 'none') {
-                return fill;
-            }
-            return stroke;
-        }
-        return '#000';
-    },
-    
-    
-    visibleInLegend: function(index){
-        var excludes = this.__excludes;
-        if (excludes) {
-            return !excludes[index];
+        if (!isNaN(this._index)) {
+            this.__excludes[this._index] = false;
+            this.areas[this._index].show(true);
+            this.drawSeries();
         }
-        return !this.seriesIsHidden;
     },
 
     
-    setTitle: function(index, title) {
-        var me = this,
-            oldTitle = me.title;
-
-        if (Ext.isString(index)) {
-            title = index;
-            index = 0;
-        }
-
-        if (Ext.isArray(oldTitle)) {
-            oldTitle[index] = title;
-        } else {
-            me.title = title;
-        }
-
-        me.fireEvent('titlechange', title, index);
+    getLegendColor: function(index) {
+        var me = this;
+        return me.colorArrayStyle[index % me.colorArrayStyle.length];
     }
 });
 
-
-Ext.define('Ext.chart.series.Cartesian', {
-
-    
-
-    extend: 'Ext.chart.series.Series',
-
-    alternateClassName: ['Ext.chart.CartesianSeries', 'Ext.chart.CartesianChart'],
-
-    
-
-    
-    xField: null,
-
-    
-    yField: null,
-
-    
-    axis: 'left'
-});
-
-
 Ext.define('Ext.chart.series.Area', {
 
     
 
     extend: 'Ext.chart.series.Cartesian',
-    
+
     alias: 'series.area',
 
     requires: ['Ext.chart.axis.Axis', 'Ext.draw.Color', 'Ext.fx.Anim'],
@@ -45484,7 +47553,7 @@ Ext.define('Ext.chart.series.Area', {
     getBounds: function() {
         var me = this,
             chart = me.chart,
-            store = chart.substore || chart.store,
+            store = chart.getChartStore(),
             areas = [].concat(me.yField),
             areasLen = areas.length,
             xValues = [],
@@ -45551,8 +47620,8 @@ Ext.define('Ext.chart.series.Area', {
             yValues.push(yValue);
         }, me);
 
-        xScale = bbox.width / (maxX - minX);
-        yScale = bbox.height / (maxY - minY);
+        xScale = bbox.width / ((maxX - minX) || 1);
+        yScale = bbox.height / ((maxY - minY) || 1);
 
         ln = xValues.length;
         if ((ln > bbox.width) && me.areas) {
@@ -45577,7 +47646,7 @@ Ext.define('Ext.chart.series.Area', {
     getPaths: function() {
         var me = this,
             chart = me.chart,
-            store = chart.substore || chart.store,
+            store = chart.getChartStore(),
             first = true,
             bounds = me.getBounds(),
             bbox = bounds.bbox,
@@ -45622,7 +47691,7 @@ Ext.define('Ext.chart.series.Area', {
                 items[areaIndex].pointsUp.push([x, y]);
             }
         }
-        
+
         
         for (areaIndex = 0; areaIndex < bounds.areasLen; areaIndex++) {
             
@@ -45662,7 +47731,7 @@ Ext.define('Ext.chart.series.Area', {
     drawSeries: function() {
         var me = this,
             chart = me.chart,
-            store = chart.substore || chart.store,
+            store = chart.getChartStore(),
             surface = chart.surface,
             animate = chart.animate,
             group = me.group,
@@ -45677,7 +47746,7 @@ Ext.define('Ext.chart.series.Area', {
         if (!store || !store.getCount()) {
             return;
         }
-        
+
         paths = me.getPaths();
 
         if (!me.areas) {
@@ -45703,7 +47772,7 @@ Ext.define('Ext.chart.series.Area', {
             path = paths.paths[areaIndex];
             if (animate) {
                 
-                rendererAttributes = me.renderer(areaElem, false, { 
+                rendererAttributes = me.renderer(areaElem, false, {
                     path: path,
                     
                     fill: colorArrayStyle[areaIndex % colorArrayLength],
@@ -45714,7 +47783,7 @@ Ext.define('Ext.chart.series.Area', {
                     to: rendererAttributes
                 });
             } else {
-                rendererAttributes = me.renderer(areaElem, false, { 
+                rendererAttributes = me.renderer(areaElem, false, {
                     path: path,
                     
                     hidden: false,
@@ -45763,16 +47832,16 @@ Ext.define('Ext.chart.series.Area', {
             x = item.point[0],
             y = item.point[1],
             bb, width, height;
-        
+
         label.setAttributes({
             text: format(storeItem.get(field[index])),
             hidden: true
         }, true);
-        
+
         bb = label.getBBox();
         width = bb.width / 2;
         height = bb.height / 2;
-        
+
         x = x - width < bbox.x? bbox.x + width : x;
         x = (x + width > bbox.x + bbox.width) ? (x - (x + width - bbox.x - bbox.width)) : x;
         y = y - height < bbox.y? bbox.y + height : y;
@@ -45831,11 +47900,11 @@ Ext.define('Ext.chart.series.Area', {
         a = (next[1] - prev[1]) / (next[0] - prev[0]);
         aprev = (cur[1] - prev[1]) / (cur[0] - prev[0]);
         anext = (next[1] - cur[1]) / (next[0] - cur[0]);
-        
+
         norm = Math.sqrt(1 + a * a);
         dir = [1 / norm, a / norm];
         normal = [-dir[1], dir[0]];
-        
+
         
         if (aprev > 0 && anext < 0 && normal[1] < 0 || aprev < 0 && anext > 0 && normal[1] > 0) {
             normal[0] *= -1;
@@ -45848,13 +47917,13 @@ Ext.define('Ext.chart.series.Area', {
         
         x = cur[0] + normal[0] * offsetFromViz;
         y = cur[1] + normal[1] * offsetFromViz;
-        
+
         
         boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox));
         boxy = y - bbox.height /2 - offsetBox;
         boxw = bbox.width + 2 * offsetBox;
         boxh = bbox.height + 2 * offsetBox;
-        
+
         
         
         if (boxx < clipRect[0] || (boxx + boxw) > (clipRect[0] + clipRect[2])) {
@@ -45867,13 +47936,13 @@ Ext.define('Ext.chart.series.Area', {
         
         x = cur[0] + normal[0] * offsetFromViz;
         y = cur[1] + normal[1] * offsetFromViz;
-        
+
         
         boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox));
         boxy = y - bbox.height /2 - offsetBox;
         boxw = bbox.width + 2 * offsetBox;
         boxh = bbox.height + 2 * offsetBox;
-        
+
         
         callout.lines.setAttributes({
             path: ["M", cur[0], cur[1], "L", x, y, "Z"]
@@ -45894,14 +47963,14 @@ Ext.define('Ext.chart.series.Area', {
             callout[p].show(true);
         }
     },
-    
+
     isItemInPoint: function(x, y, item, i) {
         var me = this,
             pointsUp = item.pointsUp,
             pointsDown = item.pointsDown,
             abs = Math.abs,
             dist = Infinity, p, pln, point;
-        
+
         for (p = 0, pln = pointsUp.length; p < pln; p++) {
             point = [pointsUp[p][0], pointsUp[p][1]];
             if (dist > abs(x - point[0])) {
@@ -46049,10 +48118,10 @@ Ext.define('Ext.chart.series.Bar', {
     alias: 'series.bar',
     
     column: false,
-    
+
     
     style: {},
-    
+
     
     gutter: 38.2,
 
@@ -46078,7 +48147,7 @@ Ext.define('Ext.chart.series.Bar', {
                 opacity: 0.8,
                 color: '#f00'
             },
-            
+
             shadowAttributes: [{
                 "stroke-width": 6,
                 "stroke-opacity": 0.05,
@@ -46116,11 +48185,11 @@ Ext.define('Ext.chart.series.Bar', {
     
     getBarGirth: function() {
         var me = this,
-            store = me.chart.store,
+            store = me.chart.getChartStore(),
             column = me.column,
             ln = store.getCount(),
             gutter = me.gutter / 100;
-        
+
         return (me.chart.chartBBox[column ? 'width' : 'height'] - me[column ? 'xPadding' : 'yPadding'] * 2) / (ln * (gutter + 1) - gutter);
     },
 
@@ -46136,7 +48205,7 @@ Ext.define('Ext.chart.series.Bar', {
     getBounds: function() {
         var me = this,
             chart = me.chart,
-            store = chart.substore || chart.store,
+            store = chart.getChartStore(),
             bars = [].concat(me.yField),
             barsLen = bars.length,
             groupBarsLen = barsLen,
@@ -46168,8 +48237,8 @@ Ext.define('Ext.chart.series.Bar', {
             axis = chart.axes.get(me.axis);
             if (axis) {
                 out = axis.calcEnds();
-                minY = out.from || axis.prevMin;
-                maxY = mmax(out.to || axis.prevMax, 0);
+                minY = out.from;
+                maxY = out.to;
             }
         }
 
@@ -46179,8 +48248,8 @@ Ext.define('Ext.chart.series.Bar', {
                 fields: [].concat(me.yField)
             });
             out = axis.calcEnds();
-            minY = out.from || axis.prevMin;
-            maxY = mmax(out.to || axis.prevMax, 0);
+            minY = out.from;
+            maxY = out.to;
         }
 
         if (!Ext.isNumber(minY)) {
@@ -46237,7 +48306,7 @@ Ext.define('Ext.chart.series.Bar', {
     getPaths: function() {
         var me = this,
             chart = me.chart,
-            store = chart.substore || chart.store,
+            store = chart.getChartStore(),
             bounds = me.bounds = me.getBounds(),
             items = me.items = [],
             gutter = me.gutter / 100,
@@ -46268,14 +48337,14 @@ Ext.define('Ext.chart.series.Bar', {
             top = bounds.zero;
             totalDim = 0;
             totalNegDim = 0;
-            hasShadow = false; 
+            hasShadow = false;
             for (j = 0, counter = 0; j < barsLen; j++) {
                 
                 if (me.__excludes && me.__excludes[j]) {
                     continue;
                 }
                 yValue = record.get(bounds.bars[j]);
-                height = Math.round((yValue - ((bounds.minY < 0) ? 0 : bounds.minY)) * bounds.scale);
+                height = Math.round((yValue - mmax(bounds.minY, 0)) * bounds.scale);
                 barAttr = {
                     fill: colors[(barsLen > 1 ? j : 0) % colorLength]
                 };
@@ -46381,7 +48450,7 @@ Ext.define('Ext.chart.series.Bar', {
             shadowGroups = me.shadowGroups,
             shadowAttributes = me.shadowAttributes,
             shadowGroupsLn = shadowGroups.length,
-            store = chart.substore || chart.store,
+            store = chart.getChartStore(),
             column = me.column,
             items = me.items,
             shadows = [],
@@ -46437,7 +48506,7 @@ Ext.define('Ext.chart.series.Bar', {
     drawSeries: function() {
         var me = this,
             chart = me.chart,
-            store = chart.substore || chart.store,
+            store = chart.getChartStore(),
             surface = chart.surface,
             animate = chart.animate,
             stacked = me.stacked,
@@ -46449,11 +48518,11 @@ Ext.define('Ext.chart.series.Bar', {
             seriesStyle = me.seriesStyle,
             items, ln, i, j, baseAttrs, sprite, rendererAttributes, shadowIndex, shadowGroup,
             bounds, endSeriesStyle, barAttr, attrs, anim;
-        
+
         if (!store || !store.getCount()) {
             return;
         }
-        
+
         
         delete seriesStyle.fill;
         endSeriesStyle = Ext.apply(seriesStyle, this.style);
@@ -46527,7 +48596,7 @@ Ext.define('Ext.chart.series.Bar', {
         }
         me.renderLabels();
     },
-    
+
     
     onCreateLabel: function(storeItem, item, i, display) {
         var me = this,
@@ -46541,9 +48610,9 @@ Ext.define('Ext.chart.series.Bar', {
             group: group
         }, endLabelStyle || {}));
     },
+
     
-    
-    onPlaceLabel: function(label, storeItem, item, i, display, animate, index) {
+    onPlaceLabel: function(label, storeItem, item, i, display, animate, j, index) {
         
         
         var me = this,
@@ -46577,6 +48646,7 @@ Ext.define('Ext.chart.series.Bar', {
             text: text
         });
 
+        label.isOutside = false;
         if (column) {
             if (display == outside) {
                 if (height + offsetY + attr.height > (yValue >= 0 ? zero - chartBBox.y : chartBBox.y + chartBBox.height - zero)) {
@@ -46585,6 +48655,7 @@ Ext.define('Ext.chart.series.Bar', {
             } else {
                 if (height + offsetY > attr.height) {
                     display = outside;
+                    label.isOutside = true;
                 }
             }
             x = attr.x + groupBarWidth / 2;
@@ -46602,6 +48673,7 @@ Ext.define('Ext.chart.series.Bar', {
             else {
                 if (width + offsetX > attr.width) {
                     display = outside;
+                    label.isOutside = true;
                 }
             }
             x = display == insideStart ?
@@ -46690,14 +48762,14 @@ Ext.define('Ext.chart.series.Bar', {
         sprite.show();
         return this.callParent(arguments);
     },
-    
+
     isItemInPoint: function(x, y, item) {
         var bbox = item.sprite.getBBox();
         return bbox.x <= x && bbox.y <= y
             && (bbox.x + bbox.width) >= x
             && (bbox.y + bbox.height) >= y;
     },
-    
+
     
     hideAll: function() {
         var axes = this.chart.axes;
@@ -46727,15 +48799,35 @@ Ext.define('Ext.chart.series.Bar', {
             });
         }
     },
-    
+
     
     getLegendColor: function(index) {
-        var me = this;
-        return me.colorArrayStyle[index % me.colorArrayStyle.length];
+        var me = this,
+            colorLength = me.colorArrayStyle.length;
+
+        if (me.style && me.style.fill) {
+            return me.style.fill;
+        } else {
+            return me.colorArrayStyle[index % colorLength];
+        }
+    },
+
+    highlightItem: function(item) {
+        this.callParent(arguments);
+        this.renderLabels();
+    },
+
+    unHighlightItem: function() {
+        this.callParent(arguments);
+        this.renderLabels();
+    },
+
+    cleanHighlights: function() {
+        this.callParent(arguments);
+        this.renderLabels();
     }
 });
 
-
 Ext.define('Ext.chart.series.Column', {
 
     
@@ -46840,7 +48932,7 @@ Ext.define('Ext.chart.series.Gauge', {
 
     initialize: function() {
         var me = this,
-            store = me.chart.substore || me.chart.store;
+            store = me.chart.getChartStore();
         
         me.yField = [];
         if (me.label.field) {
@@ -46939,7 +49031,7 @@ Ext.define('Ext.chart.series.Gauge', {
     drawSeries: function() {
         var me = this,
             chart = me.chart,
-            store = chart.substore || chart.store,
+            store = chart.getChartStore(),
             group = me.group,
             animate = me.chart.animate,
             axis = me.chart.axes.get(0),
@@ -47153,7 +49245,6 @@ Ext.define('Ext.chart.series.Gauge', {
 
 
 
-
 Ext.define('Ext.chart.series.Line', {
 
     
@@ -47167,12 +49258,14 @@ Ext.define('Ext.chart.series.Line', {
     
 
     type: 'line',
-    
+
     alias: 'series.line',
 
     
-    selectionTolerance: 20,
+
     
+    selectionTolerance: 20,
+
     
     showMarkers: true,
 
@@ -47181,11 +49274,14 @@ Ext.define('Ext.chart.series.Line', {
 
     
     style: {},
-    
+
     
     smooth: false,
 
     
+    defaultSmoothness: 3,
+
+    
     fill: false,
 
     constructor: function(config) {
@@ -47229,12 +49325,12 @@ Ext.define('Ext.chart.series.Line', {
             me.markerGroup = surface.getGroup(me.seriesId + '-markers');
         }
         if (shadow) {
-            for (i = 0, l = this.shadowAttributes.length; i < l; i++) {
+            for (i = 0, l = me.shadowAttributes.length; i < l; i++) {
                 me.shadowGroups.push(surface.getGroup(me.seriesId + '-shadows' + i));
             }
         }
     },
-    
+
     
     shrink: function(xValues, yValues, size) {
         
@@ -47245,7 +49341,7 @@ Ext.define('Ext.chart.series.Line', {
             ySum = 0,
             xRes = [xValues[0]],
             yRes = [yValues[0]];
-        
+
         for (; i < len; ++i) {
             xSum += xValues[i] || 0;
             ySum += yValues[i] || 0;
@@ -47266,48 +49362,68 @@ Ext.define('Ext.chart.series.Line', {
     drawSeries: function() {
         var me = this,
             chart = me.chart,
-            store = chart.substore || chart.store,
-            surface = chart.surface,
-            chartBBox = chart.chartBBox,
+            chartAxes = chart.axes,
+            store = chart.getChartStore(),
+            storeCount = store.getCount(),
+            surface = me.chart.surface,
             bbox = {},
             group = me.group,
-            gutterX = chart.maxGutter[0],
-            gutterY = chart.maxGutter[1],
             showMarkers = me.showMarkers,
             markerGroup = me.markerGroup,
             enableShadows = chart.shadow,
             shadowGroups = me.shadowGroups,
-            shadowAttributes = this.shadowAttributes,
+            shadowAttributes = me.shadowAttributes,
+            smooth = me.smooth,
             lnsh = shadowGroups.length,
             dummyPath = ["M"],
             path = ["M"],
+            renderPath = ["M"],
+            smoothPath = ["M"],
             markerIndex = chart.markerIndex,
             axes = [].concat(me.axis),
-            shadowGroup,
             shadowBarAttr,
             xValues = [],
+            xValueMap = {},
             yValues = [],
+            yValueMap = {},
             onbreak = false,
+            storeIndices = [],
             markerStyle = me.markerStyle,
-            seriesStyle = me.seriesStyle,
-            seriesLabelStyle = me.seriesLabelStyle,
+            seriesStyle = me.style,
             colorArrayStyle = me.colorArrayStyle,
             colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0,
-            seriesIdx = me.seriesIdx, shadows, shadow, shindex, fromPath, fill, fillPath, rendererAttributes,
-            x, y, prevX, prevY, firstY, markerCount, i, j, ln, axis, ends, marker, markerAux, item, xValue,
+            isNumber = Ext.isNumber,
+            seriesIdx = me.seriesIdx, 
+            boundAxes = me.getAxesForXAndYFields(),
+            boundXAxis = boundAxes.xAxis,
+            boundYAxis = boundAxes.yAxis,
+            shadows, shadow, shindex, fromPath, fill, fillPath, rendererAttributes,
+            x, y, prevX, prevY, firstX, firstY, markerCount, i, j, ln, axis, ends, marker, markerAux, item, xValue,
             yValue, coords, xScale, yScale, minX, maxX, minY, maxY, line, animation, endMarkerStyle,
-            endLineStyle, type, props, firstMarker;
-        
-        
-        if (!store || !store.getCount()) {
+            endLineStyle, type, count, items;
+
+        if (me.fireEvent('beforedraw', me) === false) {
             return;
         }
+
         
+        if (!storeCount || me.seriesIsHidden) {
+            items = this.items;
+            if (items) {
+                for (i = 0, ln = items.length; i < ln; ++i) {
+                    if (items[i].sprite) {
+                        items[i].sprite.hide(true);
+                    }
+                }
+            }
+            return;
+        }
+
         
-        endMarkerStyle = Ext.apply(markerStyle, me.markerConfig);
+        endMarkerStyle = Ext.apply(markerStyle || {}, me.markerConfig);
         type = endMarkerStyle.type;
         delete endMarkerStyle.type;
-        endLineStyle = Ext.apply(seriesStyle, me.style);
+        endLineStyle = seriesStyle;
         
         
         if (!endLineStyle['stroke-width']) {
@@ -47331,17 +49447,15 @@ Ext.define('Ext.chart.series.Line', {
                 }, true);
             }
         }
-        
+
         me.unHighlightItem();
         me.cleanHighlights();
 
         me.setBBox();
         bbox = me.bbox;
-
         me.clipRect = [bbox.x, bbox.y, bbox.width, bbox.height];
-
-        for (i = 0, ln = axes.length; i < ln; i++) { 
-            axis = chart.axes.get(axes[i]);
+        for (i = 0, ln = axes.length; i < ln; i++) {
+            axis = chartAxes.get(axes[i]);
             if (axis) {
                 ends = axis.calcEnds();
                 if (axis.position == 'top' || axis.position == 'bottom') {
@@ -47357,8 +49471,9 @@ Ext.define('Ext.chart.series.Line', {
         
         
         
-        if (me.xField && !Ext.isNumber(minX)
-            && (me.axis == 'bottom' || me.axis == 'top')) {
+        if (me.xField && !isNumber(minX) &&
+            (boundXAxis == 'bottom' || boundXAxis == 'top') && 
+            !chartAxes.get(boundXAxis)) {
             axis = Ext.create('Ext.chart.axis.Axis', {
                 chart: chart,
                 fields: [].concat(me.xField)
@@ -47366,8 +49481,9 @@ Ext.define('Ext.chart.series.Line', {
             minX = axis.from;
             maxX = axis.to;
         }
-        if (me.yField && !Ext.isNumber(minY)
-            && (me.axis == 'right' || me.axis == 'left')) {
+        if (me.yField && !isNumber(minY) &&
+            (boundYAxis == 'right' || boundYAxis == 'left') &&
+            !chartAxes.get(boundYAxis)) {
             axis = Ext.create('Ext.chart.axis.Axis', {
                 chart: chart,
                 fields: [].concat(me.yField)
@@ -47375,47 +49491,53 @@ Ext.define('Ext.chart.series.Line', {
             minY = axis.from;
             maxY = axis.to;
         }
-
         if (isNaN(minX)) {
             minX = 0;
-            xScale = bbox.width / (store.getCount() - 1);
+            xScale = bbox.width / ((storeCount - 1) || 1);
         }
         else {
-            xScale = bbox.width / (maxX - minX);
+            xScale = bbox.width / ((maxX - minX) || (storeCount -1) || 1);
         }
 
         if (isNaN(minY)) {
             minY = 0;
-            yScale = bbox.height / (store.getCount() - 1);
-        } 
+            yScale = bbox.height / ((storeCount - 1) || 1);
+        }
         else {
-            yScale = bbox.height / (maxY - minY);
+            yScale = bbox.height / ((maxY - minY) || (storeCount - 1) || 1);
         }
 
-        store.each(function(record, i) {
+        
+        me.eachRecord(function(record, i) {
             xValue = record.get(me.xField);
+
+            
+            if (typeof xValue == 'string' || typeof xValue == 'object' && !Ext.isDate(xValue)
+                
+                || boundXAxis && chartAxes.get(boundXAxis) && chartAxes.get(boundXAxis).type == 'Category') {
+                    if (xValue in xValueMap) {
+                        xValue = xValueMap[xValue];
+                    } else {
+                        xValue = xValueMap[xValue] = i;
+                    }
+            }
+
+            
             yValue = record.get(me.yField);
             
             if (typeof yValue == 'undefined' || (typeof yValue == 'string' && !yValue)) {
-                if (Ext.isDefined(Ext.global.console)) {
-                    Ext.global.console.warn("[Ext.chart.series.Line]  Skipping a store element with an undefined value at ", record, xValue, yValue);
-                }
                 return;
             }
             
-            if (typeof xValue == 'string' || typeof xValue == 'object'
-                
-                || (me.axis != 'top' && me.axis != 'bottom')) {
-                xValue = i;
-            }
-            if (typeof yValue == 'string' || typeof yValue == 'object'
+            if (typeof yValue == 'string' || typeof yValue == 'object' && !Ext.isDate(yValue)
                 
-                || (me.axis != 'left' && me.axis != 'right')) {
+                || boundYAxis && chartAxes.get(boundYAxis) && chartAxes.get(boundYAxis).type == 'Category') {
                 yValue = i;
             }
+            storeIndices.push(i);
             xValues.push(xValue);
             yValues.push(yValue);
-        }, me);
+        });
 
         ln = xValues.length;
         if (ln > bbox.width) {
@@ -47426,6 +49548,7 @@ Ext.define('Ext.chart.series.Line', {
 
         me.items = [];
 
+        count = 0;
         ln = xValues.length;
         for (i = 0; i < ln; i++) {
             xValue = xValues[i];
@@ -47443,11 +49566,12 @@ Ext.define('Ext.chart.series.Line', {
                 if (onbreak) {
                     onbreak = false;
                     path.push('M');
-                } 
+                }
                 path = path.concat([x, y]);
             }
             if ((typeof firstY == 'undefined') && (typeof y != 'undefined')) {
                 firstY = y;
+                firstX = x;
             }
             
             if (!me.line || chart.resizing) {
@@ -47476,21 +49600,22 @@ Ext.define('Ext.chart.series.Line', {
                 }
             }
             if (showMarkers) {
-                marker = markerGroup.getAt(i);
+                marker = markerGroup.getAt(count++);
                 if (!marker) {
                     marker = Ext.chart.Shape[type](surface, Ext.apply({
                         group: [group, markerGroup],
                         x: 0, y: 0,
                         translate: {
-                            x: prevX || x, 
+                            x: +(prevX || x),
                             y: prevY || (bbox.y + bbox.height / 2)
                         },
-                        value: '"' + xValue + ', ' + yValue + '"'
+                        value: '"' + xValue + ', ' + yValue + '"',
+                        zIndex: 4000
                     }, endMarkerStyle));
                     marker._to = {
                         translate: {
-                            x: x,
-                            y: y
+                            x: +x,
+                            y: +y
                         }
                     };
                 } else {
@@ -47501,7 +49626,8 @@ Ext.define('Ext.chart.series.Line', {
                     }, true);
                     marker._to = {
                         translate: {
-                            x: x, y: y
+                            x: +x, 
+                            y: +y
                         }
                     };
                 }
@@ -47511,25 +49637,29 @@ Ext.define('Ext.chart.series.Line', {
                 value: [xValue, yValue],
                 point: [x, y],
                 sprite: marker,
-                storeItem: store.getAt(i)
+                storeItem: store.getAt(storeIndices[i])
             });
             prevX = x;
             prevY = y;
         }
-        
+
         if (path.length <= 1) {
             
-            return;    
+            return;
         }
-        
+
         if (me.smooth) {
-            path = Ext.draw.Draw.smooth(path, 6);
+            smoothPath = Ext.draw.Draw.smooth(path, isNumber(smooth) ? smooth : me.defaultSmoothness);
         }
-        
+
+        renderPath = smooth ? smoothPath : path;
+
         
         if (chart.markerIndex && me.previousPath) {
             fromPath = me.previousPath;
-            fromPath.splice(1, 2);
+            if (!smooth) {
+                Ext.Array.erase(fromPath, 1, 2);
+            }
         } else {
             fromPath = path;
         }
@@ -47542,9 +49672,15 @@ Ext.define('Ext.chart.series.Line', {
                 path: dummyPath,
                 stroke: endLineStyle.stroke || endLineStyle.fill
             }, endLineStyle || {}));
+
+            if (enableShadows) {
+                me.line.setAttributes(Ext.apply({}, me.shadowOptions), true);
+            }
+
             
             me.line.setAttributes({
-                fill: 'none'
+                fill: 'none',
+                zIndex: 3000
             });
             if (!endLineStyle.stroke && colorArrayLength) {
                 me.line.setAttributes({
@@ -47553,11 +49689,11 @@ Ext.define('Ext.chart.series.Line', {
             }
             if (enableShadows) {
                 
-                shadows = me.line.shadows = [];                
+                shadows = me.line.shadows = [];
                 for (shindex = 0; shindex < lnsh; shindex++) {
                     shadowBarAttr = shadowAttributes[shindex];
                     shadowBarAttr = Ext.apply({}, shadowBarAttr, { path: dummyPath });
-                    shadow = chart.surface.add(Ext.apply({}, {
+                    shadow = surface.add(Ext.apply({}, {
                         type: 'path',
                         group: shadowGroups[shindex]
                     }, shadowBarAttr));
@@ -47566,17 +49702,17 @@ Ext.define('Ext.chart.series.Line', {
             }
         }
         if (me.fill) {
-            fillPath = path.concat([
+            fillPath = renderPath.concat([
                 ["L", x, bbox.y + bbox.height],
-                ["L", bbox.x, bbox.y + bbox.height],
-                ["L", bbox.x, firstY]
+                ["L", firstX, bbox.y + bbox.height],
+                ["L", firstX, firstY]
             ]);
             if (!me.fillPath) {
                 me.fillPath = surface.add({
                     group: group,
                     type: 'path',
                     opacity: endLineStyle.opacity || 0.3,
-                    fill: colorArrayStyle[seriesIdx % colorArrayLength] || endLineStyle.fill,
+                    fill: endLineStyle.fill || colorArrayStyle[seriesIdx % colorArrayLength],
                     path: dummyPath
                 });
             }
@@ -47586,12 +49722,13 @@ Ext.define('Ext.chart.series.Line', {
             fill = me.fill;
             line = me.line;
             
-            rendererAttributes = me.renderer(line, false, { path: path }, i, store);
+            rendererAttributes = me.renderer(line, false, { path: renderPath }, i, store);
             Ext.apply(rendererAttributes, endLineStyle || {}, {
                 stroke: endLineStyle.stroke || endLineStyle.fill
             });
             
             delete rendererAttributes.fill;
+            line.show(true);
             if (chart.markerIndex && me.previousPath) {
                 me.animation = animation = me.onAnimate(line, {
                     to: rendererAttributes,
@@ -47608,46 +49745,47 @@ Ext.define('Ext.chart.series.Line', {
             if (enableShadows) {
                 shadows = line.shadows;
                 for(j = 0; j < lnsh; j++) {
+                    shadows[j].show(true);
                     if (chart.markerIndex && me.previousPath) {
                         me.onAnimate(shadows[j], {
-                            to: { path: path },
+                            to: { path: renderPath },
                             from: { path: fromPath }
                         });
                     } else {
                         me.onAnimate(shadows[j], {
-                            to: { path: path }
+                            to: { path: renderPath }
                         });
                     }
                 }
             }
             
             if (fill) {
+                me.fillPath.show(true);
                 me.onAnimate(me.fillPath, {
                     to: Ext.apply({}, {
                         path: fillPath,
-                        fill: colorArrayStyle[seriesIdx % colorArrayLength] || endLineStyle.fill
+                        fill: endLineStyle.fill || colorArrayStyle[seriesIdx % colorArrayLength],
+                        'stroke-width': 0
                     }, endLineStyle || {})
                 });
             }
             
             if (showMarkers) {
+                count = 0;
                 for(i = 0; i < ln; i++) {
-                    item = markerGroup.getAt(i);
-                    if (item) {
-                        if (me.items[i]) {
+                    if (me.items[i]) {
+                        item = markerGroup.getAt(count++);
+                        if (item) {
                             rendererAttributes = me.renderer(item, store.getAt(i), item._to, i, store);
                             me.onAnimate(item, {
                                 to: Ext.apply(rendererAttributes, endMarkerStyle || {})
                             });
-                        } else {
-                            item.setAttributes(Ext.apply({
-                                hidden: true 
-                            }, item._to), true);
+                            item.show(true);
                         }
                     }
                 }
-                for(; i < markerCount; i++) {
-                    item = markerGroup.getAt(i);
+                for(; count < markerCount; count++) {
+                    item = markerGroup.getAt(count);
                     item.hide(true);
                 }
 
@@ -47656,7 +49794,7 @@ Ext.define('Ext.chart.series.Line', {
 
             }
         } else {
-            rendererAttributes = me.renderer(me.line, false, { path: path, hidden: false }, i, store);
+            rendererAttributes = me.renderer(me.line, false, { path: renderPath, hidden: false }, i, store);
             Ext.apply(rendererAttributes, endLineStyle || {}, {
                 stroke: endLineStyle.stroke || endLineStyle.fill
             });
@@ -47668,42 +49806,50 @@ Ext.define('Ext.chart.series.Line', {
                 shadows = me.line.shadows;
                 for(j = 0; j < lnsh; j++) {
                     shadows[j].setAttributes({
-                        path: path
+                        path: renderPath,
+                        hidden: false
                     }, true);
                 }
             }
             if (me.fill) {
                 me.fillPath.setAttributes({
-                    path: fillPath
+                    path: fillPath,
+                    hidden: false
                 }, true);
             }
             if (showMarkers) {
+                count = 0;
                 for(i = 0; i < ln; i++) {
-                    item = markerGroup.getAt(i);
-                    if (item) {
-                        if (me.items[i]) {
+                    if (me.items[i]) {
+                        item = markerGroup.getAt(count++);
+                        if (item) {
                             rendererAttributes = me.renderer(item, store.getAt(i), item._to, i, store);
                             item.setAttributes(Ext.apply(endMarkerStyle || {}, rendererAttributes || {}), true);
-                        } else {
-                            item.hide(true);
+                            item.show(true);
                         }
                     }
                 }
-                for(; i < markerCount; i++) {
-                    item = markerGroup.getAt(i);
+                for(; count < markerCount; count++) {
+                    item = markerGroup.getAt(count);
                     item.hide(true);
                 }
             }
         }
 
         if (chart.markerIndex) {
-            path.splice(1, 0, path[1], path[2]);
+            if (me.smooth) {
+                Ext.Array.erase(path, 1, 2);
+            } else {
+                Ext.Array.splice(path, 1, 0, path[1], path[2]);
+            }
             me.previousPath = path;
         }
         me.renderLabels();
         me.renderCallouts();
+
+        me.fireEvent('draw', me);
     },
-    
+
     
     onCreateLabel: function(storeItem, item, i, display) {
         var me = this,
@@ -47720,7 +49866,7 @@ Ext.define('Ext.chart.series.Line', {
             'y': bbox.y + bbox.height / 2
         }, endLabelStyle || {}));
     },
-    
+
     
     onPlaceLabel: function(label, storeItem, item, i, display, animate) {
         var me = this,
@@ -47734,12 +49880,12 @@ Ext.define('Ext.chart.series.Line', {
             y = item.point[1],
             radius = item.sprite.attr.radius,
             bb, width, height;
-        
+
         label.setAttributes({
             text: format(storeItem.get(field)),
             hidden: true
         }, true);
-        
+
         if (display == 'rotate') {
             label.setAttributes({
                 'text-anchor': 'start',
@@ -47756,7 +49902,7 @@ Ext.define('Ext.chart.series.Line', {
             x = x < bbox.x? bbox.x : x;
             x = (x + width > bbox.x + bbox.width)? (x - (x + width - bbox.x - bbox.width)) : x;
             y = (y - height < bbox.y)? bbox.y + height : y;
-        
+
         } else if (display == 'under' || display == 'over') {
             
             bb = item.sprite.getBBox();
@@ -47772,7 +49918,7 @@ Ext.define('Ext.chart.series.Line', {
             y = y - height < bbox.y? bbox.y + height : y;
             y = (y + height > bbox.y + bbox.height) ? (y - (y + height - bbox.y - bbox.height)) : y;
         }
-        
+
         if (me.chart.animate && !me.chart.resizing) {
             label.show(true);
             me.onAnimate(label, {
@@ -47786,7 +49932,7 @@ Ext.define('Ext.chart.series.Line', {
                 x: x,
                 y: y
             }, true);
-            if (resizing) {
+            if (resizing && me.animation) {
                 me.animation.on('afteranimate', function() {
                     label.show(true);
                 });
@@ -47801,20 +49947,20 @@ Ext.define('Ext.chart.series.Line', {
     highlightItem: function() {
         var me = this;
         me.callParent(arguments);
-        if (this.line && !this.highlighted) {
-            if (!('__strokeWidth' in this.line)) {
-                this.line.__strokeWidth = this.line.attr['stroke-width'] || 0;
+        if (me.line && !me.highlighted) {
+            if (!('__strokeWidth' in me.line)) {
+                me.line.__strokeWidth = me.line.attr['stroke-width'] || 0;
             }
-            if (this.line.__anim) {
-                this.line.__anim.paused = true;
+            if (me.line.__anim) {
+                me.line.__anim.paused = true;
             }
-            this.line.__anim = Ext.create('Ext.fx.Anim', {
-                target: this.line,
+            me.line.__anim = Ext.create('Ext.fx.Anim', {
+                target: me.line,
                 to: {
-                    'stroke-width': this.line.__strokeWidth + 3
+                    'stroke-width': me.line.__strokeWidth + 3
                 }
             });
-            this.highlighted = true;
+            me.highlighted = true;
         }
     },
 
@@ -47823,14 +49969,14 @@ Ext.define('Ext.chart.series.Line', {
     unHighlightItem: function() {
         var me = this;
         me.callParent(arguments);
-        if (this.line && this.highlighted) {
-            this.line.__anim = Ext.create('Ext.fx.Anim', {
-                target: this.line,
+        if (me.line && me.highlighted) {
+            me.line.__anim = Ext.create('Ext.fx.Anim', {
+                target: me.line,
                 to: {
-                    'stroke-width': this.line.__strokeWidth
+                    'stroke-width': me.line.__strokeWidth
                 }
             });
-            this.highlighted = false;
+            me.highlighted = false;
         }
     },
 
@@ -47840,7 +49986,7 @@ Ext.define('Ext.chart.series.Line', {
         if (!display) {
             return;
         }
-        
+
         var me = this,
             chart = me.chart,
             surface = chart.surface,
@@ -47872,11 +50018,11 @@ Ext.define('Ext.chart.series.Line', {
         a = (next[1] - prev[1]) / (next[0] - prev[0]);
         aprev = (cur[1] - prev[1]) / (cur[0] - prev[0]);
         anext = (next[1] - cur[1]) / (next[0] - cur[0]);
-        
+
         norm = Math.sqrt(1 + a * a);
         dir = [1 / norm, a / norm];
         normal = [-dir[1], dir[0]];
-        
+
         
         if (aprev > 0 && anext < 0 && normal[1] < 0
             || aprev < 0 && anext > 0 && normal[1] > 0) {
@@ -47896,7 +50042,7 @@ Ext.define('Ext.chart.series.Line', {
         boxy = y - bbox.height /2 - offsetBox;
         boxw = bbox.width + 2 * offsetBox;
         boxh = bbox.height + 2 * offsetBox;
-        
+
         
         
         if (boxx < clipRect[0] || (boxx + boxw) > (clipRect[0] + clipRect[2])) {
@@ -47909,13 +50055,13 @@ Ext.define('Ext.chart.series.Line', {
         
         x = cur[0] + normal[0] * offsetFromViz;
         y = cur[1] + normal[1] * offsetFromViz;
-        
+
         
         boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox));
         boxy = y - bbox.height /2 - offsetBox;
         boxw = bbox.width + 2 * offsetBox;
         boxh = bbox.height + 2 * offsetBox;
-        
+
         if (chart.animate) {
             
             me.onAnimate(callout.lines, {
@@ -47942,7 +50088,7 @@ Ext.define('Ext.chart.series.Line', {
             callout[p].show(true);
         }
     },
-    
+
     isItemInPoint: function(x, y, item, i) {
         var me = this,
             items = me.items,
@@ -47961,10 +50107,10 @@ Ext.define('Ext.chart.series.Line', {
             yIntersect,
             dist1, dist2, dist, midx, midy,
             sqrt = Math.sqrt, abs = Math.abs;
-        
+
         nextItem = items[i];
         prevItem = i && items[i - 1];
-        
+
         if (i >= ln) {
             prevItem = items[ln - 1];
         }
@@ -47977,22 +50123,22 @@ Ext.define('Ext.chart.series.Line', {
         dist1 = sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
         dist2 = sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2));
         dist = Math.min(dist1, dist2);
-        
+
         if (dist <= tolerance) {
             return dist == dist1? prevItem : nextItem;
         }
         return false;
     },
-    
+
     
     toggleAll: function(show) {
         var me = this,
             i, ln, shadow, shadows;
         if (!show) {
-            Ext.chart.series.Line.superclass.hideAll.call(me);
+            Ext.chart.series.Cartesian.prototype.hideAll.call(me);
         }
         else {
-            Ext.chart.series.Line.superclass.showAll.call(me);
+            Ext.chart.series.Cartesian.prototype.showAll.call(me);
         }
         if (me.line) {
             me.line.setAttributes({
@@ -48014,18 +50160,19 @@ Ext.define('Ext.chart.series.Line', {
             }, true);
         }
     },
-    
+
     
     hideAll: function() {
         this.toggleAll(false);
     },
-    
+
     
     showAll: function() {
         this.toggleAll(true);
     }
 });
 
+
 Ext.define('Ext.chart.series.Pie', {
 
     
@@ -48037,7 +50184,7 @@ Ext.define('Ext.chart.series.Pie', {
     
 
     type: "pie",
-    
+
     alias: 'series.pie',
 
     rad: Math.PI / 180,
@@ -48058,10 +50205,10 @@ Ext.define('Ext.chart.series.Pie', {
     showInLegend: false,
 
     
-    
+
     
     style: {},
-    
+
     constructor: function(config) {
         this.callParent(arguments);
         var me = this,
@@ -48076,7 +50223,7 @@ Ext.define('Ext.chart.series.Pie', {
                 }
             }
         });
-        Ext.apply(me, config, {            
+        Ext.apply(me, config, {
             shadowAttributes: [{
                 "stroke-width": 6,
                 "stroke-opacity": 1,
@@ -48114,13 +50261,14 @@ Ext.define('Ext.chart.series.Pie', {
         surface.customAttributes.segment = function(opt) {
             return me.getSegment(opt);
         };
+        me.__excludes = me.__excludes || [];
     },
-    
+
     //@private updates some onbefore render parameters.
 
     initialize: function() {
         var me = this,
-            store = me.chart.substore || me.chart.store;
+            store = me.chart.getChartStore();
         
         me.yField = [];
         if (me.label.field) {
@@ -48136,58 +50284,81 @@ Ext.define('Ext.chart.series.Pie', {
             rad = me.rad,
             cos = Math.cos,
             sin = Math.sin,
-            abs = Math.abs,
             x = me.centerX,
             y = me.centerY,
             x1 = 0, x2 = 0, x3 = 0, x4 = 0,
             y1 = 0, y2 = 0, y3 = 0, y4 = 0,
+            x5 = 0, y5 = 0, x6 = 0, y6 = 0,
             delta = 1e-2,
-            r = opt.endRho - opt.startRho,
             startAngle = opt.startAngle,
             endAngle = opt.endAngle,
             midAngle = (startAngle + endAngle) / 2 * rad,
             margin = opt.margin || 0,
-            flag = abs(endAngle - startAngle) > 180,
             a1 = Math.min(startAngle, endAngle) * rad,
             a2 = Math.max(startAngle, endAngle) * rad,
-            singleSlice = false;
-
-        x += margin * cos(midAngle);
-        y += margin * sin(midAngle);
+            c1 = cos(a1), s1 = sin(a1),
+            c2 = cos(a2), s2 = sin(a2),
+            cm = cos(midAngle), sm = sin(midAngle),
+            flag = 0, hsqr2 = 0.7071067811865476; 
 
-        x1 = x + opt.startRho * cos(a1);
-        y1 = y + opt.startRho * sin(a1);
+        if (a2 - a1 < delta) {
+            return {path: ""};
+        }
 
-        x2 = x + opt.endRho * cos(a1);
-        y2 = y + opt.endRho * sin(a1);
+        if (margin !== 0) {
+            x += margin * cm;
+            y += margin * sm;
+        }
 
-        x3 = x + opt.startRho * cos(a2);
-        y3 = y + opt.startRho * sin(a2);
+        x2 = x + opt.endRho * c1;
+        y2 = y + opt.endRho * s1;
 
-        x4 = x + opt.endRho * cos(a2);
-        y4 = y + opt.endRho * sin(a2);
+        x4 = x + opt.endRho * c2;
+        y4 = y + opt.endRho * s2;
 
-        if (abs(x1 - x3) <= delta && abs(y1 - y3) <= delta) {
-            singleSlice = true;
+        if (Math.abs(x2 - x4) + Math.abs(y2 - y4) < delta) {
+            cm = hsqr2;
+            sm = -hsqr2;
+            flag = 1;
         }
+
+        x6 = x + opt.endRho * cm;
+        y6 = y + opt.endRho * sm;
+
         
-        if (singleSlice) {
+        
+
+        if (opt.startRho !== 0) {
+            x1 = x + opt.startRho * c1;
+            y1 = y + opt.startRho * s1;
+    
+            x3 = x + opt.startRho * c2;
+            y3 = y + opt.startRho * s2;
+    
+            x5 = x + opt.startRho * cm;
+            y5 = y + opt.startRho * sm;
+
             return {
                 path: [
-                ["M", x1, y1],
-                ["L", x2, y2],
-                ["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4],
-                ["Z"]]
+                    ["M", x2, y2],
+                    ["A", opt.endRho, opt.endRho, 0, 0, 1, x6, y6], ["L", x6, y6],
+                    ["A", opt.endRho, opt.endRho, 0, flag, 1, x4, y4], ["L", x4, y4],
+                    ["L", x3, y3],
+                    ["A", opt.startRho, opt.startRho, 0, flag, 0, x5, y5], ["L", x5, y5],
+                    ["A", opt.startRho, opt.startRho, 0, 0, 0, x1, y1], ["L", x1, y1],
+                    ["Z"]
+                ]
             };
         } else {
             return {
                 path: [
-                ["M", x1, y1],
-                ["L", x2, y2],
-                ["A", opt.endRho, opt.endRho, 0, +flag, 1, x4, y4],
-                ["L", x3, y3],
-                ["A", opt.startRho, opt.startRho, 0, +flag, 0, x1, y1],
-                ["Z"]]
+                    ["M", x, y],
+                    ["L", x2, y2],
+                    ["A", opt.endRho, opt.endRho, 0, 0, 1, x6, y6], ["L", x6, y6],
+                    ["A", opt.endRho, opt.endRho, 0, flag, 1, x4, y4], ["L", x4, y4],
+                    ["L", x, y],
+                    ["Z"]
+                ]
             };
         }
     },
@@ -48202,11 +50373,10 @@ Ext.define('Ext.chart.series.Pie', {
             startAngle = slice.startAngle,
             endAngle = slice.endAngle,
             donut = +me.donut,
-            a1 = Math.min(startAngle, endAngle) * rad,
-            a2 = Math.max(startAngle, endAngle) * rad,
-            midAngle = -(a1 + (a2 - a1) / 2),
-            xm = x + (item.endRho + item.startRho) / 2 * Math.cos(midAngle),
-            ym = y - (item.endRho + item.startRho) / 2 * Math.sin(midAngle);
+            midAngle = -(startAngle + endAngle) * rad / 2,
+            r = (item.endRho + item.startRho) / 2,
+            xm = x + r * Math.cos(midAngle),
+            ym = y - r * Math.sin(midAngle);
 
         item.middle = {
             x: xm,
@@ -48217,7 +50387,7 @@ Ext.define('Ext.chart.series.Pie', {
     
     drawSeries: function() {
         var me = this,
-            store = me.chart.substore || me.chart.store,
+            store = me.chart.getChartStore(),
             group = me.group,
             animate = me.chart.animate,
             field = me.angleField || me.field || me.xField,
@@ -48251,6 +50421,7 @@ Ext.define('Ext.chart.series.Pie', {
             colorArrayLength = colorArrayStyle && colorArrayStyle.length || 0,
             gutterX = chart.maxGutter[0],
             gutterY = chart.maxGutter[1],
+            abs = Math.abs,
             rendererAttributes,
             shadowGroup,
             shadowAttr,
@@ -48278,7 +50449,7 @@ Ext.define('Ext.chart.series.Pie', {
             path,
             p,
             spriteOptions, bbox;
-        
+
         Ext.apply(seriesStyle, me.style || {});
 
         me.setBBox();
@@ -48289,12 +50460,12 @@ Ext.define('Ext.chart.series.Pie', {
             colorArrayStyle = me.colorSet;
             colorArrayLength = colorArrayStyle.length;
         }
-        
+
         
         if (!store || !store.getCount()) {
             return;
         }
-        
+
         me.unHighlightItem();
         me.cleanHighlights();
 
@@ -48319,25 +50490,26 @@ Ext.define('Ext.chart.series.Pie', {
             }
         }, this);
 
+        totalField = totalField || 1;
         store.each(function(record, i) {
             if (this.__excludes && this.__excludes[i]) {
-                
-                return;
-            } 
-            value = record.get(field);
-            middleAngle = angle - 360 * value / totalField / 2;
-            
-            if (isNaN(middleAngle)) {
-                middleAngle = 360;
-                value = 1;
-                totalField = 1;
+                value = 0;
+            } else {
+                value = record.get(field);
+                if (first == 0) {
+                    first = 1;
+                }
             }
+
             
-            if (!i || first == 0) {
-                angle = 360 - middleAngle;
-                me.firstAngle = angle;
-                middleAngle = angle - 360 * value / totalField / 2;
+            if (first == 1) {
+                first = 2;
+                me.firstAngle = angle = 360 * value / totalField / 2;
+                for (j = 0; j < i; j++) {
+                    slices[j].startAngle = slices[j].endAngle = me.firstAngle;
+                }
             }
+            
             endAngle = angle - 360 * value / totalField;
             slice = {
                 series: me,
@@ -48353,20 +50525,11 @@ Ext.define('Ext.chart.series.Pie', {
                 slice.rho = me.radius;
             }
             slices[i] = slice;
-            if((slice.startAngle % 360) == (slice.endAngle % 360)) {
-                slice.startAngle -= 0.0001;
-            }
             angle = endAngle;
-            first++;
         }, me);
         
-        
         if (enableShadows) {
             for (i = 0, ln = slices.length; i < ln; i++) {
-                if (this.__excludes && this.__excludes[i]) {
-                    
-                    continue;
-                }
                 slice = slices[i];
                 slice.shadowAttrs = [];
                 for (j = 0, rhoAcum = 0, shadows = []; j < layers; j++) {
@@ -48381,32 +50544,28 @@ Ext.define('Ext.chart.series.Pie', {
                             rho: slice.rho,
                             startRho: rhoAcum + (deltaRho * donut / 100),
                             endRho: rhoAcum + deltaRho
-                        }
+                        },
+                        hidden: !slice.value && (slice.startAngle % 360) == (slice.endAngle % 360)
                     };
                     
                     for (shindex = 0, shadows = []; shindex < lnsh; shindex++) {
                         shadowAttr = shadowAttributes[shindex];
                         shadow = shadowGroups[shindex].getAt(i);
                         if (!shadow) {
-                            shadow = chart.surface.add(Ext.apply({},
-                            {
+                            shadow = chart.surface.add(Ext.apply({}, {
                                 type: 'path',
                                 group: shadowGroups[shindex],
                                 strokeLinejoin: "round"
-                            },
-                            rendererAttributes, shadowAttr));
+                            }, rendererAttributes, shadowAttr));
                         }
                         if (animate) {
-                            rendererAttributes = me.renderer(shadow, store.getAt(i), Ext.apply({},
-                            rendererAttributes, shadowAttr), i, store);
+                            shadowAttr = me.renderer(shadow, store.getAt(i), Ext.apply({}, rendererAttributes, shadowAttr), i, store);
                             me.onAnimate(shadow, {
-                                to: rendererAttributes
+                                to: shadowAttr
                             });
                         } else {
-                            rendererAttributes = me.renderer(shadow, store.getAt(i), Ext.apply(shadowAttr, {
-                                hidden: false
-                            }), i, store);
-                            shadow.setAttributes(rendererAttributes, true);
+                            shadowAttr = me.renderer(shadow, store.getAt(i), shadowAttr, i, store);
+                            shadow.setAttributes(shadowAttr, true);
                         }
                         shadows.push(shadow);
                     }
@@ -48416,10 +50575,6 @@ Ext.define('Ext.chart.series.Pie', {
         }
         
         for (i = 0, ln = slices.length; i < ln; i++) {
-            if (this.__excludes && this.__excludes[i]) {
-                
-                continue;
-            }
             slice = slices[i];
             for (j = 0, rhoAcum = 0; j < layers; j++) {
                 sprite = group.getAt(i * layers + j);
@@ -48433,7 +50588,8 @@ Ext.define('Ext.chart.series.Pie', {
                         rho: slice.rho,
                         startRho: rhoAcum + (deltaRho * donut / 100),
                         endRho: rhoAcum + deltaRho
-                    } 
+                    },
+                    hidden: (!slice.value && (slice.startAngle % 360) == (slice.endAngle % 360))
                 }, Ext.apply(seriesStyle, colorArrayStyle && { fill: colorArrayStyle[(layers > 1? j : i) % colorArrayLength] } || {}));
                 item = Ext.apply({},
                 rendererAttributes.segment, {
@@ -48484,7 +50640,7 @@ Ext.define('Ext.chart.series.Pie', {
                 rhoAcum += deltaRho;
             }
         }
-        
+
         
         ln = group.getCount();
         for (i = 0; i < ln; i++) {
@@ -48517,7 +50673,7 @@ Ext.define('Ext.chart.series.Pie', {
             centerY = me.centerY,
             middle = item.middle,
             endLabelStyle = Ext.apply(me.seriesLabelStyle || {}, config || {});
-        
+
         return me.chart.surface.add(Ext.apply({
             'type': 'text',
             'text-anchor': 'middle',
@@ -48549,9 +50705,13 @@ Ext.define('Ext.chart.series.Pie', {
             theta = Math.atan2(y, x || 1),
             dg = theta * 180 / Math.PI,
             prevDg;
-        
+        if (this.__excludes && this.__excludes[i]) {
+            opt.hidden = true;
+        }
         function fixAngle(a) {
-            if (a < 0) a += 360;
+            if (a < 0) {
+                a += 360;
+            }
             return a % 360;
         }
 
@@ -48595,7 +50755,7 @@ Ext.define('Ext.chart.series.Pie', {
         }
         
         opt.translate = {
-            x: 0, y: 0    
+            x: 0, y: 0
         };
         if (animate && !resizing && (display != 'rotate' || prevDg != null)) {
             me.onAnimate(label, {
@@ -48706,8 +50866,8 @@ Ext.define('Ext.chart.series.Pie', {
             startAngle = item.startAngle,
             endAngle = item.endAngle,
             rho = Math.sqrt(dx * dx + dy * dy),
-            angle = Math.atan2(y - cy, x - cx) / me.rad + 360;
-        
+            angle = Math.atan2(y - cy, x - cx) / me.rad;
+
         
         if (angle > me.firstAngle) {
             angle -= 360;
@@ -48715,7 +50875,7 @@ Ext.define('Ext.chart.series.Pie', {
         return (angle <= startAngle && angle > endAngle
                 && rho >= item.startRho && rho <= item.endRho);
     },
-    
+
     
     hideAll: function() {
         var i, l, shadow, shadows, sh, lsh, sprite;
@@ -48741,7 +50901,7 @@ Ext.define('Ext.chart.series.Pie', {
             this.drawSeries();
         }
     },
-    
+
     
     showAll: function() {
         if (!isNaN(this._index)) {
@@ -48755,13 +50915,13 @@ Ext.define('Ext.chart.series.Pie', {
         var me = this,
             rad = me.rad;
         item = item || this.items[this._index];
-        
+
         
         
         
         
         this.unHighlightItem();
-        
+
         if (!item || item.sprite && item.sprite._animating) {
             return;
         }
@@ -48794,7 +50954,7 @@ Ext.define('Ext.chart.series.Pie', {
                 if (Math.abs(y) < 1e-10) {
                     y = 0;
                 }
-                
+
                 if (animate) {
                     label.stopAnimation();
                     label.animate({
@@ -48933,11 +51093,11 @@ Ext.define('Ext.chart.series.Pie', {
         }
         me.callParent(arguments);
     },
-    
+
     
     getLegendColor: function(index) {
         var me = this;
-        return me.colorArrayStyle[index % me.colorArrayStyle.length];
+        return (me.colorSet && me.colorSet[index % me.colorSet.length]) || me.colorArrayStyle[index % me.colorArrayStyle.length];
     }
 });
 
@@ -48956,14 +51116,14 @@ Ext.define('Ext.chart.series.Radar', {
     type: "radar",
     alias: 'series.radar',
 
-    
+
     rad: Math.PI / 180,
 
     showInLegend: false,
 
     
     style: {},
-    
+
     constructor: function(config) {
         this.callParent(arguments);
         var me = this,
@@ -48977,7 +51137,7 @@ Ext.define('Ext.chart.series.Radar', {
     
     drawSeries: function() {
         var me = this,
-            store = me.chart.substore || me.chart.store,
+            store = me.chart.getChartStore(),
             group = me.group,
             sprite,
             chart = me.chart,
@@ -49003,18 +51163,18 @@ Ext.define('Ext.chart.series.Radar', {
             first = chart.resizing || !me.radar,
             axis = chart.axes && chart.axes.get(0),
             aggregate = !(axis && axis.maximum);
-        
+
         me.setBBox();
 
         maxValue = aggregate? 0 : (axis.maximum || 0);
-        
+
         Ext.apply(seriesStyle, me.style || {});
-        
+
         
         if (!store || !store.getCount()) {
             return;
         }
-        
+
         me.unHighlightItem();
         me.cleanHighlights();
 
@@ -49090,7 +51250,7 @@ Ext.define('Ext.chart.series.Radar', {
         me.renderLabels();
         me.renderCallouts();
     },
-    
+
     
     drawMarkers: function() {
         var me = this,
@@ -49098,15 +51258,15 @@ Ext.define('Ext.chart.series.Radar', {
             surface = chart.surface,
             markerStyle = Ext.apply({}, me.markerStyle || {}),
             endMarkerStyle = Ext.apply(markerStyle, me.markerConfig),
-            items = me.items, 
+            items = me.items,
             type = endMarkerStyle.type,
             markerGroup = me.markerGroup,
             centerX = me.centerX,
             centerY = me.centerY,
             item, i, l, marker;
-        
+
         delete endMarkerStyle.type;
-        
+
         for (i = 0, l = items.length; i < l; i++) {
             item = items[i];
             marker = markerGroup.getAt(i);
@@ -49151,7 +51311,7 @@ Ext.define('Ext.chart.series.Radar', {
             }
         }
     },
-    
+
     isItemInPoint: function(x, y, item) {
         var point,
             tolerance = 10,
@@ -49170,7 +51330,7 @@ Ext.define('Ext.chart.series.Radar', {
             centerY = me.centerY,
             point = item.point,
             endLabelStyle = Ext.apply(me.seriesLabelStyle || {}, config);
-        
+
         return me.chart.surface.add(Ext.apply({
             'type': 'text',
             'text-anchor': 'middle',
@@ -49202,14 +51362,14 @@ Ext.define('Ext.chart.series.Radar', {
             hidden: true
         },
         true);
-        
+
         if (resizing) {
             label.setAttributes({
                 x: centerX,
                 y: centerY
             }, true);
         }
-        
+
         if (animate) {
             label.show(true);
             me.onAnimate(label, {
@@ -49246,18 +51406,18 @@ Ext.define('Ext.chart.series.Radar', {
             }
         }
     },
-    
+
     
     hideAll: function() {
         this.toggleAll(false);
         this.hideMarkers(0);
     },
-    
+
     
     showAll: function() {
         this.toggleAll(true);
     },
-    
+
     
     hideMarkers: function(index) {
         var me = this,
@@ -49285,6 +51445,8 @@ Ext.define('Ext.chart.series.Scatter', {
     alias: 'series.scatter',
 
     
+
+    
     
     
 
@@ -49322,14 +51484,14 @@ Ext.define('Ext.chart.series.Scatter', {
     getBounds: function() {
         var me = this,
             chart = me.chart,
-            store = chart.substore || chart.store,
+            store = chart.getChartStore(),
             axes = [].concat(me.axis),
             bbox, xScale, yScale, ln, minX, minY, maxX, maxY, i, axis, ends;
 
         me.setBBox();
         bbox = me.bbox;
 
-        for (i = 0, ln = axes.length; i < ln; i++) { 
+        for (i = 0, ln = axes.length; i < ln; i++) {
             axis = chart.axes.get(axes[i]);
             if (axis) {
                 ends = axis.calcEnds();
@@ -49374,7 +51536,7 @@ Ext.define('Ext.chart.series.Scatter', {
             minY = 0;
             maxY = store.getCount() - 1;
             yScale = bbox.height / (store.getCount() - 1);
-        } 
+        }
         else {
             yScale = bbox.height / (maxY - minY);
         }
@@ -49393,7 +51555,7 @@ Ext.define('Ext.chart.series.Scatter', {
         var me = this,
             chart = me.chart,
             enableShadows = chart.shadow,
-            store = chart.substore || chart.store,
+            store = chart.getChartStore(),
             group = me.group,
             bounds = me.bounds = me.getBounds(),
             bbox = me.bbox,
@@ -49413,16 +51575,13 @@ Ext.define('Ext.chart.series.Scatter', {
             yValue = record.get(me.yField);
             
             if (typeof yValue == 'undefined' || (typeof yValue == 'string' && !yValue)) {
-                if (Ext.isDefined(Ext.global.console)) {
-                    Ext.global.console.warn("[Ext.chart.series.Scatter]  Skipping a store element with an undefined value at ", record, xValue, yValue);
-                }
                 return;
             }
             
-            if (typeof xValue == 'string' || typeof xValue == 'object') {
+            if (typeof xValue == 'string' || typeof xValue == 'object' && !Ext.isDate(xValue)) {
                 xValue = i;
             }
-            if (typeof yValue == 'string' || typeof yValue == 'object') {
+            if (typeof yValue == 'string' || typeof yValue == 'object' && !Ext.isDate(yValue)) {
                 yValue = i;
             }
             x = boxX + (xValue - minX) * xScale;
@@ -49546,7 +51705,7 @@ Ext.define('Ext.chart.series.Scatter', {
     drawSeries: function() {
         var me = this,
             chart = me.chart,
-            store = chart.substore || chart.store,
+            store = chart.getChartStore(),
             group = me.group,
             enableShadows = chart.shadow,
             shadowGroups = me.shadowGroups,
@@ -49593,23 +51752,28 @@ Ext.define('Ext.chart.series.Scatter', {
                 for (shindex = 0; shindex < lnsh; shindex++) {
                     shadowAttribute = Ext.apply({}, shadowAttributes[shindex]);
                     rendererAttributes = me.renderer(shadows[shindex], store.getAt(i), Ext.apply({}, { 
+                        hidden: false,
                         translate: {
                             x: attr.x + (shadowAttribute.translate? shadowAttribute.translate.x : 0),
                             y: attr.y + (shadowAttribute.translate? shadowAttribute.translate.y : 0)
-                        } 
+                        }
                     }, shadowAttribute), i, store);
                     me.onAnimate(shadows[shindex], { to: rendererAttributes });
                 }
             }
             else {
-                rendererAttributes = me.renderer(sprite, store.getAt(i), Ext.apply({ translate: attr }, { hidden: false }), i, store);
+                rendererAttributes = me.renderer(sprite, store.getAt(i), { translate: attr }, i, store);
+                sprite._to = rendererAttributes;
                 sprite.setAttributes(rendererAttributes, true);
                 
                 for (shindex = 0; shindex < lnsh; shindex++) {
-                    shadowAttribute = shadowAttributes[shindex];
-                    rendererAttributes = me.renderer(shadows[shindex], store.getAt(i), Ext.apply({ 
-                        x: attr.x,
-                        y: attr.y
+                    shadowAttribute = Ext.apply({}, shadowAttributes[shindex]);
+                    rendererAttributes = me.renderer(shadows[shindex], store.getAt(i), Ext.apply({}, { 
+                        hidden: false,
+                        translate: {
+                            x: attr.x + (shadowAttribute.translate? shadowAttribute.translate.x : 0),
+                            y: attr.y + (shadowAttribute.translate? shadowAttribute.translate.y : 0)
+                        } 
                     }, shadowAttribute), i, store);
                     shadows[shindex].setAttributes(rendererAttributes, true);
                 }
@@ -49625,7 +51789,7 @@ Ext.define('Ext.chart.series.Scatter', {
         me.renderLabels();
         me.renderCallouts();
     },
-    
+
     
     onCreateLabel: function(storeItem, item, i, display) {
         var me = this,
@@ -49633,7 +51797,7 @@ Ext.define('Ext.chart.series.Scatter', {
             config = me.label,
             endLabelStyle = Ext.apply({}, config, me.seriesLabelStyle),
             bbox = me.bbox;
-        
+
         return me.chart.surface.add(Ext.apply({
             type: 'text',
             group: group,
@@ -49641,7 +51805,7 @@ Ext.define('Ext.chart.series.Scatter', {
             y: bbox.y + bbox.height / 2
         }, endLabelStyle));
     },
-    
+
     
     onPlaceLabel: function(label, storeItem, item, i, display, animate) {
         var me = this,
@@ -49655,12 +51819,12 @@ Ext.define('Ext.chart.series.Scatter', {
             y = item.point[1],
             radius = item.sprite.attr.radius,
             bb, width, height, anim;
-        
+
         label.setAttributes({
             text: format(storeItem.get(field)),
             hidden: true
         }, true);
-        
+
         if (display == 'rotate') {
             label.setAttributes({
                 'text-anchor': 'start',
@@ -49677,7 +51841,7 @@ Ext.define('Ext.chart.series.Scatter', {
             x = x < bbox.x? bbox.x : x;
             x = (x + width > bbox.x + bbox.width)? (x - (x + width - bbox.x - bbox.width)) : x;
             y = (y - height < bbox.y)? bbox.y + height : y;
-        
+
         } else if (display == 'under' || display == 'over') {
             
             bb = item.sprite.getBBox();
@@ -49711,7 +51875,7 @@ Ext.define('Ext.chart.series.Scatter', {
                             y: y
                         }, true);
                         label.show(true);
-                    });   
+                    });
                 }
                 else {
                     label.show(true);
@@ -49727,7 +51891,7 @@ Ext.define('Ext.chart.series.Scatter', {
             }
         }
     },
-    
+
     
     onPlaceCallout: function(callout, storeItem, item, i, display, animate, index) {
         var me = this,
@@ -49745,18 +51909,18 @@ Ext.define('Ext.chart.series.Scatter', {
             boxx, boxy, boxw, boxh,
             p, clipRect = me.bbox,
             x, y;
-    
+
         
         normal = [Math.cos(Math.PI /4), -Math.sin(Math.PI /4)];
         x = cur[0] + normal[0] * offsetFromViz;
         y = cur[1] + normal[1] * offsetFromViz;
-        
+
         
         boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox));
         boxy = y - bbox.height /2 - offsetBox;
         boxw = bbox.width + 2 * offsetBox;
         boxh = bbox.height + 2 * offsetBox;
-        
+
         
         
         if (boxx < clipRect[0] || (boxx + boxw) > (clipRect[0] + clipRect[2])) {
@@ -49765,17 +51929,17 @@ Ext.define('Ext.chart.series.Scatter', {
         if (boxy < clipRect[1] || (boxy + boxh) > (clipRect[1] + clipRect[3])) {
             normal[1] *= -1;
         }
-    
+
         
         x = cur[0] + normal[0] * offsetFromViz;
         y = cur[1] + normal[1] * offsetFromViz;
-        
+
         
         boxx = x + (normal[0] > 0? 0 : -(bbox.width + 2 * offsetBox));
         boxy = y - bbox.height /2 - offsetBox;
         boxw = bbox.width + 2 * offsetBox;
         boxh = bbox.height + 2 * offsetBox;
-        
+
         if (chart.animate) {
             
             me.onAnimate(callout.lines, {
@@ -50003,7 +52167,6 @@ Ext.define('Ext.data.ArrayStore', {
     alias: 'store.array',
     uses: ['Ext.data.reader.Array'],
 
-    
     constructor: function(config) {
         config = config || {};
 
@@ -50043,92 +52206,93 @@ Ext.define('Ext.data.Batch', {
     mixins: {
         observable: 'Ext.util.Observable'
     },
-    
+
     
     autoStart: false,
-    
+
     
     current: -1,
-    
+
     
     total: 0,
-    
+
     
     isRunning: false,
-    
+
     
     isComplete: false,
-    
+
     
     hasException: false,
-    
+
     
     pauseOnException: true,
+
     
-    constructor: function(config) {   
+    constructor: function(config) {
         var me = this;
-                     
+
         me.addEvents(
           
           'complete',
-          
+
           
           'exception',
-          
+
           
           'operationcomplete'
         );
-        
+
         me.mixins.observable.constructor.call(me, config);
-        
+
         
         me.operations = [];
     },
-    
+
     
     add: function(operation) {
         this.total++;
-        
+
         operation.setBatch(this);
-        
+
         this.operations.push(operation);
     },
-    
+
     
     start: function() {
         this.hasException = false;
         this.isRunning = true;
-        
+
         this.runNextOperation();
     },
-    
+
     
     runNextOperation: function() {
         this.runOperation(this.current + 1);
     },
-    
+
     
     pause: function() {
         this.isRunning = false;
     },
-    
+
     
     runOperation: function(index) {
         var me = this,
             operations = me.operations,
             operation  = operations[index],
             onProxyReturn;
-        
+
         if (operation === undefined) {
             me.isRunning  = false;
             me.isComplete = true;
             me.fireEvent('complete', me, operations[operations.length - 1]);
         } else {
             me.current = index;
-            
+
             onProxyReturn = function(operation) {
                 var hasException = operation.hasException();
-                
+
                 if (hasException) {
                     me.hasException = true;
                     me.fireEvent('exception', me, operation);
@@ -50143,9 +52307,9 @@ Ext.define('Ext.data.Batch', {
                     me.runNextOperation();
                 }
             };
-            
+
             operation.setStarted();
-            
+
             me.proxy[operation.action](operation, onProxyReturn, me);
         }
     }
@@ -50161,9 +52325,8 @@ Ext.define('Ext.data.BelongsToAssociation', {
     
 
     
-    
-    
 
+    
     constructor: function(config) {
         this.callParent(arguments);
 
@@ -50223,38 +52386,37 @@ Ext.define('Ext.data.BelongsToAssociation', {
         return function(options, scope) {
             options = options || {};
 
-            var foreignKeyId = this.get(foreignKey),
-                instance, callbackFn;
+            var model = this,
+                foreignKeyId = model.get(foreignKey),
+                instance,
+                args;
 
-            if (this[instanceName] === undefined) {
+            if (model[instanceName] === undefined) {
                 instance = Ext.ModelManager.create({}, associatedName);
                 instance.set(primaryKey, foreignKeyId);
 
                 if (typeof options == 'function') {
                     options = {
                         callback: options,
-                        scope: scope || this
+                        scope: scope || model
                     };
                 }
 
                 associatedModel.load(foreignKeyId, options);
+                model[instanceName] = associatedModel;
+                return associatedModel;
             } else {
-                instance = this[instanceName];
+                instance = model[instanceName];
+                args = [instance];
+                scope = scope || model;
 
                 
                 
                 
-                if (typeof options == 'function') {
-                    options.call(scope || this, instance);
-                }
-
-                if (options.success) {
-                    options.success.call(scope || this, instance);
-                }
-
-                if (options.callback) {
-                    options.callback.call(scope || this, instance);
-                }
+                Ext.callback(options, scope, args);
+                Ext.callback(options.success, scope, args);
+                Ext.callback(options.failure, scope, args);
+                Ext.callback(options.callback, scope, args);
 
                 return instance;
             }
@@ -50279,18 +52441,17 @@ Ext.define('Ext.data.BufferStore', {
     }
 });
 
-
 Ext.define('Ext.direct.Manager', {
-    
+
     
     singleton: true,
-   
+
     mixins: {
         observable: 'Ext.util.Observable'
     },
-    
+
     requires: ['Ext.util.MixedCollection'],
-    
+
     statics: {
         exceptions: {
             TRANSPORT: 'xhr',
@@ -50299,12 +52460,12 @@ Ext.define('Ext.direct.Manager', {
             SERVER: 'exception'
         }
     },
+
     
-    
-   
+
     constructor: function(){
         var me = this;
-       
+
         me.addEvents(
             
             'event',
@@ -50313,17 +52474,17 @@ Ext.define('Ext.direct.Manager', {
         );
         me.transactions = Ext.create('Ext.util.MixedCollection');
         me.providers = Ext.create('Ext.util.MixedCollection');
-        
+
         me.mixins.observable.constructor.call(me);
     },
-    
+
     
     addProvider : function(provider){
         var me = this,
             args = arguments,
             i = 0,
             len;
-            
+
         if (args.length > 1) {
             for (len = args.length; i < len; ++i) {
                 me.addProvider(args[i]);
@@ -50345,18 +52506,19 @@ Ext.define('Ext.direct.Manager', {
 
         return provider;
     },
-    
+
     
     getProvider : function(id){
         return id.isProvider ? id : this.providers.get(id);
     },
-    
+
     
     removeProvider : function(provider){
         var me = this,
-            providers = me.providers,
-            provider = provider.isProvider ? provider : providers.get(provider);
-            
+            providers = me.providers;
+
+        provider = provider.isProvider ? provider : providers.get(provider);
+
         if (provider) {
             provider.un('data', me.onProviderData, me);
             providers.remove(provider);
@@ -50364,7 +52526,7 @@ Ext.define('Ext.direct.Manager', {
         }
         return null;
     },
-    
+
     
     addTransaction: function(transaction){
         this.transactions.add(transaction);
@@ -50382,12 +52544,12 @@ Ext.define('Ext.direct.Manager', {
     getTransaction: function(transaction){
         return transaction.isTransaction ? transaction : this.transactions.get(transaction);
     },
-    
+
     onProviderData : function(provider, event){
         var me = this,
             i = 0,
             len;
-            
+
         if (Ext.isArray(event)) {
             for (len = event.length; i < len; ++i) {
                 me.onProviderData(provider, event[i]);
@@ -50396,7 +52558,7 @@ Ext.define('Ext.direct.Manager', {
         }
         if (event.name && event.name != 'event' && event.name != 'exception') {
             me.fireEvent(event.name, event);
-        } else if (event.type == 'exception') {
+        } else if (event.status === false) {
             me.fireEvent('exception', event);
         }
         me.fireEvent('event', event, provider);
@@ -50409,17 +52571,17 @@ Ext.define('Ext.direct.Manager', {
 
 Ext.define('Ext.data.proxy.Direct', {
     
-    
+
     extend: 'Ext.data.proxy.Server',
     alternateClassName: 'Ext.data.DirectProxy',
-    
+
     alias: 'proxy.direct',
-    
+
     requires: ['Ext.direct.Manager'],
+
     
+
     
-   
-   
     paramOrder: undefined,
 
     
@@ -50427,24 +52589,24 @@ Ext.define('Ext.data.proxy.Direct', {
 
     
     directFn : undefined,
+
     
+
     
-    
-    
-    
+
     
     paramOrderRe: /[\s,|]/,
-    
+
     constructor: function(config){
         var me = this;
-        
+
         Ext.apply(me, config);
         if (Ext.isString(me.paramOrder)) {
             me.paramOrder = me.paramOrder.split(me.paramOrderRe);
         }
         me.callParent(arguments);
     },
-    
+
     doRequest: function(operation, callback, scope) {
         var me = this,
             writer = me.getWriter(),
@@ -50456,19 +52618,16 @@ Ext.define('Ext.data.proxy.Direct', {
             method,
             i = 0,
             len;
-            
-        if (!fn) {
-            Ext.Error.raise('No direct function specified for this proxy');
-        }
-            
+
+
         if (operation.allowWrite()) {
             request = writer.write(request);
         }
-        
+
         if (operation.action == 'read') {
             
             method = fn.directCfg.method;
-            
+
             if (method.ordered) {
                 if (method.len > 0) {
                     if (paramOrder) {
@@ -50485,7 +52644,7 @@ Ext.define('Ext.data.proxy.Direct', {
         } else {
             args.push(request.jsonData);
         }
-        
+
         Ext.apply(request, {
             args: args,
             directFn: fn
@@ -50493,30 +52652,30 @@ Ext.define('Ext.data.proxy.Direct', {
         args.push(me.createRequestCallback(request, operation, callback, scope), me);
         fn.apply(window, args);
     },
-    
+
     
     applyEncoding: function(value){
         return value;
     },
-    
+
     createRequestCallback: function(request, operation, callback, scope){
         var me = this;
-        
+
         return function(data, event){
             me.processResponse(event.status, operation, request, event, callback, scope);
         };
     },
-    
+
     
     extractResponseData: function(response){
         return Ext.isDefined(response.result) ? response.result : response.data;
     },
-    
+
     
     setException: function(operation, response) {
         operation.setException(response.message);
     },
-    
+
     
     buildUrl: function(){
         return '';
@@ -50524,7 +52683,6 @@ Ext.define('Ext.data.proxy.Direct', {
 });
 
 
-
 Ext.define('Ext.data.DirectStore', {
     
     
@@ -50535,8 +52693,8 @@ Ext.define('Ext.data.DirectStore', {
     requires: ['Ext.data.proxy.Direct'],
    
     
-   
-   constructor : function(config){
+
+    constructor : function(config){
         config = Ext.apply({}, config);
         if (!config.proxy) {
             var proxy = {
@@ -50554,7 +52712,6 @@ Ext.define('Ext.data.DirectStore', {
 });
 
 
-
 Ext.define('Ext.util.Inflector', {
 
     
@@ -50586,7 +52743,7 @@ Ext.define('Ext.util.Inflector', {
         [(/s$/i),                     "s"      ],
         [(/$/),                       "s"      ]
     ],
-    
+
     
     singulars: [
       [(/(quiz)zes$/i),                                                    "$1"     ],
@@ -50615,7 +52772,7 @@ Ext.define('Ext.util.Inflector', {
       [(/people$/i),                                                       "person" ],
       [(/s$/i),                                                            ""       ]
     ],
-    
+
     
      uncountable: [
         "sheep",
@@ -50632,27 +52789,27 @@ Ext.define('Ext.util.Inflector', {
         "deer",
         "means"
     ],
-    
+
     
     singular: function(matcher, replacer) {
         this.singulars.unshift([matcher, replacer]);
     },
-    
+
     
     plural: function(matcher, replacer) {
         this.plurals.unshift([matcher, replacer]);
     },
-    
+
     
     clearSingulars: function() {
         this.singulars = [];
     },
-    
+
     
     clearPlurals: function() {
         this.plurals = [];
     },
-    
+
     
     isTransnumeral: function(word) {
         return Ext.Array.indexOf(this.uncountable, word) != -1;
@@ -50667,19 +52824,19 @@ Ext.define('Ext.util.Inflector', {
         var plurals = this.plurals,
             length  = plurals.length,
             tuple, regex, i;
-        
+
         for (i = 0; i < length; i++) {
             tuple = plurals[i];
             regex = tuple[0];
-            
+
             if (regex == word || (regex.test && regex.test(word))) {
                 return word.replace(regex, tuple[1]);
             }
         }
-        
+
         return word;
     },
-    
+
     
     singularize: function(word) {
         if (this.isTransnumeral(word)) {
@@ -50689,30 +52846,30 @@ Ext.define('Ext.util.Inflector', {
         var singulars = this.singulars,
             length    = singulars.length,
             tuple, regex, i;
-        
+
         for (i = 0; i < length; i++) {
             tuple = singulars[i];
             regex = tuple[0];
-            
+
             if (regex == word || (regex.test && regex.test(word))) {
                 return word.replace(regex, tuple[1]);
             }
         }
-        
+
         return word;
     },
-    
+
     
     classify: function(word) {
         return Ext.String.capitalize(this.singularize(word));
     },
-    
+
     
     ordinalize: function(number) {
         var parsed = parseInt(number, 10),
             mod10  = parsed % 10,
             mod100 = parsed % 100;
-        
+
         
         if (11 <= mod100 && mod100 <= 13) {
             return number + "th";
@@ -50761,7 +52918,7 @@ Ext.define('Ext.util.Inflector', {
             vita: 'vitae'
         },
         singular;
-    
+
     for (singular in irregulars) {
         this.plural(singular, irregulars[singular]);
         this.singular(irregulars[singular], singular);
@@ -50879,57 +53036,55 @@ Ext.define('Ext.data.HasManyAssociation', {
 });
 
 Ext.define('Ext.data.JsonP', {
+
     
-    
-    
+
     singleton: true,
-    
+
     statics: {
         requestCount: 0,
         requests: {}
     },
+
     
-    
-    
+
     
     timeout: 30000,
-    
+
     
     disableCaching: true,
-   
+
     
     disableCachingParam: '_dc',
-   
+
     
     callbackKey: 'callback',
-   
+
     
     request: function(options){
         options = Ext.apply({}, options);
-       
-        if (!options.url) {
-            Ext.Error.raise('A url must be specified for a JSONP request.');
-        }
-        
-        var me = this, 
-            disableCaching = Ext.isDefined(options.disableCaching) ? options.disableCaching : me.disableCaching, 
-            cacheParam = options.disableCachingParam || me.disableCachingParam, 
-            id = ++me.statics().requestCount, 
-            callbackName = 'callback' + id, 
-            callbackKey = options.callbackKey || me.callbackKey, 
-            timeout = Ext.isDefined(options.timeout) ? options.timeout : me.timeout, 
-            params = Ext.apply({}, options.params), 
+
+
+        var me = this,
+            disableCaching = Ext.isDefined(options.disableCaching) ? options.disableCaching : me.disableCaching,
+            cacheParam = options.disableCachingParam || me.disableCachingParam,
+            id = ++me.statics().requestCount,
+            callbackName = options.callbackName || 'callback' + id,
+            callbackKey = options.callbackKey || me.callbackKey,
+            timeout = Ext.isDefined(options.timeout) ? options.timeout : me.timeout,
+            params = Ext.apply({}, options.params),
             url = options.url,
-            request, 
+            name = Ext.isSandboxed ? Ext.getUniqueGlobalNamespace() : 'Ext',
+            request,
             script;
-            
-        params[callbackKey] = 'Ext.data.JsonP.' + callbackName;
+
+        params[callbackKey] = name + '.data.JsonP.' + callbackName;
         if (disableCaching) {
             params[cacheParam] = new Date().getTime();
         }
-        
+
         script = me.createScript(url, params);
-        
+
         me.statics().requests[id] = request = {
             url: url,
             params: params,
@@ -50941,22 +53096,22 @@ Ext.define('Ext.data.JsonP', {
             callback: options.callback,
             callbackName: callbackName
         };
-        
+
         if (timeout > 0) {
             request.timeout = setTimeout(Ext.bind(me.handleTimeout, me, [request]), timeout);
         }
-        
+
         me.setupErrorHandling(request);
         me[callbackName] = Ext.bind(me.handleResponse, me, [request], true);
         Ext.getHead().appendChild(script);
         return request;
     },
-    
+
     
     abort: function(request){
         var requests = this.statics().requests,
             key;
-            
+
         if (request) {
             if (!request.id) {
                 request = requests[request];
@@ -50970,40 +53125,40 @@ Ext.define('Ext.data.JsonP', {
             }
         }
     },
-    
+
     
     setupErrorHandling: function(request){
         request.script.onerror = Ext.bind(this.handleError, this, [request]);
     },
-    
+
     
     handleAbort: function(request){
         request.errorType = 'abort';
         this.handleResponse(null, request);
     },
-    
+
     
     handleError: function(request){
         request.errorType = 'error';
         this.handleResponse(null, request);
     },
+
     
     cleanupErrorHandling: function(request){
         request.script.onerror = null;
     },
+
     
     handleTimeout: function(request){
         request.errorType = 'timeout';
         this.handleResponse(null, request);
     },
+
     
     handleResponse: function(result, request){
+
         var success = true;
+
         if (request.timeout) {
             clearTimeout(request.timeout);
         }
@@ -51011,7 +53166,7 @@ Ext.define('Ext.data.JsonP', {
         delete this.statics()[request.id];
         this.cleanupErrorHandling(request);
         Ext.fly(request.script).remove();
+
         if (request.errorType) {
             success = false;
             Ext.callback(request.failure, request.scope, [request.errorType]);
@@ -51020,7 +53175,7 @@ Ext.define('Ext.data.JsonP', {
         }
         Ext.callback(request.callback, request.scope, [success, result, request.errorType]);
     },
-    
+
     
     createScript: function(url, params) {
         var script = document.createElement('script');
@@ -51048,7 +53203,66 @@ Ext.define('Ext.data.JsonPStore', {
 
 Ext.define('Ext.data.NodeInterface', {
     requires: ['Ext.data.Field'],
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+
+    
+
+    
+
+    
+
+    
+
+    
+
     
+
     statics: {
         
         decorate: function(record) {
@@ -51059,51 +53273,46 @@ Ext.define('Ext.data.NodeInterface', {
                     modelName = record.modelName,
                     modelClass = mgr.getModel(modelName),
                     idName = modelClass.prototype.idProperty,
-                    instances = Ext.Array.filter(mgr.all.getArray(), function(item) {
-                        return item.modelName == modelName;
-                    }),
-                    iln = instances.length,
                     newFields = [],
-                    i, instance, jln, j, newField;
+                    i, newField, len;
 
                 
                 modelClass.override(this.getPrototypeBody());
                 newFields = this.applyFields(modelClass, [
-                    {name: idName,      type: 'string',  defaultValue: null},
-                    {name: 'parentId',  type: 'string',  defaultValue: null},
-                    {name: 'index',     type: 'int',     defaultValue: null},
-                    {name: 'depth',     type: 'int',     defaultValue: 0}, 
-                    {name: 'expanded',  type: 'bool',    defaultValue: false, persist: false},
-                    {name: 'checked',   type: 'auto',    defaultValue: null},
-                    {name: 'leaf',      type: 'bool',    defaultValue: false, persist: false},
-                    {name: 'cls',       type: 'string',  defaultValue: null, persist: false},
-                    {name: 'iconCls',   type: 'string',  defaultValue: null, persist: false},
-                    {name: 'root',      type: 'boolean', defaultValue: false, persist: false},
-                    {name: 'isLast',    type: 'boolean', defaultValue: false, persist: false},
-                    {name: 'isFirst',   type: 'boolean', defaultValue: false, persist: false},
-                    {name: 'allowDrop', type: 'boolean', defaultValue: true, persist: false},
-                    {name: 'allowDrag', type: 'boolean', defaultValue: true, persist: false},
-                    {name: 'loaded',    type: 'boolean', defaultValue: false, persist: false},
-                    {name: 'loading',   type: 'boolean', defaultValue: false, persist: false},
-                    {name: 'href',      type: 'string',  defaultValue: null, persist: false},
-                    {name: 'hrefTarget',type: 'string',  defaultValue: null, persist: false},
-                    {name: 'qtip',      type: 'string',  defaultValue: null, persist: false},
-                    {name: 'qtitle',    type: 'string',  defaultValue: null, persist: false}
+                    {name: idName,       type: 'string',  defaultValue: null},
+                    {name: 'parentId',   type: 'string',  defaultValue: null},
+                    {name: 'index',      type: 'int',     defaultValue: null},
+                    {name: 'depth',      type: 'int',     defaultValue: 0},
+                    {name: 'expanded',   type: 'bool',    defaultValue: false, persist: false},
+                    {name: 'expandable', type: 'bool',    defaultValue: true, persist: false},
+                    {name: 'checked',    type: 'auto',    defaultValue: null},
+                    {name: 'leaf',       type: 'bool',    defaultValue: false, persist: false},
+                    {name: 'cls',        type: 'string',  defaultValue: null, persist: false},
+                    {name: 'iconCls',    type: 'string',  defaultValue: null, persist: false},
+                    {name: 'icon',       type: 'string',  defaultValue: null, persist: false},
+                    {name: 'root',       type: 'boolean', defaultValue: false, persist: false},
+                    {name: 'isLast',     type: 'boolean', defaultValue: false, persist: false},
+                    {name: 'isFirst',    type: 'boolean', defaultValue: false, persist: false},
+                    {name: 'allowDrop',  type: 'boolean', defaultValue: true, persist: false},
+                    {name: 'allowDrag',  type: 'boolean', defaultValue: true, persist: false},
+                    {name: 'loaded',     type: 'boolean', defaultValue: false, persist: false},
+                    {name: 'loading',    type: 'boolean', defaultValue: false, persist: false},
+                    {name: 'href',       type: 'string',  defaultValue: null, persist: false},
+                    {name: 'hrefTarget', type: 'string',  defaultValue: null, persist: false},
+                    {name: 'qtip',       type: 'string',  defaultValue: null, persist: false},
+                    {name: 'qtitle',     type: 'string',  defaultValue: null, persist: false}
                 ]);
 
-                jln = newFields.length;
+                len = newFields.length;
                 
-                for (i = 0; i < iln; i++) {
-                    instance = instances[i];
-                    for (j = 0; j < jln; j++) {
-                        newField = newFields[j];
-                        if (instance.get(newField.name) === undefined) {
-                            instance.data[newField.name] = newField.defaultValue;
-                        }
+                for (i = 0; i < len; ++i) {
+                    newField = newFields[i];
+                    if (record.get(newField.name) === undefined) {
+                        record.data[newField.name] = newField.defaultValue;
                     }
                 }
             }
-            
+
             Ext.applyIf(record, {
                 firstChild: null,
                 lastChild: null,
@@ -51114,7 +53323,7 @@ Ext.define('Ext.data.NodeInterface', {
             });
             
             record.commit(true);
-            
+
             record.enableBubble([
                 
                 "append",
@@ -51139,26 +53348,26 @@ Ext.define('Ext.data.NodeInterface', {
 
                  
                 "beforeinsert",
-                
+
                 
                 "expand",
-                
+
                 
                 "collapse",
-                
+
                 
                 "beforeexpand",
-                
+
                 
                 "beforecollapse",
-                
+
                 
                 "sort"
             ]);
-            
+
             return record;
         },
-        
+
         applyFields: function(modelClass, addFields) {
             var modelPrototype = modelClass.prototype,
                 fields = modelPrototype.fields,
@@ -51166,20 +53375,20 @@ Ext.define('Ext.data.NodeInterface', {
                 ln = addFields.length,
                 addField, i, name,
                 newFields = [];
-                
+
             for (i = 0; i < ln; i++) {
                 addField = addFields[i];
                 if (!Ext.Array.contains(keys, addField.name)) {
                     addField = Ext.create('data.field', addField);
-                    
+
                     newFields.push(addField);
                     fields.add(addField);
                 }
             }
-            
+
             return newFields;
         },
-        
+
         getPrototypeBody: function() {
             return {
                 isNode: true,
@@ -51192,7 +53401,7 @@ Ext.define('Ext.data.NodeInterface', {
                     
                     return Ext.data.NodeInterface.decorate(node);
                 },
-                
+
                 
                 isLeaf : function() {
                     return this.get('leaf') === true;
@@ -51224,8 +53433,8 @@ Ext.define('Ext.data.NodeInterface', {
                     while (parent.parentNode) {
                         ++depth;
                         parent = parent.parentNode;
-                    }                                            
-                    
+                    }
+
                     me.beginEdit();
                     me.set({
                         isFirst: isFirst,
@@ -51238,7 +53447,7 @@ Ext.define('Ext.data.NodeInterface', {
                     if (silent) {
                         me.commit();
                     }
-                    
+
                     for (i = 0; i < len; i++) {
                         children[i].updateInfo(silent);
                     }
@@ -51261,7 +53470,12 @@ Ext.define('Ext.data.NodeInterface', {
 
                 
                 isExpandable : function() {
-                    return this.get('expandable') || this.hasChildNodes();
+                    var me = this;
+
+                    if (me.get('expandable')) {
+                        return !(me.isLeaf() || (me.isLoaded() && !me.hasChildNodes()));
+                    }
+                    return false;
                 },
 
                 
@@ -51280,9 +53494,9 @@ Ext.define('Ext.data.NodeInterface', {
                     } else {
                         
                         node = me.createNode(node);
-                        
+
                         if (suppressEvents !== true && me.fireEvent("beforeappend", me, node) === false) {
-                            return false;                         
+                            return false;
                         }
 
                         index = me.childNodes.length;
@@ -51306,7 +53520,7 @@ Ext.define('Ext.data.NodeInterface', {
                         node.nextSibling = null;
 
                         me.setLastChild(node);
-                                                
+
                         ps = me.childNodes[index - 1];
                         if (ps) {
                             node.previousSibling = ps;
@@ -51317,28 +53531,28 @@ Ext.define('Ext.data.NodeInterface', {
                         }
 
                         node.updateInfo(suppressNodeUpdate);
-                        
+
                         
                         if (!me.isLoaded()) {
-                            me.set('loaded', true);                            
+                            me.set('loaded', true);
                         }
                         
                         else if (me.childNodes.length === 1) {
                             me.set('loaded', me.isLoaded());
                         }
-                        
+
                         if (suppressEvents !== true) {
                             me.fireEvent("append", me, node, index);
 
                             if (oldParent) {
                                 node.fireEvent("move", node, oldParent, me, index);
-                            }                            
+                            }
                         }
 
                         return node;
                     }
                 },
-                
+
                 
                 getBubbleTarget: function() {
                     return this.parentNode;
@@ -51348,13 +53562,13 @@ Ext.define('Ext.data.NodeInterface', {
                 removeChild : function(node, destroy, suppressEvents, suppressNodeUpdate) {
                     var me = this,
                         index = me.indexOf(node);
-                    
+
                     if (index == -1 || (suppressEvents !== true && me.fireEvent("beforeremove", me, node) === false)) {
                         return false;
                     }
 
                     
-                    me.childNodes.splice(index, 1);
+                    Ext.Array.erase(me.childNodes, index, 1);
 
                     
                     if (me.firstChild == node) {
@@ -51363,7 +53577,7 @@ Ext.define('Ext.data.NodeInterface', {
                     if (me.lastChild == node) {
                         me.setLastChild(node.previousSibling);
                     }
-                    
+
                     
                     if (node.previousSibling) {
                         node.previousSibling.nextSibling = node.nextSibling;
@@ -51377,13 +53591,13 @@ Ext.define('Ext.data.NodeInterface', {
                     if (suppressEvents !== true) {
                         me.fireEvent("remove", me, node);
                     }
-                    
-                    
+
+
                     
                     if (!me.childNodes.length) {
                         me.set('loaded', me.isLoaded());
                     }
-                    
+
                     if (destroy) {
                         node.destroy(true);
                     } else {
@@ -51412,7 +53626,7 @@ Ext.define('Ext.data.NodeInterface', {
                 
                 clear : function(destroy) {
                     var me = this;
-                    
+
                     
                     me.parentNode = me.previousSibling = me.nextSibling = null;
                     if (destroy) {
@@ -51423,19 +53637,22 @@ Ext.define('Ext.data.NodeInterface', {
                 
                 destroy : function(silent) {
                     
-                    var me = this;
-                    
+                    var me = this,
+                        options = me.destroyOptions;
+
                     if (silent === true) {
                         me.clear(true);
                         Ext.each(me.childNodes, function(n) {
                             n.destroy(true);
                         });
                         me.childNodes = null;
+                        delete me.destroyOptions;
+                        me.callOverridden([options]);
                     } else {
+                        me.destroyOptions = silent;
+                        
                         me.remove(true);
                     }
-
-                    me.callOverridden();
                 },
 
                 
@@ -51445,11 +53662,11 @@ Ext.define('Ext.data.NodeInterface', {
                         oldParent = node.parentNode,
                         refIndex  = index,
                         ps;
-                    
+
                     if (!refNode) { 
                         return me.appendChild(node);
                     }
-                    
+
                     
                     if (node == refNode) {
                         return false;
@@ -51457,11 +53674,11 @@ Ext.define('Ext.data.NodeInterface', {
 
                     
                     node = me.createNode(node);
-                    
+
                     if (suppressEvents !== true && me.fireEvent("beforeinsert", me, node, refNode) === false) {
                         return false;
                     }
-                    
+
                     
                     if (oldParent == me && me.indexOf(node) < index) {
                         refIndex--;
@@ -51479,12 +53696,12 @@ Ext.define('Ext.data.NodeInterface', {
                         me.setFirstChild(node);
                     }
 
-                    me.childNodes.splice(refIndex, 0, node);
+                    Ext.Array.splice(me.childNodes, refIndex, 0, node);
                     node.parentNode = me;
-                    
+
                     node.nextSibling = refNode;
                     refNode.previousSibling = node;
-                    
+
                     ps = me.childNodes[refIndex - 1];
                     if (ps) {
                         node.previousSibling = ps;
@@ -51493,12 +53710,12 @@ Ext.define('Ext.data.NodeInterface', {
                     } else {
                         node.previousSibling = null;
                     }
-                    
+
                     node.updateInfo();
-                    
+
                     if (!me.isLoaded()) {
-                        me.set('loaded', true);                            
-                    }    
+                        me.set('loaded', true);
+                    }
                     
                     else if (me.childNodes.length === 1) {
                         me.set('loaded', me.isLoaded());
@@ -51509,13 +53726,13 @@ Ext.define('Ext.data.NodeInterface', {
 
                         if (oldParent) {
                             node.fireEvent("move", node, oldParent, me, refIndex, refNode);
-                        }                        
+                        }
                     }
 
                     return node;
                 },
+
                 
-                    
                 insertChild: function(index, node) {
                     var sibling = this.childNodes[index];
                     if (sibling) {
@@ -51555,7 +53772,7 @@ Ext.define('Ext.data.NodeInterface', {
                 
                 replaceChild : function(newChild, oldChild, suppressEvents) {
                     var s = oldChild ? oldChild.nextSibling : null;
-                    
+
                     this.removeChild(oldChild, suppressEvents);
                     this.insertBefore(newChild, s, suppressEvents);
                     return oldChild;
@@ -51567,6 +53784,21 @@ Ext.define('Ext.data.NodeInterface', {
                 },
 
                 
+                getPath: function(field, separator) {
+                    field = field || this.idProperty;
+                    separator = separator || '/';
+
+                    var path = [this.get(field)],
+                        parent = this.parentNode;
+
+                    while (parent) {
+                        path.unshift(parent.get(field));
+                        parent = parent.parentNode;
+                    }
+                    return separator + path.join(separator);
+                },
+
+                
                 getDepth : function() {
                     return this.get('depth');
                 },
@@ -51666,14 +53898,14 @@ Ext.define('Ext.data.NodeInterface', {
                     var cs  = this.childNodes,
                         ln = cs.length,
                         i, n;
-                    
+
                     if (ln > 0) {
                         Ext.Array.sort(cs, sortFn);
                         for (i = 0; i < ln; i++) {
                             n = cs[i];
                             n.previousSibling = cs[i-1];
                             n.nextSibling = cs[i+1];
-                        
+
                             if (i === 0) {
                                 this.setFirstChild(n);
                                 n.updateInfo();
@@ -51686,34 +53918,34 @@ Ext.define('Ext.data.NodeInterface', {
                                 n.sort(sortFn, true, true);
                             }
                         }
-                        
+
                         if (suppressEvent !== true) {
                             this.fireEvent('sort', this, cs);
                         }
                     }
                 },
-                        
-                        
+
+                
                 isExpanded: function() {
                     return this.get('expanded');
                 },
+
                 
-                 
                 isLoaded: function() {
                     return this.get('loaded');
                 },
 
-                 
+                
                 isLoading: function() {
                     return this.get('loading');
                 },
-                                
-                 
+
+                
                 isRoot: function() {
                     return !this.parentNode;
                 },
+
                 
-                 
                 isVisible: function() {
                     var parent = this.parentNode;
                     while (parent) {
@@ -51724,7 +53956,7 @@ Ext.define('Ext.data.NodeInterface', {
                     }
                     return true;
                 },
-                
+
                 
                 expand: function(recursive, callback, scope) {
                     var me = this;
@@ -51735,42 +53967,41 @@ Ext.define('Ext.data.NodeInterface', {
                     
                     if (!me.isLeaf()) {
                         
-                        if (!me.isLoading() && !me.isExpanded()) {
-                            
-                            
-                            
+                        if (me.isLoading()) {
+                            me.on('expand', function(){
+                                me.expand(recursive, callback, scope);
+                            }, me, {single: true});
+                        } else {
                             
-                            me.fireEvent('beforeexpand', me, function(records) {
-                                me.set('expanded', true); 
-                                me.fireEvent('expand', me, me.childNodes, false);
+                            if (!me.isExpanded()) {
                                 
                                 
-                                if (recursive) {
-                                    me.expandChildren(true, callback, scope);
-                                }
-                                else {
-                                    Ext.callback(callback, scope || me, [me.childNodes]);                                
-                                }
-                            }, me);                            
-                        }
-                        
-                        else if (recursive) {
-                            me.expandChildren(true, callback, scope);
-                        }
-                        else {
-                            Ext.callback(callback, scope || me, [me.childNodes]);
-                        }
+                                
+                                
+                                me.fireEvent('beforeexpand', me, function(){
+                                    me.set('expanded', true);
+                                    me.fireEvent('expand', me, me.childNodes, false);
 
+                                    
+                                    if (recursive) {
+                                        me.expandChildren(true, callback, scope);
+                                    } else {
+                                        Ext.callback(callback, scope || me, [me.childNodes]);
+                                    }
+                                }, me);
+                            } else if (recursive) {
+                                
+                                me.expandChildren(true, callback, scope);
+                            } else {
+                                Ext.callback(callback, scope || me, [me.childNodes]);
+                            }
+                        }
+                    } else {
                         
-                        
-                        
-                    }
-                    
-                    else {
                         Ext.callback(callback, scope || me); 
                     }
                 },
-                
+
                 
                 expandChildren: function(recursive, callback, scope) {
                     var me = this,
@@ -51787,15 +54018,14 @@ Ext.define('Ext.data.NodeInterface', {
                             nodes[i].expand(recursive, function () {
                                 expanding--;
                                 if (callback && !expanding) {
-                                    Ext.callback(callback, scope || me, me.childNodes); 
+                                    Ext.callback(callback, scope || me, [me.childNodes]);
                                 }
-                            });                            
+                            });
                         }
                     }
-                    
+
                     if (!expanding && callback) {
-                        Ext.callback(callback, scope || me, me.childNodes);
-                    }
+                        Ext.callback(callback, scope || me, [me.childNodes]);                    }
                 },
 
                 
@@ -51806,18 +54036,18 @@ Ext.define('Ext.data.NodeInterface', {
                     if (!me.isLeaf()) {
                         
                         if (!me.collapsing && me.isExpanded()) {
-                            me.fireEvent('beforecollapse', me, function(records) {
-                                me.set('expanded', false); 
+                            me.fireEvent('beforecollapse', me, function() {
+                                me.set('expanded', false);
                                 me.fireEvent('collapse', me, me.childNodes, false);
-                                
+
                                 
                                 if (recursive) {
                                     me.collapseChildren(true, callback, scope);
                                 }
                                 else {
-                                    Ext.callback(callback, scope || me, [me.childNodes]);                                
+                                    Ext.callback(callback, scope || me, [me.childNodes]);
                                 }
-                            }, me);                            
+                            }, me);
                         }
                         
                         else if (recursive) {
@@ -51826,10 +54056,10 @@ Ext.define('Ext.data.NodeInterface', {
                     }
                     
                     else {
-                        Ext.callback(callback, scope || me, me.childNodes); 
+                        Ext.callback(callback, scope || me, [me.childNodes]);
                     }
                 },
-                
+
                 
                 collapseChildren: function(recursive, callback, scope) {
                     var me = this,
@@ -51846,14 +54076,14 @@ Ext.define('Ext.data.NodeInterface', {
                             nodes[i].collapse(recursive, function () {
                                 collapsing--;
                                 if (callback && !collapsing) {
-                                    Ext.callback(callback, scope || me, me.childNodes); 
+                                    Ext.callback(callback, scope || me, [me.childNodes]);
                                 }
-                            });                            
+                            });
                         }
                     }
-                    
+
                     if (!collapsing && callback) {
-                        Ext.callback(callback, scope || me, me.childNodes);
+                        Ext.callback(callback, scope || me, [me.childNodes]);
                     }
                 }
             };
@@ -51882,10 +54112,6 @@ Ext.define('Ext.data.NodeStore', {
         config = config || {};
         Ext.apply(me, config);
         
-        if (Ext.isDefined(me.proxy)) {
-            Ext.Error.raise("A NodeStore cannot be bound to a proxy. Instead bind it to a record " +
-                            "decorated with the NodeInterface by setting the node config.");
-        }
 
         config.proxy = {type: 'proxy'};
         me.callParent([config]);
@@ -52101,28 +54327,59 @@ Ext.define('Ext.data.Request', {
     
     url: undefined,
 
+    
     constructor: function(config) {
         Ext.apply(this, config);
     }
 });
 
+Ext.define('Ext.data.SequentialIdGenerator', {
+    extend: 'Ext.data.IdGenerator',
+    alias: 'idgen.sequential',
+
+    constructor: function() {
+        var me = this;
+
+        me.callParent(arguments);
+
+        me.parts = [ me.prefix, ''];
+    },
+
+    
+    prefix: '',
+
+    
+    seed: 1,
+
+    
+    generate: function () {
+        var me = this,
+            parts = me.parts;
+
+        parts[1] = me.seed++;
+        return parts.join('');
+    }
+});
+
+
 Ext.define('Ext.data.Tree', {
     alias: 'data.tree',
-    
+
     mixins: {
         observable: "Ext.util.Observable"
     },
 
     
     root: null,
-        
+
+    
     constructor: function(root) {
         var me = this;
+
         
-        me.nodeHash = {};
 
         me.mixins.observable.constructor.call(me);
-                        
+
         if (root) {
             me.setRootNode(root);
         }
@@ -52136,14 +54393,14 @@ Ext.define('Ext.data.Tree', {
     
     setRootNode : function(node) {
         var me = this;
-        
+
         me.root = node;
         Ext.data.NodeInterface.decorate(node);
-        
+
         if (me.fireEvent('beforeappend', null, node) !== false) {
             node.set('root', true);
             node.updateInfo();
-            
+
             me.relayEvents(node, [
                 
                 "append",
@@ -52184,7 +54441,7 @@ Ext.define('Ext.data.Tree', {
                  
                  "rootchange"
             ]);
-            
+
             node.on({
                 scope: me,
                 insert: me.onNodeInsert,
@@ -52192,20 +54449,21 @@ Ext.define('Ext.data.Tree', {
                 remove: me.onNodeRemove
             });
 
-            me.registerNode(node);        
+            me.nodeHash = {};
+            me.registerNode(node);
             me.fireEvent('append', null, node);
             me.fireEvent('rootchange', node);
         }
-            
+
         return node;
     },
-    
+
     
     flatten: function(){
         var nodes = [],
             hash = this.nodeHash,
             key;
-            
+
         for (key in hash) {
             if (hash.hasOwnProperty(key)) {
                 nodes.push(hash[key]);
@@ -52213,20 +54471,20 @@ Ext.define('Ext.data.Tree', {
         }
         return nodes;
     },
-    
+
     
     onNodeInsert: function(parent, node) {
-        this.registerNode(node);
+        this.registerNode(node, true);
     },
-    
+
     
     onNodeAppend: function(parent, node) {
-        this.registerNode(node);
+        this.registerNode(node, true);
     },
-    
+
     
     onNodeRemove: function(parent, node) {
-        this.unregisterNode(node);
+        this.unregisterNode(node, true);
     },
 
     
@@ -52235,20 +54493,30 @@ Ext.define('Ext.data.Tree', {
     },
 
     
-    registerNode : function(node) {
+    registerNode : function(node, includeChildren) {
         this.nodeHash[node.getId() || node.internalId] = node;
+        if (includeChildren === true) {
+            node.eachChild(function(child){
+                this.registerNode(child, true);
+            }, this);
+        }
     },
 
     
-    unregisterNode : function(node) {
+    unregisterNode : function(node, includeChildren) {
         delete this.nodeHash[node.getId() || node.internalId];
+        if (includeChildren === true) {
+            node.eachChild(function(child){
+                this.unregisterNode(child, true);
+            }, this);
+        }
     },
-    
+
     
     sort: function(sorterFn, recursive) {
         this.getRootNode().sort(sorterFn, recursive);
     },
-    
+
      
     filter: function(filters, recursive) {
         this.getRootNode().filter(filters, recursive);
@@ -52261,6 +54529,8 @@ Ext.define('Ext.data.TreeStore', {
     requires: ['Ext.data.Tree', 'Ext.data.NodeInterface', 'Ext.data.NodeStore'],
 
     
+
+    
     clearOnLoad : true,
 
     
@@ -52268,21 +54538,20 @@ Ext.define('Ext.data.TreeStore', {
 
     
     defaultRootId: 'root',
-    
+
     
     defaultRootProperty: 'children',
 
     
     folderSort: false,
-    
+
     constructor: function(config) {
-        var me = this, 
+        var me = this,
             root,
             fields;
-            
-        
+
         config = Ext.apply({}, config);
-        
+
         
         fields = config.fields || me.fields;
         if (!fields) {
@@ -52290,76 +54559,75 @@ Ext.define('Ext.data.TreeStore', {
         }
 
         me.callParent([config]);
-        
+
         
         me.tree = Ext.create('Ext.data.Tree');
-        
-        me.tree.on({
-            scope: me,
-            remove: me.onNodeRemove,
-            beforeexpand: me.onBeforeNodeExpand,
-            beforecollapse: me.onBeforeNodeCollapse,
-            append: me.onNodeAdded,
-            insert: me.onNodeAdded
-        });
-
-        me.onBeforeSort();
-                
-        root = me.root;
-        if (root) {
-            delete me.root;
-            me.setRootNode(root);            
-        }
 
         me.relayEvents(me.tree, [
             
             "append",
-            
+
             
             "remove",
-            
+
             
             "move",
-            
+
             
             "insert",
-            
+
             
             "beforeappend",
-            
+
             
             "beforeremove",
-            
+
             
             "beforemove",
-            
+
             
             "beforeinsert",
-             
+
              
              "expand",
-             
+
              
              "collapse",
-             
+
              
              "beforeexpand",
-             
+
              
              "beforecollapse",
 
-                          
-             "sort",
-             
              
              "rootchange"
         ]);
-        
+
+        me.tree.on({
+            scope: me,
+            remove: me.onNodeRemove,
+            
+            
+            beforeexpand: me.onBeforeNodeExpand,
+            beforecollapse: me.onBeforeNodeCollapse,
+            append: me.onNodeAdded,
+            insert: me.onNodeAdded
+        });
+
+        me.onBeforeSort();
+
+        root = me.root;
+        if (root) {
+            delete me.root;
+            me.setRootNode(root);
+        }
+
         me.addEvents(
             
-            'rootchange'
+            'sort'
         );
-        
+
         if (Ext.isDefined(me.nodeParameter)) {
             if (Ext.isDefined(Ext.global.console)) {
                 Ext.global.console.warn('Ext.data.TreeStore: nodeParameter has been deprecated. Please use nodeParam instead.');
@@ -52368,12 +54636,12 @@ Ext.define('Ext.data.TreeStore', {
             delete me.nodeParameter;
         }
     },
-    
+
     
     setProxy: function(proxy) {
         var reader,
             needsRoot;
-        
+
         if (proxy instanceof Ext.data.proxy.Proxy) {
             
             needsRoot = Ext.isEmpty(proxy.getReader().root);
@@ -52393,17 +54661,17 @@ Ext.define('Ext.data.TreeStore', {
             reader.buildExtractors(true);
         }
     },
-    
+
     
     onBeforeSort: function() {
         if (this.folderSort) {
             this.sort({
                 property: 'leaf',
                 direction: 'ASC'
-            }, 'prepend', false);    
+            }, 'prepend', false);
         }
     },
-    
+
     
     onBeforeNodeExpand: function(node, callback, scope) {
         if (node.isLoaded()) {
@@ -52420,10 +54688,10 @@ Ext.define('Ext.data.TreeStore', {
                 callback: function() {
                     Ext.callback(callback, scope || node, [node.childNodes]);
                 }
-            });            
+            });
         }
     },
-    
+
     
     getNewRecords: function() {
         return Ext.Array.filter(this.tree.flatten(), this.filterNew);
@@ -52433,28 +54701,28 @@ Ext.define('Ext.data.TreeStore', {
     getUpdatedRecords: function() {
         return Ext.Array.filter(this.tree.flatten(), this.filterUpdated);
     },
-    
+
     
     onBeforeNodeCollapse: function(node, callback, scope) {
         callback.call(scope || node, node.childNodes);
     },
-    
+
     onNodeRemove: function(parent, node) {
         var removed = this.removed;
-        
+
         if (!node.isReplace && Ext.Array.indexOf(removed, node) == -1) {
             removed.push(node);
         }
     },
-    
+
     onNodeAdded: function(parent, node) {
         var proxy = this.getProxy(),
             reader = proxy.getReader(),
             data = node.raw || node.data,
             dataRoot, children;
-            
-        Ext.Array.remove(this.removed, node); 
-        
+
+        Ext.Array.remove(this.removed, node);
+
         if (!node.isLeaf() && !node.isLoaded()) {
             dataRoot = reader.getRoot(data);
             if (dataRoot) {
@@ -52463,12 +54731,12 @@ Ext.define('Ext.data.TreeStore', {
             }
         }
     },
-        
+
     
     setRootNode: function(root) {
         var me = this;
 
-        root = root || {};        
+        root = root || {};
         if (!root.isNode) {
             
             Ext.applyIf(root, {
@@ -52483,20 +54751,20 @@ Ext.define('Ext.data.TreeStore', {
         
         
         me.getProxy().getReader().buildExtractors(true);
-        
+
         
         me.tree.setRootNode(root);
+
         
-        
-        if (!root.isLoaded() && root.isExpanded()) {
+        if (!root.isLoaded() && (me.autoLoad === true || root.isExpanded())) {
             me.load({
                 node: root
             });
         }
-        
+
         return root;
     },
-        
+
     
     getRootNode: function() {
         return this.tree.getRootNode();
@@ -52511,11 +54779,11 @@ Ext.define('Ext.data.TreeStore', {
     load: function(options) {
         options = options || {};
         options.params = options.params || {};
-        
+
         var me = this,
             node = options.node || me.tree.getRootNode(),
             root;
-            
+
         
         
         if (!node) {
@@ -52523,23 +54791,23 @@ Ext.define('Ext.data.TreeStore', {
                 expanded: true
             });
         }
-        
+
         if (me.clearOnLoad) {
-            node.removeAll();
+            node.removeAll(true);
         }
-        
+
         Ext.applyIf(options, {
             node: node
         });
         options.params[me.nodeParam] = node ? node.getId() : 'root';
-        
+
         if (node) {
             node.set('loading', true);
         }
-        
+
         return me.callParent([options]);
     },
-        
+
 
     
     fillNode: function(node, records) {
@@ -52553,12 +54821,12 @@ Ext.define('Ext.data.TreeStore', {
             sortCollection.sort(me.sorters.items);
             records = sortCollection.items;
         }
-        
+
         node.set('loaded', true);
         for (; i < ln; i++) {
             node.appendChild(records[i], undefined, true);
         }
-        
+
         return records;
     },
 
@@ -52569,17 +54837,21 @@ Ext.define('Ext.data.TreeStore', {
             records = operation.getRecords(),
             node = operation.node;
 
+        me.loading = false;
         node.set('loading', false);
         if (successful) {
             records = me.fillNode(node, records);
         }
         
+        
+        
+        
         me.fireEvent('read', me, operation.node, records, successful);
         me.fireEvent('load', me, operation.node, records, successful);
         
         Ext.callback(operation.callback, operation.scope || me, [records, operation, successful]);
     },
-    
+
     
     onCreateRecords: function(records, operation, success) {
         if (success) {
@@ -52643,7 +54915,7 @@ Ext.define('Ext.data.TreeStore', {
 
     
     removeAll: function() {
-        this.getRootNode().destroy();
+        this.getRootNode().destroy(true);
         this.fireEvent('clear', this);
     },
 
@@ -52656,11 +54928,139 @@ Ext.define('Ext.data.TreeStore', {
         } else {
             me.tree.sort(sorterFn, true);
             me.fireEvent('datachanged', me);
-        }   
+        }
         me.fireEvent('sort', me);
     }
 });
 
+
+Ext.define('Ext.data.UuidGenerator', function () {
+    var twoPow14 = Math.pow(2, 14),
+        twoPow16 = Math.pow(2, 16),
+        twoPow28 = Math.pow(2, 28),
+        twoPow32 = Math.pow(2, 32);
+
+    function toHex (value, length) {
+        var ret = value.toString(16);
+        if (ret.length > length) {
+            ret = ret.substring(ret.length - length); 
+        } else if (ret.length < length) {
+            ret = Ext.String.leftPad(ret, length, '0');
+        }
+        return ret;
+    }
+
+    function rand (lo, hi) {
+        var v = Math.random() * (hi - lo + 1);
+        return Math.floor(v) + lo;
+    }
+
+    function split (bignum) {
+        if (typeof(bignum) == 'number') {
+            var hi = Math.floor(bignum / twoPow32);
+            return {
+                lo: Math.floor(bignum - hi * twoPow32),
+                hi: hi
+            };
+        }
+        return bignum;
+    }
+
+    return {
+        extend: 'Ext.data.IdGenerator',
+
+        alias: 'idgen.uuid',
+
+        id: 'uuid', 
+
+        
+
+        
+
+        
+        version: 4,
+
+        constructor: function() {
+            var me = this;
+
+            me.callParent(arguments);
+
+            me.parts = [];
+            me.init();
+        },
+
+        generate: function () {
+            var me = this,
+                parts = me.parts,
+                ts = me.timestamp;
+
+            
+            parts[0] = toHex(ts.lo, 8);
+            parts[1] = toHex(ts.hi & 0xFFFF, 4);
+            parts[2] = toHex(((ts.hi >>> 16) & 0xFFF) | (me.version << 12), 4);
+            parts[3] = toHex(0x80 | ((me.clockSeq >>> 8) & 0x3F), 2) +
+                       toHex(me.clockSeq & 0xFF, 2);
+            parts[4] = toHex(me.salt.hi, 4) + toHex(me.salt.lo, 8);
+
+            if (me.version == 4) {
+                me.init(); 
+            } else {
+                
+                ++ts.lo;
+                if (ts.lo >= twoPow32) { 
+                    ts.lo = 0;
+                    ++ts.hi;
+                }
+            }
+
+            return parts.join('-').toLowerCase();
+        },
+
+        getRecId: function (rec) {
+            return rec.getId();
+        },
+
+        
+        init: function () {
+            var me = this,
+                salt, time;
+
+            if (me.version == 4) {
+                
+                
+                
+                
+                me.clockSeq = rand(0, twoPow14-1);
+
+                
+                salt = me.salt || (me.salt = {});
+                time = me.timestamp || (me.timestamp = {});
+
+                
+                salt.lo = rand(0, twoPow32-1);
+                salt.hi = rand(0, twoPow16-1);
+                time.lo = rand(0, twoPow32-1);
+                time.hi = rand(0, twoPow28-1);
+            } else {
+                
+                me.salt = split(me.salt);
+                me.timestamp = split(me.timestamp);
+
+                
+                
+                me.salt.hi |= 0x100;
+            }
+        },
+
+        
+        reconfigure: function (config) {
+            Ext.apply(this, config);
+            this.init();
+        }
+    };
+}());
+
+
 Ext.define('Ext.data.XmlStore', {
     extend: 'Ext.data.Store',
     alternateClassName: 'Ext.data.XmlStore',
@@ -52687,10 +55087,9 @@ Ext.define('Ext.data.XmlStore', {
 Ext.define('Ext.data.proxy.Client', {
     extend: 'Ext.data.proxy.Proxy',
     alternateClassName: 'Ext.data.ClientProxy',
-    
+
     
     clear: function() {
-        Ext.Error.raise("The Ext.data.proxy.Client subclass that you are using has not defined a 'clear' function. See src/data/ClientProxy.js for details.");
     }
 });
 
@@ -52739,12 +55138,12 @@ Ext.define('Ext.data.proxy.JsonP', {
             disableCaching: false, 
             callback: me.createRequestCallback(request, operation, callback, scope)
         });
-        
+
         
         if (me.autoAppendParams) {
             request.params = {};
         }
-        
+
         request.jsonp = Ext.data.JsonP.request(request);
         
         request.params = params;
@@ -52763,7 +55162,7 @@ Ext.define('Ext.data.proxy.JsonP', {
             me.processResponse(success, operation, request, response, callback, scope);
         };
     },
-    
+
     
     setException: function(operation, response) {
         operation.setException(operation.request.jsonp.errorType);
@@ -52780,7 +55179,7 @@ Ext.define('Ext.data.proxy.JsonP', {
             filter, i;
 
         delete params.filters;
+
         if (me.autoAppendParams) {
             url = Ext.urlAppend(url, Ext.Object.toQueryString(params));
         }
@@ -52837,27 +55236,21 @@ Ext.define('Ext.data.proxy.JsonP', {
 Ext.define('Ext.data.proxy.WebStorage', {
     extend: 'Ext.data.proxy.Client',
     alternateClassName: 'Ext.data.WebStorageProxy',
-    
+
     
     id: undefined,
 
     
     constructor: function(config) {
         this.callParent(arguments);
-        
+
         
         this.cache = {};
 
-        if (this.getStorageObject() === undefined) {
-            Ext.Error.raise("Local Storage is not supported in this browser, please use another type of data proxy");
-        }
 
         
         this.id = this.id || (this.store ? this.store.storeId : undefined);
 
-        if (this.id === undefined) {
-            Ext.Error.raise("No unique id was provided to the local storage proxy. See Ext.data.proxy.LocalStorage documentation for details");
-        }
 
         this.initialize();
     },
@@ -52868,7 +55261,7 @@ Ext.define('Ext.data.proxy.WebStorage', {
             length  = records.length,
             ids     = this.getIds(),
             id, record, i;
-        
+
         operation.setStarted();
 
         for (i = 0; i < length; i++) {
@@ -52903,11 +55296,11 @@ Ext.define('Ext.data.proxy.WebStorage', {
             ids     = this.getIds(),
             length  = ids.length,
             i, recordData, record;
-        
+
         
         if (operation.id) {
             record = this.getRecord(operation.id);
-            
+
             if (record) {
                 records.push(record);
                 operation.setSuccessful();
@@ -52918,7 +55311,7 @@ Ext.define('Ext.data.proxy.WebStorage', {
             }
             operation.setSuccessful();
         }
-        
+
         operation.setCompleted();
 
         operation.resultSet = Ext.create('Ext.data.ResultSet', {
@@ -52944,7 +55337,7 @@ Ext.define('Ext.data.proxy.WebStorage', {
         for (i = 0; i < length; i++) {
             record = records[i];
             this.setRecord(record);
-            
+
             
             
             id = record.getId();
@@ -52978,7 +55371,7 @@ Ext.define('Ext.data.proxy.WebStorage', {
         }
 
         this.setIds(newIds);
-        
+
         operation.setCompleted();
         operation.setSuccessful();
 
@@ -53013,7 +55406,7 @@ Ext.define('Ext.data.proxy.WebStorage', {
 
             this.cache[id] = record;
         }
-        
+
         return this.cache[id];
     },
 
@@ -53047,10 +55440,10 @@ Ext.define('Ext.data.proxy.WebStorage', {
 
         obj = me.getStorageObject();
         key = me.getRecordKey(id);
-        
+
         
         me.cache[id] = record;
-        
+
         
         obj.removeItem(key);
         obj.setItem(key, Ext.encode(data));
@@ -53060,7 +55453,7 @@ Ext.define('Ext.data.proxy.WebStorage', {
     removeRecord: function(id, updateIds) {
         var me = this,
             ids;
-            
+
         if (id.isModel) {
             id = id.getId();
         }
@@ -53109,9 +55502,9 @@ Ext.define('Ext.data.proxy.WebStorage', {
     setIds: function(ids) {
         var obj = this.getStorageObject(),
             str = ids.join(",");
-        
+
         obj.removeItem(this.id);
-        
+
         if (!Ext.isEmpty(str)) {
             obj.setItem(this.id, str);
         }
@@ -53123,15 +55516,15 @@ Ext.define('Ext.data.proxy.WebStorage', {
             key  = this.getRecordCounterKey(),
             last = obj.getItem(key),
             ids, id;
-        
+
         if (last === null) {
             ids = this.getIds();
             last = ids[ids.length - 1] || 0;
         }
-        
+
         id = parseInt(last, 10) + 1;
         obj.setItem(key, id);
-        
+
         return id;
     },
 
@@ -53160,7 +55553,6 @@ Ext.define('Ext.data.proxy.WebStorage', {
 
     
     getStorageObject: function() {
-        Ext.Error.raise("The getStorageObject function has not been defined in your Ext.data.proxy.WebStorage subclass");
     }
 });
 
@@ -53286,16 +55678,18 @@ Ext.define('Ext.data.reader.Array', {
         this.callParent(arguments);
         
         var fields = this.model.prototype.fields.items,
+            i = 0,
             length = fields.length,
             extractorFunctions = [],
-            i;
+            map;
         
-        for (i = 0; i < length; i++) {
+        for (; i < length; i++) {
+            map = fields[i].mapping;
             extractorFunctions.push(function(index) {
                 return function(data) {
                     return data[index];
                 };
-            }(fields[i].mapping || i));
+            }(map !== null ? map : i));
         }
         
         this.extractorFunctions = extractorFunctions;
@@ -53307,58 +55701,37 @@ Ext.define('Ext.data.reader.Xml', {
     extend: 'Ext.data.reader.Reader',
     alternateClassName: 'Ext.data.XmlReader',
     alias : 'reader.xml',
-    
+
     
 
     
+    createAccessor: function(expr) {
+        var me = this;
 
-    createAccessor: function() {
-        var selectValue = function(expr, root){
-            var node = Ext.DomQuery.selectNode(expr, root),
-                val;
-                
-            
-            
-        };
+        if (Ext.isEmpty(expr)) {
+            return Ext.emptyFn;
+        }
 
-        return function(expr) {
-            var me = this;
-            
-            if (Ext.isEmpty(expr)) {
-                return Ext.emptyFn;
-            }
-            
-            if (Ext.isFunction(expr)) {
-                return expr;
-            }
-            
-            return function(root) {
-                var node = Ext.DomQuery.selectNode(expr, root),
-                    val = me.getNodeValue(node);
-                    
-                return Ext.isEmpty(val) ? null : val;
-            };
+        if (Ext.isFunction(expr)) {
+            return expr;
+        }
+
+        return function(root) {
+            return me.getNodeValue(Ext.DomQuery.selectNode(expr, root));
         };
-    }(),
-    
+    },
+
     getNodeValue: function(node) {
-        var val;
         if (node && node.firstChild) {
-            val = node.firstChild.nodeValue;
+            return node.firstChild.nodeValue;
         }
-        return val || null;
+        return undefined;
     },
 
     
     getResponseData: function(response) {
         var xml = response.responseXML;
 
-        if (!xml) {
-            Ext.Error.raise({
-                response: response,
-                msg: 'XML data not found in the response'
-            });
-        }
 
         return xml;
     },
@@ -53372,7 +55745,7 @@ Ext.define('Ext.data.reader.Xml', {
     getRoot: function(data) {
         var nodeName = data.nodeName,
             root     = this.root;
-        
+
         if (!root || (nodeName && nodeName == root)) {
             return data;
         } else if (Ext.DomQuery.isXml(data)) {
@@ -53386,11 +55759,8 @@ Ext.define('Ext.data.reader.Xml', {
     
     extractData: function(root) {
         var recordName = this.record;
-        
-        if (!recordName) {
-            Ext.Error.raise('Record is a required parameter');
-        }
-        
+
+
         if (recordName != root.nodeName) {
             root = Ext.DomQuery.select(recordName, root);
         } else {
@@ -53398,7 +55768,7 @@ Ext.define('Ext.data.reader.Xml', {
         }
         return this.callParent([root]);
     },
-    
+
     
     getAssociatedDataRoot: function(data, associationName) {
         return Ext.DomQuery.select(associationName, data)[0];
@@ -53410,14 +55780,13 @@ Ext.define('Ext.data.reader.Xml', {
         if (Ext.isArray(doc)) {
             doc = doc[0];
         }
-        
+
         
         this.xmlData = doc;
         return this.callParent([doc]);
     }
 });
 
-
 Ext.define('Ext.data.writer.Xml', {
     
     
@@ -53486,21 +55855,22 @@ Ext.define('Ext.data.writer.Xml', {
 
 
 Ext.define('Ext.direct.Event', {
+
     
-    
-   
+
     alias: 'direct.event',
-    
+
     requires: ['Ext.direct.Manager'],
+
     
-    
-   
+
     status: true,
+
     
     constructor: function(config) {
         Ext.apply(this, config);
     },
-    
+
     
     getData: function(){
         return this.data;
@@ -53540,36 +55910,36 @@ Ext.define('Ext.direct.ExceptionEvent', {
 
 
 Ext.define('Ext.direct.Provider', {
+
     
-    
-   
+
    alias: 'direct.provider',
-   
+
     mixins: {
-        observable: 'Ext.util.Observable'   
+        observable: 'Ext.util.Observable'
     },
-   
+
     
+
    
-   
-    
+
     constructor : function(config){
         var me = this;
-        
+
         Ext.apply(me, config);
         me.addEvents(
-                        
+            
             'connect',
-                        
+            
             'disconnect',
-                        
+            
             'data',
-                                    
+            
             'exception'
         );
         me.mixins.observable.constructor.call(me, config);
     },
-    
+
     
     isConnected: function(){
         return false;
@@ -53577,7 +55947,7 @@ Ext.define('Ext.direct.Provider', {
 
     
     connect: Ext.emptyFn,
-    
+
     
     disconnect: Ext.emptyFn
 });
@@ -53585,17 +55955,17 @@ Ext.define('Ext.direct.Provider', {
 
 
 Ext.define('Ext.direct.JsonProvider', {
+
     
-    
-    
+
     extend: 'Ext.direct.Provider',
-    
+
     alias: 'direct.jsonprovider',
-    
+
     uses: ['Ext.direct.ExceptionEvent'],
+
     
-    
-   
+
    
    parseResponse: function(response){
         if (!Ext.isEmpty(response.responseText)) {
@@ -53614,7 +55984,7 @@ Ext.define('Ext.direct.JsonProvider', {
             event,
             i = 0,
             len;
-            
+
         try{
             data = this.parseResponse(response);
         } catch(e) {
@@ -53626,7 +55996,7 @@ Ext.define('Ext.direct.JsonProvider', {
             });
             return [event];
         }
-        
+
         if (Ext.isArray(data)) {
             for (len = data.length; i < len; ++i) {
                 events.push(this.createEvent(data[i]));
@@ -53636,7 +56006,7 @@ Ext.define('Ext.direct.JsonProvider', {
         }
         return events;
     },
-    
+
     
     createEvent: function(response){
         return Ext.create('direct.' + response.type, response);
@@ -53705,7 +56075,6 @@ Ext.define('Ext.direct.PollingProvider', {
             });
             me.fireEvent('connect', me);
         } else if (!url) {
-            Ext.Error.raise('Error initializing PollingProvider, no url configured.');
         }
     },
 
@@ -53744,12 +56113,12 @@ Ext.define('Ext.direct.PollingProvider', {
 });
 
 Ext.define('Ext.direct.RemotingMethod', {
-    
+
     constructor: function(config){
         var me = this,
             params = Ext.isDefined(config.params) ? config.params : config.len,
             name;
-            
+
         me.name = config.name;
         me.formHandler = config.formHandler;
         if (Ext.isNumber(params)) {
@@ -53765,7 +56134,7 @@ Ext.define('Ext.direct.RemotingMethod', {
             });
         }
     },
-    
+
     
     getCallData: function(args){
         var me = this,
@@ -53775,7 +56144,7 @@ Ext.define('Ext.direct.RemotingMethod', {
             callback,
             scope,
             name;
-            
+
         if (me.ordered) {
             callback = args[len];
             scope = args[len + 1];
@@ -53786,7 +56155,7 @@ Ext.define('Ext.direct.RemotingMethod', {
             data = Ext.apply({}, args[0]);
             callback = args[1];
             scope = args[2];
-            
+
             
             for (name in data) {
                 if (data.hasOwnProperty(name)) {
@@ -53796,11 +56165,11 @@ Ext.define('Ext.direct.RemotingMethod', {
                 }
             }
         }
-        
+
         return {
             data: data,
             callback: callback,
-            scope: scope    
+            scope: scope
         };
     }
 });
@@ -53818,7 +56187,8 @@ Ext.define('Ext.direct.Transaction', {
     },
    
     
-   
+
+    
     constructor: function(config){
         var me = this;
         
@@ -53950,7 +56320,6 @@ Ext.define('Ext.direct.RemotingProvider', {
             me.connected = true;
             me.fireEvent('connect', me);
         } else if(!me.url) {
-            Ext.Error.raise('Error initializing RemotingProvider, no url configured.');
         }
     },
 
@@ -54321,14 +56690,14 @@ Ext.define('Ext.draw.Matrix', {
 
     toFilter: function() {
         var me = this;
-        return "progid:DXImageTransform.Microsoft.Matrix(M11=" + me.get(0, 0) +
+        return "progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand',FilterType=bilinear,M11=" + me.get(0, 0) +
             ", M12=" + me.get(0, 1) + ", M21=" + me.get(1, 0) + ", M22=" + me.get(1, 1) +
             ", Dx=" + me.get(0, 2) + ", Dy=" + me.get(1, 2) + ")";
     },
 
     offset: function() {
         var matrix = this.matrix;
-        return [matrix[0][2].toFixed(4), matrix[1][2].toFixed(4)];
+        return [(matrix[0][2] || 0).toFixed(4), (matrix[1][2] || 0).toFixed(4)];
     },
 
     
@@ -54349,7 +56718,7 @@ Ext.define('Ext.draw.Matrix', {
             row;
 
         
-        row = [[matrix[0][0], matrix[0][1]], [matrix[1][1], matrix[1][1]]];
+        row = [[matrix[0][0], matrix[0][1]], [matrix[1][0], matrix[1][1]]];
         out.scaleX = Math.sqrt(norm(row[0]));
         normalize(row[0]);
 
@@ -54369,6 +56738,7 @@ Ext.define('Ext.draw.Matrix', {
     }
 });
 
+
 Ext.define('Ext.draw.SpriteDD', {
     extend: 'Ext.dd.DragSource',
 
@@ -54398,7 +56768,7 @@ Ext.define('Ext.draw.SpriteDD', {
         bbox = sprite.getBBox();
         
         try {
-            pos = Ext.core.Element.getXY(el);
+            pos = Ext.Element.getXY(el);
         } catch (e) { }
 
         if (!pos) {
@@ -54417,38 +56787,35 @@ Ext.define('Ext.draw.SpriteDD', {
      
     startDrag: function(x, y) {
         var me = this,
-            attr = me.sprite.attr,
-            trans = attr.translation;
-        if (me.sprite.vml) {
-            me.prevX = x + attr.x;
-            me.prevY = y + attr.y;
-        } else {
-            me.prevX = x - trans.x;
-            me.prevY = y - trans.y;
-        }
+            attr = me.sprite.attr;
+        me.prev = me.sprite.surface.transformToViewBox(x, y);
     },
 
     onDrag: function(e) {
         var xy = e.getXY(),
             me = this,
             sprite = me.sprite,
-            attr = sprite.attr;
-        me.translateX = xy[0] - me.prevX;
-        me.translateY = xy[1] - me.prevY;
+            attr = sprite.attr, dx, dy;
+        xy = me.sprite.surface.transformToViewBox(xy[0], xy[1]);
+        dx = xy[0] - me.prev[0];
+        dy = xy[1] - me.prev[1];
         sprite.setAttributes({
             translate: {
-                x: me.translateX,
-                y: me.translateY
+                x: attr.translation.x + dx,
+                y: attr.translation.y + dy
             }
         }, true);
-        if (sprite.vml) {
-            me.prevX = xy[0] + attr.x || 0;
-            me.prevY = xy[1] + attr.y || 0;
-        }
+        me.prev = xy;
+    },
+
+    setDragElPos: function () {
+        
+        return false;
     }
 });
 
 Ext.define('Ext.draw.Sprite', {
+
     
 
     mixins: {
@@ -54460,6 +56827,38 @@ Ext.define('Ext.draw.Sprite', {
 
     
 
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
     dirty: false,
     dirtyHidden: false,
     dirtyTransform: false,
@@ -54538,12 +56937,13 @@ Ext.define('Ext.draw.Sprite', {
     },
 
     
+
     initDraggable: function() {
         var me = this;
         me.draggable = true;
         
         if (!me.el) {
-            me.surface.createSprite(me);
+            me.surface.createSpriteElement(me);
         }
         me.dd = Ext.create('Ext.draw.SpriteDD', me, Ext.isBoolean(me.draggable) ? null : me.draggable);
         me.on('beforedestroy', me.dd.destroy, me.dd);
@@ -54561,6 +56961,7 @@ Ext.define('Ext.draw.Sprite', {
             spriteAttrs = me.attr,
             attr, i, translate, translation, rotate, rotation, scale, scaling;
 
+        attrs = Ext.apply({}, attrs);
         for (attr in custom) {
             if (attrs.hasOwnProperty(attr) && typeof custom[attr] == "function") {
                 Ext.apply(attrs, custom[attr].apply(me, [].concat(attrs[attr])));
@@ -54609,7 +57010,7 @@ Ext.define('Ext.draw.Sprite', {
         rotate = attrs.rotate;
         rotation = spriteAttrs.rotation;
         if (rotate) {
-            if ((rotate.x && rotate.x !== rotation.x) || 
+            if ((rotate.x && rotate.x !== rotation.x) ||
                 (rotate.y && rotate.y !== rotation.y) ||
                 (rotate.degrees && rotate.degrees !== rotation.degrees)) {
                 Ext.apply(rotation, rotate);
@@ -54621,7 +57022,7 @@ Ext.define('Ext.draw.Sprite', {
         scale = attrs.scale;
         scaling = spriteAttrs.scaling;
         if (scale) {
-            if ((scale.x && scale.x !== scaling.x) || 
+            if ((scale.x && scale.x !== scaling.x) ||
                 (scale.y && scale.y !== scaling.y) ||
                 (scale.cx && scale.cx !== scaling.cx) ||
                 (scale.cy && scale.cy !== scaling.cy)) {
@@ -54644,7 +57045,7 @@ Ext.define('Ext.draw.Sprite', {
     getBBox: function() {
         return this.surface.getBBox(this);
     },
-    
+
     setText: function(text) {
         return this.surface.setText(this, text);
     },
@@ -54721,7 +57122,7 @@ Ext.define('Ext.draw.engine.Svg', {
 
     extend: 'Ext.draw.Surface',
 
-    requires: ['Ext.draw.Draw', 'Ext.draw.Sprite', 'Ext.draw.Matrix', 'Ext.core.Element'],
+    requires: ['Ext.draw.Draw', 'Ext.draw.Sprite', 'Ext.draw.Matrix', 'Ext.Element'],
 
     
 
@@ -54741,6 +57142,8 @@ Ext.define('Ext.draw.engine.Svg', {
         strokeOpacity: "stroke-opacity",
         strokeLinejoin: "stroke-linejoin"
     },
+    
+    parsers: {},
 
     minDefaults: {
         circle: {
@@ -55144,6 +57547,12 @@ Ext.define('Ext.draw.engine.Svg', {
             el = sprite.el,
             group = sprite.group,
             sattr = sprite.attr,
+            parsers = me.parsers,
+            
+            
+            
+            gradientsMap = me.gradientsMap || {},
+            safariFix = Ext.isSafari && !Ext.isStrict,
             groups, i, ln, attrs, font, key, style, name, rect;
 
         if (group) {
@@ -55158,8 +57567,8 @@ Ext.define('Ext.draw.engine.Svg', {
         attrs = me.scrubAttrs(sprite) || {};
 
         
-        sprite.bbox.plain = 0;
-        sprite.bbox.transform = 0;
+            sprite.bbox.plain = 0;
+            sprite.bbox.transform = 0;
             if (sprite.type == "circle" || sprite.type == "ellipse") {
                 attrs.cx = attrs.cx || attrs.x;
                 attrs.cy = attrs.cy || attrs.y;
@@ -55168,10 +57577,13 @@ Ext.define('Ext.draw.engine.Svg', {
                 attrs.rx = attrs.ry = attrs.r;
             }
             else if (sprite.type == "path" && attrs.d) {
-                attrs.d = Ext.draw.Draw.pathToAbsolute(attrs.d);
+                attrs.d = Ext.draw.Draw.pathToString(Ext.draw.Draw.pathToAbsolute(attrs.d));
             }
             sprite.dirtyPath = false;
         
+        
+        
+        
 
         if (attrs['clip-rect']) {
             me.setClip(sprite, attrs);
@@ -55192,9 +57604,22 @@ Ext.define('Ext.draw.engine.Svg', {
         }
         for (key in attrs) {
             if (attrs.hasOwnProperty(key) && attrs[key] != null) {
-                el.dom.setAttribute(key, String(attrs[key]));
+                
+                
+                
+                
+                
+                if (safariFix && ('color|stroke|fill'.indexOf(key) > -1) && (attrs[key] in gradientsMap)) {
+                    attrs[key] = gradientsMap[attrs[key]];
+                }
+                if (key in parsers) {
+                    el.dom.setAttribute(key, parsers[key](attrs[key], sprite, me));
+                } else {
+                    el.dom.setAttribute(key, attrs[key]);
+                }
             }
         }
+        
         if (sprite.type == 'text') {
             me.tuneText(sprite, attrs);
         }
@@ -55246,17 +57671,19 @@ Ext.define('Ext.draw.engine.Svg', {
 
     
     applyZIndex: function(sprite) {
-        var idx = this.normalizeSpriteCollection(sprite),
+        var me = this,
+            items = me.items,
+            idx = items.indexOf(sprite),
             el = sprite.el,
             prevEl;
-        if (this.el.dom.childNodes[idx + 2] !== el.dom) { 
+        if (me.el.dom.childNodes[idx + 2] !== el.dom) { 
             if (idx > 0) {
                 
                 do {
-                    prevEl = this.items.getAt(--idx).el;
+                    prevEl = items.getAt(--idx).el;
                 } while (!prevEl && idx > 0);
             }
-            el.insertAfter(prevEl || this.bgRect);
+            el.insertAfter(prevEl || me.bgRect);
         }
         sprite.zIndexDirty = false;
     },
@@ -55269,40 +57696,49 @@ Ext.define('Ext.draw.engine.Svg', {
 
     addGradient: function(gradient) {
         gradient = Ext.draw.Draw.parseGradient(gradient);
-        var ln = gradient.stops.length,
+        var me = this,
+            ln = gradient.stops.length,
             vector = gradient.vector,
-            gradientEl,
-            stop,
-            stopEl,
-            i;
-        if (gradient.type == "linear") {
-            gradientEl = this.createSvgElement("linearGradient");
-            gradientEl.setAttribute("x1", vector[0]);
-            gradientEl.setAttribute("y1", vector[1]);
-            gradientEl.setAttribute("x2", vector[2]);
-            gradientEl.setAttribute("y2", vector[3]);
-        }
-        else {
-            gradientEl = this.createSvgElement("radialGradient");
-            gradientEl.setAttribute("cx", gradient.centerX);
-            gradientEl.setAttribute("cy", gradient.centerY);
-            gradientEl.setAttribute("r", gradient.radius);
-            if (Ext.isNumber(gradient.focalX) && Ext.isNumber(gradient.focalY)) {
-                gradientEl.setAttribute("fx", gradient.focalX);
-                gradientEl.setAttribute("fy", gradient.focalY);
+            
+            
+            
+            usePlain = Ext.isSafari && !Ext.isStrict,
+            gradientEl, stop, stopEl, i, gradientsMap;
+            
+        gradientsMap = me.gradientsMap || {};
+        
+        if (!usePlain) {
+            if (gradient.type == "linear") {
+                gradientEl = me.createSvgElement("linearGradient");
+                gradientEl.setAttribute("x1", vector[0]);
+                gradientEl.setAttribute("y1", vector[1]);
+                gradientEl.setAttribute("x2", vector[2]);
+                gradientEl.setAttribute("y2", vector[3]);
             }
-        }    
-        gradientEl.id = gradient.id;
-        this.getDefs().appendChild(gradientEl);
-
-        for (i = 0; i < ln; i++) {
-            stop = gradient.stops[i];
-            stopEl = this.createSvgElement("stop");
-            stopEl.setAttribute("offset", stop.offset + "%");
-            stopEl.setAttribute("stop-color", stop.color);
-            stopEl.setAttribute("stop-opacity",stop.opacity);
-            gradientEl.appendChild(stopEl);
+            else {
+                gradientEl = me.createSvgElement("radialGradient");
+                gradientEl.setAttribute("cx", gradient.centerX);
+                gradientEl.setAttribute("cy", gradient.centerY);
+                gradientEl.setAttribute("r", gradient.radius);
+                if (Ext.isNumber(gradient.focalX) && Ext.isNumber(gradient.focalY)) {
+                    gradientEl.setAttribute("fx", gradient.focalX);
+                    gradientEl.setAttribute("fy", gradient.focalY);
+                }
+            }
+            gradientEl.id = gradient.id;
+            me.getDefs().appendChild(gradientEl);
+            for (i = 0; i < ln; i++) {
+                stop = gradient.stops[i];
+                stopEl = me.createSvgElement("stop");
+                stopEl.setAttribute("offset", stop.offset + "%");
+                stopEl.setAttribute("stop-color", stop.color);
+                stopEl.setAttribute("stop-opacity",stop.opacity);
+                gradientEl.appendChild(stopEl);
+            }
+        } else {
+            gradientsMap['url(#' + gradient.id + ')'] = gradient.stops[0].color;
         }
+        me.gradientsMap = gradientsMap;
     },
 
     
@@ -55352,7 +57788,7 @@ Ext.define('Ext.draw.engine.Svg', {
                     cls = cls.replace(me.trimRe, '');
                     idx = Ext.Array.indexOf(elClasses, cls);
                     if (idx != -1) {
-                        elClasses.splice(idx, 1);
+                        Ext.Array.erase(elClasses, idx, 1);
                     }
                 }
             }
@@ -55378,7 +57814,7 @@ Ext.define('Ext.draw.engine.Vml', {
 
     extend: 'Ext.draw.Surface',
 
-    requires: ['Ext.draw.Draw', 'Ext.draw.Color', 'Ext.draw.Sprite', 'Ext.draw.Matrix', 'Ext.core.Element'],
+    requires: ['Ext.draw.Draw', 'Ext.draw.Color', 'Ext.draw.Sprite', 'Ext.draw.Matrix', 'Ext.Element'],
 
     
 
@@ -55400,8 +57836,11 @@ Ext.define('Ext.draw.engine.Vml', {
     coordsize: 1000,
     coordorigin: '0 0',
 
-    // @private
-    // Convert an SVG standard path into a VML path
+    // VML uses CSS z-index and therefore doesn't need sprites to be kept in zIndex order
+    orderSpritesByZIndex: false,
+
+    
+    
     path2vml: function (path) {
         var me = this,
             nonVML =  me.NonVmlPathRe,
@@ -55445,7 +57884,7 @@ Ext.define('Ext.draw.engine.Vml', {
         return res.join(" ");
     },
 
-    // @private - set of attributes which need to be translated from the sprite API to the native browser API
+    
     translateAttrs: {
         radius: "r",
         radiusX: "rx",
@@ -55456,7 +57895,7 @@ Ext.define('Ext.draw.engine.Vml', {
         strokeLinejoin: "stroke-linejoin"
     },
 
-    // @private - Minimun set of defaults for different types of sprites.
+    
     minDefaults: {
         circle: {
             fill: "none",
@@ -55523,17 +57962,17 @@ Ext.define('Ext.draw.engine.Vml', {
         }
     },
 
-    // private
+    
     onMouseEnter: function(e) {
         this.fireEvent("mouseenter", e);
     },
 
-    // private
+    
     onMouseLeave: function(e) {
         this.fireEvent("mouseleave", e);
     },
 
-    // @private - Normalize a delegated single event from the main container to each sprite and sprite group
+    
     processEvent: function(name, e) {
         var target = e.getTarget(),
             surface = this.surface,
@@ -55545,7 +57984,7 @@ Ext.define('Ext.draw.engine.Vml', {
         }
     },
 
-    // Create the VML element/elements and append them to the DOM
+    
     createSpriteElement: function(sprite) {
         var me = this,
             attr = sprite.attr,
@@ -55553,7 +57992,7 @@ Ext.define('Ext.draw.engine.Vml', {
             zoom = me.zoom,
             vml = sprite.vml || (sprite.vml = {}),
             round = Math.round,
-            el = (type === 'image') ? me.createNode('image') : me.createNode('shape'),
+            el = me.createNode('shape'),
             path, skew, textPath;
 
         el.coordsize = zoom + ' ' + zoom;
@@ -55585,7 +58024,7 @@ Ext.define('Ext.draw.engine.Vml', {
         return sprite.el;
     },
 
-    // @private - Get bounding box for the sprite.  The Sprite itself has the public method.
+    
     getBBox: function (sprite, isWithoutTransform) {
         var realPath = this["getPath" + sprite.type](sprite);
         if (isWithoutTransform) {
@@ -55630,24 +58069,9 @@ Ext.define('Ext.draw.engine.Vml', {
             me.setZIndex(sprite);
         }
 
-        // Apply minimum default attributes
+        
         Ext.applyIf(scrubbedAttrs, me.minDefaults[sprite.type]);
 
-        if (sprite.type == 'image') {
-            Ext.apply(sprite.attr, {
-                x: scrubbedAttrs.x,
-                y: scrubbedAttrs.y,
-                width: scrubbedAttrs.width,
-                height: scrubbedAttrs.height
-            });
-            bbox = sprite.getBBox();
-            el.setStyle({
-                width: bbox.width + 'px',
-                height: bbox.height + 'px'
-            });
-            dom.src = scrubbedAttrs.src;
-        }
-
         if (dom.href) {
             dom.href = scrubbedAttrs.href;
         }
@@ -55661,13 +58085,13 @@ Ext.define('Ext.draw.engine.Vml', {
             dom.cursor = scrubbedAttrs.cursor;
         }
 
-        // Change visibility
+        
         if (sprite.dirtyHidden) {
             (scrubbedAttrs.hidden) ? me.hidePrim(sprite) : me.showPrim(sprite);
             sprite.dirtyHidden = false;
         }
 
-        // Update path
+        
         if (sprite.dirtyPath) {
             if (sprite.type == "circle" || sprite.type == "ellipse") {
                 var cx = scrubbedAttrs.x,
@@ -55682,34 +58106,34 @@ Ext.define('Ext.draw.engine.Vml', {
                             Math.round(cx * me.zoom));
                 sprite.dirtyPath = false;
             }
-            else if (sprite.type !== "text" && sprite.type !== 'image') {
+            else if (sprite.type !== "text") {
                 sprite.attr.path = scrubbedAttrs.path = me.setPaths(sprite, scrubbedAttrs) || scrubbedAttrs.path;
                 dom.path = me.path2vml(scrubbedAttrs.path);
                 sprite.dirtyPath = false;
             }
         }
 
-        // Apply clipping
+        
         if ("clip-rect" in scrubbedAttrs) {
             me.setClip(sprite, scrubbedAttrs);
         }
 
-        // Handle text (special handling required)
+        
         if (sprite.type == "text") {
             me.setTextAttributes(sprite, scrubbedAttrs);
         }
 
-        // Handle fill and opacity
-        if (scrubbedAttrs.opacity  || scrubbedAttrs['stroke-opacity'] || scrubbedAttrs.fill) {
+        
+        if (sprite.type == 'image' || scrubbedAttrs.opacity  || scrubbedAttrs['fill-opacity'] || scrubbedAttrs.fill) {
             me.setFill(sprite, scrubbedAttrs);
         }
 
-        // Handle stroke (all fills require a stroke element)
+        
         if (scrubbedAttrs.stroke || scrubbedAttrs['stroke-opacity'] || scrubbedAttrs.fill) {
             me.setStroke(sprite, scrubbedAttrs);
         }
         
-        //set styles
+        
         style = spriteAttr.style;
         if (style) {
             el.setStyle(style);
@@ -55727,10 +58151,10 @@ Ext.define('Ext.draw.engine.Vml', {
         }
     },
 
-    // Normalize all virtualized types into paths.
+    
     setPaths: function(sprite, params) {
         var spriteAttr = sprite.attr;
-        // Clear bbox cache
+        
         sprite.bbox.plain = null;
         sprite.bbox.transform = null;
         if (sprite.type == 'circle') {
@@ -55742,7 +58166,7 @@ Ext.define('Ext.draw.engine.Vml', {
             spriteAttr.ry = params.ry;
             return Ext.draw.Draw.ellipsePath(sprite);
         }
-        else if (sprite.type == 'rect') {
+        else if (sprite.type == 'rect' || sprite.type == 'image') {
             spriteAttr.rx = spriteAttr.ry = params.r;
             return Ext.draw.Draw.rectPath(sprite);
         }
@@ -55754,23 +58178,27 @@ Ext.define('Ext.draw.engine.Vml', {
 
     setFill: function(sprite, params) {
         var me = this,
-            el = sprite.el.dom,
-            fillEl = el.fill,
-            newfill = false,
+            el = sprite.el,
+            dom = el.dom,
+            fillEl = dom.getElementsByTagName('fill')[0],
             opacity, gradient, fillUrl, rotation, angle;
 
-        if (!fillEl) {
-            // NOT an expando (but it sure looks like one)...
-            fillEl = el.fill = me.createNode("fill");
-            newfill = true;
+        if (fillEl) {
+            dom.removeChild(fillEl);
+        } else {
+            fillEl = me.createNode('fill');
         }
         if (Ext.isArray(params.fill)) {
             params.fill = params.fill[0];
         }
-        if (params.fill == "none") {
+        if (sprite.type == 'image') {
+            fillEl.on = true;
+            fillEl.src = params.src;
+            fillEl.type = "tile";
+            fillEl.rotate = true;
+        } else if (params.fill == "none") {
             fillEl.on = false;
-        }
-        else {
+        } else {
             if (typeof params.opacity == "number") {
                 fillEl.opacity = params.opacity;
             }
@@ -55782,39 +58210,38 @@ Ext.define('Ext.draw.engine.Vml', {
                 fillUrl = params.fill.match(me.fillUrlRe);
                 if (fillUrl) {
                     fillUrl = fillUrl[1];
-                    // If the URL matches one of the registered gradients, render that gradient
+                    
                     if (fillUrl.charAt(0) == "#") {
                         gradient = me.gradientsColl.getByKey(fillUrl.substring(1));
                     }
                     if (gradient) {
-                        // VML angle is offset and inverted from standard, and must be adjusted to match rotation transform
+                        
                         rotation = params.rotation;
                         angle = -(gradient.angle + 270 + (rotation ? rotation.degrees : 0)) % 360;
-                        // IE will flip the angle at 0 degrees...
+                        
                         if (angle === 0) {
                             angle = 180;
                         }
                         fillEl.angle = angle;
                         fillEl.type = "gradient";
                         fillEl.method = "sigma";
-                        fillEl.colors.value = gradient.colors;
+                        fillEl.colors = gradient.colors;
                     }
-                    // Otherwise treat it as an image
+                    
                     else {
                         fillEl.src = fillUrl;
                         fillEl.type = "tile";
+                        fillEl.rotate = true;
                     }
                 }
                 else {
-                    fillEl.color = Ext.draw.Color.toHex(params.fill);
+                    fillEl.color = Ext.draw.Color.toHex(params.fill) || params.fill;
                     fillEl.src = "";
                     fillEl.type = "solid";
                 }
             }
         }
-        if (newfill) {
-            el.appendChild(fillEl);
-        }
+        dom.appendChild(fillEl);
     },
 
     setStroke: function(sprite, params) {
@@ -55837,7 +58264,7 @@ Ext.define('Ext.draw.engine.Vml', {
         else {
             strokeEl.on = true;
             if (params.stroke && !params.stroke.match(me.fillUrlRe)) {
-                // VML does NOT support a gradient stroke :(
+                
                 strokeEl.color = Ext.draw.Color.toHex(params.stroke);
             }
             strokeEl.joinstyle = params["stroke-linejoin"];
@@ -55845,7 +58272,7 @@ Ext.define('Ext.draw.engine.Vml', {
             strokeEl.miterlimit = params["stroke-miterlimit"] || 8;
             width = parseFloat(params["stroke-width"] || 1) * 0.75;
             opacity = params["stroke-opacity"] || 1;
-            // VML Does not support stroke widths under 1, so we're going to fiddle with stroke-opacity instead.
+            
             if (Ext.isNumber(width) && width < 1) {
                 strokeEl.weight = 1;
                 strokeEl.opacity = opacity * width;
@@ -55961,64 +58388,74 @@ Ext.define('Ext.draw.engine.Vml', {
     },
 
     setSize: function(width, height) {
-        var me = this,
-            viewBox = me.viewBox,
-            scaleX, scaleY, items, i, len;
+        var me = this;
         width = width || me.width;
         height = height || me.height;
         me.width = width;
         me.height = height;
 
-        if (!me.el) {
-            return;
-        }
+        if (me.el) {
+            
+            if (width != undefined) {
+                me.el.setWidth(width);
+            }
+            if (height != undefined) {
+                me.el.setHeight(height);
+            }
 
-        
-        if (width != undefined) {
-            me.el.setWidth(width);
-        }
-        if (height != undefined) {
-            me.el.setHeight(height);
+            
+            me.applyViewBox();
+
+            me.callParent(arguments);
         }
+    },
+
+    setViewBox: function(x, y, width, height) {
+        this.callParent(arguments);
+        this.viewBox = {
+            x: x,
+            y: y,
+            width: width,
+            height: height
+        };
+        this.applyViewBox();
+    },
+
+    
+    applyViewBox: function() {
+        var me = this,
+            viewBox = me.viewBox,
+            width = me.width,
+            height = me.height,
+            viewBoxX, viewBoxY, viewBoxWidth, viewBoxHeight,
+            relativeHeight, relativeWidth, size;
 
-        
         if (viewBox && (width || height)) {
-            var viewBoxX = viewBox.x,
-                viewBoxY = viewBox.y,
-                viewBoxWidth = viewBox.width,
-                viewBoxHeight = viewBox.height,
-                relativeHeight = height / viewBoxHeight,
-                relativeWidth = width / viewBoxWidth,
-                size;
+            viewBoxX = viewBox.x;
+            viewBoxY = viewBox.y;
+            viewBoxWidth = viewBox.width;
+            viewBoxHeight = viewBox.height;
+            relativeHeight = height / viewBoxHeight;
+            relativeWidth = width / viewBoxWidth;
+
             if (viewBoxWidth * relativeHeight < width) {
                 viewBoxX -= (width - viewBoxWidth * relativeHeight) / 2 / relativeHeight;
             }
             if (viewBoxHeight * relativeWidth < height) {
                 viewBoxY -= (height - viewBoxHeight * relativeWidth) / 2 / relativeWidth;
             }
+
             size = 1 / Math.max(viewBoxWidth / width, viewBoxHeight / height);
-            
+
             me.viewBoxShift = {
                 dx: -viewBoxX,
                 dy: -viewBoxY,
                 scale: size
             };
-            items = me.items.items;
-            for (i = 0, len = items.length; i < len; i++) {
-                me.transform(items[i]);
-            }
+            me.items.each(function(item) {
+                me.transform(item);
+            });
         }
-        this.callParent(arguments);
-    },
-
-    setViewBox: function(x, y, width, height) {
-        this.callParent(arguments);
-        this.viewBox = {
-            x: x,
-            y: y,
-            width: width,
-            height: height
-        };
     },
 
     onAdd: function(item) {
@@ -56036,24 +58473,26 @@ Ext.define('Ext.draw.engine.Vml', {
         this.callParent(arguments);
     },
 
+    
+    createNode : (function () {
+        try {
+            var doc = Ext.getDoc().dom;
+            if (!doc.namespaces.rvml) {
+                doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");
+            }
+            return function (tagName) {
+                return doc.createElement("<rvml:" + tagName + ' class="rvml">');
+            };
+        } catch (e) {
+            return function (tagName) {
+                return doc.createElement("<" + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');
+            };
+        }
+    })(),
+
     render: function (container) {
         var me = this,
             doc = Ext.getDoc().dom;
-        
-        if (!me.createNode) {
-            try {
-                if (!doc.namespaces.rvml) {
-                    doc.namespaces.add("rvml", "urn:schemas-microsoft-com:vml");
-                }
-                me.createNode = function (tagName) {
-                    return doc.createElement("<rvml:" + tagName + ' class="rvml">');
-                };
-            } catch (e) {
-                me.createNode = function (tagName) {
-                    return doc.createElement("<" + tagName + ' xmlns="urn:schemas-microsoft.com:vml" class="rvml">');
-                };
-            }
-        }
 
         if (!me.el) {
             var el = doc.createElement("div");
@@ -56118,92 +58557,130 @@ Ext.define('Ext.draw.engine.Vml', {
         };
     },
 
-    transform: function(sprite) {
+    extractTransform: function (sprite) {
         var me = this,
-            matrix = Ext.create('Ext.draw.Matrix'),
-            transforms = sprite.transformations,
-            transformsLength = transforms.length,
-            i = 0,
-            deltaDegrees = 0,
-            deltaScaleX = 1,
-            deltaScaleY = 1,
-            flip = "",
-            el = sprite.el,
-            dom = el.dom,
-            domStyle = dom.style,
-            zoom = me.zoom,
-            skew = sprite.skew,
-            deltaX, deltaY, transform, type, compensate, y, fill, newAngle,zoomScaleX, zoomScaleY, newOrigin;
+            matrix = Ext.create('Ext.draw.Matrix'), scale,
+            transformstions, tranformationsLength,
+            transform, i = 0,
+            shift = me.viewBoxShift;
 
-        for (; i < transformsLength; i++) {
-            transform = transforms[i];
-            type = transform.type;
-            if (type == "translate") {
-                matrix.translate(transform.x, transform.y);
-            }
-            else if (type == "rotate") {
-                matrix.rotate(transform.degrees, transform.x, transform.y);
-                deltaDegrees += transform.degrees;
-            }
-            else if (type == "scale") {
-                matrix.scale(transform.x, transform.y, transform.centerX, transform.centerY);
-                deltaScaleX *= transform.x;
-                deltaScaleY *= transform.y;
+        for(transformstions = sprite.transformations, tranformationsLength = transformstions.length;
+            i < tranformationsLength; i ++) {
+            transform = transformstions[i];
+            switch (transform.type) {
+                case 'translate' :
+                    matrix.translate(transform.x, transform.y);
+                    break;
+                case 'rotate':
+                    matrix.rotate(transform.degrees, transform.x, transform.y);
+                    break;
+                case 'scale':
+                    matrix.scale(transform.x || transform.scale, transform.y || transform.scale, transform.centerX, transform.centerY);
+                    break;
             }
         }
 
-        if (me.viewBoxShift) {
-            matrix.scale(me.viewBoxShift.scale, me.viewBoxShift.scale, -1, -1);
-            matrix.add(1, 0, 0, 1, me.viewBoxShift.dx, me.viewBoxShift.dy);
+        if (shift) {
+            matrix.add(1, 0, 0, 1, shift.dx, shift.dy);
+            matrix.prepend(shift.scale, 0, 0, shift.scale, 0, 0);
         }
+        
+        return sprite.matrix = matrix;
+    },
 
-        sprite.matrix = matrix;
+    setSimpleCoords: function(sprite, sx, sy, dx, dy, rotate) {
+        var me = this,
+            matrix = sprite.matrix,
+            dom = sprite.el.dom,
+            style = dom.style,
+            yFlipper = 1,
+            flip = "",
+            fill = dom.getElementsByTagName('fill')[0],
+            kx = me.zoom / sx,
+            ky = me.zoom / sy,
+            rotationCompensation;
+        if (!sx || !sy) {
+            return;
+        }
+        dom.coordsize = Math.abs(kx) + ' ' + Math.abs(ky);
+        style.rotation = rotate * (sx * sy < 0 ? -1 : 1);
+        if (rotate) {
+            rotationCompensation = me.rotationCompensation(rotate, dx, dy);
+            dx = rotationCompensation.x;
+            dy = rotationCompensation.y;
+        }
+        if (sx < 0) {
+            flip += "x"
+        }
+        if (sy < 0) {
+            flip += " y";
+            yFlipper = -1;
+        }
+        style.flip = flip;
+        dom.coordorigin = (dx * -kx) + ' ' + (dy * -ky);
+        if (fill) {
+            dom.removeChild(fill);
+            rotationCompensation = me.rotationCompensation(rotate, matrix.x(sprite.x, sprite.y), matrix.y(sprite.x, sprite.y));
+            fill.position = rotationCompensation.x * yFlipper + ' ' + rotationCompensation.y * yFlipper;
+            fill.size = sprite.width * Math.abs(sx) + ' ' + sprite.height * Math.abs(sy);
+            dom.appendChild(fill);
+        }
+    },
+
+    transform : function (sprite) {
+        var me = this,
+            el = sprite.el,
+            skew = sprite.skew,
+            dom = el.dom,
+            domStyle = dom.style,
+            matrix = me.extractTransform(sprite).clone(),
+            split, zoom = me.zoom,
+            fill = dom.getElementsByTagName('fill')[0],
+            isPatt = !String(sprite.fill).indexOf("url("),
+            offset, c;
 
 
         
 
-        if (sprite.type != "image" && skew) {
+        if (sprite.type != "image" && skew && !isPatt) {
             
             skew.matrix = matrix.toString();
-            skew.offset = matrix.offset();
-        }
-        else {
-            deltaX = matrix.matrix[0][2];
-            deltaY = matrix.matrix[1][2];
             
-            zoomScaleX = zoom / deltaScaleX;
-            zoomScaleY = zoom / deltaScaleY;
-
-            dom.coordsize = Math.abs(zoomScaleX) + " " + Math.abs(zoomScaleY);
-
             
-            newAngle = deltaDegrees * (deltaScaleX * ((deltaScaleY < 0) ? -1 : 1));
-            if (newAngle != domStyle.rotation && !(newAngle === 0 && !domStyle.rotation)) {
-                domStyle.rotation = newAngle;
-            }
-            if (deltaDegrees) {
-                
-                compensate = me.rotationCompensation(deltaDegrees, deltaX, deltaY);
-                deltaX = compensate.x;
-                deltaY = compensate.y;
-            }
-
             
-            if (deltaScaleX < 0) {
-                flip += "x";
-            }
-            if (deltaScaleY < 0) {
-                flip += " y";
-                y = -1;
+            offset = matrix.offset();
+            if (offset[0] > 32767) {
+                offset[0] = 32767;
+            } else if (offset[0] < -32768) {
+                offset[0] = -32768
             }
-            if (flip != "" && !dom.style.flip) {
-                domStyle.flip = flip;
+            if (offset[1] > 32767) {
+                offset[1] = 32767;
+            } else if (offset[1] < -32768) {
+                offset[1] = -32768
             }
-
-            
-            newOrigin = (deltaX * -zoomScaleX) + " " + (deltaY * -zoomScaleY);
-            if (newOrigin != dom.coordorigin) {
-                dom.coordorigin = (deltaX * -zoomScaleX) + " " + (deltaY * -zoomScaleY);
+            skew.offset = offset;
+        } else {
+            if (skew) {
+                skew.matrix = "1 0 0 1";
+                skew.offset = "0 0";
+            }
+            split = matrix.split();
+            if (split.isSimple) {
+                domStyle.filter = '';
+                me.setSimpleCoords(sprite, split.scaleX, split.scaleY, split.translateX, split.translateY, split.rotate / Math.PI * 180);
+            } else {
+                domStyle.filter = matrix.toFilter();
+                var bb = me.getBBox(sprite),
+                    dx = bb.x - sprite.x,
+                    dy = bb.y - sprite.y;
+                dom.coordorigin = (dx * -zoom) + ' ' + (dy * -zoom);
+                if (fill) {
+                    dom.removeChild(fill);
+                    fill.position = dx + ' ' + dy;
+                    fill.size = sprite.width * sprite.scale.x + ' ' + sprite.height * 1.1;
+                    dom.appendChild(fill);
+                }
             }
         }
     },
@@ -56368,16 +58845,39 @@ Ext.define('Ext.layout.container.Fit', {
     extend: 'Ext.layout.container.AbstractFit',
     alias: 'layout.fit',
     alternateClassName: 'Ext.layout.FitLayout',
+    requires: ['Ext.layout.container.Box'],
 
     
-   
+
+    
+    defaultMargins: {
+        top: 0,
+        right: 0,
+        bottom: 0,
+        left: 0
+    },
+
     
     onLayout : function() {
-        var me = this;
+        var me = this,
+            size,
+            item,
+            margins;
         me.callParent();
 
         if (me.owner.items.length) {
-            me.setItemBox(me.owner.items.get(0), me.getLayoutTargetSize());
+            item = me.owner.items.get(0);
+            margins = item.margins || me.defaultMargins;
+            size = me.getLayoutTargetSize();
+            size.width  -= margins.width;
+            size.height -= margins.height;
+            me.setItemBox(item, size);
+
+            
+            
+            if (margins.left || margins.top) {
+                item.setPosition(margins.left, margins.top);
+            }
         }
     },
 
@@ -56388,18 +58888,31 @@ Ext.define('Ext.layout.container.Fit', {
     setItemBox : function(item, box) {
         var me = this;
         if (item && box.height > 0) {
-            if (me.isManaged('width') === true) {
+            if (!me.owner.isFixedWidth()) {
                box.width = undefined;
             }
-            if (me.isManaged('height') === true) {
+            if (!me.owner.isFixedHeight()) {
                box.height = undefined;
             }
             me.setItemSize(item, box.width, box.height);
         }
+    },
+
+    configureItem: function(item) {
+
+        
+        
+        item.layoutManagedHeight = 0;
+        item.layoutManagedWidth = 0;
+
+        this.callParent(arguments);
     }
+}, function() {
+    
+    
+    this.prototype.renderItem = Ext.layout.container.Box.prototype.renderItem;
 });
 
-
 Ext.define('Ext.layout.container.AbstractCard', {
 
     
@@ -56419,7 +58932,7 @@ Ext.define('Ext.layout.container.AbstractCard', {
 
     beforeLayout: function() {
         var me = this;
-        me.activeItem = me.getActiveItem();
+        me.getActiveItem();
         if (me.activeItem && me.deferredRender) {
             me.renderItems([me.activeItem], me.getRenderTarget());
             return true;
@@ -56429,6 +58942,13 @@ Ext.define('Ext.layout.container.AbstractCard', {
         }
     },
 
+    renderChildren: function () {
+        if (!this.deferredRender) {
+            this.getActiveItem();
+            this.callParent();
+        }
+    },
+
     onLayout: function() {
         var me = this,
             activeItem = me.activeItem,
@@ -56514,38 +59034,38 @@ Ext.define('Ext.layout.container.AbstractCard', {
     },
 
     
-    getNext: function(wrap) {
-        
+    getNext: function() {
         
         
+        var wrap = arguments[0];
         var items = this.getLayoutItems(),
             index = Ext.Array.indexOf(items, this.activeItem);
         return items[index + 1] || (wrap ? items[0] : false);
     },
 
     
-    next: function(anim, wrap) {
-        
+    next: function() {
         
         
+        var anim = arguments[0], wrap = arguments[1];
         return this.setActiveItem(this.getNext(wrap), anim);
     },
 
     
-    getPrev: function(wrap) {
-        
+    getPrev: function() {
         
         
+        var wrap = arguments[0];
         var items = this.getLayoutItems(),
             index = Ext.Array.indexOf(items, this.activeItem);
         return items[index - 1] || (wrap ? items[items.length - 1] : false);
     },
 
     
-    prev: function(anim, wrap) {
-        
+    prev: function() {
         
         
+        var anim = arguments[0], wrap = arguments[1];
         return this.setActiveItem(this.getPrev(wrap), anim);
     }
 });
@@ -56553,31 +59073,30 @@ Ext.define('Ext.layout.container.AbstractCard', {
 
 Ext.define('Ext.selection.Model', {
     extend: 'Ext.util.Observable',
-    alternateClassName: 'Ext.AbstractStoreSelectionModel',
+    alternateClassName: 'Ext.AbstractSelectionModel',
     requires: ['Ext.data.StoreManager'],
     
 
     
-    
+
     
     allowDeselect: false,
 
     
     selected: null,
-    
-    
+
     
     pruneRemoved: true,
 
     constructor: function(cfg) {
         var me = this;
-        
+
         cfg = cfg || {};
         Ext.apply(me, cfg);
-        
+
         me.addEvents(
             
-             'selectionchange'
+            'selectionchange'
         );
 
         me.modes = {
@@ -56591,17 +59110,17 @@ Ext.define('Ext.selection.Model', {
 
         
         me.selected = Ext.create('Ext.util.MixedCollection');
-        
+
         me.callParent(arguments);
     },
 
     
     bind : function(store, initial){
         var me = this;
-        
+
         if(!initial && me.store){
             if(store !== me.store && me.store.autoDestroy){
-                me.store.destroy();
+                me.store.destroyStore();
             }else{
                 me.store.un("add", me.onStoreAdd, me);
                 me.store.un("clear", me.onStoreClear, me);
@@ -56625,32 +59144,46 @@ Ext.define('Ext.selection.Model', {
         }
     },
 
-    selectAll: function(silent) {
-        var selections = this.store.getRange(),
+    
+    selectAll: function(suppressEvent) {
+        var me = this,
+            selections = me.store.getRange(),
             i = 0,
-            len = selections.length;
-            
+            len = selections.length,
+            start = me.getSelection().length;
+
+        me.bulkChange = true;
         for (; i < len; i++) {
-            this.doSelect(selections[i], true, silent);
+            me.doSelect(selections[i], true, suppressEvent);
         }
+        delete me.bulkChange;
+        
+        me.maybeFireSelectionChange(me.getSelection().length !== start);
     },
 
-    deselectAll: function() {
-        var selections = this.getSelection(),
+    
+    deselectAll: function(suppressEvent) {
+        var me = this,
+            selections = me.getSelection(),
             i = 0,
-            len = selections.length;
-            
+            len = selections.length,
+            start = me.getSelection().length;
+
+        me.bulkChange = true;
         for (; i < len; i++) {
-            this.doDeselect(selections[i]);
+            me.doDeselect(selections[i], suppressEvent);
         }
+        delete me.bulkChange;
+        
+        me.maybeFireSelectionChange(me.getSelection().length !== start);
     },
 
     
     
     
-    selectWithEvent: function(record, e) {
+    selectWithEvent: function(record, e, keepExisting) {
         var me = this;
-        
+
         switch (me.selectionMode) {
             case 'MULTI':
                 if (e.ctrlKey && me.isSelected(record)) {
@@ -56660,7 +59193,7 @@ Ext.define('Ext.selection.Model', {
                 } else if (e.ctrlKey) {
                     me.doSelect(record, true, false);
                 } else if (me.isSelected(record) && !e.shiftKey && !e.ctrlKey && me.selected.getCount() > 1) {
-                    me.doSelect(record, false, false);
+                    me.doSelect(record, keepExisting, false);
                 } else {
                     me.doSelect(record, false);
                 }
@@ -56693,22 +59226,22 @@ Ext.define('Ext.selection.Model', {
             tmp,
             dontDeselect,
             records = [];
-        
+
         if (me.isLocked()){
             return;
         }
-        
+
         if (!keepExisting) {
-            me.clearSelections();
+            me.deselectAll(true);
         }
-        
+
         if (!Ext.isNumber(startRow)) {
             startRow = store.indexOf(startRow);
-        } 
+        }
         if (!Ext.isNumber(endRow)) {
             endRow = store.indexOf(endRow);
         }
-        
+
         
         if (startRow > endRow){
             tmp = endRow;
@@ -56727,7 +59260,7 @@ Ext.define('Ext.selection.Model', {
         } else {
             dontDeselect = (dir == 'up') ? startRow : endRow;
         }
-        
+
         for (i = startRow; i <= endRow; i++){
             if (selectedCount == (endRow - startRow + 1)) {
                 if (i != dontDeselect) {
@@ -56739,21 +59272,24 @@ Ext.define('Ext.selection.Model', {
         }
         me.doMultiSelect(records, true);
     },
-    
+
     
     select: function(records, keepExisting, suppressEvent) {
-        this.doSelect(records, keepExisting, suppressEvent);
+        
+        if (Ext.isDefined(records)) {
+            this.doSelect(records, keepExisting, suppressEvent);
+        }
     },
 
     
     deselect: function(records, suppressEvent) {
         this.doDeselect(records, suppressEvent);
     },
-    
+
     doSelect: function(records, keepExisting, suppressEvent) {
         var me = this,
             record;
-            
+
         if (me.locked) {
             return;
         }
@@ -56774,17 +59310,24 @@ Ext.define('Ext.selection.Model', {
             change = false,
             i = 0,
             len, record;
-            
+
         if (me.locked) {
             return;
         }
-        
+
 
         records = !Ext.isArray(records) ? [records] : records;
         len = records.length;
         if (!keepExisting && selected.getCount() > 0) {
+            if (me.doDeselect(me.getSelection(), suppressEvent) === false) {
+                return;
+            }
+            
+        }
+
+        function commit () {
+            selected.add(record);
             change = true;
-            me.doDeselect(me.getSelection(), true);
         }
 
         for (; i < len; i++) {
@@ -56792,11 +59335,9 @@ Ext.define('Ext.selection.Model', {
             if (keepExisting && me.isSelected(record)) {
                 continue;
             }
-            change = true;
             me.lastSelected = record;
-            selected.add(record);
 
-            me.onSelectChange(record, true, suppressEvent);
+            me.onSelectChange(record, true, suppressEvent, commit);
         }
         me.setLastFocused(record, suppressEvent);
         
@@ -56807,38 +59348,49 @@ Ext.define('Ext.selection.Model', {
     doDeselect: function(records, suppressEvent) {
         var me = this,
             selected = me.selected,
-            change = false,
             i = 0,
-            len, record;
-            
+            len, record,
+            attempted = 0,
+            accepted = 0;
+
         if (me.locked) {
-            return;
+            return false;
         }
 
         if (typeof records === "number") {
             records = [me.store.getAt(records)];
+        } else if (!Ext.isArray(records)) {
+            records = [records];
+        }
+
+        function commit () {
+            ++accepted;
+            selected.remove(record);
         }
 
-        records = !Ext.isArray(records) ? [records] : records;
         len = records.length;
+
         for (; i < len; i++) {
             record = records[i];
-            if (selected.remove(record)) {
+            if (me.isSelected(record)) {
                 if (me.lastSelected == record) {
                     me.lastSelected = selected.last();
                 }
-                me.onSelectChange(record, false, suppressEvent);
-                change = true;
+                ++attempted;
+                me.onSelectChange(record, false, suppressEvent, commit);
             }
         }
+
         
-        me.maybeFireSelectionChange(change && !suppressEvent);
+        me.maybeFireSelectionChange(accepted > 0 && !suppressEvent);
+        return accepted === attempted;
     },
 
     doSingleSelect: function(record, suppressEvent) {
         var me = this,
+            changed = false,
             selected = me.selected;
-            
+
         if (me.locked) {
             return;
         }
@@ -56847,16 +59399,28 @@ Ext.define('Ext.selection.Model', {
         if (me.isSelected(record)) {
             return;
         }
-        if (selected.getCount() > 0) {
-            me.doDeselect(me.lastSelected, suppressEvent);
+
+        function commit () {
+            me.bulkChange = true;
+            if (selected.getCount() > 0 && me.doDeselect(me.lastSelected, suppressEvent) === false) {
+                delete me.bulkChange;
+                return false;
+            }
+            delete me.bulkChange;
+
+            selected.add(record);
+            me.lastSelected = record;
+            changed = true;
         }
-        selected.add(record);
-        me.lastSelected = record;
-        me.onSelectChange(record, true, suppressEvent);
-        if (!suppressEvent) {
-            me.setLastFocused(record);
+
+        me.onSelectChange(record, true, suppressEvent, commit);
+
+        if (changed) {
+            if (!suppressEvent) {
+                me.setLastFocused(record);
+            }
+            me.maybeFireSelectionChange(!suppressEvent);
         }
-        me.maybeFireSelectionChange(!suppressEvent);
     },
 
     
@@ -56866,7 +59430,7 @@ Ext.define('Ext.selection.Model', {
         me.lastFocused = record;
         me.onLastFocusChanged(recordBeforeLast, record, supressFocus);
     },
-    
+
     
     isFocused: function(record) {
         return record === this.getLastFocused();
@@ -56876,8 +59440,8 @@ Ext.define('Ext.selection.Model', {
     
     
     maybeFireSelectionChange: function(fireEvent) {
-        if (fireEvent) {
-            var me = this;
+        var me = this;
+        if (fireEvent && !me.bulkChange) {
             me.fireEvent('selectionchange', me, me.getSelection());
         }
     },
@@ -56886,7 +59450,7 @@ Ext.define('Ext.selection.Model', {
     getLastSelected: function() {
         return this.lastSelected;
     },
-    
+
     getLastFocused: function() {
         return this.lastFocused;
     },
@@ -56924,7 +59488,7 @@ Ext.define('Ext.selection.Model', {
         record = Ext.isNumber(record) ? this.store.getAt(record) : record;
         return this.selected.indexOf(record) !== -1;
     },
-    
+
     
     hasSelection: function() {
         return this.selected.getCount() > 0;
@@ -56957,7 +59521,7 @@ Ext.define('Ext.selection.Model', {
         }
 
         me.clearSelections();
-        
+
         if (me.store.indexOf(lastFocused) !== -1) {
             
             this.setLastFocused(lastFocused, true);
@@ -56967,16 +59531,16 @@ Ext.define('Ext.selection.Model', {
             
             me.doSelect(toBeSelected, false, true);
         }
-        
+
         me.maybeFireSelectionChange(change);
     },
 
+    
     clearSelections: function() {
         
-        var me = this;
-        me.selected.clear();
-        me.lastSelected = null;
-        me.setLastFocused(null);
+        this.selected.clear();
+        this.lastSelected = null;
+        this.setLastFocused(null);
     },
 
     
@@ -56987,14 +59551,9 @@ Ext.define('Ext.selection.Model', {
     
     
     onStoreClear: function() {
-        var me = this,
-            selected = this.selected;
-            
-        if (selected.getCount > 0) {
-            selected.clear();
-            me.lastSelected = null;
-            me.setLastFocused(null);
-            me.maybeFireSelectionChange(true);
+        if (this.selected.getCount > 0) {
+            this.clearSelections();
+            this.maybeFireSelectionChange(true);
         }
     },
 
@@ -57004,7 +59563,7 @@ Ext.define('Ext.selection.Model', {
     onStoreRemove: function(store, record) {
         var me = this,
             selected = me.selected;
-            
+
         if (me.locked || !me.pruneRemoved) {
             return;
         }
@@ -57020,6 +59579,7 @@ Ext.define('Ext.selection.Model', {
         }
     },
 
+    
     getCount: function() {
         return this.selected.getCount();
     },
@@ -57057,25 +59617,31 @@ Ext.define('Ext.selection.Model', {
 
 Ext.define('Ext.selection.DataViewModel', {
     extend: 'Ext.selection.Model',
-    
+
     requires: ['Ext.util.KeyNav'],
 
     deselectOnContainerClick: true,
-    
+
     
     enableKeyNav: true,
-    
+
     constructor: function(cfg){
         this.addEvents(
             
-            'deselect',
+            'beforedeselect',
+
             
+            'beforeselect',
+
+            
+            'deselect',
+
             
             'select'
         );
         this.callParent(arguments);
     },
-    
+
     bindComponent: function(view) {
         var me = this,
             eventListeners = {
@@ -57105,15 +59671,15 @@ Ext.define('Ext.selection.DataViewModel', {
             this.deselectAll();
         }
     },
-    
+
     initKeyNav: function(view) {
         var me = this;
-        
+
         if (!view.rendered) {
             view.on('render', Ext.Function.bind(me.initKeyNav, me, [view], 0), me, {single: true});
             return;
         }
-        
+
         view.el.set({
             tabIndex: -1
         });
@@ -57125,7 +59691,7 @@ Ext.define('Ext.selection.DataViewModel', {
             scope: me
         });
     },
-    
+
     onNavKey: function(step) {
         step = step || 1;
         var me = this,
@@ -57133,44 +59699,46 @@ Ext.define('Ext.selection.DataViewModel', {
             selected = me.getSelection()[0],
             numRecords = me.view.store.getCount(),
             idx;
-                
+
         if (selected) {
             idx = view.indexOf(view.getNode(selected)) + step;
         } else {
             idx = 0;
         }
-        
+
         if (idx < 0) {
             idx = numRecords - 1;
         } else if (idx >= numRecords) {
             idx = 0;
         }
-        
+
         me.select(idx);
     },
 
     
-    onSelectChange: function(record, isSelected, suppressEvent) {
+    onSelectChange: function(record, isSelected, suppressEvent, commitFn) {
         var me = this,
             view = me.view,
-            allowSelect = true;
-        
-        if (isSelected) {
-            if (!suppressEvent) {
-                allowSelect = me.fireEvent('beforeselect', me, record) !== false;
-            }
-            if (allowSelect) {
+            eventName = isSelected ? 'select' : 'deselect';
+
+        if ((suppressEvent || me.fireEvent('before' + eventName, me, record)) !== false &&
+                commitFn() !== false) {
+
+            if (isSelected) {
                 view.onItemSelect(record);
-                if (!suppressEvent) {
-                    me.fireEvent('select', me, record);
-                }
+            } else {
+                view.onItemDeselect(record);
             }
-        } else {
-            view.onItemDeselect(record);
+
             if (!suppressEvent) {
-                me.fireEvent('deselect', me, record);
+                me.fireEvent(eventName, me, record);
             }
         }
+    },
+    
+    destroy: function(){
+        Ext.destroy(this.keyNav);
+        this.callParent();
     }
 });
 
@@ -57178,6 +59746,15 @@ Ext.define('Ext.selection.DataViewModel', {
 Ext.define('Ext.state.CookieProvider', {
     extend: 'Ext.state.Provider',
 
+    
+
+    
+
+    
+
+    
+
+    
     constructor : function(config){
         var me = this;
         me.path = "/";
@@ -57187,11 +59764,11 @@ Ext.define('Ext.state.CookieProvider', {
         me.callParent(arguments);
         me.state = me.readCookies();
     },
-    
+
     
     set : function(name, value){
         var me = this;
-        
+
         if(typeof value == "undefined" || value === null){
             me.clear(name);
             return;
@@ -57216,7 +59793,7 @@ Ext.define('Ext.state.CookieProvider', {
             matches,
             name,
             value;
-            
+
         while((matches = re.exec(c)) != null){
             name = matches[1];
             value = matches[2];
@@ -57230,7 +59807,7 @@ Ext.define('Ext.state.CookieProvider', {
     
     setCookie : function(name, value){
         var me = this;
-        
+
         document.cookie = me.prefix + name + "=" + me.encodeValue(value) +
            ((me.expires == null) ? "" : ("; expires=" + me.expires.toGMTString())) +
            ((me.path == null) ? "" : ("; path=" + me.path)) +
@@ -57241,7 +59818,7 @@ Ext.define('Ext.state.CookieProvider', {
     
     clearCookie : function(name){
         var me = this;
-        
+
         document.cookie = me.prefix + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" +
            ((me.path == null) ? "" : ("; path=" + me.path)) +
            ((me.domain == null) ? "" : ("; domain=" + me.domain)) +
@@ -57249,6 +59826,8 @@ Ext.define('Ext.state.CookieProvider', {
     }
 });
 
+
+
 Ext.define('Ext.state.LocalStorageProvider', {
     
     
@@ -57309,12 +59888,10 @@ Ext.define('Ext.state.LocalStorageProvider', {
         } catch (e) {
             return false;
         }
-        Ext.Error.raise('LocalStorage is not supported by the current browser');
     }    
 });
 
 
-
 Ext.define('Ext.util.Point', {
 
     
@@ -57331,6 +59908,7 @@ Ext.define('Ext.util.Point', {
 
     
 
+    
     constructor: function(x, y) {
         this.callParent([y, x, y, x]);
     },
@@ -57368,6 +59946,196 @@ Ext.define('Ext.util.Point', {
 });
 
 
+
+Ext.define('Ext.LoadMask', {
+
+    extend: 'Ext.Component',
+
+    alias: 'widget.loadmask',
+
+    
+
+    mixins: {
+        floating: 'Ext.util.Floating'
+    },
+
+    uses: ['Ext.data.StoreManager'],
+
+    
+
+    
+
+    
+    msg : 'Loading...',
+    
+    msgCls : Ext.baseCSSPrefix + 'mask-loading',
+    
+    
+    useMsg: true,
+
+    
+    disabled: false,
+
+    baseCls: Ext.baseCSSPrefix + 'mask-msg',
+
+    renderTpl: '<div style="position:relative" class="{msgCls}"></div>',
+
+    
+    modal: true,
+
+    
+    floating: {
+        shadow: 'frame'
+    },
+
+    
+    focusOnToFront: false,
+
+    
+    constructor : function(el, config) {
+        var me = this;
+
+        
+        if (el.isComponent) {
+            me.ownerCt = el;
+            me.bindComponent(el);
+        }
+        
+        else {
+            me.ownerCt = new Ext.Component({
+                el: Ext.get(el),
+                rendered: true,
+                componentLayoutCounter: 1
+            });
+            me.container = el;
+        }
+        me.callParent([config]);
+
+        if (me.store) {
+            me.bindStore(me.store, true);
+        }
+        me.renderData = {
+            msgCls: me.msgCls
+        };
+        me.renderSelectors = {
+            msgEl: 'div'
+        };
+    },
+
+    bindComponent: function(comp) {
+        this.mon(comp, {
+            resize: this.onComponentResize,
+            scope: this
+        });
+    },
+
+    afterRender: function() {
+        this.callParent(arguments);
+        this.container = this.floatParent.getContentTarget();
+    },
+
+    
+    onComponentResize: function() {
+        var me = this;
+        if (me.rendered && me.isVisible()) {
+            me.toFront();
+            me.center();
+        }
+    },
+
+    
+    bindStore : function(store, initial) {
+        var me = this;
+
+        if (!initial && me.store) {
+            me.mun(me.store, {
+                scope: me,
+                beforeload: me.onBeforeLoad,
+                load: me.onLoad,
+                exception: me.onLoad
+            });
+            if (!store) {
+                me.store = null;
+            }
+        }
+        if (store) {
+            store = Ext.data.StoreManager.lookup(store);
+            me.mon(store, {
+                scope: me,
+                beforeload: me.onBeforeLoad,
+                load: me.onLoad,
+                exception: me.onLoad
+            });
+
+        }
+        me.store = store;
+        if (store && store.isLoading()) {
+            me.onBeforeLoad();
+        }
+    },
+
+    onDisable : function() {
+        this.callParent(arguments);
+        if (this.loading) {
+            this.onLoad();
+        }
+    },
+
+    
+    onBeforeLoad : function() {
+        var me = this,
+            owner = me.ownerCt || me.floatParent,
+            origin;
+        if (!this.disabled) {
+            
+            
+            if (owner.componentLayoutCounter) {
+                Ext.Component.prototype.show.call(me);
+            } else {
+                
+                origin = owner.afterComponentLayout;
+                owner.afterComponentLayout = function() {
+                    owner.afterComponentLayout = origin;
+                    origin.apply(owner, arguments);
+                    if(me.loading) {
+                        Ext.Component.prototype.show.call(me);
+                    }
+                };
+            }
+        }
+    },
+
+    onHide: function(){
+        var me = this;
+        me.callParent(arguments);
+        me.showOnParentShow = true;
+    },
+
+    onShow: function() {
+        var me = this,
+            msgEl = me.msgEl;
+            
+        me.callParent(arguments);
+        me.loading = true;
+        if (me.useMsg) {
+            msgEl.show().update(me.msg);
+        } else {
+            msgEl.parent().hide();
+        }
+    },
+
+    afterShow: function() {
+        this.callParent(arguments);
+        this.center();
+    },
+
+    
+    onLoad : function() {
+        this.loading = false;
+        Ext.Component.prototype.hide.call(this);
+    }
+});
+
 Ext.define('Ext.view.AbstractView', {
     extend: 'Ext.Component',
     alternateClassName: 'Ext.view.AbstractView',
@@ -57378,37 +60146,43 @@ Ext.define('Ext.view.AbstractView', {
         'Ext.DomQuery',
         'Ext.selection.DataViewModel'
     ],
-    
+
     inheritableStatics: {
         getRecord: function(node) {
             return this.getBoundView(node).getRecord(node);
         },
-        
+
         getBoundView: function(node) {
             return Ext.getCmp(node.boundView);
         }
     },
-    
+
     
     
 
     
+    deferInitialRefresh: true,
+
     
+
     
     itemCls: Ext.baseCSSPrefix + 'dataview-item',
-    
+
     
 
     
 
     
     loadingText: 'Loading...',
+
     
+    loadMask: true,
+
     
-    
+
     
     loadingUseMsg: true,
-    
+
 
     
 
@@ -57432,12 +60206,12 @@ Ext.define('Ext.view.AbstractView', {
 
     
     last: false,
-    
+
     triggerEvent: 'itemclick',
     triggerCtEvent: 'containerclick',
-    
+
     addCmpEvents: function() {
-        
+
     },
 
     
@@ -57446,7 +60220,7 @@ Ext.define('Ext.view.AbstractView', {
             isDef = Ext.isDefined,
             itemTpl = me.itemTpl,
             memberFn = {};
-            
+
         if (itemTpl) {
             if (Ext.isArray(itemTpl)) {
                 
@@ -57456,59 +60230,30 @@ Ext.define('Ext.view.AbstractView', {
                 memberFn = Ext.apply(memberFn, itemTpl.initialConfig);
                 itemTpl = itemTpl.html;
             }
-            
+
             if (!me.itemSelector) {
                 me.itemSelector = '.' + me.itemCls;
             }
-            
+
             itemTpl = Ext.String.format('<tpl for="."><div class="{0}">{1}</div></tpl>', me.itemCls, itemTpl);
             me.tpl = Ext.create('Ext.XTemplate', itemTpl, memberFn);
         }
 
-        if (!isDef(me.tpl) || !isDef(me.itemSelector)) {
-            Ext.Error.raise({
-                sourceClass: 'Ext.view.View',
-                tpl: me.tpl,
-                itemSelector: me.itemSelector,
-                msg: "DataView requires both tpl and itemSelector configurations to be defined."
-            });
-        }
 
         me.callParent();
         if(Ext.isString(me.tpl) || Ext.isArray(me.tpl)){
             me.tpl = Ext.create('Ext.XTemplate', me.tpl);
         }
 
-        
-        
-        if (isDef(me.overCls) || isDef(me.overClass)) {
-            if (Ext.isDefined(Ext.global.console)) {
-                Ext.global.console.warn('Ext.view.View: Using the deprecated overCls or overClass configuration. Use overItemCls instead.');
-            }
-            me.overItemCls = me.overCls || me.overClass;
-            delete me.overCls;
-            delete me.overClass;
-        }
 
-        if (me.overItemCls) {
-            me.trackOver = true;
-        }
-        
-        if (isDef(me.selectedCls) || isDef(me.selectedClass)) {
-            if (Ext.isDefined(Ext.global.console)) {
-                Ext.global.console.warn('Ext.view.View: Using the deprecated selectedCls or selectedClass configuration. Use selectedItemCls instead.');
-            }
-            me.selectedItemCls = me.selectedCls || me.selectedClass;
-            delete me.selectedCls;
-            delete me.selectedClass;
-        }
-        
         me.addEvents(
             
             'beforerefresh',
             
             'refresh',
             
+            'viewready',
+            
             'itemupdate',
             
             'itemadd',
@@ -57518,49 +60263,67 @@ Ext.define('Ext.view.AbstractView', {
 
         me.addCmpEvents();
 
-        if (me.store) {
-            me.store = Ext.data.StoreManager.lookup(me.store);
-        }
+        
+        me.store = Ext.data.StoreManager.lookup(me.store || 'ext-empty-store');
         me.all = new Ext.CompositeElementLite();
-        me.getSelectionModel().bindComponent(me);
     },
 
     onRender: function() {
         var me = this,
-            loadingText = me.loadingText,
-            loadingHeight = me.loadingHeight,
-            undef;
+            mask = me.loadMask,
+            cfg = {
+                msg: me.loadingText,
+                msgCls: me.loadingCls,
+                useMsg: me.loadingUseMsg
+            };
 
         me.callParent(arguments);
-        if (loadingText) {
+
+        if (mask) {
             
+            if (Ext.isObject(mask)) {
+                cfg = Ext.apply(cfg, mask);
+            }
             
             
             
             
-            me.loadMask = Ext.create('Ext.LoadMask', me.floating ? me : me.ownerCt || me, {
-                msg: loadingText,
-                msgCls: me.loadingCls,
-                useMsg: me.loadingUseMsg,
-                listeners: {
-                    beforeshow: function() {
-                        me.getTargetEl().update('');
-                        me.getSelectionModel().deselectAll();
-                        me.all.clear();
-                        if (loadingHeight) {
-                            me.setCalculatedSize(undef, loadingHeight);
-                        }
-                    },
-                    hide: function() {
-                        if (loadingHeight) {
-                            me.setHeight(me.height);
-                        }
-                    }
-                }
+            me.loadMask = Ext.create('Ext.LoadMask', me, cfg);
+            me.loadMask.on({
+                scope: me,
+                beforeshow: me.onMaskBeforeShow,
+                hide: me.onMaskHide
             });
         }
     },
 
+    onMaskBeforeShow: function(){
+        var loadingHeight = this.loadingHeight;
+        
+        this.getSelectionModel().deselectAll();
+        if (loadingHeight) {
+            this.setCalculatedSize(undefined, loadingHeight);
+        }
+    },
+
+    onMaskHide: function(){
+        var me = this;
+        
+        if (!me.destroying && me.loadingHeight) {
+            me.setHeight(me.height);
+        }
+    },
+
+    afterRender: function() {
+        this.callParent(arguments);
+
+        
+        
+        
+        this.getSelectionModel().bindComponent(this);
+    },
+
+    
     getSelectionModel: function(){
         var me = this,
             mode = 'SINGLE';
@@ -57585,7 +60348,9 @@ Ext.define('Ext.view.AbstractView', {
         }
 
         if (!me.selModel.hasRelaySetup) {
-            me.relayEvents(me.selModel, ['selectionchange', 'beforeselect', 'select', 'deselect']);
+            me.relayEvents(me.selModel, [
+                'selectionchange', 'beforeselect', 'beforedeselect', 'select', 'deselect'
+            ]);
             me.selModel.hasRelaySetup = true;
         }
 
@@ -57603,11 +60368,11 @@ Ext.define('Ext.view.AbstractView', {
         var me = this,
             el,
             records;
-            
-        if (!me.rendered) {
+
+        if (!me.rendered || me.isDestroyed) {
             return;
         }
-        
+
         me.fireEvent('beforerefresh', me);
         el = me.getTargetEl();
         records = me.store.getRange();
@@ -57623,30 +60388,40 @@ Ext.define('Ext.view.AbstractView', {
             me.all.fill(Ext.query(me.getItemSelector(), el.dom));
             me.updateIndexes(0);
         }
-        
+
         me.selModel.refresh();
         me.hasSkippedEmptyText = true;
         me.fireEvent('refresh', me);
+
+        
+        
+        if (!me.viewReady) {
+            
+            
+            me.viewReady = true;
+            me.fireEvent('viewready', me);
+        }
     },
 
     
     prepareData: function(data, index, record) {
-        if (record) {    
-            Ext.apply(data, record.getAssociatedData());            
+        if (record) {
+            Ext.apply(data, record.getAssociatedData());
         }
         return data;
     },
-    
+
     
     collectData : function(records, startIndex){
         var r = [],
             i = 0,
-            len = records.length;
+            len = records.length,
+            record;
 
         for(; i < len; i++){
-            r[r.length] = this.prepareData(records[i].data, startIndex + i, records[i]);
+            record = records[i];
+            r[r.length] = this.prepareData(record[record.persistenceProperty], startIndex + i, record);
         }
-
         return r;
     },
 
@@ -57661,20 +60436,19 @@ Ext.define('Ext.view.AbstractView', {
     onUpdate : function(ds, record){
         var me = this,
             index = me.store.indexOf(record),
-            original,
             node;
 
         if (index > -1){
-            original = me.all.elements[index];
             node = me.bufferRender([record], index)[0];
-
-            me.all.replaceElement(index, node, true);
-            me.updateIndexes(index, index);
-
-            
             
-            me.selModel.refresh();
-            me.fireEvent('itemupdate', record, index, node);
+            if (me.getNode(record)) {
+                me.all.replaceElement(index, node, true);
+                me.updateIndexes(index, index);
+                
+                
+                me.selModel.refresh();
+                me.fireEvent('itemupdate', record, index, node);
+            }
         }
 
     },
@@ -57683,12 +60457,12 @@ Ext.define('Ext.view.AbstractView', {
     onAdd : function(ds, records, index) {
         var me = this,
             nodes;
-            
+
         if (me.all.getCount() === 0) {
             me.refresh();
             return;
         }
-        
+
         nodes = me.bufferRender(records, index);
         me.doAdd(nodes, records, index);
 
@@ -57698,21 +60472,21 @@ Ext.define('Ext.view.AbstractView', {
     },
 
     doAdd: function(nodes, records, index) {
-        var n, a = this.all.elements;
-        if (index < this.all.getCount()) {
-            n = this.all.item(index).insertSibling(nodes, 'before', true);
-            a.splice.apply(a, [index, 0].concat(nodes));
-        } 
-        else {
-            n = this.all.last().insertSibling(nodes, 'after', true);
-            a.push.apply(a, nodes);
-        }    
+        var all = this.all;
+
+        if (index < all.getCount()) {
+            all.item(index).insertSibling(nodes, 'before', true);
+        } else {
+            all.last().insertSibling(nodes, 'after', true);
+        }
+
+        Ext.Array.insert(all.elements, index, nodes);
     },
-    
+
     
     onRemove : function(ds, record, index) {
         var me = this;
-        
+
         me.doRemove(record, index);
         me.updateIndexes(index);
         if (me.store.getCount() === 0){
@@ -57720,7 +60494,7 @@ Ext.define('Ext.view.AbstractView', {
         }
         me.fireEvent('itemremove', record, index);
     },
-    
+
     doRemove: function(record, index) {
         this.all.removeElement(index, true);
     },
@@ -57733,10 +60507,12 @@ Ext.define('Ext.view.AbstractView', {
     
     updateIndexes : function(startIndex, endIndex) {
         var ns = this.all.elements,
-            records = this.store.getRange();
+            records = this.store.getRange(),
+            i;
+            
         startIndex = startIndex || 0;
         endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
-        for(var i = startIndex; i <= endIndex; i++){
+        for(i = startIndex; i <= endIndex; i++){
             ns[i].viewIndex = i;
             ns[i].viewRecordId = records[i].internalId;
             if (!ns[i].boundView) {
@@ -57752,12 +60528,13 @@ Ext.define('Ext.view.AbstractView', {
 
     
     bindStore : function(store, initial) {
-        var me = this;
-        
+        var me = this,
+            maskStore;
+
         if (!initial && me.store) {
             if (store !== me.store && me.store.autoDestroy) {
-                me.store.destroy();
-            } 
+                me.store.destroyStore();
+            }
             else {
                 me.mun(me.store, {
                     scope: me,
@@ -57769,7 +60546,8 @@ Ext.define('Ext.view.AbstractView', {
                 });
             }
             if (!store) {
-                if (me.loadMask) {
+                
+                if (me.loadMask && me.loadMask.bindStore) {
                     me.loadMask.bindStore(null);
                 }
                 me.store = null;
@@ -57785,17 +60563,37 @@ Ext.define('Ext.view.AbstractView', {
                 update: me.onUpdate,
                 clear: me.refresh
             });
-            if (me.loadMask) {
-                me.loadMask.bindStore(store);
+            
+            if (me.loadMask && me.loadMask.bindStore) {
+                
+                if (Ext.Array.contains(store.alias, 'store.node')) {
+                    maskStore = this.ownerCt.store;
+                } else {
+                    maskStore = store;
+                }
+                me.loadMask.bindStore(maskStore);
             }
         }
+
+        
         
+        me.viewReady = false;
+
         me.store = store;
         
         me.getSelectionModel().bind(store);
+
         
         if (store) {
-            me.refresh(true);
+            if (initial && me.deferInitialRefresh) {
+                Ext.Function.defer(function () {
+                    if (!me.isDestroyed) {
+                        me.refresh(true);
+                    }
+                }, 1);
+            } else {
+                me.refresh(true);
+            }
         }
     },
 
@@ -57810,7 +60608,7 @@ Ext.define('Ext.view.AbstractView', {
     findItemByChild: function(node){
         return Ext.fly(node).findParent(this.getItemSelector(), this.getTargetEl());
     },
-    
+
     
     findTargetByEvent: function(e) {
         return e.getTarget(this.getItemSelector(), this.getTargetEl());
@@ -57849,7 +60647,7 @@ Ext.define('Ext.view.AbstractView', {
     getRecord: function(node){
         return this.store.data.getByKey(Ext.getDom(node).viewRecordId);
     },
-    
+
 
     
     isSelected : function(node) {
@@ -57857,7 +60655,7 @@ Ext.define('Ext.view.AbstractView', {
         var r = this.getRecord(node);
         return this.selModel.isSelected(r);
     },
-    
+
     
     select: function(records, keepExisting, suppressEvent) {
         this.selModel.select(records, keepExisting, suppressEvent);
@@ -57870,31 +60668,36 @@ Ext.define('Ext.view.AbstractView', {
 
     
     getNode : function(nodeInfo) {
+        if (!this.rendered) {
+            return null;
+        }
         if (Ext.isString(nodeInfo)) {
             return document.getElementById(nodeInfo);
-        } else if (Ext.isNumber(nodeInfo)) {
+        }
+        if (Ext.isNumber(nodeInfo)) {
             return this.all.elements[nodeInfo];
-        } else if (nodeInfo instanceof Ext.data.Model) {
+        }
+        if (nodeInfo instanceof Ext.data.Model) {
             return this.getNodeByRecord(nodeInfo);
         }
-        return nodeInfo;
+        return nodeInfo; 
     },
-    
+
     
     getNodeByRecord: function(record) {
         var ns = this.all.elements,
             ln = ns.length,
             i = 0;
-        
+
         for (; i < ln; i++) {
             if (ns[i].viewRecordId === record.internalId) {
                 return ns[i];
             }
         }
-        
+
         return null;
     },
-    
+
     
     getNodes: function(start, end) {
         var ns = this.all.elements,
@@ -57926,7 +60729,7 @@ Ext.define('Ext.view.AbstractView', {
 
     onDestroy : function() {
         var me = this;
-        
+
         me.all.clear();
         me.callParent();
         me.bindStore(null);
@@ -57936,15 +60739,21 @@ Ext.define('Ext.view.AbstractView', {
     
     onItemSelect: function(record) {
         var node = this.getNode(record);
-        Ext.fly(node).addCls(this.selectedItemCls);
+        
+        if (node) {
+            Ext.fly(node).addCls(this.selectedItemCls);
+        }
     },
 
     
     onItemDeselect: function(record) {
         var node = this.getNode(record);
-        Ext.fly(node).removeCls(this.selectedItemCls);
+        
+        if (node) {
+            Ext.fly(node).removeCls(this.selectedItemCls);
+        }
     },
-    
+
     getItemSelector: function() {
         return this.itemSelector;
     }
@@ -57958,31 +60767,39 @@ Ext.define('Ext.view.AbstractView', {
             
             
             
-            
+
             
             getSelectionCount : function(){
-                console.warn("DataView: getSelectionCount will be removed, please interact with the Ext.selection.DataViewModel");
+                if (Ext.global.console) {
+                    Ext.global.console.warn("DataView: getSelectionCount will be removed, please interact with the Ext.selection.DataViewModel");
+                }
                 return this.selModel.getSelection().length;
             },
-        
+
             
             getSelectedRecords : function(){
-                console.warn("DataView: getSelectedRecords will be removed, please interact with the Ext.selection.DataViewModel");
+                if (Ext.global.console) {
+                    Ext.global.console.warn("DataView: getSelectedRecords will be removed, please interact with the Ext.selection.DataViewModel");
+                }
                 return this.selModel.getSelection();
             },
-    
+
             select: function(records, keepExisting, supressEvents) {
-                console.warn("DataView: select will be removed, please access select through a DataView's SelectionModel, ie: view.getSelectionModel().select()");
+                if (Ext.global.console) {
+                    Ext.global.console.warn("DataView: select will be removed, please access select through a DataView's SelectionModel, ie: view.getSelectionModel().select()");
+                }
                 var sm = this.getSelectionModel();
                 return sm.select.apply(sm, arguments);
             },
-            
+
             clearSelections: function() {
-                console.warn("DataView: clearSelections will be removed, please access deselectAll through DataView's SelectionModel, ie: view.getSelectionModel().deselectAll()");
+                if (Ext.global.console) {
+                    Ext.global.console.warn("DataView: clearSelections will be removed, please access deselectAll through DataView's SelectionModel, ie: view.getSelectionModel().deselectAll()");
+                }
                 var sm = this.getSelectionModel();
                 return sm.deselectAll();
             }
-        });    
+        });
     });
 });
 
@@ -58001,6 +60818,7 @@ Ext.define('Ext.Action', {
     
     
 
+    
     constructor : function(config){
         this.initialConfig = config;
         this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
@@ -58088,9 +60906,12 @@ Ext.define('Ext.Action', {
 
     
     callEach : function(fnName, args){
-        var cs = this.items;
-        for(var i = 0, len = cs.length; i < len; i++){
-            cs[i][fnName].apply(cs[i], args);
+        var items = this.items,
+            i = 0,
+            len = items.length;
+
+        for(; i < len; i++){
+            items[i][fnName].apply(items[i], args);
         }
     },
 
@@ -58102,7 +60923,7 @@ Ext.define('Ext.Action', {
 
     
     removeComponent : function(comp){
-        this.items.remove(comp);
+        Ext.Array.remove(this.items, comp);
     },
 
     
@@ -58246,8 +61067,10 @@ Ext.define('Ext.Editor', {
         me.addEvents(
             
             'beforestartedit',
+
             
             'startedit',
+
             
             'beforecomplete',
             
@@ -58267,19 +61090,22 @@ Ext.define('Ext.Editor', {
     
     onRender : function(ct, position) {
         var me = this,
-            field = me.field;
+            field = me.field,
+            inputEl = field.inputEl;
 
         me.callParent(arguments);
 
         field.render(me.el);
         
         
-        field.inputEl.dom.name = '';
-        if (me.swallowKeys) {
-            field.inputEl.swallowEvent([
-                'keypress', 
-                'keydown'   
-            ]);
+        if (inputEl) {
+            inputEl.dom.name = '';
+            if (me.swallowKeys) {
+                inputEl.swallowEvent([
+                    'keypress', 
+                    'keydown'   
+                ]);
+            }
         }
     },
 
@@ -58484,6 +61310,9 @@ Ext.define('Ext.Img', {
     },
     
     
+    initRenderTpl: Ext.emptyFn,
+    
+    
     setSrc: function(src) {
         var me = this,
             img = me.el;
@@ -58503,12 +61332,13 @@ Ext.define('Ext.Layer', {
         shims: []
     },
 
-    extend: 'Ext.core.Element',
+    extend: 'Ext.Element',
 
+    
     constructor: function(config, existingEl) {
         config = config || {};
         var me = this,
-            dh = Ext.core.DomHelper,
+            dh = Ext.DomHelper,
             cp = config.parentEl,
             pel = cp ? Ext.getDom(cp) : document.body,
         hm = config.hideMode;
@@ -58537,14 +61367,14 @@ Ext.define('Ext.Layer', {
         
         
         if (hm) {
-            me.setVisibilityMode(Ext.core.Element[hm.toUpperCase()]);
-            if (me.visibilityMode == Ext.core.Element.ASCLASS) {
+            me.setVisibilityMode(Ext.Element[hm.toUpperCase()]);
+            if (me.visibilityMode == Ext.Element.ASCLASS) {
                 me.visibilityCls = config.visibilityCls;
             }
         } else if (config.useDisplay) {
-            me.setVisibilityMode(Ext.core.Element.DISPLAY);
+            me.setVisibilityMode(Ext.Element.DISPLAY);
         } else {
-            me.setVisibilityMode(Ext.core.Element.VISIBILITY);
+            me.setVisibilityMode(Ext.Element.VISIBILITY);
         }
 
         if (config.id) {
@@ -58567,7 +61397,7 @@ Ext.define('Ext.Layer', {
         if (config.hidden === true) {
             me.hide();
         } else {
-            this.show();
+            me.show();
         }
     },
 
@@ -58599,29 +61429,35 @@ Ext.define('Ext.Layer', {
     },
 
     hideShim: function() {
-        if (this.shim) {
-            this.shim.setDisplayed(false);
-            this.self.shims.push(this.shim);
-            delete this.shim;
+        var me = this;
+        
+        if (me.shim) {
+            me.shim.setDisplayed(false);
+            me.self.shims.push(me.shim);
+            delete me.shim;
         }
     },
 
     disableShadow: function() {
-        if (this.shadow) {
-            this.shadowDisabled = true;
-            this.shadow.hide();
-            this.lastShadowOffset = this.shadowOffset;
-            this.shadowOffset = 0;
+        var me = this;
+        
+        if (me.shadow && !me.shadowDisabled) {
+            me.shadowDisabled = true;
+            me.shadow.hide();
+            me.lastShadowOffset = me.shadowOffset;
+            me.shadowOffset = 0;
         }
     },
 
     enableShadow: function(show) {
-        if (this.shadow) {
-            this.shadowDisabled = false;
-            this.shadowOffset = this.lastShadowOffset;
-            delete this.lastShadowOffset;
+        var me = this;
+        
+        if (me.shadow && me.shadowDisabled) {
+            me.shadowDisabled = false;
+            me.shadowOffset = me.lastShadowOffset;
+            delete me.lastShadowOffset;
             if (show) {
-                this.sync(true);
+                me.sync(true);
             }
         }
     },
@@ -58632,17 +61468,17 @@ Ext.define('Ext.Layer', {
             shadow = me.shadow,
             shadowPos, shimStyle, shadowSize;
 
-        if (!this.updating && this.isVisible() && (shadow || this.useShim)) {
-            var shim = this.getShim(),
-                l = this.getLeft(true),
-                t = this.getTop(true),
-                w = this.getWidth(),
-                h = this.getHeight(),
+        if (!me.updating && me.isVisible() && (shadow || me.useShim)) {
+            var shim = me.getShim(),
+                l = me.getLeft(true),
+                t = me.getTop(true),
+                w = me.dom.offsetWidth,
+                h = me.dom.offsetHeight,
                 shimIndex;
 
-            if (shadow && !this.shadowDisabled) {
+            if (shadow && !me.shadowDisabled) {
                 if (doShow && !shadow.isVisible()) {
-                    shadow.show(this);
+                    shadow.show(me);
                 } else {
                     shadow.realign(l, t, w, h);
                 }
@@ -58658,6 +61494,12 @@ Ext.define('Ext.Layer', {
                         shadowPos = shadow.el.getXY();
                         shimStyle = shim.dom.style;
                         shadowSize = shadow.el.getSize();
+                        if (Ext.supports.CSS3BoxShadow) {
+                            shadowSize.height += 6;
+                            shadowSize.width += 4;
+                            shadowPos[0] -= 2;
+                            shadowPos[1] -= 4;
+                        }
                         shimStyle.left = (shadowPos[0]) + 'px';
                         shimStyle.top = (shadowPos[1]) + 'px';
                         shimStyle.width = (shadowSize.width) + 'px';
@@ -58678,7 +61520,7 @@ Ext.define('Ext.Layer', {
                 shim.setLeftTop(l, t);
             }
         }
-        return this;
+        return me;
     },
 
     remove: function() {
@@ -58708,8 +61550,8 @@ Ext.define('Ext.Layer', {
     
     constrainXY: function() {
         if (this.constrain) {
-            var vw = Ext.core.Element.getViewWidth(),
-                vh = Ext.core.Element.getViewHeight(),
+            var vw = Ext.Element.getViewWidth(),
+                vh = Ext.Element.getViewHeight(),
                 s = Ext.getDoc().getScroll(),
                 xy = this.getXY(),
                 x = xy[0],
@@ -58765,13 +61607,13 @@ Ext.define('Ext.Layer', {
 
         
         if (!visible) {
-            this.hideUnders(true);
+            me.hideUnders(true);
         }
-        this.callParent([visible, animate, duration, callback, easing]);
+        me.callParent([visible, animate, duration, callback, easing]);
         if (!animate) {
             cb();
         }
-        return this;
+        return me;
     },
 
     
@@ -58810,17 +61652,18 @@ Ext.define('Ext.Layer', {
     },
 
     setXY: function(xy, animate, duration, callback, easing) {
-
+        var me = this;
         
-        callback = this.createCB(callback);
+        
+        callback = me.createCB(callback);
 
-        this.fixDisplay();
-        this.beforeAction();
-        this.callParent([xy, animate, duration, callback, easing]);
+        me.fixDisplay();
+        me.beforeAction();
+        me.callParent([xy, animate, duration, callback, easing]);
         if (!animate) {
             callback();
         }
-        return this;
+        return me;
     },
 
     
@@ -58851,70 +61694,86 @@ Ext.define('Ext.Layer', {
 
     
     setSize: function(w, h, animate, duration, callback, easing) {
+        var me = this;
         
-        callback = this.createCB(callback);
+        
+        callback = me.createCB(callback);
 
-        this.beforeAction();
-        this.callParent([w, h, animate, duration, callback, easing]);
+        me.beforeAction();
+        me.callParent([w, h, animate, duration, callback, easing]);
         if (!animate) {
             callback();
         }
-        return this;
+        return me;
     },
 
     
     setWidth: function(w, animate, duration, callback, easing) {
+        var me = this;
+        
         
-        callback = this.createCB(callback);
+        callback = me.createCB(callback);
 
-        this.beforeAction();
-        this.callParent([w, animate, duration, callback, easing]);
+        me.beforeAction();
+        me.callParent([w, animate, duration, callback, easing]);
         if (!animate) {
             callback();
         }
-        return this;
+        return me;
     },
 
     
     setHeight: function(h, animate, duration, callback, easing) {
+        var me = this;
         
-        callback = this.createCB(callback);
+        
+        callback = me.createCB(callback);
 
-        this.beforeAction();
-        this.callParent([h, animate, duration, callback, easing]);
+        me.beforeAction();
+        me.callParent([h, animate, duration, callback, easing]);
         if (!animate) {
             callback();
         }
-        return this;
+        return me;
     },
 
     
     setBounds: function(x, y, width, height, animate, duration, callback, easing) {
+        var me = this;
+        
         
-        callback = this.createCB(callback);
+        callback = me.createCB(callback);
 
-        this.beforeAction();
+        me.beforeAction();
         if (!animate) {
-            Ext.Layer.superclass.setXY.call(this, [x, y]);
-            Ext.Layer.superclass.setSize.call(this, width, height);
+            Ext.Layer.superclass.setXY.call(me, [x, y]);
+            Ext.Layer.superclass.setSize.call(me, width, height);
             callback();
         } else {
-            this.callParent([x, y, width, height, animate, duration, callback, easing]);
+            me.callParent([x, y, width, height, animate, duration, callback, easing]);
         }
-        return this;
+        return me;
     },
 
     
     setZIndex: function(zindex) {
-        this.zindex = zindex;
-        if (this.getShim()) {
-            this.shim.setStyle('z-index', zindex++);
+        var me = this;
+        
+        me.zindex = zindex;
+        if (me.getShim()) {
+            me.shim.setStyle('z-index', zindex++);
+        }
+        if (me.shadow) {
+            me.shadow.setZIndex(zindex++);
         }
+        return me.setStyle('z-index', zindex);
+    },
+    
+    setOpacity: function(opacity){
         if (this.shadow) {
-            this.shadow.setZIndex(zindex++);
+            this.shadow.setOpacity(opacity);
         }
-        this.setStyle('z-index', zindex);
-        return this;
+        return this.callParent(arguments);
     }
 });
 
@@ -58958,6 +61817,15 @@ Ext.define('Ext.ProgressBar', {
     ],
 
     uses: ['Ext.fx.Anim'],
+
+   
+
+   
+
+   
+
+   
+
    
     baseCls: Ext.baseCSSPrefix + 'progress',
 
@@ -58976,7 +61844,7 @@ Ext.define('Ext.ProgressBar', {
         '<div class="{baseCls}-text {baseCls}-text-back">',
             '<div>&#160;</div>',
         '</div>',
-        '<div class="{baseCls}-bar">',
+        '<div id="{id}-bar" class="{baseCls}-bar">',
             '<div class="{baseCls}-text">',
                 '<div>&#160;</div>',
             '</div>',
@@ -58989,11 +61857,7 @@ Ext.define('Ext.ProgressBar', {
     initComponent: function() {
         this.callParent();
 
-        this.renderSelectors = Ext.apply(this.renderSelectors || {}, {
-            textTopEl: '.' + this.baseCls + '-text',
-            textBackEl: '.' + this.baseCls + '-text-back',
-            bar: '.' + this.baseCls + '-bar'
-        });
+        this.addChildEls('bar');
 
         this.addEvents(
             
@@ -59004,9 +61868,11 @@ Ext.define('Ext.ProgressBar', {
     afterRender : function() {
         var me = this;
 
+        
+        
         me.textEl = me.textEl ? Ext.get(me.textEl) : me.el.select('.' + me.baseCls + '-text');
 
-        this.callParent(arguments);
+        me.callParent(arguments);
 
         if (me.value) {
             me.updateProgress(me.value, me.text);
@@ -59018,38 +61884,47 @@ Ext.define('Ext.ProgressBar', {
 
     
     updateProgress: function(value, text, animate) {
-        var newWidth;
-        this.value = value || 0;
+        var me = this,
+            newWidth;
+            
+        me.value = value || 0;
         if (text) {
-            this.updateText(text);
+            me.updateText(text);
         }
-        if (this.rendered && !this.isDestroyed) {
-            newWidth = Math.floor(this.value * this.el.getWidth(true));
-            if (Ext.isForcedBorderBox) {
-                newWidth += this.bar.getBorderWidth("lr");
-            }
-            if (animate === true || (animate !== false && this.animate)) {
-                this.bar.stopAnimation();
-                this.bar.animate(Ext.apply({
-                    to: {
-                        width: newWidth + 'px'
-                    }
-                }, this.animate));
+        if (me.rendered && !me.isDestroyed) {
+            if (me.isVisible(true)) {
+                newWidth = Math.floor(me.value * me.el.getWidth(true));
+                if (Ext.isForcedBorderBox) {
+                    newWidth += me.bar.getBorderWidth("lr");
+                }
+                if (animate === true || (animate !== false && me.animate)) {
+                    me.bar.stopAnimation();
+                    me.bar.animate(Ext.apply({
+                        to: {
+                            width: newWidth + 'px'
+                        }
+                    }, me.animate));
+                } else {
+                    me.bar.setWidth(newWidth);
+                }
             } else {
-                this.bar.setWidth(newWidth);
+                
+                me.doComponentLayout();
             }
         }
-        this.fireEvent('update', this, this.value, text);
-        return this;
+        me.fireEvent('update', me, me.value, text);
+        return me;
     },
 
     
     updateText: function(text) {
-        this.text = text;
-        if (this.rendered) {
-            this.textEl.update(this.text);
+        var me = this;
+        
+        me.text = text;
+        if (me.rendered) {
+            me.textEl.update(me.text);
         }
-        return this;
+        return me;
     },
 
     applyText : function(text) {
@@ -59058,28 +61933,30 @@ Ext.define('Ext.ProgressBar', {
 
     
     wait: function(o) {
-        if (!this.waitTimer) {
-            var scope = this;
+        var me = this;
+            
+        if (!me.waitTimer) {
+            scope = me;
             o = o || {};
-            this.updateText(o.text);
-            this.waitTimer = Ext.TaskManager.start({
+            me.updateText(o.text);
+            me.waitTimer = Ext.TaskManager.start({
                 run: function(i){
                     var inc = o.increment || 10;
                     i -= 1;
-                    this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate);
+                    me.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate);
                 },
                 interval: o.interval || 1000,
                 duration: o.duration,
                 onStop: function(){
                     if (o.fn) {
-                        o.fn.apply(o.scope || this);
+                        o.fn.apply(o.scope || me);
                     }
-                    this.reset();
+                    me.reset();
                 },
                 scope: scope
             });
         }
-        return this;
+        return me;
     },
 
     
@@ -59089,39 +61966,45 @@ Ext.define('Ext.ProgressBar', {
 
     
     reset: function(hide){
-        this.updateProgress(0);
-        this.clearTimer();
+        var me = this;
+        
+        me.updateProgress(0);
+        me.clearTimer();
         if (hide === true) {
-            this.hide();
+            me.hide();
         }
-        return this;
+        return me;
     },
 
     
     clearTimer: function(){
-        if (this.waitTimer) {
-            this.waitTimer.onStop = null; 
-            Ext.TaskManager.stop(this.waitTimer);
-            this.waitTimer = null;
+        var me = this;
+        
+        if (me.waitTimer) {
+            me.waitTimer.onStop = null; 
+            Ext.TaskManager.stop(me.waitTimer);
+            me.waitTimer = null;
         }
     },
 
     onDestroy: function(){
-        this.clearTimer();
-        if (this.rendered) {
-            if (this.textEl.isComposite) {
-                this.textEl.clear();
+        var me = this;
+        
+        me.clearTimer();
+        if (me.rendered) {
+            if (me.textEl.isComposite) {
+                me.textEl.clear();
             }
-            Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl');
+            Ext.destroyMembers(me, 'textEl', 'progressBar');
         }
-        this.callParent();
+        me.callParent();
     }
 });
 
 
 Ext.define('Ext.ShadowPool', {
     singleton: true,
-    requires: ['Ext.core.DomHelper'],
+    requires: ['Ext.DomHelper'],
 
     markup: function() {
         if (Ext.supports.CSS3BoxShadow) {
@@ -59154,7 +62037,7 @@ Ext.define('Ext.ShadowPool', {
     pull: function() {
         var sh = this.shadows.shift();
         if (!sh) {
-            sh = Ext.get(Ext.core.DomHelper.insertHtml("beforeBegin", document.body.firstChild, this.markup));
+            sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, this.markup));
             sh.autoBoxAdjust = false;
         }
         return sh;
@@ -59175,18 +62058,23 @@ Ext.define('Ext.ShadowPool', {
 Ext.define('Ext.Shadow', {
     requires: ['Ext.ShadowPool'],
 
+    
     constructor: function(config) {
-        Ext.apply(this, config);
-        if (typeof this.mode != "string") {
-            this.mode = this.defaultMode;
-        }
-        var offset = this.offset,
+        var me = this,
             adjusts = {
                 h: 0
             },
-            rad = Math.floor(this.offset / 2);
-
-        switch (this.mode.toLowerCase()) {
+            offset,
+            rad;
+        
+        Ext.apply(me, config);
+        if (!Ext.isString(me.mode)) {
+            me.mode = me.defaultMode;
+        }
+        offset = me.offset;
+        rad = Math.floor(offset / 2);
+        me.opacity = 50;
+        switch (me.mode.toLowerCase()) {
             
             case "drop":
                 if (Ext.supports.CSS3BoxShadow) {
@@ -59243,7 +62131,7 @@ Ext.define('Ext.Shadow', {
                     break;
                 }
         }
-        this.adjusts = adjusts;
+        me.adjusts = adjusts;
     },
 
     
@@ -59255,24 +62143,28 @@ Ext.define('Ext.Shadow', {
 
     
     show: function(target) {
+        var me = this,
+            index;
+        
         target = Ext.get(target);
-        if (!this.el) {
-            this.el = Ext.ShadowPool.pull();
-            if (this.el.dom.nextSibling != target.dom) {
-                this.el.insertBefore(target);
+        if (!me.el) {
+            me.el = Ext.ShadowPool.pull();
+            if (me.el.dom.nextSibling != target.dom) {
+                me.el.insertBefore(target);
             }
         }
-        this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10) - 1);
+        index = (parseInt(target.getStyle("z-index"), 10) - 1) || 0;
+        me.el.setStyle("z-index", me.zIndex || index);
         if (Ext.isIE && !Ext.supports.CSS3BoxShadow) {
-            this.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (this.offset) + ")";
+            me.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=" + me.opacity + ") progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (me.offset) + ")";
         }
-        this.realign(
+        me.realign(
             target.getLeft(true),
             target.getTop(true),
-            target.getWidth(),
-            target.getHeight()
+            target.dom.offsetWidth,
+            target.dom.offsetHeight
         );
-        this.el.dom.style.display = "block";
+        me.el.dom.style.display = "block";
     },
 
     
@@ -59323,10 +62215,12 @@ Ext.define('Ext.Shadow', {
 
     
     hide: function() {
-        if (this.el) {
-            this.el.dom.style.display = "none";
-            Ext.ShadowPool.push(this.el);
-            delete this.el;
+        var me = this;
+        
+        if (me.el) {
+            me.el.dom.style.display = "none";
+            Ext.ShadowPool.push(me.el);
+            delete me.el;
         }
     },
 
@@ -59336,18 +62230,31 @@ Ext.define('Ext.Shadow', {
         if (this.el) {
             this.el.setStyle("z-index", z);
         }
+    },
+    
+    
+    setOpacity: function(opacity){
+        if (this.el) {
+            if (Ext.isIE && !Ext.supports.CSS3BoxShadow) {
+                opacity = Math.floor(opacity * 100 / 2) / 100;
+            }
+            this.opacity = opacity;
+            this.el.setOpacity(opacity);
+        }
     }
 });
 
-
 Ext.define('Ext.button.Split', {
 
     
-
     alias: 'widget.splitbutton',
 
     extend: 'Ext.button.Button',
     alternateClassName: 'Ext.SplitButton',
+    
+    
+    
+    
 
     
     arrowCls      : 'split',
@@ -59360,7 +62267,7 @@ Ext.define('Ext.button.Split', {
         this.addEvents("arrowclick");
     },
 
-     
+    
     setArrowHandler : function(handler, scope){
         this.arrowHandler = handler;
         this.scope = scope;
@@ -59373,28 +62280,19 @@ Ext.define('Ext.button.Split', {
         e.preventDefault();
         if (!me.disabled) {
             if (me.overMenuTrigger) {
-                if (me.menu && !me.menu.isVisible() && !me.ignoreNextClick) {
-                    me.showMenu();
-                }
+                me.maybeShowMenu();
                 me.fireEvent("arrowclick", me, e);
                 if (me.arrowHandler) {
                     me.arrowHandler.call(me.scope || me, me, e);
                 }
             } else {
-                if (me.enableToggle) {
-                    me.toggle();
-                }
-                me.fireEvent("click", me, e);
-                if (me.handler) {
-                    me.handler.call(me.scope || me, me, e);
-                }
-                me.onBlur();
+                me.doToggle();
+                me.fireHandler();
             }
         }
     }
 });
 
-
 Ext.define('Ext.button.Cycle', {
 
     
@@ -59547,9 +62445,9 @@ Ext.define('Ext.container.ButtonGroup', {
 
     
     frame: true,
-    
+
     frameHeader: false,
-    
+
     internalDefaults: {removeMode: 'container', hideParent: true},
 
     initComponent : function(){
@@ -59570,7 +62468,7 @@ Ext.define('Ext.container.ButtonGroup', {
 
     afterLayout: function() {
         var me = this;
-        
+
         me.callParent(arguments);
 
         
@@ -59579,24 +62477,39 @@ Ext.define('Ext.container.ButtonGroup', {
             var t = me.getTargetEl();
             t.setWidth(me.layout.table.offsetWidth + t.getPadding('lr'));
         }
+
+        
+        if (Ext.isIE7) {
+            me.el.repaint();
+        }
     },
 
     afterRender: function() {
         var me = this;
-        
+
         
         if (me.header) {
+            
+            delete me.header.items.items[0].flex;
+
+            
+            me.suspendLayout = true;
+            me.header.insert(1, {
+                xtype: 'component',
+                ui   : me.ui,
+                flex : 1
+            });
             me.header.insert(0, {
                 xtype: 'component',
                 ui   : me.ui,
-                html : '&nbsp;',
                 flex : 1
             });
+            me.suspendLayout = false;
         }
-        
+
         me.callParent(arguments);
     },
-    
+
     
     onBeforeAdd: function(component) {
         if (component.is('button')) {
@@ -59637,19 +62550,33 @@ Ext.define('Ext.container.Viewport', {
     
     
     
+
     
+
     
+
+    
+
+    
+
     
+
     
+
     
+
     
+
     
+
     
+
     
 
     isViewport: true,
 
     ariaRole: 'application',
+
     initComponent : function() {
         var me = this,
             html = Ext.fly(document.body.parentNode),
@@ -59665,16 +62592,15 @@ Ext.define('Ext.container.Viewport', {
         el.setSize = Ext.emptyFn;
         el.dom.scroll = 'no';
         me.allowDomMove = false;
-        
-        
         Ext.EventManager.onWindowResize(me.fireResize, me);
         me.renderTo = me.el;
+        me.width = Ext.Element.getViewportWidth();
+        me.height = Ext.Element.getViewportHeight();
     },
 
     fireResize : function(w, h){
         
         this.setSize(w, h);
-        
     }
 });
 
@@ -59684,6 +62610,8 @@ Ext.define('Ext.container.Viewport', {
 
 Ext.define('Ext.dd.DDTarget', {
     extend: 'Ext.dd.DragDrop',
+
+    
     constructor: function(id, sGroup, config) {
         if (id) {
             this.initTarget(id, sGroup, config);
@@ -59801,6 +62729,9 @@ Ext.define('Ext.dd.DragTracker', {
             'mousemove',
 
             
+            'beforedragstart',
+
+            
             'dragstart',
 
             
@@ -59911,27 +62842,30 @@ Ext.define('Ext.dd.DragTracker', {
         this.startXY = this.lastXY = e.getXY();
         this.startRegion = Ext.fly(this.dragTarget).getRegion();
 
-        if (this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false) {
+        if (this.fireEvent('mousedown', this, e) === false ||
+            this.fireEvent('beforedragstart', this, e) === false ||
+            this.onBeforeStart(e) === false) {
+            return;
+        }
 
-            
-            
-            this.mouseIsDown = true;
+        
+        
+        this.mouseIsDown = true;
 
-            
-            e.dragTracked = true;
+        
+        e.dragTracked = true;
 
-            if (this.preventDefault !== false) {
-                e.preventDefault();
-            }
-            Ext.getDoc().on({
-                scope: this,
-                mouseup: this.onMouseUp,
-                mousemove: this.onMouseMove,
-                selectstart: this.stopSelect
-            });
-            if (this.autoStart) {
-                this.timer =  Ext.defer(this.triggerStart, this.autoStart === true ? 1000 : this.autoStart, this, [e]);
-            }
+        if (this.preventDefault !== false) {
+            e.preventDefault();
+        }
+        Ext.getDoc().on({
+            scope: this,
+            mouseup: this.onMouseUp,
+            mousemove: this.onMouseMove,
+            selectstart: this.stopSelect
+        });
+        if (this.autoStart) {
+            this.timer =  Ext.defer(this.triggerStart, this.autoStart === true ? 1000 : this.autoStart, this, [e]);
         }
     },
 
@@ -59972,9 +62906,6 @@ Ext.define('Ext.dd.DragTracker', {
         this.mouseIsDown = false;
 
         
-        delete e.dragTracked;
-
-        
         if (this.mouseIsOut) {
             this.mouseIsOut = false;
             this.onMouseOut(e);
@@ -60000,6 +62931,9 @@ Ext.define('Ext.dd.DragTracker', {
         }
         
         delete this._constrainRegion;
+
+        
+        delete Ext.EventObject.dragTracked;
     },
 
     triggerStart: function(e) {
@@ -60069,7 +63003,7 @@ Ext.define('Ext.dd.DragTracker', {
     },
 
     getXY : function(constrain){
-        return constrain ? this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
+        return constrain ? this.constrainModes[constrain](this, this.lastXY) : this.lastXY;
     },
 
     
@@ -60082,9 +63016,9 @@ Ext.define('Ext.dd.DragTracker', {
 
     constrainModes: {
         
-        point: function(xy) {
-            var dr = this.dragRegion,
-                constrainTo = this.getConstrainRegion();
+        point: function(me, xy) {
+            var dr = me.dragRegion,
+                constrainTo = me.getConstrainRegion();
 
             
             if (!constrainTo) {
@@ -60099,10 +63033,10 @@ Ext.define('Ext.dd.DragTracker', {
         },
 
         
-        dragTarget: function(xy) {
-            var s = this.startXY,
-                dr = this.startRegion.copy(),
-                constrainTo = this.getConstrainRegion(),
+        dragTarget: function(me, xy) {
+            var s = me.startXY,
+                dr = me.startRegion.copy(),
+                constrainTo = me.getConstrainRegion(),
                 adjust;
 
             
@@ -60113,7 +63047,7 @@ Ext.define('Ext.dd.DragTracker', {
             
             
             
-            dr.translateBy.apply(dr, [xy[0]-s[0], xy[1]-s[1]]);
+            dr.translateBy(xy[0]-s[0], xy[1]-s[1]);
 
             
             if (dr.right > constrainTo.right) {
@@ -60141,6 +63075,7 @@ Ext.define('Ext.dd.DragZone', {
 
     extend: 'Ext.dd.DragSource',
 
+    
     constructor : function(el, config){
         this.callParent([el, config]);
         if (this.containerScroll) {
@@ -60175,7 +63110,7 @@ Ext.define('Ext.dd.DragZone', {
 
     
     getRepairXY : function(e){
-        return Ext.core.Element.fly(this.dragData.ddel).getXY();
+        return Ext.Element.fly(this.dragData.ddel).getXY();
     },
 
     destroy : function(){
@@ -60363,6 +63298,7 @@ Ext.define('Ext.dd.DropTarget', {
     extend: 'Ext.dd.DDTarget',
     requires: ['Ext.dd.ScrollManager'],
 
+    
     constructor : function(el, config){
         this.el = Ext.get(el);
 
@@ -60633,12 +63569,6 @@ Ext.define('Ext.flash.Component', {
     renderTpl: ['<div id="{swfId}"></div>'],
 
     initComponent: function() {
-        if (!('swfobject' in window)) {
-            Ext.Error.raise('The SWFObject library is not loaded. Ext.flash.Component requires SWFObject version 2.2 or later: http://code.google.com/p/swfobject/');
-        }
-        if (!this.url) {
-            Ext.Error.raise('The "url" config is required for Ext.flash.Component');
-        }
 
         this.callParent();
         this.addEvents(
@@ -60755,7 +63685,7 @@ Ext.define('Ext.form.action.Action', {
     
 
     
-
+    submitEmptyText : true,
     
 
     
@@ -60764,8 +63694,7 @@ Ext.define('Ext.form.action.Action', {
 
     
 
-
-
+    
     constructor: function(config) {
         if (config) {
             Ext.apply(this, config);
@@ -60922,7 +63851,7 @@ Ext.define('Ext.form.action.Submit', {
                 tag: 'input',
                 type: 'hidden',
                 name: name,
-                value: val
+                value: Ext.String.htmlEncode(val)
             });
         }
 
@@ -60952,7 +63881,7 @@ Ext.define('Ext.form.action.Submit', {
         }
 
         
-        formEl = Ext.core.DomHelper.append(Ext.getBody(), formSpec);
+        formEl = Ext.DomHelper.append(Ext.getBody(), formSpec);
 
         
         
@@ -61022,6 +63951,7 @@ Ext.define('Ext.util.ComponentDragger', {
 
     autoStart: 500,
 
+    
     constructor: function(comp, config) {
         this.comp = comp;
         this.initialConstrainTo = config.constrainTo;
@@ -61089,7 +64019,7 @@ Ext.define('Ext.util.ComponentDragger', {
             comp = (me.proxy && !me.comp.liveDrag) ? me.proxy : me.comp,
             offset = me.getOffset(me.constrain || me.constrainDelegate ? 'dragTarget' : null);
 
-        comp.setPosition.apply(comp, [me.startPosition[0] + offset[0], me.startPosition[1] + offset[1]]);
+        comp.setPosition(me.startPosition[0] + offset[0], me.startPosition[1] + offset[1]);
     },
 
     onEnd: function(e) {
@@ -61105,12 +64035,13 @@ Ext.define("Ext.form.Labelable", {
     
     labelableRenderTpl: [
         '<tpl if="!hideLabel && !(!fieldLabel && hideEmptyLabel)">',
-            '<label<tpl if="inputId"> for="{inputId}"</tpl> class="{labelCls}"<tpl if="labelStyle"> style="{labelStyle}"</tpl>>',
+            '<label id="{id}-labelEl"<tpl if="inputId"> for="{inputId}"</tpl> class="{labelCls}"',
+                '<tpl if="labelStyle"> style="{labelStyle}"</tpl>>',
                 '<tpl if="fieldLabel">{fieldLabel}{labelSeparator}</tpl>',
             '</label>',
         '</tpl>',
-        '<div class="{baseBodyCls} {fieldBodyCls}"<tpl if="inputId"> id="{baseBodyCls}-{inputId}"</tpl> role="presentation">{subTplMarkup}</div>',
-        '<div class="{errorMsgCls}" style="display:none"></div>',
+        '<div class="{baseBodyCls} {fieldBodyCls}" id="{id}-bodyEl" role="presentation">{subTplMarkup}</div>',
+        '<div id="{id}-errorEl" class="{errorMsgCls}" style="display:none"></div>',
         '<div class="{clearCls}" role="presentation"><!-- --></div>',
         {
             compiled: true,
@@ -61135,6 +64066,8 @@ Ext.define("Ext.form.Labelable", {
     labelCls: Ext.baseCSSPrefix + 'form-item-label',
 
     
+
+    
     errorMsgCls: Ext.baseCSSPrefix + 'form-error-msg',
 
     
@@ -61203,6 +64136,8 @@ Ext.define("Ext.form.Labelable", {
     getLabelableRenderData: function() {
         var me = this,
             labelAlign = me.labelAlign,
+            labelCls = me.labelCls,
+            labelClsExtra = me.labelClsExtra,
             labelPad = me.labelPad,
             labelStyle;
 
@@ -61222,27 +64157,27 @@ Ext.define("Ext.form.Labelable", {
             {
                 inputId: me.getInputId(),
                 fieldLabel: me.getFieldLabel(),
+                labelCls: labelClsExtra ? labelCls + ' ' + labelClsExtra : labelCls,
                 labelStyle: labelStyle + (me.labelStyle || ''),
                 subTplMarkup: me.getSubTplMarkup()
             },
             me,
-            'hideLabel,hideEmptyLabel,labelCls,fieldBodyCls,baseBodyCls,errorMsgCls,clearCls,labelSeparator',
+            'hideLabel,hideEmptyLabel,fieldBodyCls,baseBodyCls,errorMsgCls,clearCls,labelSeparator',
             true
         );
     },
 
-    
-    getLabelableSelectors: function() {
-        return {
+    onLabelableRender: function () {
+        this.addChildEls(
             
-            labelEl: 'label.' + this.labelCls,
+            'labelEl',
 
             
-            bodyEl: '.' + this.baseBodyCls,
+            'bodyEl',
 
             
-            errorEl: '.' + this.errorMsgCls
-        };
+            'errorEl'
+        );
     },
 
     
@@ -61333,12 +64268,11 @@ Ext.define("Ext.form.Labelable", {
 
 
 Ext.define('Ext.form.field.Field', {
-
     
     isFormField : true,
 
     
-    
+
     
 
     
@@ -61389,7 +64323,7 @@ Ext.define('Ext.form.field.Field', {
     getValue: function() {
         return this.value;
     },
-    
+
     
     setValue: function(value) {
         var me = this;
@@ -61402,6 +64336,11 @@ Ext.define('Ext.form.field.Field', {
     isEqual: function(value1, value2) {
         return String(value1) === String(value2);
     },
+    
+    
+    isEqualAsString: function(value1, value2){
+        return String(Ext.value(value1, '')) === String(Ext.value(value2, ''));    
+    },
 
     
     getSubmitData: function() {
@@ -61428,7 +64367,7 @@ Ext.define('Ext.form.field.Field', {
     
     reset : function(){
         var me = this;
-        
+
         me.setValue(me.originalValue);
         me.clearInvalid();
         
@@ -61507,9 +64446,14 @@ Ext.define('Ext.form.field.Field', {
 
     
     batchChanges: function(fn) {
-        this.suspendCheckChange++;
-        fn();
-        this.suspendCheckChange--;
+        try {
+            this.suspendCheckChange++;
+            fn();
+        } catch(e){
+            throw e;
+        } finally {
+            this.suspendCheckChange--;
+        }
         this.checkChange();
     },
 
@@ -61581,6 +64525,7 @@ Ext.define('Ext.layout.component.field.Field', {
             autoHeight: autoHeight,
             width: autoWidth ? owner.getBodyNaturalWidth() : width, 
             height: height,
+            setOuterWidth: false, 
 
             
             insets: {
@@ -61618,14 +64563,18 @@ Ext.define('Ext.layout.component.field.Field', {
         
         if (autoWidth && autoHeight) {
             
-            me.setElementSize(owner.el, info.width, info.height);
+            me.setElementSize(owner.el, (info.setOuterWidth ? info.width : undef), info.height);
         } else {
-            me.setTargetSize(info.width, info.height);
+            me.setTargetSize((!autoWidth || info.setOuterWidth ? info.width : undef), info.height);
         }
         me.sizeBody(info);
 
         me.activeError = owner.getActiveError();
     },
+    
+    onFocus: function(){
+        this.getErrorStrategy().onFocus(this.owner);    
+    },
 
 
     
@@ -61694,6 +64643,8 @@ Ext.define('Ext.layout.component.field.Field', {
                     if (info.autoWidth) {
                         info.width += (!owner.labelEl ? 0 : owner.labelWidth + owner.labelPad);
                     }
+                    
+                    info.setOuterWidth = true;
                 },
                 adjustHorizInsets: function(owner, info) {
                     if (owner.labelEl) {
@@ -61753,6 +64704,18 @@ Ext.define('Ext.layout.component.field.Field', {
                 el.setStyle(name, value);
             }
         }
+        
+        function showTip(owner) {
+            var tip = Ext.layout.component.field.Field.tip,
+                target;
+                
+            if (tip && tip.isVisible()) {
+                target = tip.activeTarget;
+                if (target && target.el === owner.getActionEl().dom) {
+                    tip.toFront(true);
+                }
+            }
+        }
 
         var applyIf = Ext.applyIf,
             emptyFn = Ext.emptyFn,
@@ -61763,7 +64726,8 @@ Ext.define('Ext.layout.component.field.Field', {
                 adjustHorizInsets: emptyFn,
                 adjustVertInsets: emptyFn,
                 layoutHoriz: emptyFn,
-                layoutVert: emptyFn
+                layoutVert: emptyFn,
+                onFocus: emptyFn
             };
 
         return {
@@ -61792,7 +64756,8 @@ Ext.define('Ext.layout.component.field.Field', {
                     if (owner.hasActiveError()) {
                         setStyle(owner.errorEl, 'top', info.insets.top + 'px');
                     }
-                }
+                },
+                onFocus: showTip
             }, base),
 
             
@@ -61825,7 +64790,8 @@ Ext.define('Ext.layout.component.field.Field', {
                     setDisplayed(owner.errorEl, false);
                     Ext.layout.component.field.Field.initTip();
                     owner.getActionEl().dom.setAttribute('data-errorqtip', owner.getActiveError() || '');
-                }
+                },
+                onFocus: showTip
             }, base),
 
             
@@ -62020,7 +64986,6 @@ Ext.define('Ext.layout.component.field.TextArea', {
 
 });
 
-
 Ext.define('Ext.layout.container.Anchor', {
 
     
@@ -62032,7 +64997,6 @@ Ext.define('Ext.layout.container.Anchor', {
     
 
     
-
     type: 'anchor',
 
     
@@ -62054,8 +65018,8 @@ Ext.define('Ext.layout.container.Anchor', {
             components = me.getVisibleItems(owner),
             len = components.length,
             boxes = [],
-            box, newTargetSize, anchorWidth, anchorHeight, component, anchorSpec, calcWidth, calcHeight,
-            anchorsArray, anchor, i, el;
+            box, newTargetSize, component, anchorSpec, calcWidth, calcHeight,
+            i, el, cleaner;
 
         if (ownerWidth < 20 && ownerHeight < 20) {
             return;
@@ -62072,46 +65036,27 @@ Ext.define('Ext.layout.container.Anchor', {
         }
 
         
-        if (owner.anchorSize) {
-            if (typeof owner.anchorSize == 'number') {
-                anchorWidth = owner.anchorSize;
-            }
-            else {
-                anchorWidth = owner.anchorSize.width;
-                anchorHeight = owner.anchorSize.height;
-            }
-        }
-        else {
-            anchorWidth = owner.initialConfig.width;
-            anchorHeight = owner.initialConfig.height;
-        }
-
-        
         if (!Ext.supports.RightMargin) {
+            cleaner = Ext.Element.getRightMarginFixCleaner(target);
             target.addCls(Ext.baseCSSPrefix + 'inline-children');
         }
 
         for (i = 0; i < len; i++) {
             component = components[i];
             el = component.el;
-            anchor = component.anchor;
 
-            if (!component.anchor && component.items && !Ext.isNumber(component.width) && !(Ext.isIE6 && Ext.isStrict)) {
-                component.anchor = anchor = me.defaultAnchor;
-            }
-
-            if (anchor) {
-                anchorSpec = component.anchorSpec;
-                
-                if (!anchorSpec) {
-                    anchorsArray = anchor.split(' ');
-                    component.anchorSpec = anchorSpec = {
-                        right: me.parseAnchor(anchorsArray[0], component.initialConfig.width, anchorWidth),
-                        bottom: me.parseAnchor(anchorsArray[1], component.initialConfig.height, anchorHeight)
-                    };
+            anchorSpec = component.anchorSpec;
+            if (anchorSpec) {
+                if (anchorSpec.right) {
+                    calcWidth = me.adjustWidthAnchor(anchorSpec.right(ownerWidth) - el.getMargin('lr'), component);
+                } else {
+                    calcWidth = undefined;
+                }
+                if (anchorSpec.bottom) {
+                    calcHeight = me.adjustHeightAnchor(anchorSpec.bottom(ownerHeight) - el.getMargin('tb'), component);
+                } else {
+                    calcHeight = undefined;
                 }
-                calcWidth = anchorSpec.right ? me.adjustWidthAnchor(anchorSpec.right(ownerWidth) - el.getMargin('lr'), component) : undefined;
-                calcHeight = anchorSpec.bottom ? me.adjustHeightAnchor(anchorSpec.bottom(ownerHeight) - el.getMargin('tb'), component) : undefined;
 
                 boxes.push({
                     component: component,
@@ -62130,6 +65075,7 @@ Ext.define('Ext.layout.container.Anchor', {
         
         if (!Ext.supports.RightMargin) {
             target.removeCls(Ext.baseCSSPrefix + 'inline-children');
+            cleaner();
         }
 
         for (i = 0; i < len; i++) {
@@ -62187,6 +65133,60 @@ Ext.define('Ext.layout.container.Anchor', {
     
     adjustHeightAnchor: function(value, comp) {
         return value;
+    },
+
+    configureItem: function(item) {
+        var me = this,
+            owner = me.owner,
+            anchor= item.anchor,
+            anchorsArray,
+            anchorSpec,
+            anchorWidth,
+            anchorHeight;
+
+        if (!item.anchor && item.items && !Ext.isNumber(item.width) && !(Ext.isIE6 && Ext.isStrict)) {
+            item.anchor = anchor = me.defaultAnchor;
+        }
+
+        
+        if (owner.anchorSize) {
+            if (typeof owner.anchorSize == 'number') {
+                anchorWidth = owner.anchorSize;
+            }
+            else {
+                anchorWidth = owner.anchorSize.width;
+                anchorHeight = owner.anchorSize.height;
+            }
+        }
+        else {
+            anchorWidth = owner.initialConfig.width;
+            anchorHeight = owner.initialConfig.height;
+        }
+
+        if (anchor) {
+            
+            anchorsArray = anchor.split(' ');
+            item.anchorSpec = anchorSpec = {
+                right: me.parseAnchor(anchorsArray[0], item.initialConfig.width, anchorWidth),
+                bottom: me.parseAnchor(anchorsArray[1], item.initialConfig.height, anchorHeight)
+            };
+
+            if (anchorSpec.right) {
+                item.layoutManagedWidth = 1;
+            } else {
+                item.layoutManagedWidth = 2;
+            }
+
+            if (anchorSpec.bottom) {
+                item.layoutManagedHeight = 1;
+            } else {
+                item.layoutManagedHeight = 2;
+            }
+        } else {
+            item.layoutManagedWidth = 2;
+            item.layoutManagedHeight = 2;
+        }
+        this.callParent(arguments);
     }
 
 });
@@ -62254,12 +65254,19 @@ Ext.define('Ext.window.Window', {
     alias: 'widget.window',
 
     
+
     
+
     
+
     
+
     
+
     
+
     
+
     
 
     
@@ -62314,11 +65321,11 @@ Ext.define('Ext.window.Window', {
     floating: true,
 
     ariaRole: 'alertdialog',
-    
+
     itemCls: 'x-window-item',
 
     overlapHeader: true,
-    
+
     ignoreHeaderBorderManagement: true,
 
     
@@ -62327,13 +65334,18 @@ Ext.define('Ext.window.Window', {
         me.callParent();
         me.addEvents(
             
+
             
+
             
             'resize',
+
             
             'maximize',
+
             
             'minimize',
+
             
             'restore'
         );
@@ -62395,9 +65407,14 @@ Ext.define('Ext.window.Window', {
     },
 
     
-    onMouseDown: function () {
+    onMouseDown: function (e) {
+        var preventFocus;
+            
         if (this.floating) {
-            this.toFront();
+            if (Ext.fly(e.getTarget()).focusable()) {
+                preventFocus = true;
+            }
+            this.toFront(preventFocus);
         }
     },
 
@@ -62435,6 +65452,11 @@ Ext.define('Ext.window.Window', {
 
         
         me.mon(me.el, 'mousedown', me.onMouseDown, me);
+        
+        
+        me.el.set({
+            tabIndex: -1
+        });
 
         
         if (me.maximized) {
@@ -62445,7 +65467,15 @@ Ext.define('Ext.window.Window', {
         if (me.closable) {
             keyMap = me.getKeyMap();
             keyMap.on(27, me.onEsc, me);
-            keyMap.disable();
+
+            
+                keyMap.disable();
+            
+        }
+
+        if (!hidden) {
+            me.syncMonitorWindowResize();
+            me.doConstrain();
         }
     },
 
@@ -62458,21 +65488,24 @@ Ext.define('Ext.window.Window', {
             me.updateHeader(true);
         }
 
-        ddConfig = Ext.applyIf({
-            el: me.el,
-            delegate: '#' + me.header.id
-        }, me.draggable);
-
         
-        if (me.constrain || me.constrainHeader) {
-            ddConfig.constrain = me.constrain;
-            ddConfig.constrainDelegate = me.constrainHeader;
-            ddConfig.constrainTo = me.constrainTo || me.container;
-        }
+        if (me.header) {
+            ddConfig = Ext.applyIf({
+                el: me.el,
+                delegate: '#' + me.header.id
+            }, me.draggable);
 
-        
-        me.dd = Ext.create('Ext.util.ComponentDragger', this, ddConfig);
-        me.relayEvents(me.dd, ['dragstart', 'drag', 'dragend']);
+            
+            if (me.constrain || me.constrainHeader) {
+                ddConfig.constrain = me.constrain;
+                ddConfig.constrainDelegate = me.constrainHeader;
+                ddConfig.constrainTo = me.constrainTo || me.container;
+            }
+
+            
+            me.dd = Ext.create('Ext.util.ComponentDragger', this, ddConfig);
+            me.relayEvents(me.dd, ['dragstart', 'drag', 'dragend']);
+        }
     },
 
     
@@ -62553,7 +65586,11 @@ Ext.define('Ext.window.Window', {
     
     afterShow: function(animateTarget) {
         var me = this,
-            size;
+            animating = animateTarget || me.animateTarget;
+
+
+        
+        
 
         
         
@@ -62563,10 +65600,11 @@ Ext.define('Ext.window.Window', {
             me.fitContainer();
         }
 
-        if (me.monitorResize || me.constrain || me.constrainHeader) {
-            Ext.EventManager.onWindowResize(me.onWindowResize, me);
+        me.syncMonitorWindowResize();
+        if (!animating) {
+            me.doConstrain();
         }
-        me.doConstrain();
+
         if (me.keyMap) {
             me.keyMap.enable();
         }
@@ -62579,10 +65617,12 @@ Ext.define('Ext.window.Window', {
         
         if (me.hidden) {
             me.fireEvent('close', me);
-            me[me.closeAction]();
+            if (me.closeAction == 'destroy') {
+                this.destroy();
+            }
         } else {
             
-            me.hide(me.animTarget, me.doClose, me);
+            me.hide(me.animateTarget, me.doClose, me);
         }
     },
 
@@ -62591,9 +65631,7 @@ Ext.define('Ext.window.Window', {
         var me = this;
 
         
-        if (me.monitorResize || me.constrain || me.constrainHeader) {
-            Ext.EventManager.removeResizeListener(me.onWindowResize, me);
-        }
+        me.syncMonitorWindowResize();
 
         
         if (me.keyMap) {
@@ -62671,6 +65709,7 @@ Ext.define('Ext.window.Window', {
             me.el.addCls(Ext.baseCSSPrefix + 'window-maximized');
             me.container.addCls(Ext.baseCSSPrefix + 'window-maximized-ct');
 
+            me.syncMonitorWindowResize();
             me.setPosition(0, 0);
             me.fitContainer();
             me.fireEvent('maximize', me);
@@ -62717,6 +65756,7 @@ Ext.define('Ext.window.Window', {
 
             me.container.removeCls(Ext.baseCSSPrefix + 'window-maximized-ct');
 
+            me.syncMonitorWindowResize();
             me.doConstrain();
             me.fireEvent('restore', me);
         }
@@ -62724,6 +65764,29 @@ Ext.define('Ext.window.Window', {
     },
 
     
+    syncMonitorWindowResize: function () {
+        var me = this,
+            currentlyMonitoring = me._monitoringResize,
+            
+            yes = me.monitorResize || me.constrain || me.constrainHeader || me.maximized,
+            
+            veto = me.hidden || me.destroying || me.isDestroyed;
+
+        if (yes && !veto) {
+            
+            if (!currentlyMonitoring) {
+                
+                Ext.EventManager.onWindowResize(me.onWindowResize, me);
+                me._monitoringResize = true;
+            }
+        } else if (currentlyMonitoring) {
+            
+            Ext.EventManager.removeResizeListener(me.onWindowResize, me);
+            me._monitoringResize = false;
+        }
+    },
+
+    
     toggleMaximize: function() {
         return this[this.maximized ? 'restore': 'maximize']();
     }
@@ -62731,6 +65794,7 @@ Ext.define('Ext.window.Window', {
     
 });
 
+
 Ext.define('Ext.form.field.Base', {
     extend: 'Ext.Component',
     mixins: {
@@ -62741,7 +65805,8 @@ Ext.define('Ext.form.field.Base', {
     alternateClassName: ['Ext.form.Field', 'Ext.form.BaseField'],
     requires: ['Ext.util.DelayedTask', 'Ext.XTemplate', 'Ext.layout.component.field.Field'],
 
-    fieldSubTpl: [
+    
+    fieldSubTpl: [ 
         '<input id="{id}" type="{type}" ',
         '<tpl if="name">name="{name}" </tpl>',
         '<tpl if="size">size="{size}" </tpl>',
@@ -62797,9 +65862,9 @@ Ext.define('Ext.form.field.Base', {
 
     
     hasFocus : false,
-    
+
     baseCls: Ext.baseCSSPrefix + 'field',
-    
+
     maskOnDisable: false,
 
     
@@ -62842,6 +65907,7 @@ Ext.define('Ext.form.field.Base', {
 
         return Ext.applyIf(me.subTplData, {
             id: inputId,
+            cmpId: me.id,
             name: me.name || inputId,
             type: type,
             size: me.size || 20,
@@ -62852,6 +65918,14 @@ Ext.define('Ext.form.field.Base', {
         });
     },
 
+    afterRender: function() {
+        this.callParent();
+        
+        if (this.inputEl) {
+            this.inputEl.selectable();
+        }
+    },
+
     
     getSubTplMarkup: function() {
         return this.getTpl('fieldSubTpl').apply(this.getSubTplData());
@@ -62882,15 +65956,12 @@ Ext.define('Ext.form.field.Base', {
     
     onRender : function() {
         var me = this,
-            fieldStyle = me.fieldStyle,
-            renderSelectors = me.renderSelectors;
+            fieldStyle = me.fieldStyle;
 
-        Ext.applyIf(renderSelectors, me.getLabelableSelectors());
+        me.onLabelableRender();
 
-        Ext.applyIf(renderSelectors, {
-            
-            inputEl: '.' + me.fieldCls
-        });
+        
+        me.addChildEls({ name: 'inputEl', id: me.getInputId() });
 
         me.callParent(arguments);
 
@@ -63111,6 +66182,7 @@ Ext.define('Ext.form.field.Base', {
         }
         if (!me.hasFocus) {
             me.hasFocus = true;
+            me.componentLayout.onFocus();
             me.fireEvent('focus', me);
         }
     },
@@ -63123,6 +66195,11 @@ Ext.define('Ext.form.field.Base', {
         var me = this,
             focusCls = me.focusCls,
             inputEl = me.inputEl;
+
+        if (me.destroying) {
+            return;
+        }
+
         me.beforeBlur();
         if (focusCls && inputEl) {
             inputEl.removeCls(focusCls);
@@ -63216,7 +66293,7 @@ Ext.define('Ext.form.field.Text', {
     alternateClassName: ['Ext.form.TextField', 'Ext.form.Text'],
 
     
-    
+
     
 
     
@@ -63226,13 +66303,13 @@ Ext.define('Ext.form.field.Text', {
 
     
     growMin : 30,
-    
+
     
     growMax : 800,
 
     
     growAppend: 'W',
-    
+
     
 
     
@@ -63241,33 +66318,33 @@ Ext.define('Ext.form.field.Text', {
 
     
     allowBlank : true,
-    
+
     
     minLength : 0,
-    
+
     
     maxLength : Number.MAX_VALUE,
-    
+
     
 
     
     minLengthText : 'The minimum length for this field is {0}',
-    
+
     
     maxLengthText : 'The maximum length for this field is {0}',
+
     
-    
-    
+
     
     blankText : 'This field is required',
-    
+
     
 
     
 
     
     regexText : '',
-    
+
     
 
     
@@ -63298,7 +66375,7 @@ Ext.define('Ext.form.field.Text', {
     initEvents : function(){
         var me = this,
             el = me.inputEl;
-        
+
         me.callParent();
         if(me.selectOnFocus || me.emptyText){
             me.mon(el, 'mousedown', me.onMouseDown, me);
@@ -63319,7 +66396,7 @@ Ext.define('Ext.form.field.Text', {
 
     
     isEqual: function(value1, value2) {
-        return String(Ext.value(value1, '')) === String(Ext.value(value2, ''));
+        return this.isEqualAsString(value1, value2);
     },
 
     
@@ -63327,7 +66404,7 @@ Ext.define('Ext.form.field.Text', {
         this.callParent();
         this.autoSize();
     },
-    
+
     afterRender: function(){
         var me = this;
         if (me.enforceMaxLength) {
@@ -63350,7 +66427,7 @@ Ext.define('Ext.form.field.Text', {
         var me = this,
             stripRe = me.stripCharsRe,
             newValue;
-            
+
         if (stripRe) {
             newValue = value.replace(stripRe, '');
             if (newValue !== value) {
@@ -63402,13 +66479,13 @@ Ext.define('Ext.form.field.Text', {
 
         if (me.rendered && emptyText) {
             isEmpty = me.getRawValue().length < 1 && !me.hasFocus;
-            
+
             if (Ext.supports.Placeholder) {
                 me.inputEl.dom.placeholder = emptyText;
             } else if (isEmpty) {
                 me.setRawValue(emptyText);
             }
-            
+
             
             
             if (isEmpty) {
@@ -63453,16 +66530,17 @@ Ext.define('Ext.form.field.Text', {
 
     
     filterKeys : function(e){
-        if(e.ctrlKey){
+        
+        if (e.ctrlKey && !e.altKey) {
             return;
         }
         var key = e.getKey(),
             charCode = String.fromCharCode(e.getCharCode());
-            
+
         if(Ext.isGecko && (e.isNavKeyPress() || key === e.BACKSPACE || (key === e.DELETE && e.button === -1))){
             return;
         }
-        
+
         if(!Ext.isGecko && e.isSpecialKey() && !charCode){
             return;
         }
@@ -63485,11 +66563,11 @@ Ext.define('Ext.form.field.Text', {
     setValue: function(value) {
         var me = this,
             inputEl = me.inputEl;
-        
+
         if (inputEl && me.emptyText && !Ext.isEmpty(value)) {
             inputEl.removeCls(me.emptyCls);
         }
-        
+
         me.callParent(arguments);
 
         me.applyEmptyText();
@@ -63555,7 +66633,7 @@ Ext.define('Ext.form.field.Text', {
             el = me.inputEl.dom,
             undef,
             range;
-            
+
         if (v.length > 0) {
             start = start === undef ? 0 : start;
             end = end === undef ? v.length : end;
@@ -63721,8 +66799,6 @@ Ext.define('Ext.window.MessageBox', {
         'Ext.layout.container.HBox',
         'Ext.ProgressBar'
     ],
-    
-    alternateClassName: 'Ext.MessageBox',
 
     alias: 'widget.messagebox',
 
@@ -63793,7 +66869,7 @@ Ext.define('Ext.window.MessageBox', {
         wait: 'Loading...',
         alert: 'Attention'
     },
-    
+
     iconHeight: 35,
 
     makeButton: function(btnIdx) {
@@ -63917,7 +66993,7 @@ Ext.define('Ext.window.MessageBox', {
     onPromptKey: function(textField, e) {
         var me = this,
             blur;
-            
+
         if (e.keyCode === Ext.EventObject.RETURN || e.keyCode === 10) {
             if (me.msgButtons.ok.isVisible()) {
                 blur = true;
@@ -63926,7 +67002,7 @@ Ext.define('Ext.window.MessageBox', {
                 me.msgButtons.yes.handler.call(me, me.msgButtons.yes);
                 blur = true;
             }
-            
+
             if (blur) {
                 me.textField.blur();
             }
@@ -63948,7 +67024,7 @@ Ext.define('Ext.window.MessageBox', {
 
         
         delete me.defaultFocus;
-        
+
         
         me.animateTarget = cfg.animateTarget || undefined;
 
@@ -63970,11 +67046,7 @@ Ext.define('Ext.window.MessageBox', {
 
         
         me.closable = cfg.closable && !cfg.wait;
-        if (cfg.closable === false) {
-            me.tools.close.hide();
-        } else {
-            me.tools.close.show();
-        }
+        me.header.child('[type=close]').setVisible(cfg.closable !== false);
 
         
         if (!cfg.title && !me.closable) {
@@ -64052,17 +67124,16 @@ Ext.define('Ext.window.MessageBox', {
         } else {
             me.bottomTb.show();
         }
-        me.hidden = true;
     },
 
     
     show: function(cfg) {
         var me = this;
-            
+
         me.reconfigure(cfg);
         me.addCls(cfg.cls);
         if (cfg.animateTarget) {
-            me.doAutoSize(false);
+            me.doAutoSize(true);
             me.callParent();
         } else {
             me.callParent();
@@ -64070,11 +67141,11 @@ Ext.define('Ext.window.MessageBox', {
         }
         return me;
     },
-    
+
     afterShow: function(){
         if (this.animateTarget) {
             this.center();
-        }    
+        }
         this.callParent(arguments);
     },
 
@@ -64086,7 +67157,7 @@ Ext.define('Ext.window.MessageBox', {
         if (!Ext.isDefined(me.frameWidth)) {
             me.frameWidth = me.el.getWidth() - me.body.getWidth();
         }
-        
+
         
         icon.setHeight(iconHeight);
 
@@ -64223,24 +67294,24 @@ Ext.define('Ext.window.MessageBox', {
             cfg = {
                 title: cfg,
                 msg: msg,
+                progress: true,
                 progressText: progressText
             };
         }
         return this.show(cfg);
     }
 }, function() {
+    
     Ext.MessageBox = Ext.Msg = new this();
 });
 
-
-
-
 Ext.define('Ext.form.Basic', {
     extend: 'Ext.util.Observable',
     alternateClassName: 'Ext.form.BasicForm',
     requires: ['Ext.util.MixedCollection', 'Ext.form.action.Load', 'Ext.form.action.Submit',
-               'Ext.window.MessageBox', 'Ext.data.Errors'],
+               'Ext.window.MessageBox', 'Ext.data.Errors', 'Ext.util.DelayedTask'],
 
+    
     constructor: function(owner, config) {
         var me = this,
             onItemAddOrRemove = me.onItemAddOrRemove;
@@ -64262,6 +67333,8 @@ Ext.define('Ext.form.Basic', {
             me.paramOrder = me.paramOrder.split(/[\s,|]/);
         }
 
+        me.checkValidityTask = Ext.create('Ext.util.DelayedTask', me.checkValidity, me);
+
         me.addEvents(
             
             'beforeaction',
@@ -64284,7 +67357,9 @@ Ext.define('Ext.form.Basic', {
     },
 
     
+
     
+
     
 
     
@@ -64319,6 +67394,7 @@ Ext.define('Ext.form.Basic', {
     
     destroy: function() {
         this.clearListeners();
+        this.checkValidityTask.cancel();
     },
 
     
@@ -64341,18 +67417,24 @@ Ext.define('Ext.form.Basic', {
 
         if (child.isFormField) {
             handleField(child);
-        }
-        else if (isContainer) {
+        } else if (isContainer) {
             
-            Ext.Array.forEach(child.query('[isFormField]'), handleField);
+            if (child.isDestroyed) {
+                
+                
+                delete me._fields;
+            } else {
+                Ext.Array.forEach(child.query('[isFormField]'), handleField);
+            }
         }
 
         
         delete this._boundItems;
 
         
+        
         if (me.initialized) {
-            me.onValidityChange(!me.hasInvalidField());
+            me.checkValidityTask.delay(10);
         }
     },
 
@@ -64366,12 +67448,15 @@ Ext.define('Ext.form.Basic', {
         return fields;
     },
 
+    
     getBoundItems: function() {
         var boundItems = this._boundItems;
-        if (!boundItems) {
+        
+        if (!boundItems || boundItems.getCount() === 0) {
             boundItems = this._boundItems = Ext.create('Ext.util.MixedCollection');
             boundItems.addAll(this.owner.query('[formBind]'));
         }
+        
         return boundItems;
     },
 
@@ -64493,7 +67578,7 @@ Ext.define('Ext.form.Basic', {
         this._record = record;
         return this.setValues(record.data);
     },
-    
+
     
     getRecord: function() {
         return this._record;
@@ -64973,7 +68058,7 @@ Ext.define('Ext.form.FieldContainer', {
 
     
     combineErrors: false,
-    
+
     maskOnDisable: false,
 
     initComponent: function() {
@@ -65002,11 +68087,9 @@ Ext.define('Ext.form.FieldContainer', {
     },
 
     onRender: function() {
-        var me = this,
-            renderSelectors = me.renderSelectors,
-            applyIf = Ext.applyIf;
+        var me = this;
 
-        applyIf(renderSelectors, me.getLabelableSelectors());
+        me.onLabelableRender();
 
         me.callParent(arguments);
     },
@@ -65363,8 +68446,8 @@ Ext.define('Ext.form.FieldSet', {
     
     ariaRole: '',
 
-    renderTpl: ['<div class="{baseCls}-body"></div>'],
-    
+    renderTpl: ['<div id="{id}-body" class="{baseCls}-body"></div>'],
+
     maskOnDisable: false,
 
     getElConfig: function(){
@@ -65381,9 +68464,7 @@ Ext.define('Ext.form.FieldSet', {
         me.initLegend();
 
         
-        Ext.applyIf(me.renderSelectors, {
-            body: '.' + baseCls + '-body'
-        });
+        me.addChildEls('body');
 
         if (me.collapsed) {
             me.addCls(baseCls + '-collapsed');
@@ -65423,8 +68504,23 @@ Ext.define('Ext.form.FieldSet', {
             legend = me.legend = Ext.create('Ext.container.Container', {
                 baseCls: me.baseCls + '-header',
                 ariaRole: '',
+                ownerCt: this,
                 getElConfig: function(){
-                    return {tag: 'legend', cls: this.baseCls};
+                    var result = {
+                        tag: 'legend',
+                        cls: this.baseCls
+                    };
+
+                    
+                    
+                    
+                    
+                    if (!Ext.isGecko3) {
+                        result.children = [{
+                            cls: Ext.baseCSSPrefix + 'clear'
+                        }];
+                    }
+                    return result;
                 },
                 items: legendItems
             });
@@ -65441,10 +68537,16 @@ Ext.define('Ext.form.FieldSet', {
         var me = this;
         me.titleCmp = Ext.create('Ext.Component', {
             html: me.title,
+            getElConfig: function() {
+                return {
+                    tag: Ext.isGecko3 ? 'span' : 'div',
+                    cls: me.titleCmp.cls,
+                    id: me.titleCmp.id
+                };
+            },
             cls: me.baseCls + '-header-text'
         });
         return me.titleCmp;
-        
     },
 
     
@@ -65453,8 +68555,15 @@ Ext.define('Ext.form.FieldSet', {
     createCheckboxCmp: function() {
         var me = this,
             suffix = '-checkbox';
-            
+
         me.checkboxCmp = Ext.create('Ext.form.field.Checkbox', {
+            getElConfig: function() {
+                return {
+                    tag: Ext.isGecko3 ? 'span' : 'div',
+                    id: me.checkboxCmp.id,
+                    cls: me.checkboxCmp.cls
+                };
+            },
             name: me.checkboxName || me.id + suffix,
             cls: me.baseCls + '-header' + suffix,
             checked: !me.collapsed,
@@ -65472,13 +68581,20 @@ Ext.define('Ext.form.FieldSet', {
     createToggleCmp: function() {
         var me = this;
         me.toggleCmp = Ext.create('Ext.panel.Tool', {
+            getElConfig: function() {
+                return {
+                    tag: Ext.isGecko3 ? 'span' : 'div',
+                    id: me.toggleCmp.id,
+                    cls: me.toggleCmp.cls
+                };
+            },
             type: 'toggle',
             handler: me.toggle,
             scope: me
         });
         return me.toggleCmp;
     },
-    
+
     
     setTitle: function(title) {
         var me = this;
@@ -65487,15 +68603,15 @@ Ext.define('Ext.form.FieldSet', {
         me.titleCmp.update(title);
         return me;
     },
-    
+
     getTargetEl : function() {
         return this.body || this.frameBody || this.el;
     },
-    
+
     getContentTarget: function() {
         return this.body;
     },
-    
+
     
     getRefItems: function(deep) {
         var refItems = this.callParent(arguments),
@@ -65515,7 +68631,7 @@ Ext.define('Ext.form.FieldSet', {
     expand : function(){
         return this.setExpanded(true);
     },
-    
+
     
     collapse : function() {
         return this.setExpanded(false);
@@ -65524,21 +68640,24 @@ Ext.define('Ext.form.FieldSet', {
     
     setExpanded: function(expanded) {
         var me = this,
-            checkboxCmp = me.checkboxCmp,
-            toggleCmp = me.toggleCmp;
+            checkboxCmp = me.checkboxCmp;
 
         expanded = !!expanded;
-        
+
         if (checkboxCmp) {
             checkboxCmp.setValue(expanded);
         }
-        
+
         if (expanded) {
             me.removeCls(me.baseCls + '-collapsed');
         } else {
             me.addCls(me.baseCls + '-collapsed');
         }
         me.collapsed = !expanded;
+        if (expanded) {
+            
+            me.getComponentLayout().childrenChanged = true;
+        }
         me.doComponentLayout();
         return me;
     },
@@ -65625,11 +68744,11 @@ Ext.define('Ext.form.Panel', {
 
     initComponent: function() {
         var me = this;
-        
+
         if (me.frame) {
             me.border = false;
         }
-        
+
         me.initFieldAncestor();
         me.callParent();
 
@@ -65650,7 +68769,7 @@ Ext.define('Ext.form.Panel', {
     initItems: function() {
         
         var me = this;
-        
+
         me.form = me.createForm();
         me.callParent();
         me.form.initialize();
@@ -65665,17 +68784,17 @@ Ext.define('Ext.form.Panel', {
     getForm: function() {
         return this.form;
     },
-    
+
     
     loadRecord: function(record) {
         return this.getForm().loadRecord(record);
     },
-    
+
     
     getRecord: function() {
         return this.getForm().getRecord();
     },
-    
+
     
     getValues: function() {
         return this.getForm().getValues();
@@ -65752,17 +68871,30 @@ Ext.define('Ext.form.RadioGroup', {
     allowBlank : true,
     
     blankText : 'You must select one item in this group',
-    
+
     
     defaultType : 'radiofield',
-    
+
     
     groupCls : Ext.baseCSSPrefix + 'form-radio-group',
 
     getBoxes: function() {
         return this.query('[isRadio]');
-    }
+    },
 
+    
+    setValue: function(value) {
+        var me = this;
+        if (Ext.isObject(value)) {
+            Ext.Object.each(value, function(name, cbValue) {
+                var radios = Ext.form.RadioManager.getWithValue(name, cbValue);
+                radios.each(function(cb) {
+                    cb.setValue(true);
+                });
+            });
+        }
+        return me;
+    }
 });
 
 
@@ -65900,9 +69032,10 @@ Ext.define('Ext.form.field.Checkbox', {
     alternateClassName: 'Ext.form.Checkbox',
     requires: ['Ext.XTemplate', 'Ext.form.CheckboxManager'],
 
+    
     fieldSubTpl: [
         '<tpl if="boxLabel && boxLabelAlign == \'before\'">',
-            '<label class="{boxLabelCls} {boxLabelCls}-{boxLabelAlign}" for="{id}">{boxLabel}</label>',
+            '<label id="{cmpId}-boxLabelEl" class="{boxLabelCls} {boxLabelCls}-{boxLabelAlign}" for="{id}">{boxLabel}</label>',
         '</tpl>',
         
         
@@ -65911,7 +69044,7 @@ Ext.define('Ext.form.field.Checkbox', {
             '<tpl if="tabIdx">tabIndex="{tabIdx}" </tpl>',
             'class="{fieldCls} {typeCls}" autocomplete="off" hidefocus="true" />',
         '<tpl if="boxLabel && boxLabelAlign == \'after\'">',
-            '<label class="{boxLabelCls} {boxLabelCls}-{boxLabelAlign}" for="{id}">{boxLabel}</label>',
+            '<label id="{cmpId}-boxLabelEl" class="{boxLabelCls} {boxLabelCls}-{boxLabelAlign}" for="{id}">{boxLabel}</label>',
         '</tpl>',
         {
             disableFormats: true,
@@ -65979,10 +69112,10 @@ Ext.define('Ext.form.field.Checkbox', {
     
     onRender : function(ct, position) {
         var me = this;
-        Ext.applyIf(me.renderSelectors, {
-            
-            boxLabelEl: 'label.' + me.boxLabelCls
-        });
+
+        
+        me.addChildEls('boxLabelEl');
+
         Ext.applyIf(me.subTplData, {
             boxLabel: me.boxLabel,
             boxLabelCls: me.boxLabelCls,
@@ -66018,11 +69151,9 @@ Ext.define('Ext.form.field.Checkbox', {
 
     
     getSubmitValue: function() {
-        return this.checked ? this.inputValue : (this.uncheckedValue || null);
-    },
-
-    getModelData: function() {
-        return this.getSubmitData();
+        var unchecked = this.uncheckedValue,
+            uncheckedVal = Ext.isDefined(unchecked) ? unchecked : null;
+        return this.checked ? this.inputValue : uncheckedVal;
     },
 
     
@@ -66030,8 +69161,8 @@ Ext.define('Ext.form.field.Checkbox', {
         var me = this,
             inputEl = me.inputEl,
             inputValue = me.inputValue,
-            checked = (value === true || value === 'true' || value === '1' ||
-                      ((Ext.isString(value) && inputValue) ? value == inputValue : me.onRe.test(value)));
+            checked = (value === true || value === 'true' || value === '1' || value === 1 ||
+                (((Ext.isString(value) || Ext.isNumber(value)) && inputValue) ? value == inputValue : me.onRe.test(value)));
 
         if (inputEl) {
             inputEl.dom.setAttribute('aria-checked', checked);
@@ -66078,6 +69209,12 @@ Ext.define('Ext.form.field.Checkbox', {
     },
 
     
+    beforeDestroy: function(){
+        this.callParent();
+        this.getManager().removeAtKey(this.id);
+    },
+
+    
     getManager: function() {
         return Ext.form.CheckboxManager;
     },
@@ -66103,6 +69240,7 @@ Ext.define('Ext.form.field.Checkbox', {
     },
 
     
+    
     getBodyNaturalWidth: function() {
         var me = this,
             bodyEl = me.bodyEl,
@@ -66152,9 +69290,9 @@ Ext.define('Ext.layout.component.field.Trigger', {
 
 Ext.define('Ext.view.View', {
     extend: 'Ext.view.AbstractView',
-    alternateClassName: 'Ext.view.View',
+    alternateClassName: 'Ext.DataView',
     alias: 'widget.dataview',
-    
+
     inheritableStatics: {
         EventMap: {
             mousedown: 'MouseDown',
@@ -66166,10 +69304,11 @@ Ext.define('Ext.view.View', {
             mouseout: 'MouseOut',
             mouseenter: 'MouseEnter',
             mouseleave: 'MouseLeave',
-            keydown: 'KeyDown'
+            keydown: 'KeyDown',
+            focus: 'Focus'
         }
     },
-    
+
     addCmpEvents: function() {
         this.addEvents(
             
@@ -66234,7 +69373,7 @@ Ext.define('Ext.view.View', {
             'containercontextmenu',
             
             'containerkeydown',
-            
+
             
             'selectionchange',
             
@@ -66243,13 +69382,15 @@ Ext.define('Ext.view.View', {
     },
     
     afterRender: function(){
-        var me = this, 
+        var me = this,
             listeners;
-        
+
         me.callParent();
 
         listeners = {
             scope: me,
+            
+            freezeEvent: true,
             click: me.handleEvent,
             mousedown: me.handleEvent,
             mouseup: me.handleEvent,
@@ -66259,43 +69400,59 @@ Ext.define('Ext.view.View', {
             mouseout: me.handleEvent,
             keydown: me.handleEvent
         };
-        
+
         me.mon(me.getTargetEl(), listeners);
-        
+
         if (me.store) {
             me.bindStore(me.store, true);
         }
     },
-    
+
     handleEvent: function(e) {
         if (this.processUIEvent(e) !== false) {
             this.processSpecialEvent(e);
         }
     },
-    
+
     
     processItemEvent: Ext.emptyFn,
     processContainerEvent: Ext.emptyFn,
     processSpecialEvent: Ext.emptyFn,
+
     
-    processUIEvent: function(e, type) {
-        type = type || e.type;
+    stillOverItem: function (event, overItem) {
+        var nowOver;
+
+        
+        
+        
+        
+        
+        
+        if (overItem && typeof(overItem.offsetParent) === "object") {
+            
+            
+            nowOver = (event.type == 'mouseout') ? event.getRelatedTarget() : event.getTarget();
+            return Ext.fly(overItem).contains(nowOver);
+        }
+
+        return false;
+    },
+
+    processUIEvent: function(e) {
         var me = this,
             item = e.getTarget(me.getItemSelector(), me.getTargetEl()),
             map = this.statics().EventMap,
-            index, record;
-        
+            index, record,
+            type = e.type,
+            overItem = me.mouseOverItem,
+            newType;
+
         if (!item) {
-            
-            
-            
-            
-            
-            
-            if (type == 'mouseover' && me.mouseOverItem && typeof me.mouseOverItem.offsetParent === "object" && Ext.fly(me.mouseOverItem).getRegion().contains(e.getPoint())) {
-                item = me.mouseOverItem;
+            if (type == 'mouseover' && me.stillOverItem(e, overItem)) {
+                item = overItem;
             }
-            
+
             
             if (type == 'keydown') {
                 record = me.getSelectionModel().getLastSelected();
@@ -66304,54 +69461,53 @@ Ext.define('Ext.view.View', {
                 }
             }
         }
-        
+
         if (item) {
             index = me.indexOf(item);
             if (!record) {
                 record = me.getRecord(item);
             }
-            
-            if (me.processItemEvent(type, record, item, index, e) === false) {
+
+            if (me.processItemEvent(record, item, index, e) === false) {
                 return false;
             }
-            
-            type = me.isNewItemEvent(type, item, e);
-            if (type === false) {
+
+            newType = me.isNewItemEvent(item, e);
+            if (newType === false) {
                 return false;
             }
-            
+
             if (
-                (me['onBeforeItem' + map[type]](record, item, index, e) === false) ||
-                (me.fireEvent('beforeitem' + type, me, record, item, index, e) === false) ||
-                (me['onItem' + map[type]](record, item, index, e) === false)
-            ) { 
+                (me['onBeforeItem' + map[newType]](record, item, index, e) === false) ||
+                (me.fireEvent('beforeitem' + newType, me, record, item, index, e) === false) ||
+                (me['onItem' + map[newType]](record, item, index, e) === false)
+            ) {
                 return false;
             }
-            
-            me.fireEvent('item' + type, me, record, item, index, e);
-        } 
+
+            me.fireEvent('item' + newType, me, record, item, index, e);
+        }
         else {
             if (
-                (me.processContainerEvent(type, e) === false) ||
+                (me.processContainerEvent(e) === false) ||
                 (me['onBeforeContainer' + map[type]](e) === false) ||
                 (me.fireEvent('beforecontainer' + type, me, e) === false) ||
                 (me['onContainer' + map[type]](e) === false)
             ) {
                 return false;
             }
-            
+
             me.fireEvent('container' + type, me, e);
         }
-        
+
         return true;
     },
-    
-    isNewItemEvent: function(type, item, e) {
+
+    isNewItemEvent: function (item, e) {
         var me = this,
             overItem = me.mouseOverItem,
-            contains,
-            isItem;
-            
+            type = e.type;
+
         switch (type) {
             case 'mouseover':
                 if (item === overItem) {
@@ -66359,24 +69515,18 @@ Ext.define('Ext.view.View', {
                 }
                 me.mouseOverItem = item;
                 return 'mouseenter';
-            break;
-            
+
             case 'mouseout':
-               
-                if (overItem && typeof overItem.offsetParent === "object") {
-                    contains = Ext.fly(me.mouseOverItem).getRegion().contains(e.getPoint());
-                    isItem = Ext.fly(e.getTarget()).hasCls(me.itemSelector);
-                    if (contains && isItem) {
-                        return false;
-                    }
+                
+                if (me.stillOverItem(e, overItem)) {
+                    return false;
                 }
                 me.mouseOverItem = null;
                 return 'mouseleave';
-            break;
         }
         return type;
     },
-    
+
     
     onItemMouseEnter: function(record, item, index, e) {
         if (this.trackOver) {
@@ -66394,19 +69544,21 @@ Ext.define('Ext.view.View', {
     
     onItemMouseDown: Ext.emptyFn,
     onItemMouseUp: Ext.emptyFn,
+    onItemFocus: Ext.emptyFn,
     onItemClick: Ext.emptyFn,
     onItemDblClick: Ext.emptyFn,
     onItemContextMenu: Ext.emptyFn,
     onItemKeyDown: Ext.emptyFn,
     onBeforeItemMouseDown: Ext.emptyFn,
     onBeforeItemMouseUp: Ext.emptyFn,
+    onBeforeItemFocus: Ext.emptyFn,
     onBeforeItemMouseEnter: Ext.emptyFn,
     onBeforeItemMouseLeave: Ext.emptyFn,
     onBeforeItemClick: Ext.emptyFn,
     onBeforeItemDblClick: Ext.emptyFn,
     onBeforeItemContextMenu: Ext.emptyFn,
     onBeforeItemKeyDown: Ext.emptyFn,
-    
+
     
     onContainerMouseDown: Ext.emptyFn,
     onContainerMouseUp: Ext.emptyFn,
@@ -66424,7 +69576,7 @@ Ext.define('Ext.view.View', {
     onBeforeContainerDblClick: Ext.emptyFn,
     onBeforeContainerContextMenu: Ext.emptyFn,
     onBeforeContainerKeyDown: Ext.emptyFn,
-    
+
     
     highlightItem: function(item) {
         var me = this;
@@ -66437,7 +69589,7 @@ Ext.define('Ext.view.View', {
     clearHighlight: function() {
         var me = this,
             highlighted = me.highlightedItem;
-            
+
         if (highlighted) {
             Ext.fly(highlighted).removeCls(me.overItemCls);
             delete me.highlightedItem;
@@ -66445,8 +69597,12 @@ Ext.define('Ext.view.View', {
     },
 
     refresh: function() {
-        this.clearHighlight();
-        this.callParent(arguments);
+        var me = this;
+        me.clearHighlight();
+        me.callParent(arguments);
+        if (!me.isFixedHeight()) {
+            me.doComponentLayout();
+        }
     }
 });
 
@@ -66555,14 +69711,14 @@ Ext.define('Ext.toolbar.TextItem', {
     requires: ['Ext.XTemplate'],
     alias: 'widget.tbtext',
     alternateClassName: 'Ext.Toolbar.TextItem',
-    
+
     
     text: '',
-    
+
     renderTpl: '{text}',
     
     baseCls: Ext.baseCSSPrefix + 'toolbar-text',
-    
+
     onRender : function() {
         Ext.apply(this.renderData, {
             text: this.text
@@ -66584,16 +69740,17 @@ Ext.define('Ext.toolbar.TextItem', {
 Ext.define('Ext.form.field.Trigger', {
     extend:'Ext.form.field.Text',
     alias: ['widget.triggerfield', 'widget.trigger'],
-    requires: ['Ext.core.DomHelper', 'Ext.util.ClickRepeater', 'Ext.layout.component.field.Trigger'],
+    requires: ['Ext.DomHelper', 'Ext.util.ClickRepeater', 'Ext.layout.component.field.Trigger'],
     alternateClassName: ['Ext.form.TriggerField', 'Ext.form.TwinTriggerField', 'Ext.form.Trigger'],
 
+    
     fieldSubTpl: [
         '<input id="{id}" type="{type}" ',
             '<tpl if="name">name="{name}" </tpl>',
             '<tpl if="size">size="{size}" </tpl>',
             '<tpl if="tabIdx">tabIndex="{tabIdx}" </tpl>',
             'class="{fieldCls} {typeCls}" autocomplete="off" />',
-        '<div class="{triggerWrapCls}" role="presentation">',
+        '<div id="{cmpId}-triggerWrap" class="{triggerWrapCls}" role="presentation">',
             '{triggerEl}',
             '<div class="{clearCls}" role="presentation"></div>',
         '</div>',
@@ -66668,13 +69825,12 @@ Ext.define('Ext.form.field.Trigger', {
         }
         triggerConfigs[i - 1].cls += ' ' + triggerBaseCls + '-last';
 
-        Ext.applyIf(me.renderSelectors, {
-            
-            triggerWrap: '.' + triggerWrapCls
-        });
+        
+        me.addChildEls('triggerWrap');
+
         Ext.applyIf(me.subTplData, {
             triggerWrapCls: triggerWrapCls,
-            triggerEl: Ext.core.DomHelper.markup(triggerConfigs),
+            triggerEl: Ext.DomHelper.markup(triggerConfigs),
             clearCls: me.clearCls
         });
 
@@ -66683,7 +69839,7 @@ Ext.define('Ext.form.field.Trigger', {
         
         me.triggerEl = Ext.select('.' + triggerBaseCls, true, me.triggerWrap.dom);
 
-        me.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc();
+        me.doc = Ext.getDoc();
         me.initTrigger();
     },
 
@@ -66700,6 +69856,7 @@ Ext.define('Ext.form.field.Trigger', {
     afterRender: function() {
         this.callParent();
         this.updateEditState();
+        this.triggerEl.unselectable();
     },
 
     updateEditState: function() {
@@ -66807,7 +69964,7 @@ Ext.define('Ext.form.field.Trigger', {
     
     onFocus: function() {
         var me = this;
-        this.callParent();
+        me.callParent();
         if (!me.mimicing) {
             me.bodyEl.addCls(me.wrapFocusCls);
             me.mimicing = true;
@@ -66977,7 +70134,7 @@ Ext.define('Ext.form.field.Picker', {
                 mousedown: collapseIf,
                 scope: me
             });
-
+            Ext.EventManager.onWindowResize(me.alignPicker, me);
             me.fireEvent('expand', me);
             me.onExpand();
         }
@@ -66988,28 +70145,36 @@ Ext.define('Ext.form.field.Picker', {
     
     alignPicker: function() {
         var me = this,
-            picker, isAbove,
-            aboveSfx = '-above';
+            picker;
 
-        if (this.isExpanded) {
+        if (me.isExpanded) {
             picker = me.getPicker();
             if (me.matchFieldWidth) {
                 
                 picker.setSize(me.bodyEl.getWidth(), picker.store && picker.store.getCount() ? null : 0);
             }
             if (picker.isFloating()) {
-                picker.alignTo(me.inputEl, me.pickerAlign, me.pickerOffset);
-
-                
-                
-                isAbove = picker.el.getY() < me.inputEl.getY();
-                me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls + aboveSfx);
-                picker.el[isAbove ? 'addCls' : 'removeCls'](picker.baseCls + aboveSfx);
+                me.doAlign();
             }
         }
     },
 
     
+    doAlign: function(){
+        var me = this,
+            picker = me.picker,
+            aboveSfx = '-above',
+            isAbove;
+
+        me.picker.alignTo(me.inputEl, me.pickerAlign, me.pickerOffset);
+        
+        
+        isAbove = picker.el.getY() < me.inputEl.getY();
+        me.bodyEl[isAbove ? 'addCls' : 'removeCls'](me.openCls + aboveSfx);
+        picker[isAbove ? 'addCls' : 'removeCls'](picker.baseCls + aboveSfx);
+    },
+
+    
     collapse: function() {
         if (this.isExpanded && !this.isDestroyed) {
             var me = this,
@@ -67030,7 +70195,7 @@ Ext.define('Ext.form.field.Picker', {
             
             doc.un('mousewheel', collapseIf, me);
             doc.un('mousedown', collapseIf, me);
-
+            Ext.EventManager.removeResizeListener(me.alignPicker, me);
             me.fireEvent('collapse', me);
             me.onCollapse();
         }
@@ -67079,8 +70244,15 @@ Ext.define('Ext.form.field.Picker', {
     },
 
     onDestroy : function(){
-        var me = this;
-        Ext.destroy(me.picker, me.keyNav);
+        var me = this,
+            picker = me.picker;
+
+        Ext.EventManager.removeResizeListener(me.alignPicker, me);
+        Ext.destroy(me.keyNav);
+        if (picker) {
+            delete picker.pickerField;
+            picker.destroy();
+        }
         me.callParent();
     }
 
@@ -67291,23 +70463,25 @@ Ext.define('Ext.form.field.Number', {
         var me = this,
             allowed;
 
-        this.callParent();
+        me.callParent();
 
         me.setMinValue(me.minValue);
         me.setMaxValue(me.maxValue);
 
         
-        allowed = me.baseChars + '';
-        if (me.allowDecimals) {
-            allowed += me.decimalSeparator;
-        }
-        if (me.minValue < 0) {
-            allowed += '-';
-        }
-        allowed = Ext.String.escapeRegex(allowed);
-        me.maskRe = new RegExp('[' + allowed + ']');
-        if (me.autoStripChars) {
-            me.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi');
+        if (me.disableKeyFilter !== true) {
+            allowed = me.baseChars + '';
+            if (me.allowDecimals) {
+                allowed += me.decimalSeparator;
+            }
+            if (me.minValue < 0) {
+                allowed += '-';
+            }
+            allowed = Ext.String.escapeRegex(allowed);
+            me.maskRe = new RegExp('[' + allowed + ']');
+            if (me.autoStripChars) {
+                me.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi');
+            }
         }
     },
 
@@ -67348,7 +70522,11 @@ Ext.define('Ext.form.field.Number', {
     },
 
     rawToValue: function(rawValue) {
-        return this.fixPrecision(this.parseValue(rawValue)) || rawValue || null;
+        var value = this.fixPrecision(this.parseValue(rawValue));
+        if (value === null) {
+            value = rawValue || null;
+        }
+        return  value;
     },
 
     valueToRaw: function(value) {
@@ -67435,35 +70613,47 @@ Ext.define('Ext.toolbar.Paging', {
     alternateClassName: 'Ext.PagingToolbar',
     requires: ['Ext.toolbar.TextItem', 'Ext.form.field.Number'],
     
+
     
     displayInfo: false,
+
     
     prependButtons: false,
+
     
     displayMsg : 'Displaying {0} - {1} of {2}',
+
     
     emptyMsg : 'No data to display',
+
     
     beforePageText : 'Page',
+
     
     afterPageText : 'of {0}',
+
     
     firstText : 'First Page',
+
     
     prevText : 'Previous Page',
+
     
     nextText : 'Next Page',
+
     
     lastText : 'Last Page',
+
     
     refreshText : 'Refresh',
+
     
     inputItemWidth : 30,
-    
+
     
     getPagingItems: function() {
         var me = this;
-        
+
         return [{
             itemId: 'first',
             tooltip: me.firstText,
@@ -67539,30 +70729,31 @@ Ext.define('Ext.toolbar.Paging', {
         var me = this,
             pagingItems = me.getPagingItems(),
             userItems   = me.items || me.buttons || [];
-            
+
         if (me.prependButtons) {
             me.items = userItems.concat(pagingItems);
         } else {
             me.items = pagingItems.concat(userItems);
         }
         delete me.buttons;
-        
+
         if (me.displayInfo) {
             me.items.push('->');
             me.items.push({xtype: 'tbtext', itemId: 'displayItem'});
         }
-        
+
         me.callParent();
-        
+
         me.addEvents(
             
             'change',
+
             
             'beforechange'
         );
         me.on('afterlayout', me.onLoad, me, {single: true});
 
-        me.bindStore(me.store, true);
+        me.bindStore(me.store || 'ext-empty-store', true);
     },
     
     updateInfo : function(){
@@ -67596,7 +70787,7 @@ Ext.define('Ext.toolbar.Paging', {
             currPage,
             pageCount,
             afterText;
-            
+
         if (!me.rendered) {
             return;
         }
@@ -67621,15 +70812,14 @@ Ext.define('Ext.toolbar.Paging', {
     getPageData : function(){
         var store = this.store,
             totalCount = store.getTotalCount();
-            
+
         return {
             total : totalCount,
             currentPage : store.currentPage,
             pageCount: Math.ceil(totalCount / store.pageSize),
-            
             fromRecord: ((store.currentPage - 1) * store.pageSize) + 1,
             toRecord: Math.min(store.currentPage * store.pageSize, totalCount)
-            
+
         };
     },
 
@@ -67645,7 +70835,7 @@ Ext.define('Ext.toolbar.Paging', {
     readPageFromInput : function(pageData){
         var v = this.child('#inputItem').getValue(),
             pageNum = parseInt(v, 10);
-            
+
         if (!v || isNaN(pageNum)) {
             this.child('#inputItem').setValue(pageData.currentPage);
             return false;
@@ -67665,17 +70855,17 @@ Ext.define('Ext.toolbar.Paging', {
 
     
     onPagingKeyDown : function(field, e){
-        var k = e.getKey(),
-            pageData = this.getPageData(),
+        var me = this,
+            k = e.getKey(),
+            pageData = me.getPageData(),
             increment = e.shiftKey ? 10 : 1,
-            pageNum,
-            me = this;
+            pageNum;
 
         if (k == e.RETURN) {
             e.stopEvent();
             pageNum = me.readPageFromInput(pageData);
             if (pageNum !== false) {
-                pageNum = Math.min(Math.max(1, pageNum), pageData.total);
+                pageNum = Math.min(Math.max(1, pageNum), pageData.pageCount);
                 if(me.fireEvent('beforechange', me, pageNum) !== false){
                     me.store.loadPage(pageNum);
                 }
@@ -67715,9 +70905,8 @@ Ext.define('Ext.toolbar.Paging', {
 
     
     moveFirst : function(){
-        var me = this;
-        if(me.fireEvent('beforechange', me, 1) !== false){
-            me.store.loadPage(1);
+        if (this.fireEvent('beforechange', this, 1) !== false){
+            this.store.loadPage(1);
         }
     },
 
@@ -67725,26 +70914,33 @@ Ext.define('Ext.toolbar.Paging', {
     movePrevious : function(){
         var me = this,
             prev = me.store.currentPage - 1;
-        
-        if(me.fireEvent('beforechange', me, prev) !== false){
-            me.store.previousPage();
+
+        if (prev > 0) {
+            if (me.fireEvent('beforechange', me, prev) !== false) {
+                me.store.previousPage();
+            }
         }
     },
 
     
     moveNext : function(){
-        var me = this;        
-        if(me.fireEvent('beforechange', me, me.store.currentPage + 1) !== false){
-            me.store.nextPage();
+        var me = this,
+            total = me.getPageData().pageCount,
+            next = me.store.currentPage + 1;
+
+        if (next <= total) {
+            if (me.fireEvent('beforechange', me, next) !== false) {
+                me.store.nextPage();
+            }
         }
     },
 
     
     moveLast : function(){
-        var me = this, 
-            last = this.getPageData().pageCount;
-        
-        if(me.fireEvent('beforechange', me, last) !== false){
+        var me = this,
+            last = me.getPageData().pageCount;
+
+        if (me.fireEvent('beforechange', me, last) !== false) {
             me.store.loadPage(last);
         }
     },
@@ -67753,8 +70949,8 @@ Ext.define('Ext.toolbar.Paging', {
     doRefresh : function(){
         var me = this,
             current = me.store.currentPage;
-        
-        if(me.fireEvent('beforechange', me, current) !== false){
+
+        if (me.fireEvent('beforechange', me, current) !== false) {
             me.store.loadPage(current);
         }
     },
@@ -67762,10 +70958,10 @@ Ext.define('Ext.toolbar.Paging', {
     
     bindStore : function(store, initial){
         var me = this;
-        
+
         if (!initial && me.store) {
             if(store !== me.store && me.store.autoDestroy){
-                me.store.destroy();
+                me.store.destroyStore();
             }else{
                 me.store.un('beforeload', me.beforeLoad, me);
                 me.store.un('load', me.onLoad, me);
@@ -67819,6 +71015,7 @@ Ext.define('Ext.view.BoundList', {
     
     autoScroll: true,
     baseCls: Ext.baseCSSPrefix + 'boundlist',
+    itemCls: Ext.baseCSSPrefix + 'boundlist-item',
     listItemCls: '',
     shadow: false,
     trackOver: true,
@@ -67828,13 +71025,13 @@ Ext.define('Ext.view.BoundList', {
 
     componentLayout: 'boundlist',
 
-    renderTpl: ['<div class="list-ct"></div>'],
+    renderTpl: ['<div id="{id}-listEl" class="list-ct"></div>'],
 
     initComponent: function() {
         var me = this,
             baseCls = me.baseCls,
-            itemCls = baseCls + '-item';
-        me.itemCls = itemCls;
+            itemCls = me.itemCls;
+            
         me.selectedItemCls = baseCls + '-selected';
         me.overItemCls = baseCls + '-item-over';
         me.itemSelector = "." + itemCls;
@@ -67843,13 +71040,17 @@ Ext.define('Ext.view.BoundList', {
             me.addCls(baseCls + '-floating');
         }
 
-        
-        
-        me.tpl = Ext.create('Ext.XTemplate', 
-            '<ul><tpl for=".">',
-                '<li role="option" class="' + itemCls + '">' + me.getInnerTpl(me.displayField) + '</li>',
-            '</tpl></ul>'
-        );
+        if (!me.tpl) {
+            
+            
+            me.tpl = Ext.create('Ext.XTemplate',
+                '<ul><tpl for=".">',
+                    '<li role="option" class="' + itemCls + '">' + me.getInnerTpl(me.displayField) + '</li>',
+                '</tpl></ul>'
+            );
+        } else if (Ext.isString(me.tpl)) {
+            me.tpl = Ext.create('Ext.XTemplate', me.tpl);
+        }
 
         if (me.pageSize) {
             me.pagingToolbar = me.createPagingToolbar();
@@ -67857,9 +71058,7 @@ Ext.define('Ext.view.BoundList', {
 
         me.callParent();
 
-        Ext.applyIf(me.renderSelectors, {
-            listEl: '.list-ct'
-        });
+        me.addChildEls('listEl');
     },
 
     createPagingToolbar: function() {
@@ -67905,14 +71104,14 @@ Ext.define('Ext.view.BoundList', {
             me.refreshed--;
         }
     },
-    
+
     initAria: function() {
         this.callParent();
-        
+
         var selModel = this.getSelectionModel(),
             mode     = selModel.getSelectionMode(),
             actionEl = this.getActionEl();
-        
+
         
         if (mode !== 'SINGLE') {
             actionEl.dom.setAttribute('aria-multiselectable', true);
@@ -68015,6 +71214,40 @@ Ext.define('Ext.form.field.ComboBox', {
     triggerCls: Ext.baseCSSPrefix + 'form-arrow-trigger',
 
     
+    hiddenDataCls: Ext.baseCSSPrefix + 'hide-display ' + Ext.baseCSSPrefix + 'form-data-hidden',
+
+    
+    fieldSubTpl: [
+        '<div class="{hiddenDataCls}" role="presentation"></div>',
+        '<input id="{id}" type="{type}" ',
+            '<tpl if="size">size="{size}" </tpl>',
+            '<tpl if="tabIdx">tabIndex="{tabIdx}" </tpl>',
+            'class="{fieldCls} {typeCls}" autocomplete="off" />',
+        '<div id="{cmpId}-triggerWrap" class="{triggerWrapCls}" role="presentation">',
+            '{triggerEl}',
+            '<div class="{clearCls}" role="presentation"></div>',
+        '</div>',
+        {
+            compiled: true,
+            disableFormats: true
+        }
+    ],
+
+    getSubTplData: function(){
+        var me = this;
+        Ext.applyIf(me.subTplData, {
+            hiddenDataCls: me.hiddenDataCls
+        });
+        return me.callParent(arguments);
+    },
+
+    afterRender: function(){
+        var me = this;
+        me.callParent(arguments);
+        me.setHiddenValue(me.value);
+    },
+
+    
 
     
     multiSelect: false,
@@ -68091,31 +71324,27 @@ Ext.define('Ext.form.field.ComboBox', {
             transform = me.transform,
             transformSelect, isLocalMode;
 
-        if (!store && !transform) {
-            Ext.Error.raise('Either a valid store, or a HTML select to transform, must be configured on the combo.');
-        }
-        if (me.typeAhead && me.multiSelect) {
-            Ext.Error.raise('typeAhead and multiSelect are mutually exclusive options -- please remove one of them.');
-        }
-        if (me.typeAhead && !me.editable) {
-            Ext.Error.raise('If typeAhead is enabled the combo must be editable: true -- please change one of those settings.');
-        }
-        if (me.selectOnFocus && !me.editable) {
-            Ext.Error.raise('If selectOnFocus is enabled the combo must be editable: true -- please change one of those settings.');
-        }
+        Ext.applyIf(me.renderSelectors, {
+            hiddenDataEl: '.' + me.hiddenDataCls.split(' ').join('.')
+        });
+        
 
         this.addEvents(
             
+            'beforequery',
 
             
-            'beforequery',
+            'select',
 
             
-            'select'
+            'beforeselect',
+
+            
+            'beforedeselect'
         );
 
         
-        if (!store && transform) {
+        if (transform) {
             transformSelect = Ext.getDom(transform);
             if (transformSelect) {
                 store = Ext.Array.map(Ext.Array.from(transformSelect.options), function(option) {
@@ -68130,7 +71359,7 @@ Ext.define('Ext.form.field.ComboBox', {
             }
         }
 
-        me.bindStore(store, true);
+        me.bindStore(store || 'ext-empty-store', true);
         store = me.store;
         if (store.autoCreated) {
             me.queryMode = 'local';
@@ -68156,7 +71385,7 @@ Ext.define('Ext.form.field.ComboBox', {
         if (!me.displayTpl) {
             me.displayTpl = Ext.create('Ext.XTemplate',
                 '<tpl for=".">' +
-                    '{[typeof values === "string" ? values : values.' + me.displayField + ']}' +
+                    '{[typeof values === "string" ? values : values["' + me.displayField + '"]]}' +
                     '<tpl if="xindex < xcount">' + me.delimiter + '</tpl>' +
                 '</tpl>'
             );
@@ -68181,14 +71410,14 @@ Ext.define('Ext.form.field.ComboBox', {
         }
     },
 
+    
+    getStore : function(){
+        return this.store;
+    },
+
     beforeBlur: function() {
-        var me = this;
-        me.doQueryTask.cancel();
-        if (me.forceSelection) {
-            me.assertValue();
-        } else {
-            me.collapse();
-        }
+        this.doQueryTask.cancel();
+        this.assertValue();
     },
 
     
@@ -68197,20 +71426,22 @@ Ext.define('Ext.form.field.ComboBox', {
             value = me.getRawValue(),
             rec;
 
-        if (me.multiSelect) {
-            
-            
-            if (value !== me.getDisplayValue()) {
-                me.setValue(me.lastSelection);
-            }
-        } else {
-            
-            
-            rec = me.findRecordByDisplay(value);
-            if (rec) {
-                me.select(rec);
+        if (me.forceSelection) {
+            if (me.multiSelect) {
+                
+                
+                if (value !== me.getDisplayValue()) {
+                    me.setValue(me.lastSelection);
+                }
             } else {
-                me.setValue(me.lastSelection);
+                
+                
+                rec = me.findRecordByDisplay(value);
+                if (rec) {
+                    me.select(rec);
+                } else {
+                    me.setValue(me.lastSelection);
+                }
             }
         }
         me.collapse();
@@ -68251,7 +71482,7 @@ Ext.define('Ext.form.field.ComboBox', {
         
         if (oldStore && !initial) {
             if (oldStore !== store && oldStore.autoDestroy) {
-                oldStore.destroy();
+                oldStore.destroyStore();
             } else {
                 oldStore.un({
                     scope: me,
@@ -68288,19 +71519,38 @@ Ext.define('Ext.form.field.ComboBox', {
         var me = this,
             value = me.value;
 
-        me.syncSelection();
-        if (me.picker && !me.picker.getSelectionModel().hasSelection()) {
-            me.doAutoSelect();
+        
+        if (me.rawQuery) {
+            me.rawQuery = false;
+            me.syncSelection();
+            if (me.picker && !me.picker.getSelectionModel().hasSelection()) {
+                me.doAutoSelect();
+            }
+        }
+        
+        else {
+            
+            if (me.value) {
+                me.setValue(me.value);
+            } else {
+                
+                
+                if (me.store.getCount()) {
+                    me.doAutoSelect();
+                } else {
+                    me.setValue('');
+                }
+            }
         }
     },
 
     
     doRawQuery: function() {
-        this.doQuery(this.getRawValue());
+        this.doQuery(this.getRawValue(), false, true);
     },
 
     
-    doQuery: function(queryString, forceAll) {
+    doQuery: function(queryString, forceAll, rawQuery) {
         queryString = queryString || '';
 
         
@@ -68331,15 +71581,30 @@ Ext.define('Ext.form.field.ComboBox', {
             
             if (!me.queryCaching || me.lastQuery !== queryString) {
                 me.lastQuery = queryString;
-                store.clearFilter(!forceAll);
+
                 if (isLocalMode) {
-                    if (!forceAll) {
+                    
+                    if (forceAll) {
+                        store.clearFilter();
+                    } else {
+                        
+                        store.clearFilter(true);
                         store.filter(me.displayField, queryString);
                     }
                 } else {
-                    store.load({
-                        params: me.getParams(queryString)
-                    });
+                    
+                    me.rawQuery = rawQuery;
+
+                    
+                    
+                    if (me.pageSize) {
+                        
+                        me.loadPage(1);
+                    } else {
+                        store.load({
+                            params: me.getParams(queryString)
+                        });
+                    }
                 }
             }
 
@@ -68360,16 +71625,27 @@ Ext.define('Ext.form.field.ComboBox', {
         return true;
     },
 
+    loadPage: function(pageNum){
+        this.store.loadPage(pageNum, {
+            params: this.getParams(this.lastQuery)
+        });
+    },
+
+    onPageChange: function(toolbar, newPage){
+        
+        this.loadPage(newPage);
+        return false;
+    },
+
     
     getParams: function(queryString) {
-        var p = {},
-            pageSize = this.pageSize;
-        p[this.queryParam] = queryString;
-        if (pageSize) {
-            p.start = 0;
-            p.limit = pageSize;
+        var params = {},
+            param = this.queryParam;
+
+        if (param) {
+            params[param] = queryString;
         }
-        return p;
+        return params;
     },
 
     
@@ -68407,7 +71683,7 @@ Ext.define('Ext.form.field.ComboBox', {
                 if (me.triggerAction === 'all') {
                     me.doQuery(me.allQuery, true);
                 } else {
-                    me.doQuery(me.getRawValue());
+                    me.doQuery(me.getRawValue(), false, true);
                 }
             }
             me.inputEl.focus();
@@ -68430,6 +71706,10 @@ Ext.define('Ext.form.field.ComboBox', {
                 me.doQueryTask.delay(me.queryDelay);
             }
         }
+
+        if (me.enableKeyEvents) {
+            me.callParent(arguments);
+        }
     },
 
     initEvents: function() {
@@ -68437,7 +71717,14 @@ Ext.define('Ext.form.field.ComboBox', {
         me.callParent();
 
         
-        me.mon(me.inputEl, 'keyup', me.onKeyUp, me);
+        if (!me.enableKeyEvents) {
+            me.mon(me.inputEl, 'keyup', me.onKeyUp, me);
+        }
+    },
+    
+    onDestroy: function(){
+        this.bindStore(null);
+        this.callParent();    
     },
 
     createPicker: function() {
@@ -68445,6 +71732,7 @@ Ext.define('Ext.form.field.ComboBox', {
             picker,
             menuCls = Ext.baseCSSPrefix + 'menu',
             opts = Ext.apply({
+                pickerField: me,
                 selModel: {
                     mode: me.multiSelect ? 'SIMPLE' : 'SINGLE'
                 },
@@ -68455,10 +71743,14 @@ Ext.define('Ext.form.field.ComboBox', {
                 store: me.store,
                 displayField: me.displayField,
                 focusOnToFront: false,
-                pageSize: me.pageSize
+                pageSize: me.pageSize,
+                tpl: me.tpl
             }, me.listConfig, me.defaultListConfig);
 
         picker = me.picker = Ext.create('Ext.view.BoundList', opts);
+        if (me.pageSize) {
+            picker.pagingToolbar.on('beforechange', me.onPageChange, me);
+        }
 
         me.mon(picker, {
             itemclick: me.onItemClick,
@@ -68467,43 +71759,75 @@ Ext.define('Ext.form.field.ComboBox', {
         });
 
         me.mon(picker.getSelectionModel(), {
-            selectionChange: me.onListSelectionChange,
+            'beforeselect': me.onBeforeSelect,
+            'beforedeselect': me.onBeforeDeselect,
+            'selectionchange': me.onListSelectionChange,
             scope: me
         });
 
         return picker;
     },
 
+    alignPicker: function(){
+        var me = this,
+            picker = me.picker,
+            heightAbove = me.getPosition()[1] - Ext.getBody().getScroll().top,
+            heightBelow = Ext.Element.getViewHeight() - heightAbove - me.getHeight(),
+            space = Math.max(heightAbove, heightBelow);
+
+        me.callParent();
+        if (picker.getHeight() > space) {
+            picker.setHeight(space - 5); 
+            me.doAlign();
+        }
+    },
+
     onListRefresh: function() {
         this.alignPicker();
         this.syncSelection();
     },
-    
+
     onItemClick: function(picker, record){
         
         var me = this,
             lastSelection = me.lastSelection,
             valueField = me.valueField,
             selected;
-        
+
         if (!me.multiSelect && lastSelection) {
             selected = lastSelection[0];
-            if (record.get(valueField) === selected.get(valueField)) {
+            if (selected && (record.get(valueField) === selected.get(valueField))) {
+                
+                me.displayTplData = [record.data];
+                me.setRawValue(me.getDisplayValue());
                 me.collapse();
             }
-        }   
+        }
+    },
+
+    onBeforeSelect: function(list, record) {
+        return this.fireEvent('beforeselect', this, record, record.index);
+    },
+
+    onBeforeDeselect: function(list, record) {
+        return this.fireEvent('beforedeselect', this, record, record.index);
     },
 
     onListSelectionChange: function(list, selectedRecords) {
-        var me = this;
+        var me = this,
+            isMulti = me.multiSelect,
+            hasRecords = selectedRecords.length > 0;
         
         
         if (!me.ignoreSelection && me.isExpanded) {
-            if (!me.multiSelect) {
+            if (!isMulti) {
                 Ext.defer(me.collapse, 1, me);
             }
-            me.setValue(selectedRecords, false);
-            if (selectedRecords.length > 0) {
+            
+            if (isMulti || hasRecords) {
+                me.setValue(selectedRecords, false);
+            }
+            if (hasRecords) {
                 me.fireEvent('select', me, selectedRecords);
             }
             me.inputEl.focus();
@@ -68565,9 +71889,13 @@ Ext.define('Ext.form.field.ComboBox', {
             idx = ds.findExact(field, value);
         return idx !== -1 ? ds.getAt(idx) : false;
     },
+
+    
     findRecordByValue: function(value) {
         return this.findRecord(this.valueField, value);
     },
+
+    
     findRecordByDisplay: function(value) {
         return this.findRecord(this.displayField, value);
     },
@@ -68585,6 +71913,7 @@ Ext.define('Ext.form.field.ComboBox', {
         if (me.store.loading) {
             
             me.value = value;
+            me.setHiddenValue(me.value);
             return me;
         }
 
@@ -68607,14 +71936,19 @@ Ext.define('Ext.form.field.ComboBox', {
             
             else {
                 
-                if (Ext.isDefined(valueNotFoundText)) {
+                if (!me.forceSelection) {
+                    displayTplData.push(value[i]);
+                    processedValue.push(value[i]);
+                }
+                
+                else if (Ext.isDefined(valueNotFoundText)) {
                     displayTplData.push(valueNotFoundText);
                 }
-                processedValue.push(value[i]);
             }
         }
 
         
+        me.setHiddenValue(processedValue);
         me.value = me.multiSelect ? processedValue : processedValue[0];
         if (!Ext.isDefined(me.value)) {
             me.value = null;
@@ -68639,6 +71973,37 @@ Ext.define('Ext.form.field.ComboBox', {
     },
 
     
+    setHiddenValue: function(values){
+        var me = this, i;
+        if (!me.hiddenDataEl) {
+            return;
+        }
+        values = Ext.Array.from(values);
+        var dom = me.hiddenDataEl.dom,
+            childNodes = dom.childNodes,
+            input = childNodes[0],
+            valueCount = values.length,
+            childrenCount = childNodes.length;
+        
+        if (!input && valueCount > 0) {
+            me.hiddenDataEl.update(Ext.DomHelper.markup({tag:'input', type:'hidden', name:me.name}));
+            childrenCount = 1;
+            input = dom.firstChild;
+        }
+        while (childrenCount > valueCount) {
+            dom.removeChild(childNodes[0]);
+            -- childrenCount;
+        }
+        while (childrenCount < valueCount) {
+            dom.appendChild(input.cloneNode(true));
+            ++ childrenCount;
+        }
+        for (i = 0; i < valueCount; i++) {
+            childNodes[i].value = values[i];
+        }
+    },
+
+    
     getDisplayValue: function() {
         return this.displayTpl.apply(this.displayTplData);
     },
@@ -68730,7 +72095,7 @@ Ext.define('Ext.picker.Month', {
     alternateClassName: 'Ext.MonthPicker',
 
     renderTpl: [
-        '<div class="{baseCls}-body">',
+        '<div id="{id}-bodyEl" class="{baseCls}-body">',
           '<div class="{baseCls}-months">',
               '<tpl for="months">',
                   '<div class="{parent.baseCls}-item {parent.baseCls}-month"><a href="#" hidefocus="on">{.}</a></div>',
@@ -68738,17 +72103,17 @@ Ext.define('Ext.picker.Month', {
           '</div>',
           '<div class="{baseCls}-years">',
               '<div class="{baseCls}-yearnav">',
-                  '<button class="{baseCls}-yearnav-prev"></button>',
-                  '<button class="{baseCls}-yearnav-next"></button>',
+                  '<button id="{id}-prevEl" class="{baseCls}-yearnav-prev"></button>',
+                  '<button id="{id}-nextEl" class="{baseCls}-yearnav-next"></button>',
               '</div>',
               '<tpl for="years">',
                   '<div class="{parent.baseCls}-item {parent.baseCls}-year"><a href="#" hidefocus="on">{.}</a></div>',
               '</tpl>',
           '</div>',
+          '<div class="' + Ext.baseCSSPrefix + 'clear"></div>',
         '</div>',
-        '<div class="' + Ext.baseCSSPrefix + 'clear"></div>',
         '<tpl if="showButtons">',
-          '<div class="{baseCls}-buttons"></div>',
+          '<div id="{id}-buttonsEl" class="{baseCls}-buttons"></div>',
         '</tpl>'
     ],
 
@@ -68767,11 +72132,10 @@ Ext.define('Ext.picker.Month', {
     
 
     
+    width: 178,
 
-    width: 175,
-
-    height: 195,
-
+    
+    smallCls: Ext.baseCSSPrefix + 'monthpicker-small',
 
     
     totalYears: 10,
@@ -68805,7 +72169,9 @@ Ext.define('Ext.picker.Month', {
             
             'yeardblclick'
         );
-
+        if (me.small) {
+            me.addCls(me.smallCls);
+        }
         me.setValue(me.value);
         me.activeYear = me.getYear(new Date().getFullYear() - 4, -4);
         this.callParent();
@@ -68829,13 +72195,9 @@ Ext.define('Ext.picker.Month', {
             showButtons: me.showButtons
         });
 
-        Ext.apply(me.renderSelectors, {
-            bodyEl: '.' + me.baseCls + '-body',
-            prevEl: '.' + me.baseCls + '-yearnav-prev',
-            nextEl: '.' + me.baseCls + '-yearnav-next',
-            buttonsEl: '.' + me.baseCls + '-buttons'
-        });
-        this.callParent([ct, position]);
+        me.addChildEls('bodyEl', 'prevEl', 'nextEl', 'buttonsEl');
+
+        me.callParent(arguments);
     },
 
     
@@ -69041,8 +72403,8 @@ Ext.define('Ext.picker.Month', {
     beforeDestroy: function(){
         var me = this;
         me.years = me.months = null;
-        Ext.destroyMembers('backRepeater', 'nextRepeater', 'okBtn', 'cancelBtn');
-        this.callParent();
+        Ext.destroyMembers(me, 'backRepeater', 'nextRepeater', 'okBtn', 'cancelBtn');
+        me.callParent();
     }
 });
 
@@ -69065,11 +72427,11 @@ Ext.define('Ext.picker.Date', {
     renderTpl: [
         '<div class="{cls}" id="{id}" role="grid" title="{ariaTitle} {value:this.longDay}">',
             '<div role="presentation" class="{baseCls}-header">',
-                '<div class="{baseCls}-prev"><a href="#" role="button" title="{prevText}"></a></div>',
-                '<div class="{baseCls}-month"></div>',
-                '<div class="{baseCls}-next"><a href="#" role="button" title="{nextText}"></a></div>',
+                '<div class="{baseCls}-prev"><a id="{id}-prevEl" href="#" role="button" title="{prevText}"></a></div>',
+                '<div class="{baseCls}-month" id="{id}-middleBtnEl"></div>',
+                '<div class="{baseCls}-next"><a id="{id}-nextEl" href="#" role="button" title="{nextText}"></a></div>',
             '</div>',
-            '<table class="{baseCls}-inner" cellspacing="0" role="presentation">',
+            '<table id="{id}-eventEl" class="{baseCls}-inner" cellspacing="0" role="presentation">',
                 '<thead role="presentation"><tr role="presentation">',
                     '<tpl for="dayNames">',
                         '<th role="columnheader" title="{.}"><span>{.:this.firstInitial}</span></th>',
@@ -69087,7 +72449,7 @@ Ext.define('Ext.picker.Date', {
                 '</tr></tbody>',
             '</table>',
             '<tpl if="showToday">',
-                '<div role="presentation" class="{baseCls}-footer"></div>',
+                '<div id="{id}-footerEl" role="presentation" class="{baseCls}-footer"></div>',
             '</tpl>',
         '</div>',
         {
@@ -69108,41 +72470,62 @@ Ext.define('Ext.picker.Date', {
     ],
 
     ariaTitle: 'Date Picker',
+
     
     todayText : 'Today',
+
     
+
     
+
     
     todayTip : '{0} (Spacebar)',
+
     
     minText : 'This date is before the minimum date',
+
     
     maxText : 'This date is after the maximum date',
+
     
+
     
     disabledDaysText : 'Disabled',
+
     
     disabledDatesText : 'Disabled',
+
     
+
     
+
     
     nextText : 'Next Month (Control+Right)',
+
     
     prevText : 'Previous Month (Control+Left)',
+
     
     monthYearText : 'Choose a month (Control+Up/Down to move years)',
+
     
     startDay : 0,
+
     
     showToday : true,
+
     
+
     
+
     
+
     
+
     
 
     
-    disableAnim: true,
+    disableAnim: false,
 
     
     baseCls: Ext.baseCSSPrefix + 'datepicker',
@@ -69205,8 +72588,7 @@ Ext.define('Ext.picker.Date', {
             today = Ext.Date.format(new Date(), me.format);
 
         Ext.applyIf(me, {
-            renderData: {},
-            renderSelectors: {}
+            renderData: {}
         });
 
         Ext.apply(me.renderData, {
@@ -69220,13 +72602,7 @@ Ext.define('Ext.picker.Date', {
         });
         me.getTpl('renderTpl').longDayFormat = me.longDayFormat;
 
-        Ext.apply(me.renderSelectors, {
-            eventEl: 'table.' + me.baseCls + '-inner',
-            prevEl: '.' + me.baseCls + '-prev a',
-            nextEl: '.' + me.baseCls + '-next a',
-            middleBtnEl: '.' + me.baseCls + '-month',
-            footerEl: '.' + me.baseCls + '-footer'
-        });
+        me.addChildEls('eventEl', 'prevEl', 'nextEl', 'middleBtnEl', 'footerEl');
 
         this.callParent(arguments);
         me.el.unselectable();
@@ -69422,65 +72798,68 @@ Ext.define('Ext.picker.Date', {
 
     
     getActive: function(){
-        return this.activeDate || me.value;
+        return this.activeDate || this.value;
     },
 
     
     runAnimation: function(isHide){
-        var options = {
-                target: this.monthPicker,
-                duration: 200
+        var picker = this.monthPicker,
+            options = {
+                duration: 200,
+                callback: function(){
+                    if (isHide) {
+                        picker.hide();
+                    } else {
+                        picker.show();
+                    }
+                }
             };
 
-        Ext.fx.Manager.run();
         if (isHide) {
-            
+            picker.el.slideOut('t', options);
         } else {
-            
+            picker.el.slideIn('t', options);
         }
-        Ext.create('Ext.fx.Anim', options);
     },
 
     
-    hideMonthPicker : function(){
+    hideMonthPicker : function(animate){
         var me = this,
             picker = me.monthPicker;
 
         if (picker) {
-            if (me.disableAnim) {
-                picker.hide();
+            if (me.shouldAnimate(animate)) {
+                me.runAnimation(true);
             } else {
-                this.runAnimation(true);
+                picker.hide();
             }
         }
         return me;
     },
 
     
-    showMonthPicker : function(){
-
+    showMonthPicker : function(animate){
         var me = this,
-            picker,
-            size,
-            top,
-            left;
-
-
+            picker;
+        
         if (me.rendered && !me.disabled) {
-            size = me.getSize();
             picker = me.createMonthPicker();
-            picker.show();
-            picker.setSize(size);
             picker.setValue(me.getActive());
-
-            if (me.disableAnim) {
-                picker.setPosition(-1, -1);
-            } else {
+            picker.setSize(me.getSize());
+            picker.setPosition(-1, -1);
+            if (me.shouldAnimate(animate)) {
                 me.runAnimation(false);
+            } else {
+                picker.show();
             }
         }
         return me;
     },
+    
+    
+    shouldAnimate: function(animate){
+        return Ext.isDefined(animate) ? animate : !this.disableAnim;
+    },
 
     
     createMonthPicker: function(){
@@ -69492,6 +72871,7 @@ Ext.define('Ext.picker.Date', {
                 renderTo: me.el,
                 floating: true,
                 shadow: false,
+                small: me.showToday === false,
                 listeners: {
                     scope: me,
                     cancelclick: me.onCancelClick,
@@ -69500,8 +72880,11 @@ Ext.define('Ext.picker.Date', {
                     monthdblclick: me.onOkClick
                 }
             });
-
-            me.on('beforehide', me.hideMonthPicker, me);
+            if (!me.disableAnim) {
+                
+                picker.el.setStyle('display', 'none');
+            }
+            me.on('beforehide', Ext.Function.bind(me.hideMonthPicker, me, [false]));
         }
         return picker;
     },
@@ -69774,6 +73157,7 @@ Ext.define('Ext.picker.Date', {
             delete me.textNodes;
             delete me.cells.elements;
         }
+        me.callParent();
     },
 
     
@@ -69825,7 +73209,7 @@ Ext.define('Ext.form.field.Date', {
     
     
     
-    
+
     
 
     
@@ -69837,7 +73221,7 @@ Ext.define('Ext.form.field.Date', {
     matchFieldWidth: false,
     
     startDay: 0,
-    
+
     initComponent : function(){
         var me = this,
             isString = Ext.isString,
@@ -69890,7 +73274,7 @@ Ext.define('Ext.form.field.Date', {
     setDisabledDates : function(dd){
         var me = this,
             picker = me.picker;
-            
+
         me.disabledDates = dd;
         me.initDisabledDays();
         if (picker) {
@@ -69901,7 +73285,7 @@ Ext.define('Ext.form.field.Date', {
     
     setDisabledDays : function(dd){
         var picker = this.picker;
-            
+
         this.disabledDays = dd;
         if (picker) {
             picker.setDisabledDays(dd);
@@ -69913,7 +73297,7 @@ Ext.define('Ext.form.field.Date', {
         var me = this,
             picker = me.picker,
             minValue = (Ext.isString(dt) ? me.parseDate(dt) : dt);
-            
+
         me.minValue = minValue;
         if (picker) {
             picker.minText = Ext.String.format(me.minText, me.formatDate(me.minValue));
@@ -69926,7 +73310,7 @@ Ext.define('Ext.form.field.Date', {
         var me = this,
             picker = me.picker,
             maxValue = (Ext.isString(dt) ? me.parseDate(dt) : dt);
-            
+
         me.maxValue = maxValue;
         if (picker) {
             picker.maxText = Ext.String.format(me.maxText, me.formatDate(me.maxValue));
@@ -70008,7 +73392,7 @@ Ext.define('Ext.form.field.Date', {
             utilDate = Ext.Date,
             parsedDate,
             result = null;
-            
+
         if (utilDate.formatContainsHourInfo(format)) {
             
             result = utilDate.parse(value, format);
@@ -70021,14 +73405,13 @@ Ext.define('Ext.form.field.Date', {
         }
         return result;
     },
-    
+
     
     getSubmitValue: function() {
-        var me = this,
-            format = me.submitFormat || me.format,
-            value = me.getValue();
-            
-        return value ? Ext.Date.format(value, format) : null;
+        var format = this.submitFormat || this.format,
+            value = this.getValue();
+
+        return value ? Ext.Date.format(value, format) : '';
     },
 
     
@@ -70064,7 +73447,8 @@ Ext.define('Ext.form.field.Date', {
             format = Ext.String.format;
 
         return Ext.create('Ext.picker.Date', {
-            ownerCt: this.ownerCt,
+            pickerField: me,
+            ownerCt: me.ownerCt,
             renderTo: document.body,
             floating: true,
             hidden: true,
@@ -70093,16 +73477,17 @@ Ext.define('Ext.form.field.Date', {
     },
 
     onSelect: function(m, d) {
-        this.setValue(d);
-        this.fireEvent('select', this, d);
-        this.collapse();
+        var me = this;
+
+        me.setValue(d);
+        me.fireEvent('select', me, d);
+        me.collapse();
     },
 
     
     onExpand: function() {
-        var me = this,
-            value = me.getValue();
-        me.picker.setValue(value instanceof Date ? value : new Date());
+        var value = this.getValue();
+        this.picker.setValue(Ext.isDate(value) ? value : new Date());
     },
 
     
@@ -70112,9 +73497,16 @@ Ext.define('Ext.form.field.Date', {
 
     
     beforeBlur : function(){
-        var v = this.parseDate(this.getRawValue());
-        if(v){
-            this.setValue(v);
+        var me = this,
+            v = me.parseDate(me.getRawValue()),
+            focusTask = me.focusTask;
+
+        if (focusTask) {
+            focusTask.cancel();
+        }
+
+        if (v) {
+            me.setValue(v);
         }
     }
 
@@ -70212,9 +73604,10 @@ Ext.define("Ext.form.field.File", {
     
     fieldBodyCls: Ext.baseCSSPrefix + 'form-file-wrap',
 
-
     
     readOnly: true,
+
+    
     componentLayout: 'filefield',
 
     
@@ -70244,11 +73637,11 @@ Ext.define("Ext.form.field.File", {
     createButton: function() {
         var me = this;
         me.button = Ext.widget('button', Ext.apply({
+            ui: me.ui,
             renderTo: me.bodyEl,
             text: me.buttonText,
             cls: Ext.baseCSSPrefix + 'form-file-btn',
             preventDefault: false,
-            ownerCt: me,
             style: me.buttonOnly ? '' : 'margin-left:' + me.buttonMargin + 'px'
         }, me.buttonConfig));
     },
@@ -70275,9 +73668,13 @@ Ext.define("Ext.form.field.File", {
     setValue: Ext.emptyFn,
 
     reset : function(){
-        this.fileInputEl.remove();
-        this.createFileInput();
-        this.callParent();
+        var me = this;
+        if (me.rendered) {
+            me.fileInputEl.remove();
+            me.createFileInput();
+            me.inputEl.dom.value = '';
+        }
+        me.callParent();
     },
 
     onDisable: function(){
@@ -70336,6 +73733,11 @@ Ext.define('Ext.form.field.Hidden', {
         this.formItemCls += '-hidden';
         this.callParent();    
     },
+    
+    
+    isEqual: function(value1, value2) {
+        return this.isEqualAsString(value1, value2);
+    },
 
     
     initEvents: Ext.emptyFn,
@@ -70354,16 +73756,16 @@ Ext.define('Ext.picker.Color', {
     requires: 'Ext.XTemplate',
     alias: 'widget.colorpicker',
     alternateClassName: 'Ext.ColorPalette',
-    
+
     
     componentCls : Ext.baseCSSPrefix + 'color-picker',
-    
+
     
     selectedCls: Ext.baseCSSPrefix + 'color-picker-selected',
-    
+
     
     value : null,
-    
+
     
     clickEvent :'click',
 
@@ -70380,20 +73782,24 @@ Ext.define('Ext.picker.Color', {
     ],
 
     
+
     
-    
+
     colorRe: /(?:^|\s)color-(.{6})(?:\s|$)/,
     
-    constructor: function() {
-        this.renderTpl = Ext.create('Ext.XTemplate', '<tpl for="colors"><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on">&#160;</span></em></a></tpl>');
-        this.callParent(arguments);
-    },
-    
+    renderTpl: [
+        '<tpl for="colors">',
+            '<a href="#" class="color-{.}" hidefocus="on">',
+                '<em><span style="background:#{.}" unselectable="on">&#160;</span></em>',
+            '</a>',
+        '</tpl>'
+    ],
+
     
     initComponent : function(){
         var me = this;
-        
-        this.callParent(arguments);
+
+        me.callParent(arguments);
         me.addEvents(
             
             'select'
@@ -70409,12 +73815,12 @@ Ext.define('Ext.picker.Color', {
     onRender : function(container, position){
         var me = this,
             clickEvent = me.clickEvent;
-            
+
         Ext.apply(me.renderData, {
             itemCls: me.itemCls,
-            colors: me.colors    
+            colors: me.colors
         });
-        this.callParent(arguments);
+        me.callParent(arguments);
 
         me.mon(me.el, clickEvent, me.handleClick, me, {delegate: 'a'});
         
@@ -70427,8 +73833,8 @@ Ext.define('Ext.picker.Color', {
     afterRender : function(){
         var me = this,
             value;
-            
-        this.callParent(arguments);
+
+        me.callParent(arguments);
         if (me.value) {
             value = me.value;
             me.value = null;
@@ -70440,7 +73846,7 @@ Ext.define('Ext.picker.Color', {
     handleClick : function(event, target){
         var me = this,
             color;
-            
+
         event.stopEvent();
         if (!me.disabled) {
             color = target.className.match(me.colorRe)[1];
@@ -70450,19 +73856,19 @@ Ext.define('Ext.picker.Color', {
 
     
     select : function(color, suppressEvent){
-        
+
         var me = this,
             selectedCls = me.selectedCls,
             value = me.value,
             el;
-            
+
         color = color.replace('#', '');
         if (!me.rendered) {
             me.value = color;
             return;
         }
-        
-        
+
+
         if (color != value || me.allowReselect) {
             el = me.el;
 
@@ -70476,7 +73882,7 @@ Ext.define('Ext.picker.Color', {
             }
         }
     },
-    
+
     
     getValue: function(){
         return this.value || null;
@@ -70534,10 +73940,10 @@ Ext.define('Ext.form.field.HtmlEditor', {
     ],
 
     fieldSubTpl: [
-        '<div class="{toolbarWrapCls}"></div>',
-        '<textarea id="{id}" name="{name}" tabIndex="-1" class="{textareaCls}" ',
+        '<div id="{cmpId}-toolbarWrap" class="{toolbarWrapCls}"></div>',
+        '<textarea id="{cmpId}-textareaEl" name="{name}" tabIndex="-1" class="{textareaCls}" ',
             'style="{size}" autocomplete="off"></textarea>',
-        '<iframe name="{iframeName}" frameBorder="0" style="overflow:auto;{size}" src="{iframeSrc}"></iframe>',
+        '<iframe id="{cmpId}-iframeEl" name="{iframeName}" frameBorder="0" style="overflow:auto;{size}" src="{iframeSrc}"></iframe>',
         {
             compiled: true,
             disableFormats: true
@@ -70588,7 +73994,7 @@ Ext.define('Ext.form.field.HtmlEditor', {
     hideMode:'offsets',
 
     maskOnDisable: true,
-    
+
     
     initComponent : function(){
         var me = this;
@@ -70644,7 +74050,7 @@ Ext.define('Ext.form.field.HtmlEditor', {
         if (me.enableFont && !Ext.isSafari2) {
             fontSelectItem = Ext.widget('component', {
                 renderTpl: [
-                    '<select class="{cls}">',
+                    '<select id="{id}-selectEl" class="{cls}">',
                         '<tpl for="fonts">',
                             '<option value="{[values.toLowerCase()]}" style="font-family:{.}"<tpl if="values.toLowerCase()==parent.defaultFont"> selected</tpl>>{.}</option>',
                         '</tpl>',
@@ -70655,9 +74061,7 @@ Ext.define('Ext.form.field.HtmlEditor', {
                     fonts: me.fontFamilies,
                     defaultFont: me.defaultFont
                 },
-                renderSelectors: {
-                    selectEl: 'select'
-                },
+                childEls: ['selectEl'],
                 onDisable: function() {
                     var selectEl = this.selectEl;
                     if (selectEl) {
@@ -70857,7 +74261,7 @@ Ext.define('Ext.form.field.HtmlEditor', {
     getDocMarkup: function() {
         var me = this,
             h = me.iframeEl.getHeight() - me.iframePad * 2;
-        return Ext.String.format('<html><head><style type="text/css">body{border:0;margin:0;padding:{0}px;height:{1}px;cursor:text}</style></head><body></body></html>', me.iframePad, h);
+        return Ext.String.format('<html><head><style type="text/css">body{border:0;margin:0;padding:{0}px;height:{1}px;box-sizing: border-box; -moz-box-sizing: border-box; -webkit-box-sizing: border-box;cursor:text}</style></head><body></body></html>', me.iframePad, h);
     },
 
     
@@ -70878,16 +74282,11 @@ Ext.define('Ext.form.field.HtmlEditor', {
 
     
     onRender: function() {
-        var me = this,
-            renderSelectors = me.renderSelectors;
+        var me = this;
 
-        Ext.applyIf(renderSelectors, me.getLabelableSelectors());
+        me.onLabelableRender();
 
-        Ext.applyIf(renderSelectors, {
-            toolbarWrap: 'div.' + Ext.baseCSSPrefix + 'html-editor-tb',
-            iframeEl: 'iframe',
-            textareaEl: 'textarea'
-        });
+        me.addChildEls('toolbarWrap', 'iframeEl', 'textareaEl');
 
         me.callParent(arguments);
 
@@ -70919,6 +74318,8 @@ Ext.define('Ext.form.field.HtmlEditor', {
     getSubTplData: function() {
         var cssPrefix = Ext.baseCSSPrefix;
         return {
+            cmpId: this.id,
+            id: this.getInputId(),
             toolbarWrapCls: cssPrefix + 'html-editor-tb',
             textareaCls: cssPrefix + 'hidden',
             iframeName: Ext.id(),
@@ -70928,7 +74329,8 @@ Ext.define('Ext.form.field.HtmlEditor', {
     },
 
     getSubTplMarkup: function() {
-        return this.getTpl('fieldSubTpl').apply(this.getSubTplData());
+        var data = this.getSubTplData();
+        return this.getTpl('fieldSubTpl').apply(data);
     },
 
     getBodyNaturalWidth: function() {
@@ -71154,7 +74556,7 @@ Ext.define('Ext.form.field.HtmlEditor', {
             ss['background-attachment'] = 'fixed'; 
             dbody.bgProperties = 'fixed'; 
 
-            Ext.core.DomHelper.applyStyles(dbody, ss);
+            Ext.DomHelper.applyStyles(dbody, ss);
 
             doc = me.getDoc();
 
@@ -71232,7 +74634,7 @@ Ext.define('Ext.form.field.HtmlEditor', {
             } catch(e) {
                 
             }
-            Ext.destroyMembers('tb', 'toolbarWrap', 'iframeEl', 'textareaEl');
+            Ext.destroyMembers(me, 'tb', 'toolbarWrap', 'iframeEl', 'textareaEl');
         }
         me.callParent();
     },
@@ -71653,6 +75055,10 @@ Ext.define('Ext.form.field.Radio', {
         return this.checked ? this.inputValue : null;
     },
 
+    getModelData: function() {
+        return this.getSubmitData();
+    },
+
     
     onChange: function(newVal, oldVal) {
         var me = this;
@@ -71668,12 +75074,6 @@ Ext.define('Ext.form.field.Radio', {
     },
 
     
-    beforeDestroy: function(){
-        this.callParent();
-        this.getManager().removeAtKey(this.id);
-    },
-
-    
     getManager: function() {
         return Ext.form.RadioManager;
     }
@@ -71699,27 +75099,27 @@ Ext.define('Ext.picker.Time', {
     displayField: 'disp',
 
     
-    initDate: [2008,1,1],
+    initDate: [2008,0,1],
 
     componentCls: Ext.baseCSSPrefix + 'timepicker',
 
     
-    loadingText: '',
+    loadMask: false,
 
     initComponent: function() {
         var me = this,
             dateUtil = Ext.Date,
             clearTime = dateUtil.clearTime,
-            initDate = me.initDate.join('/');
+            initDate = me.initDate;
 
         
-        me.absMin = clearTime(new Date(initDate));
-        me.absMax = dateUtil.add(clearTime(new Date(initDate)), 'mi', (24 * 60) - 1);
+        me.absMin = clearTime(new Date(initDate[0], initDate[1], initDate[2]));
+        me.absMax = dateUtil.add(clearTime(new Date(initDate[0], initDate[1], initDate[2])), 'mi', (24 * 60) - 1);
 
         me.store = me.createStore();
         me.updateList();
 
-        this.callParent();
+        me.callParent();
     },
 
     
@@ -71737,7 +75137,7 @@ Ext.define('Ext.picker.Time', {
     
     normalizeDate: function(date) {
         var initDate = this.initDate;
-        date.setFullYear(initDate[0], initDate[1] - 1, initDate[2]);
+        date.setFullYear(initDate[0], initDate[1], initDate[2]);
         return date;
     },
 
@@ -71983,6 +75383,7 @@ Ext.define('Ext.form.field.Time', {
     createPicker: function() {
         var me = this,
             picker = Ext.create('Ext.picker.Time', {
+                pickerField: me,
                 selModel: {
                     mode: 'SINGLE'
                 },
@@ -72021,7 +75422,11 @@ Ext.define('Ext.form.field.Time', {
                 forceKeyDown: true,
                 tab: function(e) {
                     if (selectOnTab) {
-                        this.selectHighlighted(e);
+                        if(me.picker.highlightedItem) {
+                            this.selectHighlighted(e);
+                        } else {
+                            me.collapse();
+                        }
                         me.triggerBlur();
                     }
                     
@@ -72056,6 +75461,17 @@ Ext.define('Ext.form.field.Time', {
     },
 
     
+    onChange: function() {
+        var me = this,
+            picker = me.picker;
+
+        me.callParent(arguments);
+        if(picker) {
+            picker.clearHighlight();
+        }
+    },
+
+    
     onListSelect: function(list, recordArray) {
         var me = this,
             record = recordArray[0],
@@ -72073,13 +75489,17 @@ Ext.define('Ext.form.field.Time', {
 Ext.define('Ext.grid.CellEditor', {
     extend: 'Ext.Editor',
     constructor: function(config) {
+        config = Ext.apply({}, config);
+        
         if (config.field) {
             config.field.monitorTab = false;
         }
-        config.autoSize = {
-            width: 'boundEl'
-        };
-        this.callParent(arguments);
+        if (!Ext.isDefined(config.autoSize)) {
+            config.autoSize = {
+                width: 'boundEl'
+            };
+        }
+        this.callParent([config]);
     },
     
     
@@ -72133,23 +75553,26 @@ Ext.define('Ext.grid.ColumnLayout', {
     alias: 'layout.gridcolumn',
     type : 'column',
 
-    
-    clearInnerCtOnLayout: false,
+    reserveOffset: false,
 
-    constructor: function() {
-        var me = this;
-        me.callParent(arguments);
-        if (!Ext.isDefined(me.availableSpaceOffset)) {
-            me.availableSpaceOffset = (Ext.getScrollBarWidth() - 2);
-        }
-    },
+    shrinkToFit: false,
+
+    
+    clearInnerCtOnLayout: true,
 
     beforeLayout: function() {
         var me = this,
             i = 0,
             items = me.getLayoutItems(),
             len = items.length,
-            item, returnValue;
+            item, returnValue,
+            s;
+
+        
+        if (!Ext.isDefined(me.availableSpaceOffset)) {
+            s = me.owner.up('tablepanel').verticalScroller;
+            me.availableSpaceOffset = s ? s.width-1 : 0;
+        }
 
         returnValue = me.callParent(arguments);
 
@@ -72157,19 +75580,17 @@ Ext.define('Ext.grid.ColumnLayout', {
         me.innerCt.setHeight(23);
 
         
-        if (me.align == 'stretchmax') {
-            for (; i < len; i++) {
-                item = items[i];
-                item.el.setStyle({
-                    height: 'auto'
-                });
-                item.titleContainer.setStyle({
-                    height: 'auto',
-                    paddingTop: '0'
-                });
-                if (item.componentLayout && item.componentLayout.lastComponentSize) {
-                    item.componentLayout.lastComponentSize.height = item.el.dom.offsetHeight;
-                }
+        for (; i < len; i++) {
+            item = items[i];
+            item.el.setStyle({
+                height: 'auto'
+            });
+            item.titleContainer.setStyle({
+                height: 'auto',
+                paddingTop: '0'
+            });
+            if (item.componentLayout && item.componentLayout.lastComponentSize) {
+                item.componentLayout.lastComponentSize.height = item.el.dom.offsetHeight;
             }
         }
         return returnValue;
@@ -72183,7 +75604,7 @@ Ext.define('Ext.grid.ColumnLayout', {
             metaData = calculations.meta,
             len = boxes.length, i = 0, box, item;
 
-        if (targetSize.width && !me.isColumn) {
+        if (targetSize.width && !me.isHeader) {
             
             if (me.owner.forceFit) {
 
@@ -72212,16 +75633,84 @@ Ext.define('Ext.grid.ColumnLayout', {
 
     afterLayout: function() {
         var me = this,
+            owner = me.owner,
+            topGrid,
+            bothHeaderCts,
+            otherHeaderCt,
+            thisHeight,
+            otherHeight,
+            modifiedGrid,
             i = 0,
-            items = me.getLayoutItems(),
-            len = items.length;
+            items,
+            len,
+            headerHeight;
 
         me.callParent(arguments);
 
         
-        if (me.align == 'stretchmax') {
+        if (!me.owner.hideHeaders) {
+
+            
+            
+            if (owner.lockableInjected) {
+                topGrid = owner.up('tablepanel').up('tablepanel');
+                bothHeaderCts = topGrid.query('headercontainer:not([isHeader])');
+                otherHeaderCt = (bothHeaderCts[0] === owner) ? bothHeaderCts[1] : bothHeaderCts[0];
+
+                
+                if (!otherHeaderCt.rendered) {
+                    return;
+                }
+
+                
+                otherHeight = otherHeaderCt.layout.getRenderTarget().getViewSize().height;
+                if (!otherHeight) {
+                    return;
+                }
+                thisHeight = this.getRenderTarget().getViewSize().height;
+                if (!thisHeight) {
+                    return;
+                }
+
+                
+                
+                topGrid.componentLayout.layoutBusy = true;
+
+                
+                headerHeight = thisHeight;
+
+                
+                if (thisHeight > otherHeight) {
+                    otherHeaderCt.layout.align = 'stretch';
+                    otherHeaderCt.setCalculatedSize(otherHeaderCt.getWidth(), owner.getHeight(), otherHeaderCt.ownerCt);
+                    delete otherHeaderCt.layout.align;
+                    modifiedGrid = otherHeaderCt.up('tablepanel');
+                } else if (otherHeight > thisHeight) {
+                    headerHeight = otherHeight;
+                    this.align = 'stretch';
+                    owner.setCalculatedSize(owner.getWidth(), otherHeaderCt.getHeight(), owner.ownerCt);
+                    delete this.align;
+                    modifiedGrid = owner.up('tablepanel');
+                }
+                topGrid.componentLayout.layoutBusy = false;
+
+                
+                items = bothHeaderCts[0].layout.getLayoutItems().concat(bothHeaderCts[1].layout.getLayoutItems());
+            } else {
+                headerHeight = this.getRenderTarget().getViewSize().height;
+                items = me.getLayoutItems();
+            }
+
+            len = items.length;
             for (; i < len; i++) {
-                items[i].setPadding();
+                items[i].setPadding(headerHeight);
+            }
+
+            
+            if (modifiedGrid) {
+                setTimeout(function() {
+                    modifiedGrid.doLayout();
+                }, 1);
             }
         }
     },
@@ -72229,26 +75718,21 @@ Ext.define('Ext.grid.ColumnLayout', {
     
     
     updateInnerCtSize: function(tSize, calcs) {
-        var me    = this,
-            extra = 0;
+        var me = this,
+            extra;
 
         
-        if (!me.isColumn && calcs.meta.tooNarrow) {
-            if (
-                Ext.isWebKit ||
-                Ext.isGecko ||
-                (Ext.isIEQuirks && (Ext.isIE6 || Ext.isIE7 || Ext.isIE8))
-            ) {
-                extra = 1;
-            
-            } else if (Ext.isIE6 || Ext.isIE7 || Ext.isIE8) {
-                extra = 2;
+        if (!me.isHeader) {
+            me.tooNarrow = calcs.meta.tooNarrow;
+            extra = (me.reserveOffset ? me.availableSpaceOffset : 0);
+
+            if (calcs.meta.tooNarrow) {
+                tSize.width = calcs.meta.desiredSize + extra;
+            } else {
+                tSize.width += extra;
             }
-            
-            
-            extra++;
-            tSize.width = calcs.meta.desiredSize + (me.reserveOffset ? me.availableSpaceOffset : 0) + extra;
         }
+
         return me.callParent(arguments);
     },
 
@@ -72261,13 +75745,13 @@ Ext.define('Ext.grid.ColumnLayout', {
 });
 
 Ext.define('Ext.grid.LockingView', {
-    
+
     mixins: {
         observable: 'Ext.util.Observable'
     },
-    
+
     eventRelayRe: /^(beforeitem|beforecontainer|item|container|cell)/,
-    
+
     constructor: function(config){
         var me = this,
             eventNames = [],
@@ -72276,7 +75760,7 @@ Ext.define('Ext.grid.LockingView', {
             normal = config.normal.getView(),
             events,
             event;
-        
+
         Ext.apply(me, {
             lockedView: locked,
             normalView: normal,
@@ -72285,7 +75769,7 @@ Ext.define('Ext.grid.LockingView', {
             panel: config.panel
         });
         me.mixins.observable.constructor.call(me, config);
-        
+
         
         events = locked.events;
         for (event in events) {
@@ -72295,31 +75779,49 @@ Ext.define('Ext.grid.LockingView', {
         }
         me.relayEvents(locked, eventNames);
         me.relayEvents(normal, eventNames);
-        
+
         normal.on({
             scope: me,
             itemmouseleave: me.onItemMouseLeave,
             itemmouseenter: me.onItemMouseEnter
         });
-        
+
         locked.on({
             scope: me,
             itemmouseleave: me.onItemMouseLeave,
             itemmouseenter: me.onItemMouseEnter
         });
     },
-    
+
     getGridColumns: function() {
         var cols = this.lockedGrid.headerCt.getGridColumns();
         return cols.concat(this.normalGrid.headerCt.getGridColumns());
     },
-    
+
+    getEl: function(column){
+        return this.getViewForColumn(column).getEl();
+    },
+
+    getViewForColumn: function(column) {
+        var view = this.lockedView,
+            inLocked;
+
+        view.headerCt.cascade(function(col){
+            if (col === column) {
+                inLocked = true;
+                return false;
+            }
+        });
+
+        return inLocked ? view : this.normalView;
+    },
+
     onItemMouseEnter: function(view, record){
         var me = this,
             locked = me.lockedView,
             other = me.normalView,
             item;
-            
+
         if (view.trackOver) {
             if (view !== locked) {
                 other = locked;
@@ -72328,12 +75830,12 @@ Ext.define('Ext.grid.LockingView', {
             other.highlightItem(item);
         }
     },
-    
+
     onItemMouseLeave: function(view, record){
         var me = this,
             locked = me.lockedView,
             other = me.normalView;
-            
+
         if (view.trackOver) {
             if (view !== locked) {
                 other = locked;
@@ -72341,42 +75843,37 @@ Ext.define('Ext.grid.LockingView', {
             other.clearHighlight();
         }
     },
-    
+
     relayFn: function(name, args){
         args = args || [];
-        
+
         var view = this.lockedView;
-        view[name].apply(view, args || []);    
+        view[name].apply(view, args || []);
         view = this.normalView;
-        view[name].apply(view, args || []);   
+        view[name].apply(view, args || []);
     },
-    
+
     getSelectionModel: function(){
-        return this.panel.getSelectionModel();    
+        return this.panel.getSelectionModel();
     },
-    
+
     getStore: function(){
         return this.panel.store;
     },
-    
+
     getNode: function(nodeInfo){
         
         return this.normalView.getNode(nodeInfo);
     },
-    
+
     getCell: function(record, column){
-        var view = this.lockedView,
+        var view = this.getViewForColumn(column),
             row;
-        
-        
-        if (view.getHeaderAtIndex(column) === -1) {
-            view = this.normalView;
-        }
-        
+
         row = view.getNode(record);
         return Ext.fly(row).down(column.getCellSelector());
     },
-    
+
     getRecord: function(node){
         var result = this.lockedView.getRecord(node);
         if (!node) {
@@ -72384,49 +75881,55 @@ Ext.define('Ext.grid.LockingView', {
         }
         return result;
     },
-    
+
+    addElListener: function(eventName, fn, scope){
+        this.relayFn('addElListener', arguments);
+    },
+
     refreshNode: function(){
         this.relayFn('refreshNode', arguments);
     },
-    
+
     refresh: function(){
         this.relayFn('refresh', arguments);
     },
-    
+
     bindStore: function(){
         this.relayFn('bindStore', arguments);
     },
-    
+
     addRowCls: function(){
         this.relayFn('addRowCls', arguments);
     },
-    
+
     removeRowCls: function(){
         this.relayFn('removeRowCls', arguments);
     }
-       
+
 });
 
 Ext.define('Ext.grid.Lockable', {
-    
+
     requires: ['Ext.grid.LockingView'],
-    
+
     
     syncRowHeight: true,
-    
-    
-    
+
     
 
     
+
     
+
     
     spacerHidden: true,
-    
+
+    headerCounter: 0,
+
     
     unlockText: 'Unlock',
     lockText: 'Lock',
-    
+
     determineXTypeToCreate: function() {
         var me = this,
             typeToCreate;
@@ -72438,17 +75941,17 @@ Ext.define('Ext.grid.Lockable', {
                 xtypesLn   = xtypes.length,
                 xtype      = xtypes[xtypesLn - 1],
                 superxtype = xtypes[xtypesLn - 2];
-                
+
             if (superxtype !== 'tablepanel') {
                 typeToCreate = superxtype;
             } else {
                 typeToCreate = xtype;
             }
         }
-        
+
         return typeToCreate;
     },
-    
+
     
     
     injectLockable: function() {
@@ -72486,9 +75989,9 @@ Ext.define('Ext.grid.Lockable', {
             columns,
             lockedHeaderCt,
             normalHeaderCt;
-        
+
         me.addCls(Ext.baseCSSPrefix + 'grid-locked');
-        
+
         
         
         
@@ -72500,59 +76003,69 @@ Ext.define('Ext.grid.Lockable', {
         for (i = 0; i < me.lockedCfgCopy.length; i++) {
             delete me[me.lockedCfgCopy[i]];
         }
-        
+
+        me.addEvents(
+            
+            'lockcolumn',
+
+            
+            'unlockcolumn'
+        );
+
+        me.addStateEvents(['lockcolumn', 'unlockcolumn']);
+
         me.lockedHeights = [];
         me.normalHeights = [];
-        
+
         columns = me.processColumns(me.columns);
 
-        lockedGrid.width = columns.lockedWidth;
+        lockedGrid.width = columns.lockedWidth + Ext.num(selModel.headerWidth, 0);
         lockedGrid.columns = columns.locked;
         normalGrid.columns = columns.normal;
-        
+
         me.store = Ext.StoreManager.lookup(me.store);
         lockedGrid.store = me.store;
         normalGrid.store = me.store;
-        
+
         
         normalGrid.flex = 1;
         lockedGrid.viewConfig = me.lockedViewConfig || {};
         lockedGrid.viewConfig.loadingUseMsg = false;
         normalGrid.viewConfig = me.normalViewConfig || {};
-        
+
         Ext.applyIf(lockedGrid.viewConfig, me.viewConfig);
         Ext.applyIf(normalGrid.viewConfig, me.viewConfig);
-        
+
         me.normalGrid = Ext.ComponentManager.create(normalGrid);
         me.lockedGrid = Ext.ComponentManager.create(lockedGrid);
-        
+
         me.view = Ext.create('Ext.grid.LockingView', {
             locked: me.lockedGrid,
             normal: me.normalGrid,
-            panel: me    
+            panel: me
         });
-        
+
         if (me.syncRowHeight) {
             me.lockedGrid.getView().on({
                 refresh: me.onLockedGridAfterRefresh,
                 itemupdate: me.onLockedGridAfterUpdate,
                 scope: me
             });
-            
+
             me.normalGrid.getView().on({
                 refresh: me.onNormalGridAfterRefresh,
                 itemupdate: me.onNormalGridAfterUpdate,
                 scope: me
             });
         }
-        
+
         lockedHeaderCt = me.lockedGrid.headerCt;
         normalHeaderCt = me.normalGrid.headerCt;
-        
+
         lockedHeaderCt.lockedCt = true;
         lockedHeaderCt.lockableInjected = true;
         normalHeaderCt.lockableInjected = true;
-        
+
         lockedHeaderCt.on({
             columnshow: me.onLockedHeaderShow,
             columnhide: me.onLockedHeaderHide,
@@ -72561,102 +76074,113 @@ Ext.define('Ext.grid.Lockable', {
             columnresize: me.onLockedHeaderResize,
             scope: me
         });
-        
+
         normalHeaderCt.on({
             columnmove: me.onNormalHeaderMove,
             sortchange: me.onNormalHeaderSortChange,
             scope: me
         });
-        
+
         me.normalGrid.on({
             scrollershow: me.onScrollerShow,
             scrollerhide: me.onScrollerHide,
             scope: me
         });
-        
+
         me.lockedGrid.on('afterlayout', me.onLockedGridAfterLayout, me, {single: true});
-        
+
         me.modifyHeaderCt();
         me.items = [me.lockedGrid, me.normalGrid];
 
+        me.relayHeaderCtEvents(lockedHeaderCt);
+        me.relayHeaderCtEvents(normalHeaderCt);
+
         me.layout = {
             type: 'hbox',
             align: 'stretch'
         };
     },
-    
+
     processColumns: function(columns){
         
         var i = 0,
             len = columns.length,
-            lockedWidth = 0,
+            lockedWidth = 1,
             lockedHeaders = [],
             normalHeaders = [],
             column;
-            
+
         for (; i < len; ++i) {
             column = columns[i];
             
             
             column.processed = true;
             if (column.locked) {
-                if (column.flex) {
-                    Ext.Error.raise("Columns which are locked do NOT support a flex width. You must set a width on the " + columns[i].text + "column.");
+                if (!column.hidden) {
+                    lockedWidth += column.width || Ext.grid.header.Container.prototype.defaultWidth;
                 }
-                lockedWidth += column.width;
                 lockedHeaders.push(column);
             } else {
                 normalHeaders.push(column);
             }
+            if (!column.headerId) {
+                column.headerId = (column.initialConfig || column).id || ('L' + (++this.headerCounter));
+            }
         }
         return {
             lockedWidth: lockedWidth,
             locked: lockedHeaders,
-            normal: normalHeaders    
+            normal: normalHeaders
         };
     },
-    
+
     
     onLockedGridAfterLayout: function() {
         var me         = this,
             lockedView = me.lockedGrid.getView();
         lockedView.on({
-            refresh: me.createSpacer,
             beforerefresh: me.destroySpacer,
             scope: me
         });
     },
-    
+
     
     onLockedHeaderMove: function() {
         if (this.syncRowHeight) {
             this.onNormalGridAfterRefresh();
         }
     },
-    
+
     
     onNormalHeaderMove: function() {
         if (this.syncRowHeight) {
             this.onLockedGridAfterRefresh();
         }
     },
+
     
     
-    
-    createSpacer: function() {
+    getSpacerEl: function() {
         var me   = this,
+            w,
+            view,
+            el;
+
+        if (!me.spacerEl) {
             
             
-            w    = Ext.getScrollBarWidth() + (Ext.isIE ? 2 : 0),
-            view = me.lockedGrid.getView(),
+            w    = Ext.getScrollBarWidth() + (Ext.isIE ? 2 : 0);
+            view = me.lockedGrid.getView();
             el   = view.el;
 
-        me.spacerEl = Ext.core.DomHelper.append(el, {
-            cls: me.spacerHidden ? (Ext.baseCSSPrefix + 'hidden') : '',
-            style: 'height: ' + w + 'px;'
-        }, true);
+            me.spacerEl = Ext.DomHelper.append(el, {
+                cls: me.spacerHidden ? (Ext.baseCSSPrefix + 'hidden') : '',
+                style: 'height: ' + w + 'px;'
+            }, true);
+        }
+        return me.spacerEl;
     },
-    
+
     destroySpacer: function() {
         var me = this;
         if (me.spacerEl) {
@@ -72664,7 +76188,7 @@ Ext.define('Ext.grid.Lockable', {
             delete me.spacerEl;
         }
     },
-    
+
     
     onLockedGridAfterRefresh: function() {
         var me     = this,
@@ -72673,16 +76197,16 @@ Ext.define('Ext.grid.Lockable', {
             rowEls = el.query(view.getItemSelector()),
             ln     = rowEls.length,
             i = 0;
-            
+
         
         me.lockedHeights = [];
-        
+
         for (; i < ln; i++) {
             me.lockedHeights[i] = rowEls[i].clientHeight;
         }
         me.syncRowHeights();
     },
-    
+
     
     onNormalGridAfterRefresh: function() {
         var me     = this,
@@ -72691,28 +76215,28 @@ Ext.define('Ext.grid.Lockable', {
             rowEls = el.query(view.getItemSelector()),
             ln     = rowEls.length,
             i = 0;
-            
+
         
         me.normalHeights = [];
-        
+
         for (; i < ln; i++) {
             me.normalHeights[i] = rowEls[i].clientHeight;
         }
         me.syncRowHeights();
     },
-    
+
     
     onLockedGridAfterUpdate: function(record, index, node) {
         this.lockedHeights[index] = node.clientHeight;
         this.syncRowHeights();
     },
-    
+
     
     onNormalGridAfterUpdate: function(record, index, node) {
         this.normalHeights[index] = node.clientHeight;
         this.syncRowHeights();
     },
-    
+
     
     
     syncRowHeights: function() {
@@ -72749,7 +76273,7 @@ Ext.define('Ext.grid.Lockable', {
 
             
             me.normalGrid.invalidateScroller();
-            
+
             
             
             if (vertScroller && vertScroller.setViewScrollTop) {
@@ -72762,55 +76286,56 @@ Ext.define('Ext.grid.Lockable', {
                 normalView.el.dom.scrollTop = scrollTop;
                 lockedView.el.dom.scrollTop = scrollTop;
             }
-            
+
             
             me.lockedHeights = [];
             me.normalHeights = [];
         }
     },
-    
+
     
     onScrollerShow: function(scroller, direction) {
         if (direction === 'horizontal') {
             this.spacerHidden = false;
-            this.spacerEl.removeCls(Ext.baseCSSPrefix + 'hidden');
+            this.getSpacerEl().removeCls(Ext.baseCSSPrefix + 'hidden');
         }
     },
-    
+
     
     onScrollerHide: function(scroller, direction) {
         if (direction === 'horizontal') {
             this.spacerHidden = true;
-            this.spacerEl.addCls(Ext.baseCSSPrefix + 'hidden');
+            if (this.spacerEl) {
+                this.spacerEl.addCls(Ext.baseCSSPrefix + 'hidden');
+            }
         }
     },
 
-    
+
     
     modifyHeaderCt: function() {
         var me = this;
         me.lockedGrid.headerCt.getMenuItems = me.getMenuItems(true);
         me.normalGrid.headerCt.getMenuItems = me.getMenuItems(false);
     },
-    
+
     onUnlockMenuClick: function() {
         this.unlock();
     },
-    
+
     onLockMenuClick: function() {
         this.lock();
     },
-    
+
     getMenuItems: function(locked) {
         var me            = this,
             unlockText    = me.unlockText,
             lockText      = me.lockText,
-            
-            unlockCls     = 'xg-hmenu-unlock',
-            lockCls       = 'xg-hmenu-lock',
+            unlockCls     = Ext.baseCSSPrefix + 'hmenu-unlock',
+            lockCls       = Ext.baseCSSPrefix + 'hmenu-lock',
             unlockHandler = Ext.Function.bind(me.onUnlockMenuClick, me),
             lockHandler   = Ext.Function.bind(me.onLockMenuClick, me);
-        
+
         
         return function() {
             var o = Ext.grid.header.Container.prototype.getMenuItems.call(this);
@@ -72829,7 +76354,7 @@ Ext.define('Ext.grid.Lockable', {
             return o;
         };
     },
-    
+
     
     
     lock: function(activeHd, toIdx) {
@@ -72838,18 +76363,19 @@ Ext.define('Ext.grid.Lockable', {
             lockedGrid = me.lockedGrid,
             normalHCt  = normalGrid.headerCt,
             lockedHCt  = lockedGrid.headerCt;
-            
+
         activeHd = activeHd || normalHCt.getMenu().activeHeader;
-        
+
         
         
         if (activeHd.flex) {
             activeHd.width = activeHd.getWidth();
             delete activeHd.flex;
         }
-        
+
         normalHCt.remove(activeHd, false);
         lockedHCt.suspendLayout = true;
+        activeHd.locked = true;
         if (Ext.isDefined(toIdx)) {
             lockedHCt.insert(toIdx, activeHd);
         } else {
@@ -72857,35 +76383,38 @@ Ext.define('Ext.grid.Lockable', {
         }
         lockedHCt.suspendLayout = false;
         me.syncLockedSection();
+
+        me.fireEvent('lockcolumn', me, activeHd);
     },
-    
+
     syncLockedSection: function() {
         var me = this;
         me.syncLockedWidth();
         me.lockedGrid.getView().refresh();
         me.normalGrid.getView().refresh();
     },
-    
+
     
     
     syncLockedWidth: function() {
         var me = this,
             width = me.lockedGrid.headerCt.getFullWidth(true);
-        me.lockedGrid.setWidth(width);
+        me.lockedGrid.setWidth(width+1); 
+        me.doComponentLayout();
     },
-    
+
     onLockedHeaderResize: function() {
         this.syncLockedWidth();
     },
-    
+
     onLockedHeaderHide: function() {
         this.syncLockedWidth();
     },
-    
+
     onLockedHeaderShow: function() {
         this.syncLockedWidth();
     },
-    
+
     onLockedHeaderSortChange: function(headerCt, header, sortState) {
         if (sortState) {
             
@@ -72893,7 +76422,7 @@ Ext.define('Ext.grid.Lockable', {
             this.normalGrid.headerCt.clearOtherSortStates(null, true);
         }
     },
-    
+
     onNormalHeaderSortChange: function(headerCt, header, sortState) {
         if (sortState) {
             
@@ -72901,7 +76430,7 @@ Ext.define('Ext.grid.Lockable', {
             this.lockedGrid.headerCt.clearOtherSortStates(null, true);
         }
     },
-    
+
     
     
     unlock: function(activeHd, toIdx) {
@@ -72915,30 +76444,97 @@ Ext.define('Ext.grid.Lockable', {
             toIdx = 0;
         }
         activeHd = activeHd || lockedHCt.getMenu().activeHeader;
-        
+
         lockedHCt.remove(activeHd, false);
         me.syncLockedWidth();
         me.lockedGrid.getView().refresh();
+        activeHd.locked = false;
         normalHCt.insert(toIdx, activeHd);
         me.normalGrid.getView().refresh();
+
+        me.fireEvent('unlockcolumn', me, activeHd);
     },
-    
+
+    applyColumnsState: function (columns) {
+        var me = this,
+            lockedGrid = me.lockedGrid,
+            lockedHeaderCt = lockedGrid.headerCt,
+            normalHeaderCt = me.normalGrid.headerCt,
+            lockedCols = lockedHeaderCt.items,
+            normalCols = normalHeaderCt.items,
+            existing,
+            locked = [],
+            normal = [],
+            lockedDefault,
+            lockedWidth = 1;
+
+        Ext.each(columns, function (col) {
+            function matches (item) {
+                return item.headerId == col.id;
+            }
+
+            lockedDefault = true;
+            if (!(existing = lockedCols.findBy(matches))) {
+                existing = normalCols.findBy(matches);
+                lockedDefault = false;
+            }
+
+            if (existing) {
+                if (existing.applyColumnState) {
+                    existing.applyColumnState(col);
+                }
+                if (!Ext.isDefined(existing.locked)) {
+                    existing.locked = lockedDefault;
+                }
+                if (existing.locked) {
+                    locked.push(existing);
+                    if (!existing.hidden && Ext.isNumber(existing.width)) {
+                        lockedWidth += existing.width;
+                    }
+                } else {
+                    normal.push(existing);
+                }
+            }
+        });
+
+        
+        if (locked.length + normal.length == lockedCols.getCount() + normalCols.getCount()) {
+            lockedHeaderCt.removeAll(false);
+            normalHeaderCt.removeAll(false);
+
+            lockedHeaderCt.add(locked);
+            normalHeaderCt.add(normal);
+
+            lockedGrid.setWidth(lockedWidth);
+        }
+    },
+
+    getColumnsState: function () {
+        var me = this,
+            locked = me.lockedGrid.headerCt.getColumnsState(),
+            normal = me.normalGrid.headerCt.getColumnsState();
+
+        return locked.concat(normal);
+    },
+
     
     reconfigureLockable: function(store, columns) {
         var me = this,
             lockedGrid = me.lockedGrid,
             normalGrid = me.normalGrid;
-        
+
         if (columns) {
+            lockedGrid.headerCt.suspendLayout = true;
+            normalGrid.headerCt.suspendLayout = true;
             lockedGrid.headerCt.removeAll();
             normalGrid.headerCt.removeAll();
-            
+
             columns = me.processColumns(columns);
             lockedGrid.setWidth(columns.lockedWidth);
             lockedGrid.headerCt.add(columns.locked);
             normalGrid.headerCt.add(columns.normal);
         }
-        
+
         if (store) {
             store = Ext.data.StoreManager.lookup(store);
             me.store = store;
@@ -72948,6 +76544,13 @@ Ext.define('Ext.grid.Lockable', {
             lockedGrid.getView().refresh();
             normalGrid.getView().refresh();
         }
+
+        if (columns) {
+            lockedGrid.headerCt.suspendLayout = false;
+            normalGrid.headerCt.suspendLayout = false;
+            lockedGrid.headerCt.forceComponentLayout();
+            normalGrid.headerCt.forceComponentLayout();
+        }
     }
 });
 
@@ -72956,62 +76559,86 @@ Ext.define('Ext.grid.Scroller', {
     extend: 'Ext.Component',
     alias: 'widget.gridscroller',
     weight: 110,
-    cls: Ext.baseCSSPrefix + 'scroller',
+    baseCls: Ext.baseCSSPrefix + 'scroller',
     focusable: false,
-    
-    renderTpl: ['<div class="' + Ext.baseCSSPrefix + 'stretcher"></div>'],
-    
+    reservedSpace: 0,
+
+    renderTpl: [
+        '<div class="' + Ext.baseCSSPrefix + 'scroller-ct" id="{baseId}_ct">',
+            '<div class="' + Ext.baseCSSPrefix + 'stretcher" id="{baseId}_stretch"></div>',
+        '</div>'
+    ],
+
     initComponent: function() {
         var me       = this,
             dock     = me.dock,
-            cls      = Ext.baseCSSPrefix + 'scroller-vertical',
-            sizeProp = 'width',
-            
-            
-            
-            
-            
-            scrollbarWidth = Ext.getScrollBarWidth() + (Ext.isIE ? 1 : -1);
+            cls      = Ext.baseCSSPrefix + 'scroller-vertical';
 
         me.offsets = {bottom: 0};
+        me.scrollProp = 'scrollTop';
+        me.vertical = true;
+        me.sizeProp = 'width';
 
         if (dock === 'top' || dock === 'bottom') {
             cls = Ext.baseCSSPrefix + 'scroller-horizontal';
-            sizeProp = 'height';
+            me.sizeProp = 'height';
+            me.scrollProp = 'scrollLeft';
+            me.vertical = false;
+            me.weight += 5;
         }
-        me[sizeProp] = scrollbarWidth;
-        
+
         me.cls += (' ' + cls);
-        
+
         Ext.applyIf(me.renderSelectors, {
-            stretchEl: '.' + Ext.baseCSSPrefix + 'stretcher'
+            stretchEl: '.' + Ext.baseCSSPrefix + 'stretcher',
+            scrollEl: '.' + Ext.baseCSSPrefix + 'scroller-ct'
         });
         me.callParent();
     },
     
-    
+    ensureDimension: function(){
+        var me = this,
+            sizeProp = me.sizeProp;
+            
+        me[sizeProp] = me.scrollerSize = Ext.getScrollbarSize()[sizeProp];  
+    },
+
+    initRenderData: function () {
+        var me = this,
+            ret = me.callParent(arguments) || {};
+
+        ret.baseId = me.id;
+
+        return ret;
+    },
+
     afterRender: function() {
         var me = this;
         me.callParent();
-        me.ownerCt.on('afterlayout', me.onOwnerAfterLayout, me);
-        me.mon(me.el, 'scroll', me.onElScroll, me);
+        
+        me.mon(me.scrollEl, 'scroll', me.onElScroll, me);
         Ext.cache[me.el.id].skipGarbageCollection = true;
     },
-    
+
+    onAdded: function(container) {
+        
+        this.ownerGrid = container;
+        this.callParent(arguments);
+    },
+
     getSizeCalculation: function() {
-        var owner  = this.getPanel(),
-            dock   = this.dock,
-            elDom  = this.el.dom,
+        var me     = this,
+            owner  = me.getPanel(),
             width  = 1,
             height = 1,
             view, tbl;
-            
-        if (dock === 'top' || dock === 'bottom') {
+
+        if (!me.vertical) {
             
             
             var items  = owner.query('tableview'),
                 center = items[1] || items[0];
-            
+
             if (!center) {
                 return false;
             }
@@ -73019,25 +76646,23 @@ Ext.define('Ext.grid.Scroller', {
             
             
             width = center.headerCt.getFullWidth();
-            
+
             if (Ext.isIEQuirks) {
                 width--;
             }
-            
-            width--;
-        } else {            
+        } else {
             view = owner.down('tableview:not([lockableInjected])');
-            if (!view) {
+            if (!view || !view.el) {
                 return false;
             }
-            tbl = view.el;
+            tbl = view.el.child('table', true);
             if (!tbl) {
                 return false;
             }
+
             
             
-            
-            height = tbl.dom.scrollHeight;
+            height = tbl.offsetHeight;
         }
         if (isNaN(width)) {
             width = 1;
@@ -73050,64 +76675,124 @@ Ext.define('Ext.grid.Scroller', {
             height: height
         };
     },
-    
+
     invalidate: function(firstPass) {
-        if (!this.stretchEl || !this.ownerCt) {
+        var me = this,
+            stretchEl = me.stretchEl;
+
+        if (!stretchEl || !me.ownerCt) {
             return;
         }
-        var size  = this.getSizeCalculation(),
-            elDom = this.el.dom;
+
+        var size  = me.getSizeCalculation(),
+            scrollEl = me.scrollEl,
+            elDom = scrollEl.dom,
+            reservedSpace = me.reservedSpace,
+            pos,
+            extra = 5;
+
         if (size) {
-            this.stretchEl.setSize(size);
-        
+            stretchEl.setSize(size);
+
+            size = me.el.getSize(true);
+
+            if (me.vertical) {
+                size.width += extra;
+                size.height -= reservedSpace;
+                pos = 'left';
+            } else {
+                size.width -= reservedSpace;
+                size.height += extra;
+                pos = 'top';
+            }
+
+            scrollEl.setSize(size);
+            elDom.style[pos] = (-extra) + 'px';
+
             
             
             elDom.scrollTop = elDom.scrollTop;
         }
     },
 
-    onOwnerAfterLayout: function(owner, layout) {
+    afterComponentLayout: function() {
+        this.callParent(arguments);
         this.invalidate();
     },
 
+    restoreScrollPos: function () {
+        var me = this,
+            el = this.scrollEl,
+            elDom = el && el.dom;
+
+        if (me._scrollPos !== null && elDom) {
+            elDom[me.scrollProp] = me._scrollPos;
+            me._scrollPos = null;
+        }
+    },
+
+    setReservedSpace: function (reservedSpace) {
+        var me = this;
+        if (me.reservedSpace !== reservedSpace) {
+            me.reservedSpace = reservedSpace;
+            me.invalidate();
+        }
+    },
+
+    saveScrollPos: function () {
+        var me = this,
+            el = this.scrollEl,
+            elDom = el && el.dom;
+
+        me._scrollPos = elDom ? elDom[me.scrollProp] : null;
+    },
+
     
     setScrollTop: function(scrollTop) {
-        if (this.el) {
-            var elDom = this.el.dom;
+        var el = this.scrollEl,
+            elDom = el && el.dom;
+
+        if (elDom) {
             return elDom.scrollTop = Ext.Number.constrain(scrollTop, 0, elDom.scrollHeight - elDom.clientHeight);
         }
     },
 
     
     setScrollLeft: function(scrollLeft) {
-        if (this.el) {
-            var elDom = this.el.dom;
+        var el = this.scrollEl,
+            elDom = el && el.dom;
+
+        if (elDom) {
             return elDom.scrollLeft = Ext.Number.constrain(scrollLeft, 0, elDom.scrollWidth - elDom.clientWidth);
         }
     },
 
     
     scrollByDeltaY: function(delta) {
-        if (this.el) {
-            var elDom = this.el.dom;
+        var el = this.scrollEl,
+            elDom = el && el.dom;
+
+        if (elDom) {
             return this.setScrollTop(elDom.scrollTop + delta);
         }
     },
 
     
     scrollByDeltaX: function(delta) {
-        if (this.el) {
-            var elDom = this.el.dom;
+        var el = this.scrollEl,
+            elDom = el && el.dom;
+
+        if (elDom) {
             return this.setScrollLeft(elDom.scrollLeft + delta);
         }
     },
-    
-    
+
+
     
     scrollToTop : function(){
         this.setScrollTop(0);
     },
-    
+
     
     onElScroll: function(event, target) {
         this.fireEvent('bodyscroll', event, target);
@@ -73135,26 +76820,25 @@ Ext.define('Ext.grid.PagingScroller', {
     
     
     percentageFromEdge: 0.35,
-    
+
     
     scrollToLoadBuffer: 200,
-    
+
     activePrefetch: true,
-    
+
     chunkSize: 50,
     snapIncrement: 25,
-    
+
     syncScroll: true,
-    
+
     initComponent: function() {
         var me = this,
             ds = me.store;
 
-        ds.on('guaranteedrange', this.onGuaranteedRange, this);
-        this.callParent(arguments);
+        ds.on('guaranteedrange', me.onGuaranteedRange, me);
+        me.callParent(arguments);
     },
-    
-    
+
     onGuaranteedRange: function(range, start, end) {
         var me = this,
             ds = me.store,
@@ -73163,34 +76847,38 @@ Ext.define('Ext.grid.PagingScroller', {
         if (range.length && me.visibleStart < range[0].index) {
             return;
         }
-        
+
         ds.loadRecords(range);
 
         if (!me.firstLoad) {
             if (me.rendered) {
                 me.invalidate();
             } else {
-                me.on('afterrender', this.invalidate, this, {single: true});
+                me.on('afterrender', me.invalidate, me, {single: true});
             }
             me.firstLoad = true;
         } else {
             
-            me.syncTo();
+            
+            if (me.scrollEl && me.scrollEl.dom && me.scrollEl.dom.scrollHeight) {
+                me.syncTo();
+            }
         }
     },
-    
+
     syncTo: function() {
         var me            = this,
             pnl           = me.getPanel(),
             store         = pnl.store,
-            scrollerElDom = this.el.dom,
+            scrollerElDom = this.scrollEl.dom,
             rowOffset     = me.visibleStart - store.guaranteedStart,
             scrollBy      = rowOffset * me.rowHeight,
             scrollHeight  = scrollerElDom.scrollHeight,
             clientHeight  = scrollerElDom.clientHeight,
             scrollTop     = scrollerElDom.scrollTop,
             useMaximum;
-        
+            
+
         
         
         if (Ext.isIE9 && Ext.isStrict) {
@@ -73202,12 +76890,12 @@ Ext.define('Ext.grid.PagingScroller', {
         useMaximum = (scrollHeight - clientHeight - scrollTop <= 0);
         this.setViewScrollTop(scrollBy, useMaximum);
     },
-    
+
     getPageData : function(){
         var panel = this.getPanel(),
             store = panel.store,
             totalCount = store.getTotalCount();
-            
+
         return {
             total : totalCount,
             currentPage : store.currentPage,
@@ -73216,7 +76904,7 @@ Ext.define('Ext.grid.PagingScroller', {
             toRecord: Math.min(store.currentPage * store.pageSize, totalCount)
         };
     },
-    
+
     onElScroll: function(e, t) {
         var me = this,
             panel = me.getPanel(),
@@ -73225,7 +76913,7 @@ Ext.define('Ext.grid.PagingScroller', {
             guaranteedStart = store.guaranteedStart,
             guaranteedEnd = store.guaranteedEnd,
             totalCount = store.getTotalCount(),
-            numFromEdge = Math.ceil(me.percentageFromEdge * store.pageSize),
+            numFromEdge = Math.ceil(me.percentageFromEdge * pageSize),
             position = t.scrollTop,
             visibleStart = Math.floor(position / me.rowHeight),
             view = panel.down('tableview'),
@@ -73233,11 +76921,11 @@ Ext.define('Ext.grid.PagingScroller', {
             visibleHeight = viewEl.getHeight(),
             visibleAhead = Math.ceil(visibleHeight / me.rowHeight),
             visibleEnd = visibleStart + visibleAhead,
-            prevPage = Math.floor(visibleStart / store.pageSize),
-            nextPage = Math.floor(visibleEnd / store.pageSize) + 2,
-            lastPage = Math.ceil(totalCount / store.pageSize),
-            
-            requestStart = Math.floor(visibleStart / me.snapIncrement) * me.snapIncrement,
+            prevPage = Math.floor(visibleStart / pageSize),
+            nextPage = Math.floor(visibleEnd / pageSize) + 2,
+            lastPage = Math.ceil(totalCount / pageSize),
+            snap = me.snapIncrement,
+            requestStart = Math.floor(visibleStart / snap) * snap,
             requestEnd = requestStart + pageSize - 1,
             activePrefetch = me.activePrefetch;
 
@@ -73249,15 +76937,25 @@ Ext.define('Ext.grid.PagingScroller', {
         if (totalCount >= pageSize) {
             
             if (requestEnd > totalCount - 1) {
-                this.cancelLoad();
+                me.cancelLoad();
                 if (store.rangeSatisfied(totalCount - pageSize, totalCount - 1)) {
                     me.syncScroll = true;
                 }
                 store.guaranteeRange(totalCount - pageSize, totalCount - 1);
             
-            } else if (visibleStart < guaranteedStart || visibleEnd > guaranteedEnd) {
+            } else if (visibleStart <= guaranteedStart || visibleEnd > guaranteedEnd) {
+                if (visibleStart <= guaranteedStart) {
+                    
+                    requestStart -= snap;
+                    requestEnd -= snap;
+                    
+                    if (requestStart < 0) {
+                        requestStart = 0;
+                        requestEnd = pageSize;
+                    }
+                }
                 if (store.rangeSatisfied(requestStart, requestEnd)) {
-                    this.cancelLoad();
+                    me.cancelLoad();
                     store.guaranteeRange(requestStart, requestEnd);
                 } else {
                     store.mask();
@@ -73273,29 +76971,30 @@ Ext.define('Ext.grid.PagingScroller', {
                 store.prefetchPage(nextPage);
             }
         }
-    
-    
+
         if (me.syncScroll) {
             me.syncTo();
         }
     },
-    
+
     getSizeCalculation: function() {
         
         
-        var owner = this.ownerCt,
+        var me     = this,
+            owner  = me.ownerGrid,
             view   = owner.getView(),
-            store  = this.store,
-            dock   = this.dock,
-            elDom  = this.el.dom,
+            store  = me.store,
+            dock   = me.dock,
+            elDom  = me.el.dom,
             width  = 1,
             height = 1;
-        
-        if (!this.rowHeight) {
-            this.rowHeight = view.el.down(view.getItemSelector()).getHeight(false, true);
+
+        if (!me.rowHeight) {
+            me.rowHeight = view.el.down(view.getItemSelector()).getHeight(false, true);
         }
 
-        height = store.getTotalCount() * this.rowHeight;
+        
+        height = store[(!store.remoteFilter && store.isFiltered()) ? 'getCount' : 'getTotalCount']() * me.rowHeight;
 
         if (isNaN(width)) {
             width = 1;
@@ -73308,7 +77007,7 @@ Ext.define('Ext.grid.PagingScroller', {
             height: height
         };
     },
-    
+
     attemptLoad: function(start, end) {
         var me = this;
         if (!me.loadTask) {
@@ -73316,20 +77015,21 @@ Ext.define('Ext.grid.PagingScroller', {
         }
         me.loadTask.delay(me.scrollToLoadBuffer, me.doAttemptLoad, me, [start, end]);
     },
-    
+
     cancelLoad: function() {
         if (this.loadTask) {
             this.loadTask.cancel();
         }
     },
-    
+
     doAttemptLoad:  function(start, end) {
         var store = this.getPanel().store;
         store.guaranteeRange(start, end);
     },
-    
+
     setViewScrollTop: function(scrollTop, useMax) {
-        var owner = this.getPanel(),
+        var me = this,
+            owner = me.getPanel(),
             items = owner.query('tableview'),
             i = 0,
             len = items.length,
@@ -73337,15 +77037,15 @@ Ext.define('Ext.grid.PagingScroller', {
             centerEl,
             calcScrollTop,
             maxScrollTop,
-            scrollerElDom = this.el.dom;
-            
+            scrollerElDom = me.el.dom;
+
         owner.virtualScrollTop = scrollTop;
-            
+
         center = items[1] || items[0];
         centerEl = center.el.dom;
-        
-        maxScrollTop = ((owner.store.pageSize * this.rowHeight) - centerEl.clientHeight);
-        calcScrollTop = (scrollTop % ((owner.store.pageSize * this.rowHeight) + 1));
+
+        maxScrollTop = ((owner.store.pageSize * me.rowHeight) - centerEl.clientHeight);
+        calcScrollTop = (scrollTop % ((owner.store.pageSize * me.rowHeight) + 1));
         if (useMax) {
             calcScrollTop = maxScrollTop;
         }
@@ -73361,7 +77061,6 @@ Ext.define('Ext.grid.PagingScroller', {
 });
 
 
-
 Ext.define('Ext.panel.Table', {
     extend: 'Ext.panel.Panel',
 
@@ -73374,7 +77073,7 @@ Ext.define('Ext.panel.Table', {
         'Ext.grid.Lockable'
     ],
 
-    cls: Ext.baseCSSPrefix + 'grid',
+    extraBaseCls: Ext.baseCSSPrefix + 'grid',
     extraBodyCls: Ext.baseCSSPrefix + 'grid-body',
 
     layout: 'fit',
@@ -73382,10 +77081,25 @@ Ext.define('Ext.panel.Table', {
     hasView: false,
 
     
+    
     viewType: null,
+
+    
+
+    
+
+    
     selType: 'rowmodel',
 
     
+
+    
+
+    
+
+    
+
+    
     scrollDelta: 40,
 
     
@@ -73398,8 +77112,17 @@ Ext.define('Ext.panel.Table', {
     
 
     
+
+    
+
+     deferRowRender: true,
+     
+    
     sortableColumns: true,
 
+    
+    enableLocking: false,
+
     verticalScrollDock: 'right',
     verticalScrollerType: 'gridscroller',
 
@@ -73411,21 +77134,17 @@ Ext.define('Ext.panel.Table', {
     scrollerOwner: true,
 
     invalidateScrollerOnRefresh: true,
+
     
     enableColumnMove: true,
+
+    
     enableColumnResize: true,
 
+    
+    enableColumnHide: true,
 
     initComponent: function() {
-        if (!this.viewType) {
-            Ext.Error.raise("You must specify a viewType config.");
-        }
-        if (!this.store) {
-            Ext.Error.raise("You must specify a store config");
-        }
-        if (this.headers) {
-            Ext.Error.raise("The headers config is not supported. Please specify columns instead.");
-        }
 
         var me          = this,
             scroll      = me.scroll,
@@ -73436,15 +77155,14 @@ Ext.define('Ext.panel.Table', {
             view,
             border = me.border;
 
-        
-        me.determineScrollbars = Ext.Function.createBuffered(me.determineScrollbars, 30);
-        me.injectView = Ext.Function.createBuffered(me.injectView, 30);
-
         if (me.hideHeaders) {
             border = false;
         }
 
         
+        me.store = Ext.data.StoreManager.lookup(me.store || 'ext-empty-store');
+
+        
         
         if (headerCtCfg instanceof Ext.grid.header.Container) {
             me.headerCt = headerCtCfg;
@@ -73462,21 +77180,25 @@ Ext.define('Ext.panel.Table', {
                 sortable: me.sortableColumns,
                 enableColumnMove: me.enableColumnMove,
                 enableColumnResize: me.enableColumnResize,
+                enableColumnHide: me.enableColumnHide,
                 border:  border
             });
             me.columns = headerCtCfg.items;
 
              
              
-             if (Ext.ComponentQuery.query('{locked !== undefined}{processed != true}', me.columns).length) {
+             if (me.enableLocking || Ext.ComponentQuery.query('{locked !== undefined}{processed != true}', me.columns).length) {
                  me.self.mixin('lockable', Ext.grid.Lockable);
                  me.injectLockable();
              }
         }
 
-        me.store = Ext.data.StoreManager.lookup(me.store);
         me.addEvents(
             
+            'reconfigure',
+            
+            'viewready',
+            
             'scrollerhide',
             
             'scrollershow'
@@ -73484,6 +77206,9 @@ Ext.define('Ext.panel.Table', {
 
         me.bodyCls = me.bodyCls || '';
         me.bodyCls += (' ' + me.extraBodyCls);
+        
+        me.cls = me.cls || '';
+        me.cls += (' ' + me.extraBaseCls);
 
         
         delete me.autoScroll;
@@ -73528,13 +77253,7 @@ Ext.define('Ext.panel.Table', {
             }
 
             if (vertical) {
-                me.verticalScroller = me.verticalScroller || {};
-                Ext.applyIf(me.verticalScroller, {
-                    dock: me.verticalScrollDock,
-                    xtype: me.verticalScrollerType,
-                    store: me.store
-                });
-                me.verticalScroller = Ext.ComponentManager.create(me.verticalScroller);
+                me.verticalScroller = Ext.ComponentManager.create(me.initVerticalScroller());
                 me.mon(me.verticalScroller, {
                     bodyscroll: me.onVerticalScroll,
                     scope: me
@@ -73542,21 +77261,19 @@ Ext.define('Ext.panel.Table', {
             }
 
             if (horizontal) {
-                me.horizontalScroller = Ext.ComponentManager.create({
-                    xtype: 'gridscroller',
-                    section: me,
-                    dock: 'bottom',
-                    store: me.store
-                });
+                me.horizontalScroller = Ext.ComponentManager.create(me.initHorizontalScroller());
                 me.mon(me.horizontalScroller, {
                     bodyscroll: me.onHorizontalScroll,
                     scope: me
                 });
             }
 
-            me.headerCt.on('columnresize', me.onHeaderResize, me);
-            me.relayEvents(me.headerCt, ['columnresize', 'columnmove', 'columnhide', 'columnshow', 'sortchange']);
+            me.headerCt.on('resize', me.onHeaderResize, me);
+            me.relayHeaderCtEvents(me.headerCt);
             me.features = me.features || [];
+            if (!Ext.isArray(me.features)) {
+                me.features = [me.features];
+            }
             me.dockedItems = me.dockedItems || [];
             me.dockedItems.unshift(me.headerCt);
             me.viewConfig = me.viewConfig || {};
@@ -73566,85 +77283,119 @@ Ext.define('Ext.panel.Table', {
             
             view = me.getView();
 
-            if (view) {
-                me.mon(view.store, {
-                    load: me.onStoreLoad,
-                    scope: me
-                });
-                me.mon(view, {
-                    refresh: {
-                        fn: this.onViewRefresh,
-                        scope: me,
-                        buffer: 50
-                    },
-                    itemupdate: me.onViewItemUpdate,
-                    scope: me
-                });
-                this.relayEvents(view, [
-                    
-                    'beforeitemmousedown',
+            view.on({
+                afterrender: function () {
                     
-                    'beforeitemmouseup',
+                    view.el.scroll = Ext.Function.bind(me.elScroll, me);
                     
-                    'beforeitemmouseenter',
                     
-                    'beforeitemmouseleave',
-                    
-                    'beforeitemclick',
-                    
-                    'beforeitemdblclick',
-                    
-                    'beforeitemcontextmenu',
-                    
-                    'itemmousedown',
-                    
-                    'itemmouseup',
-                    
-                    'itemmouseenter',
-                    
-                    'itemmouseleave',
-                    
-                    'itemclick',
-                    
-                    'itemdblclick',
-                    
-                    'itemcontextmenu',
-                    
-                    'beforecontainermousedown',
-                    
-                    'beforecontainermouseup',
-                    
-                    'beforecontainermouseover',
-                    
-                    'beforecontainermouseout',
-                    
-                    'beforecontainerclick',
-                    
-                    'beforecontainerdblclick',
-                    
-                    'beforecontainercontextmenu',
-                    
-                    'containermouseup',
-                    
-                    'containermouseover',
-                    
-                    'containermouseout',
-                    
-                    'containerclick',
-                    
-                    'containerdblclick',
-                    
-                    'containercontextmenu',
+                    me.mon(view.el, {
+                        mousewheel: me.onMouseWheel,
+                        scope: me
+                    });
+                },
+                single: true
+            });
+            me.items = [view];
+            me.hasView = true;
 
-                    
-                    'selectionchange',
-                    
-                    'beforeselect'
-                ]);
-            }
+            me.mon(view.store, {
+                load: me.onStoreLoad,
+                scope: me
+            });
+            me.mon(view, {
+                viewReady: me.onViewReady,
+                resize: me.onViewResize,
+                refresh: {
+                    fn: me.onViewRefresh,
+                    scope: me,
+                    buffer: 50
+                },
+                scope: me
+            });
+            this.relayEvents(view, [
+                
+                'beforeitemmousedown',
+                
+                'beforeitemmouseup',
+                
+                'beforeitemmouseenter',
+                
+                'beforeitemmouseleave',
+                
+                'beforeitemclick',
+                
+                'beforeitemdblclick',
+                
+                'beforeitemcontextmenu',
+                
+                'itemmousedown',
+                
+                'itemmouseup',
+                
+                'itemmouseenter',
+                
+                'itemmouseleave',
+                
+                'itemclick',
+                
+                'itemdblclick',
+                
+                'itemcontextmenu',
+                
+                'beforecontainermousedown',
+                
+                'beforecontainermouseup',
+                
+                'beforecontainermouseover',
+                
+                'beforecontainermouseout',
+                
+                'beforecontainerclick',
+                
+                'beforecontainerdblclick',
+                
+                'beforecontainercontextmenu',
+                
+                'containermouseup',
+                
+                'containermouseover',
+                
+                'containermouseout',
+                
+                'containerclick',
+                
+                'containerdblclick',
+                
+                'containercontextmenu',
+                
+                'selectionchange',
+                
+                'beforeselect',
+                
+                'select',
+                
+                'beforedeselect',
+                
+                'deselect'
+            ]);
         }
+
         me.callParent(arguments);
     },
+    
+    onRender: function(){
+        var vScroll = this.verticalScroller,
+            hScroll = this.horizontalScroller;
+
+        if (vScroll) {
+            vScroll.ensureDimension();
+        }
+        if (hScroll) {
+            hScroll.ensureDimension();
+        }
+        this.callParent(arguments);    
+    },
 
     
     initStateEvents: function(){
@@ -73658,59 +77409,79 @@ Ext.define('Ext.panel.Table', {
         this.callParent();
     },
 
-    getState: function(){
-        var state = {
-            columns: []
-        },
-        sorter = this.store.sorters.first();
-
-        this.headerCt.items.each(function(header){
-            state.columns.push({
-                id: header.headerId,
-                width: header.flex ? undefined : header.width,
-                hidden: header.hidden,
-                sortable: header.sortable
-            });
+    
+    initHorizontalScroller: function () {
+        var me = this,
+            ret = {
+                xtype: 'gridscroller',
+                dock: 'bottom',
+                section: me,
+                store: me.store
+            };
+
+        return ret;
+    },
+
+    
+    initVerticalScroller: function () {
+        var me = this,
+            ret = me.verticalScroller || {};
+
+        Ext.applyIf(ret, {
+            xtype: me.verticalScrollerType,
+            dock: me.verticalScrollDock,
+            store: me.store
         });
 
+        return ret;
+    },
+
+    relayHeaderCtEvents: function (headerCt) {
+        this.relayEvents(headerCt, [
+            
+            'columnresize',
+            
+            'columnmove',
+            
+            'columnhide',
+            
+            'columnshow',
+            
+            'sortchange'
+        ]);
+    },
+
+    getState: function(){
+        var me = this,
+            state = me.callParent(),
+            sorter = me.store.sorters.first();
+
+        state.columns = (me.headerCt || me).getColumnsState();
+
         if (sorter) {
             state.sort = {
                 property: sorter.property,
                 direction: sorter.direction
             };
         }
+
         return state;
     },
 
     applyState: function(state) {
-        var headers = state.columns,
-            length = headers ? headers.length : 0,
-            headerCt = this.headerCt,
-            items = headerCt.items,
+        var me = this,
             sorter = state.sort,
-            store = this.store,
-            i = 0,
-            index,
-            headerState,
-            header;
+            store = me.store,
+            columns = state.columns;
 
-        for (; i < length; ++i) {
-            headerState = headers[i];
-            header = headerCt.down('gridcolumn[headerId=' + headerState.id + ']');
-            index = items.indexOf(header);
-            if (i !== index) {
-                headerCt.moveHeader(index, i);
-            }
-            header.sortable = headerState.sortable;
-            if (Ext.isDefined(headerState.width)) {
-                delete header.flex;
-                if (header.rendered) {
-                    header.setWidth(headerState.width);
-                } else {
-                    header.minWidth = header.width = headerState.width;
-                }
-            }
-            header.hidden = headerState.hidden;
+        delete state.columns;
+
+        
+        
+        me.callParent(arguments);
+
+        if (columns) {
+            (me.headerCt || me).applyColumnsState(columns);
         }
 
         if (sorter) {
@@ -73739,6 +77510,7 @@ Ext.define('Ext.panel.Table', {
         if (!me.view) {
             sm = me.getSelectionModel();
             me.view = me.createComponent(Ext.apply({}, me.viewConfig, {
+                deferInitialRefresh: me.deferRowRender,
                 xtype: me.viewType,
                 store: me.store,
                 headerCt: me.headerCt,
@@ -73770,46 +77542,21 @@ Ext.define('Ext.panel.Table', {
         if (direction === "up" || direction === "left") {
             distance = -distance;
         }
-
+        
         if (direction === "down" || direction === "up") {
             scroller = me.getVerticalScroller();
-            scroller.scrollByDeltaY(distance);
+            
+            
+            if (scroller) {
+                scroller.scrollByDeltaY(distance);
+            }
         } else {
             scroller = me.getHorizontalScroller();
-            scroller.scrollByDeltaX(distance);
-        }
-    },
-    
-    afterLayout: function() {
-        this.callParent(arguments);
-        this.injectView();
-    },
-    
-
-    
-    injectView: function() {
-        if (!this.hasView && !this.collapsed) {
-            var me   = this,
-                view = me.getView();
-
-            me.hasView = true;
-            me.add(view);
-
-            
-            view.el.scroll = Ext.Function.bind(me.elScroll, me);
             
             
-            me.mon(view.el, {
-                mousewheel: me.onMouseWheel,
-                scope: me
-            });
-        }
-    },
-
-    afterExpand: function() {
-        this.callParent(arguments);
-        if (!this.hasView) {
-            this.injectView();
+            if (scroller) {
+                scroller.scrollByDeltaX(distance);
+            }
         }
     },
 
@@ -73826,54 +77573,144 @@ Ext.define('Ext.panel.Table', {
 
     
     determineScrollbars: function() {
+        
+        if (this.determineScrollbarsRunning) {
+            return;
+        }
+        this.determineScrollbarsRunning = true;
         var me = this,
-            viewElDom,
-            centerScrollWidth,
-            centerClientWidth,
+            view = me.view,
+            box,
+            tableEl,
+            scrollWidth,
+            clientWidth,
             scrollHeight,
-            clientHeight;
+            clientHeight,
+            verticalScroller = me.verticalScroller,
+            horizontalScroller = me.horizontalScroller,
+            curScrollbars = (verticalScroller   && verticalScroller.ownerCt === me ? 1 : 0) |
+                            (horizontalScroller && horizontalScroller.ownerCt === me ? 2 : 0),
+            reqScrollbars = 0; 
+
+        
+        if (!me.collapsed && view && view.viewReady) {
 
-        if (!me.collapsed && me.view && me.view.el) {
-            viewElDom = me.view.el.dom;
             
-            centerScrollWidth = me.headerCt.getFullWidth();
             
-            centerClientWidth = viewElDom.offsetWidth;
-            if (me.verticalScroller && me.verticalScroller.el) {
-                scrollHeight = me.verticalScroller.getSizeCalculation().height;
+            box = view.el.getSize();
+
+            clientWidth  = box.width  + ((curScrollbars & 1) ? verticalScroller.width : 0);
+            clientHeight = box.height + ((curScrollbars & 2) ? horizontalScroller.height : 0);
+
+            
+            
+
+            scrollWidth = (me.headerCt.query('[flex]').length && !me.headerCt.layout.tooNarrow) ? 0 : me.headerCt.getFullWidth();
+
+            
+            if (verticalScroller && verticalScroller.el) {
+                scrollHeight = verticalScroller.getSizeCalculation().height;
             } else {
-                scrollHeight = viewElDom.scrollHeight;
+                tableEl = view.el.child('table', true);
+                scrollHeight = tableEl ? tableEl.offsetHeight : 0;
             }
 
-            clientHeight = viewElDom.clientHeight;
+            
+            
+            if (scrollHeight > clientHeight) {
+                reqScrollbars = 1;
 
-            if (!me.collapsed && scrollHeight > clientHeight) {
-                me.showVerticalScroller();
-            } else {
-                me.hideVerticalScroller();
+                
+                if (horizontalScroller && ((clientWidth - scrollWidth) < verticalScroller.width)) {
+                    reqScrollbars = 3;
+                }
             }
 
-            if (!me.collapsed && centerScrollWidth > (centerClientWidth + Ext.getScrollBarWidth() - 2)) {
-                me.showHorizontalScroller();
-            } else {
-                me.hideHorizontalScroller();
+            
+            else {
+                
+                
+                if (scrollWidth > clientWidth) {
+                    reqScrollbars = 2;
+
+                    
+                    if (verticalScroller && ((clientHeight - scrollHeight) < horizontalScroller.height)) {
+                        reqScrollbars = 3;
+                    }
+                }
+            }
+
+            
+            if (reqScrollbars !== curScrollbars) {
+
+                
+                me.suspendLayout = true;
+                if (reqScrollbars & 1) {
+                    me.showVerticalScroller();
+                } else {
+                    me.hideVerticalScroller();
+                }
+                if (reqScrollbars & 2) {
+                    me.showHorizontalScroller();
+                } else {
+                    me.hideHorizontalScroller();
+                }
+                me.suspendLayout = false;
+
+                
+                me.doComponentLayout();
+                
+                me.getLayout().layout();
             }
         }
+        delete me.determineScrollbarsRunning;
+    },
+
+    onViewResize: function() {
+        this.determineScrollbars();
+    },
+
+    afterComponentLayout: function() {
+        this.callParent(arguments);
+        this.determineScrollbars();
+        this.invalidateScroller();
     },
 
     onHeaderResize: function() {
-        if (this.view && this.view.rendered) {
+        if (!this.componentLayout.layoutBusy && this.view && this.view.rendered) {
             this.determineScrollbars();
             this.invalidateScroller();
         }
     },
 
+    afterCollapse: function() {
+        var me = this;
+        if (me.verticalScroller) {
+            me.verticalScroller.saveScrollPos();
+        }
+        if (me.horizontalScroller) {
+            me.horizontalScroller.saveScrollPos();
+        }
+        me.callParent(arguments);
+    },
+
+    afterExpand: function() {
+        var me = this;
+        me.callParent(arguments);
+        if (me.verticalScroller) {
+            me.verticalScroller.restoreScrollPos();
+        }
+        if (me.horizontalScroller) {
+            me.horizontalScroller.restoreScrollPos();
+        }
+    },
+
     
     hideHorizontalScroller: function() {
         var me = this;
 
         if (me.horizontalScroller && me.horizontalScroller.ownerCt === me) {
-            me.verticalScroller.offsets.bottom = 0;
+            me.verticalScroller.setReservedSpace(0);
             me.removeDocked(me.horizontalScroller, false);
             me.removeCls(me.horizontalScrollerPresentCls);
             me.fireEvent('scrollerhide', me.horizontalScroller, 'horizontal');
@@ -73886,7 +77723,7 @@ Ext.define('Ext.panel.Table', {
         var me = this;
 
         if (me.verticalScroller) {
-            me.verticalScroller.offsets.bottom = Ext.getScrollBarWidth() - 2;
+            me.verticalScroller.setReservedSpace(Ext.getScrollbarSize().height - 1);
         }
         if (me.horizontalScroller && me.horizontalScroller.ownerCt !== me) {
             me.addDocked(me.horizontalScroller);
@@ -73897,14 +77734,9 @@ Ext.define('Ext.panel.Table', {
 
     
     hideVerticalScroller: function() {
-        var me = this,
-            headerCt = me.headerCt;
+        var me = this;
 
-        
-        if (headerCt && headerCt.layout.reserveOffset) {
-            headerCt.layout.reserveOffset = false;
-            headerCt.doLayout();
-        }
+        me.setHeaderReserveOffset(false);
         if (me.verticalScroller && me.verticalScroller.ownerCt === me) {
             me.removeDocked(me.verticalScroller, false);
             me.removeCls(me.verticalScrollerPresentCls);
@@ -73914,14 +77746,9 @@ Ext.define('Ext.panel.Table', {
 
     
     showVerticalScroller: function() {
-        var me = this,
-            headerCt = me.headerCt;
+        var me = this;
 
-        
-        if (headerCt && !headerCt.layout.reserveOffset) {
-            headerCt.layout.reserveOffset = true;
-            headerCt.doLayout();
-        }
+        me.setHeaderReserveOffset(true);
         if (me.verticalScroller && me.verticalScroller.ownerCt !== me) {
             me.addDocked(me.verticalScroller);
             me.addCls(me.verticalScrollerPresentCls);
@@ -73929,6 +77756,19 @@ Ext.define('Ext.panel.Table', {
         }
     },
 
+    setHeaderReserveOffset: function (reserveOffset) {
+        var headerCt = this.headerCt,
+            layout = headerCt.layout;
+
+        
+        if (layout && layout.reserveOffset !== reserveOffset) {
+            layout.reserveOffset = reserveOffset;
+            if (!this.suspendLayout) {
+                headerCt.doLayout();
+            }
+        }
+    },
+
     
     invalidateScroller: function() {
         var me = this,
@@ -73967,125 +77807,68 @@ Ext.define('Ext.panel.Table', {
 
     onMouseWheel: function(e) {
         var me = this,
-            browserEvent = e.browserEvent,
             vertScroller = me.getVerticalScroller(),
             horizScroller = me.getHorizontalScroller(),
-            scrollDelta = me.scrollDelta,
-            deltaY, deltaX,
+            scrollDelta = -me.scrollDelta,
+            deltas = e.getWheelDeltas(),
+            deltaX = scrollDelta * deltas.x,
+            deltaY = scrollDelta * deltas.y,
             vertScrollerEl, horizScrollerEl,
-            origScrollLeft, origScrollTop,
-            newScrollLeft, newScrollTop;
+            vertScrollerElDom, horizScrollerElDom,
+            horizontalCanScrollLeft, horizontalCanScrollRight,
+            verticalCanScrollDown, verticalCanScrollUp;
 
         
-        
         if (horizScroller) {
-            horizScrollerEl = horizScroller.el;
+            horizScrollerEl = horizScroller.scrollEl;
             if (horizScrollerEl) {
-                origScrollLeft = horizScrollerEl.dom.scrollLeft;
+                horizScrollerElDom = horizScrollerEl.dom;
+                horizontalCanScrollRight = horizScrollerElDom.scrollLeft !== horizScrollerElDom.scrollWidth - horizScrollerElDom.clientWidth;
+                horizontalCanScrollLeft  = horizScrollerElDom.scrollLeft !== 0;
             }
         }
         if (vertScroller) {
-            vertScrollerEl = vertScroller.el;
+            vertScrollerEl = vertScroller.scrollEl;
             if (vertScrollerEl) {
-                origScrollTop = vertScrollerEl.dom.scrollTop;
+                vertScrollerElDom = vertScrollerEl.dom;
+                verticalCanScrollDown = vertScrollerElDom.scrollTop !== vertScrollerElDom.scrollHeight - vertScrollerElDom.clientHeight;
+                verticalCanScrollUp   = vertScrollerElDom.scrollTop !== 0;
             }
         }
 
-        
-        if (browserEvent.wheelDeltaX || browserEvent.wheelDeltaY) {
-            deltaX = -browserEvent.wheelDeltaX / 120 * scrollDelta / 3;
-            deltaY = -browserEvent.wheelDeltaY / 120 * scrollDelta / 3;
-            if (horizScroller) {
-                newScrollLeft = horizScroller.scrollByDeltaX(deltaX);
-            }
-            if (vertScroller) {
-                newScrollTop = vertScroller.scrollByDeltaY(deltaY);
-            }
-        } else {
-            
-            if (browserEvent.axis && browserEvent.axis === 1) {
-                if (horizScroller) {
-                    deltaX = -(scrollDelta * e.getWheelDelta()) / 3;
-                    newScrollLeft = horizScroller.scrollByDeltaX(deltaX);
-                }
-            } else {
-                if (vertScroller) {
-
-                    deltaY = -(scrollDelta * e.getWheelDelta() / 3);
-                    newScrollTop = vertScroller.scrollByDeltaY(deltaY);
-                }
+        if (horizScroller) {
+            if ((deltaX < 0 && horizontalCanScrollLeft) || (deltaX > 0 && horizontalCanScrollRight)) {
+                e.stopEvent();
+                horizScroller.scrollByDeltaX(deltaX);
             }
         }
-
-        
-        
-        if ((deltaX !== 0 && newScrollLeft !== origScrollLeft) ||
-            (deltaY !== 0 && newScrollTop !== origScrollTop)) {
-            e.stopEvent();
+        if (vertScroller) {
+            if ((deltaY < 0 && verticalCanScrollUp) || (deltaY > 0 && verticalCanScrollDown)) {
+                e.stopEvent();
+                vertScroller.scrollByDeltaY(deltaY);
+            }
         }
     },
 
     
-    onViewRefresh: function() {
-        if (Ext.isIE) {
-            this.syncCellHeight();
-        }
-        this.determineScrollbars();
-        if (this.invalidateScrollerOnRefresh) {
-            this.invalidateScroller();
-        }
-    },
-
-    onViewItemUpdate: function(record, index, tr) {
-        if (Ext.isIE) {
-            this.syncCellHeight([tr]);
+    onViewReady: function() {
+        var me = this;
+        me.fireEvent('viewready', me);
+        if (me.deferRowRender) {
+            me.determineScrollbars();
+            me.invalidateScroller();
         }
     },
 
     
-    
-    
-    syncCellHeight: function(trs) {
-        var me    = this,
-            i     = 0,
-            tds,
-            j, tdsLn,
-            tr, td,
-            trsLn,
-            rowHeights = [],
-            cellHeights,
-            cellClsSelector = ('.' + Ext.baseCSSPrefix + 'grid-cell');
-
-        trs   = trs || me.view.getNodes();
-        
-        trsLn = trs.length;
-        
-        for (; i < trsLn; i++) {
-            tr = trs[i];
-            tds = Ext.fly(tr).query(cellClsSelector);
-            tdsLn = tds.length;
-            cellHeights = [];
-            for (j = 0; j < tdsLn; j++) {
-                td = tds[j];
-                cellHeights.push(td.clientHeight);
-            }
-            rowHeights.push(Ext.Array.max(cellHeights));
-        }
-
-        
-        for (i = 0; i < trsLn; i++) {
-            tr = trs[i];
-            tdsLn = tr.childNodes.length;
-            for (j = 0; j < tdsLn; j++) {
-                td = Ext.fly(tr.childNodes[j]);
-                if (rowHeights[i]) {
-                    if (td.is(cellClsSelector)) {
-                        td.setHeight(rowHeights[i]);
-                    } else {
-                        td.down(cellClsSelector).setHeight(rowHeights[i]);
-                    }
-                }
-                
+    onViewRefresh: function() {
+        var me = this;
+
+        
+        if (!me.rendering) {
+            this.determineScrollbars();
+            if (this.invalidateScrollerOnRefresh) {
+                this.invalidateScroller();
             }
         }
     },
@@ -74100,7 +77883,6 @@ Ext.define('Ext.panel.Table', {
         if (verticalScroller) {
             verticalScroller.setScrollTop(top);
         }
-
     },
 
     getScrollerOwner: function() {
@@ -74113,18 +77895,20 @@ Ext.define('Ext.panel.Table', {
 
     
     scrollByDeltaY: function(deltaY) {
-        var rootCmp = this.getScrollerOwner(),
-            scrollerRight;
-        scrollerRight = rootCmp.down('gridscroller[dock=' + this.verticalScrollDock + ']');
-        if (scrollerRight) {
-            scrollerRight.scrollByDeltaY(deltaY);
+        var verticalScroller = this.getVerticalScroller();
+
+        if (verticalScroller) {
+            verticalScroller.scrollByDeltaY(deltaY);
         }
     },
 
-
     
     scrollByDeltaX: function(deltaX) {
-        this.horizontalScroller.scrollByDeltaX(deltaX);
+        var horizontalScroller = this.getHorizontalScroller();
+
+        if (horizontalScroller) {
+            horizontalScroller.scrollByDeltaX(deltaX);
+        }
     },
 
     
@@ -74132,7 +77916,7 @@ Ext.define('Ext.panel.Table', {
         var me = this;
 
         if (!me.lhsMarker) {
-            me.lhsMarker = Ext.core.DomHelper.append(me.el, {
+            me.lhsMarker = Ext.DomHelper.append(me.el, {
                 cls: Ext.baseCSSPrefix + 'grid-resize-marker'
             }, true);
         }
@@ -74144,7 +77928,7 @@ Ext.define('Ext.panel.Table', {
         var me = this;
 
         if (!me.rhsMarker) {
-            me.rhsMarker = Ext.core.DomHelper.append(me.el, {
+            me.rhsMarker = Ext.DomHelper.append(me.el, {
                 cls: Ext.baseCSSPrefix + 'grid-resize-marker'
             }, true);
         }
@@ -74176,7 +77960,9 @@ Ext.define('Ext.panel.Table', {
         }
 
         if (!this.selModel.hasRelaySetup) {
-            this.relayEvents(this.selModel, ['selectionchange', 'select', 'deselect']);
+            this.relayEvents(this.selModel, [
+                'selectionchange', 'beforeselect', 'beforedeselect', 'select', 'deselect'
+            ]);
             this.selModel.hasRelaySetup = true;
         }
 
@@ -74202,21 +77988,9 @@ Ext.define('Ext.panel.Table', {
     onHorizontalScroll: function(event, target) {
         var owner = this.getScrollerOwner(),
             items = owner.query('tableview'),
-            i = 0,
-            len = items.length,
-            center,
-            centerEl,
-            centerScrollWidth,
-            centerClientWidth,
-            width;
-
-        center = items[1] || items[0];
-        centerEl = center.el.dom;
-        centerScrollWidth = centerEl.scrollWidth;
-        centerClientWidth = centerEl.offsetWidth;
-        width = this.horizontalScroller.getWidth();
+            center = items[1] || items[0];
 
-        centerEl.scrollLeft = target.scrollLeft;
+        center.el.dom.scrollLeft = target.scrollLeft;
         this.headerCt.el.dom.scrollLeft = target.scrollLeft;
     },
 
@@ -74232,31 +78006,40 @@ Ext.define('Ext.panel.Table', {
         me.store = store;
         me.getView().bindStore(store);
     },
+    
+    beforeDestroy: function(){
+        
+        
+        
+        Ext.destroy(this.horizontalScroller, this.verticalScroller);
+        this.callParent();
+    },
 
+    
     reconfigure: function(store, columns) {
-        var me = this;
+        var me = this,
+            headerCt = me.headerCt;
 
         if (me.lockable) {
             me.reconfigureLockable(store, columns);
-            return;
-        }
-
-        if (columns) {
-            me.headerCt.removeAll();
-            me.headerCt.add(columns);
-        }
-        if (store) {
-            store = Ext.StoreManager.lookup(store);
-            me.bindStore(store);
         } else {
-            me.getView().refresh();
+            if (columns) {
+                headerCt.suspendLayout = true;
+                headerCt.removeAll();
+                headerCt.add(columns);
+            }
+            if (store) {
+                store = Ext.StoreManager.lookup(store);
+                me.bindStore(store);
+            } else {
+                me.getView().refresh();
+            }
+            if (columns) {
+                headerCt.suspendLayout = false;
+                me.forceComponentLayout();
+            }
         }
-    },
-
-    afterComponentLayout: function() {
-        this.callParent(arguments);
-        this.determineScrollbars();
-        this.invalidateScroller();
+        me.fireEvent('reconfigure', me);
     }
 });
 
@@ -74269,7 +78052,7 @@ Ext.define('Ext.view.Table', {
         'Ext.util.MixedCollection'
     ],
 
-    cls: Ext.baseCSSPrefix + 'grid-view',
+    baseCls: Ext.baseCSSPrefix + 'grid-view',
 
     
     itemSelector: '.' + Ext.baseCSSPrefix + 'grid-row',
@@ -74291,15 +78074,17 @@ Ext.define('Ext.view.Table', {
     getRowClass: null,
 
     initComponent: function() {
-        this.scrollState = {};
-        this.selModel.view = this;
-        this.headerCt.view = this;
-        this.initFeatures();
-        this.setNewTemplate();
-        this.callParent();
-        this.mon(this.store, {
-            load: this.onStoreLoad,
-            scope: this
+        var me = this;
+
+        me.scrollState = {};
+        me.selModel.view = me;
+        me.headerCt.view = me;
+        me.initFeatures();
+        me.tpl = '<div></div>';
+        me.callParent();
+        me.mon(me.store, {
+            load: me.onStoreLoad,
+            scope: me
         });
 
         
@@ -74315,31 +78100,40 @@ Ext.define('Ext.view.Table', {
 
     
     onStoreLoad: function(){
-        if (this.invalidateScrollerOnRefresh) {
+        var me = this;
+
+        if (me.invalidateScrollerOnRefresh) {
             if (Ext.isGecko) {
-                if (!this.scrollToTopTask) {
-                    this.scrollToTopTask = Ext.create('Ext.util.DelayedTask', this.scrollToTop, this);
+                if (!me.scrollToTopTask) {
+                    me.scrollToTopTask = Ext.create('Ext.util.DelayedTask', me.scrollToTop, me);
                 }
-                this.scrollToTopTask.delay(1);
+                me.scrollToTopTask.delay(1);
             } else {
-                this.scrollToTop();
+                me    .scrollToTop();
             }
         }
     },
 
     
     scrollToTop: Ext.emptyFn,
+
     
+    addElListener: function(eventName, fn, scope){
+        this.mon(this, eventName, fn, scope, {
+            element: 'el'
+        });
+    },
+
     
     getGridColumns: function() {
-        return this.headerCt.getGridColumns();    
+        return this.headerCt.getGridColumns();
     },
-    
+
     
     getHeaderAtIndex: function(index) {
         return this.headerCt.getHeaderAtIndex(index);
     },
-    
+
     
     getCell: function(record, column) {
         var row = this.getNode(record);
@@ -74356,20 +78150,24 @@ Ext.define('Ext.view.Table', {
 
     
     initFeatures: function() {
-        this.features = this.features || [];
-        var features = this.features,
-            ln       = features.length,
-            i        = 0;
+        var me = this,
+            i = 0,
+            features,
+            len;
 
-        this.featuresMC = Ext.create('Ext.util.MixedCollection');
-        for (; i < ln; i++) {
+        me.features = me.features || [];
+        features = me.features;
+        len = features.length;
+
+        me.featuresMC = Ext.create('Ext.util.MixedCollection');
+        for (; i < len; i++) {
             
             if (!features[i].isFeature) {
-                features[i] = Ext.create('feature.'+features[i].ftype, features[i]);
+                features[i] = Ext.create('feature.' + features[i].ftype, features[i]);
             }
             
-            features[i].view = this;
-            this.featuresMC.add(features[i]);
+            features[i].view = me;
+            me.featuresMC.add(features[i]);
         }
     },
 
@@ -74387,12 +78185,15 @@ Ext.define('Ext.view.Table', {
     },
 
     afterRender: function() {
-        this.callParent();
-        this.mon(this.el, {
-            scroll: this.fireBodyScroll,
-            scope: this
+        var me = this;
+
+        me.callParent();
+        me.mon(me.el, {
+            scroll: me.fireBodyScroll,
+            scope: me
         });
-        this.attachEventsForFeatures();
+        me.el.unselectable();
+        me.attachEventsForFeatures();
     },
 
     fireBodyScroll: function(e, t) {
@@ -74402,8 +78203,9 @@ Ext.define('Ext.view.Table', {
     
     
     prepareData: function(data, idx, record) {
-        var orig     = this.headerCt.prepareData(data, idx, record, this),
-            features = this.features,
+        var me       = this,
+            orig     = me.headerCt.prepareData(data, idx, record, me, me.ownerCt),
+            features = me.features,
             ln       = features.length,
             i        = 0,
             node, feature;
@@ -74411,7 +78213,7 @@ Ext.define('Ext.view.Table', {
         for (; i < ln; i++) {
             feature = features[i];
             if (feature.isFeature) {
-                Ext.apply(orig, feature.getAdditionalData(data, idx, record, orig, this));
+                Ext.apply(orig, feature.getAdditionalData(data, idx, record, orig, me));
             }
         }
 
@@ -74442,24 +78244,6 @@ Ext.define('Ext.view.Table', {
             for (; j < jln; j++) {
                 rowParams = {};
                 preppedRecords[j]['rowCls'] = this.getRowClass(records[j], j, rowParams, this.store);
-                if (rowParams.alt) {
-                    Ext.Error.raise("The getRowClass alt property is no longer supported.");
-                }
-                if (rowParams.tstyle) {
-                    Ext.Error.raise("The getRowClass tstyle property is no longer supported.");
-                }
-                if (rowParams.cells) {
-                    Ext.Error.raise("The getRowClass cells property is no longer supported.");
-                }
-                if (rowParams.body) {
-                    Ext.Error.raise("The getRowClass body property is no longer supported. Use the getAdditionalData method of the rowbody feature.");
-                }
-                if (rowParams.bodyStyle) {
-                    Ext.Error.raise("The getRowClass bodyStyle property is no longer supported.");
-                }
-                if (rowParams.cols) {
-                    Ext.Error.raise("The getRowClass cols property is no longer supported.");
-                }
             }
         }
         
@@ -74477,35 +78261,51 @@ Ext.define('Ext.view.Table', {
     
     
     onHeaderResize: function(header, w, suppressFocus) {
-        var el = this.el;
+        var me = this,
+            el = me.el;
+
         if (el) {
-            this.saveScrollState();
+            me.saveScrollState();
+            
+            
+            
+
             
             
             
+            if (Ext.isIE6 || Ext.isIE7) {
+                if (header.el.hasCls(Ext.baseCSSPrefix + 'column-header-first')) {
+                    w += 1;
+                }
+            }
             el.select('.' + Ext.baseCSSPrefix + 'grid-col-resizer-'+header.id).setWidth(w);
-            el.select('.' + Ext.baseCSSPrefix + 'grid-table-resizer').setWidth(this.headerCt.getFullWidth());
-            this.restoreScrollState();
-            this.setNewTemplate();
+            el.select('.' + Ext.baseCSSPrefix + 'grid-table-resizer').setWidth(me.headerCt.getFullWidth());
+            me.restoreScrollState();
+            if (!me.ignoreTemplate) {
+                me.setNewTemplate();
+            }
             if (!suppressFocus) {
-                this.el.focus();
+                me.el.focus();
             }
         }
     },
 
     
     onHeaderShow: function(headerCt, header, suppressFocus) {
+        var me = this;
+        me.ignoreTemplate = true;
         
         if (header.oldWidth) {
-            this.onHeaderResize(header, header.oldWidth, suppressFocus);
+            me.onHeaderResize(header, header.oldWidth, suppressFocus);
             delete header.oldWidth;
         
         
         
         } else if (header.width && !header.flex) {
-            this.onHeaderResize(header, header.width, suppressFocus);
+            me.onHeaderResize(header, header.width, suppressFocus);
         }
-        this.setNewTemplate();
+        delete me.ignoreTemplate;
+        me.setNewTemplate();
     },
 
     
@@ -74515,10 +78315,12 @@ Ext.define('Ext.view.Table', {
 
     
     setNewTemplate: function() {
-        var columns = this.headerCt.getColumnsForTpl(true);
-        this.tpl = this.getTableChunker().getTableTpl({
+        var me = this,
+            columns = me.headerCt.getColumnsForTpl(true);
+
+        me.tpl = me.getTableChunker().getTableTpl({
             columns: columns,
-            features: this.features
+            features: me.features
         });
     },
 
@@ -74550,30 +78352,32 @@ Ext.define('Ext.view.Table', {
 
     
     onRowDeselect : function(rowIdx) {
-        this.removeRowCls(rowIdx, this.selectedItemCls);
-        this.removeRowCls(rowIdx, this.focusedItemCls);
+        var me = this;
+
+        me.removeRowCls(rowIdx, me.selectedItemCls);
+        me.removeRowCls(rowIdx, me.focusedItemCls);
     },
-    
+
     onCellSelect: function(position) {
         var cell = this.getCellByPosition(position);
         if (cell) {
             cell.addCls(this.selectedCellCls);
         }
     },
-    
+
     onCellDeselect: function(position) {
         var cell = this.getCellByPosition(position);
         if (cell) {
             cell.removeCls(this.selectedCellCls);
         }
-        
+
     },
-    
+
     onCellFocus: function(position) {
         
         this.focusCell(position);
     },
-    
+
     getCellByPosition: function(position) {
         var row    = position.row,
             column = position.column,
@@ -74582,8 +78386,8 @@ Ext.define('Ext.view.Table', {
             header = this.headerCt.getHeaderAtIndex(column),
             cellSelector,
             cell = false;
-            
-        if (header) {
+
+        if (header && node) {
             cellSelector = header.getCellSelector();
             cell = Ext.fly(node).down(cellSelector);
         }
@@ -74593,30 +78397,32 @@ Ext.define('Ext.view.Table', {
     
     
     onRowFocus: function(rowIdx, highlight, supressFocus) {
-        var row = this.getNode(rowIdx);
+        var me = this,
+            row = me.getNode(rowIdx);
 
         if (highlight) {
-            this.addRowCls(rowIdx, this.focusedItemCls);
+            me.addRowCls(rowIdx, me.focusedItemCls);
             if (!supressFocus) {
-                this.focusRow(rowIdx);
+                me.focusRow(rowIdx);
             }
             
         } else {
-            this.removeRowCls(rowIdx, this.focusedItemCls);
+            me.removeRowCls(rowIdx, me.focusedItemCls);
         }
     },
 
     
     focusRow: function(rowIdx) {
-        var row        = this.getNode(rowIdx),
-            el         = this.el,
+        var me         = this,
+            row        = me.getNode(rowIdx),
+            el         = me.el,
             adjustment = 0,
-            panel      = this.ownerCt,
+            panel      = me.ownerCt,
             rowRegion,
             elRegion,
             record;
-            
-        if (row && this.el) {
+
+        if (row && el) {
             elRegion  = el.getRegion();
             rowRegion = Ext.fly(row).getRegion();
             
@@ -74626,24 +78432,25 @@ Ext.define('Ext.view.Table', {
             } else if (rowRegion.bottom > elRegion.bottom) {
                 adjustment = rowRegion.bottom - elRegion.bottom;
             }
-            record = this.getRecord(row);
-            rowIdx = this.store.indexOf(record);
+            record = me.getRecord(row);
+            rowIdx = me.store.indexOf(record);
 
             if (adjustment) {
                 
                 panel.scrollByDeltaY(adjustment);
             }
-            this.fireEvent('rowfocus', record, row, rowIdx);
+            me.fireEvent('rowfocus', record, row, rowIdx);
         }
     },
 
     focusCell: function(position) {
-        var cell        = this.getCellByPosition(position),
-            el          = this.el,
+        var me          = this,
+            cell        = me.getCellByPosition(position),
+            el          = me.el,
             adjustmentY = 0,
             adjustmentX = 0,
             elRegion    = el.getRegion(),
-            panel       = this.ownerCt,
+            panel       = me.ownerCt,
             cellRegion,
             record;
 
@@ -74673,7 +78480,7 @@ Ext.define('Ext.view.Table', {
                 panel.scrollByDeltaX(adjustmentX);
             }
             el.focus();
-            this.fireEvent('cellfocus', record, cell, position);
+            me.fireEvent('cellfocus', record, cell, position);
         }
     },
 
@@ -74690,64 +78497,40 @@ Ext.define('Ext.view.Table', {
 
     
     saveScrollState: function() {
-        var dom = this.el.dom,
-            state = this.scrollState;
-
-        state.left = dom.scrollLeft;
-        state.top = dom.scrollTop;
+        if (this.rendered) {
+            var dom = this.el.dom, 
+                state = this.scrollState;
+            
+            state.left = dom.scrollLeft;
+            state.top = dom.scrollTop;
+        }
     },
 
     
     restoreScrollState: function() {
-        var dom = this.el.dom,
-            state = this.scrollState,
-            headerEl = this.headerCt.el.dom;
-
-        headerEl.scrollLeft = dom.scrollLeft = state.left;
-        dom.scrollTop = state.top;
+        if (this.rendered) {
+            var dom = this.el.dom, 
+                state = this.scrollState, 
+                headerEl = this.headerCt.el.dom;
+            
+            headerEl.scrollLeft = dom.scrollLeft = state.left;
+            dom.scrollTop = state.top;
+        }
     },
 
     
-    refresh: function(firstPass) {
-        var me = this,
-            table;
-
-        
-        me.setNewTemplate();
-        
-        
-        
-        
-        if (me.rendered) {
-            table = me.el.child('table');
-            if (table) {
-                table.removeAllListeners();
-            }
-        }
-        
-        me.callParent(arguments);
-
-        
-        if (me.rendered) {
-            
-            table = me.el.child('table');
-            if (table) {
-                table.unselectable();
-            }
-            
-            if (!firstPass) {
-                
-                me.el.focus();
-            }
-        }
+    refresh: function() {
+        this.setNewTemplate();
+        this.callParent(arguments);
     },
 
-    processItemEvent: function(type, record, row, rowIndex, e) {
+    processItemEvent: function(record, row, rowIndex, e) {
         var me = this,
             cell = e.getTarget(me.cellSelector, row),
             cellIndex = cell ? cell.cellIndex : -1,
             map = me.statics().EventMap,
             selModel = me.getSelectionModel(),
+            type = e.type,
             result;
 
         if (type == 'keydown' && !cell && selModel.getCurrentPosition) {
@@ -74781,15 +78564,15 @@ Ext.define('Ext.view.Table', {
 
     processSpecialEvent: function(e) {
         var me = this,
-            map = this.statics().EventMap,
-            features = this.features,
+            map = me.statics().EventMap,
+            features = me.features,
             ln = features.length,
             type = e.type,
             i, feature, prefix, featureTarget,
             beforeArgs, args,
             panel = me.ownerCt;
 
-        this.callParent(arguments);
+        me.callParent(arguments);
 
         if (type == 'mouseover' || type == 'mouseout') {
             return;
@@ -74803,9 +78586,9 @@ Ext.define('Ext.view.Table', {
                     prefix = feature.eventPrefix;
                     
                     
-                    beforeArgs = feature.getFireEventArgs('before' + prefix + type, me, featureTarget);
-                    args = feature.getFireEventArgs(prefix + type, me, featureTarget);
-                    
+                    beforeArgs = feature.getFireEventArgs('before' + prefix + type, me, featureTarget, e);
+                    args = feature.getFireEventArgs(prefix + type, me, featureTarget, e);
+
                     if (
                         
                         (me.fireEvent.apply(me, beforeArgs) === false) ||
@@ -74839,9 +78622,11 @@ Ext.define('Ext.view.Table', {
 
     
     expandToFit: function(header) {
-        var maxWidth = this.getMaxContentWidth(header);
-        delete header.flex;
-        header.setWidth(maxWidth);
+        if (header) {
+            var maxWidth = this.getMaxContentWidth(header);
+            delete header.flex;
+            header.setWidth(maxWidth);
+        }
     },
 
     
@@ -74863,12 +78648,13 @@ Ext.define('Ext.view.Table', {
     },
 
     getPositionByEvent: function(e) {
-        var cellNode = e.getTarget(this.cellSelector),
-            rowNode  = e.getTarget(this.itemSelector),
-            record   = this.getRecord(rowNode),
-            header   = this.getHeaderByCell(cellNode);
+        var me       = this,
+            cellNode = e.getTarget(me.cellSelector),
+            rowNode  = e.getTarget(me.itemSelector),
+            record   = me.getRecord(rowNode),
+            header   = me.getHeaderByCell(cellNode);
 
-        return this.getPosition(record, header);
+        return me.getPosition(record, header);
     },
 
     getHeaderByCell: function(cell) {
@@ -74883,13 +78669,14 @@ Ext.define('Ext.view.Table', {
 
     
     walkCells: function(pos, direction, e, preventWrap, verifierFn, scope) {
-        var row      = pos.row,
+        var me       = this,
+            row      = pos.row,
             column   = pos.column,
-            rowCount = this.store.getCount(),
-            firstCol = this.getFirstVisibleColumnIndex(),
-            lastCol  = this.getLastVisibleColumnIndex(),
+            rowCount = me.store.getCount(),
+            firstCol = me.getFirstVisibleColumnIndex(),
+            lastCol  = me.getLastVisibleColumnIndex(),
             newPos   = {row: row, column: column},
-            activeHeader = this.headerCt.getHeaderAtIndex(column);
+            activeHeader = me.headerCt.getHeaderAtIndex(column);
 
         
         if (!activeHeader || activeHeader.hidden) {
@@ -74914,7 +78701,7 @@ Ext.define('Ext.view.Table', {
                 
                 } else {
                     if (!e.ctrlKey) {
-                        newPos.column = column + this.getRightGap(activeHeader);
+                        newPos.column = column + me.getRightGap(activeHeader);
                     } else {
                         newPos.column = lastCol;
                     }
@@ -74936,7 +78723,7 @@ Ext.define('Ext.view.Table', {
                 
                 } else {
                     if (!e.ctrlKey) {
-                        newPos.column = column + this.getLeftGap(activeHeader);
+                        newPos.column = column + me.getLeftGap(activeHeader);
                     } else {
                         newPos.column = firstCol;
                     }
@@ -75031,10 +78818,7 @@ Ext.define('Ext.view.Table', {
 
     beforeDestroy: function() {
         if (this.rendered) {
-            table = this.el.child('table');
-            if (table) {
-                table.removeAllListeners();
-            }
+            this.el.removeAllListeners();
         }
         this.callParent(arguments);
     },
@@ -75064,15 +78848,15 @@ Ext.define('Ext.grid.View', {
 
     
     stripeRows: true,
-    
+
     invalidateScrollerOnRefresh: true,
-    
+
     
     scrollToTop : function(){
         if (this.rendered) {
             var section = this.ownerCt,
                 verticalScroller = section.verticalScroller;
-                
+
             if (verticalScroller) {
                 verticalScroller.scrollToTop();
             }
@@ -75084,34 +78868,41 @@ Ext.define('Ext.grid.View', {
         this.callParent(arguments);
         this.doStripeRows(index);
     },
-    
+
     
     onRemove: function(ds, records, index) {
         this.callParent(arguments);
         this.doStripeRows(index);
     },
+
+    onUpdate: function(ds, record, operation) {
+        var index = ds.indexOf(record);
+        this.callParent(arguments);
+        this.doStripeRows(index, index);
+    },
+
     
-    
-    doStripeRows: function(startRow) {
+    doStripeRows: function(startRow, endRow) {
         
         if (this.stripeRows) {
-            var rows   = this.getNodes(startRow),
+            var rows   = this.getNodes(startRow, endRow),
                 rowsLn = rows.length,
                 i      = 0,
                 row;
-                
+
             for (; i < rowsLn; i++) {
                 row = rows[i];
                 
                 row.className = row.className.replace(this.rowClsRe, ' ');
+                startRow++;
                 
-                if (i % 2 === 1) {
+                if (startRow % 2 === 0) {
                     row.className += (' ' + this.altRowCls);
                 }
             }
         }
     },
-    
+
     refresh: function(firstPass) {
         this.callParent(arguments);
         this.doStripeRows(0);
@@ -75130,31 +78921,31 @@ Ext.define('Ext.grid.Panel', {
     alias: ['widget.gridpanel', 'widget.grid'],
     alternateClassName: ['Ext.list.ListView', 'Ext.ListView', 'Ext.grid.GridPanel'],
     viewType: 'gridview',
-    
+
     lockable: false,
-    
+
     
     
     normalCfgCopy: ['invalidateScrollerOnRefresh', 'verticalScroller', 'verticalScrollDock', 'verticalScrollerType', 'scroll'],
     lockedCfgCopy: ['invalidateScrollerOnRefresh'],
+
     
-    
-    
+
     initComponent: function() {
         var me = this;
 
         if (me.columnLines) {
             me.setColumnLines(me.columnLines);
         }
-        
+
         me.callParent();
     },
-    
+
     setColumnLines: function(show) {
         var me = this,
             method = (show) ? 'addClsWithUI' : 'removeClsWithUI';
-        
-        me[method]('with-col-lines')
+
+        me[method]('with-col-lines');
     }
 });
 
@@ -75166,6 +78957,7 @@ Ext.define('Ext.grid.Panel', {
 
 
 
+
 Ext.define('Ext.grid.RowEditor', {
     extend: 'Ext.form.Panel',
     requires: [
@@ -75183,6 +78975,10 @@ Ext.define('Ext.grid.RowEditor', {
     lastScrollTop: 0,
 
     border: false,
+    
+    
+    
+    hideMode: 'offsets',
 
     initComponent: function() {
         var me = this,
@@ -75353,7 +79149,7 @@ Ext.define('Ext.grid.RowEditor', {
         }
     },
 
-    onFieldAdd: function(hm, fieldId, column) {
+    onFieldAdd: function(map, fieldId, column) {
         var me = this,
             colIdx = me.editingPlugin.grid.headerCt.getHeaderIndex(column),
             field = column.getEditor({ xtype: 'displayfield' });
@@ -75361,24 +79157,26 @@ Ext.define('Ext.grid.RowEditor', {
         me.insert(colIdx, field);
     },
 
-    onFieldRemove: function(hm, fieldId, column) {
+    onFieldRemove: function(map, fieldId, column) {
         var me = this,
             field = column.getEditor(),
-            fieldDom = field.el.dom;
+            fieldEl = field.el;
         me.remove(field, false);
-        fieldDom.parentNode.removeChild(fieldDom);
+        if (fieldEl) {
+            fieldEl.remove();
+        }
     },
 
-    onFieldReplace: function(hm, fieldId, column, oldColumn) {
+    onFieldReplace: function(map, fieldId, column, oldColumn) {
         var me = this;
-        me.onFieldRemove(hm, fieldId, oldColumn);
+        me.onFieldRemove(map, fieldId, oldColumn);
     },
 
     clearFields: function() {
         var me = this,
-            hm = me.columns;
-        hm.each(function(fieldId) {
-            hm.removeAtKey(fieldId);
+            map = me.columns;
+        map.each(function(fieldId) {
+            map.removeAtKey(fieldId);
         });
     },
 
@@ -75558,14 +79356,27 @@ Ext.define('Ext.grid.RowEditor', {
         }
 
         
-        field = column.getEditor(null, { xtype: 'displayfield' });
+        field = column.getEditor(null, {
+            xtype: 'displayfield',
+            
+            
+            getModelData: function() {
+                return null;
+            }
+        });
         field.margins = '0 0 0 2';
-        field.setWidth(column.getWidth() - 2);
+        field.setWidth(column.getDesiredWidth() - 2);
         me.mon(field, 'change', me.onFieldChange, me);
 
         
         
         me.columns.add(field.id, column);
+        if (column.hidden) {
+            me.onColumnHide(column);
+        }
+        if (me.isVisible() && me.context) {
+            me.renderColumnData(field, me.context.record);
+        }
     },
 
     loadRecord: function(record) {
@@ -75591,7 +79402,7 @@ Ext.define('Ext.grid.RowEditor', {
             view = grid.view,
             store = view.store,
             column = me.columns.get(field.id),
-            value = field.getRawValue();
+            value = record.get(column.dataIndex);
 
         
         if (column.renderer) {
@@ -75840,10 +79651,10 @@ Ext.define('Ext.grid.header.Container', {
 
     
     sortable: true,
-    
+
     initComponent: function() {
         var me = this;
-        
+
         me.headerCounter = 0;
         me.plugins = me.plugins || [];
 
@@ -75857,7 +79668,7 @@ Ext.define('Ext.grid.header.Container', {
             me.reorderer = Ext.create('Ext.grid.plugin.HeaderReorderer');
             if (!me.enableColumnResize) {
                 me.resizer.disable();
-            } 
+            }
             if (!me.enableColumnMove) {
                 me.reorderer.disable();
             }
@@ -75911,6 +79722,55 @@ Ext.define('Ext.grid.header.Container', {
         Ext.destroy(this.resizer, this.reorderer);
         this.callParent();
     },
+    
+    applyDefaults: function(config){
+        
+        if (config && !config.isComponent && config.xtype == 'rownumberer') {
+            return config;
+        }
+        return this.callParent([config]);
+    },
+
+    applyColumnsState: function(columns) {
+        if (!columns || !columns.length) {
+            return;
+        }
+
+        var me = this,
+            i = 0,
+            index,
+            col;
+
+        Ext.each(columns, function (columnState) {
+            col = me.down('gridcolumn[headerId=' + columnState.id + ']');
+            if (col) {
+                index = me.items.indexOf(col);
+                if (i !== index) {
+                    me.moveHeader(index, i);
+                }
+
+                if (col.applyColumnState) {
+                    col.applyColumnState(columnState);
+                }
+                ++i;
+            }
+        });
+    },
+
+    getColumnsState: function () {
+        var me = this,
+            columns = [],
+            state;
+
+        me.items.each(function (col) {
+            state = col.getColumnState && col.getColumnState();
+            if (state) {
+                columns.push(state);
+            }
+        });
+
+        return columns;
+    },
 
     
     
@@ -75918,7 +79778,7 @@ Ext.define('Ext.grid.header.Container', {
     onAdd: function(c) {
         var me = this;
         if (!c.headerId) {
-            c.headerId = 'h' + (++me.headerCounter);
+            c.headerId = c.initialConfig.id || ('h' + (++me.headerCounter));
         }
         me.callParent(arguments);
         me.purgeCache();
@@ -75952,18 +79812,36 @@ Ext.define('Ext.grid.header.Container', {
         if (!this.isHeader) {
             var me = this,
                 topHeaders = me.query('>gridcolumn:not([hidden])'),
-                viewEl;
+                viewEl,
+                firstHeaderEl,
+                lastHeaderEl;
 
             me.callParent(arguments);
 
             if (topHeaders.length) {
-                topHeaders[0].el.radioCls(me.firstHeaderCls);
-                topHeaders[topHeaders.length - 1].el.radioCls(me.lastHeaderCls);
+                firstHeaderEl = topHeaders[0].el;
+                if (firstHeaderEl !== me.pastFirstHeaderEl) {
+                    if (me.pastFirstHeaderEl) {
+                        me.pastFirstHeaderEl.removeCls(me.firstHeaderCls);
+                    }
+                    firstHeaderEl.addCls(me.firstHeaderCls);
+                    me.pastFirstHeaderEl = firstHeaderEl;
+                }
+
+                lastHeaderEl = topHeaders[topHeaders.length - 1].el;
+                if (lastHeaderEl !== me.pastLastHeaderEl) {
+                    if (me.pastLastHeaderEl) {
+                        me.pastLastHeaderEl.removeCls(me.lastHeaderCls);
+                    }
+                    lastHeaderEl.addCls(me.lastHeaderCls);
+                    me.pastLastHeaderEl = lastHeaderEl;
+                }
             }
         }
+
     },
 
-    onHeaderShow: function(header) {
+    onHeaderShow: function(header, preventLayout) {
         
         var me = this,
             gridSection = me.ownerCt,
@@ -76014,7 +79892,20 @@ Ext.define('Ext.grid.header.Container', {
         me.fireEvent('columnshow', me, header);
 
         
-        me.doLayout();
+        if (preventLayout !== true) {
+            me.doLayout();
+        }
+    },
+
+    doComponentLayout: function(){
+        var me = this;
+        if (me.view && me.view.saveScrollState) {
+            me.view.saveScrollState();
+        }
+        me.callParent(arguments);
+        if (me.view && me.view.restoreScrollState) {
+            me.view.restoreScrollState();
+        }
     },
 
     onHeaderHide: function(header, suppressLayout) {
@@ -76076,6 +79967,10 @@ Ext.define('Ext.grid.header.Container', {
             for (i = 0; i < len; i++) {
                 itemToDisable = itemsToDisable[i];
                 if (!Ext.Array.contains(me.disabledMenuItems, itemToDisable)) {
+
+                    
+                    
+                    itemToDisable.disabled = false;
                     itemToDisable[itemToDisable.menu ? 'disableCheckChange' : 'disable']();
                     me.disabledMenuItems.push(itemToDisable);
                 }
@@ -76096,7 +79991,6 @@ Ext.define('Ext.grid.header.Container', {
         if (this.view && this.view.rendered) {
             this.view.onHeaderResize(header, w, suppressFocus);
         }
-        this.fireEvent('columnresize', this, header, w);
     },
 
     onHeaderClick: function(header, e, t) {
@@ -76150,6 +80044,7 @@ Ext.define('Ext.grid.header.Container', {
         var me = this;
         
         delete me.gridDataColumns;
+        delete me.hideableColumns;
 
         
         if (me.menu) {
@@ -76162,7 +80057,7 @@ Ext.define('Ext.grid.header.Container', {
         var me = this,
             gridSection = me.ownerCt;
 
-        if (gridSection) {
+        if (gridSection && gridSection.onHeaderMove) {
             gridSection.onHeaderMove(me, header, fromIdx, toIdx);
         }
         me.fireEvent("columnmove", me, header, fromIdx, toIdx);
@@ -76174,6 +80069,7 @@ Ext.define('Ext.grid.header.Container', {
 
         if (!me.menu) {
             me.menu = Ext.create('Ext.menu.Menu', {
+                hideOnParentHide: false,  
                 items: me.getMenuItems(),
                 listeners: {
                     deactivate: me.onMenuDeactivate,
@@ -76189,27 +80085,31 @@ Ext.define('Ext.grid.header.Container', {
     
     getMenuItems: function() {
         var me = this,
-            menuItems = [{
-                itemId: 'columnItem',
-                text: me.columnsText,
-                cls: Ext.baseCSSPrefix + 'cols-icon',
-                menu: me.getColumnMenu(me)
-            }];
+            menuItems = [],
+            hideableColumns = me.enableColumnHide ? me.getColumnMenu(me) : null;
 
         if (me.sortable) {
-            menuItems.unshift({
+            menuItems = [{
                 itemId: 'ascItem',
                 text: me.sortAscText,
-                cls: 'xg-hmenu-sort-asc',
+                cls: Ext.baseCSSPrefix + 'hmenu-sort-asc',
                 handler: me.onSortAscClick,
                 scope: me
             },{
                 itemId: 'descItem',
                 text: me.sortDescText,
-                cls: 'xg-hmenu-sort-desc',
+                cls: Ext.baseCSSPrefix + 'hmenu-sort-desc',
                 handler: me.onSortDescClick,
                 scope: me
-            },'-');
+            }];
+        }
+        if (hideableColumns && hideableColumns.length) {
+            menuItems.push('-', {
+                itemId: 'columnItem',
+                text: me.columnsText,
+                cls: Ext.baseCSSPrefix + 'cols-icon',
+                menu: hideableColumns
+            });
         }
         return menuItems;
     },
@@ -76275,14 +80175,27 @@ Ext.define('Ext.grid.header.Container', {
             headers   = this.getGridColumns(flushCache),
             headersLn = headers.length,
             i = 0,
-            header;
+            header,
+            width;
 
         for (; i < headersLn; i++) {
             header = headers[i];
+
+            if (header.hidden || header.up('headercontainer[hidden=true]')) {
+                width = 0;
+            } else {
+                width = header.getDesiredWidth();
+                
+                
+                
+                if ((i === 0) && (Ext.isIE6 || Ext.isIE7)) {
+                    width += 1;
+                }
+            }
             cols.push({
                 dataIndex: header.dataIndex,
                 align: header.align,
-                width: header.hidden ? 0 : header.getDesiredWidth(),
+                width: width,
                 id: header.id,
                 cls: header.tdCls,
                 columnId: header.getItemId()
@@ -76360,6 +80273,17 @@ Ext.define('Ext.grid.header.Container', {
     },
 
     
+    getHideableColumns: function(refreshCache) {
+        var me = this,
+            result = refreshCache ? null : me.hideableColumns;
+
+        if (!result) {
+            result = me.hideableColumns = me.query('[hideable]');
+        }
+        return result;
+    },
+
+    
     getHeaderIndex: function(header) {
         var columns = this.getGridColumns();
         return Ext.Array.indexOf(columns, header);
@@ -76372,15 +80296,17 @@ Ext.define('Ext.grid.header.Container', {
     },
 
     
-    prepareData: function(data, rowIdx, record, view) {
+    prepareData: function(data, rowIdx, record, view, panel) {
         var obj       = {},
-            headers   = this.getGridColumns(),
+            headers   = this.gridDataColumns || this.getGridColumns(),
             headersLn = headers.length,
             colIdx    = 0,
-            header, value,
+            header,
+            headerId,
+            renderer,
+            value,
             metaData,
-            g = this.up('tablepanel'),
-            store = g.store;
+            store = panel.store;
 
         for (; colIdx < headersLn; colIdx++) {
             metaData = {
@@ -76388,16 +80314,18 @@ Ext.define('Ext.grid.header.Container', {
                 style: ''
             };
             header = headers[colIdx];
+            headerId = header.id;
+            renderer = header.renderer;
             value = data[header.dataIndex];
 
             
             
-            if (Ext.isString(header.renderer)) {
-                header.renderer = Ext.util.Format[header.renderer];
+            if (typeof renderer === "string") {
+                header.renderer = renderer = Ext.util.Format[renderer];
             }
 
-            if (Ext.isFunction(header.renderer)) {
-                value = header.renderer.call(
+            if (typeof renderer === "function") {
+                value = renderer.call(
                     header.scope || this.ownerCt,
                     value,
                     
@@ -76411,20 +80339,15 @@ Ext.define('Ext.grid.header.Container', {
                 );
             }
 
-            if (metaData.css) {
-                
-                obj.cssWarning = true;
-                metaData.tdCls = metaData.css;
-                delete metaData.css;
-            }
-            obj[header.id+'-modified'] = record.isModified(header.dataIndex) ? Ext.baseCSSPrefix + 'grid-dirty-cell' : Ext.baseCSSPrefix + 'grid-clean-cell';
-            obj[header.id+'-tdCls'] = metaData.tdCls;
-            obj[header.id+'-tdAttr'] = metaData.tdAttr;
-            obj[header.id+'-style'] = metaData.style;
+
+            obj[headerId+'-modified'] = record.isModified(header.dataIndex) ? Ext.baseCSSPrefix + 'grid-dirty-cell' : '';
+            obj[headerId+'-tdCls'] = metaData.tdCls;
+            obj[headerId+'-tdAttr'] = metaData.tdAttr;
+            obj[headerId+'-style'] = metaData.style;
             if (value === undefined || value === null || value === '') {
                 value = '&#160;';
             }
-            obj[header.id] = value;
+            obj[headerId] = value;
         }
         return obj;
     },
@@ -76455,11 +80378,13 @@ Ext.define('Ext.grid.column.Column', {
     possibleSortStates: ['ASC', 'DESC'],
 
     renderTpl:
-        '<div class="' + Ext.baseCSSPrefix + 'column-header-inner">' +
-            '<span class="' + Ext.baseCSSPrefix + 'column-header-text">' +
+        '<div id="{id}-titleContainer" class="' + Ext.baseCSSPrefix + 'column-header-inner">' +
+            '<span id="{id}-textEl" class="' + Ext.baseCSSPrefix + 'column-header-text">' +
                 '{text}' +
             '</span>' +
-            '<tpl if="!values.menuDisabled"><div class="' + Ext.baseCSSPrefix + 'column-header-trigger"></div></tpl>' +
+            '<tpl if="!values.menuDisabled">'+
+                '<div id="{id}-triggerEl" class="' + Ext.baseCSSPrefix + 'column-header-trigger"></div>'+
+            '</tpl>' +
         '</div>',
 
     
@@ -76468,13 +80393,17 @@ Ext.define('Ext.grid.column.Column', {
     dataIndex: null,
 
     
-    text: '&#160',
+    text: '&#160;',
 
     
     sortable: true,
+
     
+
     
-     
+
+    
+
     
     hideable: true,
 
@@ -76501,13 +80430,18 @@ Ext.define('Ext.grid.column.Column', {
     
 
     
+
+    
+
+    
     isHeader: true,
 
     initComponent: function() {
         var me = this,
             i,
-            len;
-        
+            len,
+            item;
+
         if (Ext.isDefined(me.header)) {
             me.text = me.header;
             delete me.header;
@@ -76533,12 +80467,6 @@ Ext.define('Ext.grid.column.Column', {
         if (Ext.isDefined(me.columns)) {
             me.isGroupHeader = true;
 
-            if (me.dataIndex) {
-                Ext.Error.raise('Ext.grid.column.Column: Group header may not accept a dataIndex');
-            }
-            if ((me.width && me.width !== Ext.grid.header.Container.prototype.defaultWidth) || me.flex) {
-                Ext.Error.raise('Ext.grid.column.Column: Group header does not support setting explicit widths or flexs. The group header width is calculated by the sum of its children.');
-            }
 
             
             me.items = me.columns;
@@ -76548,24 +80476,20 @@ Ext.define('Ext.grid.column.Column', {
 
             
             for (i = 0, len = me.items.length; i < len; i++) {
-                me.width += me.items[i].width || Ext.grid.header.Container.prototype.defaultWidth;
-                if (me.items[i].flex) {
-                    Ext.Error.raise('Ext.grid.column.Column: items of a grouped header do not support flexed values. Each item must explicitly define its width.');
+                item = me.items[i];
+                if (!item.hidden) {
+                    me.width += item.width || Ext.grid.header.Container.prototype.defaultWidth;
                 }
             }
             me.minWidth = me.width;
 
             me.cls = (me.cls||'') + ' ' + Ext.baseCSSPrefix + 'group-header';
             me.sortable = false;
-            me.fixed = true;
+            me.resizable = false;
             me.align = 'center';
         }
 
-        Ext.applyIf(me.renderSelectors, {
-            titleContainer: '.' + Ext.baseCSSPrefix + 'column-header-inner',
-            triggerEl: '.' + Ext.baseCSSPrefix + 'column-header-trigger',
-            textEl: '.' + Ext.baseCSSPrefix + 'column-header-text'
-        });
+        me.addChildEls('titleContainer', 'triggerEl', 'textEl');
 
         
         me.callParent(arguments);
@@ -76574,16 +80498,18 @@ Ext.define('Ext.grid.column.Column', {
     onAdd: function(childHeader) {
         childHeader.isSubHeader = true;
         childHeader.addCls(Ext.baseCSSPrefix + 'group-sub-header');
+        this.callParent(arguments);
     },
 
     onRemove: function(childHeader) {
         childHeader.isSubHeader = false;
         childHeader.removeCls(Ext.baseCSSPrefix + 'group-sub-header');
+        this.callParent(arguments);
     },
 
     initRenderData: function() {
         var me = this;
-        
+
         Ext.applyIf(me.renderData, {
             text: me.text,
             menuDisabled: me.menuDisabled
@@ -76591,12 +80517,66 @@ Ext.define('Ext.grid.column.Column', {
         return me.callParent(arguments);
     },
 
+    applyColumnState: function (state) {
+        var me = this,
+            defined = Ext.isDefined;
+            
+        
+        me.applyColumnsState(state.columns);
+
+        
+        
+        if (defined(state.hidden)) {
+            me.hidden = state.hidden;
+        }
+        if (defined(state.locked)) {
+            me.locked = state.locked;
+        }
+        if (defined(state.sortable)) {
+            me.sortable = state.sortable;
+        }
+        if (defined(state.width)) {
+            delete me.flex;
+            me.width = state.width;
+        } else if (defined(state.flex)) {
+            delete me.width;
+            me.flex = state.flex;
+        }
+    },
+
+    getColumnState: function () {
+        var me = this,
+            columns = [],
+            state = {
+                id: me.headerId
+            };
+
+        me.savePropsToState(['hidden', 'sortable', 'locked', 'flex', 'width'], state);
+        
+        if (me.isGroupHeader) {
+            me.items.each(function(column){
+                columns.push(column.getColumnState());
+            });
+            if (columns.length) {
+                state.columns = columns;
+            }
+        } else if (me.isSubHeader && me.ownerCt.hidden) {
+            
+            delete me.hidden;
+        }
+
+        if ('width' in state) {
+            delete state.flex; 
+        }
+        return state;
+    },
+
     
     setText: function(text) {
         this.text = text;
         if (this.rendered) {
             this.textEl.update(text);
-        } 
+        }
     },
 
     
@@ -76610,6 +80590,18 @@ Ext.define('Ext.grid.column.Column', {
         return this.isGroupColumn ? false : this.getOwnerHeaderCt().getHeaderIndex(this);
     },
 
+    onRender: function() {
+        var me = this,
+            grid = me.up('tablepanel');
+
+        
+        
+        if (grid && (!me.sortable || grid.sortableColumns === false) && !me.groupable && !me.lockable && (grid.enableColumnHide === false || !me.getOwnerHeaderCt().getHideableColumns().length)) {
+            me.menuDisabled = true;
+        }
+        me.callParent(arguments);
+    },
+
     afterRender: function() {
         var me = this,
             el = me.el;
@@ -76623,7 +80615,7 @@ Ext.define('Ext.grid.column.Column', {
             dblclick:  me.onElDblClick,
             scope:     me
         });
-        
+
         
         
         if (!Ext.isIE8 || !Ext.isStrict) {
@@ -76647,34 +80639,39 @@ Ext.define('Ext.grid.column.Column', {
         });
     },
 
-    setSize: function(width, height) {
+    
+    setWidth: function(width,  doLayout) {
         var me = this,
             headerCt = me.ownerCt,
-            ownerHeaderCt = me.getOwnerHeaderCt(),
             siblings,
             len, i,
             oldWidth = me.getWidth(),
-            newWidth = 0;
+            groupWidth = 0,
+            sibling;
 
         if (width !== oldWidth) {
+            me.oldWidth = oldWidth;
 
             
-            if (headerCt.isGroupHeader) {
+            
+            me.minWidth = me.width = width;
 
+            
+            if (headerCt.isGroupHeader) {
                 siblings = headerCt.items.items;
                 len = siblings.length;
 
-                
-                if (siblings[len - 1].rendered) {
-
-                    for (i = 0; i < len; i++) {
-                        newWidth += (siblings[i] === me) ? width : siblings[i].getWidth();
+                for (i = 0; i < len; i++) {
+                    sibling = siblings[i];
+                    if (!sibling.hidden) {
+                        groupWidth += (sibling === me) ? width : sibling.getWidth();
                     }
-                    headerCt.minWidth = newWidth;
-                    headerCt.setWidth(newWidth);
                 }
+                headerCt.setWidth(groupWidth, doLayout);
+            } else if (doLayout !== false) {
+                
+                headerCt.doLayout();
             }
-            me.callParent(arguments);
         }
     },
 
@@ -76690,18 +80687,21 @@ Ext.define('Ext.grid.column.Column', {
         if (width && !me.isGroupHeader && ownerHeaderCt) {
             ownerHeaderCt.onHeaderResize(me, width, true);
         }
+        if (me.oldWidth && (width !== me.oldWidth)) {
+            ownerHeaderCt.fireEvent('columnresize', ownerHeaderCt, this, width);
+        }
+        delete me.oldWidth;
     },
 
     
     
-    setPadding: function() {
+    
+    setPadding: function(headerHeight) {
         var me = this,
-            headerHeight,
-            lineHeight = parseInt(me.textEl.getStyle('line-height'), 10);
+            lineHeight = Ext.util.TextMetrics.measure(me.textEl.dom, me.text).height;
 
         
         if (!me.isGroupHeader) {
-            headerHeight = me.el.getViewSize().height;
             if (me.titleContainer.getHeight() < headerHeight) {
                 me.titleContainer.dom.style.height = headerHeight + 'px';
             }
@@ -76723,7 +80723,8 @@ Ext.define('Ext.grid.column.Column', {
 
     onDestroy: function() {
         var me = this;
-        Ext.destroy(me.keyNav);
+        
+        Ext.destroy(me.textEl, me.keyNav);
         delete me.keyNav;
         me.callParent(arguments);
     },
@@ -76783,7 +80784,7 @@ Ext.define('Ext.grid.column.Column', {
         var me = this,
             idx,
             nextIdx;
-            
+
         if (me.sortable) {
             idx = Ext.Array.indexOf(me.possibleSortStates, me.sortState);
 
@@ -76892,22 +80893,30 @@ Ext.define('Ext.grid.column.Column', {
 
     show: function() {
         var me = this,
-            ownerCt = me.getOwnerHeaderCt(),
-            lb,
+            ownerCt = me.ownerCt,
+            ownerCtCompLayout = ownerCt.componentLayout,
+            ownerCtCompLayoutBusy = ownerCtCompLayout.layoutBusy,
+            ownerCtLayout = ownerCt.layout,
+            ownerCtLayoutBusy = ownerCtLayout.layoutBusy,
             items,
             len, i,
+            item,
             newWidth = 0;
 
         
-        lb = me.ownerCt.componentLayout.layoutBusy;
-        me.ownerCt.componentLayout.layoutBusy = true;
+
+        
+        ownerCtCompLayout.layoutBusy = ownerCtLayout.layoutBusy = true;
+
         me.callParent(arguments);
-        me.ownerCt.componentLayout.layoutBusy = lb;
+
+        ownerCtCompLayout.layoutBusy = ownerCtCompLayoutBusy;
+        ownerCtLayout.layoutBusy = ownerCtLayoutBusy;
 
         
         if (me.isSubHeader) {
-            if (!me.ownerCt.isVisible()) {
-                me.ownerCt.show();
+            if (!ownerCt.isVisible()) {
+                ownerCt.show();
             }
         }
 
@@ -76915,23 +80924,29 @@ Ext.define('Ext.grid.column.Column', {
         if (me.isGroupHeader && !me.query(':not([hidden])').length) {
             items = me.query('>*');
             for (i = 0, len = items.length; i < len; i++) {
-                items[i].show();
+                item = items[i];
+                item.preventLayout = true;
+                item.show();
+                newWidth += item.getWidth();
+                delete item.preventLayout;
             }
+            me.setWidth(newWidth);
         }
 
         
-        if (me.ownerCt.isGroupHeader) {
-            items = me.ownerCt.query('>:not([hidden])');
+        if (ownerCt.isGroupHeader && me.preventLayout !== true) {
+            items = ownerCt.query('>:not([hidden])');
             for (i = 0, len = items.length; i < len; i++) {
                 newWidth += items[i].getWidth();
             }
-            me.ownerCt.minWidth = newWidth;
-            me.ownerCt.setWidth(newWidth);
+            ownerCt.minWidth = newWidth;
+            ownerCt.setWidth(newWidth);
         }
 
         
+        ownerCt = me.getOwnerHeaderCt();
         if (ownerCt) {
-            ownerCt.onHeaderShow(me);
+            ownerCt.onHeaderShow(me, me.preventLayout);
         }
     },
 
@@ -76973,18 +80988,19 @@ Ext.define('Ext.grid.column.Column', {
     isOnRightEdge: function(e) {
         return (this.el.getRight() - e.getXY()[0] <= this.handleWidth);
     }
+
     
     
-    
-    
-    
+
     
     
 });
 
+
 Ext.define('Ext.grid.RowNumberer', {
     extend: 'Ext.grid.column.Column',
     alias: 'widget.rownumberer',
+
     
     text: "&#160",
 
@@ -77004,7 +81020,7 @@ Ext.define('Ext.grid.RowNumberer', {
     },
 
     
-    fixed: true,
+    resizable: false,
     hideable: false,
     menuDisabled: true,
     dataIndex: '',
@@ -77051,9 +81067,12 @@ Ext.define('Ext.view.DropZone', {
 
 
     fireViewEvent: function() {
-        this.lock();
-        var result = this.view.fireEvent.apply(this.view, arguments);
-        this.unlock();
+        var me = this,
+            result;
+
+        me.lock();
+        result = me.view.fireEvent.apply(me.view, arguments);
+        me.unlock();
         return result;
     },
 
@@ -77157,41 +81176,46 @@ Ext.define('Ext.view.DropZone', {
 
     
     onNodeOver: function(node, dragZone, e, data) {
-        if (!Ext.Array.contains(data.records, this.view.getRecord(node))) {
-            this.positionIndicator(node, data, e);
+        var me = this;
+
+        if (!Ext.Array.contains(data.records, me.view.getRecord(node))) {
+            me.positionIndicator(node, data, e);
         }
-        return this.valid ? this.dropAllowed : this.dropNotAllowed;
+        return me.valid ? me.dropAllowed : me.dropNotAllowed;
     },
 
     
     
     notifyOut: function(node, dragZone, e, data) {
-        this.callParent(arguments);
-        delete this.overRecord;
-        delete this.currentPosition;
-        if (this.indicator) {
-            this.indicator.hide();
+        var me = this;
+
+        me.callParent(arguments);
+        delete me.overRecord;
+        delete me.currentPosition;
+        if (me.indicator) {
+            me.indicator.hide();
         }
     },
 
     
     onContainerOver : function(dd, e, data) {
-        var v = this.view,
-            c = v.store.getCount();
+        var me = this,
+            view = me.view,
+            count = view.store.getCount();
 
         
-        if (c) {
-            this.positionIndicator(v.getNode(c - 1), data, e);
+        if (count) {
+            me.positionIndicator(view.getNode(count - 1), data, e);
         }
 
         
         else {
-            delete this.overRecord;
-            delete this.currentPosition;
-            this.getIndicator().setWidth(Ext.fly(v.el).getWidth()).showAt(0, 0);
-            this.valid = true;
+            delete me.overRecord;
+            delete me.currentPosition;
+            me.getIndicator().setWidth(Ext.fly(view.el).getWidth()).showAt(0, 0);
+            me.valid = true;
         }
-        return this.dropAllowed;
+        return me.dropAllowed;
     },
 
     onContainerDrop : function(dd, e, data) {
@@ -77212,23 +81236,24 @@ Ext.define('Ext.view.DropZone', {
                 dropped = true;
                 me.fireViewEvent('drop', node, data, me.overRecord, me.currentPosition);
             },
-            performOperation;
+            performOperation = false;
 
         if (me.valid) {
             performOperation = me.fireViewEvent('beforedrop', node, data, me.overRecord, me.currentPosition, processDrop);
-            if (performOperation === 0) {
-                return;
-            } else if (performOperation !== false) {
+            if (performOperation !== false) {
                 
                 if (!dropped) {
                     processDrop();
                 }
-            } else {
-                return false;
             }
-        } else {
-            return false;
         }
+        return performOperation;
+    },
+    
+    destroy: function(){
+        Ext.destroy(this.indicator);
+        delete this.indicator;
+        this.callParent();
     }
 });
 
@@ -77256,7 +81281,9 @@ Ext.define('Ext.grid.ViewDropZone', {
         }
 
         index = store.indexOf(record);
-        if (position == 'after') {
+
+        
+        if (position !== 'before') {
             index++;
         }
         store.insert(index, data.records);
@@ -77277,13 +81304,15 @@ Ext.define('Ext.grid.column.Action', {
     
     
     
+    
+    
     header: '&#160;',
 
-    actionIdRe: /x-action-col-(\d+)/,
+    actionIdRe: new RegExp(Ext.baseCSSPrefix + 'action-col-(\\d+)'),
 
     
     altText: '',
-    
+
     sortable: false,
 
     constructor: function(config) {
@@ -77296,7 +81325,7 @@ Ext.define('Ext.grid.column.Action', {
 
         
         delete cfg.items;
-        this.callParent([cfg]);
+        me.callParent([cfg]);
 
         
         me.items = items;
@@ -77310,8 +81339,10 @@ Ext.define('Ext.grid.column.Action', {
             meta.tdCls += ' ' + Ext.baseCSSPrefix + 'action-col-cell';
             for (i = 0; i < l; i++) {
                 item = items[i];
-                v += '<img alt="' + me.altText + '" src="' + (item.icon || Ext.BLANK_IMAGE_URL) +
-                    '" class="' + Ext.baseCSSPrefix + 'action-col-icon ' + Ext.baseCSSPrefix + 'action-col-' + String(i) + ' ' +  (item.iconCls || '') + 
+                item.disable = Ext.Function.bind(me.disableAction, me, [i]);
+                item.enable = Ext.Function.bind(me.enableAction, me, [i]);
+                v += '<img alt="' + (item.altText || me.altText) + '" src="' + (item.icon || Ext.BLANK_IMAGE_URL) +
+                    '" class="' + Ext.baseCSSPrefix + 'action-col-icon ' + Ext.baseCSSPrefix + 'action-col-' + String(i) + ' ' + (item.disabled ? Ext.baseCSSPrefix + 'item-disabled' : ' ') + (item.iconCls || '') +
                     ' ' + (Ext.isFunction(item.getClass) ? item.getClass.apply(item.scope||me.scope||me, arguments) : (me.iconCls || '')) + '"' +
                     ((item.tooltip) ? ' data-qtip="' + item.tooltip + '"' : '') + ' />';
             }
@@ -77319,6 +81350,32 @@ Ext.define('Ext.grid.column.Action', {
         };
     },
 
+    
+    enableAction: function(index) {
+        var me = this;
+
+        if (!index) {
+            index = 0;
+        } else if (!Ext.isNumber(index)) {
+            index = Ext.Array.indexOf(me.items, index);
+        }
+        me.items[index].disabled = false;
+        me.up('tablepanel').el.select('.' + Ext.baseCSSPrefix + 'action-col-' + index).removeCls(me.disabledCls);
+    },
+
+    
+    disableAction: function(index) {
+        var me = this;
+
+        if (!index) {
+            index = 0;
+        } else if (!Ext.isNumber(index)) {
+            index = Ext.Array.indexOf(me.items, index);
+        }
+        me.items[index].disabled = true;
+        me.up('tablepanel').el.select('.' + Ext.baseCSSPrefix + 'action-col-' + index).addCls(me.disabledCls);
+    },
+
     destroy: function() {
         delete this.items;
         delete this.renderer;
@@ -77327,19 +81384,24 @@ Ext.define('Ext.grid.column.Action', {
 
     
     processEvent : function(type, view, cell, recordIndex, cellIndex, e){
-        var m = e.getTarget().className.match(this.actionIdRe),
+        var me = this,
+            match = e.getTarget().className.match(me.actionIdRe),
             item, fn;
-        if (m && (item = this.items[parseInt(m[1], 10)])) {
-            if (type == 'click') {
-                fn = item.handler;
-                if (fn || this.handler) {
-                    fn.call(item.scope||this.scope||this, view, recordIndex, cellIndex, item, e);
+            
+        if (match) {
+            item = me.items[parseInt(match[1], 10)];
+            if (item) {
+                if (type == 'click') {
+                    fn = item.handler || me.handler;
+                    if (fn && !item.disabled) {
+                        fn.call(item.scope || me.scope || me, view, recordIndex, cellIndex, item, e);
+                    }
+                } else if (type == 'mousedown' && item.stopSelection !== false) {
+                    return false;
                 }
-            } else if ((type == 'mousedown') && (item.stopSelection !== false)) {
-                return false;
             }
         }
-        return this.callParent(arguments);
+        return me.callParent(arguments);
     },
 
     cascade: function(fn, scope) {
@@ -77391,11 +81453,15 @@ Ext.define('Ext.grid.column.Date', {
     alternateClassName: 'Ext.grid.DateColumn',
 
     
-    format : Ext.Date.defaultFormat,
 
-    constructor: function(cfg){
-        this.callParent(arguments);
-        this.renderer = Ext.util.Format.dateRenderer(this.format);
+    initComponent: function(){
+        var me = this;
+        
+        me.callParent(arguments);
+        if (!me.format) {
+            me.format = Ext.Date.defaultFormat;
+        }
+        me.renderer = Ext.util.Format.dateRenderer(me.format);
     }
 });
 
@@ -77407,6 +81473,7 @@ Ext.define('Ext.grid.column.Number', {
 
     
     format : '0,000.00',
+
     constructor: function(cfg) {
         this.callParent(arguments);
         this.renderer = Ext.util.Format.numberRenderer(this.format);
@@ -77420,6 +81487,7 @@ Ext.define('Ext.grid.column.Template', {
     alternateClassName: 'Ext.grid.TemplateColumn',
 
     
+
     constructor: function(cfg){
         var me = this,
             tpl;
@@ -77465,8 +81533,8 @@ Ext.define('Ext.grid.feature.Feature', {
     },
     
     
-    getFireEventArgs: function(eventName, view, featureTarget) {
-        return [eventName, view, featureTarget];
+    getFireEventArgs: function(eventName, view, featureTarget, e) {
+        return [eventName, view, featureTarget, e];
     },
     
     
@@ -77543,9 +81611,10 @@ Ext.define('Ext.grid.feature.AbstractSummary', {
     
     
     printSummaryRow: function(index){
-        var inner = this.view.getTableChunker().metaRowTpl.join('');
+        var inner = this.view.getTableChunker().metaRowTpl.join(''),
+            prefix = Ext.baseCSSPrefix;
         
-        inner = inner.replace('x-grid-row', 'x-grid-row-summary');
+        inner = inner.replace(prefix + 'grid-row', prefix + 'grid-row-summary');
         inner = inner.replace('{{id}}', '{gridSummaryValue}');
         inner = inner.replace(this.nestedIdRe, '{id$1}');  
         inner = inner.replace('{[this.embedRowCls()]}', '{rowCls}');
@@ -77560,13 +81629,18 @@ Ext.define('Ext.grid.feature.AbstractSummary', {
     },
     
     
-    getColumnValue: function(column, data){
-        var comp = Ext.getCmp(column.id),
-            value = data[column.dataIndex],
-            renderer = comp.summaryRenderer || comp.renderer;
-            
+    getColumnValue: function(column, summaryData){
+        var comp     = Ext.getCmp(column.id),
+            value    = summaryData[column.id],
+            renderer = comp.summaryRenderer;
+
         if (renderer) {
-            value = renderer.call(comp.scope || this, value, data, column.dataIndex);
+            value = renderer.call(
+                comp.scope || this,
+                value,
+                summaryData,
+                column.dataIndex
+            );
         }
         return value;
     },
@@ -77687,8 +81761,10 @@ Ext.define('Ext.grid.feature.Grouping', {
     eventSelector: '.' + Ext.baseCSSPrefix + 'grid-group-hd',
 
     constructor: function() {
-        this.collapsedState = {};
-        this.callParent(arguments);
+        var me = this;
+        
+        me.collapsedState = {};
+        me.callParent(arguments);
     },
     
     
@@ -77733,33 +81809,46 @@ Ext.define('Ext.grid.feature.Grouping', {
             store = view.store,
             groupToggleMenuItem;
             
+        me.lastGroupField = me.getGroupField();
+
         if (me.lastGroupIndex) {
             store.group(me.lastGroupIndex);
         }
         me.callParent();
         groupToggleMenuItem = me.view.headerCt.getMenu().down('#groupToggleMenuItem');
         groupToggleMenuItem.setChecked(true, true);
-        view.refresh();
+        me.refreshIf();
     },
 
     disable: function() {
         var me    = this,
             view  = me.view,
             store = view.store,
+            remote = store.remoteGroup,
             groupToggleMenuItem,
             lastGroup;
             
         lastGroup = store.groupers.first();
         if (lastGroup) {
             me.lastGroupIndex = lastGroup.property;
-            store.groupers.clear();
+            me.block();
+            store.clearGrouping();
+            me.unblock();
         }
         
         me.callParent();
         groupToggleMenuItem = me.view.headerCt.getMenu().down('#groupToggleMenuItem');
         groupToggleMenuItem.setChecked(true, true);
         groupToggleMenuItem.setChecked(false, true);
-        view.refresh();
+        if (!remote) {
+            view.refresh();
+        }
+    },
+    
+    refreshIf: function() {
+        if (this.blockRefresh !== true) {
+            this.view.refresh();
+        }    
     },
 
     getFeatureTpl: function(values, parent, x, xcount) {
@@ -77799,8 +81888,7 @@ Ext.define('Ext.grid.feature.Grouping', {
     
     attachEvents: function() {
         var me = this,
-            view = me.view,
-            header, headerId, menu, menuItem;
+            view = me.view;
 
         view.on({
             scope: me,
@@ -77814,16 +81902,10 @@ Ext.define('Ext.grid.feature.Grouping', {
         if (me.enableGroupingMenu) {
             me.injectGroupingMenu();
         }
-
-        if (me.hideGroupedHeader) {
-            header = view.headerCt.down('gridcolumn[dataIndex=' + me.getGroupField() + ']');
-            headerId = header.id;
-            menu = view.headerCt.getMenu();
-            menuItem = menu.down('menuitem[headerId='+ headerId +']');
-            if (menuItem) {
-                menuItem.setChecked(false);
-            }
-        }
+        me.lastGroupField = me.getGroupField();
+        me.block();
+        me.onGroupChange();
+        me.unblock();
     },
     
     injectGroupingMenu: function() {
@@ -77850,12 +81932,13 @@ Ext.define('Ext.grid.feature.Grouping', {
             showGroupsText     = me.showGroupsText,
             enableNoGroups     = me.enableNoGroups,
             groupMenuItemClick = Ext.Function.bind(me.onGroupMenuItemClick, me),
-            groupToggleMenuItemClick = Ext.Function.bind(me.onGroupToggleMenuItemClick, me)
+            groupToggleMenuItemClick = Ext.Function.bind(me.onGroupToggleMenuItemClick, me);
         
         
         return function() {
             var o = Ext.grid.header.Container.prototype.getMenuItems.call(this);
             o.push('-', {
+                iconCls: Ext.baseCSSPrefix + 'group-by-icon',
                 itemId: 'groupMenuItem',
                 text: groupByText,
                 handler: groupMenuItemClick
@@ -77875,15 +81958,30 @@ Ext.define('Ext.grid.feature.Grouping', {
 
     
     onGroupMenuItemClick: function(menuItem, e) {
-        var menu = menuItem.parentMenu,
+        var me = this,
+            menu = menuItem.parentMenu,
             hdr  = menu.activeHeader,
-            view = this.view;
+            view = me.view,
+            store = view.store,
+            remote = store.remoteGroup;
 
-        delete this.lastGroupIndex;
-        this.enable();
-        view.store.group(hdr.dataIndex);
-        this.pruneGroupedHeader();
-        
+        delete me.lastGroupIndex;
+        me.block();
+        me.enable();
+        store.group(hdr.dataIndex);
+        me.pruneGroupedHeader();
+        me.unblock();
+        if (!remote) {
+            view.refresh();
+        }  
+    },
+    
+    block: function(){
+        this.blockRefresh = this.view.blockRefresh = true;
+    },
+    
+    unblock: function(){
+        this.blockRefresh = this.view.blockRefresh = false;
     },
 
     
@@ -77964,7 +82062,37 @@ Ext.define('Ext.grid.feature.Grouping', {
     },
     
     onGroupChange: function(){
-        this.view.refresh();
+        var me = this,
+            field = me.getGroupField(),
+            menuItem;
+            
+        if (me.hideGroupedHeader) {
+            if (me.lastGroupField) {
+                menuItem = me.getMenuItem(me.lastGroupField);
+                if (menuItem) {
+                    menuItem.setChecked(true);
+                }
+            }
+            if (field) {
+                menuItem = me.getMenuItem(field);
+                if (menuItem) {
+                    menuItem.setChecked(false);
+                }
+            }
+        }
+        if (me.blockRefresh !== true) {
+            me.view.refresh();
+        }
+        me.lastGroupField = field;
+    },
+    
+    
+    getMenuItem: function(dataIndex){
+        var view = this.view,
+            header = view.headerCt.down('gridcolumn[dataIndex=' + dataIndex + ']'),
+            menu = view.headerCt.getMenu();
+            
+        return menu.down('menuitem[headerId='+ header.id +']');
     },
 
     
@@ -78069,14 +82197,14 @@ Ext.define('Ext.grid.feature.Grouping', {
     
     
     
-    getFireEventArgs: function(type, view, featureTarget) {
+    getFireEventArgs: function(type, view, featureTarget, e) {
         var returnArray = [type, view, featureTarget],
             groupBd     = Ext.fly(featureTarget.nextSibling, '_grouping'),
             groupBdId   = Ext.getDom(groupBd).id,
             prefix      = view.id + '-gp-',
             groupName   = groupBdId.substr(prefix.length);
         
-        returnArray.push(groupName);
+        returnArray.push(groupName, e);
         
         return returnArray;
     }
@@ -78084,24 +82212,24 @@ Ext.define('Ext.grid.feature.Grouping', {
 
 
 Ext.define('Ext.grid.feature.GroupingSummary', {
+
     
-    
-    
+
     extend: 'Ext.grid.feature.Grouping',
-    
+
     alias: 'feature.groupingsummary',
-    
+
     mixins: {
         summary: 'Ext.grid.feature.AbstractSummary'
     },
-    
+
     
 
-     
+
    
    getFeatureTpl: function() {
         var tpl = this.callParent(arguments);
-            
+
         if (this.showSummaryRow) {
             
             tpl = tpl.replace('</tpl>', '');
@@ -78109,12 +82237,12 @@ Ext.define('Ext.grid.feature.GroupingSummary', {
         }
         return tpl;
     },
-    
+
     
     getFragmentTpl: function() {
         var me = this,
             fragments = me.callParent();
-            
+
         Ext.apply(fragments, me.getSummaryFragments());
         if (me.showSummaryRow) {
             
@@ -78123,7 +82251,7 @@ Ext.define('Ext.grid.feature.GroupingSummary', {
         }
         return fragments;
     },
-    
+
     
     getPrintData: function(index){
         var me = this,
@@ -78134,7 +82262,7 @@ Ext.define('Ext.grid.feature.GroupingSummary', {
             name = me.summaryGroups[index - 1].name,
             active = me.summaryData[name],
             column;
-            
+
         for (; i < length; ++i) {
             column = columns[i];
             column.gridSummaryValue = this.getColumnValue(column, active);
@@ -78142,7 +82270,7 @@ Ext.define('Ext.grid.feature.GroupingSummary', {
         }
         return data;
     },
-    
+
     
     generateSummaryData: function(){
         var me = this,
@@ -78153,40 +82281,47 @@ Ext.define('Ext.grid.feature.GroupingSummary', {
             reader = store.proxy.reader,
             groups = me.summaryGroups,
             columns = me.view.headerCt.getColumnsForTpl(),
+            remote,
             i,
             length,
             fieldData,
             root,
             key,
             comp;
-            
+
         for (i = 0, length = groups.length; i < length; ++i) {
             data[groups[i].name] = {};
         }
+
         
-    
         if (me.remoteRoot && reader.rawData) {
             
             root = reader.root;
             reader.root = me.remoteRoot;
             reader.buildExtractors(true);
             Ext.Array.each(reader.getRoot(reader.rawData), function(value) {
-                 data[value[groupField]] = value;
-                 data[value[groupField]]._remote = true;
+                 remoteData[value[groupField]] = value;
             });
             
             reader.root = root;
             reader.buildExtractors(true);
         }
-        
+
         for (i = 0, length = columns.length; i < length; ++i) {
             comp = Ext.getCmp(columns[i].id);
             fieldData = me.getSummary(store, comp.summaryType, comp.dataIndex, true);
-            
+
             for (key in fieldData) {
                 if (fieldData.hasOwnProperty(key)) {
-                    if (!data[key]._remote) {
-                        data[key][comp.dataIndex] = fieldData[key];
+                    data[key][comp.id] = fieldData[key];
+                }
+            }
+
+            for (key in remoteData) {
+                if (remoteData.hasOwnProperty(key)) {
+                    remote = remoteData[key][comp.dataIndex];
+                    if (remote !== undefined && data[key] !== undefined) {
+                        data[key][comp.id] = remote;
                     }
                 }
             }
@@ -78381,7 +82516,7 @@ Ext.define('Ext.grid.feature.Summary', {
             
         for (i = 0, length = columns.length; i < length; ++i) {
             comp = Ext.getCmp(columns[i].id);
-            data[comp.dataIndex] = me.getSummary(store, comp.summaryType, comp.dataIndex, false);
+            data[comp.id] = me.getSummary(store, comp.summaryType, comp.dataIndex, false);
         }
         return data;
     }
@@ -78475,7 +82610,7 @@ Ext.define('Ext.grid.header.DropZone', {
 
     getTopIndicator: function() {
         if (!this.topIndicator) {
-            this.topIndicator = Ext.core.DomHelper.append(Ext.getBody(), {
+            this.topIndicator = Ext.DomHelper.append(Ext.getBody(), {
                 cls: "col-move-top",
                 html: "&#160;"
             }, true);
@@ -78485,7 +82620,7 @@ Ext.define('Ext.grid.header.DropZone', {
 
     getBottomIndicator: function() {
         if (!this.bottomIndicator) {
-            this.bottomIndicator = Ext.core.DomHelper.append(Ext.getBody(), {
+            this.bottomIndicator = Ext.DomHelper.append(Ext.getBody(), {
                 cls: "col-move-bottom",
                 html: "&#160;"
             }, true);
@@ -78702,7 +82837,6 @@ Ext.define('Ext.grid.header.DropZone', {
 });
 
 
-
 Ext.define('Ext.grid.plugin.Editing', {
     alias: 'editing.editing',
 
@@ -78750,7 +82884,8 @@ Ext.define('Ext.grid.plugin.Editing', {
         me.grid = grid;
         me.view = grid.view;
         me.initEvents();
-        me.initFieldAccessors(me.view.getGridColumns());
+        me.mon(grid, 'reconfigure', me.onReconfigure, me);
+        me.onReconfigure();
 
         grid.relayEvents(me, ['beforeedit', 'edit', 'validateedit']);
         
@@ -78760,6 +82895,11 @@ Ext.define('Ext.grid.plugin.Editing', {
     },
 
     
+    onReconfigure: function(){
+        this.initFieldAccessors(this.view.getGridColumns());
+    },
+
+    
     destroy: function() {
         var me = this,
             grid = me.grid,
@@ -78998,10 +83138,11 @@ Ext.define('Ext.grid.plugin.Editing', {
     }
 });
 
+
 Ext.define('Ext.grid.plugin.CellEditing', {
     alias: 'plugin.cellediting',
     extend: 'Ext.grid.plugin.Editing',
-    requires: ['Ext.grid.CellEditor'],
+    requires: ['Ext.grid.CellEditor', 'Ext.util.DelayedTask'],
 
     constructor: function() {
         
@@ -79011,30 +83152,43 @@ Ext.define('Ext.grid.plugin.CellEditing', {
         this.editors = Ext.create('Ext.util.MixedCollection', false, function(editor) {
             return editor.editorId;
         });
+        this.editTask = Ext.create('Ext.util.DelayedTask');
+    },
+    
+    onReconfigure: function(){
+        this.editors.clear();
+        this.callParent();    
     },
 
     
     destroy: function() {
         var me = this;
+        me.editTask.cancel();
         me.editors.each(Ext.destroy, Ext);
         me.editors.clear();
         me.callParent(arguments);
     },
+    
+    onBodyScroll: function() {
+        var ed = this.getActiveEditor();
+        if (ed && ed.field) {
+            if (ed.field.triggerBlur) {
+                ed.field.triggerBlur();
+            } else {
+                ed.field.blur();
+            }
+        }
+    },
 
     
     
     initCancelTriggers: function() {
-        var me   = this;
+        var me   = this,
             grid = me.grid,
-            view   = grid.view;
-
-        me.mon(view, {
-            mousewheel: {
-                element: 'el',
-                fn: me.cancelEdit,
-                scope: me
-            }
-        });
+            view = grid.view;
+            
+        view.addElListener('mousewheel', me.cancelEdit, me);
+        me.mon(view, 'bodyscroll', me.onBodyScroll, me);
         me.mon(grid, {
             columnresize: me.cancelEdit,
             columnmove: me.cancelEdit,
@@ -79045,9 +83199,9 @@ Ext.define('Ext.grid.plugin.CellEditing', {
     
     startEdit: function(record, columnHeader) {
         var me = this,
-            ed   = me.getEditor(record, columnHeader),
             value = record.get(columnHeader.dataIndex),
-            context = me.getEditingContext(record, columnHeader);
+            context = me.getEditingContext(record, columnHeader),
+            ed;
 
         record = context.record;
         columnHeader = context.column;
@@ -79056,30 +83210,31 @@ Ext.define('Ext.grid.plugin.CellEditing', {
         
         me.completeEdit();
 
+        context.originalValue = context.value = value;
+        if (me.beforeEdit(context) === false || me.fireEvent('beforeedit', context) === false || context.cancel) {
+            return false;
+        }
+        
         
         if (columnHeader && !columnHeader.getEditor(record)) {
             return false;
         }
-
+        
+        ed = me.getEditor(record, columnHeader);
         if (ed) {
-            context.originalValue = context.value = value;
-            if (me.beforeEdit(context) === false || me.fireEvent('beforeedit', context) === false || context.cancel) {
-                return false;
-            }
-
             me.context = context;
             me.setActiveEditor(ed);
             me.setActiveRecord(record);
             me.setActiveColumn(columnHeader);
 
             
-            Ext.defer(ed.startEdit, 15, ed, [me.getCell(record, columnHeader), value]);
+            me.editTask.delay(15, ed.startEdit, ed, [me.getCell(record, columnHeader), value]);
         } else {
             
             
             
             
-            me.grid.getView().el.focus((Ext.isWebKit || Ext.isIE) ? 10 : false);
+            me.grid.getView().getEl(columnHeader).focus((Ext.isWebKit || Ext.isIE) ? 10 : false);
         }
     },
 
@@ -79116,8 +83271,9 @@ Ext.define('Ext.grid.plugin.CellEditing', {
     },
 
     getEditor: function(record, column) {
-        var editors = this.editors,
-            editorId = column.itemId || column.id,
+        var me = this,
+            editors = me.editors,
+            editorId = column.getItemId(),
             editor = editors.getByKey(editorId);
 
         if (editor) {
@@ -79135,18 +83291,26 @@ Ext.define('Ext.grid.plugin.CellEditing', {
                     field: editor
                 });
             }
-            editor.parentEl = this.grid.getEditorParent();
+            editor.parentEl = me.grid.getEditorParent();
             
             editor.on({
-                scope: this,
-                specialkey: this.onSpecialKey,
-                complete: this.onEditComplete,
-                canceledit: this.cancelEdit
+                scope: me,
+                specialkey: me.onSpecialKey,
+                complete: me.onEditComplete,
+                canceledit: me.cancelEdit
             });
             editors.add(editor);
             return editor;
         }
     },
+    
+    
+    setColumnField: function(column, field) {
+        var ed = this.editors.getByKey(column.getItemId());
+        Ext.destroy(ed, column.field);
+        this.editors.removeAtKey(column.getItemId());
+        this.callParent(arguments);
+    },
 
     
     getCell: function(record, column) {
@@ -79169,25 +83333,38 @@ Ext.define('Ext.grid.plugin.CellEditing', {
         var me = this,
             grid = me.grid,
             sm = grid.getSelectionModel(),
-            dataIndex = me.getActiveColumn().dataIndex;
+            activeColumn = me.getActiveColumn(),
+            dataIndex;
 
-        me.setActiveEditor(null);
-        me.setActiveColumn(null);
-        me.setActiveRecord(null);
-        delete sm.wasEditing;
+        if (activeColumn) {
+            dataIndex = activeColumn.dataIndex;
 
-        if (!me.validateEdit()) {
-            return;
+            me.setActiveEditor(null);
+            me.setActiveColumn(null);
+            me.setActiveRecord(null);
+            delete sm.wasEditing;
+    
+            if (!me.validateEdit()) {
+                return;
+            }
+            
+            
+            if (value !== startValue) {
+                me.context.record.set(dataIndex, value);
+            
+            } else {
+                grid.getView().getEl(activeColumn).focus();
+            }
+            me.context.value = value;
+            me.fireEvent('edit', me, me.context);
         }
-        me.context.record.set(dataIndex, value);
-        me.fireEvent('edit', me, me.context);
     },
 
     
     cancelEdit: function() {
         var me = this,
             activeEd = me.getActiveEditor(),
-            viewEl = me.grid.getView().el;
+            viewEl = me.grid.getView().getEl(me.getActiveColumn());
 
         me.setActiveEditor(null);
         me.setActiveColumn(null);
@@ -79250,6 +83427,28 @@ Ext.define('Ext.grid.plugin.DragDrop', {
         Ext.destroy(this.dragZone, this.dropZone);
     },
 
+    enable: function() {
+        var me = this;
+        if (me.dragZone) {
+            me.dragZone.unlock();
+        }
+        if (me.dropZone) {
+            me.dropZone.unlock();
+        }
+        me.callParent();
+    },
+
+    disable: function() {
+        var me = this;
+        if (me.dragZone) {
+            me.dragZone.lock();
+        }
+        if (me.dropZone) {
+            me.dropZone.lock();
+        }
+        me.callParent();
+    },
+
     onViewRender : function(view) {
         var me = this;
 
@@ -79312,7 +83511,7 @@ Ext.define('Ext.grid.plugin.HeaderResizer', {
     extend: 'Ext.util.Observable',
     requires: ['Ext.dd.DragTracker', 'Ext.util.Region'],
     alias: 'plugin.gridheaderresizer',
-    
+
     disabled: false,
 
     
@@ -79379,7 +83578,8 @@ Ext.define('Ext.grid.plugin.HeaderResizer', {
 
                 
                 if (overHeader.isOnLeftEdge(e)) {
-                    resizeHeader = overHeader.previousNode('gridcolumn:not([hidden]):not([isGroupHeader])');
+                    resizeHeader = overHeader.previousNode('gridcolumn:not([hidden])');
+
                 }
                 
                 else if (overHeader.isOnRightEdge(e)) {
@@ -79396,11 +83596,12 @@ Ext.define('Ext.grid.plugin.HeaderResizer', {
                     
                     
                     if (resizeHeader.isGroupHeader) {
-                        resizeHeader = resizeHeader.getVisibleGridColumns();
-                        resizeHeader = resizeHeader[resizeHeader.length - 1];
+                        resizeHeader = resizeHeader.down(':not([isGroupHeader]):not([hidden]):last');
                     }
 
-                    if (resizeHeader && !resizeHeader.fixed) {
+                    
+                    
+                    if (resizeHeader && !(resizeHeader.fixed || (resizeHeader.resizable === false) || this.disabled)) {
                         this.activeHd = resizeHeader;
                         overHeader.el.dom.style.cursor = this.eResizeCursor;
                     }
@@ -79530,38 +83731,32 @@ Ext.define('Ext.grid.plugin.HeaderResizer', {
                 delete dragHd.flex;
             }
 
+            this.headerCt.suspendLayout = true;
+            dragHd.setWidth(this.origWidth + offset[0], false);
+
+            
+            
             
             
             if (this.headerCt.forceFit) {
                 nextHd = dragHd.nextNode('gridcolumn:not([hidden]):not([isGroupHeader])');
                 if (nextHd) {
-                    this.headerCt.componentLayout.layoutBusy = true;
+                    delete nextHd.flex;
+                    nextHd.setWidth(nextHd.getWidth() - offset[0], false);
                 }
             }
-
-            
-            
-            dragHd.minWidth = this.origWidth + offset[0];
-            dragHd.setWidth(dragHd.minWidth);
-
-            
-            
-            if (nextHd) {
-                delete nextHd.flex;
-                nextHd.setWidth(nextHd.getWidth() - offset[0]);
-                this.headerCt.componentLayout.layoutBusy = false;
-                this.headerCt.doComponentLayout();
-            }
+            this.headerCt.suspendLayout = false;
+            this.headerCt.doComponentLayout(this.headerCt.getFullWidth());
         }
     },
-    
+
     disable: function() {
         this.disabled = true;
         if (this.tracker) {
             this.tracker.disable();
         }
     },
-    
+
     enable: function() {
         this.disabled = false;
         if (this.tracker) {
@@ -79591,6 +83786,9 @@ Ext.define('Ext.grid.plugin.RowEditing', {
     
     
     
+    
+    
+    
 
     constructor: function() {
         var me = this;
@@ -79632,6 +83830,8 @@ Ext.define('Ext.grid.plugin.RowEditing', {
         if (me.editing) {
             me.getEditor().cancelEdit();
             me.callParent(arguments);
+            
+            me.fireEvent('canceledit', me.context);
         }
     },
 
@@ -79647,7 +83847,26 @@ Ext.define('Ext.grid.plugin.RowEditing', {
 
     
     validateEdit: function() {
-        var me = this;
+        var me             = this,
+            editor         = me.editor,
+            context        = me.context,
+            record         = context.record,
+            newValues      = {},
+            originalValues = {},
+            name;
+
+        editor.items.each(function(item) {
+            name = item.name;
+
+            newValues[name]      = item.getValue();
+            originalValues[name] = record.get(name);
+        });
+
+        Ext.apply(context, {
+            newValues      : newValues,
+            originalValues : originalValues
+        });
+
         return me.callParent(arguments) && me.getEditor().completeEdit();
     },
 
@@ -79724,38 +83943,47 @@ Ext.define('Ext.grid.plugin.RowEditing', {
 
     
     onColumnAdd: function(ct, column) {
-        var me = this,
+        if (column.isHeader) {
+            var me = this,
+                editor;
+
+            me.initFieldAccessors(column);
             editor = me.getEditor();
 
-        me.initFieldAccessors(column);
-        if (editor && editor.onColumnAdd) {
-            editor.onColumnAdd(column);
+            if (editor && editor.onColumnAdd) {
+                editor.onColumnAdd(column);
+            }
         }
     },
 
     
     onColumnRemove: function(ct, column) {
-        var me = this,
-            editor = me.getEditor();
+        if (column.isHeader) {
+            var me = this,
+                editor = me.getEditor();
 
-        if (editor && editor.onColumnRemove) {
-            editor.onColumnRemove(column);
+            if (editor && editor.onColumnRemove) {
+                editor.onColumnRemove(column);
+            }
+            me.removeFieldAccessors(column);
         }
-        me.removeFieldAccessors(column);
     },
 
     
     onColumnResize: function(ct, column, width) {
-        var me = this,
-            editor = me.getEditor();
+        if (column.isHeader) {
+            var me = this,
+                editor = me.getEditor();
 
-        if (editor && editor.onColumnResize) {
-            editor.onColumnResize(column, width);
+            if (editor && editor.onColumnResize) {
+                editor.onColumnResize(column, width);
+            }
         }
     },
 
     
     onColumnHide: function(ct, column) {
+        
         var me = this,
             editor = me.getEditor();
 
@@ -79766,6 +83994,7 @@ Ext.define('Ext.grid.plugin.RowEditing', {
 
     
     onColumnShow: function(ct, column) {
+        
         var me = this,
             editor = me.getEditor();
 
@@ -79776,6 +84005,7 @@ Ext.define('Ext.grid.plugin.RowEditing', {
 
     
     onColumnMove: function(ct, column, fromIdx, toIdx) {
+        
         var me = this,
             editor = me.getEditor();
 
@@ -79792,10 +84022,13 @@ Ext.define('Ext.grid.plugin.RowEditing', {
     }
 });
 
+
 Ext.define('Ext.grid.property.Grid', {
 
     extend: 'Ext.grid.Panel',
 
+    alias: 'widget.propertygrid',
+
     alternateClassName: 'Ext.grid.PropertyGrid',
 
     uses: [
@@ -79826,6 +84059,8 @@ Ext.define('Ext.grid.property.Grid', {
     nameField: 'name',
 
     
+
+    
     enableColumnMove: false,
     columnLines: true,
     stripeRows: false,
@@ -79847,7 +84082,7 @@ Ext.define('Ext.grid.property.Grid', {
             
             startEdit: function(record, column) {
                 
-                Ext.grid.plugin.CellEditing.prototype.startEdit.call(this, record, me.headerCt.child('#' + me.valueField));
+                return this.self.prototype.startEdit.call(this, record, me.headerCt.child('#' + me.valueField));
             }
         }));
 
@@ -79856,8 +84091,8 @@ Ext.define('Ext.grid.property.Grid', {
             onCellSelect: function(position) {
                 if (position.column != 1) {
                     position.column = 1;
-                    Ext.selection.CellModel.prototype.onCellSelect.call(this, position);
                 }
+                return this.self.prototype.onCellSelect.call(this, position);
             }
         };
         me.customRenderers = me.customRenderers || {};
@@ -79894,7 +84129,7 @@ Ext.define('Ext.grid.property.Grid', {
         };
 
         
-        this.store.on('update', me.onUpdate, me);
+        me.store.on('update', me.onUpdate, me);
     },
 
     
@@ -79905,12 +84140,12 @@ Ext.define('Ext.grid.property.Grid', {
         if (operation == Ext.data.Model.EDIT) {
             v = record.get(me.valueField);
             oldValue = record.modified.value;
-            if (me.fireEvent('beforepropertychange', me.source, record.id, v, oldValue) !== false) {
+            if (me.fireEvent('beforepropertychange', me.source, record.getId(), v, oldValue) !== false) {
                 if (me.source) {
-                    me.source[record.id] = v;
+                    me.source[record.getId()] = v;
                 }
                 record.commit();
-                me.fireEvent('propertychange', me.source, record.id, v, oldValue);
+                me.fireEvent('propertychange', me.source, record.getId(), v, oldValue);
             } else {
                 record.reject();
             }
@@ -79924,7 +84159,7 @@ Ext.define('Ext.grid.property.Grid', {
         } else if (direction == 'right') {
             direction = 'down';
         }
-        var pos = Ext.view.Table.prototype.walkCells.call(this, pos, direction, e, preventWrap, verifierFn, scope);
+        pos = Ext.view.Table.prototype.walkCells.call(this, pos, direction, e, preventWrap, verifierFn, scope);
         if (!pos.column) {
             pos.column = 1;
         }
@@ -79935,7 +84170,7 @@ Ext.define('Ext.grid.property.Grid', {
     
     getCellEditor : function(record, column) {
         var me = this,
-            propName = record.get(me.nameField), 
+            propName = record.get(me.nameField),
             val = record.get(me.valueField),
             editor = me.customEditors[propName];
 
@@ -79973,7 +84208,9 @@ Ext.define('Ext.grid.property.Grid', {
 
     destroyEditors: function (editors) {
         for (var ed in editors) {
-            Ext.destroy(editors[ed]);
+            if (editors.hasOwnProperty(ed)) {
+                Ext.destroy(editors[ed]);
+            }
         }
     },
 
@@ -80009,6 +84246,8 @@ Ext.define('Ext.grid.property.HeaderContainer', {
     extend: 'Ext.grid.header.Container',
 
     alternateClassName: 'Ext.grid.PropertyColumnModel',
+    
+    nameWidth: 115,
 
     
     nameText : 'Name',
@@ -80019,27 +84258,27 @@ Ext.define('Ext.grid.property.HeaderContainer', {
 
     
     nameColumnCls: Ext.baseCSSPrefix + 'grid-property-name',
+
     
     constructor : function(grid, store) {
-
-        this.grid = grid;
-        this.store = store;
-        this.callParent([{
+        var me = this;
+        
+        me.grid = grid;
+        me.store = store;
+        me.callParent([{
             items: [{
-                header: this.nameText,
-                width: 115,
+                header: me.nameText,
+                width: grid.nameColumnWidth || me.nameWidth,
                 sortable: true,
                 dataIndex: grid.nameField,
-                renderer: Ext.Function.bind(this.renderProp, this),
+                renderer: Ext.Function.bind(me.renderProp, me),
                 itemId: grid.nameField,
                 menuDisabled :true,
-                tdCls: this.nameColumnCls
+                tdCls: me.nameColumnCls
             }, {
-                header: this.valueText,
-                renderer: Ext.Function.bind(this.renderCell, this),
-                getEditor: function(record) {
-                    return grid.getCellEditor(record, this);
-                },
+                header: me.valueText,
+                renderer: Ext.Function.bind(me.renderCell, me),
+                getEditor: Ext.Function.bind(me.getCellEditor, me),
                 flex: 1,
                 fixed: true,
                 dataIndex: grid.valueField,
@@ -80048,6 +84287,10 @@ Ext.define('Ext.grid.property.HeaderContainer', {
             }]
         }]);
     },
+    
+    getCellEditor: function(record){
+        return this.grid.getCellEditor(record, this);
+    },
 
     
     
@@ -80059,16 +84302,16 @@ Ext.define('Ext.grid.property.HeaderContainer', {
     
     renderCell : function(val, meta, rec) {
         var me = this,
-            renderer = this.grid.customRenderers[rec.get(me.grid.nameField)],
+            renderer = me.grid.customRenderers[rec.get(me.grid.nameField)],
             result = val;
 
         if (renderer) {
-            return renderer.apply(this, arguments);
+            return renderer.apply(me, arguments);
         }
         if (Ext.isDate(val)) {
-            result = this.renderDate(val);
+            result = me.renderDate(val);
         } else if (Ext.isBoolean(val)) {
-            result = this.renderBool(val);
+            result = me.renderBool(val);
         }
         return Ext.util.Format.htmlEncode(result);
     },
@@ -80111,13 +84354,16 @@ Ext.define('Ext.grid.property.Store', {
 
     uses: ['Ext.data.reader.Reader', 'Ext.data.proxy.Proxy', 'Ext.data.ResultSet', 'Ext.grid.property.Property'],
 
+    
     constructor : function(grid, source){
-        this.grid = grid;
-        this.source = source;
-        this.callParent([{
+        var me = this;
+        
+        me.grid = grid;
+        me.source = source;
+        me.callParent([{
             data: source,
             model: Ext.grid.property.Property,
-            proxy: this.getProxy()
+            proxy: me.getProxy()
         }]);
     },
 
@@ -80146,18 +84392,21 @@ Ext.define('Ext.grid.property.Store', {
 
                 readRecords: function(dataObject) {
                     var val,
+                        propName,
                         result = {
                             records: [],
                             success: true
                         };
 
-                    for (var propName in dataObject) {
-                        val = dataObject[propName];
-                        if (dataObject.hasOwnProperty(propName) && this.isEditableValue(val)) {
-                            result.records.push(new Ext.grid.property.Property({
-                                name: propName,
-                                value: val
-                            }, propName));
+                    for (propName in dataObject) {
+                        if (dataObject.hasOwnProperty(propName)) {
+                            val = dataObject[propName];
+                            if (this.isEditableValue(val)) {
+                                result.records.push(new Ext.grid.property.Property({
+                                    name: propName,
+                                    value: val
+                                }, propName));
+                            }
                         }
                     }
                     result.total = result.count = result.records.length;
@@ -80188,35 +84437,37 @@ Ext.define('Ext.grid.property.Store', {
 
     
     getProperty : function(row) {
-       return Ext.isNumber(row) ? this.store.getAt(row) : this.store.getById(row);
+       return Ext.isNumber(row) ? this.getAt(row) : this.getById(row);
     },
 
     
     setValue : function(prop, value, create){
-        var r = this.getRec(prop);
-        if (r) {
-            r.set('value', value);
-            this.source[prop] = value;
+        var me = this,
+            rec = me.getRec(prop);
+            
+        if (rec) {
+            rec.set('value', value);
+            me.source[prop] = value;
         } else if (create) {
             
-            this.source[prop] = value;
-            r = new Ext.grid.property.Property({name: prop, value: value}, prop);
-            this.store.add(r);
+            me.source[prop] = value;
+            rec = new Ext.grid.property.Property({name: prop, value: value}, prop);
+            me.add(rec);
         }
     },
 
     
     remove : function(prop) {
-        var r = this.getRec(prop);
-        if(r) {
-            this.store.remove(r);
+        var rec = this.getRec(prop);
+        if (rec) {
+            this.callParent([rec]);
             delete this.source[prop];
         }
     },
 
     
     getRec : function(prop) {
-        return this.store.getById(prop);
+        return this.getById(prop);
     },
 
     
@@ -80381,14 +84632,12 @@ Ext.define('Ext.layout.component.field.Slider', {
 });
 
 
-
 Ext.define('Ext.layout.container.Absolute', {
 
     
 
     alias: 'layout.absolute',
     extend: 'Ext.layout.container.Anchor',
-    requires: ['Ext.chart.axis.Axis', 'Ext.fx.Anim'],
     alternateClassName: 'Ext.layout.AbsoluteLayout',
 
     
@@ -80428,19 +84677,26 @@ Ext.define('Ext.layout.container.Accordion', {
     extend: 'Ext.layout.container.VBox',
     alias: ['layout.accordion'],
     alternateClassName: 'Ext.layout.AccordionLayout',
-    
+
+    itemCls: Ext.baseCSSPrefix + 'box-item ' + Ext.baseCSSPrefix + 'accordion-item',
+
     align: 'stretch',
 
     
     fill : true,
+
     
     autoWidth : true,
+
     
     titleCollapse : true,
+
     
     hideCollapseTool : false,
+
     
     collapseFirst : false,
+
     
     animate : true,
     
@@ -80470,7 +84726,7 @@ Ext.define('Ext.layout.container.Accordion', {
 
         me.callParent(arguments);
         if (me.fill) {
-            if (!me.owner.el.dom.style.height) {
+            if (!(me.owner.el.dom.style.height || me.getLayoutTargetSize().height)) {
                 return false;
             }
         } else {
@@ -80486,8 +84742,7 @@ Ext.define('Ext.layout.container.Accordion', {
             i = 0,
             comp,
             targetSize = me.getLayoutTargetSize(),
-            renderedPanels = [],
-            border;
+            renderedPanels = [];
 
         for (; i < ln; i++) {
             comp = items[i];
@@ -80509,7 +84764,6 @@ Ext.define('Ext.layout.container.Accordion', {
                 delete comp.hideHeader;
                 comp.collapsible = true;
                 comp.title = comp.title || '&#160;';
-                comp.setBorder(false);
 
                 
                 comp.width = targetSize.width;
@@ -80522,18 +84776,26 @@ Ext.define('Ext.layout.container.Accordion', {
                         comp.collapsed = true;
                     }
                     
-                    else if (comp.collapsed === false) {
+                    else if (comp.hasOwnProperty('collapsed') && comp.collapsed === false) {
                         comp.flex = 1;
                         me.expandedItem = i;
                     } else {
                         comp.collapsed = true;
                     }
+                    
+                    me.owner.mon(comp, {
+                        show: me.onComponentShow,
+                        beforeexpand: me.onComponentExpand,
+                        beforecollapse: me.onComponentCollapse,
+                        scope: me
+                    });
                 } else {
                     delete comp.flex;
                     comp.animCollapse = me.initialAnimate;
                     comp.autoHeight = true;
                     comp.autoScroll = false;
                 }
+                comp.border = comp.collapsed;
             }
         }
 
@@ -80541,15 +84803,15 @@ Ext.define('Ext.layout.container.Accordion', {
         if (ln && me.expandedItem === undefined) {
             me.expandedItem = 0;
             comp = items[0];
-            comp.collapsed = false;
+            comp.collapsed = comp.border = false;
             if (me.fill) {
                 comp.flex = 1;
             }
         }
-        
+
         
         me.callParent(arguments);
-                
+
         
         ln = renderedPanels.length;
         for (i = 0; i < ln; i++) {
@@ -80560,24 +84822,13 @@ Ext.define('Ext.layout.container.Accordion', {
 
             comp.header.addCls(Ext.baseCSSPrefix + 'accordion-hd');
             comp.body.addCls(Ext.baseCSSPrefix + 'accordion-body');
-            
-            
-            if (me.fill) {
-                me.owner.mon(comp, {
-                    show: me.onComponentShow,
-                    beforeexpand: me.onComponentExpand,
-                    beforecollapse: me.onComponentCollapse,
-                    scope: me
-                });
-            }
         }
     },
 
     onLayout: function() {
         var me = this;
-        
-        me.updatePanelClasses();
-                
+
+
         if (me.fill) {
             me.callParent(arguments);
         } else {
@@ -80595,24 +84846,33 @@ Ext.define('Ext.layout.container.Accordion', {
                 }
             }
         }
-        
+        me.updatePanelClasses();
+
         return me;
     },
-    
+
     updatePanelClasses: function() {
         var children = this.getLayoutItems(),
             ln = children.length,
             siblingCollapsed = true,
             i, child;
-            
+
         for (i = 0; i < ln; i++) {
             child = children[i];
-            if (!siblingCollapsed) {
-                child.header.addCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded');
+
+            
+            
+            if (Ext.isWindows) {
+                child.el.dom.scrollTop = 0;
             }
-            else {
+
+            if (siblingCollapsed) {
                 child.header.removeCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded');
             }
+            else {
+                child.header.addCls(Ext.baseCSSPrefix + 'accordion-hd-sibling-expanded');
+            }
+
             if (i + 1 == ln && child.collapsed) {
                 child.header.addCls(Ext.baseCSSPrefix + 'accordion-hd-last-collapsed');
             }
@@ -80622,6 +84882,21 @@ Ext.define('Ext.layout.container.Accordion', {
             siblingCollapsed = child.collapsed;
         }
     },
+    
+    animCallback: function(){
+        Ext.Array.forEach(this.toCollapse, function(comp){
+            comp.fireEvent('collapse', comp);
+        });
+        
+        Ext.Array.forEach(this.toExpand, function(comp){
+            comp.fireEvent('expand', comp);
+        });    
+    },
+    
+    setupEvents: function(){
+        this.toCollapse = [];
+        this.toExpand = [];    
+    },
 
     
     
@@ -80633,6 +84908,7 @@ Ext.define('Ext.layout.container.Accordion', {
             i = 0,
             comp;
 
+        me.setupEvents();
         for (; i < len; i++) {
             comp = it[i];
             if (comp === toExpand && comp.collapsed) {
@@ -80641,9 +84917,14 @@ Ext.define('Ext.layout.container.Accordion', {
                 me.setCollapsed(comp);
             }
         }
-        
+
         me.animate = me.initialAnimate;
-        me.layout();
+        if (me.activeOnTop) {
+            
+            me.owner.insert(0, toExpand); 
+        } else {
+            me.layout();
+        }
         me.animate = false;
         return false;
     },
@@ -80653,6 +84934,7 @@ Ext.define('Ext.layout.container.Accordion', {
             toExpand = comp.next() || comp.prev(),
             expanded = me.multi ? me.owner.query('>panel:not([collapsed])') : [];
 
+        me.setupEvents();
         
         
         if (me.multi) {
@@ -80663,7 +84945,7 @@ Ext.define('Ext.layout.container.Accordion', {
             if (expanded.length === 1 && expanded[0] === comp) {
                 me.setExpanded(toExpand);
             }
-            
+
             me.animate = me.initialAnimate;
             me.layout();
             me.animate = false;
@@ -80701,7 +84983,11 @@ Ext.define('Ext.layout.container.Accordion', {
         comp.el.setHeight(comp.height);
         comp.collapsed = true;
         delete comp.flex;
-        comp.fireEvent('collapse', comp);
+        if (this.initialAnimate) {
+            this.toCollapse.push(comp);
+        } else {
+            comp.fireEvent('collapse', comp);
+        }
         if (comp.collapseTool) {
             comp.collapseTool.setType('expand-' + comp.getOppositeDirection(comp.collapseDirection));
         }
@@ -80714,7 +85000,7 @@ Ext.define('Ext.layout.container.Accordion', {
 
         
         for (; i < len; i++) {
-            otherDocks[i].hidden = false;
+            otherDocks[i].show();
         }
 
         
@@ -80728,7 +85014,11 @@ Ext.define('Ext.layout.container.Accordion', {
         comp.flex = 1;
         comp.removeCls(comp.collapsedCls);
         comp.header.removeCls(comp.collapsedHeaderCls);
-        comp.fireEvent('expand', comp);
+         if (this.initialAnimate) {
+            this.toExpand.push(comp);
+        } else {
+            comp.fireEvent('expand', comp);
+        }
         if (comp.collapseTool) {
             comp.collapseTool.setType('collapse-' + comp.collapseDirection);
         }
@@ -80743,11 +85033,14 @@ Ext.define('Ext.resizer.Splitter', {
     alias: 'widget.splitter',
 
     renderTpl: [
-        '<tpl if="collapsible===true"><div class="' + Ext.baseCSSPrefix + 'collapse-el ' + Ext.baseCSSPrefix + 'layout-split-{collapseDir}">&nbsp;</div></tpl>'
+        '<tpl if="collapsible===true">',
+            '<div id="{id}-collapseEl" class="', Ext.baseCSSPrefix, 'collapse-el ',
+                    Ext.baseCSSPrefix, 'layout-split-{collapseDir}">&nbsp;</div>',
+        '</tpl>'
     ],
 
     baseCls: Ext.baseCSSPrefix + 'splitter',
-    collapsedCls: Ext.baseCSSPrefix + 'splitter-collapsed',
+    collapsedClsInternal: Ext.baseCSSPrefix + 'splitter-collapsed',
 
     
     collapsible: false,
@@ -80763,6 +85056,8 @@ Ext.define('Ext.resizer.Splitter', {
     
     defaultSplitMax: 1000,
 
+    
+
     width: 5,
     height: 5,
 
@@ -80780,9 +85075,8 @@ Ext.define('Ext.resizer.Splitter', {
             collapseDir: collapseDir,
             collapsible: me.collapsible || target.collapsible
         });
-        Ext.applyIf(me.renderSelectors, {
-            collapseEl: '.' + Ext.baseCSSPrefix + 'collapse-el'
-        });
+
+        me.addChildEls('collapseEl');
 
         this.callParent(arguments);
 
@@ -80806,6 +85100,9 @@ Ext.define('Ext.resizer.Splitter', {
         me.tracker = Ext.create('Ext.resizer.SplitterTracker', {
             el: me.el
         });
+
+        
+        me.relayEvents(me.tracker, [ 'beforedragstart', 'dragstart', 'dragend' ]);
     },
 
     getCollapseDirection: function() {
@@ -80832,15 +85129,17 @@ Ext.define('Ext.resizer.Splitter', {
     },
 
     getCollapseTarget: function() {
-        return this.collapseTarget.isComponent ? this.collapseTarget : this.collapseTarget == 'prev' ? this.previousSibling() : this.nextSibling();
+        var me = this;
+
+        return me.collapseTarget.isComponent ? me.collapseTarget : me.collapseTarget == 'prev' ? me.previousSibling() : me.nextSibling();
     },
 
     onTargetCollapse: function(target) {
-        this.el.addCls(this.collapsedCls);
+        this.el.addCls([this.collapsedClsInternal, this.collapsedCls]);
     },
 
     onTargetExpand: function(target) {
-        this.el.removeCls(this.collapsedCls);
+        this.el.removeCls([this.collapsedClsInternal, this.collapsedCls]);
     },
 
     toggleTargetCmp: function(e, t) {
@@ -80881,8 +85180,6 @@ Ext.define('Ext.layout.container.Border', {
 
     bindToOwnerCtContainer: true,
 
-    fixedLayout: false,
-
     percentageRe: /(\d+)%/,
 
     slideDirection: {
@@ -80904,6 +85201,7 @@ Ext.define('Ext.layout.container.Border', {
         }
 
         
+        me.fixHeightConstraints();
         me.shadowLayout.onLayout();
         if (me.embeddedContainer) {
             me.embeddedContainer.layout.onLayout();
@@ -80937,14 +85235,27 @@ Ext.define('Ext.layout.container.Border', {
 
         
         this.shadowLayout.beforeLayout();
+
+        
     },
 
     renderItems: function(items, target) {
-        Ext.Error.raise('This should not be called');
     },
 
     renderItem: function(item) {
-        Ext.Error.raise('This should not be called');
+    },
+
+    renderChildren: function() {
+        if (!this.borderLayoutInitialized) {
+            this.initializeBorderLayout();
+        }
+
+        this.shadowLayout.renderChildren();
+    },
+
+    
+    getVisibleItems: function() {
+        return Ext.ComponentQuery.query(':not([slideOutAnim])', this.callParent(arguments));
     },
 
     initializeBorderLayout: function() {
@@ -80972,7 +85283,7 @@ Ext.define('Ext.layout.container.Border', {
 
                 
                 comp.borderCollapse = comp.collapsed;
-                delete comp.collapsed;
+                comp.collapsed = false;
 
                 comp.on({
                     beforecollapse: me.onBeforeRegionCollapse,
@@ -80983,9 +85294,6 @@ Ext.define('Ext.layout.container.Border', {
                 me.setupState(comp);
             }
         }
-        if (!regions.center) {
-            Ext.Error.raise("You must specify a center region when defining a BorderLayout.");
-        }
         comp = regions.center;
         if (!comp.flex) {
             comp.flex = 1;
@@ -81035,7 +85343,8 @@ Ext.define('Ext.layout.container.Border', {
                     maintainFlex: true,
                     layout: {
                         type: 'hbox',
-                        align: 'stretch'
+                        align: 'stretch',
+                        getVisibleItems: me.getVisibleItems
                     }
                 }));
                 hBoxItems.push(regions.center);
@@ -81089,7 +85398,8 @@ Ext.define('Ext.layout.container.Border', {
                 el: me.getTarget(),
                 layout: Ext.applyIf({
                     type: 'vbox',
-                    align: 'stretch'
+                    align: 'stretch',
+                    getVisibleItems: me.getVisibleItems
                 }, me.initialConfig)
             });
             me.createItems(me.shadowContainer, vBoxItems);
@@ -81116,6 +85426,17 @@ Ext.define('Ext.layout.container.Border', {
                 }
 
                 
+                
+                
+                
+                
+                Ext.each([me.splitters.north, me.splitters.south], function (splitter) {
+                    if (splitter) {
+                        splitter.on('beforedragstart', me.fixHeightConstraints, me);
+                    }
+                });
+
+                
                 if (horizontalFlex) {
                     regions.center.flex -= horizontalFlex;
                 }
@@ -81173,7 +85494,6 @@ Ext.define('Ext.layout.container.Border', {
         me.borderLayoutInitialized = true;
     },
 
-
     setupState: function(comp){
         var getState = comp.getState;
         comp.getState = function(){
@@ -81223,6 +85543,7 @@ Ext.define('Ext.layout.container.Border', {
         
         if (comp.collapseMode == 'mini') {
             comp.placeholder = resizer;
+            resizer.collapsedCls = comp.collapsedCls;
         }
 
         
@@ -81235,6 +85556,30 @@ Ext.define('Ext.layout.container.Border', {
     },
 
     
+    
+    fixHeightConstraints: function () {
+        var me = this,
+            ct = me.embeddedContainer,
+            maxHeight = 1e99, minHeight = -1;
+
+        if (!ct) {
+            return;
+        }
+
+        ct.items.each(function (item) {
+            if (Ext.isNumber(item.maxHeight)) {
+                maxHeight = Math.max(maxHeight, item.maxHeight);
+            }
+            if (Ext.isNumber(item.minHeight)) {
+                minHeight = Math.max(minHeight, item.minHeight);
+            }
+        });
+
+        ct.maxHeight = maxHeight;
+        ct.minHeight = minHeight;
+    },
+
+    
     onRegionVisibilityChange: function(comp){
         this.splitters[comp.region][comp.hidden ? 'hide' : 'show']();
         this.layout();
@@ -81292,7 +85637,7 @@ Ext.define('Ext.layout.container.Border', {
                     baseCls: comp.baseCls + '-header',
                     ui: comp.ui,
                     indicateDrag: comp.draggable,
-                    cls: Ext.baseCSSPrefix + 'region-collapsed-placeholder ' + Ext.baseCSSPrefix + 'region-collapsed-' + comp.collapseDirection + '-placeholder',
+                    cls: Ext.baseCSSPrefix + 'region-collapsed-placeholder ' + Ext.baseCSSPrefix + 'region-collapsed-' + comp.collapseDirection + '-placeholder ' + comp.collapsedCls,
                     listeners: comp.floatable ? {
                         click: {
                             fn: function(e) {
@@ -81306,13 +85651,15 @@ Ext.define('Ext.layout.container.Border', {
                 if ((Ext.isIE6 || Ext.isIE7 || (Ext.isIEQuirks)) && !horiz) {
                     placeholder.width = 25;
                 }
-                placeholder[horiz ? 'tools' : 'items'] = [{
-                    xtype: 'tool',
-                    client: comp,
-                    type: 'expand-' + oppositeDirection,
-                    handler: me.onPlaceHolderToolClick,
-                    scope: me
-                }];
+                if (!comp.hideCollapseTool) {
+                    placeholder[horiz ? 'tools' : 'items'] = [{
+                        xtype: 'tool',
+                        client: comp,
+                        type: 'expand-' + oppositeDirection,
+                        handler: me.onPlaceHolderToolClick,
+                        scope: me
+                    }];
+                }
             }
             placeholder = me.owner.createComponent(placeholder);
             if (comp.isXType('panel')) {
@@ -81354,14 +85701,17 @@ Ext.define('Ext.layout.container.Border', {
 
     
     onBeforeRegionCollapse: function(comp, direction, animate) {
+        if (comp.collapsedChangingLayout) {
+            return false;
+        }
+        comp.collapsedChangingLayout = true;
         var me = this,
             compEl = comp.el,
+            width,
             miniCollapse = comp.collapseMode == 'mini',
             shadowContainer = comp.shadowOwnerCt,
             shadowLayout = shadowContainer.layout,
             placeholder = comp.placeholder,
-            placeholderBox,
-            targetSize = shadowLayout.getLayoutTargetSize(),
             sl = me.owner.suspendLayout,
             scsl = shadowContainer.suspendLayout,
             isNorthOrWest = (comp.region == 'north' || comp.region == 'west'); 
@@ -81404,11 +85754,21 @@ Ext.define('Ext.layout.container.Border', {
 
         if (!placeholder.rendered) {
             shadowLayout.renderItem(placeholder, shadowLayout.innerCt);
+
+            
+            
+            
+            
+            
+            if (comp.region == 'north' || comp.region == 'south') {
+                placeholder.setCalculatedSize(comp.getWidth());
+            } else {
+                placeholder.setCalculatedSize(undefined, comp.getHeight());
+            }
         }
 
         
         function afterCollapse() {
-
             
             me.owner.suspendLayout = sl;
             shadowContainer.suspendLayout = scsl;
@@ -81419,6 +85779,7 @@ Ext.define('Ext.layout.container.Border', {
             delete me.shadowContainer.layout.layoutBusy;
             delete me.layoutBusy;
             delete me.owner.componentLayout.layoutBusy;
+            delete comp.collapsedChangingLayout;
 
             
             comp.collapsed = true;
@@ -81456,11 +85817,6 @@ Ext.define('Ext.layout.container.Border', {
             compEl.setLeftTop(-10000, -10000);
             shadowLayout.layout();
             afterCollapse();
-
-            
-            if (Ext.isIE) {
-                placeholder.setCalculatedSize(placeholder.el.getWidth());
-            }
         }
 
         return false;
@@ -81468,7 +85824,8 @@ Ext.define('Ext.layout.container.Border', {
 
     
     onBeforeRegionExpand: function(comp, animate) {
-        this.onPlaceHolderToolClick(null, null, null, {client: comp});
+        
+        this.onPlaceHolderToolClick(null, null, null, {client: comp, shouldFireBeforeexpand: false});
         return false;
     },
 
@@ -81490,6 +85847,13 @@ Ext.define('Ext.layout.container.Border', {
             scsl = shadowContainer.suspendLayout,
             isFloating;
 
+        if (comp.collapsedChangingLayout) {
+            return false;
+        }
+        if (tool.shouldFireBeforeexpand !== false && comp.fireEvent('beforeexpand', comp, true) === false) {
+            return false;
+        }
+        comp.collapsedChangingLayout = true;
         
         
         
@@ -81565,6 +85929,7 @@ Ext.define('Ext.layout.container.Border', {
             delete me.shadowContainer.layout.layoutBusy;
             delete me.layoutBusy;
             delete me.owner.componentLayout.layoutBusy;
+            delete comp.collapsedChangingLayout;
 
             
             comp.removeCls(Ext.baseCSSPrefix + 'border-region-slide-in');
@@ -81783,15 +86148,13 @@ Ext.define('Ext.layout.container.Card', {
 
     
 
+    
     setActiveItem: function(newCard) {
         var me = this,
             owner = me.owner,
             oldCard = me.activeItem,
             newIndex;
 
-        
-        me.layoutBusy = true;
-
         newCard = me.parseActiveItem(newCard);
         newIndex = owner.items.indexOf(newCard);
 
@@ -81813,22 +86176,22 @@ Ext.define('Ext.layout.container.Card', {
 
             
             if (newCard.fireEvent('beforeactivate', newCard, oldCard) === false) {
-                me.layoutBusy = false;
                 return false;
             }
             if (oldCard && oldCard.fireEvent('beforedeactivate', oldCard, newCard) === false) {
-                me.layoutBusy = false;
                 return false;
             }
 
             
-            if (!me.sizeAllCards) {
-                me.setItemBox(newCard, me.getTargetBox());
-            }
-            else {
+            if (me.sizeAllCards) {
                 
                 me.onLayout();
             }
+            else {
+                me.setItemBox(newCard, me.getTargetBox());
+            }
+
+            me.owner.suspendLayout = true;
 
             if (oldCard) {
                 if (me.hideInactive) {
@@ -81838,26 +86201,28 @@ Ext.define('Ext.layout.container.Card', {
             }
 
             
+            me.owner.suspendLayout = false;
             if (newCard.hidden) {
                 newCard.show();
+            } else {
+                me.onLayout();
             }
 
             newCard.fireEvent('activate', newCard, oldCard);
 
-            me.layoutBusy = false;
-
-            if (!me.sizeAllCards) {
-                if (!owner.componentLayout.layoutBusy) {
-                    me.onLayout();
-                }
-            }
             return newCard;
         }
-
-        me.layoutBusy = false;
         return false;
-    }
-});
+    },
+
+    configureItem: function(item) {
+        
+        
+        item.layoutManagedHeight = 0;
+        item.layoutManagedWidth = 0;
+
+        this.callParent(arguments);
+    }});
 
 Ext.define('Ext.layout.container.Column', {
 
@@ -81950,9 +86315,9 @@ Ext.define('Ext.layout.container.Column', {
             item = items[i];
             if (item.columnWidth) {
                 columnWidth = Math.floor(item.columnWidth * availableWidth) - parallelMargins[i];
-                if (item.getWidth() != columnWidth) {
-                    me.setItemSize(item, columnWidth, item.height);
-                }
+                me.setItemSize(item, columnWidth, item.height);
+            } else {
+                me.layoutItem(item);
             }
         }
 
@@ -81974,10 +86339,17 @@ Ext.define('Ext.layout.container.Column', {
             }
         }
         delete me.adjustmentPass;
+    },
+
+    configureItem: function(item) {
+        this.callParent(arguments);
+
+        if (item.columnWidth) {
+            item.layoutManagedWidth = 1;
+        }
     }
 });
 
-
 Ext.define('Ext.layout.container.Table', {
 
     
@@ -82009,6 +86381,10 @@ Ext.define('Ext.layout.container.Table', {
     tableAttrs:null,
 
     
+
+    
+
+    
     renderItems: function(items) {
         var tbody = this.getTable().tBodies[0],
             rows = tbody.rows,
@@ -82032,6 +86408,9 @@ Ext.define('Ext.layout.container.Table', {
             trEl = rows[rowIdx];
             if (!trEl) {
                 trEl = tbody.insertRow(rowIdx);
+                if (this.trAttrs) {
+                    trEl.set(this.trAttrs);
+                }
             }
 
             
@@ -82050,6 +86429,9 @@ Ext.define('Ext.layout.container.Table', {
             }
 
             
+            if (this.tdAttrs) {
+                tdEl.set(this.tdAttrs);
+            }
             tdEl.set({
                 colSpan: item.colspan || 1,
                 rowSpan: item.rowspan || 1,
@@ -82125,9 +86507,11 @@ Ext.define('Ext.layout.container.Table', {
             });
 
             
-            rowspans[colIdx] = item.rowspan || 1;
-            colIdx += item.colspan || 1;
-            cellIdx++;
+            for (j = item.colspan || 1; j; --j) {
+                rowspans[colIdx] = item.rowspan || 1;
+                ++colIdx;
+            }
+            ++cellIdx;
         }
 
         return cells;
@@ -82161,75 +86545,77 @@ Ext.define('Ext.menu.Item', {
     extend: 'Ext.Component',
     alias: 'widget.menuitem',
     alternateClassName: 'Ext.menu.TextItem',
+
     
+
     
 
     
     activeCls: Ext.baseCSSPrefix + 'menu-item-active',
-    
+
     
     ariaRole: 'menuitem',
-    
+
     
     canActivate: true,
-    
+
     
     clickHideDelay: 1,
-    
+
     
     destroyMenu: true,
-    
+
     
     disabledCls: Ext.baseCSSPrefix + 'menu-item-disabled',
+
     
-    
-     
+
      
-    
+
     
     hideOnClick: true,
+
     
+
     
-     
-    
-    
+
     isMenuItem: true,
+
     
-    
-    
+
     
     menuAlign: 'tl-tr?',
-    
+
     
     menuExpandDelay: 200,
-    
+
     
     menuHideDelay: 200,
+
     
-    
-    
+
     renderTpl: [
         '<tpl if="plain">',
             '{text}',
         '</tpl>',
         '<tpl if="!plain">',
-            '<a class="' + Ext.baseCSSPrefix + 'menu-item-link" href="{href}" <tpl if="hrefTarget">target="{hrefTarget}"</tpl> hidefocus="true" unselectable="on">',
-                '<img src="{icon}" class="' + Ext.baseCSSPrefix + 'menu-item-icon {iconCls}" />',
-                '<span class="' + Ext.baseCSSPrefix + 'menu-item-text" <tpl if="menu">style="margin-right: 17px;"</tpl> >{text}</span>',
+            '<a id="{id}-itemEl" class="' + Ext.baseCSSPrefix + 'menu-item-link" href="{href}" <tpl if="hrefTarget">target="{hrefTarget}"</tpl> hidefocus="true" unselectable="on">',
+                '<img id="{id}-iconEl" src="{icon}" class="' + Ext.baseCSSPrefix + 'menu-item-icon {iconCls}" />',
+                '<span id="{id}-textEl" class="' + Ext.baseCSSPrefix + 'menu-item-text" <tpl if="menu">style="margin-right: 17px;"</tpl> >{text}</span>',
                 '<tpl if="menu">',
-                    '<img src="' + Ext.BLANK_IMAGE_URL + '" class="' + Ext.baseCSSPrefix + 'menu-item-arrow" />',
+                    '<img id="{id}-arrowEl" src="{blank}" class="' + Ext.baseCSSPrefix + 'menu-item-arrow" />',
                 '</tpl>',
             '</a>',
         '</tpl>'
     ],
-    
+
     maskOnDisable: false,
+
     
-    
-    
+
     activate: function() {
         var me = this;
-        
+
         if (!me.activated && me.canActivate && me.rendered && !me.isDisabled() && me.isVisible()) {
             me.el.addCls(me.activeCls);
             me.focus();
@@ -82237,15 +86623,15 @@ Ext.define('Ext.menu.Item', {
             me.fireEvent('activate', me);
         }
     },
-    
+
     blur: function() {
         this.$focused = false;
         this.callParent(arguments);
     },
-    
+
     deactivate: function() {
         var me = this;
-        
+
         if (me.activated) {
             me.el.removeCls(me.activeCls);
             me.blur();
@@ -82254,10 +86640,10 @@ Ext.define('Ext.menu.Item', {
             me.fireEvent('deactivate', me);
         }
     },
-    
+
     deferExpandMenu: function() {
         var me = this;
-        
+
         if (!me.menu.rendered || !me.menu.isVisible()) {
             me.parentMenu.activeChild = me.menu;
             me.menu.parentItem = me;
@@ -82265,20 +86651,20 @@ Ext.define('Ext.menu.Item', {
             me.menu.showBy(me, me.menuAlign);
         }
     },
-    
+
     deferHideMenu: function() {
         if (this.menu.isVisible()) {
             this.menu.hide();
         }
     },
-    
+
     deferHideParentMenus: function() {
         Ext.menu.Manager.hideAll();
     },
-    
+
     expandMenu: function(delay) {
         var me = this;
-        
+
         if (me.menu) {
             clearTimeout(me.hideMenuTimer);
             if (delay === 0) {
@@ -82288,95 +86674,95 @@ Ext.define('Ext.menu.Item', {
             }
         }
     },
-    
+
     focus: function() {
         this.$focused = true;
         this.callParent(arguments);
     },
-    
+
     getRefItems: function(deep){
         var menu = this.menu,
             items;
-        
+
         if (menu) {
             items = menu.getRefItems(deep);
             items.unshift(menu);
-        }   
-        return items || [];   
+        }
+        return items || [];
     },
-    
+
     hideMenu: function(delay) {
         var me = this;
-        
+
         if (me.menu) {
             clearTimeout(me.expandMenuTimer);
             me.hideMenuTimer = Ext.defer(me.deferHideMenu, Ext.isNumber(delay) ? delay : me.menuHideDelay, me);
         }
     },
-    
+
     initComponent: function() {
         var me = this,
             prefix = Ext.baseCSSPrefix,
             cls = [prefix + 'menu-item'];
-        
+
         me.addEvents(
             
             'activate',
-            
+
             
             'click',
-            
+
             
             'deactivate'
         );
-        
+
         if (me.plain) {
             cls.push(prefix + 'menu-item-plain');
         }
-        
+
         if (me.cls) {
             cls.push(me.cls);
         }
-        
+
         me.cls = cls.join(' ');
-        
+
         if (me.menu) {
             me.menu = Ext.menu.Manager.get(me.menu);
         }
-        
+
         me.callParent(arguments);
     },
-    
+
     onClick: function(e) {
         var me = this;
-        
+
         if (!me.href) {
             e.stopEvent();
         }
-        
+
         if (me.disabled) {
             return;
         }
-        
+
         if (me.hideOnClick) {
             me.deferHideParentMenusTimer = Ext.defer(me.deferHideParentMenus, me.clickHideDelay, me);
         }
-        
+
         Ext.callback(me.handler, me.scope || me, [me, e]);
         me.fireEvent('click', me, e);
-        
+
         if (!me.hideOnClick) {
             me.focus();
         }
     },
-    
+
     onDestroy: function() {
         var me = this;
-        
+
         clearTimeout(me.expandMenuTimer);
         clearTimeout(me.hideMenuTimer);
         clearTimeout(me.deferHideParentMenusTimer);
-        
+
         if (me.menu) {
             delete me.menu.parentItem;
             delete me.menu.parentMenu;
@@ -82387,80 +86773,66 @@ Ext.define('Ext.menu.Item', {
         }
         me.callParent(arguments);
     },
-    
+
     onRender: function(ct, pos) {
         var me = this,
-            prefix = '.' + Ext.baseCSSPrefix;
-        
+            blank = Ext.BLANK_IMAGE_URL;
+
         Ext.applyIf(me.renderData, {
             href: me.href || '#',
             hrefTarget: me.hrefTarget,
-            icon: me.icon || Ext.BLANK_IMAGE_URL,
-            iconCls: me.iconCls,
+            icon: me.icon || blank,
+            iconCls: me.iconCls + (me.checkChangeDisabled ? ' ' + me.disabledCls : ''),
             menu: Ext.isDefined(me.menu),
             plain: me.plain,
-            text: me.text
-        });
-        
-        Ext.applyIf(me.renderSelectors, {
-            itemEl: prefix + 'menu-item-link',
-            iconEl: prefix + 'menu-item-icon',
-            textEl: prefix + 'menu-item-text',
-            arrowEl: prefix + 'menu-item-arrow'
+            text: me.text,
+            blank: blank
         });
-        
+
+        me.addChildEls('itemEl', 'iconEl', 'textEl', 'arrowEl');
+
         me.callParent(arguments);
     },
-    
+
     
     setHandler: function(fn, scope) {
         this.handler = fn || null;
         this.scope = scope;
     },
-    
+
     
     setIconCls: function(iconCls) {
         var me = this;
-        
+
         if (me.iconEl) {
             if (me.iconCls) {
                 me.iconEl.removeCls(me.iconCls);
             }
-            
+
             if (iconCls) {
                 me.iconEl.addCls(iconCls);
             }
         }
-        
+
         me.iconCls = iconCls;
     },
-    
+
     
     setText: function(text) {
         var me = this,
-            el = me.textEl || me.el,
-            newWidth;
-        
-        if (text && el) {
-            el.update(text);
-                
-            if (me.textEl) {
-                
-                newWidth = me.textEl.getWidth() + me.iconEl.getWidth() + 25 + (me.arrowEl ? me.arrowEl.getWidth() : 0);
-                if (newWidth > me.itemEl.getWidth()) {
-                    me.parentMenu.setWidth(newWidth);
-                }
-            }
-        } else if (el) {
-            el.update('');
-        }
-        
+            el = me.textEl || me.el;
+
         me.text = text;
+
+        if (me.rendered) {
+            el.update(text || '');
+            
+            me.ownerCt.redoComponentLayout();
+        }
     }
 });
 
 
-
 Ext.define('Ext.menu.CheckItem', {
     extend: 'Ext.menu.Item',
     alias: 'widget.menucheckitem',
@@ -82510,7 +86882,9 @@ Ext.define('Ext.menu.CheckItem', {
     disableCheckChange: function() {
         var me = this;
 
-        me.iconEl.addCls(me.disabledCls);
+        if (me.iconEl) {
+            me.iconEl.addCls(me.disabledCls);
+        }
         me.checkChangeDisabled = true;
     },
 
@@ -82585,10 +86959,14 @@ Ext.define('Ext.menu.KeyNav', {
     },
 
     enter: function(e) {
-        var menu = this.menu;
-
+        var menu = this.menu,
+            focused = menu.focusedItem;
         if (menu.activeItem) {
             menu.onClick(e);
+        } else if (focused && focused.isFormField) {
+            
+            return true;
         }
     },
 
@@ -82683,58 +87061,54 @@ Ext.define('Ext.menu.KeyNav', {
 Ext.define('Ext.menu.Separator', {
     extend: 'Ext.menu.Item',
     alias: 'widget.menuseparator',
+
     
-    
-    
+
     
     canActivate: false,
+
     
+
     
-     
-    
-     
+
     
-     
+
     focusable: false,
-     
-    
-    
+
     
+
     
+
     
     hideOnClick: false,
+
     
+
     
+
     
+
     
+
     
+
     
-    
-    
-    
-    
-    
-    
-    
+
     
     plain: true,
-    
+
     
     separatorCls: Ext.baseCSSPrefix + 'menu-item-separator',
-    
+
     
     text: '&#160;',
-    
+
     onRender: function(ct, pos) {
         var me = this,
             sepCls = me.separatorCls;
-            
+
         me.cls += ' ' + sepCls;
-        
-        Ext.applyIf(me.renderSelectors, {
-            itemSepEl: '.' + sepCls
-        });
-        
+
         me.callParent(arguments);
     }
 });
@@ -82753,6 +87127,8 @@ Ext.define('Ext.menu.Menu', {
     ],
 
     
+
+    
     allowOtherMenus: false,
 
     
@@ -82767,11 +87143,13 @@ Ext.define('Ext.menu.Menu', {
     floating: true,
 
     
-    constrain: false,
+    constrain: true,
 
     
     hidden: true,
 
+    hideMode: 'visibility',
+
     
     ignoreParentClicks: false,
 
@@ -82789,7 +87167,9 @@ Ext.define('Ext.menu.Menu', {
 
     initComponent: function() {
         var me = this,
-            prefix = Ext.baseCSSPrefix;
+            prefix = Ext.baseCSSPrefix,
+            cls = [prefix + 'menu'],
+            bodyCls = me.bodyCls ? [me.bodyCls] : [];
 
         me.addEvents(
             
@@ -82808,14 +87188,12 @@ Ext.define('Ext.menu.Menu', {
         Ext.menu.Manager.register(me);
 
         
-        var cls = [prefix + 'menu'];
         if (me.plain) {
             cls.push(prefix + 'menu-plain');
         }
         me.cls = cls.join(' ');
 
         
-        var bodyCls = me.bodyCls ? [me.bodyCls] : [];
         bodyCls.unshift(prefix + 'menu-body');
         me.bodyCls = bodyCls.join(' ');
 
@@ -82893,7 +87271,7 @@ Ext.define('Ext.menu.Menu', {
         
         
         
-        if ((!Ext.iStrict && Ext.isIE) || Ext.isIE6) {
+        if ((!Ext.isStrict && Ext.isIE) || Ext.isIE6) {
             var innerCt = me.layout.getRenderTarget(),
                 innerCtWidth = 0,
                 dis = me.dockedItems,
@@ -82917,6 +87295,10 @@ Ext.define('Ext.menu.Menu', {
             me.el.setWidth(newWidth);
         }
     },
+    
+    getBubbleTarget: function(){
+        return this.parentMenu || this.callParent();
+    },
 
     
     canActivateItem: function(item) {
@@ -82933,7 +87315,9 @@ Ext.define('Ext.menu.Menu', {
                 delete me.activeItem;
             }
         }
-        if (me.focusedItem) {
+
+        
+        if (me.focusedItem && !me.filtered) {
             me.focusedItem.blur();
             if (!me.focusedItem.$focused) {
                 delete me.focusedItem;
@@ -82941,6 +87325,47 @@ Ext.define('Ext.menu.Menu', {
         }
     },
 
+    clearStretch: function () {
+        
+        
+        if (this.rendered) {
+            this.items.each(function (item) {
+                
+                if (item.componentLayout) {
+                    delete item.componentLayout.lastComponentSize;
+                }
+                if (item.el) {
+                    item.el.setWidth(null);
+                }
+            });
+        }
+    },
+
+    onAdd: function () {
+        var me = this;
+
+        me.clearStretch();
+        me.callParent(arguments);
+
+        if (Ext.isIE6 || Ext.isIE7) {
+            
+            Ext.Function.defer(me.doComponentLayout, 10, me);
+        }
+    },
+
+    onRemove: function () {
+        this.clearStretch();
+        this.callParent(arguments);
+
+    },
+
+    redoComponentLayout: function () {
+        if (this.rendered) {
+            this.clearStretch();
+            this.doComponentLayout();
+        }
+    },
+
     
     getFocusEl: function() {
         return this.focusEl;
@@ -82976,7 +87401,9 @@ Ext.define('Ext.menu.Menu', {
     
     lookupItemFromObject: function(cmp) {
         var me = this,
-            prefix = Ext.baseCSSPrefix;
+            prefix = Ext.baseCSSPrefix,
+            cls,
+            intercept;
 
         if (!cmp.isComponent) {
             if (!cmp.xtype) {
@@ -82991,11 +87418,8 @@ Ext.define('Ext.menu.Menu', {
         }
 
         if (!cmp.isMenuItem && !cmp.dock) {
-            var cls = [
-                    prefix + 'menu-item',
-                    prefix + 'menu-item-cmp'
-                ],
-                intercept = Ext.Function.createInterceptor;
+            cls = [prefix + 'menu-item', prefix + 'menu-item-cmp'];
+            intercept = Ext.Function.createInterceptor;
 
             
             cmp.focus = intercept(cmp.focus, function() {
@@ -83131,39 +87555,45 @@ Ext.define('Ext.menu.Menu', {
 
     
     showBy: function(cmp, pos, off) {
-        var me = this;
+        var me = this,
+            xy,
+            region;
 
         if (me.floating && cmp) {
             me.layout.autoSize = true;
-            me.show();
+
+            
+            me.doAutoRender();
+            delete me.needsLayout;
 
             
             cmp = cmp.el || cmp;
 
             
-            var xy = me.el.getAlignToXY(cmp, pos || me.defaultAlign, off);
+            xy = me.el.getAlignToXY(cmp, pos || me.defaultAlign, off);
             if (me.floatParent) {
-                var r = me.floatParent.getTargetEl().getViewRegion();
-                xy[0] -= r.x;
-                xy[1] -= r.y;
+                region = me.floatParent.getTargetEl().getViewRegion();
+                xy[0] -= region.x;
+                xy[1] -= region.y;
             }
             me.showAt(xy);
-            me.doConstrain();
         }
         return me;
     },
 
     doConstrain : function() {
         var me = this,
-            y = this.el.getY(),
+            y = me.el.getY(),
             max, full,
+            vector,
             returnY = y, normalY, parentEl, scrollTop, viewHeight;
 
         delete me.height;
         me.setSize();
         full = me.getHeight();
         if (me.floating) {
-            parentEl = Ext.fly(me.el.dom.parentNode);
+            
+            parentEl = Ext.fly(me.el.getScopeParent());
             scrollTop = parentEl.getScroll().top;
             viewHeight = parentEl.getViewSize().height;
             
@@ -83192,10 +87622,15 @@ Ext.define('Ext.menu.Menu', {
                 me.iconSepEl.setHeight(me.layout.getRenderTarget().dom.scrollHeight);
             }
         }
+        vector = me.getConstrainVector(me.el.getScopeParent());
+        if (vector) {
+            me.setPosition(me.getPosition()[0] + vector[0]);
+        }
         me.el.setY(returnY);
     }
 });
 
+
  Ext.define('Ext.menu.ColorPicker', {
      extend: 'Ext.menu.Menu',
 
@@ -83220,8 +87655,11 @@ Ext.define('Ext.menu.Menu', {
     
 
     initComponent : function(){
-        var me = this;
+        var me = this,
+            cfg = Ext.apply({}, me.initialConfig);
 
+        
+        delete cfg.listeners;
         Ext.apply(me, {
             plain: true,
             showSeparator: false,
@@ -83229,7 +87667,7 @@ Ext.define('Ext.menu.Menu', {
                 cls: Ext.baseCSSPrefix + 'menu-color-item',
                 id: me.pickerId,
                 xtype: 'colorpicker'
-            }, me.initialConfig)
+            }, cfg)
         });
 
         me.callParent(arguments);
@@ -83279,6 +87717,8 @@ Ext.define('Ext.menu.Menu', {
         Ext.apply(me, {
             showSeparator: false,
             plain: true,
+            border: false,
+            bodyPadding: 0, 
             items: Ext.applyIf({
                 cls: Ext.baseCSSPrefix + 'menu-date-item',
                 id: me.pickerId,
@@ -83312,16 +87752,19 @@ Ext.define('Ext.panel.Tool', {
     toolPressedCls: Ext.baseCSSPrefix + 'tool-pressed',
     toolOverCls: Ext.baseCSSPrefix + 'tool-over',
     ariaRole: 'button',
-    renderTpl: ['<img src="{blank}" class="{baseCls}-{type}" role="presentation"/>'],
-    
-    
-    
-    
-    
+    renderTpl: ['<img id="{id}-toolEl" src="{blank}" class="{baseCls}-{type}" role="presentation"/>'],
+
     
+
     
+
     
+
     
+
+     
+    tooltipType: 'qtip',
+
     
     stopEvent: true,
 
@@ -83331,39 +87774,8 @@ Ext.define('Ext.panel.Tool', {
             
             'click'
         );
-        
-        var types = [
-            'close', 
-            'collapse', 
-            'down', 
-            'expand', 
-            'gear', 
-            'help', 
-            'left', 
-            'maximize', 
-            'minimize', 
-            'minus', 
-            'move', 
-            'next', 
-            'pin', 
-            'plus', 
-            'prev', 
-            'print', 
-            'refresh', 
-            'resize', 
-            'restore', 
-            'right', 
-            'save', 
-            'search', 
-            'toggle',
-            'unpin', 
-            'up'
-        ];
-        
-        if (me.id && Ext.Array.indexOf(types, me.id) > -1) {
-            Ext.global.console.warn('When specifying a tool you should use the type option, the id can conflict now that tool is a Component');
-        }
-        
+
+
         me.type = me.type || me.id;
 
         Ext.applyIf(me.renderData, {
@@ -83371,22 +87783,29 @@ Ext.define('Ext.panel.Tool', {
             blank: Ext.BLANK_IMAGE_URL,
             type: me.type
         });
-        me.renderSelectors.toolEl = '.' + me.baseCls + '-' + me.type;
+
+        me.addChildEls('toolEl');
+
+        
+        me.tooltip = me.tooltip || me.qtip;
         me.callParent();
     },
 
     
     afterRender: function() {
-        var me = this;
+        var me = this,
+            attr;
+
         me.callParent(arguments);
-        if (me.qtip) {
-            if (Ext.isObject(me.qtip)) {
+        if (me.tooltip) {
+            if (Ext.isObject(me.tooltip)) {
                 Ext.tip.QuickTipManager.register(Ext.apply({
                     target: me.id
-                }, me.qtip));
+                }, me.tooltip));
             }
             else {
-                me.toolEl.dom.qtip = me.qtip;
+                attr = me.tooltipType == 'qtip' ? 'data-qtip' : 'title';
+                me.toolEl.dom.setAttribute(attr, me.tooltip);
             }
         }
 
@@ -83402,7 +87821,7 @@ Ext.define('Ext.panel.Tool', {
     
     setType: function(type) {
         var me = this;
-        
+
         me.type = type;
         if (me.rendered) {
             me.toolEl.dom.className = me.baseCls + '-' + type;
@@ -83419,7 +87838,7 @@ Ext.define('Ext.panel.Tool', {
     onClick: function(e, target) {
         var me = this,
             owner;
-            
+
         if (me.disabled) {
             return false;
         }
@@ -83437,12 +87856,12 @@ Ext.define('Ext.panel.Tool', {
         me.fireEvent('click', me, e);
         return true;
     },
-    
+
     
     onDestroy: function(){
         if (Ext.isObject(this.tooltip)) {
             Ext.tip.QuickTipManager.unregister(this.id);
-        }    
+        }
         this.callParent();
     },
 
@@ -83500,7 +87919,6 @@ Ext.define('Ext.resizer.Resizer', {
     handleCls: Ext.baseCSSPrefix + 'resizable-handle',
     pinnedCls: Ext.baseCSSPrefix + 'resizable-pinned',
     overCls:   Ext.baseCSSPrefix + 'resizable-over',
-    proxyCls:  Ext.baseCSSPrefix + 'resizable-proxy',
     wrapCls:   Ext.baseCSSPrefix + 'resizable-wrap',
 
     
@@ -83516,6 +87934,12 @@ Ext.define('Ext.resizer.Resizer', {
     width : null,
 
     
+    heightIncrement : 0,
+
+    
+    widthIncrement : 0,
+
+    
     minHeight : 20,
 
     
@@ -83650,6 +88074,8 @@ Ext.define('Ext.resizer.Resizer', {
             delegate: '.' + me.handleCls,
             dynamic: me.dynamic,
             preserveRatio: me.preserveRatio,
+            heightIncrement: me.heightIncrement,
+            widthIncrement: me.widthIncrement,
             minHeight: me.minHeight,
             maxHeight: me.maxHeight,
             minWidth: me.minWidth,
@@ -83769,11 +88195,11 @@ Ext.define('Ext.resizer.Resizer', {
         var me = this,
             handle;
         if (Ext.isIE6) {
-            handle = me.east; 
+            handle = me.east;
             if (handle) {
                 handle.setHeight(me.el.getHeight());
             }
-            handle = me.west; 
+            handle = me.west;
             if (handle) {
                 handle.setHeight(me.el.getHeight());
             }
@@ -83790,6 +88216,8 @@ Ext.define('Ext.resizer.ResizeTracker', {
 
     
     constrainTo: null,
+    
+    proxyCls:  Ext.baseCSSPrefix + 'resizable-proxy',
 
     constructor: function(config) {
         var me = this;
@@ -83842,15 +88270,41 @@ Ext.define('Ext.resizer.ResizeTracker', {
 
     
     getDynamicTarget: function() {
-        var d = this.target;
-        if (this.dynamic) {
-            return d;
-        } else if (!this.proxy) {
-            this.proxy = d.isComponent ? d.getProxy().addCls(Ext.baseCSSPrefix + 'resizable-proxy') : d.createProxy({tag: 'div', cls: Ext.baseCSSPrefix + 'resizable-proxy', id: d.id + '-rzproxy'}, Ext.getBody());
-            this.proxy.removeCls(Ext.baseCSSPrefix + 'proxy-el');
+        var me = this,
+            target = me.target;
+            
+        if (me.dynamic) {
+            return target;
+        } else if (!me.proxy) {
+            me.proxy = me.createProxy(target);
         }
-        this.proxy.show();
-        return this.proxy;
+        me.proxy.show();
+        return me.proxy;
+    },
+    
+    
+    createProxy: function(target){
+        var proxy,
+            cls = this.proxyCls,
+            renderTo;
+            
+        if (target.isComponent) {
+            proxy = target.getProxy().addCls(cls);
+        } else {
+            renderTo = Ext.getBody();
+            if (Ext.scopeResetCSS) {
+                renderTo = Ext.getBody().createChild({
+                    cls: Ext.baseCSSPrefix + 'reset'
+                });
+            }
+            proxy = target.createProxy({
+                tag: 'div',
+                cls: cls,
+                id: target.id + '-rzproxy'
+            }, renderTo);
+        }
+        proxy.removeCls(Ext.baseCSSPrefix + 'proxy-el');
+        return proxy;
     },
 
     onStart: function(e) {
@@ -83881,6 +88335,8 @@ Ext.define('Ext.resizer.ResizeTracker', {
             ratio,
             widthAdjust = 0,
             heightAdjust = 0,
+            snappedWidth,
+            snappedHeight,
             adjustX = 0,
             adjustY = 0,
             dragRatio,
@@ -83946,15 +88402,48 @@ Ext.define('Ext.resizer.ResizeTracker', {
         };
 
         
+        snappedWidth = Ext.Number.snap(newBox.width, me.widthIncrement);
+        snappedHeight = Ext.Number.snap(newBox.height, me.heightIncrement);
+        if (snappedWidth != newBox.width || snappedHeight != newBox.height){
+            switch (region) {
+                case 'northeast':
+                    newBox.y -= snappedHeight - newBox.height;
+                    break;
+                case 'north':
+                    newBox.y -= snappedHeight - newBox.height;
+                    break;
+                case 'southwest':
+                    newBox.x -= snappedWidth - newBox.width;
+                    break;
+                case 'west':
+                    newBox.x -= snappedWidth - newBox.width;
+                    break;
+                case 'northwest':
+                    newBox.x -= snappedWidth - newBox.width;
+                    newBox.y -= snappedHeight - newBox.height;
+            }
+            newBox.width = snappedWidth;
+            newBox.height = snappedHeight;
+        }
+
+        
         if (newBox.width < me.minWidth || newBox.width > me.maxWidth) {
             newBox.width = Ext.Number.constrain(newBox.width, me.minWidth, me.maxWidth);
-            newBox.x = me.lastX || newBox.x;
+
+            
+            if (adjustX) {
+                newBox.x = box.x + (box.width - newBox.width);
+            }
         } else {
             me.lastX = newBox.x;
         }
         if (newBox.height < me.minHeight || newBox.height > me.maxHeight) {
             newBox.height = Ext.Number.constrain(newBox.height, me.minHeight, me.maxHeight);
-            newBox.y = me.lastY || newBox.y;
+
+            
+            if (adjustY) {
+                newBox.y = box.y + (box.height - newBox.height);
+            }
         } else {
             me.lastY = newBox.y;
         }
@@ -84050,6 +88539,8 @@ Ext.define('Ext.resizer.SplitterTracker', {
     extend: 'Ext.dd.DragTracker',
     requires: ['Ext.util.Region'],
     enabled: true,
+    
+    overlayCls: Ext.baseCSSPrefix + 'resizable-overlay',
 
     getPrevCmp: function() {
         var splitter = this.getSplitter();
@@ -84064,17 +88555,33 @@ Ext.define('Ext.resizer.SplitterTracker', {
     
     
     onBeforeStart: function(e) {
-        var prevCmp = this.getPrevCmp(),
-            nextCmp = this.getNextCmp();
+        var me = this,
+            prevCmp = me.getPrevCmp(),
+            nextCmp = me.getNextCmp(),
+            collapseEl = me.getSplitter().collapseEl,
+            overlay;
+            
+        if (collapseEl && (e.getTarget() === me.getSplitter().collapseEl.dom)) {
+            return false;
+        }
 
         
         if (nextCmp.collapsed || prevCmp.collapsed) {
             return false;
         }
         
-        this.prevBox  = prevCmp.getEl().getBox();
-        this.nextBox  = nextCmp.getEl().getBox();
-        this.constrainTo = this.calculateConstrainRegion();
+        overlay = me.overlay =  Ext.getBody().createChild({
+            cls: me.overlayCls, 
+            html: '&#160;'
+        });
+        overlay.unselectable();
+        overlay.setSize(Ext.Element.getViewWidth(true), Ext.Element.getViewHeight(true));
+        overlay.show();
+        
+        
+        me.prevBox  = prevCmp.getEl().getBox();
+        me.nextBox  = nextCmp.getEl().getBox();
+        me.constrainTo = me.calculateConstrainRegion();
     },
 
     
@@ -84085,16 +88592,15 @@ Ext.define('Ext.resizer.SplitterTracker', {
 
     
     calculateConstrainRegion: function() {
-        var splitter   = this.getSplitter(),
-            topPad     = 0,
-            bottomPad  = 0,
+        var me         = this,
+            splitter   = me.getSplitter(),
             splitWidth = splitter.getWidth(),
             defaultMin = splitter.defaultSplitMin,
             orient     = splitter.orientation,
-            prevBox    = this.prevBox,
-            prevCmp    = this.getPrevCmp(),
-            nextBox    = this.nextBox,
-            nextCmp    = this.getNextCmp(),
+            prevBox    = me.prevBox,
+            prevCmp    = me.getPrevCmp(),
+            nextBox    = me.nextBox,
+            nextCmp    = me.getNextCmp(),
             
             
             
@@ -84144,16 +88650,17 @@ Ext.define('Ext.resizer.SplitterTracker', {
         }
 
         
-        return  prevConstrainRegion.intersect(nextConstrainRegion);
+        return prevConstrainRegion.intersect(nextConstrainRegion);
     },
 
     
     performResize: function(e) {
-        var offset   = this.getOffset('dragTarget'),
-            splitter = this.getSplitter(),
+        var me       = this,
+            offset   = me.getOffset('dragTarget'),
+            splitter = me.getSplitter(),
             orient   = splitter.orientation,
-            prevCmp  = this.getPrevCmp(),
-            nextCmp  = this.getNextCmp(),
+            prevCmp  = me.getPrevCmp(),
+            nextCmp  = me.getNextCmp(),
             owner    = splitter.ownerCt,
             layout   = owner.getLayout();
 
@@ -84164,13 +88671,13 @@ Ext.define('Ext.resizer.SplitterTracker', {
             if (prevCmp) {
                 if (!prevCmp.maintainFlex) {
                     delete prevCmp.flex;
-                    prevCmp.setSize(this.prevBox.width + offset[0], prevCmp.getHeight());
+                    prevCmp.setSize(me.prevBox.width + offset[0], prevCmp.getHeight());
                 }
             }
             if (nextCmp) {
                 if (!nextCmp.maintainFlex) {
                     delete nextCmp.flex;
-                    nextCmp.setSize(this.nextBox.width - offset[0], nextCmp.getHeight());
+                    nextCmp.setSize(me.nextBox.width - offset[0], nextCmp.getHeight());
                 }
             }
         
@@ -84178,13 +88685,13 @@ Ext.define('Ext.resizer.SplitterTracker', {
             if (prevCmp) {
                 if (!prevCmp.maintainFlex) {
                     delete prevCmp.flex;
-                    prevCmp.setSize(prevCmp.getWidth(), this.prevBox.height + offset[1]);
+                    prevCmp.setSize(prevCmp.getWidth(), me.prevBox.height + offset[1]);
                 }
             }
             if (nextCmp) {
                 if (!nextCmp.maintainFlex) {
                     delete nextCmp.flex;
-                    nextCmp.setSize(prevCmp.getWidth(), this.nextBox.height - offset[1]);
+                    nextCmp.setSize(prevCmp.getWidth(), me.nextBox.height - offset[1]);
                 }
             }
         }
@@ -84193,24 +88700,41 @@ Ext.define('Ext.resizer.SplitterTracker', {
     },
 
     
+    
+    
+    endDrag: function () {
+        var me = this;
+
+        if (me.overlay) {
+             me.overlay.remove();
+             delete me.overlay;
+        }
+
+        me.callParent(arguments); 
+    },
+
+    
     onEnd: function(e) {
-        var splitter = this.getSplitter();
+        var me = this,
+            splitter = me.getSplitter();
+            
         splitter.removeCls(splitter.baseCls + '-active');
-        this.performResize();
+        me.performResize();
     },
 
     
     
     onDrag: function(e) {
-        var offset    = this.getOffset('dragTarget'),
-            splitter  = this.getSplitter(),
+        var me        = this,
+            offset    = me.getOffset('dragTarget'),
+            splitter  = me.getSplitter(),
             splitEl   = splitter.getEl(),
             orient    = splitter.orientation;
 
         if (orient === "vertical") {
-            splitEl.setX(this.startRegion.left + offset[0]);
+            splitEl.setX(me.startRegion.left + offset[0]);
         } else {
-            splitEl.setY(this.startRegion.top + offset[1]);
+            splitEl.setY(me.startRegion.top + offset[1]);
         }
     },
 
@@ -84223,10 +88747,10 @@ Ext.define('Ext.selection.CellModel', {
     extend: 'Ext.selection.Model',
     alias: 'selection.cellmodel',
     requires: ['Ext.util.KeyNav'],
-    
+
     
     enableKeyNav: true,
-    
+
     
     preventWrap: false,
 
@@ -84234,11 +88758,11 @@ Ext.define('Ext.selection.CellModel', {
         this.addEvents(
             
             'deselect',
-            
+
             
             'select'
         );
-        this.callParent(arguments);    
+        this.callParent(arguments);
     },
 
     bindComponent: function(view) {
@@ -84261,7 +88785,7 @@ Ext.define('Ext.selection.CellModel', {
 
     initKeyNav: function(view) {
         var me = this;
-        
+
         if (!view.rendered) {
             view.on('render', Ext.Function.bind(me.initKeyNav, me, [view], 0), me, {single: true});
             return;
@@ -84282,7 +88806,7 @@ Ext.define('Ext.selection.CellModel', {
             scope: me
         });
     },
-    
+
     getHeaderCt: function() {
         return this.primaryView.headerCt;
     },
@@ -84298,11 +88822,11 @@ Ext.define('Ext.selection.CellModel', {
     onKeyLeft: function(e, t) {
         this.move('left', e);
     },
-    
+
     onKeyRight: function(e, t) {
         this.move('right', e);
     },
-    
+
     move: function(dir, e) {
         var me = this,
             pos = me.primaryView.walkCells(me.getCurrentPosition(), dir, e, me.preventWrap);
@@ -84316,11 +88840,11 @@ Ext.define('Ext.selection.CellModel', {
     getCurrentPosition: function() {
         return this.position;
     },
-    
+
     
     setCurrentPosition: function(pos) {
         var me = this;
-        
+
         if (me.position) {
             me.onCellDeselect(me.position);
         }
@@ -84411,27 +88935,36 @@ Ext.define('Ext.selection.RowModel', {
     extend: 'Ext.selection.Model',
     alias: 'selection.rowmodel',
     requires: ['Ext.util.KeyNav'],
-    
+
     
     deltaScroll: 5,
-    
+
     
     enableKeyNav: true,
     
+    
+    ignoreRightMouseSelection: true,
+
     constructor: function(){
         this.addEvents(
             
-            'deselect',
+            'beforedeselect',
+
+            
+            'beforeselect',
+
             
+            'deselect',
+
             
             'select'
         );
-        this.callParent(arguments);    
+        this.callParent(arguments);
     },
 
     bindComponent: function(view) {
         var me = this;
-        
+
         me.views = me.views || [];
         me.views.push(view);
         me.bind(view.getStore(), true);
@@ -84448,7 +88981,7 @@ Ext.define('Ext.selection.RowModel', {
 
     initKeyNav: function(view) {
         var me = this;
-        
+
         if (!view.rendered) {
             view.on('render', Ext.Function.bind(me.initKeyNav, me, [view], 0), me, {single: true});
             return;
@@ -84496,7 +89029,7 @@ Ext.define('Ext.selection.RowModel', {
     onKeyEnd: function(e, t) {
         var me = this,
             last = me.store.getAt(me.store.getCount() - 1);
-            
+
         if (last) {
             if (e.shiftKey) {
                 me.selectRange(last, me.lastFocused || 0);
@@ -84513,7 +89046,7 @@ Ext.define('Ext.selection.RowModel', {
     onKeyHome: function(e, t) {
         var me = this,
             first = me.store.getAt(0);
-            
+
         if (first) {
             if (e.shiftKey) {
                 me.selectRange(first, me.lastFocused || 0);
@@ -84534,7 +89067,7 @@ Ext.define('Ext.selection.RowModel', {
             prevIdx,
             prevRecord,
             currRec;
-            
+
         if (rowsVisible) {
             selIdx = me.lastFocused ? me.store.indexOf(me.lastFocused) : 0;
             prevIdx = selIdx - rowsVisible;
@@ -84564,7 +89097,7 @@ Ext.define('Ext.selection.RowModel', {
             nextIdx,
             nextRecord,
             currRec;
-            
+
         if (rowsVisible) {
             selIdx = me.lastFocused ? me.store.indexOf(me.lastFocused) : 0;
             nextIdx = selIdx + rowsVisible;
@@ -84594,7 +89127,7 @@ Ext.define('Ext.selection.RowModel', {
             e.stopEvent();
             var me = this,
                 record = me.lastFocused;
-                
+
             if (record) {
                 if (me.isSelected(record)) {
                     me.doDeselect(record, false);
@@ -84613,7 +89146,7 @@ Ext.define('Ext.selection.RowModel', {
             view = me.views[0],
             idx  = me.store.indexOf(me.lastFocused),
             record;
-            
+
         if (idx > 0) {
             
             
@@ -84652,7 +89185,7 @@ Ext.define('Ext.selection.RowModel', {
             view = me.views[0],
             idx  = me.store.indexOf(me.lastFocused),
             record;
-            
+
         
         
         if (idx + 1 < me.store.getCount()) {
@@ -84678,21 +89211,21 @@ Ext.define('Ext.selection.RowModel', {
             }
         }
     },
-    
+
     scrollByDeltaX: function(delta) {
         var view    = this.views[0],
             section = view.up(),
             hScroll = section.horizontalScroller;
-            
+
         if (hScroll) {
             hScroll.scrollByDeltaX(delta);
         }
     },
-    
+
     onKeyLeft: function(e, t) {
         this.scrollByDeltaX(-this.deltaScroll);
     },
-    
+
     onKeyRight: function(e, t) {
         this.scrollByDeltaX(this.deltaScroll);
     },
@@ -84701,31 +89234,46 @@ Ext.define('Ext.selection.RowModel', {
     
     onRowMouseDown: function(view, record, item, index, e) {
         view.el.focus();
+        if (!this.allowRightMouseSelection(e)) {
+            return;
+        }
         this.selectWithEvent(record, e);
     },
+    
+    
+    allowRightMouseSelection: function(e) {
+        var disallow = this.ignoreRightMouseSelection && e.button !== 0;
+        if (disallow) {
+            disallow = this.hasSelection();
+        }
+        return !disallow;
+    },
 
     
     
-    onSelectChange: function(record, isSelected, suppressEvent) {
+    onSelectChange: function(record, isSelected, suppressEvent, commitFn) {
         var me      = this,
             views   = me.views,
             viewsLn = views.length,
             store   = me.store,
             rowIdx  = store.indexOf(record),
+            eventName = isSelected ? 'select' : 'deselect',
             i = 0;
-            
-        for (; i < viewsLn; i++) {
-            if (isSelected) {
-                views[i].onRowSelect(rowIdx, suppressEvent);
-                if (!suppressEvent) {
-                    me.fireEvent('select', me, record, rowIdx);
-                }
-            } else {
-                views[i].onRowDeselect(rowIdx, suppressEvent);
-                if (!suppressEvent) {
-                    me.fireEvent('deselect', me, record, rowIdx);
+
+        if ((suppressEvent || me.fireEvent('before' + eventName, me, record, rowIdx)) !== false &&
+                commitFn() !== false) {
+
+            for (; i < viewsLn; i++) {
+                if (isSelected) {
+                    views[i].onRowSelect(rowIdx, suppressEvent);
+                } else {
+                    views[i].onRowDeselect(rowIdx, suppressEvent);
                 }
             }
+
+            if (!suppressEvent) {
+                me.fireEvent(eventName, me, record, rowIdx);
+            }
         }
     },
 
@@ -84737,7 +89285,7 @@ Ext.define('Ext.selection.RowModel', {
             store   = this.store,
             rowIdx,
             i = 0;
-            
+
         if (oldFocused) {
             rowIdx = store.indexOf(oldFocused);
             if (rowIdx != -1) {
@@ -84756,7 +89304,7 @@ Ext.define('Ext.selection.RowModel', {
             }
         }
     },
-    
+
     onEditorTab: function(editingPlugin, e) {
         var me = this,
             view = me.views[0],
@@ -84765,12 +89313,12 @@ Ext.define('Ext.selection.RowModel', {
             position = view.getPosition(record, header),
             direction = e.shiftKey ? 'left' : 'right',
             newPosition  = view.walkCells(position, direction, e, this.preventWrap);
-            
+
         if (newPosition) {
             editingPlugin.startEditByPosition(newPosition);
         }
     },
-    
+
     selectByPosition: function(position) {
         var record = this.store.getAt(position.row);
         this.select(record);
@@ -84778,6 +89326,7 @@ Ext.define('Ext.selection.RowModel', {
 });
 
 Ext.define('Ext.selection.CheckboxModel', {
+    alias: 'selection.checkboxmodel',
     extend: 'Ext.selection.RowModel',
 
     
@@ -84789,25 +89338,54 @@ Ext.define('Ext.selection.CheckboxModel', {
     
     checkOnly: false,
 
+    headerWidth: 24,
+
     
     checkerOnCls: Ext.baseCSSPrefix + 'grid-hd-checker-on',
 
-    bindComponent: function() {
-        this.sortable = false;
-        this.callParent(arguments);
+    bindComponent: function(view) {
+        var me = this;
 
-        var view     = this.views[0],
+        me.sortable = false;
+        me.callParent(arguments);
+        if (!me.hasLockedHeader() || view.headerCt.lockedCt) {
+            
+            view.headerCt.on('headerclick', me.onHeaderClick, me);
+            me.addCheckbox(true);
+            me.mon(view.ownerCt, 'reconfigure', me.addCheckbox, me);
+        }
+    },
+
+    hasLockedHeader: function(){
+        var hasLocked = false;
+        Ext.each(this.views, function(view){
+            if (view.headerCt.lockedCt) {
+                hasLocked = true;
+                return false;
+            }
+        });
+        return hasLocked;
+    },
+
+    
+    addCheckbox: function(initial){
+        var me = this,
+            checkbox = me.injectCheckbox,
+            view = me.views[0],
             headerCt = view.headerCt;
 
-        if (this.injectCheckbox !== false) {
-            if (this.injectCheckbox == 'first') {
-                this.injectCheckbox = 0;
-            } else if (this.injectCheckbox == 'last') {
-                this.injectCheckbox = headerCt.getColumnCount();
+        if (checkbox !== false) {
+            if (checkbox == 'first') {
+                checkbox = 0;
+            } else if (checkbox == 'last') {
+                checkbox = headerCt.getColumnCount();
             }
-            headerCt.add(this.injectCheckbox,  this.getHeaderConfig());
+            headerCt.add(checkbox,  me.getHeaderConfig());
+        }
+
+        if (initial !== true) {
+            view.refresh();
         }
-        headerCt.on('headerclick', this.onHeaderClick, this);
     },
 
     
@@ -84842,17 +89420,21 @@ Ext.define('Ext.selection.CheckboxModel', {
 
     
     getHeaderConfig: function() {
+        var me = this;
+
         return {
             isCheckerHd: true,
             text : '&#160;',
-            width: 24,
+            width: me.headerWidth,
             sortable: false,
-            fixed: true,
+            draggable: false,
+            resizable: false,
             hideable: false,
             menuDisabled: true,
             dataIndex: '',
             cls: Ext.baseCSSPrefix + 'column-header-checkbox ',
-            renderer: Ext.Function.bind(this.renderer, this)
+            renderer: Ext.Function.bind(me.renderer, me),
+            locked: me.hasLockedHeader()
         };
     },
 
@@ -84867,6 +89449,10 @@ Ext.define('Ext.selection.CheckboxModel', {
         view.el.focus();
         var me = this,
             checker = e.getTarget('.' + Ext.baseCSSPrefix + 'grid-row-checker');
+            
+        if (!me.allowRightMouseSelection(e)) {
+            return;
+        }
 
         
         if (me.checkOnly && !checker) {
@@ -84888,8 +89474,9 @@ Ext.define('Ext.selection.CheckboxModel', {
     },
 
     
-    onSelectChange: function(record, isSelected) {
-        this.callParent([record, isSelected]);
+    onSelectChange: function() {
+        this.callParent(arguments);
+
         
         var hdSelectStatus = this.selected.getCount() === this.store.getCount();
         this.toggleUiHeader(hdSelectStatus);
@@ -84953,16 +89540,15 @@ Ext.define('Ext.selection.TreeModel', {
     },
     
     onKeyPress: function(e, t) {
-        var selected, checked;
+        var key = e.getKey(),
+            selected, 
+            checked;
         
-        if (e.getKey() === e.SPACE || e.getKey() === e.ENTER) {
+        if (key === e.SPACE || key === e.ENTER) {
             e.stopEvent();
             selected = this.getLastSelected();
-            if (selected && selected.isLeaf()) {
-                checked = selected.get('checked');
-                if (Ext.isBoolean(checked)) {
-                    selected.set('checked', !checked);
-                }
+            if (selected) {
+                this.view.onCheckChange(selected);
             }
         } else {
             this.callParent(arguments);
@@ -84975,10 +89561,13 @@ Ext.define('Ext.slider.Thumb', {
     requires: ['Ext.dd.DragTracker', 'Ext.util.Format'],
     
     topZIndex: 10000,
+
+    
+
     
     constructor: function(config) {
         var me = this;
-        
+
         
         Ext.apply(me, config || {}, {
             cls: Ext.baseCSSPrefix + 'slider-thumb',
@@ -84996,14 +89585,14 @@ Ext.define('Ext.slider.Thumb', {
     
     render: function() {
         var me = this;
-        
+
         me.el = me.slider.innerEl.insertFirst({cls: me.cls});
         if (me.disabled) {
             me.disable();
         }
         me.initEvents();
     },
-    
+
     
     move: function(v, animate){
         if(!animate){
@@ -85023,16 +89612,16 @@ Ext.define('Ext.slider.Thumb', {
     bringToFront: function() {
         this.el.setStyle('zIndex', this.topZIndex);
     },
-    
+
     
     sendToBack: function() {
         this.el.setStyle('zIndex', '');
     },
-    
+
     
     enable: function() {
         var me = this;
-        
+
         me.disabled = false;
         if (me.el) {
             me.el.removeCls(me.slider.disabledCls);
@@ -85042,7 +89631,7 @@ Ext.define('Ext.slider.Thumb', {
     
     disable: function() {
         var me = this;
-        
+
         me.disabled = true;
         if (me.el) {
             me.el.addCls(me.slider.disabledCls);
@@ -85080,7 +89669,7 @@ Ext.define('Ext.slider.Thumb', {
     
     onDragStart: function(e){
         var me = this;
-        
+
         me.el.addCls(Ext.baseCSSPrefix + 'slider-thumb-drag');
         me.dragging = true;
         me.dragStartValue = me.value;
@@ -85104,7 +89693,7 @@ Ext.define('Ext.slider.Thumb', {
             if (below !== undefined && newValue <= below.value) {
                 newValue = below.value;
             }
-            
+
             if (above !== undefined && newValue >= above.value) {
                 newValue = above.value;
             }
@@ -85174,12 +89763,12 @@ Ext.define('Ext.slider.Tip', {
     minWidth: 10,
     alias: 'widget.slidertip',
     offsets : [0, -10],
-    
+
     isSliderTip: true,
 
     init: function(slider) {
         var me = this;
-        
+
         slider.on({
             scope    : me,
             dragstart: me.onSlide,
@@ -85217,11 +89806,12 @@ Ext.define('Ext.slider.Multi', {
         'Ext.layout.component.field.Slider'
     ],
 
+    
     fieldSubTpl: [
-        '<div class="' + Ext.baseCSSPrefix + 'slider {fieldCls} {vertical}" aria-valuemin="{minValue}" aria-valuemax="{maxValue}" aria-valuenow="{value}" aria-valuetext="{value}">',
-            '<div class="' + Ext.baseCSSPrefix + 'slider-end" role="presentation">',
-                '<div class="' + Ext.baseCSSPrefix + 'slider-inner" role="presentation">',
-                    '<a class="' + Ext.baseCSSPrefix + 'slider-focus" href="#" tabIndex="-1" hidefocus="on" role="presentation"></a>',
+        '<div id="{id}" class="' + Ext.baseCSSPrefix + 'slider {fieldCls} {vertical}" aria-valuemin="{minValue}" aria-valuemax="{maxValue}" aria-valuenow="{value}" aria-valuetext="{value}">',
+            '<div id="{cmpId}-endEl" class="' + Ext.baseCSSPrefix + 'slider-end" role="presentation">',
+                '<div id="{cmpId}-innerEl" class="' + Ext.baseCSSPrefix + 'slider-inner" role="presentation">',
+                    '<a id="{cmpId}-focusEl" class="' + Ext.baseCSSPrefix + 'slider-focus" href="#" tabIndex="-1" hidefocus="on" role="presentation"></a>',
                 '</div>',
             '</div>',
         '</div>',
@@ -85237,14 +89827,19 @@ Ext.define('Ext.slider.Multi', {
 
     
     vertical: false,
+
     
     minValue: 0,
+
     
     maxValue: 100,
+
     
     decimalPrecision: 0,
+
     
     keyIncrement: 1,
+
     
     increment: 0,
 
@@ -85253,6 +89848,7 @@ Ext.define('Ext.slider.Multi', {
 
     
     clickToChange : true,
+
     
     animate: true,
 
@@ -85295,7 +89891,7 @@ Ext.define('Ext.slider.Multi', {
         var me = this,
             tipPlug,
             hasTip;
-        
+
         
         me.thumbs = [];
 
@@ -85367,7 +89963,7 @@ Ext.define('Ext.slider.Multi', {
         var thumbs = this.thumbs,
             ln = thumbs.length,
             zIndex, thumb, i;
-            
+
         for (i = 0; i < ln; i++) {
             thumb = thumbs[i];
 
@@ -85394,11 +89990,7 @@ Ext.define('Ext.slider.Multi', {
             value: me.value
         });
 
-        Ext.applyIf(me.renderSelectors, {
-            endEl: '.' + Ext.baseCSSPrefix + 'slider-end',
-            innerEl: '.' + Ext.baseCSSPrefix + 'slider-inner',
-            focusEl: '.' + Ext.baseCSSPrefix + 'slider-focus'
-        });
+        me.addChildEls('endEl', 'innerEl', 'focusEl');
 
         me.callParent(arguments);
 
@@ -85421,7 +90013,7 @@ Ext.define('Ext.slider.Multi', {
     
     initEvents : function() {
         var me = this;
-        
+
         me.mon(me.el, {
             scope    : me,
             mousedown: me.onMouseDown,
@@ -85440,7 +90032,7 @@ Ext.define('Ext.slider.Multi', {
             thumbs = me.thumbs,
             len = thumbs.length,
             local;
-            
+
         if (me.disabled) {
             return;
         }
@@ -85461,7 +90053,7 @@ Ext.define('Ext.slider.Multi', {
     onClickChange : function(local) {
         var me = this,
             thumb, index;
-            
+
         if (local.top > me.clickRange[0] && local.top < me.clickRange[1]) {
             
             thumb = me.getNearest(local, 'left');
@@ -85507,13 +90099,13 @@ Ext.define('Ext.slider.Multi', {
         var me = this,
             k,
             val;
-        
+
         if(me.disabled || me.thumbs.length !== 1) {
             e.preventDefault();
             return;
         }
         k = e.getKey();
-        
+
         switch(k) {
             case e.UP:
             case e.RIGHT:
@@ -85533,27 +90125,6 @@ Ext.define('Ext.slider.Multi', {
     },
 
     
-    doSnap : function(value) {
-        var newValue = value,
-            inc = this.increment,
-            m;
-            
-        if (!(inc && value)) {
-            return value;
-        }
-        m = value % inc;
-        if (m !== 0) {
-            newValue -= m;
-            if (m * 2 >= inc) {
-                newValue += inc;
-            } else if (m * 2 < -inc) {
-                newValue -= inc;
-            }
-        }
-        return Ext.Number.constrain(newValue, this.minValue,  this.maxValue);
-    },
-
-    
     afterRender : function() {
         var me = this,
             i = 0,
@@ -85561,7 +90132,7 @@ Ext.define('Ext.slider.Multi', {
             len = thumbs.length,
             thumb,
             v;
-            
+
         me.callParent(arguments);
 
         for (; i < len; i++) {
@@ -85589,8 +90160,8 @@ Ext.define('Ext.slider.Multi', {
     
     normalizeValue : function(v) {
         var me = this;
-        
-        v = me.doSnap(v);
+
+        v = Ext.Number.snap(v, this.increment, this.minValue, this.maxValue);
         v = Ext.util.Format.round(v, me.decimalPrecision);
         v = Ext.Number.constrain(v, me.minValue, me.maxValue);
         return v;
@@ -85603,9 +90174,11 @@ Ext.define('Ext.slider.Multi', {
             thumbs = me.thumbs,
             len = thumbs.length,
             t;
-            
+
         me.minValue = val;
-        me.inputEl.dom.setAttribute('aria-valuemin', val);
+        if (me.rendered) {
+            me.inputEl.dom.setAttribute('aria-valuemin', val);
+        }
 
         for (; i < len; ++i) {
             t = thumbs[i];
@@ -85621,9 +90194,11 @@ Ext.define('Ext.slider.Multi', {
             thumbs = me.thumbs,
             len = thumbs.length,
             t;
-            
+
         me.maxValue = val;
-        me.inputEl.dom.setAttribute('aria-valuemax', val);
+        if (me.rendered) {
+            me.inputEl.dom.setAttribute('aria-valuemax', val);
+        }
 
         for (; i < len; ++i) {
             t = thumbs[i];
@@ -85686,7 +90261,7 @@ Ext.define('Ext.slider.Multi', {
             thumb,
             el,
             xy;
-            
+
         me.callParent();
 
         for (; i < len; i++) {
@@ -85720,7 +90295,7 @@ Ext.define('Ext.slider.Multi', {
             len = thumbs.length,
             thumb,
             el;
-            
+
         this.callParent();
 
         for (; i < len; i++) {
@@ -85793,8 +90368,8 @@ Ext.define('Ext.slider.Multi', {
     
     beforeDestroy : function() {
         var me = this;
-        
-        Ext.destroyMembers(me.innerEl, me.endEl, me.focusEl);
+
+        Ext.destroy(me.innerEl, me.endEl, me.focusEl);
         Ext.each(me.thumbs, function(thumb) {
             Ext.destroy(thumb);
         }, me);
@@ -85867,7 +90442,7 @@ Ext.define('Ext.slider.Single', {
 Ext.define('Ext.tab.Tab', {
     extend: 'Ext.button.Button',
     alias: 'widget.tab',
-    
+
     requires: [
         'Ext.layout.component.Tab',
         'Ext.util.KeyNav'
@@ -85881,7 +90456,7 @@ Ext.define('Ext.tab.Tab', {
 
     
     activeCls: 'active',
-    
+
     
 
     
@@ -85901,7 +90476,7 @@ Ext.define('Ext.tab.Tab', {
     scale: false,
 
     position: 'top',
-    
+
     initComponent: function() {
         var me = this;
 
@@ -85918,7 +90493,7 @@ Ext.define('Ext.tab.Tab', {
             
             'close'
         );
-        
+
         me.callParent(arguments);
 
         if (me.card) {
@@ -85928,36 +90503,55 @@ Ext.define('Ext.tab.Tab', {
 
     
     onRender: function() {
-        var me = this;
-        
+        var me = this,
+            tabBar = me.up('tabbar'),
+            tabPanel = me.up('tabpanel');
+
         me.addClsWithUI(me.position);
-        
+
         
         
 
         me.syncClosableUI();
 
-        me.callParent(arguments);
         
+        if (!me.minWidth) {
+            me.minWidth = (tabBar) ? tabBar.minTabWidth : me.minWidth;
+            if (!me.minWidth && tabPanel) {
+                me.minWidth = tabPanel.minTabWidth;
+            }
+            if (me.minWidth && me.iconCls) {
+                me.minWidth += 25;
+            }
+        }
+        if (!me.maxWidth) {
+            me.maxWidth = (tabBar) ? tabBar.maxTabWidth : me.maxWidth;
+            if (!me.maxWidth && tabPanel) {
+                me.maxWidth = tabPanel.maxTabWidth;
+            }
+        }
+
+        me.callParent(arguments);
+
         if (me.active) {
             me.activate(true);
         }
 
         me.syncClosableElements();
-        
+
         me.keyNav = Ext.create('Ext.util.KeyNav', me.el, {
             enter: me.onEnterKey,
             del: me.onDeleteKey,
             scope: me
         });
     },
-    
+
     
     enable : function(silent) {
         var me = this;
 
         me.callParent(arguments);
-        
+
         me.removeClsWithUI(me.position + '-disabled');
 
         return me;
@@ -85966,14 +90560,14 @@ Ext.define('Ext.tab.Tab', {
     
     disable : function(silent) {
         var me = this;
-        
+
         me.callParent(arguments);
-        
+
         me.addClsWithUI(me.position + '-disabled');
 
         return me;
     },
-    
+
     
     onDestroy: function() {
         var me = this;
@@ -86028,7 +90622,7 @@ Ext.define('Ext.tab.Tab', {
                     tag: 'a',
                     cls: me.baseCls + '-close-btn',
                     href: '#',
-                    html: me.closeText,
+                    
                     title: me.closeText
                 }).on('click', Ext.EventManager.preventDefault);  
             }
@@ -86068,35 +90662,44 @@ Ext.define('Ext.tab.Tab', {
 
         if (me.fireEvent('beforeclose', me) !== false) {
             if (me.tabBar) {
-                me.tabBar.closeTab(me);
+                if (me.tabBar.closeTab(me) === false) {
+                    
+                    return;
+                }
+            } else {
+                
+                me.fireEvent('close', me);
             }
-
-            me.fireEvent('close', me);
         }
     },
+
     
+    fireClose: function(){
+        this.fireEvent('close', this);
+    },
+
     
     onEnterKey: function(e) {
         var me = this;
-        
+
         if (me.tabBar) {
             me.tabBar.onClick(e, me.el);
         }
     },
-    
+
    
     onDeleteKey: function(e) {
         var me = this;
-        
+
         if (me.closable) {
             me.onCloseClick();
         }
     },
-    
+
     
     activate : function(supressEvent) {
         var me = this;
-        
+
         me.active = true;
         me.addClsWithUI([me.activeCls, me.position + '-' + me.activeCls]);
 
@@ -86108,10 +90711,10 @@ Ext.define('Ext.tab.Tab', {
     
     deactivate : function(supressEvent) {
         var me = this;
-        
+
         me.active = false;
         me.removeClsWithUI([me.activeCls, me.position + '-' + me.activeCls]);
-        
+
         if (supressEvent !== true) {
             me.fireEvent('deactivate', me);
         }
@@ -86129,6 +90732,12 @@ Ext.define('Ext.tab.Bar', {
         'Ext.FocusManager'
     ],
 
+    isTabBar: true,
+    
+    
+    
+    
+
     
     defaultType: 'tab',
 
@@ -86137,15 +90746,13 @@ Ext.define('Ext.tab.Bar', {
 
     
     renderTpl: [
-        '<div class="{baseCls}-body<tpl if="ui"> {baseCls}-body-{ui}<tpl for="uiCls"> {parent.baseCls}-body-{parent.ui}-{.}</tpl></tpl>"<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>></div>',
-        '<div class="{baseCls}-strip<tpl if="ui"> {baseCls}-strip-{ui}<tpl for="uiCls"> {parent.baseCls}-strip-{parent.ui}-{.}</tpl></tpl>"></div>'
+        '<div id="{id}-body" class="{baseCls}-body <tpl if="bodyCls"> {bodyCls}</tpl> <tpl if="ui"> {baseCls}-body-{ui}<tpl for="uiCls"> {parent.baseCls}-body-{parent.ui}-{.}</tpl></tpl>"<tpl if="bodyStyle"> style="{bodyStyle}"</tpl>></div>',
+        '<div id="{id}-strip" class="{baseCls}-strip<tpl if="ui"> {baseCls}-strip-{ui}<tpl for="uiCls"> {parent.baseCls}-strip-{parent.ui}-{.}</tpl></tpl>"></div>'
     ],
 
     
-    minTabWidth: 30,
 
     
-    maxTabWidth: undefined,
 
     
     initComponent: function() {
@@ -86155,7 +90762,7 @@ Ext.define('Ext.tab.Bar', {
         if (me.plain) {
             me.setUI(me.ui + '-plain');
         }
-        
+
         me.addClsWithUI(me.dock);
 
         me.addEvents(
@@ -86163,40 +90770,43 @@ Ext.define('Ext.tab.Bar', {
             'change'
         );
 
-        Ext.applyIf(this.renderSelectors, {
-            body : '.' + this.baseCls + '-body',
-            strip: '.' + this.baseCls + '-strip'
-        });
+        me.addChildEls('body', 'strip');
         me.callParent(arguments);
 
         
         me.layout.align = (me.orientation == 'vertical') ? 'left' : 'top';
         me.layout.overflowHandler = Ext.create('Ext.layout.container.boxOverflow.Scroller', me.layout);
-        me.items.removeAt(me.items.getCount() - 1);
-        me.items.removeAt(me.items.getCount() - 1);
-        
+
+        me.remove(me.titleCmp);
+        delete me.titleCmp;
+
         
         keys = me.orientation == 'vertical' ? ['up', 'down'] : ['left', 'right'];
         Ext.FocusManager.subscribe(me, {
             keys: keys
         });
+
+        Ext.apply(me.renderData, {
+            bodyCls: me.bodyCls
+        });
     },
 
     
     onAdd: function(tab) {
-        var me = this,
-            tabPanel = me.tabPanel,
-            hasOwner = !!tabPanel;
-
-        me.callParent(arguments);
-        tab.position = me.dock;
-        if (hasOwner) {
-            tab.minWidth = tabPanel.minTabWidth;
+        tab.position = this.dock;
+        this.callParent(arguments);
+    },
+    
+    onRemove: function(tab) {
+        var me = this;
+        
+        if (tab === me.previousTab) {
+            me.previousTab = null;
         }
-        else {
-            tab.minWidth = me.minTabWidth + (tab.iconCls ? 25 : 0);
+        if (me.items.getCount() === 0) {
+            me.activeTab = null;
         }
-        tab.maxWidth = me.maxTabWidth || (hasOwner ? tabPanel.maxTabWidth : undefined);
+        me.callParent(arguments);    
     },
 
     
@@ -86209,12 +90819,12 @@ Ext.define('Ext.tab.Bar', {
             delegate: '.' + Ext.baseCSSPrefix + 'tab'
         });
         me.callParent(arguments);
-        
+
     },
 
     afterComponentLayout : function() {
         var me = this;
-        
+
         me.callParent(arguments);
         me.strip.setWidth(me.el.getWidth());
     },
@@ -86231,9 +90841,11 @@ Ext.define('Ext.tab.Bar', {
             if (tab.closable && target === tab.closeEl.dom) {
                 tab.onCloseClick();
             } else {
-                this.setActiveTab(tab);
                 if (tabPanel) {
+                    
                     tabPanel.setActiveTab(tab.card);
+                } else {
+                    this.setActiveTab(tab);
                 }
                 tab.focus();
             }
@@ -86242,23 +90854,31 @@ Ext.define('Ext.tab.Bar', {
 
     
     closeTab: function(tab) {
-        var card    = tab.card,
-            tabPanel = this.tabPanel,
+        var me = this,
+            card = tab.card,
+            tabPanel = me.tabPanel,
             nextTab;
 
-        if (tab.active && this.items.getCount() > 1) {
-            nextTab = tab.next('tab') || this.items.items[0];
-            this.setActiveTab(nextTab);
+        if (card && card.fireEvent('beforeclose', card) === false) {
+            return false;
+        }
+
+        if (tab.active && me.items.getCount() > 1) {
+            nextTab = me.previousTab || tab.next('tab') || me.items.first();
+            me.setActiveTab(nextTab);
             if (tabPanel) {
                 tabPanel.setActiveTab(nextTab.card);
             }
         }
-        this.remove(tab);
+        
+        tab.fireClose();
+        me.remove(tab);
 
         if (tabPanel && card) {
+            card.fireEvent('close', card);
             tabPanel.remove(card);
         }
-        
+
         if (nextTab) {
             nextTab.focus();
         }
@@ -86271,19 +90891,21 @@ Ext.define('Ext.tab.Bar', {
         }
         var me = this;
         if (me.activeTab) {
+            me.previousTab = me.activeTab;
             me.activeTab.deactivate();
         }
         tab.activate();
-        
+
         if (me.rendered) {
             me.layout.layout();
-            tab.el.scrollIntoView(me.layout.getRenderTarget());
+            tab.el && tab.el.scrollIntoView(me.layout.getRenderTarget());
         }
         me.activeTab = tab;
         me.fireEvent('change', me, tab, tab.card);
     }
 });
 
+
 Ext.define('Ext.tab.Panel', {
     extend: 'Ext.panel.Panel',
     alias: 'widget.tabpanel',
@@ -86293,7 +90915,11 @@ Ext.define('Ext.tab.Panel', {
 
     
     tabPosition : 'top',
+
     
+
+    
+
     
 
     
@@ -86308,6 +90934,10 @@ Ext.define('Ext.tab.Panel', {
     itemCls: 'x-tabpanel-child',
 
     
+    minTabWidth: undefined,
+
+    
+    maxTabWidth: undefined,
 
     
     deferredRender : true,
@@ -86359,7 +90989,7 @@ Ext.define('Ext.tab.Panel', {
     afterInitialLayout: function() {
         var me = this,
             card = me.getComponent(me.activeTab);
-            
+
         if (card) {
             me.layout.setActiveItem(card);
         }
@@ -86373,17 +91003,17 @@ Ext.define('Ext.tab.Panel', {
         card = me.getComponent(card);
         if (card) {
             previous = me.getActiveTab();
-            
+
             if (previous && previous !== card && me.fireEvent('beforetabchange', me, card, previous) === false) {
                 return false;
             }
-            
+
             me.tabBar.setActiveTab(card.tab);
             me.activeTab = card;
             if (me.rendered) {
                 me.layout.setActiveItem(card);
             }
-            
+
             if (previous && previous !== card) {
                 me.fireEvent('tabchange', me, card, previous);
             }
@@ -86402,17 +91032,23 @@ Ext.define('Ext.tab.Panel', {
 
     
     onAdd: function(item, index) {
-        var me = this;
+        var me = this,
+            cfg = item.tabConfig || {},
+            defaultConfig = {
+                xtype: 'tab',
+                card: item,
+                disabled: item.disabled,
+                closable: item.closable,
+                hidden: item.hidden,
+                tabBar: me.tabBar
+            };
+
+        if (item.closeText) {
+            defaultConfig.closeText = item.closeText;
+        }
+        cfg = Ext.applyIf(cfg, defaultConfig);
+        item.tab = me.tabBar.insert(index, cfg);
 
-        item.tab = me.tabBar.insert(index, {
-            xtype: 'tab',
-            card: item,
-            disabled: item.disabled,
-            closable: item.closable,
-            hidden: item.hidden,
-            tabBar: me.tabBar
-        });
-        
         item.on({
             scope : me,
             enable: me.onItemEnable,
@@ -86439,31 +91075,31 @@ Ext.define('Ext.tab.Panel', {
             me.setActiveTab(0);
         }
     },
-    
+
     
     onItemEnable: function(item){
         item.tab.enable();
     },
 
-        
+    
     onItemDisable: function(item){
         item.tab.disable();
     },
-    
+
     
     onItemBeforeShow: function(item) {
         if (item !== this.activeTab) {
             this.setActiveTab(item);
             return false;
-        }    
+        }
     },
-    
+
     
     onItemIconChange: function(item, newIconCls) {
         item.tab.setIconCls(newIconCls);
         this.getTabBar().doLayout();
     },
-    
+
     
     onItemTitleChange: function(item, newTitle) {
         item.tab.setText(newTitle);
@@ -86476,12 +91112,14 @@ Ext.define('Ext.tab.Panel', {
         var me = this,
             items = me.items,
             
+            
+            
             hasItemsLeft = items.getCount() > 1;
 
         if (me.destroying || !hasItemsLeft) {
             me.activeTab = null;
         } else if (item === me.activeTab) {
-             me.setActiveTab(item.next() || items.getAt(0)); 
+             me.setActiveTab(item.next() || items.getAt(0));
         }
         me.callParent(arguments);
 
@@ -86493,7 +91131,7 @@ Ext.define('Ext.tab.Panel', {
     
     onRemove: function(item, autoDestroy) {
         var me = this;
-        
+
         item.un({
             scope : me,
             enable: me.onItemEnable,
@@ -86534,7 +91172,8 @@ Ext.define('Ext.tree.Column', {
                 checkboxText= '<input type="button" role="checkbox" class="{0}" {1} />',
                 formattedValue = origRenderer.apply(origScope, arguments),
                 href = record.get('href'),
-                target = record.get('hrefTarget');
+                target = record.get('hrefTarget'),
+                cls = record.get('cls');
 
             while (record) {
                 if (!record.isRoot() || (record.isRoot() && view.rootVisible)) {
@@ -86552,21 +91191,21 @@ Ext.define('Ext.tree.Column', {
                                 record.get('checked') ? 'aria-checked="true"' : ''
                             ));
                             if (record.get('checked')) {
-                                metaData.tdCls += (' ' + Ext.baseCSSPrefix + 'tree-checked');
+                                metaData.tdCls += (' ' + treePrefix + 'checked');
                             }
                         }
                         if (record.isLast()) {
-                            if (record.isLeaf() || (record.isLoaded() && !record.hasChildNodes())) {
-                                buf.unshift(format(imgText, (elbowPrefix + 'end'), Ext.BLANK_IMAGE_URL));
-                            } else {
+                            if (record.isExpandable()) {
                                 buf.unshift(format(imgText, (elbowPrefix + 'end-plus ' + expanderCls), Ext.BLANK_IMAGE_URL));
+                            } else {
+                                buf.unshift(format(imgText, (elbowPrefix + 'end'), Ext.BLANK_IMAGE_URL));
                             }
                             
                         } else {
-                            if (record.isLeaf() || (record.isLoaded() && !record.hasChildNodes())) {
-                                buf.unshift(format(imgText, (treePrefix + 'elbow'), Ext.BLANK_IMAGE_URL));
-                            } else {
+                            if (record.isExpandable()) {
                                 buf.unshift(format(imgText, (elbowPrefix + 'plus ' + expanderCls), Ext.BLANK_IMAGE_URL));
+                            } else {
+                                buf.unshift(format(imgText, (treePrefix + 'elbow'), Ext.BLANK_IMAGE_URL));
                             }
                         }
                     } else {
@@ -86580,9 +91219,14 @@ Ext.define('Ext.tree.Column', {
                 record = record.parentNode;
             }
             if (href) {
-                formattedValue = format('<a href="{0}" target="{1}">{2}</a>', href, target, formattedValue);
+                buf.push('<a href="', href, '" target="', target, '">', formattedValue, '</a>');
+            } else {
+                buf.push(formattedValue);
+            }
+            if (cls) {
+                metaData.tdCls += ' ' + cls;
             }
-            return buf.join("") + formattedValue;
+            return buf.join('');
         };
         this.callParent(arguments);
     },
@@ -86603,6 +91247,11 @@ Ext.define('Ext.tree.View', {
     checkboxSelector: '.' + Ext.baseCSSPrefix + 'tree-checkbox',
     expanderIconOverCls: Ext.baseCSSPrefix + 'tree-expander-over',
 
+    
+    
+    
+    nodeAnimWrapCls: Ext.baseCSSPrefix + 'tree-animator-wrap',
+
     blockRefresh: true,
 
     
@@ -86640,7 +91289,17 @@ Ext.define('Ext.tree.View', {
         me.animQueue = {};
         me.callParent(arguments);
     },
-    
+
+    processUIEvent: function(e) {
+        
+        
+        
+        if (e.getTarget('.' + this.nodeAnimWrapCls, this.el)) {
+            return false;
+        }
+        return this.callParent(arguments);
+    },
+
     onClear: function(){
         this.store.removeAll();    
     },
@@ -86656,7 +91315,6 @@ Ext.define('Ext.tree.View', {
     
     onRender: function() {
         var me = this,
-            opts = {delegate: me.expanderSelector},
             el;
 
         me.callParent(arguments);
@@ -86676,14 +91334,20 @@ Ext.define('Ext.tree.View', {
     },
 
     onCheckboxChange: function(e, t) {
-        var item = e.getTarget(this.getItemSelector(), this.getTargetEl()),
-            record, value;
+        var me = this,
+            item = e.getTarget(me.getItemSelector(), me.getTargetEl());
             
         if (item) {
-            record = this.getRecord(item);
-            value = !record.get('checked');
-            record.set('checked', value);
-            this.fireEvent('checkchange', record, value);
+            me.onCheckChange(me.getRecord(item));
+        }
+    },
+    
+    onCheckChange: function(record){
+        var checked = record.get('checked');
+        if (Ext.isBoolean(checked)) {
+            checked = !checked;
+            record.set('checked', checked);
+            this.fireEvent('checkchange', record, checked);
         }
     },
 
@@ -86719,7 +91383,7 @@ Ext.define('Ext.tree.View', {
             tag: 'tr',
             html: [
                 '<td colspan="' + headerCt.getColumnCount() + '">',
-                    '<div class="' + Ext.baseCSSPrefix + 'tree-animator-wrap' + '">',
+                    '<div class="' + this.nodeAnimWrapCls + '">',
                         '<table class="' + Ext.baseCSSPrefix + 'grid-table" style="width: ' + headerCt.getFullWidth() + 'px;"><tbody>',
                             thHtml,
                         '</tbody></table>',
@@ -86795,14 +91459,9 @@ Ext.define('Ext.tree.View', {
             
             Ext.fly(children[relativeIndex + 1]).insertSibling(nodes, 'before', true);
         }
+
         
-        
-        if (index < a.length) {
-            a.splice.apply(a, [index, 0].concat(nodes));
-        }
-        else {            
-            a.push.apply(a, nodes);
-        }
+        Ext.Array.insert(a, index, nodes);
         
         
         
@@ -86811,6 +91470,36 @@ Ext.define('Ext.tree.View', {
         }
     },
     
+    beginBulkUpdate: function(){
+        this.bulkUpdate = true;
+        this.ownerCt.changingScrollbars = true;  
+    },
+    
+    endBulkUpdate: function(){
+        var me = this,
+            ownerCt = me.ownerCt;
+        
+        me.bulkUpdate = false;
+        me.ownerCt.changingScrollbars = true;  
+        me.resetScrollers();  
+    },
+    
+    onRemove : function(ds, record, index) {
+        var me = this,
+            bulk = me.bulkUpdate;
+
+        me.doRemove(record, index);
+        if (!bulk) {
+            me.updateIndexes(index);
+        }
+        if (me.store.getCount() === 0){
+            me.refresh();
+        }
+        if (!bulk) {
+            me.fireEvent('itemremove', record, index);
+        }
+    },
+    
     doRemove: function(record, index) {
         
         
@@ -86833,7 +91522,7 @@ Ext.define('Ext.tree.View', {
         var me = this,
             animWrap;
             
-        if (!me.animate) {
+        if (!me.rendered || !me.animate) {
             return;
         }
 
@@ -86898,17 +91587,19 @@ Ext.define('Ext.tree.View', {
     },
     
     resetScrollers: function(){
-        var panel = this.panel;
-        
-        panel.determineScrollbars();
-        panel.invalidateScroller();
+        if (!this.bulkUpdate) {
+            var panel = this.panel;
+            
+            panel.determineScrollbars();
+            panel.invalidateScroller();
+        }
     },
 
     onBeforeCollapse: function(parent, records, index) {
         var me = this,
             animWrap;
             
-        if (!me.animate) {
+        if (!me.rendered || !me.animate) {
             return;
         }
 
@@ -87062,43 +91753,45 @@ Ext.define('Ext.tree.Panel', {
     requires: ['Ext.tree.View', 'Ext.selection.TreeModel', 'Ext.tree.Column'],
     viewType: 'treeview',
     selType: 'treemodel',
-    
+
     treeCls: Ext.baseCSSPrefix + 'tree-panel',
-    
+
+    deferRowRender: false,
+
     
     lines: true,
-    
+
     
     useArrows: false,
-    
+
     
     singleExpand: false,
-    
+
     ddConfig: {
         enableDrag: true,
         enableDrop: true
     },
+
     
-    
-            
+
     
     rootVisible: true,
+
     
-        
     displayField: 'text',
 
     
     root: null,
-    
+
     
     
     normalCfgCopy: ['displayField', 'root', 'singleExpand', 'useArrows', 'lines', 'rootVisible', 'scroll'],
     lockedCfgCopy: ['displayField', 'root', 'singleExpand', 'useArrows', 'lines', 'rootVisible'],
 
     
+
     
-     
-    
+
     constructor: function(config) {
         config = config || {};
         if (config.animate === undefined) {
@@ -87106,10 +91799,10 @@ Ext.define('Ext.tree.Panel', {
         }
         this.enableAnimations = config.animate;
         delete config.animate;
-        
+
         this.callParent([config]);
     },
-    
+
     initComponent: function() {
         var me = this,
             cls = [me.treeCls];
@@ -87118,35 +91811,36 @@ Ext.define('Ext.tree.Panel', {
             cls.push(Ext.baseCSSPrefix + 'tree-arrows');
             me.lines = false;
         }
-        
+
         if (me.lines) {
             cls.push(Ext.baseCSSPrefix + 'tree-lines');
         } else if (!me.useArrows) {
             cls.push(Ext.baseCSSPrefix + 'tree-no-lines');
         }
 
-        if (!me.store || Ext.isObject(me.store) && !me.store.isStore) {
+        if (Ext.isString(me.store)) {
+            me.store = Ext.StoreMgr.lookup(me.store);
+        } else if (!me.store || Ext.isObject(me.store) && !me.store.isStore) {
             me.store = Ext.create('Ext.data.TreeStore', Ext.apply({}, me.store || {}, {
                 root: me.root,
                 fields: me.fields,
                 model: me.model,
                 folderSort: me.folderSort
             }));
-        }
-        else if (me.root) {
+        } else if (me.root) {
             me.store = Ext.data.StoreManager.lookup(me.store);
             me.store.setRootNode(me.root);
             if (me.folderSort !== undefined) {
                 me.store.folderSort = me.folderSort;
                 me.store.sort();
-            }            
+            }
         }
+
         
         
         
         
-        
-        
+
         me.viewConfig = Ext.applyIf(me.viewConfig || {}, {
             rootVisible: me.rootVisible,
             animate: me.enableAnimations,
@@ -87154,59 +91848,59 @@ Ext.define('Ext.tree.Panel', {
             node: me.store.getRootNode(),
             hideHeaders: me.hideHeaders
         });
-        
+
         me.mon(me.store, {
             scope: me,
             rootchange: me.onRootChange,
             clear: me.onClear
         });
-    
+
         me.relayEvents(me.store, [
             
             'beforeload',
 
             
-            'load'   
+            'load'
         ]);
-        
+
         me.store.on({
             
             append: me.createRelayer('itemappend'),
-            
+
             
             remove: me.createRelayer('itemremove'),
-            
+
             
             move: me.createRelayer('itemmove'),
-            
+
             
             insert: me.createRelayer('iteminsert'),
-            
+
             
             beforeappend: me.createRelayer('beforeitemappend'),
-            
+
             
             beforeremove: me.createRelayer('beforeitemremove'),
-            
+
             
             beforemove: me.createRelayer('beforeitemmove'),
-            
+
             
             beforeinsert: me.createRelayer('beforeiteminsert'),
-             
+
             
             expand: me.createRelayer('itemexpand'),
-             
+
             
             collapse: me.createRelayer('itemcollapse'),
-             
+
             
             beforeexpand: me.createRelayer('beforeitemexpand'),
-             
+
             
             beforecollapse: me.createRelayer('beforeitemcollapse')
         });
-        
+
         
         if (!me.columns) {
             if (me.initialConfig.hideHeaders === undefined) {
@@ -87216,21 +91910,21 @@ Ext.define('Ext.tree.Panel', {
                 xtype    : 'treecolumn',
                 text     : 'Name',
                 flex     : 1,
-                dataIndex: me.displayField         
+                dataIndex: me.displayField
             }];
         }
-        
+
         if (me.cls) {
             cls.push(me.cls);
         }
         me.cls = cls.join(' ');
         me.callParent();
-        
+
         me.relayEvents(me.getView(), [
             
             'checkchange'
         ]);
-            
+
         
         if (!me.getView().rootVisible && !me.getRootNode()) {
             me.setRootNode({
@@ -87238,19 +91932,21 @@ Ext.define('Ext.tree.Panel', {
             });
         }
     },
-    
+
     onClear: function(){
         this.view.onClear();
     },
+
     
     setRootNode: function() {
         return this.store.setRootNode.apply(this.store, arguments);
     },
+
     
     getRootNode: function() {
         return this.store.getRootNode();
     },
-    
+
     onRootChange: function(root) {
         this.view.setRootNode(root);
     },
@@ -87259,29 +91955,45 @@ Ext.define('Ext.tree.Panel', {
     getChecked: function() {
         return this.getView().getChecked();
     },
-    
+
     isItemChecked: function(rec) {
         return rec.get('checked');
     },
-        
+
     
     expandAll : function(callback, scope) {
-        var root = this.getRootNode();
+        var root = this.getRootNode(),
+            animate = this.enableAnimations,
+            view = this.getView();
         if (root) {
+            if (!animate) {
+                view.beginBulkUpdate();
+            }
             root.expand(true, callback, scope);
+            if (!animate) {
+                view.endBulkUpdate();
+            }
         }
     },
 
     
     collapseAll : function(callback, scope) {
-        var root = this.getRootNode();
+        var root = this.getRootNode(),
+            animate = this.enableAnimations,
+            view = this.getView();
+
         if (root) {
-            if (this.getView().rootVisible) {
-                root.collapse(true, callback, scope);
+            if (!animate) {
+                view.beginBulkUpdate();
             }
-            else {
+            if (view.rootVisible) {
+                root.collapse(true, callback, scope);
+            } else {
                 root.collapseChildren(true, callback, scope);
             }
+            if (!animate) {
+                view.endBulkUpdate();
+            }
         }
     },
 
@@ -87293,22 +92005,22 @@ Ext.define('Ext.tree.Panel', {
             view = me.getView(),
             keys,
             expander;
-        
+
         field = field || me.getRootNode().idProperty;
         separator = separator || '/';
-        
+
         if (Ext.isEmpty(path)) {
             Ext.callback(callback, scope || me, [false, null]);
             return;
         }
-        
+
         keys = path.split(separator);
         if (current.get(field) != keys[1]) {
             
             Ext.callback(callback, scope || me, [false, current]);
             return;
         }
-        
+
         expander = function(){
             if (++index === keys.length) {
                 Ext.callback(callback, scope || me, [true, current]);
@@ -87324,20 +92036,20 @@ Ext.define('Ext.tree.Panel', {
         };
         current.expand(false, expander);
     },
-    
+
     
     selectPath: function(path, field, separator, callback, scope) {
         var me = this,
             keys,
             last;
-        
+
         field = field || me.getRootNode().idProperty;
         separator = separator || '/';
-        
+
         keys = path.split(separator);
         last = keys.pop();
-        
-        me.expandPath(keys.join('/'), field, separator, function(success, node){
+
+        me.expandPath(keys.join(separator), field, separator, function(success, node){
             var doSuccess = false;
             if (success && node) {
                 node = node.findChild(field, last);
@@ -87354,6 +92066,7 @@ Ext.define('Ext.tree.Panel', {
     }
 });
 
+
 Ext.define('Ext.view.DragZone', {
     extend: 'Ext.dd.DragZone',
     containerScroll: false,
@@ -87396,6 +92109,12 @@ Ext.define('Ext.view.DragZone', {
     onItemMouseDown: function(view, record, item, index, e) {
         if (!this.isPreventDrag(e, record, item, index)) {
             this.handleMouseDown(e);
+
+            
+            
+            if (view.getSelectionModel().selectionMode == 'MULTI' && !e.ctrlKey && view.getSelectionModel().isSelected(record)) {
+                return false;
+            }
         }
     },
 
@@ -87436,7 +92155,7 @@ Ext.define('Ext.view.DragZone', {
         
         
         if (!selectionModel.isSelected(record) || e.hasModifier()) {
-            selectionModel.selectWithEvent(record, e);
+            selectionModel.selectWithEvent(record, e, true);
         }
         data.records = selectionModel.getSelection();
 
@@ -87598,10 +92317,10 @@ Ext.define('Ext.tree.ViewDropZone', {
         }
         
         
-        if (position === 'append' && targetNode.get('allowDrop') == false) {
+        if (position === 'append' && targetNode.get('allowDrop') === false) {
             return false;
         }
-        else if (position != 'append' && targetNode.parentNode.get('allowDrop') == false) {
+        else if (position != 'append' && targetNode.parentNode.get('allowDrop') === false) {
             return false;
         }
 
@@ -87630,6 +92349,7 @@ Ext.define('Ext.tree.ViewDropZone', {
             this.queueExpand(targetNode);
         }
             
+            
         if (this.isValidDropPoint(node, position, dragZone, e, data)) {
             this.valid = true;
             this.currentPosition = position;
@@ -87638,24 +92358,22 @@ Ext.define('Ext.tree.ViewDropZone', {
             indicator.setWidth(Ext.fly(node).getWidth());
             indicatorY = Ext.fly(node).getY() - Ext.fly(view.el).getY() - 1;
 
+            
             if (position == 'before') {
                 returnCls = targetNode.isFirst() ? Ext.baseCSSPrefix + 'tree-drop-ok-above' : Ext.baseCSSPrefix + 'tree-drop-ok-between';
                 indicator.showAt(0, indicatorY);
-                indicator.toFront();
-            }
-            else if (position == 'after') {
+                dragZone.proxy.show();
+            } else if (position == 'after') {
                 returnCls = targetNode.isLast() ? Ext.baseCSSPrefix + 'tree-drop-ok-below' : Ext.baseCSSPrefix + 'tree-drop-ok-between';
                 indicatorY += Ext.fly(node).getHeight();
                 indicator.showAt(0, indicatorY);
-                indicator.toFront();
-            }
-            else {
+                dragZone.proxy.show();
+            } else {
                 returnCls = Ext.baseCSSPrefix + 'tree-drop-ok-append';
                 
                 indicator.hide();
             }
-        }
-        else {
+        } else {
             this.valid = false;
         }
 
@@ -87742,7 +92460,9 @@ Ext.define('Ext.tree.ViewDropZone', {
                 
                 
                 Ext.Array.forEach(recordDomNodes, function(n) {
-                    Ext.fly(n.firstChild ? n.firstChild : n).highlight(me.dropHighlightColor);
+                    if (n) {
+                        Ext.fly(n.firstChild ? n.firstChild : n).highlight(me.dropHighlightColor);
+                    }
                 });
             }
         };
@@ -87797,13 +92517,13 @@ Ext.define('Ext.tree.plugin.TreeViewDragDrop', {
 
     
     enableDrag: true,
-    
+
     
     nodeHighlightColor: 'c3daf9',
-    
+
     
     nodeHighlightOnDrop: Ext.enableFx,
-    
+
     
     nodeHighlightOnRepair: Ext.enableFx,
 
@@ -87914,7 +92634,7 @@ Ext.define('Ext.util.CSS', function() {
             this.rules = {};
             this.initialized = false;
         },
+
         
         createStyleSheet : function(cssText, id) {
             var ss,
@@ -87983,7 +92703,7 @@ Ext.define('Ext.util.CSS', function() {
                 for (; i >= 0; --i) {
                     selectorText = ssRules[i].selectorText;
                     if (selectorText) {
+
                         
                         selectorText = selectorText.split(',');
                         selectors = selectorText.length;
@@ -88008,7 +92728,7 @@ Ext.define('Ext.util.CSS', function() {
                         if (!ds[i].disabled) {
                             this.cacheStyleSheet(ds[i]);
                         }
-                    } catch(e) {} 
+                    } catch(e) {}
                 }
             }
             return rules;
@@ -88054,7 +92774,7 @@ Ext.define('Ext.util.History', {
     mixins: {
         observable: 'Ext.util.Observable'
     },
-    
+
     constructor: function() {
         var me = this;
         me.oldIEMode = Ext.isIE6 || Ext.isIE7 || !Ext.isStrict && Ext.isIE8;
@@ -88063,18 +92783,18 @@ Ext.define('Ext.util.History', {
         me.ready = false;
         me.currentToken = null;
     },
-    
+
     getHash: function() {
         var href = window.location.href,
             i = href.indexOf("#");
-            
+
         return i >= 0 ? href.substr(i + 1) : null;
     },
 
     doSave: function() {
         this.hiddenField.value = this.currentToken;
     },
-    
+
 
     handleStateChange: function(token) {
         this.currentToken = token;
@@ -88082,8 +92802,8 @@ Ext.define('Ext.util.History', {
     },
 
     updateIFrame: function(token) {
-        var html = '<html><body><div id="state">' + 
-                    Ext.util.Format.htmlEncode(token) + 
+        var html = '<html><body><div id="state">' +
+                    Ext.util.Format.htmlEncode(token) +
                     '</div></body></html>';
 
         try {
@@ -88100,17 +92820,17 @@ Ext.define('Ext.util.History', {
     checkIFrame: function () {
         var me = this,
             contentWindow = me.iframe.contentWindow;
-            
+
         if (!contentWindow || !contentWindow.document) {
             Ext.Function.defer(this.checkIFrame, 10, this);
             return;
         }
-       
+
         var doc = contentWindow.document,
             elem = doc.getElementById("state"),
             oldToken = elem ? elem.innerText : null,
             oldHash = me.getHash();
-           
+
         Ext.TaskManager.start({
             run: function () {
                 var doc = contentWindow.document,
@@ -88128,17 +92848,17 @@ Ext.define('Ext.util.History', {
                     oldHash = newHash;
                     me.updateIFrame(newHash);
                 }
-            }, 
+            },
             interval: 50,
             scope: me
         });
         me.ready = true;
-        me.fireEvent('ready', me);            
+        me.fireEvent('ready', me);
     },
 
     startUp: function () {
         var me = this;
-        
+
         me.currentToken = me.hiddenField.value || this.getHash();
 
         if (me.oldIEMode) {
@@ -88160,7 +92880,7 @@ Ext.define('Ext.util.History', {
             me.ready = true;
             me.fireEvent('ready', me);
         }
-        
+
     },
 
     
@@ -88171,32 +92891,32 @@ Ext.define('Ext.util.History', {
     
     init: function (onReady, scope) {
         var me = this;
-        
+
         if (me.ready) {
             Ext.callback(onReady, scope, [me]);
             return;
         }
-        
+
         if (!Ext.isReady) {
             Ext.onReady(function() {
                 me.init(onReady, scope);
             });
             return;
         }
-        
+
         me.hiddenField = Ext.getDom(me.fieldId);
-        
+
         if (me.oldIEMode) {
             me.iframe = Ext.getDom(me.iframeId);
         }
-        
+
         me.addEvents(
             
             'ready',
             
             'change'
         );
-        
+
         if (onReady) {
             me.on('ready', onReady, scope, {single: true});
         }
@@ -88206,13 +92926,13 @@ Ext.define('Ext.util.History', {
     
     add: function (token, preventDup) {
         var me = this;
-        
+
         if (preventDup !== false) {
             if (me.getToken() === token) {
                 return true;
             }
         }
-        
+
         if (me.oldIEMode) {
             return me.updateIFrame(token);
         } else {
@@ -88244,7 +92964,7 @@ Ext.define('Ext.view.TableChunker', {
         '{[this.openTableWrap()]}',
         '<table class="' + Ext.baseCSSPrefix + 'grid-table ' + Ext.baseCSSPrefix + 'grid-table-resizer" border="0" cellspacing="0" cellpadding="0" {[this.embedFullWidth()]}>',
             '<tbody>',
-            '<tr>',
+            '<tr class="' + Ext.baseCSSPrefix + 'grid-header-row">',
             '<tpl for="columns">',
                 '<th class="' + Ext.baseCSSPrefix + 'grid-col-resizer-{id}" style="width: {width}px; height: 0px;"></th>',
             '</tpl>',