Upgrade to ExtJS 3.0.3 - Released 10/11/2009
[extjs.git] / ext-all-debug.js
index 0f649b5..d38b19f 100644 (file)
 /*!
- * Ext JS Library 3.0.0
+ * Ext JS Library 3.0.3
  * Copyright(c) 2006-2009 Ext JS, LLC
  * licensing@extjs.com
  * http://www.extjs.com/license
  */
-/**
- * @class Ext.DomHelper
- * <p>The DomHelper class provides a layer of abstraction from DOM and transparently supports creating
- * elements via DOM or using HTML fragments. It also has the ability to create HTML fragment templates
- * from your DOM building code.</p>
- *
- * <p><b><u>DomHelper element specification object</u></b></p>
- * <p>A specification object is used when creating elements. Attributes of this object
- * are assumed to be element attributes, except for 4 special attributes:
- * <div class="mdetail-params"><ul>
- * <li><b><tt>tag</tt></b> : <div class="sub-desc">The tag name of the element</div></li>
- * <li><b><tt>children</tt></b> : or <tt>cn</tt><div class="sub-desc">An array of the
- * same kind of element definition objects to be created and appended. These can be nested
- * as deep as you want.</div></li>
- * <li><b><tt>cls</tt></b> : <div class="sub-desc">The class attribute of the element.
- * This will end up being either the "class" attribute on a HTML fragment or className
- * for a DOM node, depending on whether DomHelper is using fragments or DOM.</div></li>
- * <li><b><tt>html</tt></b> : <div class="sub-desc">The innerHTML for the element</div></li>
- * </ul></div></p>
- *
- * <p><b><u>Insertion methods</u></b></p>
- * <p>Commonly used insertion methods:
- * <div class="mdetail-params"><ul>
- * <li><b><tt>{@link #append}</tt></b> : <div class="sub-desc"></div></li>
- * <li><b><tt>{@link #insertBefore}</tt></b> : <div class="sub-desc"></div></li>
- * <li><b><tt>{@link #insertAfter}</tt></b> : <div class="sub-desc"></div></li>
- * <li><b><tt>{@link #overwrite}</tt></b> : <div class="sub-desc"></div></li>
- * <li><b><tt>{@link #createTemplate}</tt></b> : <div class="sub-desc"></div></li>
- * <li><b><tt>{@link #insertHtml}</tt></b> : <div class="sub-desc"></div></li>
- * </ul></div></p>
- *
- * <p><b><u>Example</u></b></p>
- * <p>This is an example, where an unordered list with 3 children items is appended to an existing
- * element with id <tt>'my-div'</tt>:<br>
- <pre><code>
-var dh = Ext.DomHelper; // create shorthand alias
-// specification object
-var spec = {
-    id: 'my-ul',
-    tag: 'ul',
-    cls: 'my-list',
-    // append children after creating
-    children: [     // may also specify 'cn' instead of 'children'
-        {tag: 'li', id: 'item0', html: 'List Item 0'},
-        {tag: 'li', id: 'item1', html: 'List Item 1'},
-        {tag: 'li', id: 'item2', html: 'List Item 2'}
-    ]
-};
-var list = dh.append(
-    'my-div', // the context element 'my-div' can either be the id or the actual node
-    spec      // the specification object
-);
- </code></pre></p>
- * <p>Element creation specification parameters in this class may also be passed as an Array of
- * specification objects. This can be used to insert multiple sibling nodes into an existing
- * container very efficiently. For example, to add more list items to the example above:<pre><code>
-dh.append('my-ul', [
-    {tag: 'li', id: 'item3', html: 'List Item 3'},
-    {tag: 'li', id: 'item4', html: 'List Item 4'}
-]);
- * </code></pre></p>
- *
- * <p><b><u>Templating</u></b></p>
- * <p>The real power is in the built-in templating. Instead of creating or appending any elements,
- * <tt>{@link #createTemplate}</tt> returns a Template object which can be used over and over to
- * insert new elements. Revisiting the example above, we could utilize templating this time:
- * <pre><code>
-// create the node
-var list = dh.append('my-div', {tag: 'ul', cls: 'my-list'});
-// get template
-var tpl = dh.createTemplate({tag: 'li', id: 'item{0}', html: 'List Item {0}'});
-
-for(var i = 0; i < 5, i++){
-    tpl.append(list, [i]); // use template to append to the actual node
-}
- * </code></pre></p>
- * <p>An example using a template:<pre><code>
-var html = '<a id="{0}" href="{1}" class="nav">{2}</a>';
-
-var tpl = new Ext.DomHelper.createTemplate(html);
-tpl.append('blog-roll', ['link1', 'http://www.jackslocum.com/', "Jack&#39;s Site"]);
-tpl.append('blog-roll', ['link2', 'http://www.dustindiaz.com/', "Dustin&#39;s Site"]);
- * </code></pre></p>
- *
- * <p>The same example using named parameters:<pre><code>
-var html = '<a id="{id}" href="{url}" class="nav">{text}</a>';
-
-var tpl = new Ext.DomHelper.createTemplate(html);
-tpl.append('blog-roll', {
-    id: 'link1',
-    url: 'http://www.jackslocum.com/',
-    text: "Jack&#39;s Site"
-});
-tpl.append('blog-roll', {
-    id: 'link2',
-    url: 'http://www.dustindiaz.com/',
-    text: "Dustin&#39;s Site"
-});
- * </code></pre></p>
- *
- * <p><b><u>Compiling Templates</u></b></p>
- * <p>Templates are applied using regular expressions. The performance is great, but if
- * you are adding a bunch of DOM elements using the same template, you can increase
- * performance even further by {@link Ext.Template#compile "compiling"} the template.
- * The way "{@link Ext.Template#compile compile()}" works is the template is parsed and
- * broken up at the different variable points and a dynamic function is created and eval'ed.
- * The generated function performs string concatenation of these parts and the passed
- * variables instead of using regular expressions.
- * <pre><code>
-var html = '<a id="{id}" href="{url}" class="nav">{text}</a>';
-
-var tpl = new Ext.DomHelper.createTemplate(html);
-tpl.compile();
-
-//... use template like normal
- * </code></pre></p>
- *
- * <p><b><u>Performance Boost</u></b></p>
- * <p>DomHelper will transparently create HTML fragments when it can. Using HTML fragments instead
- * of DOM can significantly boost performance.</p>
- * <p>Element creation specification parameters may also be strings. If {@link #useDom} is <tt>false</tt>,
- * then the string is used as innerHTML. If {@link #useDom} is <tt>true</tt>, a string specification
- * results in the creation of a text node. Usage:</p>
- * <pre><code>
-Ext.DomHelper.useDom = true; // force it to use DOM; reduces performance
- * </code></pre>
- * @singleton
- */
-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,
-       pub,
-       // kill repeat to save bytes
-       afterbegin = "afterbegin",
-       afterend = "afterend",
-       beforebegin = "beforebegin",
-       beforeend = "beforeend",
-       ts = '<table>',
-        te = '</table>',
-        tbs = ts+'<tbody>',
-        tbe = '</tbody>'+te,
-        trs = tbs + '<tr>',
-        tre = '</tr>'+tbe;
-
-    // private
-    function doInsert(el, o, returnElement, pos, sibling, append){
-        var newNode = pub.insertHtml(pos, Ext.getDom(el), createHtml(o));
-        return returnElement ? Ext.get(newNode, true) : newNode;
-    }
-
-    // build as innerHTML where available
-    function createHtml(o){
-           var b = "",
-               attr,
-               val,
-               key,
-               keyVal,
-               cn;
-
-        if(typeof o == 'string'){
-            b = o;
-        } else if (Ext.isArray(o)) {
-               Ext.each(o, function(v) {
-                b += createHtml(v);
-            });
-        } else {
-               b += "<" + (o.tag = o.tag || "div");
-            Ext.iterate(o, function(attr, val){
-                if(!/tag|children|cn|html$/i.test(attr)){
-                    if (Ext.isObject(val)) {
-                        b += " " + attr + "='";
-                        Ext.iterate(val, function(key, keyVal){
-                            b += key + ":" + keyVal + ";";
-                        });
-                        b += "'";
-                    }else{
-                        b += " " + ({cls : "class", htmlFor : "for"}[attr] || attr) + "='" + val + "'";
-                    }
-                }
-            });
-               // Now either just close the tag or try to add children and close the tag.
-               if (emptyTags.test(o.tag)) {
-                   b += "/>";
-               } else {
-                   b += ">";
-                   if ((cn = o.children || o.cn)) {
-                       b += createHtml(cn);
-                   } else if(o.html){
-                       b += o.html;
-                   }
-                   b += "</" + o.tag + ">";
-               }
-        }
-        return b;
-    }
-
-    function ieTable(depth, s, h, e){
-        tempTableEl.innerHTML = [s, h, e].join('');
-        var i = -1,
-               el = tempTableEl;
-        while(++i < depth){
-            el = el.firstChild;
-        }
-        return el;
-    }
-
-    /**
-     * @ignore
-     * Nasty code for IE's broken table implementation
-     */
-    function insertIntoTable(tag, where, el, html) {
-           var node,
-               before;
-
-        tempTableEl = tempTableEl || document.createElement('div');
-
-           if(tag == 'td' && (where == afterbegin || where == beforeend) ||
-              !/td|tr|tbody/i.test(tag) && (where == beforebegin || where == afterend)) {
-            return;
-        }
-        before = where == beforebegin ? el :
-                                where == afterend ? el.nextSibling :
-                                where == afterbegin ? el.firstChild : null;
-
-        if (where == beforebegin || where == afterend) {
-               el = el.parentNode;
-       }
-
-        if (tag == 'td' || (tag == "tr" && (where == beforeend || where == afterbegin))) {
-               node = ieTable(4, trs, html, tre);
-        } else if ((tag == "tbody" && (where == beforeend || where == afterbegin)) ||
-                          (tag == "tr" && (where == beforebegin || where == afterend))) {
-               node = ieTable(3, tbs, html, tbe);
-        } else {
-               node = ieTable(2, ts, html, te);
-        }
-        el.insertBefore(node, before);
-        return node;
-    }
-
-
-    pub = {
-           /**
-            * Returns the markup for the passed Element(s) config.
-            * @param {Object} o The DOM object spec (and children)
-            * @return {String}
-            */
-           markup : function(o){
-               return createHtml(o);
-           },
-
-           /**
-            * Inserts an HTML fragment into the DOM.
-            * @param {String} where Where to insert the html in relation to el - beforeBegin, afterBegin, beforeEnd, afterEnd.
-            * @param {HTMLElement} el The context element
-            * @param {String} html The HTML fragmenet
-            * @return {HTMLElement} The new node
-            */
-           insertHtml : function(where, el, html){
-               var hash = {},
-                       hashVal,
-                       setStart,
-                       range,
-                       frag,
-                       rangeEl,
-                       rs;
-
-               where = where.toLowerCase();
-               // add these here because they are used in both branches of the condition.
-               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;
-                   }
-                   // add these two to the hash.
-                   hash[afterbegin] = ['AfterBegin', 'firstChild'];
-                   hash[beforeend] = ['BeforeEnd', 'lastChild'];
-                   if ((hashVal = hash[where])) {
-                               el.insertAdjacentHTML(hashVal[0], html);
-                       return el[hashVal[1]];
-                   }
-               } else {
-                       range = el.ownerDocument.createRange();
-                       setStart = "setStart" + (/end/i.test(where) ? "After" : "Before");
-                       if (hash[where]) {
-                               range[setStart](el);
-                               frag = range.createContextualFragment(html);
-                               el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling);
-                               return el[(where == beforebegin ? "previous" : "next") + "Sibling"];
-                       } else {
-                               rangeEl = (where == afterbegin ? "first" : "last") + "Child";
-                               if (el.firstChild) {
-                                       range[setStart](el[rangeEl]);
-                                       frag = range.createContextualFragment(html);
-                        if(where == afterbegin){
-                            el.insertBefore(frag, el.firstChild);
-                        }else{
-                            el.appendChild(frag);
-                        }
-                               } else {
-                                   el.innerHTML = html;
-                           }
-                           return el[rangeEl];
-                       }
-               }
-               throw 'Illegal insertion point -> "' + where + '"';
-           },
-
-           /**
-            * Creates new DOM element(s) and inserts them before el.
-            * @param {Mixed} el The context element
-            * @param {Object/String} o The DOM object spec (and children) or raw HTML blob
-            * @param {Boolean} returnElement (optional) true to return a Ext.Element
-            * @return {HTMLElement/Ext.Element} The new node
-            */
-           insertBefore : function(el, o, returnElement){
-               return doInsert(el, o, returnElement, beforebegin);
-           },
-
-           /**
-            * Creates new DOM element(s) and inserts them after el.
-            * @param {Mixed} el The context element
-            * @param {Object} o The DOM object spec (and children)
-            * @param {Boolean} returnElement (optional) true to return a Ext.Element
-            * @return {HTMLElement/Ext.Element} The new node
-            */
-           insertAfter : function(el, o, returnElement){
-               return doInsert(el, o, returnElement, afterend, "nextSibling");
-           },
-
-           /**
-            * Creates new DOM element(s) and inserts them as the first child of el.
-            * @param {Mixed} el The context element
-            * @param {Object/String} o The DOM object spec (and children) or raw HTML blob
-            * @param {Boolean} returnElement (optional) true to return a Ext.Element
-            * @return {HTMLElement/Ext.Element} The new node
-            */
-           insertFirst : function(el, o, returnElement){
-               return doInsert(el, o, returnElement, afterbegin, "firstChild");
-           },
-
-           /**
-            * Creates new DOM element(s) and appends them to el.
-            * @param {Mixed} el The context element
-            * @param {Object/String} o The DOM object spec (and children) or raw HTML blob
-            * @param {Boolean} returnElement (optional) true to return a Ext.Element
-            * @return {HTMLElement/Ext.Element} The new node
-            */
-           append : function(el, o, returnElement){
-                   return doInsert(el, o, returnElement, beforeend, "", true);
-           },
-
-           /**
-            * Creates new DOM element(s) and overwrites the contents of el with them.
-            * @param {Mixed} el The context element
-            * @param {Object/String} o The DOM object spec (and children) or raw HTML blob
-            * @param {Boolean} returnElement (optional) true to return a Ext.Element
-            * @return {HTMLElement/Ext.Element} The new node
-            */
-           overwrite : function(el, o, returnElement){
-               el = Ext.getDom(el);
-               el.innerHTML = createHtml(o);
-               return returnElement ? Ext.get(el.firstChild) : el.firstChild;
-           },
-
-           createHtml : createHtml
-    };
-    return pub;
+/**\r
+ * @class Ext.DomHelper\r
+ * <p>The DomHelper class provides a layer of abstraction from DOM and transparently supports creating\r
+ * elements via DOM or using HTML fragments. It also has the ability to create HTML fragment templates\r
+ * from your DOM building code.</p>\r
+ *\r
+ * <p><b><u>DomHelper element specification object</u></b></p>\r
+ * <p>A specification object is used when creating elements. Attributes of this object\r
+ * are assumed to be element attributes, except for 4 special attributes:\r
+ * <div class="mdetail-params"><ul>\r
+ * <li><b><tt>tag</tt></b> : <div class="sub-desc">The tag name of the element</div></li>\r
+ * <li><b><tt>children</tt></b> : or <tt>cn</tt><div class="sub-desc">An array of the\r
+ * same kind of element definition objects to be created and appended. These can be nested\r
+ * as deep as you want.</div></li>\r
+ * <li><b><tt>cls</tt></b> : <div class="sub-desc">The class attribute of the element.\r
+ * This will end up being either the "class" attribute on a HTML fragment or className\r
+ * for a DOM node, depending on whether DomHelper is using fragments or DOM.</div></li>\r
+ * <li><b><tt>html</tt></b> : <div class="sub-desc">The innerHTML for the element</div></li>\r
+ * </ul></div></p>\r
+ *\r
+ * <p><b><u>Insertion methods</u></b></p>\r
+ * <p>Commonly used insertion methods:\r
+ * <div class="mdetail-params"><ul>\r
+ * <li><b><tt>{@link #append}</tt></b> : <div class="sub-desc"></div></li>\r
+ * <li><b><tt>{@link #insertBefore}</tt></b> : <div class="sub-desc"></div></li>\r
+ * <li><b><tt>{@link #insertAfter}</tt></b> : <div class="sub-desc"></div></li>\r
+ * <li><b><tt>{@link #overwrite}</tt></b> : <div class="sub-desc"></div></li>\r
+ * <li><b><tt>{@link #createTemplate}</tt></b> : <div class="sub-desc"></div></li>\r
+ * <li><b><tt>{@link #insertHtml}</tt></b> : <div class="sub-desc"></div></li>\r
+ * </ul></div></p>\r
+ *\r
+ * <p><b><u>Example</u></b></p>\r
+ * <p>This is an example, where an unordered list with 3 children items is appended to an existing\r
+ * element with id <tt>'my-div'</tt>:<br>\r
+ <pre><code>\r
+var dh = Ext.DomHelper; // create shorthand alias\r
+// specification object\r
+var spec = {\r
+    id: 'my-ul',\r
+    tag: 'ul',\r
+    cls: 'my-list',\r
+    // append children after creating\r
+    children: [     // may also specify 'cn' instead of 'children'\r
+        {tag: 'li', id: 'item0', html: 'List Item 0'},\r
+        {tag: 'li', id: 'item1', html: 'List Item 1'},\r
+        {tag: 'li', id: 'item2', html: 'List Item 2'}\r
+    ]\r
+};\r
+var list = dh.append(\r
+    'my-div', // the context element 'my-div' can either be the id or the actual node\r
+    spec      // the specification object\r
+);\r
+ </code></pre></p>\r
+ * <p>Element creation specification parameters in this class may also be passed as an Array of\r
+ * specification objects. This can be used to insert multiple sibling nodes into an existing\r
+ * container very efficiently. For example, to add more list items to the example above:<pre><code>\r
+dh.append('my-ul', [\r
+    {tag: 'li', id: 'item3', html: 'List Item 3'},\r
+    {tag: 'li', id: 'item4', html: 'List Item 4'}\r
+]);\r
+ * </code></pre></p>\r
+ *\r
+ * <p><b><u>Templating</u></b></p>\r
+ * <p>The real power is in the built-in templating. Instead of creating or appending any elements,\r
+ * <tt>{@link #createTemplate}</tt> returns a Template object which can be used over and over to\r
+ * insert new elements. Revisiting the example above, we could utilize templating this time:\r
+ * <pre><code>\r
+// create the node\r
+var list = dh.append('my-div', {tag: 'ul', cls: 'my-list'});\r
+// get template\r
+var tpl = dh.createTemplate({tag: 'li', id: 'item{0}', html: 'List Item {0}'});\r
+\r
+for(var i = 0; i < 5, i++){\r
+    tpl.append(list, [i]); // use template to append to the actual node\r
+}\r
+ * </code></pre></p>\r
+ * <p>An example using a template:<pre><code>\r
+var html = '<a id="{0}" href="{1}" class="nav">{2}</a>';\r
+\r
+var tpl = new Ext.DomHelper.createTemplate(html);\r
+tpl.append('blog-roll', ['link1', 'http://www.jackslocum.com/', "Jack&#39;s Site"]);\r
+tpl.append('blog-roll', ['link2', 'http://www.dustindiaz.com/', "Dustin&#39;s Site"]);\r
+ * </code></pre></p>\r
+ *\r
+ * <p>The same example using named parameters:<pre><code>\r
+var html = '<a id="{id}" href="{url}" class="nav">{text}</a>';\r
+\r
+var tpl = new Ext.DomHelper.createTemplate(html);\r
+tpl.append('blog-roll', {\r
+    id: 'link1',\r
+    url: 'http://www.jackslocum.com/',\r
+    text: "Jack&#39;s Site"\r
+});\r
+tpl.append('blog-roll', {\r
+    id: 'link2',\r
+    url: 'http://www.dustindiaz.com/',\r
+    text: "Dustin&#39;s Site"\r
+});\r
+ * </code></pre></p>\r
+ *\r
+ * <p><b><u>Compiling Templates</u></b></p>\r
+ * <p>Templates are applied using regular expressions. The performance is great, but if\r
+ * you are adding a bunch of DOM elements using the same template, you can increase\r
+ * performance even further by {@link Ext.Template#compile "compiling"} the template.\r
+ * The way "{@link Ext.Template#compile compile()}" works is the template is parsed and\r
+ * broken up at the different variable points and a dynamic function is created and eval'ed.\r
+ * The generated function performs string concatenation of these parts and the passed\r
+ * variables instead of using regular expressions.\r
+ * <pre><code>\r
+var html = '<a id="{id}" href="{url}" class="nav">{text}</a>';\r
+\r
+var tpl = new Ext.DomHelper.createTemplate(html);\r
+tpl.compile();\r
+\r
+//... use template like normal\r
+ * </code></pre></p>\r
+ *\r
+ * <p><b><u>Performance Boost</u></b></p>\r
+ * <p>DomHelper will transparently create HTML fragments when it can. Using HTML fragments instead\r
+ * of DOM can significantly boost performance.</p>\r
+ * <p>Element creation specification parameters may also be strings. If {@link #useDom} is <tt>false</tt>,\r
+ * then the string is used as innerHTML. If {@link #useDom} is <tt>true</tt>, a string specification\r
+ * results in the creation of a text node. Usage:</p>\r
+ * <pre><code>\r
+Ext.DomHelper.useDom = true; // force it to use DOM; reduces performance\r
+ * </code></pre>\r
+ * @singleton\r
+ */\r
+Ext.DomHelper = function(){\r
+    var tempTableEl = null,\r
+        emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i,\r
+        tableRe = /^table|tbody|tr|td$/i,\r
+        pub,\r
+        // kill repeat to save bytes\r
+        afterbegin = 'afterbegin',\r
+        afterend = 'afterend',\r
+        beforebegin = 'beforebegin',\r
+        beforeend = 'beforeend',\r
+        ts = '<table>',\r
+        te = '</table>',\r
+        tbs = ts+'<tbody>',\r
+        tbe = '</tbody>'+te,\r
+        trs = tbs + '<tr>',\r
+        tre = '</tr>'+tbe;\r
+\r
+    // private\r
+    function doInsert(el, o, returnElement, pos, sibling, append){\r
+        var newNode = pub.insertHtml(pos, Ext.getDom(el), createHtml(o));\r
+        return returnElement ? Ext.get(newNode, true) : newNode;\r
+    }\r
+\r
+    // build as innerHTML where available\r
+    function createHtml(o){\r
+        var b = '',\r
+            attr,\r
+            val,\r
+            key,\r
+            keyVal,\r
+            cn;\r
+\r
+        if(Ext.isString(o)){\r
+            b = o;\r
+        } else if (Ext.isArray(o)) {\r
+            Ext.each(o, function(v) {\r
+                b += createHtml(v);\r
+            });\r
+        } else {\r
+            b += '<' + (o.tag = o.tag || 'div');\r
+            Ext.iterate(o, function(attr, val){\r
+                if(!/tag|children|cn|html$/i.test(attr)){\r
+                    if (Ext.isObject(val)) {\r
+                        b += ' ' + attr + '="';\r
+                        Ext.iterate(val, function(key, keyVal){\r
+                            b += key + ':' + keyVal + ';';\r
+                        });\r
+                        b += '"';\r
+                    }else{\r
+                        b += ' ' + ({cls : 'class', htmlFor : 'for'}[attr] || attr) + '="' + val + '"';\r
+                    }\r
+                }\r
+            });\r
+            // Now either just close the tag or try to add children and close the tag.\r
+            if (emptyTags.test(o.tag)) {\r
+                b += '/>';\r
+            } else {\r
+                b += '>';\r
+                if ((cn = o.children || o.cn)) {\r
+                    b += createHtml(cn);\r
+                } else if(o.html){\r
+                    b += o.html;\r
+                }\r
+                b += '</' + o.tag + '>';\r
+            }\r
+        }\r
+        return b;\r
+    }\r
+\r
+    function ieTable(depth, s, h, e){\r
+        tempTableEl.innerHTML = [s, h, e].join('');\r
+        var i = -1,\r
+            el = tempTableEl,\r
+            ns;\r
+        while(++i < depth){\r
+            el = el.firstChild;\r
+        }\r
+//      If the result is multiple siblings, then encapsulate them into one fragment.\r
+        if(ns = el.nextSibling){\r
+            var df = document.createDocumentFragment();\r
+            while(el){\r
+                ns = el.nextSibling;\r
+                df.appendChild(el);\r
+                el = ns;\r
+            }\r
+            el = df;\r
+        }\r
+        return el;\r
+    }\r
+\r
+    /**\r
+     * @ignore\r
+     * Nasty code for IE's broken table implementation\r
+     */\r
+    function insertIntoTable(tag, where, el, html) {\r
+        var node,\r
+            before;\r
+\r
+        tempTableEl = tempTableEl || document.createElement('div');\r
+\r
+        if(tag == 'td' && (where == afterbegin || where == beforeend) ||\r
+           !/td|tr|tbody/i.test(tag) && (where == beforebegin || where == afterend)) {\r
+            return;\r
+        }\r
+        before = where == beforebegin ? el :\r
+                 where == afterend ? el.nextSibling :\r
+                 where == afterbegin ? el.firstChild : null;\r
+\r
+        if (where == beforebegin || where == afterend) {\r
+            el = el.parentNode;\r
+        }\r
+\r
+        if (tag == 'td' || (tag == 'tr' && (where == beforeend || where == afterbegin))) {\r
+            node = ieTable(4, trs, html, tre);\r
+        } else if ((tag == 'tbody' && (where == beforeend || where == afterbegin)) ||\r
+                   (tag == 'tr' && (where == beforebegin || where == afterend))) {\r
+            node = ieTable(3, tbs, html, tbe);\r
+        } else {\r
+            node = ieTable(2, ts, html, te);\r
+        }\r
+        el.insertBefore(node, before);\r
+        return node;\r
+    }\r
+\r
+\r
+    pub = {\r
+        /**\r
+         * Returns the markup for the passed Element(s) config.\r
+         * @param {Object} o The DOM object spec (and children)\r
+         * @return {String}\r
+         */\r
+        markup : function(o){\r
+            return createHtml(o);\r
+        },\r
+        \r
+        /**\r
+         * Applies a style specification to an element.\r
+         * @param {String/HTMLElement} el The element to apply styles to\r
+         * @param {String/Object/Function} styles A style specification string e.g. 'width:100px', or object in the form {width:'100px'}, or\r
+         * a function which returns such a specification.\r
+         */\r
+        applyStyles : function(el, styles){\r
+            if(styles){\r
+                var i = 0,\r
+                    len,\r
+                    style;\r
+\r
+                el = Ext.fly(el);\r
+                if(Ext.isFunction(styles)){\r
+                    styles = styles.call();\r
+                }\r
+                if(Ext.isString(styles)){\r
+                    styles = styles.trim().split(/\s*(?::|;)\s*/);\r
+                    for(len = styles.length; i < len;){\r
+                        el.setStyle(styles[i++], styles[i++]);\r
+                    }\r
+                }else if (Ext.isObject(styles)){\r
+                    el.setStyle(styles);\r
+                }\r
+            }\r
+        },\r
+\r
+        /**\r
+         * Inserts an HTML fragment into the DOM.\r
+         * @param {String} where Where to insert the html in relation to el - beforeBegin, afterBegin, beforeEnd, afterEnd.\r
+         * @param {HTMLElement} el The context element\r
+         * @param {String} html The HTML fragment\r
+         * @return {HTMLElement} The new node\r
+         */\r
+        insertHtml : function(where, el, html){\r
+            var hash = {},\r
+                hashVal,\r
+                setStart,\r
+                range,\r
+                frag,\r
+                rangeEl,\r
+                rs;\r
+\r
+            where = where.toLowerCase();\r
+            // add these here because they are used in both branches of the condition.\r
+            hash[beforebegin] = ['BeforeBegin', 'previousSibling'];\r
+            hash[afterend] = ['AfterEnd', 'nextSibling'];\r
+\r
+            if (el.insertAdjacentHTML) {\r
+                if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){\r
+                    return rs;\r
+                }\r
+                // add these two to the hash.\r
+                hash[afterbegin] = ['AfterBegin', 'firstChild'];\r
+                hash[beforeend] = ['BeforeEnd', 'lastChild'];\r
+                if ((hashVal = hash[where])) {\r
+                    el.insertAdjacentHTML(hashVal[0], html);\r
+                    return el[hashVal[1]];\r
+                }\r
+            } else {\r
+                range = el.ownerDocument.createRange();\r
+                setStart = 'setStart' + (/end/i.test(where) ? 'After' : 'Before');\r
+                if (hash[where]) {\r
+                    range[setStart](el);\r
+                    frag = range.createContextualFragment(html);\r
+                    el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling);\r
+                    return el[(where == beforebegin ? 'previous' : 'next') + 'Sibling'];\r
+                } else {\r
+                    rangeEl = (where == afterbegin ? 'first' : 'last') + 'Child';\r
+                    if (el.firstChild) {\r
+                        range[setStart](el[rangeEl]);\r
+                        frag = range.createContextualFragment(html);\r
+                        if(where == afterbegin){\r
+                            el.insertBefore(frag, el.firstChild);\r
+                        }else{\r
+                            el.appendChild(frag);\r
+                        }\r
+                    } else {\r
+                        el.innerHTML = html;\r
+                    }\r
+                    return el[rangeEl];\r
+                }\r
+            }\r
+            throw 'Illegal insertion point -> "' + where + '"';\r
+        },\r
+\r
+        /**\r
+         * Creates new DOM element(s) and inserts them before el.\r
+         * @param {Mixed} el The context element\r
+         * @param {Object/String} o The DOM object spec (and children) or raw HTML blob\r
+         * @param {Boolean} returnElement (optional) true to return a Ext.Element\r
+         * @return {HTMLElement/Ext.Element} The new node\r
+         */\r
+        insertBefore : function(el, o, returnElement){\r
+            return doInsert(el, o, returnElement, beforebegin);\r
+        },\r
+\r
+        /**\r
+         * Creates new DOM element(s) and inserts them after el.\r
+         * @param {Mixed} el The context element\r
+         * @param {Object} o The DOM object spec (and children)\r
+         * @param {Boolean} returnElement (optional) true to return a Ext.Element\r
+         * @return {HTMLElement/Ext.Element} The new node\r
+         */\r
+        insertAfter : function(el, o, returnElement){\r
+            return doInsert(el, o, returnElement, afterend, 'nextSibling');\r
+        },\r
+\r
+        /**\r
+         * Creates new DOM element(s) and inserts them as the first child of el.\r
+         * @param {Mixed} el The context element\r
+         * @param {Object/String} o The DOM object spec (and children) or raw HTML blob\r
+         * @param {Boolean} returnElement (optional) true to return a Ext.Element\r
+         * @return {HTMLElement/Ext.Element} The new node\r
+         */\r
+        insertFirst : function(el, o, returnElement){\r
+            return doInsert(el, o, returnElement, afterbegin, 'firstChild');\r
+        },\r
+\r
+        /**\r
+         * Creates new DOM element(s) and appends them to el.\r
+         * @param {Mixed} el The context element\r
+         * @param {Object/String} o The DOM object spec (and children) or raw HTML blob\r
+         * @param {Boolean} returnElement (optional) true to return a Ext.Element\r
+         * @return {HTMLElement/Ext.Element} The new node\r
+         */\r
+        append : function(el, o, returnElement){\r
+            return doInsert(el, o, returnElement, beforeend, '', true);\r
+        },\r
+\r
+        /**\r
+         * Creates new DOM element(s) and overwrites the contents of el with them.\r
+         * @param {Mixed} el The context element\r
+         * @param {Object/String} o The DOM object spec (and children) or raw HTML blob\r
+         * @param {Boolean} returnElement (optional) true to return a Ext.Element\r
+         * @return {HTMLElement/Ext.Element} The new node\r
+         */\r
+        overwrite : function(el, o, returnElement){\r
+            el = Ext.getDom(el);\r
+            el.innerHTML = createHtml(o);\r
+            return returnElement ? Ext.get(el.firstChild) : el.firstChild;\r
+        },\r
+\r
+        createHtml : createHtml\r
+    };\r
+    return pub;\r
 }();/**\r
  * @class Ext.DomHelper\r
  */\r
@@ -436,7 +474,7 @@ function(){
                        }\r
                 }\r
             });\r
-            pub.applyStyles(el, o.style);\r
+            Ext.DomHelper.applyStyles(el, o.style);\r
 \r
             if ((cn = o.children || o.cn)) {\r
                 createDom(cn, el);\r
@@ -464,33 +502,6 @@ function(){
                /** True to force the use of DOM instead of html fragments @type Boolean */\r
            useDom : false,\r
 \r
-           /**\r
-            * Applies a style specification to an element.\r
-            * @param {String/HTMLElement} el The element to apply styles to\r
-            * @param {String/Object/Function} styles A style specification string e.g. 'width:100px', or object in the form {width:'100px'}, or\r
-            * a function which returns such a specification.\r
-            */\r
-           applyStyles : function(el, styles){\r
-                   if(styles){\r
-                               var i = 0,\r
-                               len,\r
-                               style;\r
-\r
-                       el = Ext.fly(el);\r
-                               if(Ext.isFunction(styles)){\r
-                                       styles = styles.call();\r
-                               }\r
-                               if(Ext.isString(styles)){\r
-                                       styles = styles.trim().split(/\s*(?::|;)\s*/);\r
-                                       for(len = styles.length; i < len;){\r
-                                               el.setStyle(styles[i++], styles[i++]);\r
-                                       }\r
-                               }else if (Ext.isObject(styles)){\r
-                                       el.setStyle(styles);\r
-                               }\r
-                       }\r
-           },\r
-\r
            /**\r
             * Creates new DOM element(s) and inserts them before el.\r
             * @param {Mixed} el The context element\r
@@ -549,19 +560,58 @@ function(){
        return pub;\r
 }());/**
  * @class Ext.Template
- * Represents an HTML fragment template. Templates can be precompiled for greater performance.
- * For a list of available format functions, see {@link Ext.util.Format}.<br />
- * Usage:
+ * <p>Represents an HTML fragment template. Templates may be {@link #compile precompiled}
+ * for greater performance.</p>
+ * <p>For example usage {@link #Template see the constructor}.</p>
+ * 
+ * @constructor
+ * An instance of this class may be created by passing to the constructor either
+ * a single argument, or multiple arguments:
+ * <div class="mdetail-params"><ul>
+ * <li><b>single argument</b> : String/Array
+ * <div class="sub-desc">
+ * The single argument may be either a String or an Array:<ul>
+ * <li><tt>String</tt> : </li><pre><code>
+var t = new Ext.Template("&lt;div>Hello {0}.&lt;/div>");
+t.{@link #append}('some-element', ['foo']);
+ * </code></pre>
+ * <li><tt>Array</tt> : </li>
+ * An Array will be combined with <code>join('')</code>.
 <pre><code>
-var t = new Ext.Template(
+var t = new Ext.Template([
     '&lt;div name="{id}"&gt;',
         '&lt;span class="{cls}"&gt;{name:trim} {value:ellipsis(10)}&lt;/span&gt;',
-    '&lt;/div&gt;'
-);
-t.append('some-element', {id: 'myid', cls: 'myclass', name: 'foo', value: 'bar'});
+    '&lt;/div&gt;',
+]);
+t.{@link #compile}();
+t.{@link #append}('some-element', {id: 'myid', cls: 'myclass', name: 'foo', value: 'bar'});
 </code></pre>
- * @constructor
- * @param {String/Array} html The HTML fragment or an array of fragments to join("") or multiple arguments to join("")
+ * </ul></div></li>
+ * <li><b>multiple arguments</b> : String, Object, Array, ...
+ * <div class="sub-desc">
+ * Multiple arguments will be combined with <code>join('')</code>.
+ * <pre><code>
+var t = new Ext.Template(
+    '&lt;div name="{id}"&gt;',
+        '&lt;span class="{cls}"&gt;{name} {value}&lt;/span&gt;',
+    '&lt;/div&gt;',
+    // a configuration object:
+    {
+        compiled: true,      // {@link #compile} immediately
+        disableFormats: true // See Notes below.
+    } 
+);
+ * </code></pre>
+ * <p><b>Notes</b>:</p>
+ * <div class="mdetail-params"><ul>
+ * <li>Formatting and <code>disableFormats</code> are not applicable for Ext Core.</li>
+ * <li>For a list of available format functions, see {@link Ext.util.Format}.</li>
+ * <li><code>disableFormats</code> reduces <code>{@link #apply}</code> time
+ * when no formatting is required.</li>
+ * </ul></div>
+ * </div></li>
+ * </ul></div>
+ * @param {Mixed} config
  */
 Ext.Template = function(html){
     var me = this,
@@ -583,14 +633,35 @@ Ext.Template = function(html){
 
     /**@private*/
     me.html = html;
+    /**
+     * @cfg {Boolean} compiled Specify <tt>true</tt> to compile the template
+     * immediately (see <code>{@link #compile}</code>).
+     * Defaults to <tt>false</tt>.
+     */
     if (me.compiled) {
         me.compile();
     }
 };
 Ext.Template.prototype = {
     /**
-     * Returns an HTML fragment of this template with the specified values applied.
-     * @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'})
+     * @cfg {RegExp} re The regular expression used to match template variables.
+     * Defaults to:<pre><code>
+     * re : /\{([\w-]+)\}/g                                     // for Ext Core
+     * re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g      // for Ext JS
+     * </code></pre>
+     */
+    re : /\{([\w-]+)\}/g,
+    /**
+     * See <code>{@link #re}</code>.
+     * @type RegExp
+     * @property re
+     */
+
+    /**
+     * 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
      */
     applyTemplate : function(values){
@@ -616,13 +687,6 @@ Ext.Template.prototype = {
         return compile ? me.compile() : me;
     },
 
-    /**
-    * The regular expression used to match template variables
-    * @type RegExp
-    * @property
-    */
-    re : /\{([\w-]+)\}/g,
-
     /**
      * Compiles the template into an internal function, eliminating the RegEx overhead.
      * @return {Ext.Template} this
@@ -676,10 +740,14 @@ Ext.Template.prototype = {
     },
 
     /**
-     * Applies the supplied values to the template and appends the new node(s) to el.
+     * 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 your params are numeric (i.e. {0}) or an object (i.e. {foo: 'bar'})
-     * @param {Boolean} returnElement (optional) true to return a Ext.Element (defaults to undefined)
+     * @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.Element (defaults to undefined)
      * @return {HTMLElement/Ext.Element} The new node or Element
      */
     append : function(el, values, returnElement){
@@ -707,8 +775,10 @@ Ext.Template.prototype = {
 };
 /**
  * Alias for {@link #applyTemplate}
- * Returns an HTML fragment of this template with the specified values applied.
- * @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'})
+ * 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
@@ -729,6 +799,39 @@ Ext.Template.from = function(el, config){
  * @class Ext.Template\r
  */\r
 Ext.apply(Ext.Template.prototype, {\r
+    /**\r
+     * @cfg {Boolean} disableFormats Specify <tt>true</tt> to disable format\r
+     * functions in the template. If the template does not contain\r
+     * {@link Ext.util.Format format functions}, setting <code>disableFormats</code>\r
+     * to true will reduce <code>{@link #apply}</code> time. Defaults to <tt>false</tt>.\r
+     * <pre><code>\r
+var t = new Ext.Template(\r
+    '&lt;div name="{id}"&gt;',\r
+        '&lt;span class="{cls}"&gt;{name} {value}&lt;/span&gt;',\r
+    '&lt;/div&gt;',\r
+    {\r
+        compiled: true,      // {@link #compile} immediately\r
+        disableFormats: true // reduce <code>{@link #apply}</code> time since no formatting\r
+    }    \r
+);\r
+     * </code></pre>\r
+     * For a list of available format functions, see {@link Ext.util.Format}.\r
+     */\r
+    disableFormats : false,                            \r
+    /**\r
+     * See <code>{@link #disableFormats}</code>.\r
+     * @type Boolean\r
+     * @property disableFormats\r
+     */\r
+\r
+    /**\r
+     * The regular expression used to match template variables\r
+     * @type RegExp\r
+     * @property\r
+     * @hide repeat doc\r
+     */\r
+    re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,\r
+\r
     /**\r
      * Returns an HTML fragment of this template with the specified values applied.\r
      * @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'})\r
@@ -771,21 +874,6 @@ Ext.apply(Ext.Template.prototype, {
         return me.html.replace(me.re, fn);\r
     },\r
                \r
-    /**\r
-     * <tt>true</tt> to disable format functions (defaults to <tt>false</tt>)\r
-     * @type Boolean\r
-     * @property\r
-     */\r
-    disableFormats : false,                            \r
-       \r
-    /**\r
-     * The regular expression used to match template variables\r
-     * @type RegExp\r
-     * @property\r
-     * @hide repeat doc\r
-     */\r
-    re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,\r
-    \r
     /**\r
      * Compiles the template into an internal function, eliminating the RegEx overhead.\r
      * @return {Ext.Template} this\r
@@ -1457,8 +1545,29 @@ Ext.DomQuery = function(){
         },\r
 \r
         /**\r
-         * Collection of "pseudo class" processors. Each processor is passed the current nodeset (array)\r
-         * and the argument (if any) supplied in the selector.\r
+         * <p>Object hash of "pseudo class" filter functions which are used when filtering selections. Each function is passed\r
+         * two parameters:</p><div class="mdetail-params"><ul>\r
+         * <li><b>c</b> : Array<div class="sub-desc">An Array of DOM elements to filter.</div></li>\r
+         * <li><b>v</b> : String<div class="sub-desc">The argument (if any) supplied in the selector.</div></li>\r
+         * </ul></div>\r
+         * <p>A filter function returns an Array of DOM elements which conform to the pseudo class.</p>\r
+         * <p>In addition to the provided pseudo classes listed above such as <code>first-child</code> and <code>nth-child</code>,\r
+         * developers may add additional, custom psuedo class filters to select elements according to application-specific requirements.</p>\r
+         * <p>For example, to filter <code>&lt;a></code> elements to only return links to <i>external</i> resources:</p>\r
+         * <code><pre>\r
+Ext.DomQuery.pseudos.external = function(c, v){\r
+    var r = [], ri = -1;\r
+    for(var i = 0, ci; ci = c[i]; i++){\r
+//      Include in result set only if it's a link to an external resource\r
+        if(ci.hostname != location.hostname){\r
+            r[++ri] = ci;\r
+        }\r
+    }\r
+    return r;\r
+};</pre></code>\r
+         * Then external links could be gathered with the following statement:<code><pre>\r
+var externalLinks = Ext.select("a:external");\r
+</code></pre>\r
          */\r
         pseudos : {\r
             "first-child" : function(c){\r
@@ -1765,216 +1874,221 @@ var combo = new Ext.form.ComboBox({
     me.events = e || {};
 };
 
-EXTUTIL.Observable.prototype = function(){
-    var filterOptRe = /^(?:scope|delay|buffer|single)$/, toLower = function(s){
-        return s.toLowerCase();
-    };
-
-    return {
-        /**
-         * <p>Fires the specified event with the passed parameters (minus the event name).</p>
-         * <p>An event may be set to bubble up an Observable parent hierarchy (See {@link Ext.Component#getBubbleTarget})
-         * by calling {@link #enableBubble}.</p>
-         * @param {String} eventName The name of the event to fire.
-         * @param {Object...} args Variable number of parameters are passed to handlers.
-         * @return {Boolean} returns false if any of the handlers return false otherwise it returns true.
-         */
+EXTUTIL.Observable.prototype = {
+    // private
+    filterOptRe : /^(?:scope|delay|buffer|single)$/,
 
-        fireEvent : function(){
-            var a = TOARRAY(arguments),
-                ename = toLower(a[0]),
-                me = this,
-                ret = TRUE,
-                ce = me.events[ename],
-                q,
-                c;
-            if (me.eventsSuspended === TRUE) {
-                if (q = me.suspendedEventsQueue) {
-                    q.push(a);
-                }
+    /**
+     * <p>Fires the specified event with the passed parameters (minus the event name).</p>
+     * <p>An event may be set to bubble up an Observable parent hierarchy (See {@link Ext.Component#getBubbleTarget})
+     * by calling {@link #enableBubble}.</p>
+     * @param {String} eventName The name of the event to fire.
+     * @param {Object...} args Variable number of parameters are passed to handlers.
+     * @return {Boolean} returns false if any of the handlers return false otherwise it returns true.
+     */
+    fireEvent : function(){
+        var a = TOARRAY(arguments),
+            ename = a[0].toLowerCase(),
+            me = this,
+            ret = TRUE,
+            ce = me.events[ename],
+            q,
+            c;
+        if (me.eventsSuspended === TRUE) {
+            if (q = me.eventQueue) {
+                q.push(a);
             }
-            else if(ISOBJECT(ce) && ce.bubble){
-                if(ce.fire.apply(ce, a.slice(1)) === FALSE) {
-                    return FALSE;
-                }
-                c = me.getBubbleTarget && me.getBubbleTarget();
-                if(c && c.enableBubble) {
+        }
+        else if(ISOBJECT(ce) && ce.bubble){
+            if(ce.fire.apply(ce, a.slice(1)) === FALSE) {
+                return FALSE;
+            }
+            c = me.getBubbleTarget && me.getBubbleTarget();
+            if(c && c.enableBubble) {
+                if(!c.events[ename] || !Ext.isObject(c.events[ename]) || !c.events[ename].bubble) {
                     c.enableBubble(ename);
-                    return c.fireEvent.apply(c, a);
                 }
+                return c.fireEvent.apply(c, a);
             }
-            else {
-                if (ISOBJECT(ce)) {
-                    a.shift();
-                    ret = ce.fire.apply(ce, a);
-                }
+        }
+        else {
+            if (ISOBJECT(ce)) {
+                a.shift();
+                ret = ce.fire.apply(ce, a);
             }
-            return ret;
-        },
+        }
+        return ret;
+    },
 
-        /**
-         * Appends an event handler to this object.
-         * @param {String}   eventName The name of the event to listen for.
-         * @param {Function} handler The method the event invokes.
-         * @param {Object}   scope (optional) The scope (<code><b>this</b></code> reference) in which the handler function is executed.
-         * <b>If omitted, defaults to the object which fired the event.</b>
-         * @param {Object}   options (optional) An object containing handler configuration.
-         * properties. This may contain any of the following properties:<ul>
-         * <li><b>scope</b> : Object<div class="sub-desc">The scope (<code><b>this</b></code> reference) in which the handler function is executed.
-         * <b>If omitted, defaults to the object which fired the event.</b></div></li>
-         * <li><b>delay</b> : Number<div class="sub-desc">The number of milliseconds to delay the invocation of the handler after the event fires.</div></li>
-         * <li><b>single</b> : Boolean<div class="sub-desc">True to add a handler to handle just the next firing of the event, and then remove itself.</div></li>
-         * <li><b>buffer</b> : Number<div class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed
-         * by the specified number of milliseconds. If the event fires again within that time, the original
-         * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</div></li>
-         * <li><b>target</b> : Observable<div class="sub-desc">Only call the handler if the event was fired on the target Observable, <i>not</i>
-         * if the event was bubbled up from a child Observable.</div></li>
-         * </ul><br>
-         * <p>
-         * <b>Combining Options</b><br>
-         * Using the options argument, it is possible to combine different types of listeners:<br>
-         * <br>
-         * A delayed, one-time listener.
-         * <pre><code>
+    /**
+     * Appends an event handler to this object.
+     * @param {String}   eventName The name of the event to listen for.
+     * @param {Function} handler The method the event invokes.
+     * @param {Object}   scope (optional) The scope (<code><b>this</b></code> reference) in which the handler function is executed.
+     * <b>If omitted, defaults to the object which fired the event.</b>
+     * @param {Object}   options (optional) An object containing handler configuration.
+     * properties. This may contain any of the following properties:<ul>
+     * <li><b>scope</b> : Object<div class="sub-desc">The scope (<code><b>this</b></code> reference) in which the handler function is executed.
+     * <b>If omitted, defaults to the object which fired the event.</b></div></li>
+     * <li><b>delay</b> : Number<div class="sub-desc">The number of milliseconds to delay the invocation of the handler after the event fires.</div></li>
+     * <li><b>single</b> : Boolean<div class="sub-desc">True to add a handler to handle just the next firing of the event, and then remove itself.</div></li>
+     * <li><b>buffer</b> : Number<div class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed
+     * by the specified number of milliseconds. If the event fires again within that time, the original
+     * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</div></li>
+     * <li><b>target</b> : Observable<div class="sub-desc">Only call the handler if the event was fired on the target Observable, <i>not</i>
+     * if the event was bubbled up from a child Observable.</div></li>
+     * </ul><br>
+     * <p>
+     * <b>Combining Options</b><br>
+     * Using the options argument, it is possible to combine different types of listeners:<br>
+     * <br>
+     * A delayed, one-time listener.
+     * <pre><code>
 myDataView.on('click', this.onClick, this, {
-    single: true,
-    delay: 100
-});</code></pre>
-         * <p>
-         * <b>Attaching multiple handlers in 1 call</b><br>
-         * The method also allows for a single argument to be passed which is a config object containing properties
-         * which specify multiple handlers.
-         * <p>
-         * <pre><code>
-myGridPanel.on({
-    'click' : {
-        fn: this.onClick,
-        scope: this,
-        delay: 100
-    },
-    'mouseover' : {
-        fn: this.onMouseOver,
-        scope: this
-    },
-    'mouseout' : {
-        fn: this.onMouseOut,
-        scope: this
-    }
+single: true,
+delay: 100
 });</code></pre>
      * <p>
-     * Or a shorthand syntax:<br>
+     * <b>Attaching multiple handlers in 1 call</b><br>
+     * The method also allows for a single argument to be passed which is a config object containing properties
+     * which specify multiple handlers.
+     * <p>
      * <pre><code>
 myGridPanel.on({
-    'click' : this.onClick,
-    'mouseover' : this.onMouseOver,
-    'mouseout' : this.onMouseOut,
-     scope: this
+'click' : {
+    fn: this.onClick,
+    scope: this,
+    delay: 100
+},
+'mouseover' : {
+    fn: this.onMouseOver,
+    scope: this
+},
+'mouseout' : {
+    fn: this.onMouseOut,
+    scope: this
+}
 });</code></pre>
-         */
-        addListener : function(eventName, fn, scope, o){
-            var me = this,
-                e,
-                oe,
-                isF,
-            ce;
-            if (ISOBJECT(eventName)) {
-                o = eventName;
-                for (e in o){
-                    oe = o[e];
-                    if (!filterOptRe.test(e)) {
-                        me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
-                    }
-                }
-            } else {
-                eventName = toLower(eventName);
-                ce = me.events[eventName] || TRUE;
-                if (typeof ce == "boolean") {
-                    me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
+ * <p>
+ * Or a shorthand syntax:<br>
+ * <pre><code>
+myGridPanel.on({
+'click' : this.onClick,
+'mouseover' : this.onMouseOver,
+'mouseout' : this.onMouseOut,
+ scope: this
+});</code></pre>
+     */
+    addListener : function(eventName, fn, scope, o){
+        var me = this,
+            e,
+            oe,
+            isF,
+        ce;
+        if (ISOBJECT(eventName)) {
+            o = eventName;
+            for (e in o){
+                oe = o[e];
+                if (!me.filterOptRe.test(e)) {
+                    me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
                 }
-                ce.addListener(fn, scope, ISOBJECT(o) ? o : {});
             }
-        },
-
-        /**
-         * Removes an event handler.
-         * @param {String}   eventName The type of event the handler was associated with.
-         * @param {Function} handler   The handler to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>
-         * @param {Object}   scope     (optional) The scope originally specified for the handler.
-         */
-        removeListener : function(eventName, fn, scope){
-            var ce = this.events[toLower(eventName)];
-            if (ISOBJECT(ce)) {
-                ce.removeListener(fn, scope);
+        } else {
+            eventName = eventName.toLowerCase();
+            ce = me.events[eventName] || TRUE;
+            if (Ext.isBoolean(ce)) {
+                me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
             }
-        },
+            ce.addListener(fn, scope, ISOBJECT(o) ? o : {});
+        }
+    },
 
-        /**
-         * Removes all listeners for this object
-         */
-        purgeListeners : function(){
-            var events = this.events,
-                evt,
-                key;
-            for(key in events){
-                evt = events[key];
-                if(ISOBJECT(evt)){
-                    evt.clearListeners();
-                }
-            }
-        },
+    /**
+     * Removes an event handler.
+     * @param {String}   eventName The type of event the handler was associated with.
+     * @param {Function} handler   The handler to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>
+     * @param {Object}   scope     (optional) The scope originally specified for the handler.
+     */
+    removeListener : function(eventName, fn, scope){
+        var ce = this.events[eventName.toLowerCase()];
+        if (ISOBJECT(ce)) {
+            ce.removeListener(fn, scope);
+        }
+    },
 
-        /**
-         * Used to define events on this Observable
-         * @param {Object} object The object with the events defined
-         */
-        addEvents : function(o){
-            var me = this;
-            me.events = me.events || {};
-            if (typeof o == 'string') {
-                EACH(arguments, function(a) {
-                    me.events[a] = me.events[a] || TRUE;
-                });
-            } else {
-                Ext.applyIf(me.events, o);
+    /**
+     * Removes all listeners for this object
+     */
+    purgeListeners : function(){
+        var events = this.events,
+            evt,
+            key;
+        for(key in events){
+            evt = events[key];
+            if(ISOBJECT(evt)){
+                evt.clearListeners();
             }
-        },
+        }
+    },
 
-        /**
-         * Checks to see if this object has any listeners for a specified event
-         * @param {String} eventName The name of the event to check for
-         * @return {Boolean} True if the event is being listened for, else false
-         */
-        hasListener : function(eventName){
-            var e = this.events[eventName];
-            return ISOBJECT(e) && e.listeners.length > 0;
-        },
+    /**
+     * Adds the specified events to the list of events which this Observable may fire.
+     * @param {Object|String} o Either an object with event names as properties with a value of <code>true</code>
+     * or the first event name string if multiple event names are being passed as separate parameters.
+     * @param {string} Optional. Event name if multiple event names are being passed as separate parameters.
+     * Usage:<pre><code>
+this.addEvents('storeloaded', 'storecleared');
+</code></pre>
+     */
+    addEvents : function(o){
+        var me = this;
+        me.events = me.events || {};
+        if (Ext.isString(o)) {
+            EACH(arguments, function(a) {
+                me.events[a] = me.events[a] || TRUE;
+            });
+        } else {
+            Ext.applyIf(me.events, o);
+        }
+    },
 
-        /**
-         * Suspend the firing of all events. (see {@link #resumeEvents})
-         * @param {Boolean} queueSuspended Pass as true to queue up suspended events to be fired
-         * after the {@link #resumeEvents} call instead of discarding all suspended events;
-         */
-        suspendEvents : function(queueSuspended){
-            this.eventsSuspended = TRUE;
-            if (queueSuspended){
-                this.suspendedEventsQueue = [];
-            }
-        },
+    /**
+     * Checks to see if this object has any listeners for a specified event
+     * @param {String} eventName The name of the event to check for
+     * @return {Boolean} True if the event is being listened for, else false
+     */
+    hasListener : function(eventName){
+        var e = this.events[eventName];
+        return ISOBJECT(e) && e.listeners.length > 0;
+    },
 
-        /**
-         * Resume firing events. (see {@link #suspendEvents})
-         * If events were suspended using the <tt><b>queueSuspended</b></tt> parameter, then all
-         * events fired during event suspension will be sent to any listeners now.
-         */
-        resumeEvents : function(){
-            var me = this;
-            me.eventsSuspended = !delete me.suspendedEventQueue;
-            EACH(me.suspendedEventsQueue, function(e) {
-                me.fireEvent.apply(me, e);
-            });
+    /**
+     * Suspend the firing of all events. (see {@link #resumeEvents})
+     * @param {Boolean} queueSuspended Pass as true to queue up suspended events to be fired
+     * after the {@link #resumeEvents} call instead of discarding all suspended events;
+     */
+    suspendEvents : function(queueSuspended){
+        this.eventsSuspended = TRUE;
+        if(queueSuspended && !this.eventQueue){
+            this.eventQueue = [];
         }
+    },
+
+    /**
+     * Resume firing events. (see {@link #suspendEvents})
+     * If events were suspended using the <tt><b>queueSuspended</b></tt> parameter, then all
+     * events fired during event suspension will be sent to any listeners now.
+     */
+    resumeEvents : function(){
+        var me = this,
+            queued = me.eventQueue || [];
+        me.eventsSuspended = FALSE;
+        delete me.eventQueue;
+        EACH(queued, function(e) {
+            me.fireEvent.apply(me, e);
+        });
     }
-}();
+};
 
 var OBSERVABLE = EXTUTIL.Observable.prototype;
 /**
@@ -2247,21 +2361,56 @@ Ext.apply(Ext.util.Observable.prototype, function(){
         },\r
         \r
         /**\r
-         * Used to enable bubbling of events\r
-         * @param {Object} events\r
+         * <p>Enables events fired by this Observable to bubble up an owner hierarchy by calling\r
+         * <code>this.getBubbleTarget()</code> if present. There is no implementation in the Observable base class.</p>\r
+         * <p>This is commonly used by Ext.Components to bubble events to owner Containers. See {@link Ext.Component.getBubbleTarget}. The default\r
+         * implementation in Ext.Component returns the Component's immediate owner. But if a known target is required, this can be overridden to\r
+         * access the required target more quickly.</p>\r
+         * <p>Example:</p><pre><code>\r
+Ext.override(Ext.form.Field, {\r
+//  Add functionality to Field's initComponent to enable the change event to bubble\r
+    initComponent: Ext.form.Field.prototype.initComponent.createSequence(function() {\r
+        this.enableBubble('change');\r
+    }),\r
+\r
+//  We know that we want Field's events to bubble directly to the FormPanel.\r
+    getBubbleTarget: function() {\r
+        if (!this.formPanel) {\r
+            this.formPanel = this.findParentByType('form');\r
+        }\r
+        return this.formPanel;\r
+    }\r
+});\r
+\r
+var myForm = new Ext.formPanel({\r
+    title: 'User Details',\r
+    items: [{\r
+        ...\r
+    }],\r
+    listeners: {\r
+        change: function() {\r
+//          Title goes red if form has been modified.\r
+            myForm.header.setStyle("color", "red");\r
+        }\r
+    }\r
+});\r
+</code></pre>\r
+         * @param {Object} events The event name to bubble, or an Array of event names.\r
          */\r
         enableBubble: function(events){\r
             var me = this;\r
-            events = Ext.isArray(events) ? events : Ext.toArray(arguments);\r
-            Ext.each(events, function(ename){\r
-                ename = ename.toLowerCase();\r
-                var ce = me.events[ename] || true;\r
-                if (typeof ce == "boolean") {\r
-                    ce = new Ext.util.Event(me, ename);\r
-                    me.events[ename] = ce;\r
-                }\r
-                ce.bubble = true;\r
-            });\r
+            if(!Ext.isEmpty(events)){\r
+                events = Ext.isArray(events) ? events : Ext.toArray(arguments);\r
+                Ext.each(events, function(ename){\r
+                    ename = ename.toLowerCase();\r
+                    var ce = me.events[ename] || true;\r
+                    if (Ext.isBoolean(ce)) {\r
+                        ce = new Ext.util.Event(me, ename);\r
+                        me.events[ename] = ce;\r
+                    }\r
+                    ce.bubble = true;\r
+                });\r
+            }\r
         }\r
     };\r
 }());\r
@@ -2309,21 +2458,21 @@ Ext.util.Observable.observeClass = function(c){
  */
 Ext.EventManager = function(){
     var docReadyEvent, 
-       docReadyProcId, 
-       docReadyState = false,          
-       E = Ext.lib.Event,
-       D = Ext.lib.Dom,
-       DOC = document,
-       WINDOW = window,
-       IEDEFERED = "ie-deferred-loader",
-       DOMCONTENTLOADED = "DOMContentLoaded",
-       elHash = {},
-       propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
+        docReadyProcId, 
+        docReadyState = false,        
+        E = Ext.lib.Event,
+        D = Ext.lib.Dom,
+        DOC = document,
+        WINDOW = window,
+        IEDEFERED = "ie-deferred-loader",
+        DOMCONTENTLOADED = "DOMContentLoaded",
+        elHash = {},
+        propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
 
     /// There is some jquery work around stuff here that isn't needed in Ext Core.
-    function addListener(el, ename, fn, wrap, scope){      
+    function addListener(el, ename, fn, wrap, scope){        
         var id = Ext.id(el),
-               es = elHash[id] = elHash[id] || {};             
+            es = elHash[id] = elHash[id] || {};         
        
         (es[ename] = es[ename] || []).push([fn, wrap, scope]);
         E.on(el, ename, wrap);
@@ -2331,10 +2480,10 @@ Ext.EventManager = function(){
         // this is a workaround for jQuery and should somehow be removed from Ext Core in the future
         // without breaking ExtJS.
         if(ename == "mousewheel" && el.addEventListener){ // workaround for jQuery
-               var args = ["DOMMouseScroll", wrap, false];
-               el.addEventListener.apply(el, args);
+            var args = ["DOMMouseScroll", wrap, false];
+            el.addEventListener.apply(el, args);
             E.on(window, 'unload', function(){
-                   el.removeEventListener.apply(el, args);                
+                el.removeEventListener.apply(el, args);                
             });
         }
         if(ename == "mousedown" && el == document){ // fix stopped mousedowns on the document
@@ -2366,8 +2515,8 @@ Ext.EventManager = function(){
     };
 
     function initDocReady(){
-           var COMPLETE = "complete";
-               
+        var COMPLETE = "complete";
+            
         docReadyEvent = new Ext.util.Event();
         if (Ext.isGecko || Ext.isOpera) {
             DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
@@ -2391,7 +2540,7 @@ Ext.EventManager = function(){
 
     function createTargeted(h, o){
         return function(){
-               var args = Ext.toArray(arguments);
+            var args = Ext.toArray(arguments);
             if(o.target == Ext.EventObject.setEvent(args[0]).target){
                 h.apply(this, args);
             }
@@ -2425,8 +2574,8 @@ Ext.EventManager = function(){
 
     function listen(element, ename, opt, fn, scope){
         var o = !Ext.isObject(opt) ? {} : opt,
-               el = Ext.getDom(element);
-               
+            el = Ext.getDom(element);
+            
         fn = fn || o.fn; 
         scope = scope || o.scope;
         
@@ -2480,112 +2629,115 @@ Ext.EventManager = function(){
     };
 
     var pub = {
-           /**
-            * Appends an event handler to an element.  The shorthand version {@link #on} is equivalent.  Typically you will
-            * use {@link Ext.Element#addListener} directly on an Element in favor of calling this version.
-            * @param {String/HTMLElement} el The html element or id to assign the event handler to
-            * @param {String} eventName The type of event to listen for
-            * @param {Function} handler The handler function the event invokes This function is passed
-            * the following parameters:<ul>
-            * <li>evt : EventObject<div class="sub-desc">The {@link Ext.EventObject EventObject} describing the event.</div></li>
-            * <li>t : Element<div class="sub-desc">The {@link Ext.Element Element} which was the target of the event.
-            * Note that this may be filtered by using the <tt>delegate</tt> option.</div></li>
-            * <li>o : Object<div class="sub-desc">The options object from the addListener call.</div></li>
-            * </ul>
-            * @param {Object} scope (optional) The scope (<b><code>this</code></b> reference) in which the handler function is executed. <b>Defaults to the Element</b>.
-            * @param {Object} options (optional) An object containing handler configuration properties.
-            * This may contain any of the following properties:<ul>
-            * <li>scope : Object<div class="sub-desc">The scope (<b><code>this</code></b> reference) in which the handler function is executed. <b>Defaults to the Element</b>.</div></li>
-            * <li>delegate : String<div class="sub-desc">A simple selector to filter the target or look for a descendant of the target</div></li>
-            * <li>stopEvent : Boolean<div class="sub-desc">True to stop the event. That is stop propagation, and prevent the default action.</div></li>
-            * <li>preventDefault : Boolean<div class="sub-desc">True to prevent the default action</div></li>
-            * <li>stopPropagation : Boolean<div class="sub-desc">True to prevent event propagation</div></li>
-            * <li>normalized : Boolean<div class="sub-desc">False to pass a browser event to the handler function instead of an Ext.EventObject</div></li>
-            * <li>delay : Number<div class="sub-desc">The number of milliseconds to delay the invocation of the handler after te event fires.</div></li>
-            * <li>single : Boolean<div class="sub-desc">True to add a handler to handle just the next firing of the event, and then remove itself.</div></li>
-            * <li>buffer : Number<div class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed
-            * by the specified number of milliseconds. If the event fires again within that time, the original
-            * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</div></li>
-            * <li>target : Element<div class="sub-desc">Only call the handler if the event was fired on the target Element, <i>not</i> if the event was bubbled up from a child node.</div></li>
-            * </ul><br>
-            * <p>See {@link Ext.Element#addListener} for examples of how to use these options.</p>
-            */
-               addListener : function(element, eventName, fn, scope, options){                                              
+        /**
+         * Appends an event handler to an element.  The shorthand version {@link #on} is equivalent.  Typically you will
+         * use {@link Ext.Element#addListener} directly on an Element in favor of calling this version.
+         * @param {String/HTMLElement} el The html element or id to assign the event handler to.
+         * @param {String} eventName The name of the event to listen for.
+         * @param {Function} handler The handler function the event invokes. This function is passed
+         * the following parameters:<ul>
+         * <li>evt : EventObject<div class="sub-desc">The {@link Ext.EventObject EventObject} describing the event.</div></li>
+         * <li>t : Element<div class="sub-desc">The {@link Ext.Element Element} which was the target of the event.
+         * Note that this may be filtered by using the <tt>delegate</tt> option.</div></li>
+         * <li>o : Object<div class="sub-desc">The options object from the addListener call.</div></li>
+         * </ul>
+         * @param {Object} scope (optional) The scope (<b><code>this</code></b> reference) in which the handler function is executed. <b>Defaults to the Element</b>.
+         * @param {Object} options (optional) An object containing handler configuration properties.
+         * This may contain any of the following properties:<ul>
+         * <li>scope : Object<div class="sub-desc">The scope (<b><code>this</code></b> reference) in which the handler function is executed. <b>Defaults to the Element</b>.</div></li>
+         * <li>delegate : String<div class="sub-desc">A simple selector to filter the target or look for a descendant of the target</div></li>
+         * <li>stopEvent : Boolean<div class="sub-desc">True to stop the event. That is stop propagation, and prevent the default action.</div></li>
+         * <li>preventDefault : Boolean<div class="sub-desc">True to prevent the default action</div></li>
+         * <li>stopPropagation : Boolean<div class="sub-desc">True to prevent event propagation</div></li>
+         * <li>normalized : Boolean<div class="sub-desc">False to pass a browser event to the handler function instead of an Ext.EventObject</div></li>
+         * <li>delay : Number<div class="sub-desc">The number of milliseconds to delay the invocation of the handler after te event fires.</div></li>
+         * <li>single : Boolean<div class="sub-desc">True to add a handler to handle just the next firing of the event, and then remove itself.</div></li>
+         * <li>buffer : Number<div class="sub-desc">Causes the handler to be scheduled to run in an {@link Ext.util.DelayedTask} delayed
+         * by the specified number of milliseconds. If the event fires again within that time, the original
+         * handler is <em>not</em> invoked, but the new handler is scheduled in its place.</div></li>
+         * <li>target : Element<div class="sub-desc">Only call the handler if the event was fired on the target Element, <i>not</i> if the event was bubbled up from a child node.</div></li>
+         * </ul><br>
+         * <p>See {@link Ext.Element#addListener} for examples of how to use these options.</p>
+         */
+        addListener : function(element, eventName, fn, scope, options){                                       
             if(Ext.isObject(eventName)){                
-                   var o = eventName, e, val;
+                var o = eventName, e, val;
                 for(e in o){
-                       val = o[e];
-                    if(!propRe.test(e)){                                                
-                           if(Ext.isFunction(val)){
-                               // shared options
-                               listen(element, e, o, val, o.scope);
-                           }else{
-                               // individual options
-                               listen(element, e, val);
-                           }
+                    val = o[e];
+                    if(!propRe.test(e)){                                             
+                        if(Ext.isFunction(val)){
+                            // shared options
+                            listen(element, e, o, val, o.scope);
+                        }else{
+                            // individual options
+                            listen(element, e, val);
+                        }
                     }
                 }
             } else {
-               listen(element, eventName, options, fn, scope);
-               }
+                listen(element, eventName, options, fn, scope);
+            }
         },
         
         /**
          * Removes an event handler from an element.  The shorthand version {@link #un} is equivalent.  Typically
          * you will use {@link Ext.Element#removeListener} directly on an Element in favor of calling this version.
-         * @param {String/HTMLElement} el The id or html element from which to remove the event
-         * @param {String} eventName The type of event
-         * @param {Function} fn The handler function to remove
+         * @param {String/HTMLElement} el The id or html element from which to remove the listener.
+         * @param {String} eventName The name of the event.
+         * @param {Function} fn The handler function to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>
+         * @param {Object} scope If a scope (<b><code>this</code></b> reference) was specified when the listener was added,
+         * then this must refer to the same object.
          */
         removeListener : function(element, eventName, fn, scope){            
             var el = Ext.getDom(element),
                 id = Ext.id(el),
-                   wrap;      
-               
-               Ext.each((elHash[id] || {})[eventName], function (v,i,a) {
-                           if (Ext.isArray(v) && v[0] == fn && (!scope || v[2] == scope)) {                                                    
-                               E.un(el, eventName, wrap = v[1]);
-                               a.splice(i,1);
-                               return false;                           
-                       }
-               });     
+                wrap;      
+            
+            Ext.each((elHash[id] || {})[eventName], function (v,i,a) {
+                if (Ext.isArray(v) && v[0] == fn && (!scope || v[2] == scope)) {                                    
+                    E.un(el, eventName, wrap = v[1]);
+                    a.splice(i,1);
+                    return false;                    
+                }
+            });    
 
             // jQuery workaround that should be removed from Ext Core
-               if(eventName == "mousewheel" && el.addEventListener && wrap){
-                   el.removeEventListener("DOMMouseScroll", wrap, false);
-               }
-                       
-               if(eventName == "mousedown" && el == DOC && wrap){ // fix stopped mousedowns on the document
-                   Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
-               }
+            if(eventName == "mousewheel" && el.addEventListener && wrap){
+                el.removeEventListener("DOMMouseScroll", wrap, false);
+            }
+                        
+            if(eventName == "mousedown" && el == DOC && wrap){ // fix stopped mousedowns on the document
+                Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
+            }
         },
         
         /**
          * Removes all event handers from an element.  Typically you will use {@link Ext.Element#removeAllListeners}
          * directly on an Element in favor of calling this version.
-         * @param {String/HTMLElement} el The id or html element from which to remove the event
+         * @param {String/HTMLElement} el The id or html element from which to remove all event handlers.
          */
         removeAll : function(el){
-               var id = Ext.id(el = Ext.getDom(el)), 
-                               es = elHash[id],                                
-                               ename;
-              
-               for(ename in es){
-                   if(es.hasOwnProperty(ename)){                           
-                       Ext.each(es[ename], function(v) {
-                           E.un(el, ename, v.wrap);                    
-                       });
-                   }            
-               }
-               elHash[id] = null;       
+            var id = Ext.id(el = Ext.getDom(el)), 
+                es = elHash[id],                 
+                ename;
+           
+            for(ename in es){
+                if(es.hasOwnProperty(ename)){                        
+                    Ext.each(es[ename], function(v) {
+                        E.un(el, ename, v.wrap);                    
+                    });
+                }            
+            }
+            elHash[id] = null;       
         },
 
         /**
-         * Fires when the document is ready (before onload and before images are loaded). Can be
+         * Adds a listener to be notified when the document is ready (before onload and before images are loaded). Can be
          * accessed shorthanded as Ext.onReady().
-         * @param {Function} fn The method the event invokes
-         * @param {Object} scope (optional) An object that becomes the scope of the handler
-         * @param {boolean} options (optional) An object containing standard {@link #addListener} options
+         * @param {Function} fn The method the event invokes.
+         * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the handler function executes. Defaults to the browser window.
+         * @param {boolean} options (optional) Options object as passed to {@link Ext.Element#addListener}. It is recommended that the options
+         * <code>{single: true}</code> be used so that the handler is removed on first invocation.
          */
         onDocumentReady : function(fn, scope, options){
             if(docReadyState){ // if it already fired
@@ -2595,8 +2747,8 @@ Ext.EventManager = function(){
             } else {
                 if(!docReadyEvent) initDocReady();
                 options = options || {};
-                   options.delay = options.delay || 1;             
-                   docReadyEvent.addListener(fn, scope, options);
+                options.delay = options.delay || 1;                
+                docReadyEvent.addListener(fn, scope, options);
             }
         },
         
@@ -2605,10 +2757,9 @@ Ext.EventManager = function(){
      /**
      * Appends an event handler to an element.  Shorthand for {@link #addListener}.
      * @param {String/HTMLElement} el The html element or id to assign the event handler to
-     * @param {String} eventName The type of event to listen for
-     * @param {Function} handler The handler function the event invokes
-     * @param {Object} scope (optional) The scope in which to execute the handler
-     * function (the handler function's "this" context)
+     * @param {String} eventName The name of the event to listen for.
+     * @param {Function} handler The handler function the event invokes.
+     * @param {Object} scope (optional) (<code>this</code> reference) in which the handler function executes. <b>Defaults to the Element</b>.
      * @param {Object} options (optional) An object containing standard {@link #addListener} options
      * @member Ext.EventManager
      * @method on
@@ -2616,10 +2767,11 @@ Ext.EventManager = function(){
     pub.on = pub.addListener;
     /**
      * Removes an event handler from an element.  Shorthand for {@link #removeListener}.
-     * @param {String/HTMLElement} el The id or html element from which to remove the event
-     * @param {String} eventName The type of event
-     * @param {Function} fn The handler function to remove
-     * @return {Boolean} True if a listener was actually removed, else false
+     * @param {String/HTMLElement} el The id or html element from which to remove the listener.
+     * @param {String} eventName The name of the event.
+     * @param {Function} fn The handler function to remove. <b>This must be a reference to the function passed into the {@link #on} call.</b>
+     * @param {Object} scope If a scope (<b><code>this</code></b> reference) was specified when the listener was added,
+     * then this must refer to the same object.
      * @member Ext.EventManager
      * @method un
      */
@@ -2629,10 +2781,11 @@ Ext.EventManager = function(){
     return pub;
 }();
 /**
-  * Fires when the document is ready (before onload and before images are loaded).  Shorthand of {@link Ext.EventManager#onDocumentReady}.
-  * @param {Function} fn The method the event invokes
-  * @param {Object} scope An object that becomes the scope of the handler
-  * @param {boolean} options (optional) An object containing standard {@link #addListener} options
+  * Adds a listener to be notified when the document is ready (before onload and before images are loaded). Shorthand of {@link Ext.EventManager#onDocumentReady}.
+  * @param {Function} fn The method the event invokes.
+  * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the handler function executes. Defaults to the browser window.
+  * @param {boolean} options (optional) Options object as passed to {@link Ext.Element#addListener}. It is recommended that the options
+  * <code>{single: true}</code> be used so that the handler is removed on first invocation.
   * @member Ext
   * @method onReady
  */
@@ -2707,21 +2860,21 @@ Ext.EventManager.addListener("myDiv", 'click', handleClick);
  */
 Ext.EventObject = function(){
     var E = Ext.lib.Event,
-       // safari keypress events for special keys return bad keycodes
-       safariKeys = {
-               3 : 13, // enter
-               63234 : 37, // left
-               63235 : 39, // right
-               63232 : 38, // up
-               63233 : 40, // down
-               63276 : 33, // page up
-               63277 : 34, // page down
-               63272 : 46, // delete
-               63273 : 36, // home
-               63275 : 35  // end
-       },
-       // normalize button clicks
-       btnMap = Ext.isIE ? {1:0,4:1,2:2} :
+        // safari keypress events for special keys return bad keycodes
+        safariKeys = {
+            3 : 13, // enter
+            63234 : 37, // left
+            63235 : 39, // right
+            63232 : 38, // up
+            63233 : 40, // down
+            63276 : 33, // page up
+            63277 : 34, // page down
+            63272 : 46, // delete
+            63273 : 36, // home
+            63275 : 35  // end
+        },
+        // normalize button clicks
+        btnMap = Ext.isIE ? {1:0,4:1,2:2} :
                 (Ext.isWebKit ? {1:0,2:1,3:2} : {0:0,1:1,2:2});
 
     Ext.EventObjectImpl = function(e){
@@ -2733,7 +2886,7 @@ Ext.EventObject = function(){
     Ext.EventObjectImpl.prototype = {
            /** @private */
         setEvent : function(e){
-               var me = this;
+            var me = this;
             if(e == me || (e && e.browserEvent)){ // already wrapped
                 return e;
             }
@@ -2773,7 +2926,7 @@ Ext.EventObject = function(){
          * Stop the event (preventDefault and stopPropagation)
          */
         stopEvent : function(){
-               var me = this;
+            var me = this;
             if(me.browserEvent){
                 if(me.browserEvent.type == 'mousedown'){
                     Ext.EventManager.stoppedMouseDownEvent.fire(me);
@@ -2795,7 +2948,7 @@ Ext.EventObject = function(){
          * Cancels bubbling of the event.
          */
         stopPropagation : function(){
-               var me = this;
+            var me = this;
             if(me.browserEvent){
                 if(me.browserEvent.type == 'mousedown'){
                     Ext.EventManager.stoppedMouseDownEvent.fire(me);
@@ -2819,11 +2972,11 @@ Ext.EventObject = function(){
         getKey : function(){
             return this.normalizeKey(this.keyCode || this.charCode)
         },
-               
-               // private
-               normalizeKey: function(k){
-                       return Ext.isSafari ? (safariKeys[k] || k) : k; 
-               },
+        
+        // private
+        normalizeKey: function(k){
+            return Ext.isSafari ? (safariKeys[k] || k) : k; 
+        },
 
         /**
          * Gets the x coordinate of the event.
@@ -2883,37 +3036,37 @@ Ext.EventObject = function(){
             }
             return delta;
         },
-               
-               /**
-               * Returns true if the target of this event is a child of el.  Unless the allowEl parameter is set, it will return false if if the target is el.
-               * Example usage:<pre><code>
-               // Handle click on any child of an element
-               Ext.getBody().on('click', function(e){
-                       if(e.within('some-el')){
-                               alert('Clicked on a child of some-el!');
-                       }
-               });
-               
-               // Handle click directly on an element, ignoring clicks on child nodes
-               Ext.getBody().on('click', function(e,t){
-                       if((t.id == 'some-el') && !e.within(t, true)){
-                               alert('Clicked directly on some-el!');
-                       }
-               });
-               </code></pre>
-                * @param {Mixed} el The id, DOM element or Ext.Element to check
-                * @param {Boolean} related (optional) true to test if the related target is within el instead of the target
-                * @param {Boolean} allowEl {optional} true to also check if the passed element is the target or related target
-                * @return {Boolean}
-                */
-               within : function(el, related, allowEl){
+        
+        /**
+        * Returns true if the target of this event is a child of el.  Unless the allowEl parameter is set, it will return false if if the target is el.
+        * Example usage:<pre><code>
+        // Handle click on any child of an element
+        Ext.getBody().on('click', function(e){
+            if(e.within('some-el')){
+                alert('Clicked on a child of some-el!');
+            }
+        });
+        
+        // Handle click directly on an element, ignoring clicks on child nodes
+        Ext.getBody().on('click', function(e,t){
+            if((t.id == 'some-el') && !e.within(t, true)){
+                alert('Clicked directly on some-el!');
+            }
+        });
+        </code></pre>
+         * @param {Mixed} el The id, DOM element or Ext.Element to check
+         * @param {Boolean} related (optional) true to test if the related target is within el instead of the target
+         * @param {Boolean} allowEl {optional} true to also check if the passed element is the target or related target
+         * @return {Boolean}
+         */
+        within : function(el, related, allowEl){
             if(el){
-                           var t = this[related ? "getRelatedTarget" : "getTarget"]();
-                           return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
+                var t = this[related ? "getRelatedTarget" : "getTarget"]();
+                return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
             }
             return false;
-               }
-        };
+        }
+     };
 
     return new Ext.EventObjectImpl();
 }();/**\r
@@ -2932,8 +3085,8 @@ Ext.apply(Ext.EventManager, function(){
         // note 1: IE fires ONLY the keydown event on specialkey autorepeat\r
         // note 2: Safari < 3.1, Gecko (Mac/Linux) & Opera fire only the keypress event on specialkey autorepeat\r
         // (research done by @Jan Wolter at http://unixpapa.com/js/key.html)\r
-        useKeydown = Ext.isSafari ? \r
-                    Ext.num(navigator.userAgent.toLowerCase().match(/version\/(\d+\.\d)/)[1] || 2) >= 3.1 :\r
+        useKeydown = Ext.isWebKit ? \r
+                    Ext.num(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) >= 525 :\r
                     !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera);\r
        \r
        return { \r
@@ -3371,7 +3524,7 @@ El.prototype = {
             }\r
         }\r
         if(o.style){\r
-            Ext.DomHelper.applyStyles(el, o.style);\r
+            DH.applyStyles(el, o.style);\r
         }\r
         return this;\r
     },\r
@@ -3384,6 +3537,13 @@ El.prototype = {
      * @param {HtmlElement} t The target of the event.\r
      * @param {Object} o The options configuration passed to the {@link #addListener} call.\r
      */\r
+    /**\r
+     * @event contextmenu\r
+     * Fires when a right click is detected within the element.\r
+     * @param {Ext.EventObject} e The {@link Ext.EventObject} encapsulating the DOM event.\r
+     * @param {HtmlElement} t The target of the event.\r
+     * @param {Object} o The options configuration passed to the {@link #addListener} call.\r
+     */\r
     /**\r
      * @event dblclick\r
      * Fires when a mouse double click is detected within the element.\r
@@ -3683,11 +3843,11 @@ El.prototype = {
 \r
     /**\r
      * Appends an event handler to this element.  The shorthand version {@link #on} is equivalent.\r
-     * @param {String} eventName The type of event to handle\r
+     * @param {String} eventName The name of event to handle.\r
      * @param {Function} fn The handler function the event invokes. This function is passed\r
      * the following parameters:<ul>\r
      * <li><b>evt</b> : EventObject<div class="sub-desc">The {@link Ext.EventObject EventObject} describing the event.</div></li>\r
-     * <li><b>el</b> : Element<div class="sub-desc">The {@link Ext.Element Element} which was the target of the event.\r
+     * <li><b>el</b> : HtmlElement<div class="sub-desc">The DOM element which was the target of the event.\r
      * Note that this may be filtered by using the <tt>delegate</tt> option.</div></li>\r
      * <li><b>o</b> : Object<div class="sub-desc">The options object from the addListener call.</div></li>\r
      * </ul>\r
@@ -3801,10 +3961,10 @@ el.removeListener('click', this.handlerFn);
 // or\r
 el.un('click', this.handlerFn);\r
 </code></pre>\r
-     * @param {String} eventName the type of event to remove\r
-     * @param {Function} fn the method the event invokes\r
-     * @param {Object} scope (optional) The scope (The <tt>this</tt> reference) of the handler function. Defaults\r
-     * to this Element.\r
+     * @param {String} eventName The name of the event from which to remove the handler.\r
+     * @param {Function} fn The handler function to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>\r
+     * @param {Object} scope If a scope (<b><code>this</code></b> reference) was specified when the listener was added,\r
+     * then this must refer to the same object.\r
      * @return {Ext.Element} this\r
      */\r
     removeListener : function(eventName, fn, scope){\r
@@ -3868,16 +4028,19 @@ el.un('click', this.handlerFn);
             dom = me.dom;\r
         \r
         me.removeAllListeners();\r
-        delete El.cache[dom.id];\r
-        delete El.dataCache[dom.id]\r
-        Ext.removeNode(dom);\r
+        if (dom) {\r
+            delete me.dom;\r
+            delete El.cache[dom.id];\r
+            delete El.dataCache[dom.id];\r
+            Ext.removeNode(dom);\r
+        }\r
     },\r
 \r
     /**\r
      * Sets up event handlers to call the passed functions when the mouse is moved into and out of the Element.\r
      * @param {Function} overFn The function to call when the mouse enters the Element.\r
      * @param {Function} outFn The function to call when the mouse leaves the Element.\r
-     * @param {Object} scope (optional) The scope (<tt>this</tt> reference) in which the functions are executed. Defaults to the Element's DOM element.\r
+     * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the functions are executed. Defaults to the Element's DOM element.\r
      * @param {Object} options (optional) Options for the listener. See {@link Ext.util.Observable#addListener the <tt>options</tt> parameter}.\r
      * @return {Ext.Element} this\r
      */\r
@@ -3933,7 +4096,9 @@ el.un('click', this.handlerFn);
     * @return {Ext.Element} this\r
      */\r
     update : function(html) {\r
-        this.dom.innerHTML = html;\r
+        if (this.dom) {\r
+            this.dom.innerHTML = html;\r
+        }\r
         return this;\r
     }\r
 };\r
@@ -3946,9 +4111,9 @@ El.addMethods = function(o){
 \r
 /**\r
  * Appends an event handler (shorthand for {@link #addListener}).\r
- * @param {String} eventName The type of event to handle\r
- * @param {Function} fn The handler function the event invokes\r
- * @param {Object} scope (optional) The scope (this element) of the handler function\r
+ * @param {String} eventName The name of event to handle.\r
+ * @param {Function} fn The handler function the event invokes.\r
+ * @param {Object} scope (optional) The scope (<code>this</code> reference) in which the handler function is executed.\r
  * @param {Object} options (optional) An object containing standard {@link #addListener} options\r
  * @member Ext.Element\r
  * @method on\r
@@ -3957,10 +4122,10 @@ ep.on = ep.addListener;
 \r
 /**\r
  * Removes an event handler from this element (see {@link #removeListener} for additional notes).\r
- * @param {String} eventName the type of event to remove\r
- * @param {Function} fn the method the event invokes\r
- * @param {Object} scope (optional) The scope (The <tt>this</tt> reference) of the handler function. Defaults\r
- * to this Element.\r
+ * @param {String} eventName The name of the event from which to remove the handler.\r
+ * @param {Function} fn The handler function to remove. <b>This must be a reference to the function passed into the {@link #addListener} call.</b>\r
+ * @param {Object} scope If a scope (<b><code>this</code></b> reference) was specified when the listener was added,\r
+ * then this must refer to the same object.\r
  * @return {Ext.Element} this\r
  * @member Ext.Element\r
  * @method un\r
@@ -4053,7 +4218,7 @@ El.data = function(el, key, value){
     if(arguments.length == 2){\r
         return c[key];    \r
     }else{\r
-        c[key] = value;\r
+        return (c[key] = value);\r
     }\r
 };\r
 \r
@@ -4907,10 +5072,7 @@ Ext.Element.addMethods(
 function() {\r
        var GETDOM = Ext.getDom,\r
                GET = Ext.get,\r
-               DH = Ext.DomHelper,\r
-        isEl = function(el){\r
-            return  (el.nodeType || el.dom || typeof el == 'string');  \r
-        };\r
+               DH = Ext.DomHelper;\r
        \r
        return {\r
            /**\r
@@ -4959,14 +5121,14 @@ function() {
             */\r
            insertFirst: function(el, returnDom){\r
             el = el || {};\r
-            if(isEl(el)){ // element\r
+            if(el.nodeType || el.dom || typeof el == 'string'){ // element\r
                 el = GETDOM(el);\r
                 this.dom.insertBefore(el, this.dom.firstChild);\r
                 return !returnDom ? GET(el) : el;\r
             }else{ // dh config\r
                 return this.createChild(el, this.dom.firstChild, returnDom);\r
             }\r
-    },\r
+        },\r
        \r
            /**\r
             * Replaces the passed element with this element\r
@@ -4988,7 +5150,7 @@ function() {
            replaceWith: function(el){\r
                    var me = this,\r
                        Element = Ext.Element;\r
-            if(isEl(el)){\r
+            if(el.nodeType || el.dom || typeof el == 'string'){\r
                 el = GETDOM(el);\r
                 me.dom.parentNode.insertBefore(el, me.dom);\r
             }else{\r
@@ -5085,556 +5247,565 @@ Ext.apply(Ext.Element.prototype, function() {
                return rt;\r
            }\r
     };\r
-}());/**\r
+}());/**
+ * @class Ext.Element
+ */
+Ext.Element.addMethods(function(){  
+    // local style camelizing for speed
+    var propCache = {},
+        camelRe = /(-[a-z])/gi,
+        classReCache = {},
+        view = document.defaultView,
+        propFloat = Ext.isIE ? 'styleFloat' : 'cssFloat',
+        opacityRe = /alpha\(opacity=(.*)\)/i,
+        trimRe = /^\s+|\s+$/g,
+        EL = Ext.Element,   
+        PADDING = "padding",
+        MARGIN = "margin",
+        BORDER = "border",
+        LEFT = "-left",
+        RIGHT = "-right",
+        TOP = "-top",
+        BOTTOM = "-bottom",
+        WIDTH = "-width",    
+        MATH = Math,
+        HIDDEN = 'hidden',
+        ISCLIPPED = 'isClipped',
+        OVERFLOW = 'overflow',
+        OVERFLOWX = 'overflow-x',
+        OVERFLOWY = 'overflow-y',
+        ORIGINALCLIP = 'originalClip',
+        // special markup used throughout Ext when box wrapping elements    
+        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.Element.data;
+        
+    
+    // private  
+    function camelFn(m, a) {
+        return a.charAt(1).toUpperCase();
+    }
+    
+    function chkCache(prop) {
+        return propCache[prop] || (propCache[prop] = prop == 'float' ? propFloat : prop.replace(camelRe, camelFn));
+    }
+            
+    return {
+        // private  ==> used by Fx  
+        adjustWidth : function(width) {
+            var me = this;
+            var isNum = Ext.isNumber(width);
+            if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
+               width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
+            }
+            return (isNum && width < 0) ? 0 : width;
+        },
+        
+        // private   ==> used by Fx 
+        adjustHeight : function(height) {
+            var me = this;
+            var isNum = Ext.isNumber(height);
+            if(isNum && me.autoBoxAdjust && !me.isBorderBox()){
+               height -= (me.getBorderWidth("tb") + me.getPadding("tb"));               
+            }
+            return (isNum && height < 0) ? 0 : height;
+        },
+    
+    
+        /**
+         * Adds one or more CSS classes to the element. Duplicate classes are automatically filtered out.
+         * @param {String/Array} className The CSS class to add, or an array of classes
+         * @return {Ext.Element} this
+         */
+        addClass : function(className){
+            var me = this;
+            Ext.each(className, function(v) {
+                me.dom.className += (!me.hasClass(v) && v ? " " + v : "");  
+            });
+            return me;
+        },
+    
+        /**
+         * Adds one or more CSS classes to this element and removes the same class(es) from all siblings.
+         * @param {String/Array} className The CSS class to add, or an array of classes
+         * @return {Ext.Element} this
+         */
+        radioClass : function(className){
+            Ext.each(this.dom.parentNode.childNodes, function(v) {
+                if(v.nodeType == 1) {
+                    Ext.fly(v, '_internal').removeClass(className);          
+                }
+            });
+            return this.addClass(className);
+        },
+    
+        /**
+         * Removes one or more CSS classes from the element.
+         * @param {String/Array} className The CSS class to remove, or an array of classes
+         * @return {Ext.Element} this
+         */
+        removeClass : function(className){
+            var me = this;
+            if (me.dom && me.dom.className) {
+                Ext.each(className, function(v) {               
+                    me.dom.className = me.dom.className.replace(
+                        classReCache[v] = classReCache[v] || new RegExp('(?:^|\\s+)' + v + '(?:\\s+|$)', "g"), 
+                        " ");               
+                });    
+            }
+            return me;
+        },
+    
+        /**
+         * Toggles the specified CSS class on this element (removes it if it already exists, otherwise adds it).
+         * @param {String} className The CSS class to toggle
+         * @return {Ext.Element} this
+         */
+        toggleClass : function(className){
+            return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
+        },
+    
+        /**
+         * Checks if the specified CSS class exists on this element's DOM node.
+         * @param {String} className The CSS class to check for
+         * @return {Boolean} True if the class exists, else false
+         */
+        hasClass : function(className){
+            return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
+        },
+    
+        /**
+         * Replaces a CSS class on the element with another.  If the old name does not exist, the new name will simply be added.
+         * @param {String} oldClassName The CSS class to replace
+         * @param {String} newClassName The replacement CSS class
+         * @return {Ext.Element} this
+         */
+        replaceClass : function(oldClassName, newClassName){
+            return this.removeClass(oldClassName).addClass(newClassName);
+        },
+        
+        isStyle : function(style, val) {
+            return this.getStyle(style) == val;  
+        },
+    
+        /**
+         * Normalizes currentStyle and computedStyle.
+         * @param {String} property The style property whose value is returned.
+         * @return {String} The current value of the style property for this element.
+         */
+        getStyle : function(){         
+            return view && view.getComputedStyle ?
+                function(prop){
+                    var el = this.dom,
+                        v,                  
+                        cs,
+                        out;
+                    if(el == document) return null;
+                    prop = chkCache(prop);
+                    out = (v = el.style[prop]) ? v : 
+                           (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
+                    
+                    // Webkit returns rgb values for transparent.
+                    if(Ext.isWebKit && out == 'rgba(0, 0, 0, 0)'){
+                        out = 'transparent';
+                    }
+                    return out;
+                } :
+                function(prop){      
+                    var el = this.dom, 
+                        m, 
+                        cs;     
+                        
+                    if(el == document) return null;      
+                    if (prop == 'opacity') {
+                        if (el.style.filter.match) {                       
+                            if(m = el.style.filter.match(opacityRe)){
+                                var fv = parseFloat(m[1]);
+                                if(!isNaN(fv)){
+                                    return fv ? fv / 100 : 0;
+                                }
+                            }
+                        }
+                        return 1;
+                    }
+                    prop = chkCache(prop);  
+                    return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
+                };
+        }(),
+
+        /**
+         * Return the CSS color for the specified CSS attribute. rgb, 3 digit (like #fff) and valid values
+         * are convert to standard 6 digit hex color.
+         * @param {String} attr The css attribute
+         * @param {String} defaultValue The default value to use when a valid color isn't found
+         * @param {String} prefix (optional) defaults to #. Use an empty string when working with
+         * color anims.
+         */
+        getColor : function(attr, defaultValue, prefix){
+            var v = this.getStyle(attr),
+                color = Ext.isDefined(prefix) ? prefix : '#',
+                h;
+                
+            if(!v || /transparent|inherit/.test(v)){
+                return defaultValue;
+            }
+            if(/^r/.test(v)){
+                Ext.each(v.slice(4, v.length -1).split(','), function(s){
+                    h = parseInt(s, 10);
+                    color += (h < 16 ? '0' : '') + h.toString(16); 
+                });
+            }else{
+                v = v.replace('#', '');
+                color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;
+            }
+            return(color.length > 5 ? color.toLowerCase() : defaultValue);
+        },
+    
+        /**
+         * Wrapper for setting style properties, also takes single object parameter of multiple styles.
+         * @param {String/Object} property The style property to be set, or an object of multiple styles.
+         * @param {String} value (optional) The value to apply to the given property, or null if an object was passed.
+         * @return {Ext.Element} this
+         */
+        setStyle : function(prop, value){
+            var tmp, 
+                style,
+                camel;
+            if (!Ext.isObject(prop)) {
+                tmp = {};
+                tmp[prop] = value;          
+                prop = tmp;
+            }
+            for (style in prop) {
+                value = prop[style];            
+                style == 'opacity' ? 
+                    this.setOpacity(value) : 
+                    this.dom.style[chkCache(style)] = value;
+            }
+            return this;
+        },
+        
+        /**
+         * Set the opacity of the element
+         * @param {Float} opacity The new opacity. 0 = transparent, .5 = 50% visibile, 1 = fully visible, etc
+         * @param {Boolean/Object} animate (optional) a standard Element animation config object or <tt>true</tt> for
+         * the default animation (<tt>{duration: .35, easing: 'easeIn'}</tt>)
+         * @return {Ext.Element} this
+         */
+         setOpacity : function(opacity, animate){
+            var me = this,
+                s = me.dom.style;
+                
+            if(!animate || !me.anim){            
+                if(Ext.isIE){
+                    var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '', 
+                    val = s.filter.replace(opacityRe, '').replace(trimRe, '');
+
+                    s.zoom = 1;
+                    s.filter = val + (val.length > 0 ? ' ' : '') + opac;
+                }else{
+                    s.opacity = opacity;
+                }
+            }else{
+                me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');
+            }
+            return me;
+        },
+        
+        /**
+         * Clears any opacity settings from this element. Required in some cases for IE.
+         * @return {Ext.Element} this
+         */
+        clearOpacity : function(){
+            var style = this.dom.style;
+            if(Ext.isIE){
+                if(!Ext.isEmpty(style.filter)){
+                    style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');
+                }
+            }else{
+                style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';
+            }
+            return this;
+        },
+    
+        /**
+         * Returns the offset height of the element
+         * @param {Boolean} contentHeight (optional) true to get the height minus borders and padding
+         * @return {Number} The element's height
+         */
+        getHeight : function(contentHeight){
+            var me = this,
+                dom = me.dom,
+                hidden = Ext.isIE && me.isStyle('display', 'none'),
+                h = MATH.max(dom.offsetHeight, hidden ? 0 : dom.clientHeight) || 0;
+                
+            h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");
+            return h < 0 ? 0 : h;
+        },
+    
+        /**
+         * Returns the offset width of the element
+         * @param {Boolean} contentWidth (optional) true to get the width minus borders and padding
+         * @return {Number} The element's width
+         */
+        getWidth : function(contentWidth){
+            var me = this,
+                dom = me.dom,
+                hidden = Ext.isIE && me.isStyle('display', 'none'),
+                w = MATH.max(dom.offsetWidth, hidden ? 0 : dom.clientWidth) || 0;
+            w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");
+            return w < 0 ? 0 : w;
+        },
+    
+        /**
+         * Set the width of this Element.
+         * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>
+         * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>
+         * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.
+         * </ul></div>
+         * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
+         * @return {Ext.Element} this
+         */
+        setWidth : function(width, animate){
+            var me = this;
+            width = me.adjustWidth(width);
+            !animate || !me.anim ? 
+                me.dom.style.width = me.addUnits(width) :
+                me.anim({width : {to : width}}, me.preanim(arguments, 1));
+            return me;
+        },
+    
+        /**
+         * Set the height of this Element.
+         * <pre><code>
+// change the height to 200px and animate with default configuration
+Ext.fly('elementId').setHeight(200, true);
+
+// change the height to 150px and animate with a custom configuration
+Ext.fly('elId').setHeight(150, {
+    duration : .5, // animation will have a duration of .5 seconds
+    // will change the content to "finished"
+    callback: function(){ this.{@link #update}("finished"); } 
+});
+         * </code></pre>
+         * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>
+         * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels.)</li>
+         * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>
+         * </ul></div>
+         * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object
+         * @return {Ext.Element} this
+         */
+         setHeight : function(height, animate){
+            var me = this;
+            height = me.adjustHeight(height);
+            !animate || !me.anim ? 
+                me.dom.style.height = me.addUnits(height) :
+                me.anim({height : {to : height}}, me.preanim(arguments, 1));
+            return me;
+        },
+        
+        /**
+         * Gets the width of the border(s) for the specified side(s)
+         * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,
+         * passing <tt>'lr'</tt> would get the border <b><u>l</u></b>eft width + the border <b><u>r</u></b>ight width.
+         * @return {Number} The width of the sides passed added together
+         */
+        getBorderWidth : function(side){
+            return this.addStyles(side, borders);
+        },
+    
+        /**
+         * Gets the width of the padding(s) for the specified side(s)
+         * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,
+         * passing <tt>'lr'</tt> would get the padding <b><u>l</u></b>eft + the padding <b><u>r</u></b>ight.
+         * @return {Number} The padding of the sides passed added together
+         */
+        getPadding : function(side){
+            return this.addStyles(side, paddings);
+        },
+    
+        /**
+         *  Store the current overflow setting and clip overflow on the element - use <tt>{@link #unclip}</tt> to remove
+         * @return {Ext.Element} this
+         */
+        clip : function(){
+            var me = this,
+                dom = me.dom;
+                
+            if(!data(dom, ISCLIPPED)){
+                data(dom, ISCLIPPED, true);
+                data(dom, ORIGINALCLIP, {
+                    o: me.getStyle(OVERFLOW),
+                    x: me.getStyle(OVERFLOWX),
+                    y: me.getStyle(OVERFLOWY)
+                });
+                me.setStyle(OVERFLOW, HIDDEN);
+                me.setStyle(OVERFLOWX, HIDDEN);
+                me.setStyle(OVERFLOWY, HIDDEN);
+            }
+            return me;
+        },
+    
+        /**
+         *  Return clipping (overflow) to original clipping before <tt>{@link #clip}</tt> was called
+         * @return {Ext.Element} this
+         */
+        unclip : function(){
+            var me = this,
+                dom = me.dom;
+                
+            if(data(dom, ISCLIPPED)){
+                data(dom, ISCLIPPED, false);
+                var o = data(dom, ORIGINALCLIP);
+                if(o.o){
+                    me.setStyle(OVERFLOW, o.o);
+                }
+                if(o.x){
+                    me.setStyle(OVERFLOWX, o.x);
+                }
+                if(o.y){
+                    me.setStyle(OVERFLOWY, o.y);
+                }
+            }
+            return me;
+        },
+
+        // private
+        addStyles : function(sides, styles){
+            var val = 0;
+
+            Ext.each(sides.match(/\w/g), function(s) {
+                if (s = parseInt(this.getStyle(styles[s]), 10)) {
+                    val += MATH.abs(s);
+                }
+            },
+            this);
+            return val;
+        },
+
+        margins : margins
+    }
+}()         
+);
+/**\r
  * @class Ext.Element\r
  */\r
-Ext.Element.addMethods(function(){  \r
-    // local style camelizing for speed\r
-    var propCache = {},\r
-        camelRe = /(-[a-z])/gi,\r
-        classReCache = {},\r
-        view = document.defaultView,\r
-        propFloat = Ext.isIE ? 'styleFloat' : 'cssFloat',\r
-        opacityRe = /alpha\(opacity=(.*)\)/i,\r
-        trimRe = /^\s+|\s+$/g,\r
-        EL = Ext.Element,   \r
-        PADDING = "padding",\r
-        MARGIN = "margin",\r
-        BORDER = "border",\r
-        LEFT = "-left",\r
-        RIGHT = "-right",\r
-        TOP = "-top",\r
-        BOTTOM = "-bottom",\r
-        WIDTH = "-width",    \r
-        MATH = Math,\r
-        HIDDEN = 'hidden',\r
-        ISCLIPPED = 'isClipped',\r
-        OVERFLOW = 'overflow',\r
-        OVERFLOWX = 'overflow-x',\r
-        OVERFLOWY = 'overflow-y',\r
-        ORIGINALCLIP = 'originalClip',\r
-        // special markup used throughout Ext when box wrapping elements    \r
-        borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},\r
-        paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},\r
-        margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM},\r
-        data = Ext.Element.data;\r
-        \r
-    \r
-    // private  \r
-    function camelFn(m, a) {\r
-        return a.charAt(1).toUpperCase();\r
-    }\r
-    \r
-    // private (needs to be called => addStyles.call(this, sides, styles))\r
-    function addStyles(sides, styles){\r
-        var val = 0;    \r
-        \r
-        Ext.each(sides.match(/\w/g), function(s) {\r
-            if (s = parseInt(this.getStyle(styles[s]), 10)) {\r
-                val += MATH.abs(s);      \r
-            }\r
-        },\r
-        this);\r
-        return val;\r
-    }\r
 \r
-    function chkCache(prop) {\r
-        return propCache[prop] || (propCache[prop] = prop == 'float' ? propFloat : prop.replace(camelRe, camelFn));\r
+// special markup used throughout Ext when box wrapping elements\r
+Ext.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>';\r
+\r
+Ext.Element.addMethods(function(){\r
+       var INTERNAL = "_internal";\r
+       return {\r
+           /**\r
+            * More flexible version of {@link #setStyle} for setting style properties.\r
+            * @param {String/Object/Function} styles A style specification string, e.g. "width:100px", or object in the form {width:"100px"}, or\r
+            * a function which returns such a specification.\r
+            * @return {Ext.Element} this\r
+            */\r
+           applyStyles : function(style){\r
+               Ext.DomHelper.applyStyles(this.dom, style);\r
+               return this;\r
+           },\r
+\r
+               /**\r
+            * Returns an object with properties matching the styles requested.\r
+            * For example, el.getStyles('color', 'font-size', 'width') might return\r
+            * {'color': '#FFFFFF', 'font-size': '13px', 'width': '100px'}.\r
+            * @param {String} style1 A style name\r
+            * @param {String} style2 A style name\r
+            * @param {String} etc.\r
+            * @return {Object} The style object\r
+            */\r
+           getStyles : function(){\r
+                   var ret = {};\r
+                   Ext.each(arguments, function(v) {\r
+                          ret[v] = this.getStyle(v);\r
+                   },\r
+                   this);\r
+                   return ret;\r
+           },\r
+\r
+               getStyleSize : function(){\r
+               var me = this,\r
+                       w,\r
+                       h,\r
+                       d = this.dom,\r
+                       s = d.style;\r
+               if(s.width && s.width != 'auto'){\r
+                   w = parseInt(s.width, 10);\r
+                   if(me.isBorderBox()){\r
+                      w -= me.getFrameWidth('lr');\r
+                   }\r
+               }\r
+               if(s.height && s.height != 'auto'){\r
+                   h = parseInt(s.height, 10);\r
+                   if(me.isBorderBox()){\r
+                      h -= me.getFrameWidth('tb');\r
+                   }\r
+               }\r
+               return {width: w || me.getWidth(true), height: h || me.getHeight(true)};\r
+           },\r
+\r
+           // private  ==> used by ext full\r
+               setOverflow : function(v){\r
+                       var dom = this.dom;\r
+               if(v=='auto' && Ext.isMac && Ext.isGecko2){ // work around stupid FF 2.0/Mac scroll bar bug\r
+                       dom.style.overflow = 'hidden';\r
+                       (function(){dom.style.overflow = 'auto';}).defer(1);\r
+               }else{\r
+                       dom.style.overflow = v;\r
+               }\r
+               },\r
+\r
+          /**\r
+               * <p>Wraps the specified element with a special 9 element markup/CSS block that renders by default as\r
+               * a gray container with a gradient background, rounded corners and a 4-way shadow.</p>\r
+               * <p>This special markup is used throughout Ext when box wrapping elements ({@link Ext.Button},\r
+               * {@link Ext.Panel} when <tt>{@link Ext.Panel#frame frame=true}</tt>, {@link Ext.Window}).  The markup\r
+               * is of this form:</p>\r
+               * <pre><code>\r
+Ext.Element.boxMarkup =\r
+    &#39;&lt;div class="{0}-tl">&lt;div class="{0}-tr">&lt;div class="{0}-tc">&lt;/div>&lt;/div>&lt;/div>\r
+     &lt;div class="{0}-ml">&lt;div class="{0}-mr">&lt;div class="{0}-mc">&lt;/div>&lt;/div>&lt;/div>\r
+     &lt;div class="{0}-bl">&lt;div class="{0}-br">&lt;div class="{0}-bc">&lt;/div>&lt;/div>&lt;/div>&#39;;\r
+               * </code></pre>\r
+               * <p>Example usage:</p>\r
+               * <pre><code>\r
+// Basic box wrap\r
+Ext.get("foo").boxWrap();\r
+\r
+// You can also add a custom class and use CSS inheritance rules to customize the box look.\r
+// 'x-box-blue' is a built-in alternative -- look at the related CSS definitions as an example\r
+// for how to create a custom box wrap style.\r
+Ext.get("foo").boxWrap().addClass("x-box-blue");\r
+               * </code></pre>\r
+               * @param {String} class (optional) A base CSS class to apply to the containing wrapper element\r
+               * (defaults to <tt>'x-box'</tt>). Note that there are a number of CSS rules that are dependent on\r
+               * this name to make the overall effect work, so if you supply an alternate base class, make sure you\r
+               * also supply all of the necessary rules.\r
+               * @return {Ext.Element} this\r
+               */\r
+           boxWrap : function(cls){\r
+               cls = cls || 'x-box';\r
+               var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>"));        //String.format('<div class="{0}">'+Ext.Element.boxMarkup+'</div>', cls)));\r
+               Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);\r
+               return el;\r
+           },\r
 \r
-    }\r
-            \r
-    return {    \r
-        // private  ==> used by Fx  \r
-        adjustWidth : function(width) {\r
-            var me = this;\r
-            var isNum = (typeof width == "number");\r
-            if(isNum && me.autoBoxAdjust && !me.isBorderBox()){\r
-               width -= (me.getBorderWidth("lr") + me.getPadding("lr"));\r
-            }\r
-            return (isNum && width < 0) ? 0 : width;\r
-        },\r
-        \r
-        // private   ==> used by Fx \r
-        adjustHeight : function(height) {\r
-            var me = this;\r
-            var isNum = (typeof height == "number");\r
-            if(isNum && me.autoBoxAdjust && !me.isBorderBox()){\r
-               height -= (me.getBorderWidth("tb") + me.getPadding("tb"));               \r
-            }\r
-            return (isNum && height < 0) ? 0 : height;\r
-        },\r
-    \r
-    \r
-        /**\r
-         * Adds one or more CSS classes to the element. Duplicate classes are automatically filtered out.\r
-         * @param {String/Array} className The CSS class to add, or an array of classes\r
-         * @return {Ext.Element} this\r
-         */\r
-        addClass : function(className){\r
-            var me = this;\r
-            Ext.each(className, function(v) {\r
-                me.dom.className += (!me.hasClass(v) && v ? " " + v : "");  \r
-            });\r
-            return me;\r
-        },\r
-    \r
-        /**\r
-         * Adds one or more CSS classes to this element and removes the same class(es) from all siblings.\r
-         * @param {String/Array} className The CSS class to add, or an array of classes\r
-         * @return {Ext.Element} this\r
-         */\r
-        radioClass : function(className){\r
-            Ext.each(this.dom.parentNode.childNodes, function(v) {\r
-                if(v.nodeType == 1) {\r
-                    Ext.fly(v, '_internal').removeClass(className);          \r
-                }\r
-            });\r
-            return this.addClass(className);\r
-        },\r
-    \r
         /**\r
-         * Removes one or more CSS classes from the element.\r
-         * @param {String/Array} className The CSS class to remove, or an array of classes\r
-         * @return {Ext.Element} this\r
-         */\r
-        removeClass : function(className){\r
-            var me = this;\r
-            if (me.dom.className) {\r
-                Ext.each(className, function(v) {               \r
-                    me.dom.className = me.dom.className.replace(\r
-                        classReCache[v] = classReCache[v] || new RegExp('(?:^|\\s+)' + v + '(?:\\s+|$)', "g"), \r
-                        " ");               \r
-                });    \r
-            }\r
-            return me;\r
-        },\r
-    \r
-        /**\r
-         * Toggles the specified CSS class on this element (removes it if it already exists, otherwise adds it).\r
-         * @param {String} className The CSS class to toggle\r
-         * @return {Ext.Element} this\r
-         */\r
-        toggleClass : function(className){\r
-            return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);\r
-        },\r
-    \r
-        /**\r
-         * Checks if the specified CSS class exists on this element's DOM node.\r
-         * @param {String} className The CSS class to check for\r
-         * @return {Boolean} True if the class exists, else false\r
-         */\r
-        hasClass : function(className){\r
-            return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;\r
-        },\r
-    \r
-        /**\r
-         * Replaces a CSS class on the element with another.  If the old name does not exist, the new name will simply be added.\r
-         * @param {String} oldClassName The CSS class to replace\r
-         * @param {String} newClassName The replacement CSS class\r
-         * @return {Ext.Element} this\r
-         */\r
-        replaceClass : function(oldClassName, newClassName){\r
-            return this.removeClass(oldClassName).addClass(newClassName);\r
-        },\r
-        \r
-        isStyle : function(style, val) {\r
-            return this.getStyle(style) == val;  \r
-        },\r
-    \r
-        /**\r
-         * Normalizes currentStyle and computedStyle.\r
-         * @param {String} property The style property whose value is returned.\r
-         * @return {String} The current value of the style property for this element.\r
-         */\r
-        getStyle : function(){         \r
-            return view && view.getComputedStyle ?\r
-                function(prop){\r
-                    var el = this.dom,\r
-                        v,                  \r
-                        cs;\r
-                    if(el == document) return null;\r
-                    prop = chkCache(prop);\r
-                    return (v = el.style[prop]) ? v : \r
-                           (cs = view.getComputedStyle(el, "")) ? cs[prop] : null;\r
-                } :\r
-                function(prop){      \r
-                    var el = this.dom, \r
-                        m, \r
-                        cs;     \r
-                        \r
-                    if(el == document) return null;      \r
-                    if (prop == 'opacity') {\r
-                        if (el.style.filter.match) {                       \r
-                            if(m = el.style.filter.match(opacityRe)){\r
-                                var fv = parseFloat(m[1]);\r
-                                if(!isNaN(fv)){\r
-                                    return fv ? fv / 100 : 0;\r
-                                }\r
-                            }\r
-                        }\r
-                        return 1;\r
-                    }\r
-                    prop = chkCache(prop);  \r
-                    return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);\r
-                };\r
-        }(),\r
-        \r
-        /**\r
-         * Return the CSS color for the specified CSS attribute. rgb, 3 digit (like #fff) and valid values\r
-         * are convert to standard 6 digit hex color.\r
-         * @param {String} attr The css attribute\r
-         * @param {String} defaultValue The default value to use when a valid color isn't found\r
-         * @param {String} prefix (optional) defaults to #. Use an empty string when working with\r
-         * color anims.\r
-         */\r
-        getColor : function(attr, defaultValue, prefix){\r
-            var v = this.getStyle(attr),\r
-                color = prefix || '#',\r
-                h;\r
-                \r
-            if(!v || /transparent|inherit/.test(v)){\r
-                return defaultValue;\r
-            }\r
-            if(/^r/.test(v)){\r
-                Ext.each(v.slice(4, v.length -1).split(','), function(s){\r
-                    h = parseInt(s, 10);\r
-                    color += (h < 16 ? '0' : '') + h.toString(16); \r
-                });\r
-            }else{\r
-                v = v.replace('#', '');\r
-                color += v.length == 3 ? v.replace(/^(\w)(\w)(\w)$/, '$1$1$2$2$3$3') : v;\r
-            }\r
-            return(color.length > 5 ? color.toLowerCase() : defaultValue);\r
-        },\r
-    \r
-        /**\r
-         * Wrapper for setting style properties, also takes single object parameter of multiple styles.\r
-         * @param {String/Object} property The style property to be set, or an object of multiple styles.\r
-         * @param {String} value (optional) The value to apply to the given property, or null if an object was passed.\r
-         * @return {Ext.Element} this\r
-         */\r
-        setStyle : function(prop, value){\r
-            var tmp, \r
-                style,\r
-                camel;\r
-            if (!Ext.isObject(prop)) {\r
-                tmp = {};\r
-                tmp[prop] = value;          \r
-                prop = tmp;\r
-            }\r
-            for (style in prop) {\r
-                value = prop[style];            \r
-                style == 'opacity' ? \r
-                    this.setOpacity(value) : \r
-                    this.dom.style[chkCache(style)] = value;\r
-            }\r
-            return this;\r
-        },\r
-        \r
-        /**\r
-         * Set the opacity of the element\r
-         * @param {Float} opacity The new opacity. 0 = transparent, .5 = 50% visibile, 1 = fully visible, etc\r
-         * @param {Boolean/Object} animate (optional) a standard Element animation config object or <tt>true</tt> for\r
-         * the default animation (<tt>{duration: .35, easing: 'easeIn'}</tt>)\r
-         * @return {Ext.Element} this\r
-         */\r
-         setOpacity : function(opacity, animate){\r
-            var me = this,\r
-                s = me.dom.style;\r
-                \r
-            if(!animate || !me.anim){            \r
-                if(Ext.isIE){\r
-                    var opac = opacity < 1 ? 'alpha(opacity=' + opacity * 100 + ')' : '', \r
-                    val = s.filter.replace(opacityRe, '').replace(trimRe, '');\r
-\r
-                    s.zoom = 1;\r
-                    s.filter = val + (val.length > 0 ? ' ' : '') + opac;\r
-                }else{\r
-                    s.opacity = opacity;\r
-                }\r
-            }else{\r
-                me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');\r
-            }\r
-            return me;\r
-        },\r
-        \r
-        /**\r
-         * Clears any opacity settings from this element. Required in some cases for IE.\r
-         * @return {Ext.Element} this\r
-         */\r
-        clearOpacity : function(){\r
-            var style = this.dom.style;\r
-            if(Ext.isIE){\r
-                if(!Ext.isEmpty(style.filter)){\r
-                    style.filter = style.filter.replace(opacityRe, '').replace(trimRe, '');\r
-                }\r
-            }else{\r
-                style.opacity = style['-moz-opacity'] = style['-khtml-opacity'] = '';\r
-            }\r
-            return this;\r
-        },\r
-    \r
-        /**\r
-         * Returns the offset height of the element\r
-         * @param {Boolean} contentHeight (optional) true to get the height minus borders and padding\r
-         * @return {Number} The element's height\r
-         */\r
-        getHeight : function(contentHeight){\r
-            var me = this,\r
-                dom = me.dom,\r
-                h = MATH.max(dom.offsetHeight, dom.clientHeight) || 0;\r
-            h = !contentHeight ? h : h - me.getBorderWidth("tb") - me.getPadding("tb");\r
-            return h < 0 ? 0 : h;\r
-        },\r
-    \r
-        /**\r
-         * Returns the offset width of the element\r
-         * @param {Boolean} contentWidth (optional) true to get the width minus borders and padding\r
-         * @return {Number} The element's width\r
-         */\r
-        getWidth : function(contentWidth){\r
-            var me = this,\r
-                dom = me.dom,\r
-                w = MATH.max(dom.offsetWidth, dom.clientWidth) || 0;\r
-            w = !contentWidth ? w : w - me.getBorderWidth("lr") - me.getPadding("lr");\r
-            return w < 0 ? 0 : w;\r
-        },\r
-    \r
-        /**\r
-         * Set the width of this Element.\r
-         * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>\r
-         * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>\r
-         * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.\r
-         * </ul></div>\r
-         * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
-         * @return {Ext.Element} this\r
-         */\r
-        setWidth : function(width, animate){\r
-            var me = this;\r
-            width = me.adjustWidth(width);\r
-            !animate || !me.anim ? \r
-                me.dom.style.width = me.addUnits(width) :\r
-                me.anim({width : {to : width}}, me.preanim(arguments, 1));\r
-            return me;\r
-        },\r
-    \r
-        /**\r
-         * Set the height of this Element.\r
-         * <pre><code>\r
-// change the height to 200px and animate with default configuration\r
-Ext.fly('elementId').setHeight(200, true);\r
-\r
-// change the height to 150px and animate with a custom configuration\r
-Ext.fly('elId').setHeight(150, {\r
-    duration : .5, // animation will have a duration of .5 seconds\r
-    // will change the content to "finished"\r
-    callback: function(){ this.{@link #update}("finished"); } \r
-});\r
-         * </code></pre>\r
-         * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>\r
-         * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels.)</li>\r
-         * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>\r
-         * </ul></div>\r
-         * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
-         * @return {Ext.Element} this\r
-         */\r
-         setHeight : function(height, animate){\r
-            var me = this;\r
-            height = me.adjustHeight(height);\r
-            !animate || !me.anim ? \r
-                me.dom.style.height = me.addUnits(height) :\r
-                me.anim({height : {to : height}}, me.preanim(arguments, 1));\r
-            return me;\r
-        },\r
-        \r
-        /**\r
-         * Gets the width of the border(s) for the specified side(s)\r
-         * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,\r
-         * passing <tt>'lr'</tt> would get the border <b><u>l</u></b>eft width + the border <b><u>r</u></b>ight width.\r
-         * @return {Number} The width of the sides passed added together\r
-         */\r
-        getBorderWidth : function(side){\r
-            return addStyles.call(this, side, borders);\r
-        },\r
-    \r
-        /**\r
-         * Gets the width of the padding(s) for the specified side(s)\r
-         * @param {String} side Can be t, l, r, b or any combination of those to add multiple values. For example,\r
-         * passing <tt>'lr'</tt> would get the padding <b><u>l</u></b>eft + the padding <b><u>r</u></b>ight.\r
-         * @return {Number} The padding of the sides passed added together\r
-         */\r
-        getPadding : function(side){\r
-            return addStyles.call(this, side, paddings);\r
-        },\r
-    \r
-        /**\r
-         *  Store the current overflow setting and clip overflow on the element - use <tt>{@link #unclip}</tt> to remove\r
-         * @return {Ext.Element} this\r
-         */\r
-        clip : function(){\r
-            var me = this,\r
-                dom = me.dom;\r
-                \r
-            if(!data(dom, ISCLIPPED)){\r
-                data(dom, ISCLIPPED, true);\r
-                data(dom, ORIGINALCLIP, {\r
-                    o: me.getStyle(OVERFLOW),\r
-                    x: me.getStyle(OVERFLOWX),\r
-                    y: me.getStyle(OVERFLOWY)\r
-                });\r
-                me.setStyle(OVERFLOW, HIDDEN);\r
-                me.setStyle(OVERFLOWX, HIDDEN);\r
-                me.setStyle(OVERFLOWY, HIDDEN);\r
-            }\r
-            return me;\r
-        },\r
-    \r
-        /**\r
-         *  Return clipping (overflow) to original clipping before <tt>{@link #clip}</tt> was called\r
-         * @return {Ext.Element} this\r
-         */\r
-        unclip : function(){\r
-            var me = this,\r
-                dom = me.dom;\r
-                \r
-            if(data(dom, ISCLIPPED)){\r
-                data(dom, ISCLIPPED, false);\r
-                var o = data(dom, ORIGINALCLIP);\r
-                if(o.o){\r
-                    me.setStyle(OVERFLOW, o.o);\r
-                }\r
-                if(o.x){\r
-                    me.setStyle(OVERFLOWX, o.x);\r
-                }\r
-                if(o.y){\r
-                    me.setStyle(OVERFLOWY, o.y);\r
-                }\r
-            }\r
-            return me;\r
-        },\r
-        \r
-        addStyles : addStyles,\r
-        margins : margins\r
-    }\r
-}()         \r
-);/**\r
- * @class Ext.Element\r
- */\r
-\r
-// special markup used throughout Ext when box wrapping elements\r
-Ext.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>';\r
-\r
-Ext.Element.addMethods(function(){\r
-       var INTERNAL = "_internal";\r
-       return {\r
-           /**\r
-            * More flexible version of {@link #setStyle} for setting style properties.\r
-            * @param {String/Object/Function} styles A style specification string, e.g. "width:100px", or object in the form {width:"100px"}, or\r
-            * a function which returns such a specification.\r
-            * @return {Ext.Element} this\r
-            */\r
-           applyStyles : function(style){\r
-               Ext.DomHelper.applyStyles(this.dom, style);\r
-               return this;\r
-           },\r
-\r
-               /**\r
-            * Returns an object with properties matching the styles requested.\r
-            * For example, el.getStyles('color', 'font-size', 'width') might return\r
-            * {'color': '#FFFFFF', 'font-size': '13px', 'width': '100px'}.\r
-            * @param {String} style1 A style name\r
-            * @param {String} style2 A style name\r
-            * @param {String} etc.\r
-            * @return {Object} The style object\r
-            */\r
-           getStyles : function(){\r
-                   var ret = {};\r
-                   Ext.each(arguments, function(v) {\r
-                          ret[v] = this.getStyle(v);\r
-                   },\r
-                   this);\r
-                   return ret;\r
-           },\r
-\r
-               getStyleSize : function(){\r
-               var me = this,\r
-                       w,\r
-                       h,\r
-                       d = this.dom,\r
-                       s = d.style;\r
-               if(s.width && s.width != 'auto'){\r
-                   w = parseInt(s.width, 10);\r
-                   if(me.isBorderBox()){\r
-                      w -= me.getFrameWidth('lr');\r
-                   }\r
-               }\r
-               if(s.height && s.height != 'auto'){\r
-                   h = parseInt(s.height, 10);\r
-                   if(me.isBorderBox()){\r
-                      h -= me.getFrameWidth('tb');\r
-                   }\r
-               }\r
-               return {width: w || me.getWidth(true), height: h || me.getHeight(true)};\r
-           },\r
-\r
-           // private  ==> used by ext full\r
-               setOverflow : function(v){\r
-                       var dom = this.dom;\r
-               if(v=='auto' && Ext.isMac && Ext.isGecko2){ // work around stupid FF 2.0/Mac scroll bar bug\r
-                       dom.style.overflow = 'hidden';\r
-                       (function(){dom.style.overflow = 'auto';}).defer(1);\r
-               }else{\r
-                       dom.style.overflow = v;\r
-               }\r
-               },\r
-\r
-          /**\r
-               * <p>Wraps the specified element with a special 9 element markup/CSS block that renders by default as\r
-               * a gray container with a gradient background, rounded corners and a 4-way shadow.</p>\r
-               * <p>This special markup is used throughout Ext when box wrapping elements ({@link Ext.Button},\r
-               * {@link Ext.Panel} when <tt>{@link Ext.Panel#frame frame=true}</tt>, {@link Ext.Window}).  The markup\r
-               * is of this form:</p>\r
-               * <pre><code>\r
-Ext.Element.boxMarkup =\r
-    &#39;&lt;div class="{0}-tl">&lt;div class="{0}-tr">&lt;div class="{0}-tc">&lt;/div>&lt;/div>&lt;/div>\r
-     &lt;div class="{0}-ml">&lt;div class="{0}-mr">&lt;div class="{0}-mc">&lt;/div>&lt;/div>&lt;/div>\r
-     &lt;div class="{0}-bl">&lt;div class="{0}-br">&lt;div class="{0}-bc">&lt;/div>&lt;/div>&lt;/div>&#39;;\r
-               * </code></pre>\r
-               * <p>Example usage:</p>\r
-               * <pre><code>\r
-// Basic box wrap\r
-Ext.get("foo").boxWrap();\r
-\r
-// You can also add a custom class and use CSS inheritance rules to customize the box look.\r
-// 'x-box-blue' is a built-in alternative -- look at the related CSS definitions as an example\r
-// for how to create a custom box wrap style.\r
-Ext.get("foo").boxWrap().addClass("x-box-blue");\r
-               * </code></pre>\r
-               * @param {String} class (optional) A base CSS class to apply to the containing wrapper element\r
-               * (defaults to <tt>'x-box'</tt>). Note that there are a number of CSS rules that are dependent on\r
-               * this name to make the overall effect work, so if you supply an alternate base class, make sure you\r
-               * also supply all of the necessary rules.\r
-               * @return {Ext.Element} this\r
-               */\r
-           boxWrap : function(cls){\r
-               cls = cls || 'x-box';\r
-               var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>"));        //String.format('<div class="{0}">'+Ext.Element.boxMarkup+'</div>', cls)));\r
-               Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);\r
-               return el;\r
-           },\r
-\r
-        /**\r
-         * Set the size of this Element. If animation is true, both width and height will be animated concurrently.\r
-         * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>\r
-         * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>\r
-         * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.\r
-         * <li>A size object in the format <code>{width: widthValue, height: heightValue}</code>.</li>\r
-         * </ul></div>\r
-         * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>\r
-         * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels).</li>\r
-         * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>\r
-         * </ul></div>\r
-         * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
+         * Set the size of this Element. If animation is true, both width and height will be animated concurrently.\r
+         * @param {Mixed} width The new width. This may be one of:<div class="mdetail-params"><ul>\r
+         * <li>A Number specifying the new width in this Element's {@link #defaultUnit}s (by default, pixels).</li>\r
+         * <li>A String used to set the CSS width style. Animation may <b>not</b> be used.\r
+         * <li>A size object in the format <code>{width: widthValue, height: heightValue}</code>.</li>\r
+         * </ul></div>\r
+         * @param {Mixed} height The new height. This may be one of:<div class="mdetail-params"><ul>\r
+         * <li>A Number specifying the new height in this Element's {@link #defaultUnit}s (by default, pixels).</li>\r
+         * <li>A String used to set the CSS height style. Animation may <b>not</b> be used.</li>\r
+         * </ul></div>\r
+         * @param {Boolean/Object} animate (optional) true for the default animation or a standard Element animation config object\r
          * @return {Ext.Element} this\r
          */\r
            setSize : function(width, height, animate){\r
@@ -5843,10 +6014,6 @@ var D = Ext.lib.Dom,
         AUTO = "auto",\r
         ZINDEX = "z-index";\r
 \r
-function animTest(args, animate, i) {\r
-       return this.preanim && !!animate ? this.preanim(args, i) : false        \r
-}\r
-\r
 Ext.Element.addMethods({\r
        /**\r
       * Gets the current X position of the element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).\r
@@ -5890,7 +6057,7 @@ Ext.Element.addMethods({
      * @return {Ext.Element} this\r
      */\r
     setX : function(x, animate){           \r
-           return this.setXY([x, this.getY()], animTest.call(this, arguments, animate, 1));\r
+           return this.setXY([x, this.getY()], this.animTest(arguments, animate, 1));\r
     },\r
 \r
     /**\r
@@ -5900,7 +6067,7 @@ Ext.Element.addMethods({
      * @return {Ext.Element} this\r
      */\r
     setY : function(y, animate){           \r
-           return this.setXY([this.getX(), y], animTest.call(this, arguments, animate, 1));\r
+           return this.setXY([this.getX(), y], this.animTest(arguments, animate, 1));\r
     },\r
 \r
     /**\r
@@ -5969,7 +6136,7 @@ Ext.Element.addMethods({
      * @return {Ext.Element} this\r
      */\r
     setLocation : function(x, y, animate){\r
-        return this.setXY([x, y], animTest.call(this, arguments, animate, 2));\r
+        return this.setXY([x, y], this.animTest(arguments, animate, 2));\r
     },\r
 \r
     /**\r
@@ -5981,7 +6148,7 @@ Ext.Element.addMethods({
      * @return {Ext.Element} this\r
      */\r
     moveTo : function(x, y, animate){\r
-        return this.setXY([x, y], animTest.call(this, arguments, animate, 2));        \r
+        return this.setXY([x, y], this.animTest(arguments, animate, 2));        \r
     },    \r
     \r
     /**\r
@@ -6122,7 +6289,9 @@ Ext.Element.addMethods({
         return {left: (x - o[0] + l), top: (y - o[1] + t)}; \r
     },\r
     \r
-    animTest : animTest\r
+    animTest : function(args, animate, i) {\r
+        return !!animate && this.preanim ? this.preanim(args, i) : false;\r
+    }\r
 });\r
 })();/**\r
  * @class Ext.Element\r
@@ -6345,15 +6514,15 @@ Ext.Element.addMethods({
      * @return {Element} this\r
      */\r
     scrollTo : function(side, value, animate){\r
-        var tester = /top/i,\r
-               prop = "scroll" + (tester.test(side) ? "Top" : "Left"),\r
-               me = this,\r
-               dom = me.dom;\r
+        var top = /top/i.test(side), //check if we're scrolling top or left\r
+            prop = 'scroll' + (top ? 'Left' : 'Top'), // if scrolling top, we need to grab scrollLeft, if left, scrollTop\r
+            me = this,\r
+            dom = me.dom;\r
         if (!animate || !me.anim) {\r
             dom[prop] = value;\r
         } else {\r
-            me.anim({scroll: {to: tester.test(prop) ? [dom[prop], value] : [value, dom[prop]]}},\r
-                        me.preanim(arguments, 2), 'scroll');\r
+            me.anim({scroll: {to: top ? [dom[prop], value] : [value, dom[prop]]}},\r
+                     me.preanim(arguments, 2), 'scroll');\r
         }\r
         return me;\r
     },\r
@@ -6487,7 +6656,7 @@ Ext.Element.addMethods(function(){
         /**\r
          * Sets the element's visibility mode. When setVisible() is called it\r
          * will use this to determine whether to set the visibility or the display property.\r
-         * @param visMode Ext.Element.VISIBILITY or Ext.Element.DISPLAY\r
+         * @param {Number} visMode Ext.Element.VISIBILITY or Ext.Element.DISPLAY\r
          * @return {Ext.Element} this\r
          */\r
         setVisibilityMode : function(visMode){  \r
@@ -6890,9 +7059,7 @@ function(){
                        shim;\r
                el.frameBorder = '0';\r
                el.className = 'ext-shim';\r
-               if(Ext.isIE && Ext.isSecure){\r
-                   el.src = Ext.SSL_SECURE_URL;\r
-               }\r
+               el.src = Ext.SSL_SECURE_URL;\r
                shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));\r
                shim.autoBoxAdjust = false;\r
                return shim;\r
@@ -7031,7 +7198,7 @@ br     The bottom right corner
  * The callback is intended for any additional code that should run once a particular effect has completed. The Element\r
  * being operated upon is passed as the first parameter.\r
  * \r
- * @cfg {Object} scope The scope of the <tt>{@link #callback}</tt> function\r
+ * @cfg {Object} scope The scope (<code>this</code> reference) in which the <tt>{@link #callback}</tt> function is executed. Defaults to the browser window.\r
  * \r
  * @cfg {String} easing A valid Ext.lib.Easing value for the effect:</p><div class="mdetail-params"><ul>\r
  * <li><b><tt>backBoth</tt></b></li>\r
@@ -7505,9 +7672,9 @@ el.frame("C3DAF9", 1, {
             active;\r
 \r
         me.queueFx(o, function(){\r
-            color = color || "#C3DAF9"\r
+            color = color || '#C3DAF9'\r
             if(color.length == 6){\r
-                color = "#" + color;\r
+                color = '#' + color;\r
             }            \r
             count = count || 1;\r
             fly(dom).show();\r
@@ -7517,10 +7684,9 @@ el.frame("C3DAF9", 1, {
                 queue = function(){\r
                     proxy = fly(document.body || document.documentElement).createChild({\r
                         style:{\r
-                            visbility: HIDDEN,\r
                             position : ABSOLUTE,\r
-                            "z-index": 35000, // yee haw\r
-                            border : "0px solid " + color\r
+                            'z-index': 35000, // yee haw\r
+                            border : '0px solid ' + color\r
                         }\r
                     });\r
                     return proxy.queueFx({}, animFn);\r
@@ -7939,7 +8105,7 @@ el.ghost('b', {
 \r
     /* @private */\r
     queueFx : function(o, fn){\r
-        var me = this;\r
+        var me = fly(this.dom);\r
         if(!me.hasFxBlock()){\r
             Ext.applyIf(o, me.fxDefaults);\r
             if(!o.concurrent){\r
@@ -7988,7 +8154,8 @@ el.ghost('b', {
         fly(dom).clearPositioning();\r
         fly(dom).setPositioning(pos);\r
         if(!o.wrap){\r
-            wrap.parentNode.insertBefore(dom, wrap);\r
+            var pn = fly(wrap).dom.parentNode;
+            pn.insertBefore(dom, wrap); \r
             fly(wrap).remove();\r
         }\r
     },\r
@@ -8002,8 +8169,7 @@ el.ghost('b', {
     /* @private */\r
     afterFx : function(o){\r
         var dom = this.dom,\r
-            id = dom.id,\r
-            notConcurrent = !o.concurrent;\r
+            id = dom.id;\r
         if(o.afterStyle){\r
             fly(dom).setStyle(o.afterStyle);            \r
         }\r
@@ -8013,13 +8179,11 @@ el.ghost('b', {
         if(o.remove == TRUE){\r
             fly(dom).remove();\r
         }\r
-        if(notConcurrent){\r
-            getQueue(id).shift();\r
-        }\r
         if(o.callback){\r
             o.callback.call(o.scope, fly(dom));\r
         }\r
-        if(notConcurrent){\r
+        if(!o.concurrent){\r
+            getQueue(id).shift();\r
             fly(dom).nextFx();\r
         }\r
     },\r
@@ -8047,45 +8211,78 @@ Ext.Fx.resize = Ext.Fx.scale;
 //When included, Ext.Fx is automatically applied to Element so that all basic\r
 //effects are available directly via the Element API\r
 Ext.Element.addMethods(Ext.Fx);\r
-})();/**\r
+})();
+/**\r
  * @class Ext.CompositeElementLite\r
- * Flyweight composite class. Reuses the same Ext.Element for element operations.\r
- <pre><code>\r
- var els = Ext.select("#some-el div.some-class");\r
- // or select directly from an existing element\r
- var el = Ext.get('some-el');\r
- el.select('div.some-class');\r
-\r
- els.setWidth(100); // all elements become 100 width\r
- els.hide(true); // all elements fade out and hide\r
- // or\r
- els.setWidth(100).hide(true);\r
- </code></pre><br><br>\r
- * <b>NOTE: Although they are not listed, this class supports all of the set/update methods of Ext.Element. All Ext.Element\r
- * actions will be performed on all the elements in this collection.</b>\r
+ * <p>This class encapsulates a <i>collection</i> of DOM elements, providing methods to filter\r
+ * members, or to perform collective actions upon the whole set.</p>\r
+ * <p>Although they are not listed, this class supports all of the methods of {@link Ext.Element} and\r
+ * {@link Ext.Fx}. The methods from these classes will be performed on all the elements in this collection.</p>\r
+ * Example:<pre><code>\r
+var els = Ext.select("#some-el div.some-class");\r
+// or select directly from an existing element\r
+var el = Ext.get('some-el');\r
+el.select('div.some-class');\r
+\r
+els.setWidth(100); // all elements become 100 width\r
+els.hide(true); // all elements fade out and hide\r
+// or\r
+els.setWidth(100).hide(true);\r
+</code>\r
  */\r
 Ext.CompositeElementLite = function(els, root){\r
+    /**\r
+     * <p>The Array of DOM elements which this CompositeElement encapsulates. Read-only.</p>\r
+     * <p>This will not <i>usually</i> be accessed in developers' code, but developers wishing\r
+     * to augment the capabilities of the CompositeElementLite class may use it when adding\r
+     * methods to the class.</p>\r
+     * <p>For example to add the <code>nextAll</code> method to the class to <b>add</b> all\r
+     * following siblings of selected elements, the code would be</p><code><pre>\r
+Ext.override(Ext.CompositeElementLite, {\r
+    nextAll: function() {\r
+        var els = this.elements, i, l = els.length, n, r = [], ri = -1;\r
+\r
+//      Loop through all elements in this Composite, accumulating\r
+//      an Array of all siblings.\r
+        for (i = 0; i < l; i++) {\r
+            for (n = els[i].nextSibling; n; n = n.nextSibling) {\r
+                r[++ri] = n;\r
+            }\r
+        }\r
+\r
+//      Add all found siblings to this Composite\r
+        return this.add(r);\r
+    }\r
+});</pre></code>\r
+     * @type Array\r
+     * @property elements\r
+     */\r
     this.elements = [];\r
     this.add(els, root);\r
     this.el = new Ext.Element.Flyweight();\r
 };\r
 \r
 Ext.CompositeElementLite.prototype = {\r
-       isComposite: true,      \r
-       /**\r
-     * Returns the number of elements in this composite\r
+    isComposite: true,    \r
+    /**\r
+     * Returns the number of elements in this Composite.\r
      * @return Number\r
      */\r
     getCount : function(){\r
         return this.elements.length;\r
     },    \r
-       add : function(els){\r
+    /**\r
+     * Adds elements to this Composite object.\r
+     * @param {Mixed} els Either an Array of DOM elements to add, or another Composite object who's elements should be added.\r
+     * @return {CompositeElement} This Composite object.\r
+     */\r
+    add : function(els){\r
         if(els){\r
             if (Ext.isArray(els)) {\r
                 this.elements = this.elements.concat(els);\r
             } else {\r
-                var yels = this.elements;                                      \r
-                   Ext.each(els, function(e) {\r
+                var yels = this.elements;                                    \r
+                Ext.each(els, function(e) {\r
                     yels.push(e);\r
                 });\r
             }\r
@@ -8094,10 +8291,10 @@ Ext.CompositeElementLite.prototype = {
     },\r
     invoke : function(fn, args){\r
         var els = this.elements,\r
-               el = this.el;        \r
-           Ext.each(els, function(e) {    \r
+            el = this.el;        \r
+        Ext.each(els, function(e) {    \r
             el.dom = e;\r
-               Ext.Element.prototype[fn].apply(el, args);\r
+            Ext.Element.prototype[fn].apply(el, args);\r
         });\r
         return this;\r
     },\r
@@ -8107,7 +8304,7 @@ Ext.CompositeElementLite.prototype = {
      * @return {Ext.Element}\r
      */\r
     item : function(index){\r
-           var me = this;\r
+        var me = this;\r
         if(!me.elements[index]){\r
             return null;\r
         }\r
@@ -8118,26 +8315,67 @@ Ext.CompositeElementLite.prototype = {
     // fixes scope with flyweight\r
     addListener : function(eventName, handler, scope, opt){\r
         Ext.each(this.elements, function(e) {\r
-               Ext.EventManager.on(e, eventName, handler, scope || e, opt);\r
+            Ext.EventManager.on(e, eventName, handler, scope || e, opt);\r
         });\r
         return this;\r
     },\r
     /**\r
-    * Calls the passed function passing (el, this, index) for each element in this composite. <b>The element\r
-    * passed is the flyweight (shared) Ext.Element instance, so if you require a\r
-    * a reference to the dom node, use el.dom.</b>\r
-    * @param {Function} fn The function to call\r
-    * @param {Object} scope (optional) The <i>this</i> object (defaults to the element)\r
-    * @return {CompositeElement} this\r
-    */\r
+     * <p>Calls the passed function for each element in this composite.</p>\r
+     * @param {Function} fn The function to call. The function is passed the following parameters:<ul>\r
+     * <li><b>el</b> : Element<div class="sub-desc">The current Element in the iteration.\r
+     * <b>This is the flyweight (shared) Ext.Element instance, so if you require a\r
+     * a reference to the dom node, use el.dom.</b></div></li>\r
+     * <li><b>c</b> : Composite<div class="sub-desc">This Composite object.</div></li>\r
+     * <li><b>idx</b> : Number<div class="sub-desc">The zero-based index in the iteration.</div></li>\r
+     * </ul>\r
+     * @param {Object} scope (optional) The scope (<i>this</i> reference) in which the function is executed. (defaults to the Element)\r
+     * @return {CompositeElement} this\r
+     */\r
     each : function(fn, scope){       \r
         var me = this,\r
-               el = me.el;\r
+            el = me.el;\r
        \r
-           Ext.each(me.elements, function(e,i) {    \r
+        Ext.each(me.elements, function(e,i) {    \r
             el.dom = e;\r
-               return fn.call(scope || el, el, me, i);\r
+            return fn.call(scope || el, el, me, i);\r
+        });\r
+        return me;\r
+    },\r
+    \r
+    /**\r
+    * Clears this Composite and adds the elements passed.\r
+    * @param {Mixed} els Either an array of DOM elements, or another Composite from which to fill this Composite.\r
+    * @return {CompositeElement} this\r
+    */\r
+    fill : function(els){\r
+        var me = this;\r
+        me.elements = [];\r
+        me.add(els);\r
+        return me;\r
+    },\r
+    \r
+    /**\r
+     * Filters this composite to only elements that match the passed selector.\r
+     * @param {String/Function} selector A string CSS selector or a comparison function.\r
+     * The comparison function will be called with the following arguments:<ul>\r
+     * <li><code>el</code> : Ext.Element<div class="sub-desc">The current DOM element.</div></li>\r
+     * <li><code>index</code> : Number<div class="sub-desc">The current index within the collection.</div></li>\r
+     * </ul>\r
+     * @return {CompositeElement} this\r
+     */\r
+    filter : function(selector){\r
+        var els = [],\r
+            me = this,\r
+            fn = Ext.isFunction(selector) ? selector\r
+                : function(el){\r
+                    return el.is(selector);\r
+                }\r
+        me.each(function(el, self, i){\r
+            if(fn(el, i) !== false){\r
+                els[els.length] = el.dom;\r
+            }\r
         });\r
+        me.fill(els);\r
         return me;\r
     },\r
     \r
@@ -8160,7 +8398,7 @@ Ext.CompositeElementLite.prototype = {
     */    \r
     replaceElement : function(el, replacement, domReplace){\r
         var index = !isNaN(el) ? el : this.indexOf(el),\r
-               d;\r
+            d;\r
         if(index > -1){\r
             replacement = Ext.getDom(replacement);\r
             if(domReplace){\r
@@ -8185,16 +8423,16 @@ Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addLi
 \r
 (function(){\r
 var fnName,\r
-       ElProto = Ext.Element.prototype,\r
-       CelProto = Ext.CompositeElementLite.prototype;\r
-       \r
+    ElProto = Ext.Element.prototype,\r
+    CelProto = Ext.CompositeElementLite.prototype;\r
+    \r
 for(fnName in ElProto){\r
     if(Ext.isFunction(ElProto[fnName])){\r
-           (function(fnName){ \r
-                   CelProto[fnName] = CelProto[fnName] || function(){\r
-                       return this.invoke(fnName, arguments);\r
-               };\r
-       }).call(CelProto, fnName);\r
+        (function(fnName){ \r
+            CelProto[fnName] = CelProto[fnName] || function(){\r
+                return this.invoke(fnName, arguments);\r
+            };\r
+        }).call(CelProto, fnName);\r
         \r
     }\r
 }\r
@@ -8255,17 +8493,6 @@ Ext.apply(Ext.CompositeElementLite.prototype, {
         return this;\r
     },\r
     \r
-    /**\r
-    * Clears this composite and adds the elements returned by the passed selector.\r
-    * @param {String/Array} els A string CSS selector, an array of elements or an element\r
-    * @return {CompositeElement} this\r
-    */\r
-    fill : function(els){\r
-        this.elements = [];\r
-        this.add(els);\r
-        return this;\r
-    },\r
-    \r
     /**\r
      * Returns the first Element\r
      * @return {Ext.Element}\r
@@ -8289,22 +8516,6 @@ Ext.apply(Ext.CompositeElementLite.prototype, {
      */\r
     contains : function(el){\r
         return this.indexOf(el) != -1;\r
-    },\r
-\r
-    /**\r
-    * Filters this composite to only elements that match the passed selector.\r
-    * @param {String} selector A string CSS selector\r
-    * @return {CompositeElement} this\r
-    */\r
-    filter : function(selector){\r
-        var els = [];\r
-        this.each(function(el){\r
-            if(el.is(selector)){\r
-                els[els.length] = el.dom;\r
-            }\r
-        });\r
-        this.fill(els);\r
-        return this;\r
     },
     
     /**\r
@@ -8366,7 +8577,7 @@ Ext.extend(Ext.CompositeElement, Ext.CompositeElementLite, {
         });\r
         return this;\r
     },\r
-    \r
+\r
     /**\r
     * Adds elements to this composite.\r
     * @param {String/Array} els A string CSS selector, an array of elements or an element\r
@@ -8379,13 +8590,13 @@ Ext.extend(Ext.CompositeElement, Ext.CompositeElementLite, {
         if(typeof els == "string"){\r
             els = Ext.Element.selectorFunction(els, root);\r
         }\r
-        var yels = this.elements;        \r
+        var yels = this.elements;\r
            Ext.each(els, function(e) {\r
                yels.push(Ext.get(e));\r
         });\r
         return this;\r
-    },    \r
-    \r
+    },\r
+\r
     /**\r
      * Returns the Element object at the specified index\r
      * @param {Number} index\r
@@ -8399,12 +8610,12 @@ Ext.extend(Ext.CompositeElement, Ext.CompositeElementLite, {
     indexOf : function(el){\r
         return this.elements.indexOf(Ext.get(el));\r
     },\r
-        \r
+\r
     filter : function(selector){\r
                var me = this,\r
                        out = [];\r
-                       \r
-               Ext.each(me.elements, function(el) {    \r
+\r
+               Ext.each(me.elements, function(el) {\r
                        if(el.is(selector)){\r
                                out.push(Ext.get(el));\r
                        }\r
@@ -8412,16 +8623,31 @@ Ext.extend(Ext.CompositeElement, Ext.CompositeElementLite, {
                me.elements = out;\r
                return me;\r
        },\r
-       \r
-       /**\r
-    * Calls the passed function passing (el, this, index) for each element in this composite.\r
-    * @param {Function} fn The function to call\r
-    * @param {Object} scope (optional) The <i>this</i> object (defaults to the element)\r
-    * @return {CompositeElement} this\r
-    */\r
-    each : function(fn, scope){        \r
-        Ext.each(this.elements, function(e,i) {\r
-               return fn.call(scope || e, e, this, i);\r
+\r
+    /**\r
+     * Iterates each <code>element</code> in this <code>composite</code>\r
+     * calling the supplied function using {@link Ext#each}.\r
+     * @param {Function} fn The function to be called with each\r
+     * <code>element</code>. If the supplied function returns <tt>false</tt>,\r
+     * iteration stops. This function is called with the following arguments:\r
+     * <div class="mdetail-params"><ul>\r
+     * <li><code>element</code> : <i>Object</i>\r
+     * <div class="sub-desc">The element at the current <code>index</code>\r
+     * in the <code>composite</code></div></li>\r
+     * <li><code>composite</code> : <i>Object</i>\r
+     * <div class="sub-desc">This composite.</div></li>\r
+     * <li><code>index</code> : <i>Number</i>\r
+     * <div class="sub-desc">The current index within the <code>composite</code>\r
+     * </div></li>\r
+     * </ul></div>\r
+     * @param {Object} scope (optional) The scope to call the specified function.\r
+     * Defaults to the <code>element</code> at the current <code>index</code>\r
+     * within the composite.\r
+     * @return {CompositeElement} this\r
+     */\r
+    each : function(fn, scope){\r
+        Ext.each(this.elements, function(e, i){\r
+            return fn.call(scope || e, e, this, i);\r
         }, this);\r
         return this;\r
     }\r
@@ -8449,7 +8675,7 @@ Ext.Element.select = function(selector, unique, root){
     }\r
 \r
     return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);\r
-};
+};\r
 \r
 /**\r
  * Selects elements based on the passed CSS selector to enable {@link Ext.Element Element} methods\r
@@ -8540,136 +8766,6 @@ Ext.select = Ext.Element.select;(function(){
         Ext.data.Connection.superclass.constructor.call(this);\r
     };\r
 \r
-    // private\r
-    function handleResponse(response){\r
-        this.transId = false;\r
-        var options = response.argument.options;\r
-        response.argument = options ? options.argument : null;\r
-        this.fireEvent(REQUESTCOMPLETE, this, response, options);\r
-        if(options.success){\r
-            options.success.call(options.scope, response, options);\r
-        }\r
-        if(options.callback){\r
-            options.callback.call(options.scope, options, true, response);\r
-        }\r
-    }\r
-\r
-    // private\r
-    function handleFailure(response, e){\r
-        this.transId = false;\r
-        var options = response.argument.options;\r
-        response.argument = options ? options.argument : null;\r
-        this.fireEvent(REQUESTEXCEPTION, this, response, options, e);\r
-        if(options.failure){\r
-            options.failure.call(options.scope, response, options);\r
-        }\r
-        if(options.callback){\r
-            options.callback.call(options.scope, options, false, response);\r
-        }\r
-    }\r
-\r
-    // private\r
-    function doFormUpload(o, ps, url){\r
-        var id = Ext.id(),\r
-            doc = document,\r
-            frame = doc.createElement('iframe'),\r
-            form = Ext.getDom(o.form),\r
-            hiddens = [],\r
-            hd,\r
-            encoding = 'multipart/form-data',\r
-            buf = {\r
-                target: form.target,\r
-                method: form.method,\r
-                encoding: form.encoding,\r
-                enctype: form.enctype,\r
-                action: form.action\r
-            };\r
-            \r
-        Ext.apply(frame, {\r
-            id: id,\r
-            name: id,\r
-            className: 'x-hidden',\r
-            src: Ext.SSL_SECURE_URL // for IE\r
-        });     \r
-        doc.body.appendChild(frame);\r
-        \r
-        // This is required so that IE doesn't pop the response up in a new window.\r
-        if(Ext.isIE){\r
-           document.frames[id].name = id;\r
-        }\r
-        \r
-        Ext.apply(form, {\r
-            target: id,\r
-            method: POST,\r
-            enctype: encoding,\r
-            encoding: encoding,\r
-            action: url || buf.action\r
-        });\r
-        \r
-        // add dynamic params            \r
-        ps = Ext.urlDecode(ps, false);\r
-        for(var k in ps){\r
-            if(ps.hasOwnProperty(k)){\r
-                hd = doc.createElement('input');\r
-                hd.type = 'hidden';                    \r
-                hd.value = ps[hd.name = k];\r
-                form.appendChild(hd);\r
-                hiddens.push(hd);\r
-            }\r
-        }        \r
-\r
-        function cb(){\r
-            var me = this,\r
-                // bogus response object\r
-                r = {responseText : '',\r
-                     responseXML : null,\r
-                     argument : o.argument},\r
-                doc,\r
-                firstChild;\r
-\r
-            try{ \r
-                doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;\r
-                if(doc){\r
-                    if(doc.body){\r
-                        if(/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)){ // json response wrapped in textarea                        \r
-                            r.responseText = firstChild.value;\r
-                        }else{\r
-                            r.responseText = doc.body.innerHTML;\r
-                        }\r
-                    }\r
-                    //in IE the document may still have a body even if returns XML.\r
-                    r.responseXML = doc.XMLDocument || doc;\r
-                }\r
-            }\r
-            catch(e) {}\r
-\r
-            Ext.EventManager.removeListener(frame, LOAD, cb, me);\r
-\r
-            me.fireEvent(REQUESTCOMPLETE, me, r, o);\r
-            \r
-            function runCallback(fn, scope, args){\r
-                if(Ext.isFunction(fn)){\r
-                    fn.apply(scope, args);\r
-                }\r
-            }\r
-\r
-            runCallback(o.success, o.scope, [r, o]);\r
-            runCallback(o.callback, o.scope, [o, true, r]);\r
-\r
-            if(!me.debugUploads){\r
-                setTimeout(function(){Ext.removeNode(frame);}, 100);\r
-            }\r
-        }\r
-\r
-        Ext.EventManager.on(frame, LOAD, cb, this);\r
-        form.submit();\r
-        \r
-        Ext.apply(form, buf);\r
-        Ext.each(hiddens, function(h) {\r
-            Ext.removeNode(h);\r
-        });\r
-    }\r
-\r
     Ext.extend(Ext.data.Connection, Ext.util.Observable, {\r
         /**\r
          * @cfg {String} url (Optional) <p>The default URL to be used for requests to the server. Defaults to undefined.</p>\r
@@ -8827,8 +8923,8 @@ Ext.Ajax.request({
                 var p = o.params,\r
                     url = o.url || me.url,                \r
                     method,\r
-                    cb = {success: handleResponse,\r
-                          failure: handleFailure,\r
+                    cb = {success: me.handleResponse,\r
+                          failure: me.handleFailure,\r
                           scope: me,\r
                           argument: {options: o},\r
                           timeout : o.timeout || me.timeout\r
@@ -8850,7 +8946,7 @@ Ext.Ajax.request({
                 if((form = Ext.getDom(o.form))){\r
                     url = url || form.action;\r
                      if(o.isUpload || /multipart\/form-data/i.test(form.getAttribute("enctype"))) { \r
-                         return doFormUpload.call(me, o, p, url);\r
+                         return me.doFormUpload.call(me, o, p, url);\r
                      }\r
                     serForm = Ext.lib.Ajax.serializeForm(form);                    \r
                     p = p ? (p + '&' + serForm) : serForm;\r
@@ -8896,6 +8992,136 @@ Ext.Ajax.request({
             if(transId || this.isLoading()){\r
                 Ext.lib.Ajax.abort(transId || this.transId);\r
             }\r
+        },\r
+\r
+        // private\r
+        handleResponse : function(response){\r
+            this.transId = false;\r
+            var options = response.argument.options;\r
+            response.argument = options ? options.argument : null;\r
+            this.fireEvent(REQUESTCOMPLETE, this, response, options);\r
+            if(options.success){\r
+                options.success.call(options.scope, response, options);\r
+            }\r
+            if(options.callback){\r
+                options.callback.call(options.scope, options, true, response);\r
+            }\r
+        },\r
+\r
+        // private\r
+        handleFailure : function(response, e){\r
+            this.transId = false;\r
+            var options = response.argument.options;\r
+            response.argument = options ? options.argument : null;\r
+            this.fireEvent(REQUESTEXCEPTION, this, response, options, e);\r
+            if(options.failure){\r
+                options.failure.call(options.scope, response, options);\r
+            }\r
+            if(options.callback){\r
+                options.callback.call(options.scope, options, false, response);\r
+            }\r
+        },\r
+\r
+        // private\r
+        doFormUpload : function(o, ps, url){\r
+            var id = Ext.id(),\r
+                doc = document,\r
+                frame = doc.createElement('iframe'),\r
+                form = Ext.getDom(o.form),\r
+                hiddens = [],\r
+                hd,\r
+                encoding = 'multipart/form-data',\r
+                buf = {\r
+                    target: form.target,\r
+                    method: form.method,\r
+                    encoding: form.encoding,\r
+                    enctype: form.enctype,\r
+                    action: form.action\r
+                };\r
+\r
+            Ext.fly(frame).set({\r
+                id: id,\r
+                name: id,\r
+                cls: 'x-hidden',\r
+                src: Ext.SSL_SECURE_URL // for IE\r
+            });\r
+            doc.body.appendChild(frame);\r
+\r
+            // This is required so that IE doesn't pop the response up in a new window.\r
+            if(Ext.isIE){\r
+               document.frames[id].name = id;\r
+            }\r
+\r
+            Ext.fly(form).set({\r
+                target: id,\r
+                method: POST,\r
+                enctype: encoding,\r
+                encoding: encoding,\r
+                action: url || buf.action\r
+            });\r
+\r
+            // add dynamic params\r
+            Ext.iterate(Ext.urlDecode(ps, false), function(k, v){\r
+                hd = doc.createElement('input');\r
+                Ext.fly(hd).set({\r
+                    type: 'hidden',\r
+                    value: v,\r
+                    name: k\r
+                });\r
+                form.appendChild(hd);\r
+                hiddens.push(hd);\r
+            });\r
+\r
+            function cb(){\r
+                var me = this,\r
+                    // bogus response object\r
+                    r = {responseText : '',\r
+                         responseXML : null,\r
+                         argument : o.argument},\r
+                    doc,\r
+                    firstChild;\r
+\r
+                try{\r
+                    doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;\r
+                    if(doc){\r
+                        if(doc.body){\r
+                            if(/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)){ // json response wrapped in textarea\r
+                                r.responseText = firstChild.value;\r
+                            }else{\r
+                                r.responseText = doc.body.innerHTML;\r
+                            }\r
+                        }\r
+                        //in IE the document may still have a body even if returns XML.\r
+                        r.responseXML = doc.XMLDocument || doc;\r
+                    }\r
+                }\r
+                catch(e) {}\r
+\r
+                Ext.EventManager.removeListener(frame, LOAD, cb, me);\r
+\r
+                me.fireEvent(REQUESTCOMPLETE, me, r, o);\r
+\r
+                function runCallback(fn, scope, args){\r
+                    if(Ext.isFunction(fn)){\r
+                        fn.apply(scope, args);\r
+                    }\r
+                }\r
+\r
+                runCallback(o.success, o.scope, [r, o]);\r
+                runCallback(o.callback, o.scope, [o, true, r]);\r
+\r
+                if(!me.debugUploads){\r
+                    setTimeout(function(){Ext.removeNode(frame);}, 100);\r
+                }\r
+            }\r
+\r
+            Ext.EventManager.on(frame, LOAD, cb, this);\r
+            form.submit();\r
+\r
+            Ext.fly(form).set(buf);\r
+            Ext.each(hiddens, function(h) {\r
+                Ext.removeNode(h);\r
+            });\r
         }\r
     });\r
 })();\r
@@ -9518,7 +9744,7 @@ Ext.Updater.defaults = {
     * Blank page URL to use with SSL file uploads (defaults to {@link Ext#SSL_SECURE_URL} if set, or "javascript:false").
     * @type String
     */
-    sslBlankUrl : (Ext.SSL_SECURE_URL || "javascript:false")      
+    sslBlankUrl : Ext.SSL_SECURE_URL      
 };
 
 
@@ -10350,15 +10576,15 @@ dt = Date.parseDate("2006-02-29 03:20:01", "Y-m-d H:i:s", true); // returns null
         a: {
             g:1,
             c:"if (results[{0}] == 'am') {\n"
-                + "if (h == 12) { h = 0; }\n"
-                + "} else { if (h < 12) { h += 12; }}",
+                + "if (!h || h == 12) { h = 0; }\n"
+                + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
             s:"(am|pm)"
         },
         A: {
             g:1,
             c:"if (results[{0}] == 'AM') {\n"
-                + "if (h == 12) { h = 0; }\n"
-                + "} else { if (h < 12) { h += 12; }}",
+                + "if (!h || h == 12) { h = 0; }\n"
+                + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
             s:"(AM|PM)"
         },
         g: function() {
@@ -10534,12 +10760,12 @@ Ext.apply(Date.prototype, {
      * @return {Number} 0 to 364 (365 in leap years).
      */
     getDayOfYear: function() {
-        var i = 0,
-            num = 0,
+        var num = 0,
             d = this.clone(),
-            m = this.getMonth();
+            m = this.getMonth(),
+            i;
 
-        for (i = 0, d.setMonth(0); i < m; d.setMonth(++i)) {
+        for (i = 0, d.setDate(1), d.setMonth(0); i < m; d.setMonth(++i)) {
             num += d.getDaysInMonth();
         }
         return num + this.getDate() - 1;
@@ -10894,9 +11120,10 @@ Ext.get('myInputField').on('keypress', function(){
  * option <tt>buffer</tt> for {@link Ext.util.Observable#addListener addListener/on} will
  * also setup a delayed task for you to buffer events.</p> 
  * @constructor The parameters to this constructor serve as defaults and are not required.
- * @param {Function} fn (optional) The default function to timeout
- * @param {Object} scope (optional) The default scope of that timeout
- * @param {Array} args (optional) The default Array of arguments
+ * @param {Function} fn (optional) The default function to call.
+ * @param {Object} scope The default scope (The <code><b>this</b></code> reference) in which the
+ * function is called. If not specified, <code>this</code> will refer to the browser window.
+ * @param {Array} args (optional) The default Array of arguments.
  */
 Ext.util.DelayedTask = function(fn, scope, args){
     var me = this,
@@ -10911,7 +11138,8 @@ Ext.util.DelayedTask = function(fn, scope, args){
      * Cancels any pending timeout and queues a new one
      * @param {Number} delay The milliseconds to delay
      * @param {Function} newFn (optional) Overrides function passed to constructor
-     * @param {Object} newScope (optional) Overrides scope passed to constructor
+     * @param {Object} newScope (optional) Overrides scope passed to constructor. Remember that if no scope
+     * is specified, <code>this</code> will refer to the browser window.
      * @param {Array} newArgs (optional) Overrides args passed to constructor
      */
     me.delay = function(delay, newFn, newScope, newArgs){
@@ -10936,8 +11164,9 @@ Ext.util.DelayedTask = function(fn, scope, args){
  * @extends Ext.util.Observable\r
  * A Collection class that maintains both numeric indexes and keys and exposes events.\r
  * @constructor\r
- * @param {Boolean} allowFunctions True if the addAll function should add function references to the\r
- * collection (defaults to false)\r
+ * @param {Boolean} allowFunctions Specify <tt>true</tt> if the {@link #addAll}\r
+ * function should add function references to the collection. Defaults to\r
+ * <tt>false</tt>.\r
  * @param {Function} keyFn A function that can accept an item of the type(s) stored in this MixedCollection\r
  * and return the key value for that item.  This is used when available to look up the key on items that\r
  * were passed without an explicit key parameter to a MixedCollection method.  Passing this parameter is\r
@@ -10953,7 +11182,7 @@ Ext.util.MixedCollection = function(allowFunctions, keyFn){
          * @event clear\r
          * Fires when the collection is cleared.\r
          */\r
-        "clear",\r
+        'clear',\r
         /**\r
          * @event add\r
          * Fires when an item is added to the collection.\r
@@ -10961,7 +11190,7 @@ Ext.util.MixedCollection = function(allowFunctions, keyFn){
          * @param {Object} o The item added.\r
          * @param {String} key The key associated with the added item.\r
          */\r
-        "add",\r
+        'add',\r
         /**\r
          * @event replace\r
          * Fires when an item is replaced in the collection.\r
@@ -10969,15 +11198,15 @@ Ext.util.MixedCollection = function(allowFunctions, keyFn){
          * @param {Object} old The item being replaced.\r
          * @param {Object} new The new item.\r
          */\r
-        "replace",\r
+        'replace',\r
         /**\r
          * @event remove\r
          * Fires when an item is removed from the collection.\r
          * @param {Object} o The item being removed.\r
          * @param {String} key (optional) The key associated with the removed item.\r
          */\r
-        "remove",\r
-        "sort"\r
+        'remove',\r
+        'sort'\r
     );\r
     this.allowFunctions = allowFunctions === true;\r
     if(keyFn){\r
@@ -10987,19 +11216,25 @@ Ext.util.MixedCollection = function(allowFunctions, keyFn){
 };\r
 \r
 Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {\r
+\r
+    /**\r
+     * @cfg {Boolean} allowFunctions Specify <tt>true</tt> if the {@link #addAll}\r
+     * function should add function references to the collection. Defaults to\r
+     * <tt>false</tt>.\r
+     */\r
     allowFunctions : false,\r
 \r
-/**\r
- * Adds an item to the collection. Fires the {@link #add} event when complete.\r
- * @param {String} key <p>The key to associate with the item, or the new item.</p>\r
- * <p>If you supplied a {@link #getKey} implementation for this MixedCollection, or if the key\r
- * of your stored items is in a property called <tt><b>id</b></tt>, then the MixedCollection\r
- * will be able to <i>derive</i> the key for the new item. In this case just pass the new item in\r
* this parameter.</p>\r
- * @param {Object} o The item to add.\r
- * @return {Object} The item added.\r
- */\r
-    add: function(key, o){\r
+    /**\r
    * Adds an item to the collection. Fires the {@link #add} event when complete.\r
    * @param {String} key <p>The key to associate with the item, or the new item.</p>\r
+     * <p>If a {@link #getKey} implementation was specified for this MixedCollection,\r
+     * or if the key of the stored items is in a property called <tt><b>id</b></tt>,\r
+     * the MixedCollection will be able to <i>derive</i> the key for the new item.\r
    * In this case just pass the new item in this parameter.</p>\r
    * @param {Object} o The item to add.\r
    * @return {Object} The item added.\r
    */\r
+    add : function(key, o){\r
         if(arguments.length == 1){\r
             o = arguments[0];\r
             key = this.getKey(o);\r
@@ -11018,11 +11253,10 @@ Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
         return o;\r
     },\r
 \r
-/**\r
-  * MixedCollection has a generic way to fetch keys if you implement getKey.  The default implementation\r
-  * simply returns <tt style="font-weight:bold;">item.id</tt> but you can provide your own implementation\r
-  * to return a different value as in the following examples:\r
-<pre><code>\r
+    /**\r
+      * MixedCollection has a generic way to fetch keys if you implement getKey.  The default implementation\r
+      * simply returns <b><code>item.id</code></b> but you can provide your own implementation\r
+      * to return a different value as in the following examples:<pre><code>\r
 // normal way\r
 var mc = new Ext.util.MixedCollection();\r
 mc.add(someEl.dom.id, someEl);\r
@@ -11043,46 +11277,48 @@ var mc = new Ext.util.MixedCollection(false, function(el){
 });\r
 mc.add(someEl);\r
 mc.add(otherEl);\r
-</code></pre>\r
- * @param {Object} item The item for which to find the key.\r
- * @return {Object} The key for the passed item.\r
- */\r
+     * </code></pre>\r
    * @param {Object} item The item for which to find the key.\r
    * @return {Object} The key for the passed item.\r
    */\r
     getKey : function(o){\r
          return o.id;\r
     },\r
 \r
-/**\r
- * Replaces an item in the collection. Fires the {@link #replace} event when complete.\r
- * @param {String} key <p>The key associated with the item to replace, or the replacement item.</p>\r
- * <p>If you supplied a {@link #getKey} implementation for this MixedCollection, or if the key\r
- * of your stored items is in a property called <tt><b>id</b></tt>, then the MixedCollection\r
- * will be able to <i>derive</i> the key of the replacement item. If you want to replace an item\r
- * with one having the same key value, then just pass the replacement item in this parameter.</p>\r
- * @param o {Object} o (optional) If the first parameter passed was a key, the item to associate\r
- * with that key.\r
- * @return {Object}  The new item.\r
- */\r
+    /**\r
    * Replaces an item in the collection. Fires the {@link #replace} event when complete.\r
    * @param {String} key <p>The key associated with the item to replace, or the replacement item.</p>\r
    * <p>If you supplied a {@link #getKey} implementation for this MixedCollection, or if the key\r
    * of your stored items is in a property called <tt><b>id</b></tt>, then the MixedCollection\r
    * will be able to <i>derive</i> the key of the replacement item. If you want to replace an item\r
    * with one having the same key value, then just pass the replacement item in this parameter.</p>\r
    * @param o {Object} o (optional) If the first parameter passed was a key, the item to associate\r
    * with that key.\r
    * @return {Object}  The new item.\r
    */\r
     replace : function(key, o){\r
         if(arguments.length == 1){\r
             o = arguments[0];\r
             key = this.getKey(o);\r
         }\r
         var old = this.map[key];\r
-        if(typeof key == "undefined" || key === null || typeof old == "undefined"){\r
+        if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){\r
              return this.add(key, o);\r
         }\r
         var index = this.indexOfKey(key);\r
         this.items[index] = o;\r
         this.map[key] = o;\r
-        this.fireEvent("replace", key, old, o);\r
+        this.fireEvent('replace', key, old, o);\r
         return o;\r
     },\r
 \r
-/**\r
- * Adds all elements of an Array or an Object to the collection.\r
- * @param {Object/Array} objs An Object containing properties which will be added to the collection, or\r
- * an Array of values, each of which are added to the collection.\r
- */\r
+    /**\r
+     * Adds all elements of an Array or an Object to the collection.\r
+     * @param {Object/Array} objs An Object containing properties which will be added\r
+     * to the collection, or an Array of values, each of which are added to the collection.\r
+     * Functions references will be added to the collection if <code>{@link #allowFunctions}</code>\r
+     * has been set to <tt>true</tt>.\r
+     */\r
     addAll : function(objs){\r
         if(arguments.length > 1 || Ext.isArray(objs)){\r
             var args = arguments.length > 1 ? arguments : objs;\r
@@ -11091,24 +11327,24 @@ mc.add(otherEl);
             }\r
         }else{\r
             for(var key in objs){\r
-                if(this.allowFunctions || typeof objs[key] != "function"){\r
+                if(this.allowFunctions || typeof objs[key] != 'function'){\r
                     this.add(key, objs[key]);\r
                 }\r
             }\r
         }\r
     },\r
 \r
-/**\r
- * Executes the specified function once for every item in the collection, passing the following arguments:\r
- * <div class="mdetail-params"><ul>\r
- * <li><b>item</b> : Mixed<p class="sub-desc">The collection item</p></li>\r
- * <li><b>index</b> : Number<p class="sub-desc">The item's index</p></li>\r
- * <li><b>length</b> : Number<p class="sub-desc">The total number of items in the collection</p></li>\r
- * </ul></div>\r
- * The function should return a boolean value. Returning false from the function will stop the iteration.\r
- * @param {Function} fn The function to execute for each item.\r
- * @param {Object} scope (optional) The scope in which to execute the function.\r
- */\r
+    /**\r
    * Executes the specified function once for every item in the collection, passing the following arguments:\r
    * <div class="mdetail-params"><ul>\r
    * <li><b>item</b> : Mixed<p class="sub-desc">The collection item</p></li>\r
    * <li><b>index</b> : Number<p class="sub-desc">The item's index</p></li>\r
    * <li><b>length</b> : Number<p class="sub-desc">The total number of items in the collection</p></li>\r
    * </ul></div>\r
    * The function should return a boolean value. Returning false from the function will stop the iteration.\r
    * @param {Function} fn The function to execute for each item.\r
    * @param {Object} scope (optional) The scope in which to execute the function.\r
    */\r
     each : function(fn, scope){\r
         var items = [].concat(this.items); // each safe for removal\r
         for(var i = 0, len = items.length; i < len; i++){\r
@@ -11118,12 +11354,12 @@ mc.add(otherEl);
         }\r
     },\r
 \r
-/**\r
- * Executes the specified function once for every key in the collection, passing each\r
- * key, and its associated item as the first two parameters.\r
- * @param {Function} fn The function to execute for each item.\r
- * @param {Object} scope (optional) The scope in which to execute the function.\r
- */\r
+    /**\r
    * Executes the specified function once for every key in the collection, passing each\r
    * key, and its associated item as the first two parameters.\r
    * @param {Function} fn The function to execute for each item.\r
    * @param {Object} scope (optional) The scope in which to execute the function.\r
    */\r
     eachKey : function(fn, scope){\r
         for(var i = 0, len = this.keys.length; i < len; i++){\r
             fn.call(scope || window, this.keys[i], this.items[i], i, len);\r
@@ -11146,13 +11382,13 @@ mc.add(otherEl);
         return null;\r
     },\r
 \r
-/**\r
- * Inserts an item at the specified index in the collection. Fires the {@link #add} event when complete.\r
- * @param {Number} index The index to insert the item at.\r
- * @param {String} key The key to associate with the new item, or the item itself.\r
- * @param {Object} o (optional) If the second parameter was a key, the new item.\r
- * @return {Object} The item inserted.\r
- */\r
+    /**\r
    * Inserts an item at the specified index in the collection. Fires the {@link #add} event when complete.\r
    * @param {Number} index The index to insert the item at.\r
    * @param {String} key The key to associate with the new item, or the item itself.\r
    * @param {Object} o (optional) If the second parameter was a key, the new item.\r
    * @return {Object} The item inserted.\r
    */\r
     insert : function(index, key, o){\r
         if(arguments.length == 2){\r
             o = arguments[1];\r
@@ -11168,160 +11404,167 @@ mc.add(otherEl);
         }\r
         this.length++;\r
         this.items.splice(index, 0, o);\r
-        if(typeof key != "undefined" && key !== null){\r
+        if(typeof key != 'undefined' && key !== null){\r
             this.map[key] = o;\r
         }\r
         this.keys.splice(index, 0, key);\r
-        this.fireEvent("add", index, o, key);\r
+        this.fireEvent('add', index, o, key);\r
         return o;\r
     },\r
 \r
-/**\r
- * Remove an item from the collection.\r
- * @param {Object} o The item to remove.\r
- * @return {Object} The item removed or false if no item was removed.\r
- */\r
+    /**\r
    * Remove an item from the collection.\r
    * @param {Object} o The item to remove.\r
    * @return {Object} The item removed or false if no item was removed.\r
    */\r
     remove : function(o){\r
         return this.removeAt(this.indexOf(o));\r
     },\r
 \r
-/**\r
- * Remove an item from a specified index in the collection. Fires the {@link #remove} event when complete.\r
- * @param {Number} index The index within the collection of the item to remove.\r
- * @return {Object} The item removed or false if no item was removed.\r
- */\r
+    /**\r
    * Remove an item from a specified index in the collection. Fires the {@link #remove} event when complete.\r
    * @param {Number} index The index within the collection of the item to remove.\r
    * @return {Object} The item removed or false if no item was removed.\r
    */\r
     removeAt : function(index){\r
         if(index < this.length && index >= 0){\r
             this.length--;\r
             var o = this.items[index];\r
             this.items.splice(index, 1);\r
             var key = this.keys[index];\r
-            if(typeof key != "undefined"){\r
+            if(typeof key != 'undefined'){\r
                 delete this.map[key];\r
             }\r
             this.keys.splice(index, 1);\r
-            this.fireEvent("remove", o, key);\r
+            this.fireEvent('remove', o, key);\r
             return o;\r
         }\r
         return false;\r
     },\r
 \r
-/**\r
- * Removed an item associated with the passed key fom the collection.\r
- * @param {String} key The key of the item to remove.\r
- * @return {Object} The item removed or false if no item was removed.\r
- */\r
+    /**\r
    * Removed an item associated with the passed key fom the collection.\r
    * @param {String} key The key of the item to remove.\r
    * @return {Object} The item removed or false if no item was removed.\r
    */\r
     removeKey : function(key){\r
         return this.removeAt(this.indexOfKey(key));\r
     },\r
 \r
-/**\r
- * Returns the number of items in the collection.\r
- * @return {Number} the number of items in the collection.\r
- */\r
+    /**\r
    * Returns the number of items in the collection.\r
    * @return {Number} the number of items in the collection.\r
    */\r
     getCount : function(){\r
         return this.length;\r
     },\r
-\r
-/**\r
- * Returns index within the collection of the passed Object.\r
- * @param {Object} o The item to find the index of.\r
- * @return {Number} index of the item. Returns -1 if not found.\r
- */\r
+    \r
+    /**\r
    * Returns index within the collection of the passed Object.\r
    * @param {Object} o The item to find the index of.\r
    * @return {Number} index of the item. Returns -1 if not found.\r
    */\r
     indexOf : function(o){\r
         return this.items.indexOf(o);\r
     },\r
 \r
-/**\r
- * Returns index within the collection of the passed key.\r
- * @param {String} key The key to find the index of.\r
- * @return {Number} index of the key.\r
- */\r
+    /**\r
    * Returns index within the collection of the passed key.\r
    * @param {String} key The key to find the index of.\r
    * @return {Number} index of the key.\r
    */\r
     indexOfKey : function(key){\r
         return this.keys.indexOf(key);\r
     },\r
 \r
-/**\r
- * Returns the item associated with the passed key OR index. Key has priority over index.  This is the equivalent\r
- * of calling {@link #key} first, then if nothing matched calling {@link #itemAt}.\r
- * @param {String/Number} key The key or index of the item.\r
- * @return {Object} If the item is found, returns the item.  If the item was not found, returns <tt>undefined</tt>.\r
- * If an item was found, but is a Class, returns <tt>null</tt>.\r
- */\r
+    /**\r
+     * Returns the item associated with the passed key OR index.\r
+     * Key has priority over index.  This is the equivalent\r
+     * of calling {@link #key} first, then if nothing matched calling {@link #itemAt}.\r
+     * @param {String/Number} key The key or index of the item.\r
+     * @return {Object} If the item is found, returns the item.  If the item was not found, returns <tt>undefined</tt>.\r
+     * If an item was found, but is a Class, returns <tt>null</tt>.\r
+     */\r
     item : function(key){\r
         var mk = this.map[key],\r
             item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;\r
         return !Ext.isFunction(item) || this.allowFunctions ? item : null; // for prototype!\r
     },\r
 \r
-/**\r
- * Returns the item at the specified index.\r
- * @param {Number} index The index of the item.\r
- * @return {Object} The item at the specified index.\r
- */\r
+    /**\r
    * Returns the item at the specified index.\r
    * @param {Number} index The index of the item.\r
    * @return {Object} The item at the specified index.\r
    */\r
     itemAt : function(index){\r
         return this.items[index];\r
     },\r
 \r
-/**\r
- * Returns the item associated with the passed key.\r
- * @param {String/Number} key The key of the item.\r
- * @return {Object} The item associated with the passed key.\r
- */\r
+    /**\r
    * Returns the item associated with the passed key.\r
    * @param {String/Number} key The key of the item.\r
    * @return {Object} The item associated with the passed key.\r
    */\r
     key : function(key){\r
         return this.map[key];\r
     },\r
 \r
-/**\r
- * Returns true if the collection contains the passed Object as an item.\r
- * @param {Object} o  The Object to look for in the collection.\r
- * @return {Boolean} True if the collection contains the Object as an item.\r
- */\r
+    /**\r
    * Returns true if the collection contains the passed Object as an item.\r
    * @param {Object} o  The Object to look for in the collection.\r
    * @return {Boolean} True if the collection contains the Object as an item.\r
    */\r
     contains : function(o){\r
         return this.indexOf(o) != -1;\r
     },\r
 \r
-/**\r
- * Returns true if the collection contains the passed Object as a key.\r
- * @param {String} key The key to look for in the collection.\r
- * @return {Boolean} True if the collection contains the Object as a key.\r
- */\r
+    /**\r
    * Returns true if the collection contains the passed Object as a key.\r
    * @param {String} key The key to look for in the collection.\r
    * @return {Boolean} True if the collection contains the Object as a key.\r
    */\r
     containsKey : function(key){\r
-        return typeof this.map[key] != "undefined";\r
+        return typeof this.map[key] != 'undefined';\r
     },\r
 \r
-/**\r
- * Removes all items from the collection.  Fires the {@link #clear} event when complete.\r
- */\r
+    /**\r
    * Removes all items from the collection.  Fires the {@link #clear} event when complete.\r
    */\r
     clear : function(){\r
         this.length = 0;\r
         this.items = [];\r
         this.keys = [];\r
         this.map = {};\r
-        this.fireEvent("clear");\r
+        this.fireEvent('clear');\r
     },\r
 \r
-/**\r
- * Returns the first item in the collection.\r
- * @return {Object} the first item in the collection..\r
- */\r
+    /**\r
    * Returns the first item in the collection.\r
    * @return {Object} the first item in the collection..\r
    */\r
     first : function(){\r
         return this.items[0];\r
     },\r
 \r
-/**\r
- * Returns the last item in the collection.\r
- * @return {Object} the last item in the collection..\r
- */\r
+    /**\r
    * Returns the last item in the collection.\r
    * @return {Object} the last item in the collection..\r
    */\r
     last : function(){\r
         return this.items[this.length-1];\r
     },\r
 \r
-    // private\r
+    /**\r
+     * @private\r
+     * @param {String} property Property to sort by ('key', 'value', or 'index')\r
+     * @param {String} dir (optional) Direction to sort 'ASC' or 'DESC'. Defaults to 'ASC'.\r
+     * @param {Function} fn (optional) Comparison function that defines the sort order.\r
+     * Defaults to sorting by numeric value.  \r
+     */\r
     _sort : function(property, dir, fn){\r
         var i,\r
             len,\r
-            dsc = String(dir).toUpperCase() == "DESC" ? -1 : 1,\r
+            dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1,\r
             c = [], k = this.keys, items = this.items;\r
             \r
         fn = fn || function(a, b){\r
@@ -11341,25 +11584,27 @@ mc.add(otherEl);
             items[i] = c[i].value;\r
             k[i] = c[i].key;\r
         }\r
-        this.fireEvent("sort", this);\r
+        this.fireEvent('sort', this);\r
     },\r
 \r
     /**\r
-     * Sorts this collection with the passed comparison function\r
-     * @param {String} direction (optional) "ASC" or "DESC"\r
-     * @param {Function} fn (optional) comparison function\r
+     * Sorts this collection by <b>item</b> value with the passed comparison function.\r
+     * @param {String} direction (optional) 'ASC' or 'DESC'. Defaults to 'ASC'.\r
+     * @param {Function} fn (optional) Comparison function that defines the sort order.\r
+     * Defaults to sorting by numeric value.  \r
      */\r
     sort : function(dir, fn){\r
-        this._sort("value", dir, fn);\r
+        this._sort('value', dir, fn);\r
     },\r
 \r
     /**\r
-     * Sorts this collection by keys\r
-     * @param {String} direction (optional) "ASC" or "DESC"\r
-     * @param {Function} fn (optional) a comparison function (defaults to case insensitive string)\r
+     * Sorts this collection by <b>key</b>s.\r
+     * @param {String} direction (optional) 'ASC' or 'DESC'. Defaults to 'ASC'.\r
+     * @param {Function} fn (optional) Comparison function that defines the sort order.\r
+     * Defaults to sorting by case insensitive string.  \r
      */\r
     keySort : function(dir, fn){\r
-        this._sort("key", dir, fn || function(a, b){\r
+        this._sort('key', dir, fn || function(a, b){\r
             var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();\r
             return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);\r
         });\r
@@ -11367,8 +11612,8 @@ mc.add(otherEl);
 \r
     /**\r
      * Returns a range of items in this collection\r
-     * @param {Number} startIndex (optional) defaults to 0\r
-     * @param {Number} endIndex (optional) default to the last item\r
+     * @param {Number} startIndex (optional) The starting index. Defaults to 0.\r
+     * @param {Number} endIndex (optional) The ending index. Defaults to the last item.\r
      * @return {Array} An array of items\r
      */\r
     getRange : function(start, end){\r
@@ -11377,7 +11622,7 @@ mc.add(otherEl);
             return [];\r
         }\r
         start = start || 0;\r
-        end = Math.min(typeof end == "undefined" ? this.length-1 : end, this.length-1);\r
+        end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1);\r
         var i, r = [];\r
         if(start <= end){\r
             for(i = start; i <= end; i++) {\r
@@ -11494,11 +11739,13 @@ mc.add(otherEl);
 });\r
 /**\r
  * This method calls {@link #item item()}.\r
- * Returns the item associated with the passed key OR index. Key has priority over index.  This is the equivalent\r
- * of calling {@link #key} first, then if nothing matched calling {@link #itemAt}.\r
+ * Returns the item associated with the passed key OR index. Key has priority\r
+ * over index.  This is the equivalent of calling {@link #key} first, then if\r
+ * nothing matched calling {@link #itemAt}.\r
  * @param {String/Number} key The key or index of the item.\r
- * @return {Object} If the item is found, returns the item.  If the item was not found, returns <tt>undefined</tt>.\r
- * If an item was found, but is a Class, returns <tt>null</tt>.\r
+ * @return {Object} If the item is found, returns the item.  If the item was\r
+ * not found, returns <tt>undefined</tt>. If an item was found, but is a Class,\r
+ * returns <tt>null</tt>.\r
  */\r
 Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;/**
  * @class Ext.util.JSON
@@ -11527,35 +11774,39 @@ Ext.util.JSON = new (function(){
             return eval("(" + json + ')');    
         },
         doEncode = function(o){
-            if(typeof o == "undefined" || o === null){
+            if(!Ext.isDefined(o) || o === null){
                 return "null";
             }else if(Ext.isArray(o)){
                 return encodeArray(o);
-            }else if(Object.prototype.toString.apply(o) === '[object Date]'){
+            }else if(Ext.isDate(o)){
                 return Ext.util.JSON.encodeDate(o);
-            }else if(typeof o == "string"){
+            }else if(Ext.isString(o)){
                 return encodeString(o);
             }else if(typeof o == "number"){
+                //don't use isNumber here, since finite checks happen inside isNumber
                 return isFinite(o) ? String(o) : "null";
-            }else if(typeof o == "boolean"){
+            }else if(Ext.isBoolean(o)){
                 return String(o);
             }else {
                 var a = ["{"], b, i, v;
                 for (i in o) {
-                    if(!useHasOwn || o.hasOwnProperty(i)) {
-                        v = o[i];
-                        switch (typeof v) {
-                        case "undefined":
-                        case "function":
-                        case "unknown":
-                            break;
-                        default:
-                            if(b){
-                                a.push(',');
+                    // don't encode DOM objects
+                    if(!o.getElementsByTagName){
+                        if(!useHasOwn || o.hasOwnProperty(i)) {
+                            v = o[i];
+                            switch (typeof v) {
+                            case "undefined":
+                            case "function":
+                            case "unknown":
+                                break;
+                            default:
+                                if(b){
+                                    a.push(',');
+                                }
+                                a.push(doEncode(i), ":",
+                                        v === null ? "null" : doEncode(v));
+                                b = true;
                             }
-                            a.push(doEncode(i), ":",
-                                    v === null ? "null" : doEncode(v));
-                            b = true;
                         }
                     }
                 }
@@ -12020,12 +12271,38 @@ Ext.util.Format = function(){
 }();/**
  * @class Ext.XTemplate
  * @extends Ext.Template
- * <p>A template class that supports advanced functionality like autofilling arrays, conditional processing with
- * basic comparison operators, sub-templates, basic math function support, special built-in template variables,
- * inline code execution and more.  XTemplate also provides the templating mechanism built into {@link Ext.DataView}.</p>
- * <p>XTemplate supports 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.  The following examples demonstrate all of the supported features.
- * This is the data object used for reference in each code example:</p>
+ * <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.DataView}</li>
+ * <li>{@link Ext.ListView}</li>
+ * <li>{@link Ext.form.ComboBox}</li>
+ * <li>{@link Ext.grid.TemplateColumn}</li>
+ * <li>{@link Ext.grid.GroupingView}</li>
+ * <li>{@link Ext.menu.Item}</li>
+ * <li>{@link Ext.layout.MenuLayout}</li>
+ * <li>{@link Ext.ColorPalette}</li>
+ * </ul></div></p>
+ * 
+ * <p>For example usage {@link #XTemplate see the constructor}.</p>  
+ *   
+ * @constructor
+ * The {@link Ext.Template#Template Ext.Template constructor} 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: 'Jack Slocum',
@@ -12049,104 +12326,161 @@ var data = {
     }]
 };
  * </code></pre>
- * <p><b>Auto filling of arrays</b><br/>The <tt>tpl</tt> tag and the <tt>for</tt> operator are used
- * to process the provided data object. If <tt>for="."</tt> is specified, the data object provided
- * is examined. If the variable 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:</p>
+ * </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 for=".">',
-        '&lt;p>{name}&lt;/p>',
+    '&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><b>Scope switching</b><br/>The <tt>for</tt> property can be leveraged to access specified members
- * of the provided data object to populate the template:</p>
+ * <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;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><b>Access to parent object from within sub-template scope</b><br/>When processing a sub-template, for example while
- * looping through a child array, you can access the parent object's members via the <tt>parent</tt> object:</p>
+ * <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">',  // <-- Note that the &gt; is encoded
+        '&lt;tpl if="age > 1">',
             '&lt;p>{name}&lt;/p>',
-            '&lt;p>Dad: {parent.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>
- * <p><b>Array item index and basic math support</b> <br/>While processing an array, the special variable <tt>{#}</tt>
- * will provide the current array index + 1 (starts at 1, not 0). Templates also support the basic math operators
- * + - * and / that can be applied directly on numeric data values:</p>
+ * </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 == "Jack"">Hello&lt;/tpl>
+// encode &#34; if it is part of the condition, e.g.
+&lt;tpl if="name == &#38;quot;Jack&#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">',  // <-- 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 if="age > 1">',
+            '&lt;p>{name}&lt;/p>',
         '&lt;/tpl>',
     '&lt;/tpl>&lt;/p>'
 );
 tpl.overwrite(panel.body, data);
-</code></pre>
- * <p><b>Auto-rendering of flat arrays</b> <br/>Flat arrays that contain values (and not objects) can be auto-rendered
- * using the special <tt>{.}</tt> 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}\'s favorite beverages:&lt;/p>',
-    '&lt;tpl for="drinks">',
-       '&lt;div> - {.}&lt;/div>',
-    '&lt;/tpl>'
-);
-tpl.overwrite(panel.body, data);
-</code></pre>
- * <p><b>Basic conditional logic</b> <br/>Using the <tt>tpl</tt> tag and the <tt>if</tt>
- * operator you can provide conditional checks for deciding whether or not to render specific parts of the template.
- * Note that there is no <tt>else</tt> operator &mdash; if needed, you should use two opposite <tt>if</tt> statements.
- * Properly-encoded attributes are required as seen in the following example:</p>
+ * </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>',
+            '&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>
- * <p><b>Ability to execute arbitrary inline code</b> <br/>In an XTemplate, anything between {[ ... ]}  is considered
- * code to be executed in the scope of the template. There are some special variables available in that code:
+ * </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>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>
+ * <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>
  * <li><b><tt>fm</tt></b>: An alias for <tt>Ext.util.Format</tt>.</li>
  * </ul>
- * This example demonstrates basic row striping using an inline code block and the <tt>xindex</tt> variable:</p>
+ * 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>',
@@ -12159,8 +12493,13 @@ var tpl = new Ext.XTemplate(
     '&lt;/tpl>&lt;/p>'
 );
 tpl.overwrite(panel.body, data);
-</code></pre>
- * <p><b>Template member functions</b> <br/>One or more member functions can be defined directly on the config
+ * </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(
@@ -12170,25 +12509,35 @@ var tpl = new Ext.XTemplate(
         '&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>', {
-     isGirl: function(name){
-         return name == 'Sara Grace';
-     },
-     isBaby: function(age){
-        return age < 1;
-     }
-});
+    '&lt;/tpl>&lt;/p>',
+    {
+        // XTemplate configuration:
+        compiled: true,
+        disableFormats: true,
+        // member functions:
+        isGirl: function(name){
+            return name == 'Sara Grace';
+        },
+        isBaby: function(age){
+            return age < 1;
+        }
+    }
+);
 tpl.overwrite(panel.body, data);
-</code></pre>
- * @constructor
- * @param {String/Array/Object} parts The HTML fragment or an array of fragments to join(""), or multiple arguments
- * to join("") that can also include a config object
+ * </code></pre>
+ * </div>
+ * </li>
+ * 
+ * </ul></div>
+ * 
+ * @param {Mixed} config
  */
 Ext.XTemplate = function(){
     Ext.XTemplate.superclass.constructor.apply(this, arguments);
@@ -12323,7 +12672,8 @@ Ext.extend(Ext.XTemplate, Ext.Template, {
         }
 
         function codeFn(m, code){
-            return "'"+ sep +'('+code+')'+sep+"'";
+            // Single quotes get escaped when the template is compiled, however we want to undo this when running code.
+            return "'" + sep + '(' + code.replace(/\\'/g, "'") + ')' + sep + "'";
         }
 
         // branched to use + in gecko and [].join() in others
@@ -12476,7 +12826,7 @@ Ext.util.CSS = function(){
        try{// try catch for cross domain access issue\r
            var ssRules = ss.cssRules || ss.rules;\r
            for(var j = ssRules.length-1; j >= 0; --j){\r
-               rules[ssRules[j].selectorText] = ssRules[j];\r
+               rules[ssRules[j].selectorText.toLowerCase()] = ssRules[j];\r
            }\r
        }catch(e){}\r
    },\r
@@ -12508,11 +12858,11 @@ Ext.util.CSS = function(){
    getRule : function(selector, refreshCache){\r
                var rs = this.getRules(refreshCache);\r
                if(!Ext.isArray(selector)){\r
-                   return rs[selector];\r
+                   return rs[selector.toLowerCase()];\r
                }\r
                for(var i = 0; i < selector.length; i++){\r
                        if(rs[selector[i]]){\r
-                               return rs[selector[i]];\r
+                               return rs[selector[i].toLowerCase()];\r
                        }\r
                }\r
                return null;\r
@@ -12791,15 +13141,6 @@ Ext.KeyNav.prototype = {
      */
     forceKeyDown : false,
 
-    // private
-    prepareEvent : function(e){
-        var k = e.getKey();
-        var h = this.keyToHandler[k];
-        if(Ext.isSafari2 && h && k >= 37 && k <= 40){
-            e.stopEvent();
-        }
-    },
-
     // private
     relay : function(e){
         var k = e.getKey();
@@ -12845,38 +13186,46 @@ Ext.KeyNav.prototype = {
         27 : "esc",
         9  : "tab"
     },
+    
+    stopKeyUp: function(e) {
+        var k = e.getKey();
+
+        if (k >= 37 && k <= 40) {
+            // *** bugfix - safari 2.x fires 2 keyup events on cursor keys
+            // *** (note: this bugfix sacrifices the "keyup" event originating from keyNav elements in Safari 2)
+            e.stopEvent();
+        }
+    },
 
        /**
         * Enable this KeyNav
         */
-       enable: function(){
-               if(this.disabled){
-            // ie won't do special keys on keypress, no one else will repeat keys with keydown
-            // the EventObject will normalize Safari automatically
-            if(this.isKeydown()){
-                this.el.on("keydown", this.relay,  this);
-            }else{
-                this.el.on("keydown", this.prepareEvent,  this);
-                this.el.on("keypress", this.relay,  this);
+       enable: function() {
+        if (this.disabled) {
+            if (Ext.isSafari2) {
+                // call stopKeyUp() on "keyup" event
+                this.el.on('keyup', this.stopKeyUp, this);
             }
-                   this.disabled = false;
-               }
-       },
+
+            this.el.on(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
+            this.disabled = false;
+        }
+    },
 
        /**
         * Disable this KeyNav
         */
-       disable: function(){
-               if(!this.disabled){
-                   if(this.isKeydown()){
-                this.el.un("keydown", this.relay, this);
-            }else{
-                this.el.un("keydown", this.prepareEvent, this);
-                this.el.un("keypress", this.relay, this);
+       disable: function() {
+        if (!this.disabled) {
+            if (Ext.isSafari2) {
+                // remove "keyup" event handler
+                this.el.un('keyup', this.stopKeyUp, this);
             }
-                   this.disabled = true;
-               }
-       },
+
+            this.el.un(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
+            this.disabled = true;
+        }
+    },
     
     /**
      * Convenience function for setting disabled/enabled by boolean.
@@ -13261,8 +13610,8 @@ Ext.util.Cookies = {
      * Create a cookie with the specified name and value. Additional settings\r
      * for the cookie may be optionally specified (for example: expiration,\r
      * access restriction, SSL).\r
-     * @param {Object} name\r
-     * @param {Object} value\r
+     * @param {String} name The name of the cookie to set. \r
+     * @param {Mixed} value The value to set for the cookie.\r
      * @param {Object} expires (Optional) Specify an expiration date the\r
      * cookie is to persist until.  Note that the specified Date object will\r
      * be converted to Greenwich Mean Time (GMT). \r
@@ -13297,7 +13646,7 @@ Ext.util.Cookies = {
      * <pre><code>\r
      * var validStatus = Ext.util.Cookies.get("valid");\r
      * </code></pre>\r
-     * @param {Object} name The name of the cookie to get\r
+     * @param {String} name The name of the cookie to get\r
      * @return {Mixed} Returns the cookie value for the specified name;\r
      * null if the cookie name does not exist.\r
      */\r
@@ -13322,8 +13671,8 @@ Ext.util.Cookies = {
 \r
     /**\r
      * Removes a cookie with the provided name from the browser\r
-     * if found.\r
-     * @param {Object} name The name of the cookie to remove\r
+     * if found by setting its expiration date to sometime in the past. \r
+     * @param {String} name The name of the cookie to remove\r
      */\r
     clear : function(name){\r
         if(Ext.util.Cookies.get(name)){\r
@@ -13422,12 +13771,12 @@ Ext.apply(Ext.Error.prototype, {
  * {@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 <tt>{@link Ext.Component#xtype xtype}</tt> provides a way to avoid instantiating child Components
+ * 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 <tt>{@link Ext.Component#xtype xtype}</tt> is specified so that if and when the Component
+ * 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 <tt>{@link Ext.Component#xtype xtypes}</tt>, see {@link Ext.Component}.</p>
+ * <p>For a list of all available <code>{@link Ext.Component#xtype xtypes}</code>, see {@link Ext.Component}.</p>
  * @singleton
  */
 Ext.ComponentMgr = function(){
@@ -13456,7 +13805,7 @@ Ext.ComponentMgr = function(){
          * Returns a component by {@link Ext.Component#id id}.
          * For additional details see {@link Ext.util.MixedCollection#get}.
          * @param {String} id The component {@link Ext.Component#id id}
-         * @return Ext.Component The Component, <tt>undefined</tt> if not found, or <tt>null</tt> if a
+         * @return Ext.Component The Component, <code>undefined</code> if not found, or <code>null</code> if a
          * Class was found.
          */
         get : function(id){
@@ -13514,7 +13863,7 @@ Ext.ComponentMgr = function(){
          * config object's {@link Ext.component#xtype 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 <tt>xtype</tt>. (Optional if the config contains a <tt>xtype</tt>).
+         * 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(config, defaultType){
@@ -13540,7 +13889,7 @@ Ext.ComponentMgr = function(){
          * config object's {@link Ext.component#ptype 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 <tt>ptype</tt>. (Optional if the config contains a <tt>ptype</tt>).
+         * 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.
          */
         createPlugin : function(config, defaultType){
@@ -13567,8 +13916,18 @@ Ext.reg = Ext.ComponentMgr.registerType; // this will be called a lot internally
  * @method preg
  */
 Ext.preg = Ext.ComponentMgr.registerPlugin;
-Ext.create = Ext.ComponentMgr.create;
 /**
+ * Shorthand for {@link Ext.ComponentMgr#create}
+ * Creates a new Component from the specified config object using the
+ * config object's {@link Ext.component#xtype 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.
+ * @member Ext
+ * @method create
+ */
+Ext.create = Ext.ComponentMgr.create;/**
  * @class Ext.Component
  * @extends Ext.util.Observable
  * <p>Base class for all Ext components.  All subclasses of Component may participate in the automated
@@ -13856,7 +14215,7 @@ Ext.Component = function(config){
 Ext.Component.AUTO_ID = 1000;
 
 Ext.extend(Ext.Component, Ext.util.Observable, {
-       // Configs below are used for all Components when rendered by FormLayout.
+    // Configs below are used for all Components when rendered by FormLayout.
     /**
      * @cfg {String} fieldLabel <p>The label text to display next to this Component (defaults to '').</p>
      * <br><p><b>Note</b>: this config is only used when this Component is rendered by a Container which
@@ -13955,7 +14314,11 @@ new Ext.FormPanel({
      * <p>See {@link Ext.layout.FormLayout}.{@link Ext.layout.FormLayout#fieldTpl fieldTpl} also.</p>
      */
     /**
-     * @cfg {String} itemCls <p>An additional CSS class to apply to the div wrapping the form item
+     * @cfg {String} itemCls
+     * <p><b>Note</b>: this config is only used when this Component is rendered by a Container which
+     * has been configured to use the <b>{@link Ext.layout.FormLayout FormLayout}</b> layout manager (e.g.
+     * {@link Ext.form.FormPanel} or specifying <tt>layout:'form'</tt>).</p><br>
+     * <p>An additional CSS class to apply to the div wrapping the form item
      * element of this field.  If supplied, <tt>itemCls</tt> at the <b>field</b> level will override
      * the default <tt>itemCls</tt> supplied at the <b>container</b> level. The value specified for
      * <tt>itemCls</tt> will be added to the default class (<tt>'x-form-item'</tt>).</p>
@@ -13965,27 +14328,27 @@ new Ext.FormPanel({
      * any other element within the markup for the field.</p>
      * <br><p><b>Note</b>: see the note for <tt>{@link #fieldLabel}</tt>.</p><br>
      * Example use:<pre><code>
-// Apply a style to the field's label:
+// Apply a style to the field&#39;s label:
 &lt;style>
     .required .x-form-item-label {font-weight:bold;color:red;}
 &lt;/style>
 
 new Ext.FormPanel({
-       height: 100,
-       renderTo: Ext.getBody(),
-       items: [{
-               xtype: 'textfield',
-               fieldLabel: 'Name',
-               itemCls: 'required' //this label will be styled
-       },{
-               xtype: 'textfield',
-               fieldLabel: 'Favorite Color'
-       }]
+    height: 100,
+    renderTo: Ext.getBody(),
+    items: [{
+        xtype: 'textfield',
+        fieldLabel: 'Name',
+        itemCls: 'required' //this label will be styled
+    },{
+        xtype: 'textfield',
+        fieldLabel: 'Favorite Color'
+    }]
 });
 </code></pre>
      */
 
-       // Configs below are used for all Components when rendered by AnchorLayout.
+    // Configs below are used for all Components when rendered by AnchorLayout.
     /**
      * @cfg {String} anchor <p><b>Note</b>: this config is only used when this Component is rendered
      * by a Container which has been configured to use an <b>{@link Ext.layout.AnchorLayout AnchorLayout}</b>
@@ -14324,26 +14687,26 @@ new Ext.Panel({
      * @property el
      */
     /**
-     * The component's owner {@link Ext.Container} (defaults to undefined, and is set automatically when
-     * the component is added to a container).  Read-only.
-     * <p><b>Note</b>: to access items within the container see <tt>{@link #itemId}</tt>.</p>
+     * This Component's owner {@link Ext.Container Container} (defaults to undefined, and is set automatically when
+     * this Component is added to a Container).  Read-only.
+     * <p><b>Note</b>: to access items within the Container see <tt>{@link #itemId}</tt>.</p>
      * @type Ext.Container
      * @property ownerCt
      */
     /**
      * True if this component is hidden. Read-only.
      * @type Boolean
-     * @property
+     * @property hidden
      */
     /**
      * True if this component is disabled. Read-only.
      * @type Boolean
-     * @property
+     * @property disabled
      */
     /**
      * True if this component has been rendered. Read-only.
      * @type Boolean
-     * @property
+     * @property rendered
      */
     rendered : false,
 
@@ -14555,7 +14918,7 @@ var myGrid = new Ext.grid.EditorGridPanel({
     },
 
     // private
-    applyState : function(state, config){
+    applyState : function(state){
         if(state){
             Ext.apply(this, state);
         }
@@ -14662,19 +15025,22 @@ var myGrid = new Ext.grid.EditorGridPanel({
      *
      */
     destroy : function(){
-        if(this.fireEvent('beforedestroy', this) !== false){
-            this.beforeDestroy();
-            if(this.rendered){
-                this.el.removeAllListeners();
-                this.el.remove();
-                if(this.actionMode == 'container' || this.removeMode == 'container'){
-                    this.container.remove();
+        if(!this.isDestroyed){
+            if(this.fireEvent('beforedestroy', this) !== false){
+                this.beforeDestroy();
+                if(this.rendered){
+                    this.el.removeAllListeners();
+                    this.el.remove();
+                    if(this.actionMode == 'container' || this.removeMode == 'container'){
+                        this.container.remove();
+                    }
                 }
+                this.onDestroy();
+                Ext.ComponentMgr.unregister(this);
+                this.fireEvent('destroy', this);
+                this.purgeListeners();
+                this.isDestroyed = true;
             }
-            this.onDestroy();
-            Ext.ComponentMgr.unregister(this);
-            this.fireEvent('destroy', this);
-            this.purgeListeners();
         }
     },
 
@@ -14829,7 +15195,7 @@ new Ext.Panel({
 
     // private
     onShow : function(){
-        this.getVisibiltyEl().removeClass('x-hide-' + this.hideMode);
+        this.getVisibilityEl().removeClass('x-hide-' + this.hideMode);
     },
 
     /**
@@ -14857,11 +15223,11 @@ new Ext.Panel({
 
     // private
     onHide : function(){
-        this.getVisibiltyEl().addClass('x-hide-' + this.hideMode);
+        this.getVisibilityEl().addClass('x-hide-' + this.hideMode);
     },
 
     // private
-    getVisibiltyEl : function(){
+    getVisibilityEl : function(){
         return this.hideParent ? this.container : this.getActionEl();
     },
 
@@ -14879,7 +15245,7 @@ new Ext.Panel({
      * @return {Boolean} True if this component is visible, false otherwise.
      */
     isVisible : function(){
-        return this.rendered && this.getVisibiltyEl().isVisible();
+        return this.rendered && this.getVisibilityEl().isVisible();
     },
 
     /**
@@ -15009,16 +15375,20 @@ alert(t.getXTypes());  // alerts 'component/box/field/textfield'
         }, this);
         this.mons = [];
     },
-
-    // internal function for auto removal of assigned event handlers on destruction
-    mon : function(item, ename, fn, scope, opt){
+    
+    // private
+    createMons: function(){
         if(!this.mons){
             this.mons = [];
             this.on('beforedestroy', this.clearMons, this, {single: true});
         }
+    },
 
+    // internal function for auto removal of assigned event handlers on destruction
+    mon : function(item, ename, fn, scope, opt){
+        this.createMons();
         if(Ext.isObject(ename)){
-               var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
+            var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
 
             var o = ename;
             for(var e in o){
@@ -15027,22 +15397,21 @@ alert(t.getXTypes());  // alerts 'component/box/field/textfield'
                 }
                 if(Ext.isFunction(o[e])){
                     // shared options
-                               this.mons.push({
-                                   item: item, ename: e, fn: o[e], scope: o.scope
-                               });
-                               item.on(e, o[e], o.scope, o);
+                    this.mons.push({
+                        item: item, ename: e, fn: o[e], scope: o.scope
+                    });
+                    item.on(e, o[e], o.scope, o);
                 }else{
                     // individual options
-                               this.mons.push({
-                                   item: item, ename: e, fn: o[e], scope: o.scope
-                               });
-                               item.on(e, o[e]);
+                    this.mons.push({
+                        item: item, ename: e, fn: o[e], scope: o.scope
+                    });
+                    item.on(e, o[e]);
                 }
             }
             return;
         }
 
-
         this.mons.push({
             item: item, ename: ename, fn: fn, scope: scope
         });
@@ -15052,6 +15421,7 @@ alert(t.getXTypes());  // alerts 'component/box/field/textfield'
     // protected, opposite of mon
     mun : function(item, ename, fn, scope){
         var found, mon;
+        this.createMons();
         for(var i = 0, len = this.mons.length; i < len; ++i){
             mon = this.mons[i];
             if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
@@ -16022,6 +16392,14 @@ var myImage = new Ext.BoxComponent({
  */
 Ext.BoxComponent = Ext.extend(Ext.Component, {
 
+    // tabTip config is used when a BoxComponent is a child of a TabPanel
+    /**
+     * @cfg {String} tabTip
+     * <p><b>Note</b>: this config is only used when this BoxComponent is a child item of a TabPanel.</p>
+     * A string to be used as innerHTML (html tags are accepted) to show in a tooltip when mousing over
+     * the associated tab selector element. {@link Ext.QuickTips}.init()
+     * must be called in order for the tips to render.
+     */
     // Configs below are used for all Components when rendered by BorderLayout.
     /**
      * @cfg {String} region <p><b>Note</b>: this config is only used when this BoxComponent is rendered
@@ -16421,19 +16799,14 @@ var myPanel = new Ext.Panel({
     },
 
     // private
-    onRender : function(ct, position){
-        Ext.BoxComponent.superclass.onRender.call(this, ct, position);
+    afterRender : function(){
+        Ext.BoxComponent.superclass.afterRender.call(this);
         if(this.resizeEl){
             this.resizeEl = Ext.get(this.resizeEl);
         }
         if(this.positionEl){
             this.positionEl = Ext.get(this.positionEl);
         }
-    },
-
-    // private
-    afterRender : function(){
-        Ext.BoxComponent.superclass.afterRender.call(this);
         this.boxReady = true;
         this.setSize(this.width, this.height);
         if(this.x || this.y){
@@ -16934,908 +17307,967 @@ Ext.SplitBar.TOP = 3;
  * @type Number\r
  */\r
 Ext.SplitBar.BOTTOM = 4;\r
+/**\r
+ * @class Ext.Container\r
+ * @extends Ext.BoxComponent\r
+ * <p>Base class for any {@link Ext.BoxComponent} that may contain other Components. Containers handle the\r
+ * basic behavior of containing items, namely adding, inserting and removing items.</p>\r
+ *\r
+ * <p>The most commonly used Container classes are {@link Ext.Panel}, {@link Ext.Window} and {@link Ext.TabPanel}.\r
+ * If you do not need the capabilities offered by the aforementioned classes you can create a lightweight\r
+ * Container to be encapsulated by an HTML element to your specifications by using the\r
+ * <tt><b>{@link Ext.Component#autoEl autoEl}</b></tt> config option. This is a useful technique when creating\r
+ * embedded {@link Ext.layout.ColumnLayout column} layouts inside {@link Ext.form.FormPanel FormPanels}\r
+ * for example.</p>\r
+ *\r
+ * <p>The code below illustrates both how to explicitly create a Container, and how to implicitly\r
+ * create one using the <b><tt>'container'</tt></b> xtype:<pre><code>\r
+// explicitly create a Container\r
+var embeddedColumns = new Ext.Container({\r
+    autoEl: 'div',  // This is the default\r
+    layout: 'column',\r
+    defaults: {\r
+        // implicitly create Container by specifying xtype\r
+        xtype: 'container',\r
+        autoEl: 'div', // This is the default.\r
+        layout: 'form',\r
+        columnWidth: 0.5,\r
+        style: {\r
+            padding: '10px'\r
+        }\r
+    },\r
+//  The two items below will be Ext.Containers, each encapsulated by a &lt;DIV> element.\r
+    items: [{\r
+        items: {\r
+            xtype: 'datefield',\r
+            name: 'startDate',\r
+            fieldLabel: 'Start date'\r
+        }\r
+    }, {\r
+        items: {\r
+            xtype: 'datefield',\r
+            name: 'endDate',\r
+            fieldLabel: 'End date'\r
+        }\r
+    }]\r
+});</code></pre></p>\r
+ *\r
+ * <p><u><b>Layout</b></u></p>\r
+ * <p>Container classes delegate the rendering of child Components to a layout\r
+ * manager class which must be configured into the Container using the\r
+ * <code><b>{@link #layout}</b></code> configuration property.</p>\r
+ * <p>When either specifying child <code>{@link #items}</code> of a Container,\r
+ * or dynamically {@link #add adding} Components to a Container, remember to\r
+ * consider how you wish the Container to arrange those child elements, and\r
+ * whether those child elements need to be sized using one of Ext's built-in\r
+ * <b><code>{@link #layout}</code></b> schemes. By default, Containers use the\r
+ * {@link Ext.layout.ContainerLayout ContainerLayout} scheme which only\r
+ * renders child components, appending them one after the other inside the\r
+ * Container, and <b>does not apply any sizing</b> at all.</p>\r
+ * <p>A common mistake is when a developer neglects to specify a\r
+ * <b><code>{@link #layout}</code></b> (e.g. widgets like GridPanels or\r
+ * TreePanels are added to Containers for which no <tt><b>{@link #layout}</b></tt>\r
+ * has been specified). If a Container is left to use the default\r
+ * {@link Ext.layout.ContainerLayout ContainerLayout} scheme, none of its\r
+ * child components will be resized, or changed in any way when the Container\r
+ * is resized.</p>\r
+ * <p>Certain layout managers allow dynamic addition of child components.\r
+ * Those that do include {@link Ext.layout.CardLayout},\r
+ * {@link Ext.layout.AnchorLayout}, {@link Ext.layout.FormLayout}, and\r
+ * {@link Ext.layout.TableLayout}. For example:<pre><code>\r
+//  Create the GridPanel.\r
+var myNewGrid = new Ext.grid.GridPanel({\r
+    store: myStore,\r
+    columns: myColumnModel,\r
+    title: 'Results', // the title becomes the title of the tab\r
+});\r
+\r
+myTabPanel.add(myNewGrid); // {@link Ext.TabPanel} implicitly uses {@link Ext.layout.CardLayout CardLayout}\r
+myTabPanel.{@link Ext.TabPanel#setActiveTab setActiveTab}(myNewGrid);\r
+ * </code></pre></p>\r
+ * <p>The example above adds a newly created GridPanel to a TabPanel. Note that\r
+ * a TabPanel uses {@link Ext.layout.CardLayout} as its layout manager which\r
+ * means all its child items are sized to {@link Ext.layout.FitLayout fit}\r
+ * exactly into its client area.\r
+ * <p><b><u>Overnesting is a common problem</u></b>.\r
+ * An example of overnesting occurs when a GridPanel is added to a TabPanel\r
+ * by wrapping the GridPanel <i>inside</i> a wrapping Panel (that has no\r
+ * <tt><b>{@link #layout}</b></tt> specified) and then add that wrapping Panel\r
+ * to the TabPanel. The point to realize is that a GridPanel <b>is</b> a\r
+ * Component which can be added directly to a Container. If the wrapping Panel\r
+ * has no <tt><b>{@link #layout}</b></tt> configuration, then the overnested\r
+ * GridPanel will not be sized as expected.<p>\r
+ *\r
+ * <p><u><b>Adding via remote configuration</b></u></p>\r
+ *\r
+ * <p>A server side script can be used to add Components which are generated dynamically on the server.\r
+ * An example of adding a GridPanel to a TabPanel where the GridPanel is generated by the server\r
+ * based on certain parameters:\r
+ * </p><pre><code>\r
+// execute an Ajax request to invoke server side script:\r
+Ext.Ajax.request({\r
+    url: 'gen-invoice-grid.php',\r
+    // send additional parameters to instruct server script\r
+    params: {\r
+        startDate: Ext.getCmp('start-date').getValue(),\r
+        endDate: Ext.getCmp('end-date').getValue()\r
+    },\r
+    // process the response object to add it to the TabPanel:\r
+    success: function(xhr) {\r
+        var newComponent = eval(xhr.responseText); // see discussion below\r
+        myTabPanel.add(newComponent); // add the component to the TabPanel\r
+        myTabPanel.setActiveTab(newComponent);\r
+    },\r
+    failure: function() {\r
+        Ext.Msg.alert("Grid create failed", "Server communication failure");\r
+    }\r
+});\r
+</code></pre>\r
+ * <p>The server script needs to return an executable Javascript statement which, when processed\r
+ * using <tt>eval()</tt>, will return either a config object with an {@link Ext.Component#xtype xtype},\r
+ * or an instantiated Component. The server might return this for example:</p><pre><code>\r
+(function() {\r
+    function formatDate(value){\r
+        return value ? value.dateFormat('M d, Y') : '';\r
+    };\r
+\r
+    var store = new Ext.data.Store({\r
+        url: 'get-invoice-data.php',\r
+        baseParams: {\r
+            startDate: '01/01/2008',\r
+            endDate: '01/31/2008'\r
+        },\r
+        reader: new Ext.data.JsonReader({\r
+            record: 'transaction',\r
+            idProperty: 'id',\r
+            totalRecords: 'total'\r
+        }, [\r
+           'customer',\r
+           'invNo',\r
+           {name: 'date', type: 'date', dateFormat: 'm/d/Y'},\r
+           {name: 'value', type: 'float'}\r
+        ])\r
+    });\r
+\r
+    var grid = new Ext.grid.GridPanel({\r
+        title: 'Invoice Report',\r
+        bbar: new Ext.PagingToolbar(store),\r
+        store: store,\r
+        columns: [\r
+            {header: "Customer", width: 250, dataIndex: 'customer', sortable: true},\r
+            {header: "Invoice Number", width: 120, dataIndex: 'invNo', sortable: true},\r
+            {header: "Invoice Date", width: 100, dataIndex: 'date', renderer: formatDate, sortable: true},\r
+            {header: "Value", width: 120, dataIndex: 'value', renderer: 'usMoney', sortable: true}\r
+        ],\r
+    });\r
+    store.load();\r
+    return grid;  // return instantiated component\r
+})();\r
+</code></pre>\r
+ * <p>When the above code fragment is passed through the <tt>eval</tt> function in the success handler\r
+ * of the Ajax request, the code is executed by the Javascript processor, and the anonymous function\r
+ * runs, and returns the instantiated grid component.</p>\r
+ * <p>Note: since the code above is <i>generated</i> by a server script, the <tt>baseParams</tt> for\r
+ * the Store, the metadata to allow generation of the Record layout, and the ColumnModel\r
+ * can all be generated into the code since these are all known on the server.</p>\r
+ *\r
+ * @xtype container\r
+ */\r
+Ext.Container = Ext.extend(Ext.BoxComponent, {\r
+    /**\r
+     * @cfg {Boolean} monitorResize\r
+     * True to automatically monitor window resize events to handle anything that is sensitive to the current size\r
+     * of the viewport.  This value is typically managed by the chosen <code>{@link #layout}</code> and should not need\r
+     * to be set manually.\r
+     */\r
+    /**\r
+     * @cfg {String/Object} layout\r
+     * <p><b>*Important</b>: In order for child items to be correctly sized and\r
+     * positioned, typically a layout manager <b>must</b> be specified through\r
+     * the <code>layout</code> configuration option.</p>\r
+     * <br><p>The sizing and positioning of child {@link items} is the responsibility of\r
+     * the Container's layout manager which creates and manages the type of layout\r
+     * you have in mind.  For example:</p><pre><code>\r
+new Ext.Window({\r
+    width:300, height: 300,\r
+    layout: 'fit', // explicitly set layout manager: override the default (layout:'auto')\r
+    items: [{\r
+        title: 'Panel inside a Window'\r
+    }]\r
+}).show();\r
+     * </code></pre>\r
+     * <p>If the {@link #layout} configuration is not explicitly specified for\r
+     * a general purpose container (e.g. Container or Panel) the\r
+     * {@link Ext.layout.ContainerLayout default layout manager} will be used\r
+     * which does nothing but render child components sequentially into the\r
+     * Container (no sizing or positioning will be performed in this situation).\r
+     * Some container classes implicitly specify a default layout\r
+     * (e.g. FormPanel specifies <code>layout:'form'</code>). Other specific\r
+     * purpose classes internally specify/manage their internal layout (e.g.\r
+     * GridPanel, TabPanel, TreePanel, Toolbar, Menu, etc.).</p>\r
+     * <br><p><b><code>layout</code></b> may be specified as either as an Object or\r
+     * as a String:</p><div><ul class="mdetail-params">\r
+     *\r
+     * <li><u>Specify as an Object</u></li>\r
+     * <div><ul class="mdetail-params">\r
+     * <li>Example usage:</li>\r
+<pre><code>\r
+layout: {\r
+    type: 'vbox',\r
+    padding: '5',\r
+    align: 'left'\r
+}\r
+</code></pre>\r
+     *\r
+     * <li><tt><b>type</b></tt></li>\r
+     * <br/><p>The layout type to be used for this container.  If not specified,\r
+     * a default {@link Ext.layout.ContainerLayout} will be created and used.</p>\r
+     * <br/><p>Valid layout <tt>type</tt> values are:</p>\r
+     * <div class="sub-desc"><ul class="mdetail-params">\r
+     * <li><tt><b>{@link Ext.layout.AbsoluteLayout absolute}</b></tt></li>\r
+     * <li><tt><b>{@link Ext.layout.AccordionLayout accordion}</b></tt></li>\r
+     * <li><tt><b>{@link Ext.layout.AnchorLayout anchor}</b></tt></li>\r
+     * <li><tt><b>{@link Ext.layout.ContainerLayout auto}</b></tt> &nbsp;&nbsp;&nbsp; <b>Default</b></li>\r
+     * <li><tt><b>{@link Ext.layout.BorderLayout border}</b></tt></li>\r
+     * <li><tt><b>{@link Ext.layout.CardLayout card}</b></tt></li>\r
+     * <li><tt><b>{@link Ext.layout.ColumnLayout column}</b></tt></li>\r
+     * <li><tt><b>{@link Ext.layout.FitLayout fit}</b></tt></li>\r
+     * <li><tt><b>{@link Ext.layout.FormLayout form}</b></tt></li>\r
+     * <li><tt><b>{@link Ext.layout.HBoxLayout hbox}</b></tt></li>\r
+     * <li><tt><b>{@link Ext.layout.MenuLayout menu}</b></tt></li>\r
+     * <li><tt><b>{@link Ext.layout.TableLayout table}</b></tt></li>\r
+     * <li><tt><b>{@link Ext.layout.ToolbarLayout toolbar}</b></tt></li>\r
+     * <li><tt><b>{@link Ext.layout.VBoxLayout vbox}</b></tt></li>\r
+     * </ul></div>\r
+     *\r
+     * <li>Layout specific configuration properties</li>\r
+     * <br/><p>Additional layout specific configuration properties may also be\r
+     * specified. For complete details regarding the valid config options for\r
+     * each layout type, see the layout class corresponding to the <tt>type</tt>\r
+     * specified.</p>\r
+     *\r
+     * </ul></div>\r
+     *\r
+     * <li><u>Specify as a String</u></li>\r
+     * <div><ul class="mdetail-params">\r
+     * <li>Example usage:</li>\r
+<pre><code>\r
+layout: 'vbox',\r
+layoutConfig: {\r
+    padding: '5',\r
+    align: 'left'\r
+}\r
+</code></pre>\r
+     * <li><tt><b>layout</b></tt></li>\r
+     * <br/><p>The layout <tt>type</tt> to be used for this container (see list\r
+     * of valid layout type values above).</p><br/>\r
+     * <li><tt><b>{@link #layoutConfig}</b></tt></li>\r
+     * <br/><p>Additional layout specific configuration properties. For complete\r
+     * details regarding the valid config options for each layout type, see the\r
+     * layout class corresponding to the <tt>layout</tt> specified.</p>\r
+     * </ul></div></ul></div>\r
+     */\r
+    /**\r
+     * @cfg {Object} layoutConfig\r
+     * This is a config object containing properties specific to the chosen\r
+     * <b><code>{@link #layout}</code></b> if <b><code>{@link #layout}</code></b>\r
+     * has been specified as a <i>string</i>.</p>\r
+     */\r
+    /**\r
+     * @cfg {Boolean/Number} bufferResize\r
+     * When set to true (50 milliseconds) or a number of milliseconds, the layout assigned for this container will buffer\r
+     * the frequency it calculates and does a re-layout of components. This is useful for heavy containers or containers\r
+     * with a large quantity of sub-components for which frequent layout calls would be expensive. Defaults to <tt>50</tt>.\r
+     */\r
+    bufferResize: 50,\r
+\r
+    /**\r
+     * @cfg {String/Number} activeItem\r
+     * A string component id or the numeric index of the component that should be initially activated within the\r
+     * container's layout on render.  For example, activeItem: 'item-1' or activeItem: 0 (index 0 = the first\r
+     * item in the container's collection).  activeItem only applies to layout styles that can display\r
+     * items one at a time (like {@link Ext.layout.AccordionLayout}, {@link Ext.layout.CardLayout} and\r
+     * {@link Ext.layout.FitLayout}).  Related to {@link Ext.layout.ContainerLayout#activeItem}.\r
+     */\r
+    /**\r
+     * @cfg {Object/Array} items\r
+     * <pre><b>** IMPORTANT</b>: be sure to <b>{@link #layout specify a <code>layout</code>} if needed ! **</b></pre>\r
+     * <p>A single item, or an array of child Components to be added to this container,\r
+     * for example:</p>\r
+     * <pre><code>\r
+// specifying a single item\r
+items: {...},\r
+layout: 'fit',    // specify a layout!\r
+\r
+// specifying multiple items\r
+items: [{...}, {...}],\r
+layout: 'anchor', // specify a layout!\r
+     * </code></pre>\r
+     * <p>Each item may be:</p>\r
+     * <div><ul class="mdetail-params">\r
+     * <li>any type of object based on {@link Ext.Component}</li>\r
+     * <li>a fully instanciated object or</li>\r
+     * <li>an object literal that:</li>\r
+     * <div><ul class="mdetail-params">\r
+     * <li>has a specified <code>{@link Ext.Component#xtype xtype}</code></li>\r
+     * <li>the {@link Ext.Component#xtype} specified is associated with the Component\r
+     * desired and should be chosen from one of the available xtypes as listed\r
+     * in {@link Ext.Component}.</li>\r
+     * <li>If an <code>{@link Ext.Component#xtype xtype}</code> is not explicitly\r
+     * specified, the {@link #defaultType} for that Container is used.</li>\r
+     * <li>will be "lazily instanciated", avoiding the overhead of constructing a fully\r
+     * instanciated Component object</li>\r
+     * </ul></div></ul></div>\r
+     * <p><b>Notes</b>:</p>\r
+     * <div><ul class="mdetail-params">\r
+     * <li>Ext uses lazy rendering. Child Components will only be rendered\r
+     * should it become necessary. Items are automatically laid out when they are first\r
+     * shown (no sizing is done while hidden), or in response to a {@link #doLayout} call.</li>\r
+     * <li>Do not specify <code>{@link Ext.Panel#contentEl contentEl}</code>/\r
+     * <code>{@link Ext.Panel#html html}</code> with <code>items</code>.</li>\r
+     * </ul></div>\r
+     */\r
+    /**\r
+     * @cfg {Object} defaults\r
+     * <p>A config object that will be applied to all components added to this container either via the {@link #items}\r
+     * config or via the {@link #add} or {@link #insert} methods.  The <tt>defaults</tt> config can contain any\r
+     * number of name/value property pairs to be added to each item, and should be valid for the types of items\r
+     * being added to the container.  For example, to automatically apply padding to the body of each of a set of\r
+     * contained {@link Ext.Panel} items, you could pass: <tt>defaults: {bodyStyle:'padding:15px'}</tt>.</p><br/>\r
+     * <p><b>Note</b>: <tt>defaults</tt> will not be applied to config objects if the option is already specified.\r
+     * For example:</p><pre><code>\r
+defaults: {               // defaults are applied to items, not the container\r
+    autoScroll:true\r
+},\r
+items: [\r
+    {\r
+        xtype: 'panel',   // defaults <b>do not</b> have precedence over\r
+        id: 'panel1',     // options in config objects, so the defaults\r
+        autoScroll: false // will not be applied here, panel1 will be autoScroll:false\r
+    },\r
+    new Ext.Panel({       // defaults <b>do</b> have precedence over options\r
+        id: 'panel2',     // options in components, so the defaults\r
+        autoScroll: false // will be applied here, panel2 will be autoScroll:true.\r
+    })\r
+]\r
+     * </code></pre>\r
+     */\r
+\r
+\r
+    /** @cfg {Boolean} autoDestroy\r
+     * If true the container will automatically destroy any contained component that is removed from it, else\r
+     * destruction must be handled manually (defaults to true).\r
+     */\r
+    autoDestroy : true,\r
+\r
+    /** @cfg {Boolean} forceLayout\r
+     * If true the container will force a layout initially even if hidden or collapsed. This option\r
+     * is useful for forcing forms to render in collapsed or hidden containers. (defaults to false).\r
+     */\r
+    forceLayout: false,\r
+\r
+    /** @cfg {Boolean} hideBorders\r
+     * True to hide the borders of each contained component, false to defer to the component's existing\r
+     * border settings (defaults to false).\r
+     */\r
+    /** @cfg {String} defaultType\r
+     * <p>The default {@link Ext.Component xtype} of child Components to create in this Container when\r
+     * a child item is specified as a raw configuration object, rather than as an instantiated Component.</p>\r
+     * <p>Defaults to <tt>'panel'</tt>, except {@link Ext.menu.Menu} which defaults to <tt>'menuitem'</tt>,\r
+     * and {@link Ext.Toolbar} and {@link Ext.ButtonGroup} which default to <tt>'button'</tt>.</p>\r
+     */\r
+    defaultType : 'panel',\r
+\r
+    /** @cfg {String} resizeEvent\r
+     * The event to listen to for resizing in layouts. Defaults to <tt>'resize'</tt>.\r
+     */\r
+    resizeEvent: 'resize',\r
+    \r
+    /**\r
+     * @cfg {Array} bubbleEvents\r
+     * <p>An array of events that, when fired, should be bubbled to any parent container.\r
+     * Defaults to <tt>['add', 'remove']</tt>.\r
+     */\r
+    bubbleEvents: ['add', 'remove'],\r
+\r
+    // private\r
+    initComponent : function(){\r
+        Ext.Container.superclass.initComponent.call(this);\r
+\r
+        this.addEvents(\r
+            /**\r
+             * @event afterlayout\r
+             * Fires when the components in this container are arranged by the associated layout manager.\r
+             * @param {Ext.Container} this\r
+             * @param {ContainerLayout} layout The ContainerLayout implementation for this container\r
+             */\r
+            'afterlayout',\r
+            /**\r
+             * @event beforeadd\r
+             * Fires before any {@link Ext.Component} is added or inserted into the container.\r
+             * A handler can return false to cancel the add.\r
+             * @param {Ext.Container} this\r
+             * @param {Ext.Component} component The component being added\r
+             * @param {Number} index The index at which the component will be added to the container's items collection\r
+             */\r
+            'beforeadd',\r
+            /**\r
+             * @event beforeremove\r
+             * Fires before any {@link Ext.Component} is removed from the container.  A handler can return\r
+             * false to cancel the remove.\r
+             * @param {Ext.Container} this\r
+             * @param {Ext.Component} component The component being removed\r
+             */\r
+            'beforeremove',\r
+            /**\r
+             * @event add\r
+             * @bubbles\r
+             * Fires after any {@link Ext.Component} is added or inserted into the container.\r
+             * @param {Ext.Container} this\r
+             * @param {Ext.Component} component The component that was added\r
+             * @param {Number} index The index at which the component was added to the container's items collection\r
+             */\r
+            'add',\r
+            /**\r
+             * @event remove\r
+             * @bubbles\r
+             * Fires after any {@link Ext.Component} is removed from the container.\r
+             * @param {Ext.Container} this\r
+             * @param {Ext.Component} component The component that was removed\r
+             */\r
+            'remove'\r
+        );\r
+\r
+        this.enableBubble(this.bubbleEvents);\r
+\r
+        /**\r
+         * The collection of components in this container as a {@link Ext.util.MixedCollection}\r
+         * @type MixedCollection\r
+         * @property items\r
+         */\r
+        var items = this.items;\r
+        if(items){\r
+            delete this.items;\r
+            this.add(items);\r
+        }\r
+    },\r
+\r
+    // private\r
+    initItems : function(){\r
+        if(!this.items){\r
+            this.items = new Ext.util.MixedCollection(false, this.getComponentId);\r
+            this.getLayout(); // initialize the layout\r
+        }\r
+    },\r
+\r
+    // private\r
+    setLayout : function(layout){\r
+        if(this.layout && this.layout != layout){\r
+            this.layout.setContainer(null);\r
+        }\r
+        this.initItems();\r
+        this.layout = layout;\r
+        layout.setContainer(this);\r
+    },\r
+\r
+    afterRender: function(){\r
+        Ext.Container.superclass.afterRender.call(this);\r
+        if(!this.layout){\r
+            this.layout = 'auto';\r
+        }\r
+        if(Ext.isObject(this.layout) && !this.layout.layout){\r
+            this.layoutConfig = this.layout;\r
+            this.layout = this.layoutConfig.type;\r
+        }\r
+        if(Ext.isString(this.layout)){\r
+            this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);\r
+        }\r
+        this.setLayout(this.layout);\r
+\r
+        if(this.activeItem !== undefined){\r
+            var item = this.activeItem;\r
+            delete this.activeItem;\r
+            this.layout.setActiveItem(item);\r
+        }\r
+        if(!this.ownerCt){\r
+            // force a layout if no ownerCt is set\r
+            this.doLayout(false, true);\r
+        }\r
+        if(this.monitorResize === true){\r
+            Ext.EventManager.onWindowResize(this.doLayout, this, [false]);\r
+        }\r
+    },\r
+\r
+    /**\r
+     * <p>Returns the Element to be used to contain the child Components of this Container.</p>\r
+     * <p>An implementation is provided which returns the Container's {@link #getEl Element}, but\r
+     * if there is a more complex structure to a Container, this may be overridden to return\r
+     * the element into which the {@link #layout layout} renders child Components.</p>\r
+     * @return {Ext.Element} The Element to render child Components into.\r
+     */\r
+    getLayoutTarget : function(){\r
+        return this.el;\r
+    },\r
+\r
+    // private - used as the key lookup function for the items collection\r
+    getComponentId : function(comp){\r
+        return comp.getItemId();\r
+    },\r
+\r
+    /**\r
+     * <p>Adds {@link Ext.Component Component}(s) to this Container.</p>\r
+     * <br><p><b>Description</b></u> :\r
+     * <div><ul class="mdetail-params">\r
+     * <li>Fires the {@link #beforeadd} event before adding</li>\r
+     * <li>The Container's {@link #defaults default config values} will be applied\r
+     * accordingly (see <code>{@link #defaults}</code> for details).</li>\r
+     * <li>Fires the {@link #add} event after the component has been added.</li>\r
+     * </ul></div>\r
+     * <br><p><b>Notes</b></u> :\r
+     * <div><ul class="mdetail-params">\r
+     * <li>If the Container is <i>already rendered</i> when <tt>add</tt>\r
+     * is called, you may need to call {@link #doLayout} to refresh the view which causes\r
+     * any unrendered child Components to be rendered. This is required so that you can\r
+     * <tt>add</tt> multiple child components if needed while only refreshing the layout\r
+     * once. For example:<pre><code>\r
+var tb = new {@link Ext.Toolbar}();\r
+tb.render(document.body);  // toolbar is rendered\r
+tb.add({text:'Button 1'}); // add multiple items ({@link #defaultType} for {@link Ext.Toolbar Toolbar} is 'button')\r
+tb.add({text:'Button 2'});\r
+tb.{@link #doLayout}();             // refresh the layout\r
+     * </code></pre></li>\r
+     * <li><i>Warning:</i> Containers directly managed by the BorderLayout layout manager\r
+     * may not be removed or added.  See the Notes for {@link Ext.layout.BorderLayout BorderLayout}\r
+     * for more details.</li>\r
+     * </ul></div>\r
+     * @param {Object/Array} component\r
+     * <p>Either a single component or an Array of components to add.  See\r
+     * <code>{@link #items}</code> for additional information.</p>\r
+     * @param {Object} (Optional) component_2\r
+     * @param {Object} (Optional) component_n\r
+     * @return {Ext.Component} component The Component (or config object) that was added.\r
+     */\r
+    add : function(comp){\r
+        this.initItems();\r
+        var args = arguments.length > 1;\r
+        if(args || Ext.isArray(comp)){\r
+            Ext.each(args ? arguments : comp, function(c){\r
+                this.add(c);\r
+            }, this);\r
+            return;\r
+        }\r
+        var c = this.lookupComponent(this.applyDefaults(comp));\r
+        var pos = this.items.length;\r
+        if(this.fireEvent('beforeadd', this, c, pos) !== false && this.onBeforeAdd(c) !== false){\r
+            this.items.add(c);\r
+            c.ownerCt = this;\r
+            this.onAdd(c);\r
+            this.fireEvent('add', this, c, pos);\r
+        }\r
+        return c;\r
+    },\r
+\r
+    onAdd : function(c){\r
+        // Empty template method\r
+    },\r
+\r
+    /**\r
+     * Inserts a Component into this Container at a specified index. Fires the\r
+     * {@link #beforeadd} event before inserting, then fires the {@link #add} event after the\r
+     * Component has been inserted.\r
+     * @param {Number} index The index at which the Component will be inserted\r
+     * into the Container's items collection\r
+     * @param {Ext.Component} component The child Component to insert.<br><br>\r
+     * Ext uses lazy rendering, and will only render the inserted Component should\r
+     * it become necessary.<br><br>\r
+     * A Component config object may be passed in order to avoid the overhead of\r
+     * constructing a real Component object if lazy rendering might mean that the\r
+     * inserted Component will not be rendered immediately. To take advantage of\r
+     * this 'lazy instantiation', set the {@link Ext.Component#xtype} config\r
+     * property to the registered type of the Component wanted.<br><br>\r
+     * For a list of all available xtypes, see {@link Ext.Component}.\r
+     * @return {Ext.Component} component The Component (or config object) that was\r
+     * inserted with the Container's default config values applied.\r
+     */\r
+    insert : function(index, comp){\r
+        this.initItems();\r
+        var a = arguments, len = a.length;\r
+        if(len > 2){\r
+            for(var i = len-1; i >= 1; --i) {\r
+                this.insert(index, a[i]);\r
+            }\r
+            return;\r
+        }\r
+        var c = this.lookupComponent(this.applyDefaults(comp));\r
+        index = Math.min(index, this.items.length);\r
+        if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){\r
+            if(c.ownerCt == this){\r
+                this.items.remove(c);\r
+            }\r
+            this.items.insert(index, c);\r
+            c.ownerCt = this;\r
+            this.onAdd(c);\r
+            this.fireEvent('add', this, c, index);\r
+        }\r
+        return c;\r
+    },\r
+\r
+    // private\r
+    applyDefaults : function(c){\r
+        if(this.defaults){\r
+            if(Ext.isString(c)){\r
+                c = Ext.ComponentMgr.get(c);\r
+                Ext.apply(c, this.defaults);\r
+            }else if(!c.events){\r
+                Ext.applyIf(c, this.defaults);\r
+            }else{\r
+                Ext.apply(c, this.defaults);\r
+            }\r
+        }\r
+        return c;\r
+    },\r
+\r
+    // private\r
+    onBeforeAdd : function(item){\r
+        if(item.ownerCt){\r
+            item.ownerCt.remove(item, false);\r
+        }\r
+        if(this.hideBorders === true){\r
+            item.border = (item.border === true);\r
+        }\r
+    },\r
+\r
+    /**\r
+     * Removes a component from this container.  Fires the {@link #beforeremove} event before removing, then fires\r
+     * the {@link #remove} event after the component has been removed.\r
+     * @param {Component/String} component The component reference or id to remove.\r
+     * @param {Boolean} autoDestroy (optional) True to automatically invoke the removed Component's {@link Ext.Component#destroy} function.\r
+     * Defaults to the value of this Container's {@link #autoDestroy} config.\r
+     * @return {Ext.Component} component The Component that was removed.\r
+     */\r
+    remove : function(comp, autoDestroy){\r
+        this.initItems();\r
+        var c = this.getComponent(comp);\r
+        if(c && this.fireEvent('beforeremove', this, c) !== false){\r
+            delete c.ownerCt;\r
+            if(this.layout && this.rendered){\r
+                this.layout.onRemove(c);\r
+            }\r
+            this.onRemove(c);\r
+            this.items.remove(c);\r
+            if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){\r
+                c.destroy();\r
+            }\r
+            this.fireEvent('remove', this, c);\r
+        }\r
+        return c;\r
+    },\r
+\r
+    onRemove: function(c){\r
+        // Empty template method\r
+    },\r
+\r
+    /**\r
+     * Removes all components from this container.\r
+     * @param {Boolean} autoDestroy (optional) True to automatically invoke the removed Component's {@link Ext.Component#destroy} function.\r
+     * Defaults to the value of this Container's {@link #autoDestroy} config.\r
+     * @return {Array} Array of the destroyed components\r
+     */\r
+    removeAll: function(autoDestroy){\r
+        this.initItems();\r
+        var item, rem = [], items = [];\r
+        this.items.each(function(i){\r
+            rem.push(i);\r
+        });\r
+        for (var i = 0, len = rem.length; i < len; ++i){\r
+            item = rem[i];\r
+            this.remove(item, autoDestroy);\r
+            if(item.ownerCt !== this){\r
+                items.push(item);\r
+            }\r
+        }\r
+        return items;\r
+    },\r
+\r
+    /**\r
+     * Examines this container's <code>{@link #items}</code> <b>property</b>\r
+     * and gets a direct child component of this container.\r
+     * @param {String/Number} comp This parameter may be any of the following:\r
+     * <div><ul class="mdetail-params">\r
+     * <li>a <b><tt>String</tt></b> : representing the <code>{@link Ext.Component#itemId itemId}</code>\r
+     * or <code>{@link Ext.Component#id id}</code> of the child component </li>\r
+     * <li>a <b><tt>Number</tt></b> : representing the position of the child component\r
+     * within the <code>{@link #items}</code> <b>property</b></li>\r
+     * </ul></div>\r
+     * <p>For additional information see {@link Ext.util.MixedCollection#get}.\r
+     * @return Ext.Component The component (if found).\r
+     */\r
+    getComponent : function(comp){\r
+        if(Ext.isObject(comp)){\r
+            comp = comp.getItemId();\r
+        }\r
+        return this.items.get(comp);\r
+    },\r
+\r
+    // private\r
+    lookupComponent : function(comp){\r
+        if(Ext.isString(comp)){\r
+            return Ext.ComponentMgr.get(comp);\r
+        }else if(!comp.events){\r
+            return this.createComponent(comp);\r
+        }\r
+        return comp;\r
+    },\r
+\r
+    // private\r
+    createComponent : function(config){\r
+        return Ext.create(config, this.defaultType);\r
+    },\r
+\r
+    // private\r
+    canLayout: function() {\r
+        var el = this.getVisibilityEl();\r
+        return el && !el.isStyle("display", "none");\r
+    },\r
+\r
+\r
+    /**\r
+     * Force this container's layout to be recalculated. A call to this function is required after adding a new component\r
+     * to an already rendered container, or possibly after changing sizing/position properties of child components.\r
+     * @param {Boolean} shallow (optional) True to only calc the layout of this component, and let child components auto\r
+     * calc layouts as required (defaults to false, which calls doLayout recursively for each subcontainer)\r
+     * @param {Boolean} force (optional) True to force a layout to occur, even if the item is hidden.\r
+     * @return {Ext.Container} this\r
+     */\r
+    doLayout: function(shallow, force){\r
+        var rendered = this.rendered;\r
+        forceLayout = force || this.forceLayout;\r
+\r
+        if(!this.canLayout() || this.collapsed){\r
+            this.deferLayout = this.deferLayout || !shallow;\r
+            if(!forceLayout){\r
+                return;\r
+            }\r
+            shallow = shallow && !this.deferLayout;\r
+        } else {\r
+            delete this.deferLayout;\r
+        }\r
+        if(rendered && this.layout){\r
+            this.layout.layout();\r
+        }\r
+        if(shallow !== true && this.items){\r
+            var cs = this.items.items;\r
+            for(var i = 0, len = cs.length; i < len; i++){\r
+                var c = cs[i];\r
+                if(c.doLayout){\r
+                    c.doLayout(false, forceLayout);\r
+                }\r
+            }\r
+        }\r
+        if(rendered){\r
+            this.onLayout(shallow, forceLayout);\r
+        }\r
+        // Initial layout completed\r
+        this.hasLayout = true;\r
+        delete this.forceLayout;\r
+    },\r
+\r
+    //private\r
+    onLayout : Ext.emptyFn,\r
+\r
+    // private\r
+    shouldBufferLayout: function(){\r
+        /*\r
+         * Returns true if the container should buffer a layout.\r
+         * This is true only if the container has previously been laid out\r
+         * and has a parent container that is pending a layout.\r
+         */\r
+        var hl = this.hasLayout;\r
+        if(this.ownerCt){\r
+            // Only ever buffer if we've laid out the first time and we have one pending.\r
+            return hl ? !this.hasLayoutPending() : false;\r
+        }\r
+        // Never buffer initial layout\r
+        return hl;\r
+    },\r
+\r
+    // private\r
+    hasLayoutPending: function(){\r
+        // Traverse hierarchy to see if any parent container has a pending layout.\r
+        var pending = false;\r
+        this.ownerCt.bubble(function(c){\r
+            if(c.layoutPending){\r
+                pending = true;\r
+                return false;\r
+            }\r
+        });\r
+        return pending;\r
+    },\r
+\r
+    onShow : function(){\r
+        Ext.Container.superclass.onShow.call(this);\r
+        if(this.deferLayout !== undefined){\r
+            this.doLayout(true);\r
+        }\r
+    },\r
+\r
+    /**\r
+     * Returns the layout currently in use by the container.  If the container does not currently have a layout\r
+     * set, a default {@link Ext.layout.ContainerLayout} will be created and set as the container's layout.\r
+     * @return {ContainerLayout} layout The container's layout\r
+     */\r
+    getLayout : function(){\r
+        if(!this.layout){\r
+            var layout = new Ext.layout.ContainerLayout(this.layoutConfig);\r
+            this.setLayout(layout);\r
+        }\r
+        return this.layout;\r
+    },\r
+\r
+    // private\r
+    beforeDestroy : function(){\r
+        if(this.items){\r
+            Ext.destroy.apply(Ext, this.items.items);\r
+        }\r
+        if(this.monitorResize){\r
+            Ext.EventManager.removeResizeListener(this.doLayout, this);\r
+        }\r
+        Ext.destroy(this.layout);\r
+        Ext.Container.superclass.beforeDestroy.call(this);\r
+    },\r
+\r
+    /**\r
+     * Bubbles up the component/container heirarchy, calling the specified function with each component. The scope (<i>this</i>) of\r
+     * function call will be the scope provided or the current component. The arguments to the function\r
+     * will be the args provided or the current component. If the function returns false at any point,\r
+     * the bubble is stopped.\r
+     * @param {Function} fn The function to call\r
+     * @param {Object} scope (optional) The scope of the function (defaults to current node)\r
+     * @param {Array} args (optional) The args to call the function with (default to passing the current component)\r
+     * @return {Ext.Container} this\r
+     */\r
+    bubble : function(fn, scope, args){\r
+        var p = this;\r
+        while(p){\r
+            if(fn.apply(scope || p, args || [p]) === false){\r
+                break;\r
+            }\r
+            p = p.ownerCt;\r
+        }\r
+        return this;\r
+    },\r
+\r
+    /**\r
+     * Cascades down the component/container heirarchy from this component (called first), calling the specified function with\r
+     * each component. The scope (<i>this</i>) of\r
+     * function call will be the scope provided or the current component. The arguments to the function\r
+     * will be the args provided or the current component. If the function returns false at any point,\r
+     * the cascade is stopped on that branch.\r
+     * @param {Function} fn The function to call\r
+     * @param {Object} scope (optional) The scope of the function (defaults to current component)\r
+     * @param {Array} args (optional) The args to call the function with (defaults to passing the current component)\r
+     * @return {Ext.Container} this\r
+     */\r
+    cascade : function(fn, scope, args){\r
+        if(fn.apply(scope || this, args || [this]) !== false){\r
+            if(this.items){\r
+                var cs = this.items.items;\r
+                for(var i = 0, len = cs.length; i < len; i++){\r
+                    if(cs[i].cascade){\r
+                        cs[i].cascade(fn, scope, args);\r
+                    }else{\r
+                        fn.apply(scope || cs[i], args || [cs[i]]);\r
+                    }\r
+                }\r
+            }\r
+        }\r
+        return this;\r
+    },\r
+\r
+    /**\r
+     * Find a component under this container at any level by id\r
+     * @param {String} id\r
+     * @return Ext.Component\r
+     */\r
+    findById : function(id){\r
+        var m, ct = this;\r
+        this.cascade(function(c){\r
+            if(ct != c && c.id === id){\r
+                m = c;\r
+                return false;\r
+            }\r
+        });\r
+        return m || null;\r
+    },\r
+\r
+    /**\r
+     * Find a component under this container at any level by xtype or class\r
+     * @param {String/Class} xtype The xtype string for a component, or the class of the component directly\r
+     * @param {Boolean} shallow (optional) False to check whether this Component is descended from the xtype (this is\r
+     * the default), or true to check whether this Component is directly of the specified xtype.\r
+     * @return {Array} Array of Ext.Components\r
+     */\r
+    findByType : function(xtype, shallow){\r
+        return this.findBy(function(c){\r
+            return c.isXType(xtype, shallow);\r
+        });\r
+    },\r
+\r
+    /**\r
+     * Find a component under this container at any level by property\r
+     * @param {String} prop\r
+     * @param {String} value\r
+     * @return {Array} Array of Ext.Components\r
+     */\r
+    find : function(prop, value){\r
+        return this.findBy(function(c){\r
+            return c[prop] === value;\r
+        });\r
+    },\r
+\r
+    /**\r
+     * Find a component under this container at any level by a custom function. If the passed function returns\r
+     * true, the component will be included in the results. The passed function is called with the arguments (component, this container).\r
+     * @param {Function} fn The function to call\r
+     * @param {Object} scope (optional)\r
+     * @return {Array} Array of Ext.Components\r
+     */\r
+    findBy : function(fn, scope){\r
+        var m = [], ct = this;\r
+        this.cascade(function(c){\r
+            if(ct != c && fn.call(scope || c, c, ct) === true){\r
+                m.push(c);\r
+            }\r
+        });\r
+        return m;\r
+    },\r
+\r
+    /**\r
+     * Get a component contained by this container (alias for items.get(key))\r
+     * @param {String/Number} key The index or id of the component\r
+     * @return {Ext.Component} Ext.Component\r
+     */\r
+    get : function(key){\r
+        return this.items.get(key);\r
+    }\r
+});\r
+\r
+Ext.Container.LAYOUTS = {};\r
+Ext.reg('container', Ext.Container);\r
 /**
- * @class Ext.Container
- * @extends Ext.BoxComponent
- * <p>Base class for any {@link Ext.BoxComponent} that may contain other Components. Containers handle the
- * basic behavior of containing items, namely adding, inserting and removing items.</p>
- *
- * <p>The most commonly used Container classes are {@link Ext.Panel}, {@link Ext.Window} and {@link Ext.TabPanel}.
- * If you do not need the capabilities offered by the aforementioned classes you can create a lightweight
- * Container to be encapsulated by an HTML element to your specifications by using the
- * <tt><b>{@link Ext.Component#autoEl autoEl}</b></tt> config option. This is a useful technique when creating
- * embedded {@link Ext.layout.ColumnLayout column} layouts inside {@link Ext.form.FormPanel FormPanels}
- * for example.</p>
- *
- * <p>The code below illustrates both how to explicitly create a Container, and how to implicitly
- * create one using the <b><tt>'container'</tt></b> xtype:<pre><code>
-// explicitly create a Container
-var embeddedColumns = new Ext.Container({
-    autoEl: 'div',  // This is the default
-    layout: 'column',
-    defaults: {
-        // implicitly create Container by specifying xtype
-        xtype: 'container',
-        autoEl: 'div', // This is the default.
-        layout: 'form',
-        columnWidth: 0.5,
-        style: {
-            padding: '10px'
-        }
-    },
-//  The two items below will be Ext.Containers, each encapsulated by a &lt;DIV> element.
-    items: [{
-        items: {
-            xtype: 'datefield',
-            name: 'startDate',
-            fieldLabel: 'Start date'
-        }
-    }, {
-        items: {
-            xtype: 'datefield',
-            name: 'endDate',
-            fieldLabel: 'End date'
-        }
-    }]
-});</code></pre></p>
- *
- * <p><u><b>Layout</b></u></p>
- * <p>Container classes delegate the rendering of child Components to a layout
- * manager class which must be configured into the Container using the
- * <code><b>{@link #layout}</b></code> configuration property.</p>
- * <p>When either specifying child <code>{@link #items}</code> of a Container,
- * or dynamically {@link #add adding} Components to a Container, remember to
- * consider how you wish the Container to arrange those child elements, and
- * whether those child elements need to be sized using one of Ext's built-in
- * <b><code>{@link #layout}</code></b> schemes. By default, Containers use the
- * {@link Ext.layout.ContainerLayout ContainerLayout} scheme which only
- * renders child components, appending them one after the other inside the
- * Container, and <b>does not apply any sizing</b> at all.</p>
- * <p>A common mistake is when a developer neglects to specify a
- * <b><code>{@link #layout}</code></b> (e.g. widgets like GridPanels or
- * TreePanels are added to Containers for which no <tt><b>{@link #layout}</b></tt>
- * has been specified). If a Container is left to use the default
- * {@link Ext.layout.ContainerLayout ContainerLayout} scheme, none of its
- * child components will be resized, or changed in any way when the Container
- * is resized.</p>
- * <p>Certain layout managers allow dynamic addition of child components.
- * Those that do include {@link Ext.layout.CardLayout},
- * {@link Ext.layout.AnchorLayout}, {@link Ext.layout.FormLayout}, and
- * {@link Ext.layout.TableLayout}. For example:<pre><code>
-//  Create the GridPanel.
-var myNewGrid = new Ext.grid.GridPanel({
-    store: myStore,
-    columns: myColumnModel,
-    title: 'Results', // the title becomes the title of the tab
-});
-
-myTabPanel.add(myNewGrid); // {@link Ext.TabPanel} implicitly uses {@link Ext.layout.CardLayout CardLayout}
-myTabPanel.{@link Ext.TabPanel#setActiveTab setActiveTab}(myNewGrid);
- * </code></pre></p>
- * <p>The example above adds a newly created GridPanel to a TabPanel. Note that
- * a TabPanel uses {@link Ext.layout.CardLayout} as its layout manager which
- * means all its child items are sized to {@link Ext.layout.FitLayout fit}
- * exactly into its client area.
- * <p><b><u>Overnesting is a common problem</u></b>.
- * An example of overnesting occurs when a GridPanel is added to a TabPanel
- * by wrapping the GridPanel <i>inside</i> a wrapping Panel (that has no
- * <tt><b>{@link #layout}</b></tt> specified) and then add that wrapping Panel
- * to the TabPanel. The point to realize is that a GridPanel <b>is</b> a
- * Component which can be added directly to a Container. If the wrapping Panel
- * has no <tt><b>{@link #layout}</b></tt> configuration, then the overnested
- * GridPanel will not be sized as expected.<p>
-</code></pre>
- *
- * <p><u><b>Adding via remote configuration</b></u></p>
- *
- * <p>A server side script can be used to add Components which are generated dynamically on the server.
- * An example of adding a GridPanel to a TabPanel where the GridPanel is generated by the server
- * based on certain parameters:
- * </p><pre><code>
-// execute an Ajax request to invoke server side script:
-Ext.Ajax.request({
-    url: 'gen-invoice-grid.php',
-    // send additional parameters to instruct server script
-    params: {
-        startDate: Ext.getCmp('start-date').getValue(),
-        endDate: Ext.getCmp('end-date').getValue()
-    },
-    // process the response object to add it to the TabPanel:
-    success: function(xhr) {
-        var newComponent = eval(xhr.responseText); // see discussion below
-        myTabPanel.add(newComponent); // add the component to the TabPanel
-        myTabPanel.setActiveTab(newComponent);
-    },
-    failure: function() {
-        Ext.Msg.alert("Grid create failed", "Server communication failure");
-    }
-});
-</code></pre>
- * <p>The server script needs to return an executable Javascript statement which, when processed
- * using <tt>eval()</tt>, will return either a config object with an {@link Ext.Component#xtype xtype},
- * or an instantiated Component. The server might return this for example:</p><pre><code>
-(function() {
-    function formatDate(value){
-        return value ? value.dateFormat('M d, Y') : '';
-    };
-
-    var store = new Ext.data.Store({
-        url: 'get-invoice-data.php',
-        baseParams: {
-            startDate: '01/01/2008',
-            endDate: '01/31/2008'
-        },
-        reader: new Ext.data.JsonReader({
-            record: 'transaction',
-            idProperty: 'id',
-            totalRecords: 'total'
-        }, [
-           'customer',
-           'invNo',
-           {name: 'date', type: 'date', dateFormat: 'm/d/Y'},
-           {name: 'value', type: 'float'}
-        ])
-    });
-
-    var grid = new Ext.grid.GridPanel({
-        title: 'Invoice Report',
-        bbar: new Ext.PagingToolbar(store),
-        store: store,
-        columns: [
-            {header: "Customer", width: 250, dataIndex: 'customer', sortable: true},
-            {header: "Invoice Number", width: 120, dataIndex: 'invNo', sortable: true},
-            {header: "Invoice Date", width: 100, dataIndex: 'date', renderer: formatDate, sortable: true},
-            {header: "Value", width: 120, dataIndex: 'value', renderer: 'usMoney', sortable: true}
-        ],
-    });
-    store.load();
-    return grid;  // return instantiated component
-})();
-</code></pre>
- * <p>When the above code fragment is passed through the <tt>eval</tt> function in the success handler
- * of the Ajax request, the code is executed by the Javascript processor, and the anonymous function
- * runs, and returns the instantiated grid component.</p>
- * <p>Note: since the code above is <i>generated</i> by a server script, the <tt>baseParams</tt> for
- * the Store, the metadata to allow generation of the Record layout, and the ColumnModel
- * can all be generated into the code since these are all known on the server.</p>
- *
- * @xtype container
- */
-Ext.Container = Ext.extend(Ext.BoxComponent, {
-    /**
-     * @cfg {Boolean} monitorResize
-     * True to automatically monitor window resize events to handle anything that is sensitive to the current size
-     * of the viewport.  This value is typically managed by the chosen <code>{@link #layout}</code> and should not need
-     * to be set manually.
-     */
-    /**
-     * @cfg {String/Object} layout
-     * When creating complex UIs, it is important to remember that sizing and
-     * positioning of child items is the responsibility of the Container's
-     * layout manager. If you expect child items to be sized in response to
-     * user interactions, <b>you must specify a layout manager</b> which
-     * creates and manages the type of layout you have in mind.  For example:<pre><code>
-new Ext.Window({
-    width:300, height: 300,
-    layout: 'fit', // explicitly set layout manager: override the default (layout:'auto')
-    items: [{
-        title: 'Panel inside a Window'
-    }]
-}).show();
-     * </code></pre>
-     * <p>Omitting the {@link #layout} config means that the
-     * {@link Ext.layout.ContainerLayout default layout manager} will be used which does
-     * nothing but render child components sequentially into the Container (no sizing or
-     * positioning will be performed in this situation).</p>
-     * <p>The layout manager class for this container may be specified as either as an
-     * Object or as a String:</p>
-     * <div><ul class="mdetail-params">
-     *
-     * <li><u>Specify as an Object</u></li>
-     * <div><ul class="mdetail-params">
-     * <li>Example usage:</li>
-<pre><code>
-layout: {
-    type: 'vbox',
-    padding: '5',
-    align: 'left'
-}
-</code></pre>
-     *
-     * <li><tt><b>type</b></tt></li>
-     * <br/><p>The layout type to be used for this container.  If not specified,
-     * a default {@link Ext.layout.ContainerLayout} will be created and used.</p>
-     * <br/><p>Valid layout <tt>type</tt> values are:</p>
-     * <div class="sub-desc"><ul class="mdetail-params">
-     * <li><tt><b>{@link Ext.layout.AbsoluteLayout absolute}</b></tt></li>
-     * <li><tt><b>{@link Ext.layout.AccordionLayout accordion}</b></tt></li>
-     * <li><tt><b>{@link Ext.layout.AnchorLayout anchor}</b></tt></li>
-     * <li><tt><b>{@link Ext.layout.ContainerLayout auto}</b></tt> &nbsp;&nbsp;&nbsp; <b>Default</b></li>
-     * <li><tt><b>{@link Ext.layout.BorderLayout border}</b></tt></li>
-     * <li><tt><b>{@link Ext.layout.CardLayout card}</b></tt></li>
-     * <li><tt><b>{@link Ext.layout.ColumnLayout column}</b></tt></li>
-     * <li><tt><b>{@link Ext.layout.FitLayout fit}</b></tt></li>
-     * <li><tt><b>{@link Ext.layout.FormLayout form}</b></tt></li>
-     * <li><tt><b>{@link Ext.layout.HBoxLayout hbox}</b></tt></li>
-     * <li><tt><b>{@link Ext.layout.MenuLayout menu}</b></tt></li>
-     * <li><tt><b>{@link Ext.layout.TableLayout table}</b></tt></li>
-     * <li><tt><b>{@link Ext.layout.ToolbarLayout toolbar}</b></tt></li>
-     * <li><tt><b>{@link Ext.layout.VBoxLayout vbox}</b></tt></li>
-     * </ul></div>
-     *
-     * <li>Layout specific configuration properties</li>
-     * <br/><p>Additional layout specific configuration properties may also be
-     * specified. For complete details regarding the valid config options for
-     * each layout type, see the layout class corresponding to the <tt>type</tt>
-     * specified.</p>
-     *
-     * </ul></div>
-     *
-     * <li><u>Specify as a String</u></li>
-     * <div><ul class="mdetail-params">
-     * <li>Example usage:</li>
-<pre><code>
-layout: 'vbox',
-layoutConfig: {
-    padding: '5',
-    align: 'left'
-}
-</code></pre>
-     * <li><tt><b>layout</b></tt></li>
-     * <br/><p>The layout <tt>type</tt> to be used for this container (see list
-     * of valid layout type values above).</p><br/>
-     * <li><tt><b>{@link #layoutConfig}</b></tt></li>
-     * <br/><p>Additional layout specific configuration properties. For complete
-     * details regarding the valid config options for each layout type, see the
-     * layout class corresponding to the <tt>layout</tt> specified.</p>
-     * </ul></div></ul></div>
-     */
-    /**
-     * @cfg {Object} layoutConfig
-     * This is a config object containing properties specific to the chosen
-     * <b><code>{@link #layout}</code></b> if <b><code>{@link #layout}</code></b>
-     * has been specified as a <i>string</i>.</p>
-     */
-    /**
-     * @cfg {Boolean/Number} bufferResize
-     * When set to true (100 milliseconds) or a number of milliseconds, the layout assigned for this container will buffer
-     * the frequency it calculates and does a re-layout of components. This is useful for heavy containers or containers
-     * with a large quantity of sub-components for which frequent layout calls would be expensive.
-     */
-    bufferResize: 100,
-    
-    /**
-     * @cfg {String/Number} activeItem
-     * A string component id or the numeric index of the component that should be initially activated within the
-     * container's layout on render.  For example, activeItem: 'item-1' or activeItem: 0 (index 0 = the first
-     * item in the container's collection).  activeItem only applies to layout styles that can display
-     * items one at a time (like {@link Ext.layout.AccordionLayout}, {@link Ext.layout.CardLayout} and
-     * {@link Ext.layout.FitLayout}).  Related to {@link Ext.layout.ContainerLayout#activeItem}.
-     */
-    /**
-     * @cfg {Object/Array} items
-     * <pre><b>** IMPORTANT</b>: be sure to specify a <b><code>{@link #layout}</code> ! **</b></pre>
-     * <p>A single item, or an array of child Components to be added to this container,
-     * for example:</p>
-     * <pre><code>
-// specifying a single item
-items: {...},
-layout: 'fit',    // specify a layout!
-
-// specifying multiple items
-items: [{...}, {...}],
-layout: 'anchor', // specify a layout!
-     * </code></pre>
-     * <p>Each item may be:</p>
-     * <div><ul class="mdetail-params">
-     * <li>any type of object based on {@link Ext.Component}</li>
-     * <li>a fully instanciated object or</li>
-     * <li>an object literal that:</li>
-     * <div><ul class="mdetail-params">
-     * <li>has a specified <code>{@link Ext.Component#xtype xtype}</code></li>
-     * <li>the {@link Ext.Component#xtype} specified is associated with the Component
-     * desired and should be chosen from one of the available xtypes as listed
-     * in {@link Ext.Component}.</li>
-     * <li>If an <code>{@link Ext.Component#xtype xtype}</code> is not explicitly
-     * specified, the {@link #defaultType} for that Container is used.</li>
-     * <li>will be "lazily instanciated", avoiding the overhead of constructing a fully
-     * instanciated Component object</li>
-     * </ul></div></ul></div>
-     * <p><b>Notes</b>:</p>
-     * <div><ul class="mdetail-params">
-     * <li>Ext uses lazy rendering. Child Components will only be rendered
-     * should it become necessary. Items are automatically laid out when they are first
-     * shown (no sizing is done while hidden), or in response to a {@link #doLayout} call.</li>
-     * <li>Do not specify <code>{@link Ext.Panel#contentEl contentEl}</code>/
-     * <code>{@link Ext.Panel#html html}</code> with <code>items</code>.</li>
-     * </ul></div>
-     */
-    /**
-     * @cfg {Object} defaults
-     * <p>A config object that will be applied to all components added to this container either via the {@link #items}
-     * config or via the {@link #add} or {@link #insert} methods.  The <tt>defaults</tt> config can contain any
-     * number of name/value property pairs to be added to each item, and should be valid for the types of items
-     * being added to the container.  For example, to automatically apply padding to the body of each of a set of
-     * contained {@link Ext.Panel} items, you could pass: <tt>defaults: {bodyStyle:'padding:15px'}</tt>.</p><br/>
-     * <p><b>Note</b>: <tt>defaults</tt> will not be applied to config objects if the option is already specified.
-     * For example:</p><pre><code>
-defaults: {               // defaults are applied to items, not the container
-    autoScroll:true
-},
-items: [
-    {
-        xtype: 'panel',   // defaults <b>do not</b> have precedence over
-        id: 'panel1',     // options in config objects, so the defaults
-        autoScroll: false // will not be applied here, panel1 will be autoScroll:false
-    },
-    new Ext.Panel({       // defaults <b>do</b> have precedence over options
-        id: 'panel2',     // options in components, so the defaults
-        autoScroll: false // will be applied here, panel2 will be autoScroll:true.
-    })
-]
-     * </code></pre>
-     */
-
-
-    /** @cfg {Boolean} autoDestroy
-     * If true the container will automatically destroy any contained component that is removed from it, else
-     * destruction must be handled manually (defaults to true).
-     */
-    autoDestroy : true,
-
-    /** @cfg {Boolean} forceLayout
-     * If true the container will force a layout initially even if hidden or collapsed. This option
-     * is useful for forcing forms to render in collapsed or hidden containers. (defaults to false).
-     */
-    forceLayout: false,
-
-    /** @cfg {Boolean} hideBorders
-     * True to hide the borders of each contained component, false to defer to the component's existing
-     * border settings (defaults to false).
-     */
-    /** @cfg {String} defaultType
-     * <p>The default {@link Ext.Component xtype} of child Components to create in this Container when
-     * a child item is specified as a raw configuration object, rather than as an instantiated Component.</p>
-     * <p>Defaults to <tt>'panel'</tt>, except {@link Ext.menu.Menu} which defaults to <tt>'menuitem'</tt>,
-     * and {@link Ext.Toolbar} and {@link Ext.ButtonGroup} which default to <tt>'button'</tt>.</p>
-     */
-    defaultType : 'panel',
-
-    // private
-    initComponent : function(){
-        Ext.Container.superclass.initComponent.call(this);
-
-        this.addEvents(
-            /**
-             * @event afterlayout
-             * Fires when the components in this container are arranged by the associated layout manager.
-             * @param {Ext.Container} this
-             * @param {ContainerLayout} layout The ContainerLayout implementation for this container
-             */
-            'afterlayout',
-            /**
-             * @event beforeadd
-             * Fires before any {@link Ext.Component} is added or inserted into the container.
-             * A handler can return false to cancel the add.
-             * @param {Ext.Container} this
-             * @param {Ext.Component} component The component being added
-             * @param {Number} index The index at which the component will be added to the container's items collection
-             */
-            'beforeadd',
-            /**
-             * @event beforeremove
-             * Fires before any {@link Ext.Component} is removed from the container.  A handler can return
-             * false to cancel the remove.
-             * @param {Ext.Container} this
-             * @param {Ext.Component} component The component being removed
-             */
-            'beforeremove',
-            /**
-             * @event add
-             * @bubbles
-             * Fires after any {@link Ext.Component} is added or inserted into the container.
-             * @param {Ext.Container} this
-             * @param {Ext.Component} component The component that was added
-             * @param {Number} index The index at which the component was added to the container's items collection
-             */
-            'add',
-            /**
-             * @event remove
-             * @bubbles
-             * Fires after any {@link Ext.Component} is removed from the container.
-             * @param {Ext.Container} this
-             * @param {Ext.Component} component The component that was removed
-             */
-            'remove'
-        );
-
-               this.enableBubble('add', 'remove');
-
-        /**
-         * The collection of components in this container as a {@link Ext.util.MixedCollection}
-         * @type MixedCollection
-         * @property items
-         */
-        var items = this.items;
-        if(items){
-            delete this.items;
-            if(Ext.isArray(items) && items.length > 0){
-                this.add.apply(this, items);
-            }else{
-                this.add(items);
-            }
-        }
-    },
-
-    // private
-    initItems : function(){
-        if(!this.items){
-            this.items = new Ext.util.MixedCollection(false, this.getComponentId);
-            this.getLayout(); // initialize the layout
-        }
-    },
-
-    // private
-    setLayout : function(layout){
-        if(this.layout && this.layout != layout){
-            this.layout.setContainer(null);
-        }
-        this.initItems();
-        this.layout = layout;
-        layout.setContainer(this);
-    },
-
-    // private
-    render : function(){
-        Ext.Container.superclass.render.apply(this, arguments);
-        if(this.layout){
-            if(Ext.isObject(this.layout) && !this.layout.layout){
-                this.layoutConfig = this.layout;
-                this.layout = this.layoutConfig.type;
-            }
-            if(typeof this.layout == 'string'){
-                this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
-            }
-            this.setLayout(this.layout);
-
-            if(this.activeItem !== undefined){
-                var item = this.activeItem;
-                delete this.activeItem;
-                this.layout.setActiveItem(item);
-            }
-        }
-        if(!this.ownerCt){
-            // force a layout if no ownerCt is set
-            this.doLayout(false, true);
-        }
-        if(this.monitorResize === true){
-            Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
-        }
-    },
-
-    /**
-     * <p>Returns the Element to be used to contain the child Components of this Container.</p>
-     * <p>An implementation is provided which returns the Container's {@link #getEl Element}, but
-     * if there is a more complex structure to a Container, this may be overridden to return
-     * the element into which the {@link #layout layout} renders child Components.</p>
-     * @return {Ext.Element} The Element to render child Components into.
-     */
-    getLayoutTarget : function(){
-        return this.el;
-    },
-
-    // private - used as the key lookup function for the items collection
-    getComponentId : function(comp){
-        return comp.getItemId();
-    },
-
-    /**
-     * <p>Adds {@link Ext.Component Component}(s) to this Container.</p>
-     * <br><p><b>Description</b></u> :
-     * <div><ul class="mdetail-params">
-     * <li>Fires the {@link #beforeadd} event before adding</li>
-     * <li>The Container's {@link #defaults default config values} will be applied
-     * accordingly (see <code>{@link #defaults}</code> for details).</li>
-     * <li>Fires the {@link #add} event after the component has been added.</li>
-     * </ul></div>
-     * <br><p><b>Notes</b></u> :
-     * <div><ul class="mdetail-params">
-     * <li>If the Container is <i>already rendered</i> when <tt>add</tt>
-     * is called, you may need to call {@link #doLayout} to refresh the view which causes
-     * any unrendered child Components to be rendered. This is required so that you can
-     * <tt>add</tt> multiple child components if needed while only refreshing the layout
-     * once. For example:<pre><code>
-var tb = new {@link Ext.Toolbar}();
-tb.render(document.body);  // toolbar is rendered
-tb.add({text:'Button 1'}); // add multiple items ({@link #defaultType} for {@link Ext.Toolbar Toolbar} is 'button')
-tb.add({text:'Button 2'});
-tb.{@link #doLayout}();             // refresh the layout
-     * </code></pre></li>
-     * <li><i>Warning:</i> Containers directly managed by the BorderLayout layout manager
-     * may not be removed or added.  See the Notes for {@link Ext.layout.BorderLayout BorderLayout}
-     * for more details.</li>
-     * </ul></div>
-     * @param {Object/Array} component
-     * <p>Either a single component or an Array of components to add.  See
-     * <code>{@link #items}</code> for additional information.</p>
-     * @param {Object} (Optional) component_2
-     * @param {Object} (Optional) component_n
-     * @return {Ext.Component} component The Component (or config object) that was added.
-     */
-    add : function(comp){
-        this.initItems();
-        var args = arguments.length > 1;
-        if(args || Ext.isArray(comp)){
-            Ext.each(args ? arguments : comp, function(c){
-                this.add(c);
-            }, this);
-            return;
-        }
-        var c = this.lookupComponent(this.applyDefaults(comp));
-        var pos = this.items.length;
-        if(this.fireEvent('beforeadd', this, c, pos) !== false && this.onBeforeAdd(c) !== false){
-            this.items.add(c);
-            c.ownerCt = this;
-            this.fireEvent('add', this, c, pos);
-        }
-        return c;
-    },
-
-    /**
-     * Inserts a Component into this Container at a specified index. Fires the
-     * {@link #beforeadd} event before inserting, then fires the {@link #add} event after the
-     * Component has been inserted.
-     * @param {Number} index The index at which the Component will be inserted
-     * into the Container's items collection
-     * @param {Ext.Component} component The child Component to insert.<br><br>
-     * Ext uses lazy rendering, and will only render the inserted Component should
-     * it become necessary.<br><br>
-     * A Component config object may be passed in order to avoid the overhead of
-     * constructing a real Component object if lazy rendering might mean that the
-     * inserted Component will not be rendered immediately. To take advantage of
-     * this 'lazy instantiation', set the {@link Ext.Component#xtype} config
-     * property to the registered type of the Component wanted.<br><br>
-     * For a list of all available xtypes, see {@link Ext.Component}.
-     * @return {Ext.Component} component The Component (or config object) that was
-     * inserted with the Container's default config values applied.
-     */
-    insert : function(index, comp){
-        this.initItems();
-        var a = arguments, len = a.length;
-        if(len > 2){
-            for(var i = len-1; i >= 1; --i) {
-                this.insert(index, a[i]);
-            }
-            return;
-        }
-        var c = this.lookupComponent(this.applyDefaults(comp));
-
-        if(c.ownerCt == this && this.items.indexOf(c) < index){
-            --index;
-        }
-
-        if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
-            this.items.insert(index, c);
-            c.ownerCt = this;
-            this.fireEvent('add', this, c, index);
-        }
-        return c;
-    },
-
-    // private
-    applyDefaults : function(c){
-        if(this.defaults){
-            if(typeof c == 'string'){
-                c = Ext.ComponentMgr.get(c);
-                Ext.apply(c, this.defaults);
-            }else if(!c.events){
-                Ext.applyIf(c, this.defaults);
-            }else{
-                Ext.apply(c, this.defaults);
-            }
-        }
-        return c;
-    },
-
-    // private
-    onBeforeAdd : function(item){
-        if(item.ownerCt){
-            item.ownerCt.remove(item, false);
-        }
-        if(this.hideBorders === true){
-            item.border = (item.border === true);
-        }
-    },
-
-    /**
-     * Removes a component from this container.  Fires the {@link #beforeremove} event before removing, then fires
-     * the {@link #remove} event after the component has been removed.
-     * @param {Component/String} component The component reference or id to remove.
-     * @param {Boolean} autoDestroy (optional) True to automatically invoke the removed Component's {@link Ext.Component#destroy} function.
-     * Defaults to the value of this Container's {@link #autoDestroy} config.
-     * @return {Ext.Component} component The Component that was removed.
-     */
-    remove : function(comp, autoDestroy){
-        this.initItems();
-        var c = this.getComponent(comp);
-        if(c && this.fireEvent('beforeremove', this, c) !== false){
-            this.items.remove(c);
-            delete c.ownerCt;
-            if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
-                c.destroy();
-            }
-            if(this.layout && this.layout.activeItem == c){
-                delete this.layout.activeItem;
-            }
-            this.fireEvent('remove', this, c);
-        }
-        return c;
-    },
-
-    /**
-     * Removes all components from this container.
-     * @param {Boolean} autoDestroy (optional) True to automatically invoke the removed Component's {@link Ext.Component#destroy} function.
-     * Defaults to the value of this Container's {@link #autoDestroy} config.
-     * @return {Array} Array of the destroyed components
-     */
-    removeAll: function(autoDestroy){
-        this.initItems();
-        var item, rem = [], items = [];
-        this.items.each(function(i){
-            rem.push(i);
-        });
-        for (var i = 0, len = rem.length; i < len; ++i){
-            item = rem[i];
-            this.remove(item, autoDestroy);
-            if(item.ownerCt !== this){
-                items.push(item);
-            }
-        }
-        return items;
-    },
-
-    /**
-     * Examines this container's <code>{@link #items}</code> <b>property</b>
-     * and gets a direct child component of this container.
-     * @param {String/Number} comp This parameter may be any of the following:
-     * <div><ul class="mdetail-params">
-     * <li>a <b><tt>String</tt></b> : representing the <code>{@link Ext.Component#itemId itemId}</code>
-     * or <code>{@link Ext.Component#id id}</code> of the child component </li>
-     * <li>a <b><tt>Number</tt></b> : representing the position of the child component
-     * within the <code>{@link #items}</code> <b>property</b></li>
-     * </ul></div>
-     * <p>For additional information see {@link Ext.util.MixedCollection#get}.
-     * @return Ext.Component The component (if found).
-     */
-    getComponent : function(comp){
-        if(Ext.isObject(comp)){
-            return comp;
-        }
-        return this.items.get(comp);
-    },
-
-    // private
-    lookupComponent : function(comp){
-        if(typeof comp == 'string'){
-            return Ext.ComponentMgr.get(comp);
-        }else if(!comp.events){
-            return this.createComponent(comp);
-        }
-        return comp;
-    },
-
-    // private
-    createComponent : function(config){
-        return Ext.create(config, this.defaultType);
-    },
-
-    /**
-     * Force this container's layout to be recalculated. A call to this function is required after adding a new component
-     * to an already rendered container, or possibly after changing sizing/position properties of child components.
-     * @param {Boolean} shallow (optional) True to only calc the layout of this component, and let child components auto
-     * calc layouts as required (defaults to false, which calls doLayout recursively for each subcontainer)
-     * @param {Boolean} force (optional) True to force a layout to occur, even if the item is hidden.
-     * @return {Ext.Container} this
-     */
-    doLayout: function(shallow, force){
-        var rendered = this.rendered,
-            forceLayout = this.forceLayout;
-
-        if(!this.isVisible() || this.collapsed){
-            this.deferLayout = this.deferLayout || !shallow;
-            if(!(force || forceLayout)){
-                return;
-            }
-            shallow = shallow && !this.deferLayout;
-        } else {
-            delete this.deferLayout;
-        }
-        if(rendered && this.layout){
-            this.layout.layout();
-        }
-        if(shallow !== true && this.items){
-            var cs = this.items.items;
-            for(var i = 0, len = cs.length; i < len; i++){
-                var c = cs[i];
-                if(c.doLayout){
-                    c.forceLayout = forceLayout;
-                    c.doLayout();
-                }
-            }
-        }
-        if(rendered){
-            this.onLayout(shallow, force);
-        }
-        delete this.forceLayout;
-    },
-
-    //private
-    onLayout : Ext.emptyFn,
-
-    onShow : function(){
-        Ext.Container.superclass.onShow.call(this);
-        if(this.deferLayout !== undefined){
-            this.doLayout(true);
-        }
-    },
-
-    /**
-     * Returns the layout currently in use by the container.  If the container does not currently have a layout
-     * set, a default {@link Ext.layout.ContainerLayout} will be created and set as the container's layout.
-     * @return {ContainerLayout} layout The container's layout
-     */
-    getLayout : function(){
-        if(!this.layout){
-            var layout = new Ext.layout.ContainerLayout(this.layoutConfig);
-            this.setLayout(layout);
-        }
-        return this.layout;
-    },
-
-    // private
-    beforeDestroy : function(){
-        if(this.items){
-            Ext.destroy.apply(Ext, this.items.items);
-        }
-        if(this.monitorResize){
-            Ext.EventManager.removeResizeListener(this.doLayout, this);
-        }
-        Ext.destroy(this.layout);
-        Ext.Container.superclass.beforeDestroy.call(this);
-    },
-
-    /**
-     * Bubbles up the component/container heirarchy, calling the specified function with each component. The scope (<i>this</i>) of
-     * function call will be the scope provided or the current component. The arguments to the function
-     * will be the args provided or the current component. If the function returns false at any point,
-     * the bubble is stopped.
-     * @param {Function} fn The function to call
-     * @param {Object} scope (optional) The scope of the function (defaults to current node)
-     * @param {Array} args (optional) The args to call the function with (default to passing the current component)
-     * @return {Ext.Container} this
-     */
-    bubble : function(fn, scope, args){
-        var p = this;
-        while(p){
-            if(fn.apply(scope || p, args || [p]) === false){
-                break;
-            }
-            p = p.ownerCt;
-        }
-        return this;
-    },
-
-    /**
-     * Cascades down the component/container heirarchy from this component (called first), calling the specified function with
-     * each component. The scope (<i>this</i>) of
-     * function call will be the scope provided or the current component. The arguments to the function
-     * will be the args provided or the current component. If the function returns false at any point,
-     * the cascade is stopped on that branch.
-     * @param {Function} fn The function to call
-     * @param {Object} scope (optional) The scope of the function (defaults to current component)
-     * @param {Array} args (optional) The args to call the function with (defaults to passing the current component)
-     * @return {Ext.Container} this
-     */
-    cascade : function(fn, scope, args){
-        if(fn.apply(scope || this, args || [this]) !== false){
-            if(this.items){
-                var cs = this.items.items;
-                for(var i = 0, len = cs.length; i < len; i++){
-                    if(cs[i].cascade){
-                        cs[i].cascade(fn, scope, args);
-                    }else{
-                        fn.apply(scope || cs[i], args || [cs[i]]);
-                    }
-                }
-            }
-        }
-        return this;
-    },
-
-    /**
-     * Find a component under this container at any level by id
-     * @param {String} id
-     * @return Ext.Component
-     */
-    findById : function(id){
-        var m, ct = this;
-        this.cascade(function(c){
-            if(ct != c && c.id === id){
-                m = c;
-                return false;
-            }
-        });
-        return m || null;
-    },
-
-    /**
-     * Find a component under this container at any level by xtype or class
-     * @param {String/Class} xtype The xtype string for a component, or the class of the component directly
-     * @param {Boolean} shallow (optional) False to check whether this Component is descended from the xtype (this is
-     * the default), or true to check whether this Component is directly of the specified xtype.
-     * @return {Array} Array of Ext.Components
-     */
-    findByType : function(xtype, shallow){
-        return this.findBy(function(c){
-            return c.isXType(xtype, shallow);
-        });
-    },
-
-    /**
-     * Find a component under this container at any level by property
-     * @param {String} prop
-     * @param {String} value
-     * @return {Array} Array of Ext.Components
-     */
-    find : function(prop, value){
-        return this.findBy(function(c){
-            return c[prop] === value;
-        });
-    },
-
-    /**
-     * Find a component under this container at any level by a custom function. If the passed function returns
-     * true, the component will be included in the results. The passed function is called with the arguments (component, this container).
-     * @param {Function} fn The function to call
-     * @param {Object} scope (optional)
-     * @return {Array} Array of Ext.Components
-     */
-    findBy : function(fn, scope){
-        var m = [], ct = this;
-        this.cascade(function(c){
-            if(ct != c && fn.call(scope || c, c, ct) === true){
-                m.push(c);
-            }
-        });
-        return m;
-    },
-
-    /**
-     * Get a component contained by this container (alias for items.get(key))
-     * @param {String/Number} key The index or id of the component
-     * @return {Ext.Component} Ext.Component
-     */
-    get : function(key){
-        return this.items.get(key);
-    }
-});
-
-Ext.Container.LAYOUTS = {};
-Ext.reg('container', Ext.Container);
-/**
- * @class Ext.layout.ContainerLayout
- * <p>The ContainerLayout class is the default layout manager delegated by {@link Ext.Container} to
- * render any child Components when no <tt>{@link Ext.Container#layout layout}</tt> is configured into
- * a {@link Ext.Container Container}. ContainerLayout provides the basic foundation for all other layout
- * classes in Ext. It simply renders all child Components into the Container, performing no sizing or
- * positioning services. To utilize a layout that provides sizing and positioning of child Components,
- * specify an appropriate <tt>{@link Ext.Container#layout layout}</tt>.</p>
- * <p>This class is intended to be extended or created via the <tt><b>{@link Ext.Container#layout layout}</b></tt>
- * configuration property.  See <tt><b>{@link Ext.Container#layout}</b></tt> for additional details.</p>
- */
-Ext.layout.ContainerLayout = function(config){
-    Ext.apply(this, config);
-};
+ * @class Ext.layout.ContainerLayout
+ * <p>The ContainerLayout class is the default layout manager delegated by {@link Ext.Container} to
+ * render any child Components when no <tt>{@link Ext.Container#layout layout}</tt> is configured into
+ * a {@link Ext.Container Container}. ContainerLayout provides the basic foundation for all other layout
+ * classes in Ext. It simply renders all child Components into the Container, performing no sizing or
+ * positioning services. To utilize a layout that provides sizing and positioning of child Components,
+ * specify an appropriate <tt>{@link Ext.Container#layout layout}</tt>.</p>
+ * <p>This class is intended to be extended or created via the <tt><b>{@link Ext.Container#layout layout}</b></tt>
+ * configuration property.  See <tt><b>{@link Ext.Container#layout}</b></tt> for additional details.</p>
+ */
+Ext.layout.ContainerLayout = function(config){
+    Ext.apply(this, config);
+};
 
 Ext.layout.ContainerLayout.prototype = {
     /**
@@ -17911,7 +18343,7 @@ Ext.layout.ContainerLayout.prototype = {
             c.render(target, position);
             this.configureItem(c, position);
         }else if(c && !this.isValidParent(c, target)){
-            if(typeof position == 'number'){
+            if(Ext.isNumber(position)){
                 position = target.dom.childNodes[position];
             }
             target.dom.insertBefore(c.getDomPositionEl().dom, position || null);
@@ -17929,47 +18361,60 @@ Ext.layout.ContainerLayout.prototype = {
         if (this.renderHidden && c != this.activeItem) {
             c.hide();
         }
-        if(c.doLayout){
-            c.doLayout(false, this.forceLayout);
+        if(c.doLayout && this.forceLayout){
+            c.doLayout(false, true);
+        }
+    },
+    
+    onRemove: function(c){
+         if(this.activeItem == c){
+            delete this.activeItem;
+         }
+         if(c.rendered && this.extraCls){
+            var t = c.getPositionEl ? c.getPositionEl() : c;
+            t.removeClass(this.extraCls);
         }
     },
 
     // private
     onResize: function(){
-        if(this.container.collapsed){
+        var ct = this.container,
+            b;
+            
+        if(ct.collapsed){
             return;
         }
-        var b = this.container.bufferResize;
-        if(b){
-            if(!this.resizeTask){
-                this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
-                this.resizeBuffer = typeof b == 'number' ? b : 100;
+        if(b = ct.bufferResize){
+            // Only allow if we should buffer the layout
+            if(ct.shouldBufferLayout()){
+                if(!this.resizeTask){
+                    this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
+                    this.resizeBuffer = Ext.isNumber(b) ? b : 50;
+                }
+                ct.layoutPending = true;
+                this.resizeTask.delay(this.resizeBuffer);
             }
-            this.resizeTask.delay(this.resizeBuffer);
         }else{
-            this.runLayout();
+            ct.doLayout();
         }
     },
     
     // private
     runLayout: function(){
-        this.layout();
-        this.container.onLayout();
+        var ct = this.container;
+        ct.doLayout();
+        delete ct.layoutPending;
     },
 
     // private
     setContainer : function(ct){
         if(this.monitorResize && ct != this.container){
-            if(this.container){
-                this.container.un('resize', this.onResize, this);
-                this.container.un('bodyresize', this.onResize, this);
+            var old = this.container;
+            if(old){
+                old.un(old.resizeEvent, this.onResize, this);
             }
             if(ct){
-                ct.on({
-                    scope: this,
-                    resize: this.onResize,
-                    bodyresize: this.onResize
-                });
+                ct.on(ct.resizeEvent, this.onResize, this);
             }
         }
         this.container = ct;
@@ -17977,7 +18422,7 @@ Ext.layout.ContainerLayout.prototype = {
 
     // private
     parseMargins : function(v){
-        if(typeof v == 'number'){
+        if(Ext.isNumber(v)){
             v = v.toString();
         }
         var ms = v.split(' ');
@@ -18003,7 +18448,7 @@ Ext.layout.ContainerLayout.prototype = {
     },
 
     /**
-     * The {@link Template Ext.Template} used by Field rendering layout classes (such as
+     * The {@link Ext.Template Ext.Template} used by Field rendering layout classes (such as
      * {@link Ext.layout.FormLayout}) to create the DOM structure of a fully wrapped,
      * labeled and styled form Field. A default Template is supplied, but this may be
      * overriden to create custom field structures. The template processes values returned from
@@ -18173,10 +18618,11 @@ Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
             if(this.activeItem){\r
                 this.activeItem.hide();\r
             }\r
+            var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered);\r
             this.activeItem = item;\r
             item.show();\r
-            this.container.doLayout();\r
-            if(this.layoutOnCardChange && item.doLayout){\r
+            this.layout();\r
+            if(layout){\r
                 item.doLayout();\r
             }\r
         }\r
@@ -18607,8 +19053,8 @@ Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
                 }
                 c.collapsed = false;
                 if(!c.rendered){
-                    c.cls = c.cls ? c.cls +' x-border-panel' : 'x-border-panel';
                     c.render(target, i);
+                    c.getDomPositionEl().addClass('x-border-panel');
                 }
                 this[pos] = pos != 'center' && c.split ?
                     new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
@@ -19718,7 +20164,33 @@ Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
      * @type String
      * @property labelStyle
      */
+    
+    /**
+     * @cfg {Boolean} trackLabels
+     * True to show/hide the field label when the field is hidden. Defaults to <tt>false</tt>.
+     */
+    trackLabels: false,
+    
 
+    onRemove: function(c){
+        Ext.layout.FormLayout.superclass.onRemove.call(this, c);
+        if(this.trackLabels && !this.isHide(c)){
+            c.un('show', this.onFieldShow, this);
+            c.un('hide', this.onFieldHide, this);
+        }
+        // check for itemCt, since we may be removing a fieldset or something similar
+        var el = c.getPositionEl(),
+                ct = c.getItemCt && c.getItemCt();
+        if(c.rendered && ct){
+            el.insertAfter(ct);
+            Ext.destroy(ct);
+            Ext.destroyMembers(c, 'label', 'itemCt');
+            if(c.customItemCt){
+                Ext.destroyMembers(c, 'getItemCt', 'customItemCt');
+            }
+        }
+    },
+    
     // private
     setContainer : function(ct){
         Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
@@ -19727,25 +20199,43 @@ Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
         }
 
         if(ct.hideLabels){
-            this.labelStyle = "display:none";
-            this.elementStyle = "padding-left:0;";
-            this.labelAdjust = 0;
+            Ext.apply(this, {
+                labelStyle: 'display:none',
+                elementStyle: 'padding-left:0;',
+                labelAdjust: 0
+            });
         }else{
             this.labelSeparator = ct.labelSeparator || this.labelSeparator;
             ct.labelWidth = ct.labelWidth || 100;
-            if(typeof ct.labelWidth == 'number'){
-                var pad = (typeof ct.labelPad == 'number' ? ct.labelPad : 5);
-                this.labelAdjust = ct.labelWidth+pad;
-                this.labelStyle = "width:"+ct.labelWidth+"px;";
-                this.elementStyle = "padding-left:"+(ct.labelWidth+pad)+'px';
+            if(Ext.isNumber(ct.labelWidth)){
+                var pad = Ext.isNumber(ct.labelPad) ? ct.labelPad : 5;
+                Ext.apply(this, {
+                    labelAdjust: ct.labelWidth + pad,
+                    labelStyle: 'width:' + ct.labelWidth + 'px;',
+                    elementStyle: 'padding-left:' + (ct.labelWidth + pad) + 'px'
+                });
             }
             if(ct.labelAlign == 'top'){
-                this.labelStyle = "width:auto;";
-                this.labelAdjust = 0;
-                this.elementStyle = "padding-left:0;";
+                Ext.apply(this, {
+                    labelStyle: 'width:auto;',
+                    labelAdjust: 0,
+                    elementStyle: 'padding-left:0;'
+                });
             }
         }
     },
+    
+    isHide: function(c){
+        return c.hideLabel || this.container.hideLabels;
+    },
+    
+    onFieldShow: function(c){
+        c.getItemCt().removeClass('x-hide-' + c.hideMode);
+    },
+    
+    onFieldHide: function(c){
+        c.getItemCt().addClass('x-hide-' + c.hideMode);   
+    },
 
     //private
     getLabelStyle: function(s){
@@ -19797,17 +20287,43 @@ new Ext.Template(
 
     // private
     renderItem : function(c, position, target){
-        if(c && !c.rendered && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
+        if(c && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
             var args = this.getTemplateArgs(c);
-            if(typeof position == 'number'){
+            if(Ext.isNumber(position)){
                 position = target.dom.childNodes[position] || null;
             }
             if(position){
-                this.fieldTpl.insertBefore(position, args);
+                c.itemCt = this.fieldTpl.insertBefore(position, args, true);
             }else{
-                this.fieldTpl.append(target, args);
+                c.itemCt = this.fieldTpl.append(target, args, true);
+            }
+            if(!c.rendered){
+                c.render('x-form-el-' + c.id);
+            }else if(!this.isValidParent(c, target)){
+                Ext.fly('x-form-el-' + c.id).appendChild(c.getPositionEl());
+            }
+            if(!c.getItemCt){
+                // Non form fields don't have getItemCt, apply it here
+                // This will get cleaned up in onRemove
+                Ext.apply(c, {
+                    getItemCt: function(){
+                        return c.itemCt;
+                    },
+                    customItemCt: true
+                });
             }
-            c.render('x-form-el-'+c.id);
+            c.label = c.getItemCt().child('label.x-form-item-label');
+            if(this.trackLabels && !this.isHide(c)){
+                if(c.hidden){
+                    this.onFieldHide(c);
+                }
+                c.on({
+                    scope: this,
+                    show: this.onFieldShow,
+                    hide: this.onFieldHide
+                });
+            }
+            this.configureItem(c);
         }else {
             Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
         }
@@ -19843,22 +20359,33 @@ new Ext.Template(
         return {
             id: field.id,
             label: field.fieldLabel,
-            labelStyle: field.labelStyle||this.labelStyle||'',
+            labelStyle: this.getLabelStyle(field.labelStyle),
             elementStyle: this.elementStyle||'',
-            labelSeparator: noLabelSep ? '' : (typeof field.labelSeparator == 'undefined' ? this.labelSeparator : field.labelSeparator),
+            labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator),
             itemCls: (field.itemCls||this.container.itemCls||'') + (field.hideLabel ? ' x-hide-label' : ''),
             clearCls: field.clearCls || 'x-form-clear-left'
         };
     },
 
     // private
-    adjustWidthAnchor : function(value, comp){
-        return value - (comp.isFormField || comp.fieldLabel  ? (comp.hideLabel ? 0 : this.labelAdjust) : 0);
+    adjustWidthAnchor: function(value, c){
+        if(c.label && !this.isHide(c) && (this.container.labelAlign != 'top')){
+            var adjust = Ext.isIE6 || (Ext.isIE && !Ext.isStrict);
+            return value - this.labelAdjust + (adjust ? -3 : 0);
+        }
+        return value;
+    },
+    
+    adjustHeightAnchor : function(value, c){
+        if(c.label && !this.isHide(c) && (this.container.labelAlign == 'top')){
+            return value - c.label.getHeight();
+        }
+        return value;
     },
 
     // private
     isValidParent : function(c, target){
-        return true;
+        return target && this.container.getEl().contains(c.getDomPositionEl());
     }
 
     /**
@@ -19870,8 +20397,9 @@ new Ext.Template(
 Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;/**\r
  * @class Ext.layout.AccordionLayout\r
  * @extends Ext.layout.FitLayout\r
- * <p>This is a layout that contains multiple panels in an expandable accordion style such that only\r
- * <b>one panel can be open at any given time</b>.  Each panel has built-in support for expanding and collapsing.\r
+ * <p>This is a layout that manages multiple Panels in an expandable accordion style such that only\r
+ * <b>one Panel can be expanded at any given time</b>. Each Panel has built-in support for expanding and collapsing.</p>\r
+ * <p>Note: Only Ext.Panels <b>and all subclasses of Ext.Panel</b> may be used in an accordion layout Container.</p>\r
  * <p>This class is intended to be extended or created via the <tt><b>{@link Ext.Container#layout layout}</b></tt>\r
  * configuration property.  See <tt><b>{@link Ext.Container#layout}</b></tt> for additional details.</p>\r
  * <p>Example usage:</p>\r
@@ -19980,6 +20508,14 @@ Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, {
         c.header.addClass('x-accordion-hd');\r
         c.on('beforeexpand', this.beforeExpand, this);\r
     },\r
+    \r
+    onRemove: function(c){\r
+        Ext.layout.AccordionLayout.superclass.onRemove.call(this, c);\r
+        if(c.rendered){\r
+            c.header.removeClass('x-accordion-hd');\r
+        }\r
+        c.un('beforeexpand', this.beforeExpand, this);\r
+    },\r
 \r
     // private\r
     beforeExpand : function(p, anim){\r
@@ -20206,16 +20742,18 @@ Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
     renderItem : function(c, position, target){\r
         if(c && !c.rendered){\r
             c.render(this.getNextCell(c));\r
-            if(this.extraCls){\r
-                var t = c.getPositionEl ? c.getPositionEl() : c;\r
-                t.addClass(this.extraCls);\r
-            }\r
+            this.configureItem(c, position);\r
+        }else if(c && !this.isValidParent(c, target)){\r
+            var container = this.getNextCell(c);\r
+            container.insertBefore(c.getDomPositionEl().dom, null);\r
+            c.container = Ext.get(container);\r
+            this.configureItem(c, position);\r
         }\r
     },\r
 \r
     // private\r
     isValidParent : function(c, target){\r
-        return true;\r
+        return c.getDomPositionEl().up('table', 5).dom.parentNode === (target.dom || target);\r
     }\r
 \r
     /**\r
@@ -20338,8 +20876,20 @@ Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
     defaultMargins : {left:0,top:0,right:0,bottom:0},\r
     /**\r
      * @cfg {String} padding\r
-     * Defaults to <tt>'0'</tt>. Sets the padding to be applied to all child items managed by this\r
-     * container's layout. \r
+     * <p>Sets the padding to be applied to all child items managed by this layout.</p> \r
+     * <p>This property must be specified as a string containing\r
+     * space-separated, numeric padding values. The order of the sides associated\r
+     * with each value matches the way CSS processes padding values:</p>\r
+     * <div class="mdetail-params"><ul>\r
+     * <li>If there is only one value, it applies to all sides.</li>\r
+     * <li>If there are two values, the top and bottom borders are set to the\r
+     * first value and the right and left are set to the second.</li>\r
+     * <li>If there are three values, the top is set to the first value, the left\r
+     * and right are set to the second, and the bottom is set to the third.</li>\r
+     * <li>If there are four values, they apply to the top, right, bottom, and\r
+     * left, respectively.</li>\r
+     * </ul></div>\r
+     * <p>Defaults to: <code>"0"</code></p>\r
      */\r
     padding : '0',\r
     // documented in subclasses\r
@@ -20351,6 +20901,13 @@ Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
     extraCls : 'x-box-item',\r
     ctCls : 'x-box-layout-ct',\r
     innerCls : 'x-box-inner',\r
+    \r
+    constructor : function(config){\r
+        Ext.layout.BoxLayout.superclass.constructor.call(this, config);\r
+        if(Ext.isString(this.defaultMargins)){\r
+            this.defaultMargins = this.parseMargins(this.defaultMargins);\r
+        }\r
+    },\r
 \r
     // private\r
     isValidParent : function(c, target){\r
@@ -20374,7 +20931,7 @@ Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
 \r
     // private\r
     renderItem : function(c){\r
-        if(typeof c.margins == 'string'){\r
+        if(Ext.isString(c.margins)){\r
             c.margins = this.parseMargins(c.margins);\r
         }else if(!c.margins){\r
             c.margins = this.defaultMargins;\r
@@ -20405,7 +20962,9 @@ Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
 /**\r
  * @class Ext.layout.VBoxLayout\r
  * @extends Ext.layout.BoxLayout\r
- * A layout that arranges items vertically\r
+ * <p>A layout that arranges items vertically down a Container. This layout optionally divides available vertical\r
+ * space between child items containing a numeric <code>flex</code> configuration.</p>\r
+ * This layout may also be used to set the widths of child items by configuring it with the {@link #align} option.\r
  */\r
 Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {\r
     /**\r
@@ -20453,8 +21012,8 @@ Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
         \r
         var cs = this.getItems(ct), cm, ch, margin,\r
             size = this.getTargetSize(target),\r
-            w = size.width - target.getPadding('lr') - this.scrollOffset,\r
-            h = size.height - target.getPadding('tb'),\r
+            w = size.width - target.getPadding('lr'),\r
+            h = size.height - target.getPadding('tb') - this.scrollOffset,\r
             l = this.padding.left, t = this.padding.top,\r
             isStart = this.pack == 'start',\r
             isRestore = ['stretch', 'stretchmax'].indexOf(this.align) == -1,\r
@@ -20560,7 +21119,9 @@ Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;
 /**\r
  * @class Ext.layout.HBoxLayout\r
  * @extends Ext.layout.BoxLayout\r
- * A layout that arranges items horizontally\r
+ * <p>A layout that arranges items horizontally across a Container. This layout optionally divides available horizontal\r
+ * space between child items containing a numeric <code>flex</code> configuration.</p>\r
+ * This layout may also be used to set the heights of child items by configuring it with the {@link #align} option.\r
  */\r
 Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {\r
     /**\r
@@ -20837,7 +21398,7 @@ Ext.reg('viewport', Ext.Viewport);/**
  * of being configured with a {@link Ext.Container#layout layout}, and containing child Components.</p>
  * <p>When either specifying child {@link Ext.Component#items items} of a Panel, or dynamically {@link Ext.Container#add adding} Components
  * to a Panel, remember to consider how you wish the Panel to arrange those child elements, and whether
- * those child elements need to be sized using one of Ext's built-in <tt><b>{@link Ext.Container#layout layout}</b></tt> schemes. By
+ * those child elements need to be sized using one of Ext's built-in <code><b>{@link Ext.Container#layout layout}</b></code> schemes. By
  * default, Panels use the {@link Ext.layout.ContainerLayout ContainerLayout} scheme. This simply renders
  * child components, appending them one after the other inside the Container, and <b>does not apply any sizing</b>
  * at all.</p>
@@ -20856,7 +21417,7 @@ Ext.Panel = Ext.extend(Ext.Container, {
     /**
      * The Panel's header {@link Ext.Element Element}. Read-only.
      * <p>This Element is used to house the {@link #title} and {@link #tools}</p>
-     * <br><p><b>Note</b>: see the Note for <tt>{@link Ext.Component#el el} also.</p>
+     * <br><p><b>Note</b>: see the Note for <code>{@link Ext.Component#el el}</code> also.</p>
      * @type Ext.Element
      * @property header
      */
@@ -20869,7 +21430,7 @@ Ext.Panel = Ext.extend(Ext.Container, {
      * <p>If this Panel is intended to be used as the host of a Layout (See {@link #layout}
      * then the body Element must not be loaded or changed - it is under the control
      * of the Panel's Layout.
-     * <br><p><b>Note</b>: see the Note for <tt>{@link Ext.Component#el el} also.</p>
+     * <br><p><b>Note</b>: see the Note for <code>{@link Ext.Component#el el}</code> also.</p>
      * @type Ext.Element
      * @property body
      */
@@ -20889,8 +21450,8 @@ Ext.Panel = Ext.extend(Ext.Container, {
      * <p>A {@link Ext.DomHelper DomHelper} element specification object may be specified for any
      * Panel Element.</p>
      * <p>By default, the Default element in the table below will be used for the html markup to
-     * create a child element with the commensurate Default class name (<tt>baseCls</tt> will be
-     * replaced by <tt>{@link #baseCls}</tt>):</p>
+     * create a child element with the commensurate Default class name (<code>baseCls</code> will be
+     * replaced by <code>{@link #baseCls}</code>):</p>
      * <pre>
      * Panel      Default  Default             Custom      Additional       Additional
      * Element    element  class               element     class            style
@@ -20926,51 +21487,51 @@ new Ext.Panel({
     footerStyle:    'background-color:red' // see {@link #bodyStyle}
 });
      * </code></pre>
-     * <p>The example above also explicitly creates a <tt>{@link #footer}</tt> with custom markup and
+     * <p>The example above also explicitly creates a <code>{@link #footer}</code> with custom markup and
      * styling applied.</p>
      */
     /**
      * @cfg {Object} headerCfg
      * <p>A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure
-     * of this Panel's {@link #header} Element.  See <tt>{@link #bodyCfg}</tt> also.</p>
+     * of this Panel's {@link #header} Element.  See <code>{@link #bodyCfg}</code> also.</p>
      */
     /**
      * @cfg {Object} bwrapCfg
      * <p>A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure
-     * of this Panel's {@link #bwrap} Element.  See <tt>{@link #bodyCfg}</tt> also.</p>
+     * of this Panel's {@link #bwrap} Element.  See <code>{@link #bodyCfg}</code> also.</p>
      */
     /**
      * @cfg {Object} tbarCfg
      * <p>A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure
-     * of this Panel's {@link #tbar} Element.  See <tt>{@link #bodyCfg}</tt> also.</p>
+     * of this Panel's {@link #tbar} Element.  See <code>{@link #bodyCfg}</code> also.</p>
      */
     /**
      * @cfg {Object} bbarCfg
      * <p>A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure
-     * of this Panel's {@link #bbar} Element.  See <tt>{@link #bodyCfg}</tt> also.</p>
+     * of this Panel's {@link #bbar} Element.  See <code>{@link #bodyCfg}</code> also.</p>
      */
     /**
      * @cfg {Object} footerCfg
      * <p>A {@link Ext.DomHelper DomHelper} element specification object specifying the element structure
-     * of this Panel's {@link #footer} Element.  See <tt>{@link #bodyCfg}</tt> also.</p>
+     * of this Panel's {@link #footer} Element.  See <code>{@link #bodyCfg}</code> also.</p>
      */
     /**
      * @cfg {Boolean} closable
      * Panels themselves do not directly support being closed, but some Panel subclasses do (like
-     * {@link Ext.Window}) or a Panel Class within an {@link Ext.TabPanel}.  Specify <tt>true</tt>
-     * to enable closing in such situations. Defaults to <tt>false</tt>.
+     * {@link Ext.Window}) or a Panel Class within an {@link Ext.TabPanel}.  Specify <code>true</code>
+     * to enable closing in such situations. Defaults to <code>false</code>.
      */
     /**
      * The Panel's footer {@link Ext.Element Element}. Read-only.
-     * <p>This Element is used to house the Panel's <tt>{@link #buttons}</tt> or <tt>{@link #fbar}</tt>.</p>
-     * <br><p><b>Note</b>: see the Note for <tt>{@link Ext.Component#el el} also.</p>
+     * <p>This Element is used to house the Panel's <code>{@link #buttons}</code> or <code>{@link #fbar}</code>.</p>
+     * <br><p><b>Note</b>: see the Note for <code>{@link Ext.Component#el el}</code> also.</p>
      * @type Ext.Element
      * @property footer
      */
     /**
      * @cfg {Mixed} applyTo
      * <p>The id of the node, a DOM node or an existing Element corresponding to a DIV that is already present in
-     * the document that specifies some panel-specific structural markup.  When <tt>applyTo</tt> is used,
+     * the document that specifies some panel-specific structural markup.  When <code>applyTo</code> is used,
      * constituent parts of the panel can be specified by CSS class name within the main element, and the panel
      * will automatically create those components from that markup. Any required components not specified in the
      * markup will be autogenerated if necessary.</p>
@@ -21001,7 +21562,7 @@ new Ext.Panel({
      * <p>The bottom toolbar of the panel. This can be a {@link Ext.Toolbar} object, a toolbar config, or an array of
      * buttons/button configs to be added to the toolbar.  Note that this is not available as a property after render.
      * To access the bottom toolbar after render, use {@link #getBottomToolbar}.</p>
-     * <p><b>Note:</b> Although a Toolbar may contain Field components, these will <b>not<b> be updated by a load
+     * <p><b>Note:</b> Although a Toolbar may contain Field components, these will <b>not</b> be updated by a load
      * of an ancestor FormPanel. A Panel's toolbars are not part of the standard Container->Component hierarchy, and
      * so are not scanned to collect form items. However, the values <b>will</b> be submitted because form
      * submission parameters are collected from the DOM tree.</p>
@@ -21010,8 +21571,8 @@ new Ext.Panel({
      * <p>A {@link Ext.Toolbar Toolbar} object, a Toolbar config, or an array of
      * {@link Ext.Button Button}s/{@link Ext.Button Button} configs, describing a {@link Ext.Toolbar Toolbar} to be rendered into this Panel's footer element.</p>
      * <p>After render, the <code>fbar</code> property will be an {@link Ext.Toolbar Toolbar} instance.</p>
-     * <p>If <tt>{@link #buttons}</tt> are specified, they will supersede the <tt>fbar</tt> configuration property.</p>
-     * The Panel's <tt>{@link #buttonAlign}</tt> configuration affects the layout of these items, for example:
+     * <p>If <code>{@link #buttons}</code> are specified, they will supersede the <code>fbar</code> configuration property.</p>
+     * The Panel's <code>{@link #buttonAlign}</code> configuration affects the layout of these items, for example:
      * <pre><code>
 var w = new Ext.Window({
     height: 250,
@@ -21023,7 +21584,7 @@ var w = new Ext.Window({
             text: 'bbar Right'
         }]
     }),
-    {@link #buttonAlign}: 'left', // anything but 'center' or 'right' and you can use "-", and "->"
+    {@link #buttonAlign}: 'left', // anything but 'center' or 'right' and you can use '-', and '->'
                                   // to control the alignment of fbar items
     fbar: [{
         text: 'fbar Left'
@@ -21032,40 +21593,40 @@ var w = new Ext.Window({
     }]
 }).show();
      * </code></pre>
-     * <p><b>Note:</b> Although a Toolbar may contain Field components, these will <b>not<b> be updated by a load
+     * <p><b>Note:</b> Although a Toolbar may contain Field components, these will <b>not</b> be updated by a load
      * of an ancestor FormPanel. A Panel's toolbars are not part of the standard Container->Component hierarchy, and
      * so are not scanned to collect form items. However, the values <b>will</b> be submitted because form
      * submission parameters are collected from the DOM tree.</p>
      */
     /**
      * @cfg {Boolean} header
-     * <tt>true</tt> to create the Panel's header element explicitly, <tt>false</tt> to skip creating
-     * it.  If a <tt>{@link #title}</tt> is set the header will be created automatically, otherwise it will not.
-     * If a <tt>{@link #title}</tt> is set but <tt>header</tt> is explicitly set to <tt>false</tt>, the header
+     * <code>true</code> to create the Panel's header element explicitly, <code>false</code> to skip creating
+     * it.  If a <code>{@link #title}</code> is set the header will be created automatically, otherwise it will not.
+     * If a <code>{@link #title}</code> is set but <code>header</code> is explicitly set to <code>false</code>, the header
      * will not be rendered.
      */
     /**
      * @cfg {Boolean} footer
-     * <tt>true</tt> to create the footer element explicitly, false to skip creating it. The footer
-     * will be created automatically if <tt>{@link #buttons}</tt> or a <tt>{@link #fbar}</tt> have
-     * been configured.  See <tt>{@link #bodyCfg}</tt> for an example.
+     * <code>true</code> to create the footer element explicitly, false to skip creating it. The footer
+     * will be created automatically if <code>{@link #buttons}</code> or a <code>{@link #fbar}</code> have
+     * been configured.  See <code>{@link #bodyCfg}</code> for an example.
      */
     /**
      * @cfg {String} title
      * The title text to be used as innerHTML (html tags are accepted) to display in the panel
-     * <tt>{@link #header}</tt> (defaults to ''). When a <tt>title</tt> is specified the
-     * <tt>{@link #header}</tt> element will automatically be created and displayed unless
-     * {@link #header} is explicitly set to <tt>false</tt>.  If you do not want to specify a
-     * <tt>title</tt> at config time, but you may want one later, you must either specify a non-empty
-     * <tt>title</tt> (a blank space ' ' will do) or <tt>header:true</tt> so that the container
+     * <code>{@link #header}</code> (defaults to ''). When a <code>title</code> is specified the
+     * <code>{@link #header}</code> element will automatically be created and displayed unless
+     * {@link #header} is explicitly set to <code>false</code>.  If you do not want to specify a
+     * <code>title</code> at config time, but you may want one later, you must either specify a non-empty
+     * <code>title</code> (a blank space ' ' will do) or <code>header:true</code> so that the container
      * element will get created.
      */
     /**
      * @cfg {Array} buttons
-     * <tt>buttons</tt> will be used as <tt>{@link Ext.Container#items items}</tt> for the toolbar in
-     * the footer (<tt>{@link #fbar}</tt>). Typically the value of this configuration property will be
+     * <code>buttons</code> will be used as <code>{@link Ext.Container#items items}</code> for the toolbar in
+     * the footer (<code>{@link #fbar}</code>). Typically the value of this configuration property will be
      * an array of {@link Ext.Button}s or {@link Ext.Button} configuration objects.
-     * If an item is configured with <tt>minWidth</tt> or the Panel is configured with <tt>minButtonWidth</tt>,
+     * If an item is configured with <code>minWidth</code> or the Panel is configured with <code>minButtonWidth</code>,
      * that width will be applied to the item.
      */
     /**
@@ -21078,7 +21639,7 @@ var w = new Ext.Window({
      */
     /**
      * @cfg {Boolean} frame
-     * <tt>false</tt> by default to render with plain 1px square borders. <tt>true</tt> to render with
+     * <code>false</code> by default to render with plain 1px square borders. <code>true</code> to render with
      * 9 elements, complete with custom rounded corners (also see {@link Ext.Element#boxWrap}).
      * <p>The template generated for each condition is depicted below:</p><pre><code>
      *
@@ -21150,33 +21711,33 @@ var w = new Ext.Window({
     /**
      * @cfg {Array} tools
      * An array of tool button configs to be added to the header tool area. When rendered, each tool is
-     * stored as an {@link Ext.Element Element} referenced by a public property called <tt><b></b>tools.<i>&lt;tool-type&gt;</i></tt>
+     * stored as an {@link Ext.Element Element} referenced by a public property called <code><b></b>tools.<i>&lt;tool-type&gt;</i></code>
      * <p>Each tool config may contain the following properties:
      * <div class="mdetail-params"><ul>
      * <li><b>id</b> : String<div class="sub-desc"><b>Required.</b> The type
-     * of tool to create. By default, this assigns a CSS class of the form <tt>x-tool-<i>&lt;tool-type&gt;</i></tt> to the
+     * of tool to create. By default, this assigns a CSS class of the form <code>x-tool-<i>&lt;tool-type&gt;</i></code> to the
      * resulting tool Element. Ext provides CSS rules, and an icon sprite containing images for the tool types listed below.
      * The developer may implement custom tools by supplying alternate CSS rules and background images:
      * <ul>
-     * <div class="x-tool x-tool-toggle" style="float:left; margin-right:5;"> </div><div><tt> toggle</tt> (Created by default when {@link #collapsible} is <tt>true</tt>)</div>
-     * <div class="x-tool x-tool-close" style="float:left; margin-right:5;"> </div><div><tt> close</tt></div>
-     * <div class="x-tool x-tool-minimize" style="float:left; margin-right:5;"> </div><div><tt> minimize</tt></div>
-     * <div class="x-tool x-tool-maximize" style="float:left; margin-right:5;"> </div><div><tt> maximize</tt></div>
-     * <div class="x-tool x-tool-restore" style="float:left; margin-right:5;"> </div><div><tt> restore</tt></div>
-     * <div class="x-tool x-tool-gear" style="float:left; margin-right:5;"> </div><div><tt> gear</tt></div>
-     * <div class="x-tool x-tool-pin" style="float:left; margin-right:5;"> </div><div><tt> pin</tt></div>
-     * <div class="x-tool x-tool-unpin" style="float:left; margin-right:5;"> </div><div><tt> unpin</tt></div>
-     * <div class="x-tool x-tool-right" style="float:left; margin-right:5;"> </div><div><tt> right</tt></div>
-     * <div class="x-tool x-tool-left" style="float:left; margin-right:5;"> </div><div><tt> left</tt></div>
-     * <div class="x-tool x-tool-up" style="float:left; margin-right:5;"> </div><div><tt> up</tt></div>
-     * <div class="x-tool x-tool-down" style="float:left; margin-right:5;"> </div><div><tt> down</tt></div>
-     * <div class="x-tool x-tool-refresh" style="float:left; margin-right:5;"> </div><div><tt> refresh</tt></div>
-     * <div class="x-tool x-tool-minus" style="float:left; margin-right:5;"> </div><div><tt> minus</tt></div>
-     * <div class="x-tool x-tool-plus" style="float:left; margin-right:5;"> </div><div><tt> plus</tt></div>
-     * <div class="x-tool x-tool-help" style="float:left; margin-right:5;"> </div><div><tt> help</tt></div>
-     * <div class="x-tool x-tool-search" style="float:left; margin-right:5;"> </div><div><tt> search</tt></div>
-     * <div class="x-tool x-tool-save" style="float:left; margin-right:5;"> </div><div><tt> save</tt></div>
-     * <div class="x-tool x-tool-print" style="float:left; margin-right:5;"> </div><div><tt> print</tt></div>
+     * <div class="x-tool x-tool-toggle" style="float:left; margin-right:5;"> </div><div><code> toggle</code> (Created by default when {@link #collapsible} is <code>true</code>)</div>
+     * <div class="x-tool x-tool-close" style="float:left; margin-right:5;"> </div><div><code> close</code></div>
+     * <div class="x-tool x-tool-minimize" style="float:left; margin-right:5;"> </div><div><code> minimize</code></div>
+     * <div class="x-tool x-tool-maximize" style="float:left; margin-right:5;"> </div><div><code> maximize</code></div>
+     * <div class="x-tool x-tool-restore" style="float:left; margin-right:5;"> </div><div><code> restore</code></div>
+     * <div class="x-tool x-tool-gear" style="float:left; margin-right:5;"> </div><div><code> gear</code></div>
+     * <div class="x-tool x-tool-pin" style="float:left; margin-right:5;"> </div><div><code> pin</code></div>
+     * <div class="x-tool x-tool-unpin" style="float:left; margin-right:5;"> </div><div><code> unpin</code></div>
+     * <div class="x-tool x-tool-right" style="float:left; margin-right:5;"> </div><div><code> right</code></div>
+     * <div class="x-tool x-tool-left" style="float:left; margin-right:5;"> </div><div><code> left</code></div>
+     * <div class="x-tool x-tool-up" style="float:left; margin-right:5;"> </div><div><code> up</code></div>
+     * <div class="x-tool x-tool-down" style="float:left; margin-right:5;"> </div><div><code> down</code></div>
+     * <div class="x-tool x-tool-refresh" style="float:left; margin-right:5;"> </div><div><code> refresh</code></div>
+     * <div class="x-tool x-tool-minus" style="float:left; margin-right:5;"> </div><div><code> minus</code></div>
+     * <div class="x-tool x-tool-plus" style="float:left; margin-right:5;"> </div><div><code> plus</code></div>
+     * <div class="x-tool x-tool-help" style="float:left; margin-right:5;"> </div><div><code> help</code></div>
+     * <div class="x-tool x-tool-search" style="float:left; margin-right:5;"> </div><div><code> search</code></div>
+     * <div class="x-tool x-tool-save" style="float:left; margin-right:5;"> </div><div><code> save</code></div>
+     * <div class="x-tool x-tool-print" style="float:left; margin-right:5;"> </div><div><code> print</code></div>
      * </ul></div></li>
      * <li><b>handler</b> : Function<div class="sub-desc"><b>Required.</b> The function to
      * call when clicked. Arguments passed are:<ul>
@@ -21214,7 +21775,7 @@ tools:[{
     }
 }]
 </code></pre>
-     * <p>For the custom id of <tt>'help'</tt> define two relevant css classes with a link to
+     * <p>For the custom id of <code>'help'</code> define two relevant css classes with a link to
      * a 15x15 image:</p>
      * <pre><code>
 .x-tool-help {background-image: url(images/help.png);}
@@ -21249,7 +21810,7 @@ var win = new Ext.Window({
     height:300,
     closeAction:'hide'
 });</code></pre>
-     * <p>Note that the CSS class "x-tool-pdf" should have an associated style rule which provides an
+     * <p>Note that the CSS class 'x-tool-pdf' should have an associated style rule which provides an
      * appropriate background image, something like:</p>
     <pre><code>
     a.x-tool-pdf {background-image: url(../shared/extjs/images/pdf.gif)!important;}
@@ -21257,56 +21818,56 @@ var win = new Ext.Window({
      */
     /**
      * @cfg {Boolean} hideCollapseTool
-     * <tt>true</tt> to hide the expand/collapse toggle button when <code>{@link #collapsible} == true</code>,
-     * <tt>false</tt> to display it (defaults to <tt>false</tt>).
+     * <code>true</code> to hide the expand/collapse toggle button when <code>{@link #collapsible} == true</code>,
+     * <code>false</code> to display it (defaults to <code>false</code>).
      */
     /**
      * @cfg {Boolean} titleCollapse
-     * <tt>true</tt> to allow expanding and collapsing the panel (when <tt>{@link #collapsible} = true</tt>)
-     * by clicking anywhere in the header bar, <tt>false</tt>) to allow it only by clicking to tool button
-     * (defaults to <tt>false</tt>)). If this panel is a child item of a border layout also see the
+     * <code>true</code> to allow expanding and collapsing the panel (when <code>{@link #collapsible} = true</code>)
+     * by clicking anywhere in the header bar, <code>false</code>) to allow it only by clicking to tool button
+     * (defaults to <code>false</code>)). If this panel is a child item of a border layout also see the
      * {@link Ext.layout.BorderLayout.Region BorderLayout.Region}
-     * <tt>{@link Ext.layout.BorderLayout.Region#floatable floatable}</tt> config option.
+     * <code>{@link Ext.layout.BorderLayout.Region#floatable floatable}</code> config option.
      */
     /**
      * @cfg {Boolean} autoScroll
-     * <tt>true</tt> to use overflow:'auto' on the panel's body element and show scroll bars automatically when
-     * necessary, <tt>false</tt> to clip any overflowing content (defaults to <tt>false</tt>).
+     * <code>true</code> to use overflow:'auto' on the panel's body element and show scroll bars automatically when
+     * necessary, <code>false</code> to clip any overflowing content (defaults to <code>false</code>).
      */
     /**
      * @cfg {Mixed} floating
      * <p>This property is used to configure the underlying {@link Ext.Layer}. Acceptable values for this
      * configuration property are:</p><div class="mdetail-params"><ul>
-     * <li><b><tt>false</tt></b> : <b>Default.</b><div class="sub-desc">Display the panel inline where it is
+     * <li><b><code>false</code></b> : <b>Default.</b><div class="sub-desc">Display the panel inline where it is
      * rendered.</div></li>
-     * <li><b><tt>true</tt></b> : <div class="sub-desc">Float the panel (absolute position it with automatic
+     * <li><b><code>true</code></b> : <div class="sub-desc">Float the panel (absolute position it with automatic
      * shimming and shadow).<ul>
      * <div class="sub-desc">Setting floating to true will create an Ext.Layer for this panel and display the
      * panel at negative offsets so that it is hidden.</div>
      * <div class="sub-desc">Since the panel will be absolute positioned, the position must be set explicitly
-     * <i>after</i> render (e.g., <tt>myPanel.setPosition(100,100);</tt>).</div>
+     * <i>after</i> render (e.g., <code>myPanel.setPosition(100,100);</code>).</div>
      * <div class="sub-desc"><b>Note</b>: when floating a panel you should always assign a fixed width,
      * otherwise it will be auto width and will expand to fill to the right edge of the viewport.</div>
      * </ul></div></li>
-     * <li><b><tt>{@link Ext.Layer object}</tt></b> : <div class="sub-desc">The specified object will be used
+     * <li><b><code>{@link Ext.Layer object}</code></b> : <div class="sub-desc">The specified object will be used
      * as the configuration object for the {@link Ext.Layer} that will be created.</div></li>
      * </ul></div>
      */
     /**
      * @cfg {Boolean/String} shadow
-     * <tt>true</tt> (or a valid Ext.Shadow {@link Ext.Shadow#mode} value) to display a shadow behind the
-     * panel, <tt>false</tt> to display no shadow (defaults to <tt>'sides'</tt>).  Note that this option
-     * only applies when <tt>{@link #floating} = true</tt>.
+     * <code>true</code> (or a valid Ext.Shadow {@link Ext.Shadow#mode} value) to display a shadow behind the
+     * panel, <code>false</code> to display no shadow (defaults to <code>'sides'</code>).  Note that this option
+     * only applies when <code>{@link #floating} = true</code>.
      */
     /**
      * @cfg {Number} shadowOffset
-     * The number of pixels to offset the shadow if displayed (defaults to <tt>4</tt>). Note that this
-     * option only applies when <tt>{@link #floating} = true</tt>.
+     * The number of pixels to offset the shadow if displayed (defaults to <code>4</code>). Note that this
+     * option only applies when <code>{@link #floating} = true</code>.
      */
     /**
      * @cfg {Boolean} shim
-     * <tt>false</tt> to disable the iframe shim in browsers which need one (defaults to <tt>true</tt>).
-     * Note that this option only applies when <tt>{@link #floating} = true</tt>.
+     * <code>false</code> to disable the iframe shim in browsers which need one (defaults to <code>true</code>).
+     * Note that this option only applies when <code>{@link #floating} = true</code>.
      */
     /**
      * @cfg {String/Object} html
@@ -21317,36 +21878,34 @@ var win = new Ext.Window({
      */
     /**
      * @cfg {String} contentEl
-     * <p>Specify the <tt>id</tt> of an existing HTML node to use as the panel's body content
-     * (defaults to '').</p><div><ul>
-     * <li><b>Description</b> : <ul>
+     * <p>Optional. Specify an existing HTML element, or the <code>id</code> of an existing HTML element to use as this Panel's
+     * <code><b>{@link #body}</b></code> content.</p>
+     * <ul>
+     * <li><b>Description</b> :
      * <div class="sub-desc">This config option is used to take an existing HTML element and place it in the body
      * of a new panel (it simply moves the specified DOM element into the body element of the Panel
-     * <i>when the Panel is rendered</i> to use as the content (it is not going to be the
-     * actual panel itself).</div>
-     * </ul></li>
-     * <li><b>Notes</b> : <ul>
-     * <div class="sub-desc">The specified HTML Element is appended to the Panel's {@link #body} Element by the
-     * Panel's {@link #afterRender} method <i>after any configured {@link #html HTML} has
-     * been inserted</i>, and so the document will not contain this HTML at the time the
+     * <i>after the Panel is rendered</i> to use as the content (it is not going to be the actual panel itself).</div></li>
+     * <li><b>Notes</b> :
+     * <div class="sub-desc">The specified HTML element is appended to the Panel's {@link #body} Element by the
+     * Panel's <code>afterRender</code> method <i>after any configured {@link #html HTML} has
+     * been inserted</i>, and so the document will not contain this element at the time the
      * {@link #render} event is fired.</div>
-     * <div class="sub-desc">The specified HTML element used will not participate in any layout scheme that the
-     * Panel may use. It's just HTML. Layouts operate on child items.</div>
-     * <div class="sub-desc">Add either the <tt>x-hidden</tt> or the <tt>x-hide-display</tt> CSS class to
-     * prevent a brief flicker of the content before it is rendered to the panel.</div>
-     * </ul></li>
-     * </ul></div>
+     * <div class="sub-desc">The specified HTML element used will not participate in any <code><b>{@link Ext.Container#layout layout}</b></code>
+     * scheme that the Panel may use. It is just HTML. Layouts operate on child <code><b>{@link Ext.Container#items items}</b></code>.</div>
+     * <div class="sub-desc">Add either the <code>x-hidden</code> or the <code>x-hide-display</code> CSS class to
+     * prevent a brief flicker of the content before it is rendered to the panel.</div></li>
+     * </ul>
      */
     /**
      * @cfg {Object/Array} keys
      * A {@link Ext.KeyMap} config object (in the format expected by {@link Ext.KeyMap#addBinding}
-     * used to assign custom key handling to this panel (defaults to <tt>null</tt>).
+     * used to assign custom key handling to this panel (defaults to <code>null</code>).
      */
     /**
      * @cfg {Boolean/Object} draggable
-     * <p><tt>true</tt> to enable dragging of this Panel (defaults to <tt>false</tt>).</p>
+     * <p><code>true</code> to enable dragging of this Panel (defaults to <code>false</code>).</p>
      * <p>For custom drag/drop implementations, an <b>Ext.Panel.DD</b> config could also be passed
-     * in this config instead of <tt>true</tt>. Ext.Panel.DD is an internal, undocumented class which
+     * in this config instead of <code>true</code>. Ext.Panel.DD is an internal, undocumented class which
      * moves a proxy Element around in place of the Panel's element, but provides no other behaviour
      * during dragging or on drop. It is a subclass of {@link Ext.dd.DragSource}, so behaviour may be
      * added by implementing the interface methods of {@link Ext.dd.DragDrop} e.g.:
@@ -21388,15 +21947,9 @@ new Ext.Panel({
 }).show();
 </code></pre>
      */
-    /**
-     * @cfg {String} tabTip
-     * A string to be used as innerHTML (html tags are accepted) to show in a tooltip when mousing over
-     * the tab of a Ext.Panel which is an item of a {@link Ext.TabPanel}. {@link Ext.QuickTips}.init()
-     * must be called in order for the tips to render.
-     */
     /**
      * @cfg {Boolean} disabled
-     * Render this panel disabled (default is <tt>false</tt>). An important note when using the disabled
+     * Render this panel disabled (default is <code>false</code>). An important note when using the disabled
      * config on panels is that IE will often fail to initialize the disabled mask element correectly if
      * the panel's layout has not yet completed by the time the Panel is disabled during the render process.
      * If you experience this issue, you may need to instead use the {@link #afterlayout} event to initialize
@@ -21417,10 +21970,10 @@ new Ext.Panel({
      */
     /**
      * @cfg {Boolean} autoHeight
-     * <tt>true</tt> to use height:'auto', <tt>false</tt> to use fixed height (defaults to <tt>false</tt>).
-     * <b>Note</b>: Setting <tt>autoHeight:true</tt> means that the browser will manage the panel's height
+     * <code>true</code> to use height:'auto', <code>false</code> to use fixed height (defaults to <code>false</code>).
+     * <b>Note</b>: Setting <code>autoHeight: true</code> means that the browser will manage the panel's height
      * based on its contents, and that Ext will not manage it at all. If the panel is within a layout that
-     * manages dimensions (<tt>fit</tt>, <tt>border</tt>, etc.) then setting <tt>autoHeight:true</tt>
+     * manages dimensions (<code>fit</code>, <code>border</code>, etc.) then setting <code>autoHeight: true</code>
      * can cause issues with scrolling and will not generally work as expected since the panel will take
      * on the height of its contents rather than the height required by the Ext layout.
      */
@@ -21428,64 +21981,64 @@ new Ext.Panel({
 
     /**
      * @cfg {String} baseCls
-     * The base CSS class to apply to this panel's element (defaults to <tt>'x-panel'</tt>).
-     * <p>Another option available by default is to specify <tt>'x-plain'</tt> which strips all styling
+     * The base CSS class to apply to this panel's element (defaults to <code>'x-panel'</code>).
+     * <p>Another option available by default is to specify <code>'x-plain'</code> which strips all styling
      * except for required attributes for Ext layouts to function (e.g. overflow:hidden).
-     * See <tt>{@link #unstyled}</tt> also.</p>
+     * See <code>{@link #unstyled}</code> also.</p>
      */
     baseCls : 'x-panel',
     /**
      * @cfg {String} collapsedCls
      * A CSS class to add to the panel's element after it has been collapsed (defaults to
-     * <tt>'x-panel-collapsed'</tt>).
+     * <code>'x-panel-collapsed'</code>).
      */
     collapsedCls : 'x-panel-collapsed',
     /**
      * @cfg {Boolean} maskDisabled
-     * <tt>true</tt> to mask the panel when it is {@link #disabled}, <tt>false</tt> to not mask it (defaults
-     * to <tt>true</tt>).  Either way, the panel will always tell its contained elements to disable themselves
+     * <code>true</code> to mask the panel when it is {@link #disabled}, <code>false</code> to not mask it (defaults
+     * to <code>true</code>).  Either way, the panel will always tell its contained elements to disable themselves
      * when it is disabled, but masking the panel can provide an additional visual cue that the panel is
      * disabled.
      */
     maskDisabled : true,
     /**
      * @cfg {Boolean} animCollapse
-     * <tt>true</tt> to animate the transition when the panel is collapsed, <tt>false</tt> to skip the
-     * animation (defaults to <tt>true</tt> if the {@link Ext.Fx} class is available, otherwise <tt>false</tt>).
+     * <code>true</code> to animate the transition when the panel is collapsed, <code>false</code> to skip the
+     * animation (defaults to <code>true</code> if the {@link Ext.Fx} class is available, otherwise <code>false</code>).
      */
     animCollapse : Ext.enableFx,
     /**
      * @cfg {Boolean} headerAsText
-     * <tt>true</tt> to display the panel <tt>{@link #title}</tt> in the <tt>{@link #header}</tt>,
-     * <tt>false</tt> to hide it (defaults to <tt>true</tt>).
+     * <code>true</code> to display the panel <code>{@link #title}</code> in the <code>{@link #header}</code>,
+     * <code>false</code> to hide it (defaults to <code>true</code>).
      */
     headerAsText : true,
     /**
      * @cfg {String} buttonAlign
-     * The alignment of any {@link #buttons} added to this panel.  Valid values are <tt>'right'</tt>,
-     * <tt>'left'</tt> and <tt>'center'</tt> (defaults to <tt>'right'</tt>).
+     * The alignment of any {@link #buttons} added to this panel.  Valid values are <code>'right'</code>,
+     * <code>'left'</code> and <code>'center'</code> (defaults to <code>'right'</code>).
      */
     buttonAlign : 'right',
     /**
      * @cfg {Boolean} collapsed
-     * <tt>true</tt> to render the panel collapsed, <tt>false</tt> to render it expanded (defaults to
-     * <tt>false</tt>).
+     * <code>true</code> to render the panel collapsed, <code>false</code> to render it expanded (defaults to
+     * <code>false</code>).
      */
     collapsed : false,
     /**
      * @cfg {Boolean} collapseFirst
-     * <tt>true</tt> to make sure the collapse/expand toggle button always renders first (to the left of)
-     * any other tools in the panel's title bar, <tt>false</tt> to render it last (defaults to <tt>true</tt>).
+     * <code>true</code> to make sure the collapse/expand toggle button always renders first (to the left of)
+     * any other tools in the panel's title bar, <code>false</code> to render it last (defaults to <code>true</code>).
      */
     collapseFirst : true,
     /**
      * @cfg {Number} minButtonWidth
-     * Minimum width in pixels of all {@link #buttons} in this panel (defaults to <tt>75</tt>)
+     * Minimum width in pixels of all {@link #buttons} in this panel (defaults to <code>75</code>)
      */
     minButtonWidth : 75,
     /**
      * @cfg {Boolean} unstyled
-     * Overrides the <tt>{@link #baseCls}</tt> setting to <tt>{@link #baseCls} = 'x-plain'</tt> which renders
+     * Overrides the <code>{@link #baseCls}</code> setting to <code>{@link #baseCls} = 'x-plain'</code> which renders
      * the panel unstyled except for required attributes for Ext layouts to function (e.g. overflow:hidden).
      */
     /**
@@ -21495,23 +22048,28 @@ new Ext.Panel({
      * make sure a structural element is rendered even if not specified at config time (for example, you may want
      * to add a button or toolbar dynamically after the panel has been rendered).  Adding those elements to this
      * list will allocate the required placeholders in the panel when it is rendered.  Valid values are<div class="mdetail-params"><ul>
-     * <li><tt>header</tt></li>
-     * <li><tt>tbar</tt> (top bar)</li>
-     * <li><tt>body</tt></li>
-     * <li><tt>bbar</tt> (bottom bar)</li>
-     * <li><tt>footer</tt></li>
+     * <li><code>header</code></li>
+     * <li><code>tbar</code> (top bar)</li>
+     * <li><code>body</code></li>
+     * <li><code>bbar</code> (bottom bar)</li>
+     * <li><code>footer</code></li>
      * </ul></div>
-     * Defaults to '<tt>body</tt>'.
+     * Defaults to '<code>body</code>'.
      */
     elements : 'body',
     /**
      * @cfg {Boolean} preventBodyReset
-     * Defaults to <tt>false</tt>.  When set to <tt>true</tt>, an extra css class <tt>'x-panel-normal'</tt>
+     * Defaults to <code>false</code>.  When set to <code>true</code>, an extra css class <code>'x-panel-normal'</code>
      * will be added to the panel's element, effectively applying css styles suggested by the W3C
      * (see http://www.w3.org/TR/CSS21/sample.html) to the Panel's <b>body</b> element (not the header,
      * footer, etc.).
      */
     preventBodyReset : false,
+    
+    /** @cfg {String} resizeEvent
+     * The event to listen to for resizing in layouts. Defaults to <tt>'bodyresize'</tt>.
+     */
+    resizeEvent: 'bodyresize',
 
     // protected - these could be used to customize the behavior of the window,
     // but changing them would not be useful without further mofifications and
@@ -21658,21 +22216,21 @@ new Ext.Panel({
             this.elements += ',footer';
             var btns = this.buttons;
             /**
-             * This Panel's Array of buttons as created from the <tt>{@link #buttons}</tt>
+             * This Panel's Array of buttons as created from the <code>{@link #buttons}</code>
              * config property. Read only.
              * @type Array
              * @property buttons
              */
             this.buttons = [];
-            for(var i = 0, len = btns.length; i < len; i++) {
-                if(btns[i].render){ // button instance
-                    this.buttons.push(btns[i]);
-                }else if(btns[i].xtype){
-                    this.buttons.push(Ext.create(btns[i], 'button'));
+            Ext.each(btns, function(btn){
+                if(btn.render){ // button instance
+                    this.buttons.push(btn);
+                }else if(btn.xtype){
+                    this.buttons.push(Ext.create(btn, 'button'));
                 }else{
-                    this.addButton(btns[i]);
+                    this.addButton(btn);
                 }
-            }
+            }, this);
         }
         if(this.fbar){
             this.elements += ',footer';
@@ -21713,7 +22271,25 @@ new Ext.Panel({
 
         var el = this.el,
             d = el.dom,
-            bw;
+            bw,
+            ts;
+            
+            
+        if(this.collapsible && !this.hideCollapseTool){
+            this.tools = this.tools ? this.tools.slice(0) : [];
+            this.tools[this.collapseFirst?'unshift':'push']({
+                id: 'toggle',
+                handler : this.toggleCollapse,
+                scope: this
+            });   
+        }
+        
+        if(this.tools){
+            ts = this.tools;
+            this.elements += (this.header !== false) ? ',header' : '';
+        }
+        this.tools = {};
+            
         el.addClass(this.baseCls);
         if(d.firstChild){ // existing markup
             this.header = el.down('.'+this.headerCls);
@@ -21760,6 +22336,13 @@ new Ext.Panel({
             if(!this.footer){
                 this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
             }
+            /*
+             * Store a reference to this element so:
+             * a) We aren't looking it up all the time
+             * b) The last element is reported incorrectly when using a loadmask
+             */
+            this.ft = Ext.get(this.bwrap.dom.lastChild);
+            this.mc = Ext.get(this.bwrap.dom.firstChild.firstChild.firstChild);
         }else{
             this.createElement('header', d);
             this.createElement('bwrap', d);
@@ -21779,7 +22362,7 @@ new Ext.Panel({
             }
         }
 
-        if(this.padding !== undefined) {
+        if(Ext.isDefined(this.padding)){
             this.body.setStyle('padding', this.body.addUnits(this.padding));
         }
 
@@ -21824,26 +22407,12 @@ new Ext.Panel({
             this.makeFloating(this.floating);
         }
 
-        if(this.collapsible){
-            this.tools = this.tools ? this.tools.slice(0) : [];
-            if(!this.hideCollapseTool){
-                this.tools[this.collapseFirst?'unshift':'push']({
-                    id: 'toggle',
-                    handler : this.toggleCollapse,
-                    scope: this
-                });
-            }
-            if(this.titleCollapse && this.header){
-                this.mon(this.header, 'click', this.toggleCollapse, this);
-                this.header.setStyle('cursor', 'pointer');
-            }
+        if(this.collapsible && this.titleCollapse && this.header){
+            this.mon(this.header, 'click', this.toggleCollapse, this);
+            this.header.setStyle('cursor', 'pointer');
         }
-        if(this.tools){
-            var ts = this.tools;
-            this.tools = {};
+        if(ts){
             this.addTool.apply(this, ts);
-        }else{
-            this.tools = {};
         }
 
         if(this.buttons && this.buttons.length > 0){
@@ -21890,13 +22459,6 @@ new Ext.Panel({
             this.bottomToolbar.render(this.bbar);
             this.toolbars.push(this.bottomToolbar);
         }
-        Ext.each(this.toolbars, function(tb){
-            tb.on({
-                scope: this,
-                afterlayout: this.syncHeight,
-                remove: this.syncHeight
-            });
-        }, this);
     },
 
     /**
@@ -21912,12 +22474,12 @@ new Ext.Panel({
                 this.header.addClass('x-panel-icon');
                 this.header.replaceClass(old, this.iconCls);
             }else{
-                var hd = this.header.dom;
-                var img = hd.firstChild && String(hd.firstChild.tagName).toLowerCase() == 'img' ? hd.firstChild : null;
+                var hd = this.header,
+                    img = hd.child('img.x-panel-inline-icon');
                 if(img){
                     Ext.fly(img).replaceClass(old, this.iconCls);
                 }else{
-                    Ext.DomHelper.insertBefore(hd.firstChild, {
+                    Ext.DomHelper.insertBefore(hd.dom.firstChild, {
                         tag:'img', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
                     });
                  }
@@ -21931,7 +22493,7 @@ new Ext.Panel({
         this.floating = true;
         this.el = new Ext.Layer(
             Ext.isObject(cfg) ? cfg : {
-                shadow: this.shadow !== undefined ? this.shadow : 'sides',
+                shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides',
                 shadowOffset: this.shadowOffset,
                 constrain:false,
                 shim: this.shim === false ? false : undefined
@@ -21940,7 +22502,7 @@ new Ext.Panel({
     },
 
     /**
-     * Returns the {@link Ext.Toolbar toolbar} from the top (<tt>{@link #tbar}</tt>) section of the panel.
+     * Returns the {@link Ext.Toolbar toolbar} from the top (<code>{@link #tbar}</code>) section of the panel.
      * @return {Ext.Toolbar} The toolbar
      */
     getTopToolbar : function(){
@@ -21948,7 +22510,7 @@ new Ext.Panel({
     },
 
     /**
-     * Returns the {@link Ext.Toolbar toolbar} from the bottom (<tt>{@link #bbar}</tt>) section of the panel.
+     * Returns the {@link Ext.Toolbar toolbar} from the bottom (<code>{@link #bbar}</code>) section of the panel.
      * @return {Ext.Toolbar} The toolbar
      */
     getBottomToolbar : function(){
@@ -21971,7 +22533,7 @@ new Ext.Panel({
             minWidth: this.minButtonWidth,
             hideParent:true
         };
-        if(typeof config == "string"){
+        if(Ext.isString(config)){
             bc.text = config;
         }else{
             Ext.apply(bc, config);
@@ -21986,7 +22548,17 @@ new Ext.Panel({
 
     // private
     addTool : function(){
-        if(!this[this.toolTarget]) { // no where to render tools!
+        if(!this.rendered){
+            if(!this.tools){
+                this.tools = [];
+            }
+            Ext.each(arguments, function(arg){
+                this.tools.push(arg)
+            }, this);
+            return;
+        }
+         // nowhere to render tools!
+        if(!this[this.toolTarget]){
             return;
         }
         if(!this.toolTemplate){
@@ -22026,35 +22598,31 @@ new Ext.Panel({
         }
     },
 
-    onLayout : function(){
-        if(this.toolbars.length > 0){
-            this.duringLayout = true;
+    onLayout : function(shallow, force){
+        if(this.hasLayout && this.toolbars.length > 0){
             Ext.each(this.toolbars, function(tb){
-                tb.doLayout();
+                tb.doLayout(undefined, force);
             });
-            delete this.duringLayout;
             this.syncHeight();
         }
     },
 
     syncHeight : function(){
-        if(!(this.autoHeight || this.duringLayout)){
-            var last = this.lastSize;
-            if(last && !Ext.isEmpty(last.height)){
-                var old = last.height, h = this.el.getHeight();
-                if(old != 'auto' && old != h){
-                    var bd = this.body, bdh = bd.getHeight();
-                    h = Math.max(bdh + old - h, 0);
-                    if(bdh > 0 && bdh != h){
-                        bd.setHeight(h);
-                        if(Ext.isIE && h <= 0){
-                            return;
-                        }
-                        var sz = bd.getSize();
-                        this.fireEvent('bodyresize', sz.width, sz.height);
-                    }
-                }
-            }
+        var h = this.toolbarHeight,
+                bd = this.body,
+                lsh = this.lastSize.height;
+                
+        if(this.autoHeight || !Ext.isDefined(lsh) || lsh == 'auto'){
+            return;
+        }
+            
+           
+        if(h != this.getToolbarHeight()){
+            h = Math.max(0, this.adjustBodyHeight(lsh - this.getFrameHeight()));
+            bd.setHeight(h);
+            sz = bd.getSize();
+            this.toolbarHeight = this.getToolbarHeight();
+            this.onBodyResize(sz.width, sz.height);
         }
     },
 
@@ -22141,6 +22709,19 @@ new Ext.Panel({
         if(this.draggable){
             this.initDraggable();
         }
+        if(this.toolbars.length > 0){
+            Ext.each(this.toolbars, function(tb){
+                tb.doLayout();
+                tb.on({
+                    scope: this,
+                    afterlayout: this.syncHeight,
+                    remove: this.syncHeight
+                });
+            }, this);
+            if(!this.ownerCt){
+                this.syncHeight();
+            }
+        }
     },
 
     // private
@@ -22153,21 +22734,25 @@ new Ext.Panel({
          * @type Ext.dd.DragSource.
          * @property dd
          */
-        this.dd = new Ext.Panel.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
+        this.dd = new Ext.Panel.DD(this, Ext.isBoolean(this.draggable) ? null : this.draggable);
     },
 
     // private
-    beforeEffect : function(){
+    beforeEffect : function(anim){
         if(this.floating){
             this.el.beforeAction();
         }
-        this.el.addClass('x-panel-animated');
+        if(anim !== false){
+            this.el.addClass('x-panel-animated');
+        }
     },
 
     // private
-    afterEffect : function(){
+    afterEffect : function(anim){
         this.syncShadow();
-        this.el.removeClass('x-panel-animated');
+        if(anim !== false){
+            this.el.removeClass('x-panel-animated');
+        }
     },
 
     // private - wraps up an animation param with internal callbacks
@@ -22202,7 +22787,7 @@ new Ext.Panel({
             return;
         }
         var doAnim = animate === true || (animate !== false && this.animCollapse);
-        this.beforeEffect();
+        this.beforeEffect(doAnim);
         this.onCollapse(doAnim, animate);
         return this;
     },
@@ -22215,15 +22800,15 @@ new Ext.Panel({
                         this.collapseDefaults));
         }else{
             this[this.collapseEl].hide();
-            this.afterCollapse();
+            this.afterCollapse(false);
         }
     },
 
     // private
-    afterCollapse : function(){
+    afterCollapse : function(anim){
         this.collapsed = true;
         this.el.addClass(this.collapsedCls);
-        this.afterEffect();
+        this.afterEffect(anim);
         this.fireEvent('collapse', this);
     },
 
@@ -22240,7 +22825,7 @@ new Ext.Panel({
         }
         var doAnim = animate === true || (animate !== false && this.animCollapse);
         this.el.removeClass(this.collapsedCls);
-        this.beforeEffect();
+        this.beforeEffect(doAnim);
         this.onExpand(doAnim, animate);
         return this;
     },
@@ -22253,15 +22838,15 @@ new Ext.Panel({
                         this.expandDefaults));
         }else{
             this[this.collapseEl].show();
-            this.afterExpand();
+            this.afterExpand(false);
         }
     },
 
     // private
-    afterExpand : function(){
+    afterExpand : function(anim){
         this.collapsed = false;
-        this.afterEffect();
-        if(this.deferLayout !== undefined){
+        this.afterEffect(anim);
+        if(Ext.isDefined(this.deferLayout)){
             this.doLayout(true);
         }
         this.fireEvent('expand', this);
@@ -22296,9 +22881,9 @@ new Ext.Panel({
 
     // private
     onResize : function(w, h){
-        if(w !== undefined || h !== undefined){
+        if(Ext.isDefined(w) || Ext.isDefined(h)){
             if(!this.collapsed){
-                if(typeof w == 'number'){
+                if(Ext.isNumber(w)){
                     w = this.adjustBodyWidth(w - this.getFrameWidth());
                     if(this.tbar){
                         this.tbar.setWidth(w);
@@ -22341,7 +22926,7 @@ new Ext.Panel({
                     this.body.setWidth(w);
                 }
 
-                if(typeof h == 'number'){
+                if(Ext.isNumber(h)){
                     h = Math.max(0, this.adjustBodyHeight(h - this.getFrameHeight()));
                     this.body.setHeight(h);
                 }else if(h == 'auto'){
@@ -22362,10 +22947,26 @@ new Ext.Panel({
                     }, this, {single:true});
                 }
             }
-            this.fireEvent('bodyresize', this, w, h);
+            this.onBodyResize(w, h);
         }
         this.syncShadow();
     },
+    
+    // private
+    onBodyResize: function(w, h){
+        this.fireEvent('bodyresize', this, w, h);
+    },
+    
+    // private
+    getToolbarHeight: function(){
+        var h = 0;
+        if(this.rendered){
+            Ext.each(this.toolbars, function(tb){
+                h += tb.getHeight();
+            }, this);
+        }
+        return h;
+    },
 
     // private
     adjustBodyHeight : function(h){
@@ -22388,13 +22989,12 @@ new Ext.Panel({
      * @return {Number} The frame width
      */
     getFrameWidth : function(){
-        var w = this.el.getFrameWidth('lr')+this.bwrap.getFrameWidth('lr');
+        var w = this.el.getFrameWidth('lr') + this.bwrap.getFrameWidth('lr');
 
         if(this.frame){
             var l = this.bwrap.dom.firstChild;
             w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r'));
-            var mc = this.bwrap.dom.firstChild.firstChild.firstChild;
-            w += Ext.fly(mc).getFrameWidth('lr');
+            w += this.mc.getFrameWidth('lr');
         }
         return w;
     },
@@ -22405,16 +23005,12 @@ new Ext.Panel({
      * @return {Number} The frame height
      */
     getFrameHeight : function(){
-        var h  = this.el.getFrameWidth('tb')+this.bwrap.getFrameWidth('tb');
+        var h  = this.el.getFrameWidth('tb') + this.bwrap.getFrameWidth('tb');
         h += (this.tbar ? this.tbar.getHeight() : 0) +
              (this.bbar ? this.bbar.getHeight() : 0);
 
         if(this.frame){
-            var hd = this.el.dom.firstChild;
-            var ft = this.bwrap.dom.lastChild;
-            h += (hd.offsetHeight + ft.offsetHeight);
-            var mc = this.bwrap.dom.firstChild.firstChild.firstChild;
-            h += Ext.fly(mc).getFrameWidth('tb');
+            h += this.el.dom.firstChild.offsetHeight + this.ft.dom.offsetHeight + this.mc.getFrameWidth('tb');
         }else{
             h += (this.header ? this.header.getHeight() : 0) +
                 (this.footer ? this.footer.getHeight() : 0);
@@ -22455,8 +23051,8 @@ new Ext.Panel({
     /**
      * <p>Sets the title text for the panel and optionally the {@link #iconCls icon class}.</p>
      * <p>In order to be able to set the title, a header element must have been created
-     * for the Panel. This is triggered either by configuring the Panel with a non-blank <tt>{@link #title}</tt>,
-     * or configuring it with <tt><b>{@link #header}: true</b></tt>.</p>
+     * for the Panel. This is triggered either by configuring the Panel with a non-blank <code>{@link #title}</code>,
+     * or configuring it with <code><b>{@link #header}: true</b></code>.</p>
      * @param {String} title The title text to set
      * @param {String} iconCls (optional) {@link #iconCls iconCls} A user-defined CSS class that provides the icon image for this panel
      */
@@ -22485,13 +23081,13 @@ new Ext.Panel({
      * @param {Object/String/Function} config A config object containing any of the following options:
 <pre><code>
 panel.load({
-    url: "your-url.php",
-    params: {param1: "foo", param2: "bar"}, // or a URL encoded string
+    url: 'your-url.php',
+    params: {param1: 'foo', param2: 'bar'}, // or a URL encoded string
     callback: yourFunction,
     scope: yourObject, // optional scope for the callback
     discardUrl: false,
     nocache: false,
-    text: "Loading...",
+    text: 'Loading...',
     timeout: 30,
     scripts: false
 });
@@ -22516,6 +23112,8 @@ panel.load({
             }
         }
         Ext.Element.uncache(
+            this.ft,
+            this.mc,
             this.header,
             this.tbar,
             this.bbar,
@@ -22533,7 +23131,11 @@ panel.load({
                 Ext.destroy(this.buttons[b]);
             }
         }
-        Ext.destroy(this.toolbars);
+        if(this.rendered){
+            Ext.destroy(this.toolbars);
+        }else{
+            Ext.destroy(this.topToolbar, this.bottomToolbar);
+        }
         Ext.Panel.superclass.beforeDestroy.call(this);
     },
 
@@ -22626,8 +23228,8 @@ Ext.extend(Ext.Editor, Ext.Component, {
      */
     /**
      * @cfg {Boolean/String} autoSize
-     * True for the editor to automatically adopt the size of the element being edited, "width" to adopt the width only,
-     * or "height" to adopt the height only (defaults to false)
+     * True for the editor to automatically adopt the size of the underlying field, "width" to adopt the width only,
+     * or "height" to adopt the height only, "none" to always use the field dimensions. (defaults to false)
      */
     /**
      * @cfg {Boolean} revertInvalid
@@ -22668,13 +23270,13 @@ Ext.extend(Ext.Editor, Ext.Component, {
      */
     swallowKeys : true,
     /**
-     * @cfg {Boolean} completeOnEnter True to complete the edit when the enter key is pressed (defaults to false)
+     * @cfg {Boolean} completeOnEnter True to complete the edit when the enter key is pressed. Defaults to <tt>true</tt>.
      */
-    completeOnEnter : false,
+    completeOnEnter : true,
     /**
-     * @cfg {Boolean} cancelOnEsc True to cancel the edit when the escape key is pressed (defaults to false)
+     * @cfg {Boolean} cancelOnEsc True to cancel the edit when the escape key is pressed. Defaults to <tt>true</tt>.
      */
-    cancelOnEsc : false,
+    cancelOnEsc : true,
     /**
      * @cfg {Boolean} updateEl True to update the innerHTML of the bound element when the update completes (defaults to false)
      */
@@ -22756,35 +23358,41 @@ Ext.extend(Ext.Editor, Ext.Component, {
             this.field.msgTarget = 'qtip';
         }
         this.field.inEditor = true;
-        this.field.render(this.el);
-        if(Ext.isGecko){
-            this.field.el.dom.setAttribute('autocomplete', 'off');
+        this.mon(this.field, {
+            scope: this,
+            blur: this.onBlur,
+            specialkey: this.onSpecialKey
+        });
+        if(this.field.grow){
+            this.mon(this.field, "autosize", this.el.sync,  this.el, {delay:1});
         }
-        this.mon(this.field, "specialkey", this.onSpecialKey, this);
+        this.field.render(this.el).show();
+        this.field.getEl().dom.name = '';
         if(this.swallowKeys){
-            this.field.el.swallowEvent(['keydown','keypress']);
-        }
-        this.field.show();
-        this.mon(this.field, "blur", this.onBlur, this);
-        if(this.field.grow){
-               this.mon(this.field, "autosize", this.el.sync,  this.el, {delay:1});
+            this.field.el.swallowEvent([
+                'keypress', // *** Opera
+                'keydown'   // *** all other browsers
+            ]);
         }
     },
 
     // private
     onSpecialKey : function(field, e){
-        var key = e.getKey();
-        if(this.completeOnEnter && key == e.ENTER){
+        var key = e.getKey(),
+            complete = this.completeOnEnter && key == e.ENTER,
+            cancel = this.cancelOnEsc && key == e.ESC;
+        if(complete || cancel){
             e.stopEvent();
-            this.completeEdit();
-        }else if(this.cancelOnEsc && key == e.ESC){
-            this.cancelEdit();
-        }else{
-            this.fireEvent('specialkey', field, e);
-        }
-        if(this.field.triggerBlur && (key == e.ENTER || key == e.ESC || key == e.TAB)){
-            this.field.triggerBlur();
+            if(complete){
+                this.completeEdit();
+            }else{
+                this.cancelEdit();
+            }
+            if(field.triggerBlur){
+                field.triggerBlur(); 
+            }
         }
+        this.fireEvent('specialkey', field, e);
     },
 
     /**
@@ -22802,30 +23410,34 @@ Ext.extend(Ext.Editor, Ext.Component, {
         if(!this.rendered){
             this.render(this.parentEl || document.body);
         }
-        if(this.fireEvent("beforestartedit", this, this.boundEl, v) === false){
-            return;
+        if(this.fireEvent("beforestartedit", this, this.boundEl, v) !== false){
+            this.startValue = v;
+            this.field.setValue(v);
+            this.doAutoSize();
+            this.el.alignTo(this.boundEl, this.alignment);
+            this.editing = true;
+            this.show();
         }
-        this.startValue = v;
-        this.field.setValue(v);
-        this.doAutoSize();
-        this.el.alignTo(this.boundEl, this.alignment);
-        this.editing = true;
-        this.show();
     },
 
     // private
     doAutoSize : function(){
         if(this.autoSize){
-            var sz = this.boundEl.getSize();
+            var sz = this.boundEl.getSize(),
+                fs = this.field.getSize();
+
             switch(this.autoSize){
                 case "width":
-                    this.setSize(sz.width,  "");
-                break;
+                    this.setSize(sz.width, fs.height);
+                    break;
                 case "height":
-                    this.setSize("",  sz.height);
-                break;
+                    this.setSize(fs.width, sz.height);
+                    break;
+                case "none":
+                    this.setSize(fs.width, fs.height);
+                    break;
                 default:
-                    this.setSize(sz.width,  sz.height);
+                    this.setSize(sz.width, sz.height);
             }
         }
     },
@@ -22889,22 +23501,10 @@ Ext.extend(Ext.Editor, Ext.Component, {
         if(this.hideEl !== false){
             this.boundEl.hide();
         }
-        this.field.show();
-        if(Ext.isIE && !this.fixIEFocus){ // IE has problems with focusing the first time
-            this.fixIEFocus = true;
-            this.deferredFocus.defer(50, this);
-        }else{
-            this.field.focus();
-        }
+        this.field.show().focus(false, true);
         this.fireEvent("startedit", this.boundEl, this.startValue);
     },
 
-    deferredFocus : function(){
-        if(this.editing){
-            this.field.focus();
-        }
-    },
-
     /**
      * Cancels the editing process and hides the editor without persisting any changes.  The field value will be
      * reverted to the original starting value.
@@ -23003,7 +23603,7 @@ Ext.ColorPalette = function(config){
     );
 
     if(this.handler){
-        this.on("select", this.handler, this.scope, true);
+        this.on('select', this.handler, this.scope, true);
     }
 };
 Ext.extend(Ext.ColorPalette, Ext.Component, {
@@ -23012,18 +23612,18 @@ Ext.extend(Ext.ColorPalette, Ext.Component, {
         */
     /**
      * @cfg {String} itemCls
-     * The CSS class to apply to the containing element (defaults to "x-color-palette")
+     * The CSS class to apply to the containing element (defaults to 'x-color-palette')
      */
-    itemCls : "x-color-palette",
+    itemCls : 'x-color-palette',
     /**
      * @cfg {String} value
      * The initial color to highlight (should be a valid 6-digit color hex code without the # symbol).  Note that
      * the hex codes are case-sensitive.
      */
     value : null,
-    clickEvent:'click',
+    clickEvent :'click',
     // private
-    ctype: "Ext.ColorPalette",
+    ctype : 'Ext.ColorPalette',
 
     /**
      * @cfg {Boolean} allowReselect If set to true then reselecting a color that is already selected fires the {@link #select} event
@@ -23038,30 +23638,44 @@ Ext.extend(Ext.ColorPalette, Ext.Component, {
      * <p>You can override individual colors if needed:</p>
      * <pre><code>
 var cp = new Ext.ColorPalette();
-cp.colors[0] = "FF0000";  // change the first box to red
+cp.colors[0] = 'FF0000';  // change the first box to red
 </code></pre>
 
 Or you can provide a custom array of your own for complete control:
 <pre><code>
 var cp = new Ext.ColorPalette();
-cp.colors = ["000000", "993300", "333300"];
+cp.colors = ['000000', '993300', '333300'];
 </code></pre>
      * @type Array
      */
     colors : [
-        "000000", "993300", "333300", "003300", "003366", "000080", "333399", "333333",
-        "800000", "FF6600", "808000", "008000", "008080", "0000FF", "666699", "808080",
-        "FF0000", "FF9900", "99CC00", "339966", "33CCCC", "3366FF", "800080", "969696",
-        "FF00FF", "FFCC00", "FFFF00", "00FF00", "00FFFF", "00CCFF", "993366", "C0C0C0",
-        "FF99CC", "FFCC99", "FFFF99", "CCFFCC", "CCFFFF", "99CCFF", "CC99FF", "FFFFFF"
+        '000000', '993300', '333300', '003300', '003366', '000080', '333399', '333333',
+        '800000', 'FF6600', '808000', '008000', '008080', '0000FF', '666699', '808080',
+        'FF0000', 'FF9900', '99CC00', '339966', '33CCCC', '3366FF', '800080', '969696',
+        'FF00FF', 'FFCC00', 'FFFF00', '00FF00', '00FFFF', '00CCFF', '993366', 'C0C0C0',
+        'FF99CC', 'FFCC99', 'FFFF99', 'CCFFCC', 'CCFFFF', '99CCFF', 'CC99FF', 'FFFFFF'
     ],
 
+    /**
+     * @cfg {Function} handler
+     * Optional. A function that will handle the select event of this palette.
+     * The handler is passed the following parameters:<div class="mdetail-params"><ul>
+     * <li><code>palette</code> : ColorPalette<div class="sub-desc">The {@link #palette Ext.ColorPalette}.</div></li>
+     * <li><code>color</code> : String<div class="sub-desc">The 6-digit color hex code (without the # symbol).</div></li>
+     * </ul></div>
+     */
+    /**
+     * @cfg {Object} scope
+     * The scope (<tt><b>this</b></tt> reference) in which the <code>{@link #handler}</code>
+     * function will be called.  Defaults to this ColorPalette instance.
+     */
+
     // private
     onRender : function(container, position){
         var t = this.tpl || new Ext.XTemplate(
             '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on">&#160;</span></em></a></tpl>'
         );
-        var el = document.createElement("div");
+        var el = document.createElement('div');
         el.id = this.getId();
         el.className = this.itemCls;
         t.overwrite(el, this.colors);
@@ -23097,15 +23711,15 @@ cp.colors = ["000000", "993300", "333300"];
      * @param {String} color A valid 6-digit color hex code (# will be stripped if included)
      */
     select : function(color){
-        color = color.replace("#", "");
+        color = color.replace('#', '');
         if(color != this.value || this.allowReselect){
             var el = this.el;
             if(this.value){
-                el.child("a.color-"+this.value).removeClass("x-color-palette-sel");
+                el.child('a.color-'+this.value).removeClass('x-color-palette-sel');
             }
-            el.child("a.color-"+color).addClass("x-color-palette-sel");
+            el.child('a.color-'+color).addClass('x-color-palette-sel');
             this.value = color;
-            this.fireEvent("select", this, color);
+            this.fireEvent('select', this, color);
         }
     }
 
@@ -23113,7 +23727,8 @@ cp.colors = ["000000", "993300", "333300"];
      * @cfg {String} autoEl @hide
      */
 });
-Ext.reg('colorpalette', Ext.ColorPalette);/**\r
+Ext.reg('colorpalette', Ext.ColorPalette);
+/**\r
  * @class Ext.DatePicker\r
  * @extends Ext.Component\r
  * Simple date picker class.\r
@@ -23138,6 +23753,19 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
      * The text to display on the cancel button (defaults to <tt>'Cancel'</tt>)\r
      */\r
     cancelText : 'Cancel',\r
+    /**\r
+     * @cfg {Function} handler\r
+     * Optional. A function that will handle the select event of this picker.\r
+     * The handler is passed the following parameters:<div class="mdetail-params"><ul>\r
+     * <li><code>picker</code> : DatePicker<div class="sub-desc">The Ext.DatePicker.</div></li>\r
+     * <li><code>date</code> : Date<div class="sub-desc">The selected date.</div></li>\r
+     * </ul></div>\r
+     */\r
+    /**\r
+     * @cfg {Object} scope\r
+     * The scope (<tt><b>this</b></tt> reference) in which the <code>{@link #handler}</code>\r
+     * function will be called.  Defaults to this DatePicker instance.\r
+     */ \r
     /**\r
      * @cfg {String} todayTip\r
      * The tooltip to display for the button that selects the current date (defaults to <tt>'{current date} (Spacebar)'</tt>)\r
@@ -23244,7 +23872,7 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
         Ext.DatePicker.superclass.initComponent.call(this);\r
 \r
         this.value = this.value ?\r
-                 this.value.clearTime() : new Date().clearTime();\r
+                 this.value.clearTime(true) : new Date().clearTime();\r
 \r
         this.addEvents(\r
             /**\r
@@ -23329,11 +23957,8 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
      * @param {Date} value The date to set\r
      */\r
     setValue : function(value){\r
-        var old = this.value;\r
         this.value = value.clearTime(true);\r
-        if(this.el){\r
-            this.update(this.value);\r
-        }\r
+        this.update(this.value);\r
     },\r
 \r
     /**\r
@@ -23346,9 +23971,7 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
 \r
     // private\r
     focus : function(){\r
-        if(this.el){\r
-            this.update(this.activeDate);\r
-        }\r
+        this.update(this.activeDate);\r
     },\r
     \r
     // private\r
@@ -23363,7 +23986,7 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
     },\r
     \r
     // private\r
-    onDisable: function(){\r
+    onDisable : function(){\r
         Ext.DatePicker.superclass.onDisable.call(this);   \r
         this.doDisabled(true);\r
         if(Ext.isIE && !Ext.isIE8){\r
@@ -23378,7 +24001,7 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
     },\r
     \r
     // private\r
-    doDisabled: function(disabled){\r
+    doDisabled : function(disabled){\r
         this.keyNav.setDisabled(disabled);\r
         this.prevRepeater.setDisabled(disabled);\r
         this.nextRepeater.setDisabled(disabled);\r
@@ -23717,142 +24340,142 @@ Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
 \r
     // private\r
     update : function(date, forceRefresh){\r
-        var vd = this.activeDate, vis = this.isVisible();\r
-        this.activeDate = date;\r
-        if(!forceRefresh && vd && this.el){\r
-            var t = date.getTime();\r
-            if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){\r
-                this.cells.removeClass('x-date-selected');\r
-                this.cells.each(function(c){\r
-                   if(c.dom.firstChild.dateValue == t){\r
-                       c.addClass('x-date-selected');\r
-                       if(vis){\r
-                           Ext.fly(c.dom.firstChild).focus(50);\r
-                       }\r
-                       return false;\r
-                   }\r
-                });\r
-                return;\r
-            }\r
-        }\r
-        var days = date.getDaysInMonth();\r
-        var firstOfMonth = date.getFirstDateOfMonth();\r
-        var startingPos = firstOfMonth.getDay()-this.startDay;\r
-\r
-        if(startingPos <= this.startDay){\r
-            startingPos += 7;\r
-        }\r
-\r
-        var pm = date.add('mo', -1);\r
-        var prevStart = pm.getDaysInMonth()-startingPos;\r
-\r
-        var cells = this.cells.elements;\r
-        var textEls = this.textNodes;\r
-        days += startingPos;\r
-\r
-        // convert everything to numbers so it's fast\r
-        var day = 86400000;\r
-        var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();\r
-        var today = new Date().clearTime().getTime();\r
-        var sel = date.clearTime().getTime();\r
-        var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;\r
-        var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;\r
-        var ddMatch = this.disabledDatesRE;\r
-        var ddText = this.disabledDatesText;\r
-        var ddays = this.disabledDays ? this.disabledDays.join('') : false;\r
-        var ddaysText = this.disabledDaysText;\r
-        var format = this.format;\r
-\r
-        if(this.showToday){\r
-            var td = new Date().clearTime();\r
-            var disable = (td < min || td > max ||\r
-                (ddMatch && format && ddMatch.test(td.dateFormat(format))) ||\r
-                (ddays && ddays.indexOf(td.getDay()) != -1));\r
-\r
-            if(!this.disabled){\r
-                this.todayBtn.setDisabled(disable);\r
-                this.todayKeyListener[disable ? 'disable' : 'enable']();\r
-            }\r
-        }\r
-\r
-        var setCellClass = function(cal, cell){\r
-            cell.title = '';\r
-            var t = d.getTime();\r
-            cell.firstChild.dateValue = t;\r
-            if(t == today){\r
-                cell.className += ' x-date-today';\r
-                cell.title = cal.todayText;\r
-            }\r
-            if(t == sel){\r
-                cell.className += ' x-date-selected';\r
-                if(vis){\r
-                    Ext.fly(cell.firstChild).focus(50);\r
-                }\r
-            }\r
-            // disabling\r
-            if(t < min) {\r
-                cell.className = ' x-date-disabled';\r
-                cell.title = cal.minText;\r
-                return;\r
-            }\r
-            if(t > max) {\r
-                cell.className = ' x-date-disabled';\r
-                cell.title = cal.maxText;\r
-                return;\r
-            }\r
-            if(ddays){\r
-                if(ddays.indexOf(d.getDay()) != -1){\r
-                    cell.title = ddaysText;\r
-                    cell.className = ' x-date-disabled';\r
-                }\r
-            }\r
-            if(ddMatch && format){\r
-                var fvalue = d.dateFormat(format);\r
-                if(ddMatch.test(fvalue)){\r
-                    cell.title = ddText.replace('%0', fvalue);\r
-                    cell.className = ' x-date-disabled';\r
-                }\r
-            }\r
-        };\r
-\r
-        var i = 0;\r
-        for(; i < startingPos; i++) {\r
-            textEls[i].innerHTML = (++prevStart);\r
-            d.setDate(d.getDate()+1);\r
-            cells[i].className = 'x-date-prevday';\r
-            setCellClass(this, cells[i]);\r
-        }\r
-        for(; i < days; i++){\r
-            var intDay = i - startingPos + 1;\r
-            textEls[i].innerHTML = (intDay);\r
-            d.setDate(d.getDate()+1);\r
-            cells[i].className = 'x-date-active';\r
-            setCellClass(this, cells[i]);\r
-        }\r
-        var extraDays = 0;\r
-        for(; i < 42; i++) {\r
-             textEls[i].innerHTML = (++extraDays);\r
-             d.setDate(d.getDate()+1);\r
-             cells[i].className = 'x-date-nextday';\r
-             setCellClass(this, cells[i]);\r
-        }\r
-\r
-        this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear());\r
-\r
-        if(!this.internalRender){\r
-            var main = this.el.dom.firstChild;\r
-            var w = main.offsetWidth;\r
-            this.el.setWidth(w + this.el.getBorderWidth('lr'));\r
-            Ext.fly(main).setWidth(w);\r
-            this.internalRender = true;\r
-            // opera does not respect the auto grow header center column\r
-            // then, after it gets a width opera refuses to recalculate\r
-            // without a second pass\r
-            if(Ext.isOpera && !this.secondPass){\r
-                main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px';\r
-                this.secondPass = true;\r
-                this.update.defer(10, this, [date]);\r
-            }\r
+        if(this.rendered){\r
+               var vd = this.activeDate, vis = this.isVisible();\r
+               this.activeDate = date;\r
+               if(!forceRefresh && vd && this.el){\r
+                   var t = date.getTime();\r
+                   if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){\r
+                       this.cells.removeClass('x-date-selected');\r
+                       this.cells.each(function(c){\r
+                          if(c.dom.firstChild.dateValue == t){\r
+                              c.addClass('x-date-selected');\r
+                              if(vis){\r
+                                  Ext.fly(c.dom.firstChild).focus(50);\r
+                              }\r
+                              return false;\r
+                          }\r
+                       });\r
+                       return;\r
+                   }\r
+               }\r
+               var days = date.getDaysInMonth(),\r
+                   firstOfMonth = date.getFirstDateOfMonth(),\r
+                   startingPos = firstOfMonth.getDay()-this.startDay;\r
+       \r
+               if(startingPos < 0){\r
+                   startingPos += 7;\r
+               }\r
+               days += startingPos;\r
+       \r
+               var pm = date.add('mo', -1),\r
+                   prevStart = pm.getDaysInMonth()-startingPos,\r
+                   cells = this.cells.elements,\r
+                   textEls = this.textNodes,\r
+                   // convert everything to numbers so it's fast\r
+                   day = 86400000,\r
+                   d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime(),\r
+                   today = new Date().clearTime().getTime(),\r
+                   sel = date.clearTime(true).getTime(),\r
+                   min = this.minDate ? this.minDate.clearTime(true) : Number.NEGATIVE_INFINITY,\r
+                   max = this.maxDate ? this.maxDate.clearTime(true) : Number.POSITIVE_INFINITY,\r
+                   ddMatch = this.disabledDatesRE,\r
+                   ddText = this.disabledDatesText,\r
+                   ddays = this.disabledDays ? this.disabledDays.join('') : false,\r
+                   ddaysText = this.disabledDaysText,\r
+                   format = this.format;\r
+       \r
+               if(this.showToday){\r
+                   var td = new Date().clearTime(),\r
+                       disable = (td < min || td > max ||\r
+                       (ddMatch && format && ddMatch.test(td.dateFormat(format))) ||\r
+                       (ddays && ddays.indexOf(td.getDay()) != -1));\r
+       \r
+                   if(!this.disabled){\r
+                       this.todayBtn.setDisabled(disable);\r
+                       this.todayKeyListener[disable ? 'disable' : 'enable']();\r
+                   }\r
+               }\r
+       \r
+               var setCellClass = function(cal, cell){\r
+                   cell.title = '';\r
+                   var t = d.getTime();\r
+                   cell.firstChild.dateValue = t;\r
+                   if(t == today){\r
+                       cell.className += ' x-date-today';\r
+                       cell.title = cal.todayText;\r
+                   }\r
+                   if(t == sel){\r
+                       cell.className += ' x-date-selected';\r
+                       if(vis){\r
+                           Ext.fly(cell.firstChild).focus(50);\r
+                       }\r
+                   }\r
+                   // disabling\r
+                   if(t < min) {\r
+                       cell.className = ' x-date-disabled';\r
+                       cell.title = cal.minText;\r
+                       return;\r
+                   }\r
+                   if(t > max) {\r
+                       cell.className = ' x-date-disabled';\r
+                       cell.title = cal.maxText;\r
+                       return;\r
+                   }\r
+                   if(ddays){\r
+                       if(ddays.indexOf(d.getDay()) != -1){\r
+                           cell.title = ddaysText;\r
+                           cell.className = ' x-date-disabled';\r
+                       }\r
+                   }\r
+                   if(ddMatch && format){\r
+                       var fvalue = d.dateFormat(format);\r
+                       if(ddMatch.test(fvalue)){\r
+                           cell.title = ddText.replace('%0', fvalue);\r
+                           cell.className = ' x-date-disabled';\r
+                       }\r
+                   }\r
+               };\r
+       \r
+               var i = 0;\r
+               for(; i < startingPos; i++) {\r
+                   textEls[i].innerHTML = (++prevStart);\r
+                   d.setDate(d.getDate()+1);\r
+                   cells[i].className = 'x-date-prevday';\r
+                   setCellClass(this, cells[i]);\r
+               }\r
+               for(; i < days; i++){\r
+                   var intDay = i - startingPos + 1;\r
+                   textEls[i].innerHTML = (intDay);\r
+                   d.setDate(d.getDate()+1);\r
+                   cells[i].className = 'x-date-active';\r
+                   setCellClass(this, cells[i]);\r
+               }\r
+               var extraDays = 0;\r
+               for(; i < 42; i++) {\r
+                    textEls[i].innerHTML = (++extraDays);\r
+                    d.setDate(d.getDate()+1);\r
+                    cells[i].className = 'x-date-nextday';\r
+                    setCellClass(this, cells[i]);\r
+               }\r
+       \r
+               this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear());\r
+       \r
+               if(!this.internalRender){\r
+                   var main = this.el.dom.firstChild,\r
+                       w = main.offsetWidth;\r
+                   this.el.setWidth(w + this.el.getBorderWidth('lr'));\r
+                   Ext.fly(main).setWidth(w);\r
+                   this.internalRender = true;\r
+                   // opera does not respect the auto grow header center column\r
+                   // then, after it gets a width opera refuses to recalculate\r
+                   // without a second pass\r
+                   if(Ext.isOpera && !this.secondPass){\r
+                       main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px';\r
+                       this.secondPass = true;\r
+                       this.update.defer(10, this, [date]);\r
+                   }\r
+               }\r
         }\r
     },\r
 \r
@@ -24606,6 +25229,7 @@ myAction.on('complete', function(){
             this.waitTimer = Ext.TaskMgr.start({\r
                 run: function(i){\r
                     var inc = o.increment || 10;\r
+                    i -= 1;\r
                     this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate);\r
                 },\r
                 interval: o.interval || 1000,\r
@@ -25222,7 +25846,7 @@ Ext.dd.DragDrop.prototype = {
             c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};
         }else{
             var xy = ce.getXY();
-            c = {x : xy[0]+s.left, y: xy[1]+s.top, width: cd.clientWidth, height: cd.clientHeight};
+            c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight};
         }
 
 
@@ -29255,7 +29879,8 @@ Ext.Element.addMethods({
         var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);\r
         return Ext.apply(dd, overrides);\r
     }\r
-});/**
+});
+/**
  * @class Ext.data.Api
  * @extends Object
  * Ext.data.Api is a singleton designed to manage the data API including methods
@@ -29435,10 +30060,86 @@ new Ext.data.HttpProxy({
             for (var verb in this.restActions) {
                 proxy.api[this.actions[verb]].method = this.restActions[verb];
             }
+            // TODO: perhaps move this interceptor elsewhere?  like into DataProxy, perhaps?  Placed here
+            // to satisfy initial 3.0 final release of REST features.
+            proxy.onWrite = proxy.onWrite.createInterceptor(function(action, o, response, rs) {
+                var reader = o.reader;
+                var res = new Ext.data.Response({
+                    action: action,
+                    raw: response
+                });
+
+                switch (response.status) {
+                    case 200:   // standard 200 response, send control back to HttpProxy#onWrite
+                        return true;
+                        break;
+                    case 201:   // entity created but no response returned
+                        //res[reader.meta.successProperty] = true;
+                        res.success = true;
+                        break;
+                    case 204:  // no-content.  Create a fake response.
+                        //res[reader.meta.successProperty] = true;
+                        //res[reader.meta.root] = null;
+                        res.success = true;
+                        res.data = null;
+                        break;
+                    default:
+                        return true;
+                        break;
+                }
+                /*
+                if (res[reader.meta.successProperty] === true) {
+                    this.fireEvent("write", this, action, res[reader.meta.root], res, rs, o.request.arg);
+                } else {
+                    this.fireEvent('exception', this, 'remote', action, o, res, rs);
+                }
+                */
+                if (res.success === true) {
+                    this.fireEvent("write", this, action, res.data, res, rs, o.request.arg);
+                } else {
+                    this.fireEvent('exception', this, 'remote', action, o, res, rs);
+                }
+                o.request.callback.call(o.request.scope, res.data, res, res.success);
+
+                return false;   // <-- false to prevent intercepted function from running.
+            }, proxy);
         }
     };
 })();
 
+/**
+ * Ext.data.Response
+ * Experimental.  Do not use directly.
+ */
+Ext.data.Response = function(params, response) {
+    Ext.apply(this, params, {
+        raw: response
+    });
+};
+Ext.data.Response.prototype = {
+    message : null,
+    success : false,
+    status : null,
+    root : null,
+    raw : null,
+
+    getMessage : function() {
+        return this.message;
+    },
+    getSuccess : function() {
+        return this.success;
+    },
+    getStatus : function() {
+        return this.status
+    },
+    getRoot : function() {
+        return this.root;
+    },
+    getRawResponse : function() {
+        return this.raw;
+    }
+};
+
 /**
  * @class Ext.data.Api.Error
  * @extends Ext.Error
@@ -29459,6 +30160,8 @@ Ext.apply(Ext.data.Api.Error.prototype, {
         'execute': 'Attempted to execute an unknown action.  Valid API actions are defined in Ext.data.Api.actions"'
     }
 });
+
+
 \r
 /**\r
  * @class Ext.data.SortTypes\r
@@ -29560,8 +30263,9 @@ Ext.data.SortTypes = {
  * <code>{@link #data}</code> and <code>{@link #id}</code> properties.</p>
  * <p>Record objects generated by this constructor inherit all the methods of Ext.data.Record listed below.</p>
  * @constructor
- * This constructor should not be used to create Record objects. Instead, use {@link #create} to
- * generate a subclass of Ext.data.Record configured with information about its constituent fields.
+ * <p>This constructor should not be used to create Record objects. Instead, use {@link #create} to
+ * generate a subclass of Ext.data.Record configured with information about its constituent fields.<p>
+ * <p><b>The generated constructor has the same signature as this constructor.</b></p>
  * @param {Object} data (Optional) An object, the properties of which provide values for the new Record's
  * fields. If not specified the <code>{@link Ext.data.Field#defaultValue defaultValue}</code>
  * for each field will be assigned.
@@ -29612,7 +30316,7 @@ myStore.{@link Ext.data.Store#add add}(myNewRecord);
 </code></pre>
  * @method create
  * @return {function} A constructor which is used to create new Records according
- * to the definition. The constructor has the same signature as {@link #Ext.data.Record}.
+ * to the definition. The constructor has the same signature as {@link #Record}.
  * @static
  */
 Ext.data.Record.create = function(o){
@@ -30064,6 +30768,9 @@ var recId = 100; // provide unique id for the record
 var r = new myStore.recordType(defaultData, ++recId); // create new record
 myStore.{@link #insert}(0, r); // insert a new record into the store (also see {@link #add})
  * </code></pre>
+ * <p><u>Writing Data</u></p>
+ * <p>And <b>new in Ext version 3</b>, use the new {@link Ext.data.DataWriter DataWriter} to create an automated, <a href="http://extjs.com/deploy/dev/examples/writer/writer.html">Writable Store</a>
+ * along with <a href="http://extjs.com/deploy/dev/examples/restful/restful.html">RESTful features.</a>
  * @constructor
  * Creates a new Store.
  * @param {Object} config A config object containing the objects needed for the Store to access data,
@@ -30092,7 +30799,7 @@ Ext.data.Store = function(config){
     }
 
     Ext.apply(this, config);
-    
+
     this.paramNames = Ext.applyIf(this.paramNames || {}, this.defaultParamNames);
 
     if(this.url && !this.proxy){
@@ -30110,7 +30817,8 @@ Ext.data.Store = function(config){
             this.recordType = this.reader.recordType;
         }
         if(this.reader.onMetaChange){
-            this.reader.onMetaChange = this.onMetaChange.createDelegate(this);
+            //this.reader.onMetaChange = this.onMetaChange.createDelegate(this);
+            this.reader.onMetaChange = this.reader.onMetaChange.createSequence(this.onMetaChange, this);
         }
         if (this.writer) { // writer passed
             this.writer.meta = this.reader.meta;
@@ -30242,6 +30950,7 @@ var grid = new Ext.grid.EditorGridPanel({
          * @event clear
          * Fires when the data cache has been cleared.
          * @param {Store} this
+         * @param {Record[]} The records that were cleared.
          */
         'clear',
         /**
@@ -30283,7 +30992,7 @@ var grid = new Ext.grid.EditorGridPanel({
         'loadexception',
         /**
          * @event beforewrite
-         * @param {DataProxy} this
+         * @param {Ext.data.Store} store
          * @param {String} action [Ext.data.Api.actions.create|update|destroy]
          * @param {Record/Array[Record]} rs
          * @param {Object} options The loading options that were specified. Edit <code>options.params</code> to add Http parameters to the request.  (see {@link #save} for details)
@@ -30293,9 +31002,8 @@ var grid = new Ext.grid.EditorGridPanel({
         /**
          * @event write
          * Fires if the server returns 200 after an Ext.data.Api.actions CRUD action.
-         * Success or failure of the action is available in the <code>result['successProperty']</code> property.
-         * The server-code might set the <code>successProperty</code> to <tt>false</tt> if a database validation
-         * failed, for example.
+         * Success of the action is determined in the <code>result['successProperty']</code>property (<b>NOTE</b> for RESTful stores,
+         * a simple 20x response is sufficient for the actions "destroy" and "update".  The "create" action should should return 200 along with a database pk).
          * @param {Ext.data.Store} store
          * @param {String} action [Ext.data.Api.actions.create|update|destroy]
          * @param {Object} result The 'data' picked-out out of the response for convenience.
@@ -30314,7 +31022,8 @@ var grid = new Ext.grid.EditorGridPanel({
             scope: this,
             add: this.createRecords,
             remove: this.destroyRecord,
-            update: this.updateRecord
+            update: this.updateRecord,
+            clear: this.onClear
         });
     }
 
@@ -30492,7 +31201,7 @@ sortInfo: {
      * internally be set to <tt>false</tt>.</p>
      */
     restful: false,
-    
+
     /**
      * @cfg {Object} paramNames
      * <p>An object containing properties which specify the names of the paging and
@@ -30512,7 +31221,7 @@ sortInfo: {
      * the parameter names to use in its {@link #load requests}.
      */
     paramNames : undefined,
-    
+
     /**
      * @cfg {Object} defaultParamNames
      * Provides the default values for the {@link #paramNames} property. To globally modify the parameters
@@ -30529,13 +31238,17 @@ sortInfo: {
      * Destroys the store.
      */
     destroy : function(){
-        if(this.storeId){
-            Ext.StoreMgr.unregister(this);
+        if(!this.isDestroyed){
+            if(this.storeId){
+                Ext.StoreMgr.unregister(this);
+            }
+            this.clearData();
+            this.data = null;
+            Ext.destroy(this.proxy);
+            this.reader = this.writer = null;
+            this.purgeListeners();
+            this.isDestroyed = true;
         }
-        this.data = null;
-        Ext.destroy(this.proxy);
-        this.reader = this.writer = null;
-        this.purgeListeners();
     },
 
     /**
@@ -30578,6 +31291,7 @@ sortInfo: {
     remove : function(record){
         var index = this.data.indexOf(record);
         if(index > -1){
+            record.join(null);
             this.data.removeAt(index);
             if(this.pruneModifiedRecords){
                 this.modified.remove(record);
@@ -30601,14 +31315,25 @@ sortInfo: {
      * Remove all Records from the Store and fires the {@link #clear} event.
      */
     removeAll : function(){
-        this.data.clear();
+        var items = [];
+        this.each(function(rec){
+            items.push(rec);
+        });
+        this.clearData();
         if(this.snapshot){
             this.snapshot.clear();
         }
         if(this.pruneModifiedRecords){
             this.modified = [];
         }
-        this.fireEvent('clear', this);
+        this.fireEvent('clear', this, items);
+    },
+
+    // private
+    onClear: function(store, records){
+        Ext.each(records, function(rec, index){
+            this.destroyRecord(this, rec, index);
+        }, this);
     },
 
     /**
@@ -30680,6 +31405,14 @@ sortInfo: {
         this.lastOptions = o;
     },
 
+    // private
+    clearData: function(){
+        this.data.each(function(rec) {
+            rec.join(null);
+        });
+        this.data.clear();
+    },
+
     /**
      * <p>Loads the Record cache from the configured <tt>{@link #proxy}</tt> using the configured <tt>{@link #reader}</tt>.</p>
      * <br><p>Notes:</p><div class="mdetail-params"><ul>
@@ -30811,10 +31544,12 @@ sortInfo: {
         var doRequest = true;
 
         if (action === 'read') {
+            Ext.applyIf(options.params, this.baseParams);
             doRequest = this.fireEvent('beforeload', this, options);
         }
         else {
-            // if Writer is configured as listful, force single-recoord rs to be [{}} instead of {}
+            // if Writer is configured as listful, force single-record rs to be [{}] instead of {}
+            // TODO Move listful rendering into DataWriter where the @cfg is defined.  Should be easy now.
             if (this.writer.listful === true && this.restful !== true) {
                 rs = (Ext.isArray(rs)) ? rs : [rs];
             }
@@ -30831,10 +31566,11 @@ sortInfo: {
             // Send request to proxy.
             var params = Ext.apply({}, options.params, this.baseParams);
             if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
-                params.xaction = action;
+                params.xaction = action;    // <-- really old, probaby unecessary.
             }
-            // Note:  Up until this point we've been dealing with 'action' as a key from Ext.data.Api.actions.  We'll flip it now
-            // and send the value into DataProxy#request, since it's the value which maps to the DataProxy#api
+            // Note:  Up until this point we've been dealing with 'action' as a key from Ext.data.Api.actions.
+            // We'll flip it now and send the value into DataProxy#request, since it's the value which maps to
+            // the user's configured DataProxy#api
             this.proxy.request(Ext.data.Api.actions[action], rs, params, this.reader, this.createCallback(action, rs), this, options);
         }
         return doRequest;
@@ -30917,7 +31653,7 @@ sortInfo: {
         var actions = Ext.data.Api.actions;
         return (action == 'read') ? this.loadRecords : function(data, response, success) {
             // calls: onCreateRecords | onUpdateRecords | onDestroyRecords
-            this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, data);
+            this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, [].concat(data));
             // If success === false here, exception will have been called in DataProxy
             if (success === true) {
                 this.fireEvent('write', this, action, data, response, rs);
@@ -30927,6 +31663,7 @@ sortInfo: {
 
     // Clears records from modified array after an exception event.
     // NOTE:  records are left marked dirty.  Do we want to commit them even though they were not updated/realized?
+    // TODO remove this method?
     clearModified : function(rs) {
         if (Ext.isArray(rs)) {
             for (var n=rs.length-1;n>=0;n--) {
@@ -30987,7 +31724,7 @@ sortInfo: {
     // @protected onDestroyRecords proxy callback for destroy action
     onDestroyRecords : function(success, rs, data) {
         // splice each rec out of this.removed
-        rs = (rs instanceof Ext.data.Record) ? [rs] : rs;
+        rs = (rs instanceof Ext.data.Record) ? [rs] : [].concat(rs);
         for (var i=0,len=rs.length;i<len;i++) {
             this.removed.splice(this.removed.indexOf(rs[i]), 1);
         }
@@ -31042,7 +31779,7 @@ sortInfo: {
                 this.data = this.snapshot;
                 delete this.snapshot;
             }
-            this.data.clear();
+            this.clearData();
             this.data.addAll(r);
             this.totalLength = t;
             this.applySort();
@@ -31429,18 +32166,27 @@ sortInfo: {
         for(var i = 0, len = m.length; i < len; i++){
             m[i].reject();
         }
+        var m = this.removed.slice(0).reverse();
+        this.removed = [];
+        for(var i = 0, len = m.length; i < len; i++){
+            this.insert(m[i].lastIndex||0, m[i]);
+            m[i].reject();
+        }
     },
 
     // private
-    onMetaChange : function(meta, rtype, o){
-        this.recordType = rtype;
-        this.fields = rtype.prototype.fields;
+    onMetaChange : function(meta){
+        this.recordType = this.reader.recordType;
+        this.fields = this.recordType.prototype.fields;
         delete this.snapshot;
-        if(meta.sortInfo){
-            this.sortInfo = meta.sortInfo;
+        if(this.reader.meta.sortInfo){
+            this.sortInfo = this.reader.meta.sortInfo;
         }else if(this.sortInfo  && !this.fields.get(this.sortInfo.field)){
             delete this.sortInfo;
         }
+        if(this.writer){
+            this.writer.meta = this.reader.meta;
+        }
         this.modified = [];
         this.fireEvent('metachange', this, this.reader.meta);
     },
@@ -31758,14 +32504,49 @@ Ext.data.DataReader = function(meta, recordType){
      */\r
     this.recordType = Ext.isArray(recordType) ?\r
         Ext.data.Record.create(recordType) : recordType;\r
+
+    // if recordType defined make sure extraction functions are defined\r
+    if (this.recordType){\r
+        this.buildExtractors();\r
+    }
 };\r
 \r
 Ext.data.DataReader.prototype = {\r
-\r
     /**\r
-     * Abstract method, overridden in {@link Ext.data.JsonReader}\r
+     * @cfg {String} messageProperty [undefined] Optional name of a property within a server-response that represents a user-feedback message.\r
+     */\r
+    /**\r
+     * Abstract method created in extension's buildExtractors impl.\r
+     */\r
+    getTotal: Ext.emptyFn,\r
+    /**\r
+     * Abstract method created in extension's buildExtractors impl.\r
+     */\r
+    getRoot: Ext.emptyFn,\r
+    /**\r
+     * Abstract method created in extension's buildExtractors impl.\r
+     */\r
+    getMessage: Ext.emptyFn,\r
+    /**\r
+     * Abstract method created in extension's buildExtractors impl.\r
+     */\r
+    getSuccess: Ext.emptyFn,\r
+    /**\r
+     * Abstract method created in extension's buildExtractors impl.\r
+     */\r
+    getId: Ext.emptyFn,\r
+    /**\r
+     * Abstract method, overridden in DataReader extensions such as {@link Ext.data.JsonReader} and {@link Ext.data.XmlReader}\r
      */\r
     buildExtractors : Ext.emptyFn,\r
+    /**\r
+     * Abstract method overridden in DataReader extensions such as {@link Ext.data.JsonReader} and {@link Ext.data.XmlReader}\r
+     */\r
+    extractData : Ext.emptyFn,\r
+    /**\r
+     * Abstract method overridden in DataReader extensions such as {@link Ext.data.JsonReader} and {@link Ext.data.XmlReader}\r
+     */\r
+    extractValues : Ext.emptyFn,\r
 \r
     /**\r
      * Used for un-phantoming a record after a successful database insert.  Sets the records pk along with new data from server.\r
@@ -31800,24 +32581,19 @@ Ext.data.DataReader.prototype = {
                 //rs.commit();\r
                 throw new Ext.data.DataReader.Error('realize', rs);\r
             }\r
-            this.buildExtractors();\r
-            var values = this.extractValues(data, rs.fields.items, rs.fields.items.length);\r
             rs.phantom = false; // <-- That's what it's all about\r
             rs._phid = rs.id;  // <-- copy phantom-id -> _phid, so we can remap in Store#onCreateRecords\r
-            rs.id = data[this.meta.idProperty];\r
-            rs.data = values;\r
+            rs.id = this.getId(data);\r
+            rs.data = data;\r
             rs.commit();\r
         }\r
     },\r
 \r
     /**\r
      * Used for updating a non-phantom or "real" record's data with fresh data from server after remote-save.\r
-     * You <b>must</b> return a complete new record from the server.  If you don't, your local record's missing fields\r
-     * will be populated with the default values specified in your Ext.data.Record.create specification.  Without a defaultValue,\r
-     * local fields will be populated with empty string "".  So return your entire record's data after both remote create and update.\r
-     * In addition, you <b>must</b> return record-data from the server in the same order received.\r
-     * Will perform a commit as well, un-marking dirty-fields.  Store's "update" event will be suppressed as the record receives\r
-     * a fresh new data-hash.\r
+     * If returning data from multiple-records after a batch-update, you <b>must</b> return record-data from the server in\r
+     * the same order received.  Will perform a commit as well, un-marking dirty-fields.  Store's "update" event will be\r
+     * suppressed as the record receives fresh new data-hash\r
      * @param {Record/Record[]} rs\r
      * @param {Object/Object[]} data\r
      */\r
@@ -31835,18 +32611,13 @@ Ext.data.DataReader.prototype = {
             }\r
         }\r
         else {\r
-                     // If rs is NOT an array but data IS, see if data contains just 1 record.  If so extract it and carry on.\r
+            // If rs is NOT an array but data IS, see if data contains just 1 record.  If so extract it and carry on.\r
             if (Ext.isArray(data) && data.length == 1) {\r
                 data = data.shift();\r
             }\r
-            if (!this.isData(data)) {\r
-                // TODO: create custom Exception class to return record in thrown exception.  Allow exception-handler the choice\r
-                // to commit or not rather than blindly rs.commit() here.\r
-                rs.commit();\r
-                throw new Ext.data.DataReader.Error('update', rs);\r
+            if (this.isData(data)) {\r
+                rs.data = Ext.apply(rs.data, data);\r
             }\r
-            this.buildExtractors();\r
-            rs.data = this.extractValues(Ext.apply(rs.data, data), rs.fields.items, rs.fields.items.length);\r
             rs.commit();\r
         }\r
     },\r
@@ -31858,7 +32629,15 @@ Ext.data.DataReader.prototype = {
      * @return {Boolean}\r
      */\r
     isData : function(data) {\r
-        return (data && Ext.isObject(data) && !Ext.isEmpty(data[this.meta.idProperty])) ? true : false;\r
+        return (data && Ext.isObject(data) && !Ext.isEmpty(this.getId(data))) ? true : false;\r
+    },\r
+\r
+    // private function a store will createSequence upon\r
+    onMetaChange : function(meta){\r
+        delete this.ef;\r
+        this.meta = meta;\r
+        this.recordType = Ext.data.Record.create(meta.fields);\r
+        this.buildExtractors();\r
     }\r
 };\r
 \r
@@ -31883,6 +32662,40 @@ Ext.apply(Ext.data.DataReader.Error.prototype, {
 });\r
 \r
 \r
+/**\r
+ * Ext.data.Response\r
+ * A generic response class to normalize response-handling internally to the framework.\r
+ * TODO move to own file, add to jsb.\r
+ */\r
+Ext.data.Response = function(params) {\r
+    Ext.apply(this, params);\r
+};\r
+Ext.data.Response.prototype = {\r
+    /**\r
+     * @property {String} action {@link Ext.data.Api#actions}\r
+     */\r
+    action: undefined,\r
+    /**\r
+     * @property {Boolean} success\r
+     */\r
+    success : undefined,\r
+    /**\r
+     * @property {String} message\r
+     */\r
+    message : undefined,\r
+    /**\r
+     * @property {Array/Object} data\r
+     */\r
+    data: undefined,\r
+    /**\r
+     * @property {Object} raw The raw response returned from server-code\r
+     */\r
+    raw: undefined,\r
+    /**\r
+     * @property {Ext.data.Record/Ext.data.Record[]} record(s) related to the Request action\r
+     */\r
+    records: undefined\r
+}\r
 /**
  * @class Ext.data.DataWriter
  * <p>Ext.data.DataWriter facilitates create, update, and destroy actions between
@@ -31929,14 +32742,8 @@ var store = new Ext.data.Store({
  * using {@link Ext.data.Record#create}.
  */
 Ext.data.DataWriter = function(config){
-    /**
-     * This DataWriter's configured metadata as passed to the constructor.
-     * @type Mixed
-     * @property meta
-     */
     Ext.apply(this, config);
 };
-
 Ext.data.DataWriter.prototype = {
 
     /**
@@ -31961,7 +32768,18 @@ Ext.data.DataWriter.prototype = {
      * @param {Record/Record[]} rs The recordset write.
      */
     write : function(action, params, rs) {
-        this.render(action, rs, params, this[action](rs));
+        var data    = [],
+        renderer    = action + 'Record';
+        // TODO implement @cfg listful here
+        if (Ext.isArray(rs)) {
+            Ext.each(rs, function(rec){
+                data.push(this[renderer](rec));
+            }, this);
+        }
+        else if (rs instanceof Ext.data.Record) {
+            data = this[renderer](rs);
+        }
+        this.render(action, rs, params, data);
     },
 
     /**
@@ -31975,84 +32793,17 @@ Ext.data.DataWriter.prototype = {
     render : Ext.emptyFn,
 
     /**
-     * update
-     * @param {Object} p Params-hash to apply result to.
-     * @param {Record/Record[]} rs Record(s) to write
-     * @private
-     */
-    update : function(rs) {
-        var params = {};
-        if (Ext.isArray(rs)) {
-            var data = [],
-                ids = [];
-            Ext.each(rs, function(val){
-                ids.push(val.id);
-                data.push(this.updateRecord(val));
-            }, this);
-            params[this.meta.idProperty] = ids;
-            params[this.meta.root] = data;
-        }
-        else if (rs instanceof Ext.data.Record) {
-            params[this.meta.idProperty] = rs.id;
-            params[this.meta.root] = this.updateRecord(rs);
-        }
-        return params;
-    },
-
-    /**
-     * @cfg {Function} saveRecord Abstract method that should be implemented in all subclasses
-     * (e.g.: {@link Ext.data.JsonWriter#saveRecord JsonWriter.saveRecord}
+     * @cfg {Function} updateRecord Abstract method that should be implemented in all subclasses
+     * (e.g.: {@link Ext.data.JsonWriter#updateRecord JsonWriter.updateRecord}
      */
     updateRecord : Ext.emptyFn,
 
-    /**
-     * create
-     * @param {Object} p Params-hash to apply result to.
-     * @param {Record/Record[]} rs Record(s) to write
-     * @private
-     */
-    create : function(rs) {
-        var params = {};
-        if (Ext.isArray(rs)) {
-            var data = [];
-            Ext.each(rs, function(val){
-                data.push(this.createRecord(val));
-            }, this);
-            params[this.meta.root] = data;
-        }
-        else if (rs instanceof Ext.data.Record) {
-            params[this.meta.root] = this.createRecord(rs);
-        }
-        return params;
-    },
-
     /**
      * @cfg {Function} createRecord Abstract method that should be implemented in all subclasses
      * (e.g.: {@link Ext.data.JsonWriter#createRecord JsonWriter.createRecord})
      */
     createRecord : Ext.emptyFn,
 
-    /**
-     * destroy
-     * @param {Object} p Params-hash to apply result to.
-     * @param {Record/Record[]} rs Record(s) to write
-     * @private
-     */
-    destroy : function(rs) {
-        var params = {};
-        if (Ext.isArray(rs)) {
-            var data = [],
-                ids = [];
-            Ext.each(rs, function(val){
-                data.push(this.destroyRecord(val));
-            }, this);
-            params[this.meta.root] = data;
-        } else if (rs instanceof Ext.data.Record) {
-            params[this.meta.root] = this.destroyRecord(rs);
-        }
-        return params;
-    },
-
     /**
      * @cfg {Function} destroyRecord Abstract method that should be implemented in all subclasses
      * (e.g.: {@link Ext.data.JsonWriter#destroyRecord JsonWriter.destroyRecord})
@@ -32060,7 +32811,7 @@ Ext.data.DataWriter.prototype = {
     destroyRecord : Ext.emptyFn,
 
     /**
-     * Converts a Record to a hash
+     * Converts a Record to a hash.
      * @param {Record}
      * @private
      */
@@ -32074,7 +32825,16 @@ Ext.data.DataWriter.prototype = {
                 data[m.mapping ? m.mapping : m.name] = value;
             }
         });
-        data[this.meta.idProperty] = rec.id;
+        // we don't want to write Ext auto-generated id to hash.  Careful not to remove it on Models not having auto-increment pk though.
+        // We can tell its not auto-increment if the user defined a DataReader field for it *and* that field's value is non-empty.
+        // we could also do a RegExp here for the Ext.data.Record AUTO_ID prefix.
+        if (rec.phantom) {
+            if (rec.fields.containsKey(this.meta.idProperty) && Ext.isEmpty(rec.data[this.meta.idProperty])) {
+                delete data[this.meta.idProperty];
+            }
+        } else {
+            data[this.meta.idProperty] = rec.id
+        }
         return data;
     }
 };/**\r
@@ -32140,7 +32900,27 @@ api: {
     update  : undefined,\r
     destroy : undefined\r
 }\r
-</code></pre>\r
+     * </code></pre>\r
+     * <p>The url is built based upon the action being executed <tt>[load|create|save|destroy]</tt>\r
+     * using the commensurate <tt>{@link #api}</tt> property, or if undefined default to the\r
+     * configured {@link Ext.data.Store}.{@link Ext.data.Store#url url}.</p><br>\r
+     * <p>For example:</p>\r
+     * <pre><code>\r
+api: {\r
+    load :    '/controller/load',\r
+    create :  '/controller/new',  // Server MUST return idProperty of new record\r
+    save :    '/controller/update',\r
+    destroy : '/controller/destroy_action'\r
+}\r
+\r
+// Alternatively, one can use the object-form to specify each API-action\r
+api: {\r
+    load: {url: 'read.php', method: 'GET'},\r
+    create: 'create.php',\r
+    destroy: 'destroy.php',\r
+    save: 'update.php'\r
+}\r
+     * </code></pre>\r
      * <p>If the specific URL for a given CRUD action is undefined, the CRUD action request\r
      * will be directed to the configured <tt>{@link Ext.data.Connection#url url}</tt>.</p>\r
      * <br><p><b>Note</b>: To modify the URL for an action dynamically the appropriate API\r
@@ -32158,22 +32938,9 @@ myStore.on({
             // permanent, applying this URL for all subsequent requests.\r
             store.proxy.setUrl('changed1.php', true);\r
 \r
-            // manually set the <b>private</b> connection URL.\r
-            // <b>Warning:</b>  Accessing the private URL property should be avoided.\r
-            // Use the public method <tt>{@link Ext.data.HttpProxy#setUrl setUrl}</tt> instead, shown above.\r
-            // It should be noted that changing the URL like this will affect\r
-            // the URL for just this request.  Subsequent requests will use the\r
-            // API or URL defined in your initial proxy configuration.\r
-            store.proxy.conn.url = 'changed1.php';\r
-\r
-            // proxy URL will be superseded by API (only if proxy created to use ajax):\r
-            // It should be noted that proxy API changes are permanent and will\r
-            // be used for all subsequent requests.\r
-            store.proxy.api.load = 'changed2.php';\r
-\r
-            // However, altering the proxy API should be done using the public\r
-            // method <tt>{@link Ext.data.DataProxy#setApi setApi}</tt> instead.\r
-            store.proxy.setApi('load', 'changed2.php');\r
+            // Altering the proxy API should be done using the public\r
+            // method <tt>{@link Ext.data.DataProxy#setApi setApi}</tt>.\r
+            store.proxy.setApi('read', 'changed2.php');\r
 \r
             // Or set the entire API with a config-object.\r
             // When using the config-object option, you must redefine the <b>entire</b>\r
@@ -32190,23 +32957,17 @@ myStore.on({
      * </code></pre>\r
      * </p>\r
      */\r
-    // Prepare the proxy api.  Ensures all API-actions are defined with the Object-form.\r
-    try {\r
-        Ext.data.Api.prepare(this);\r
-    } catch (e) {\r
-        if (e instanceof Ext.data.Api.Error) {\r
-            e.toConsole();\r
-        }\r
-    }\r
 \r
     this.addEvents(\r
         /**\r
          * @event exception\r
-         * <p>Fires if an exception occurs in the Proxy during a remote request.\r
-         * This event is relayed through a corresponding\r
-         * {@link Ext.data.Store}.{@link Ext.data.Store#exception exception},\r
-         * so any Store instance may observe this event.\r
-         * This event can be fired for one of two reasons:</p>\r
+         * <p>Fires if an exception occurs in the Proxy during a remote request. This event is relayed\r
+         * through a corresponding {@link Ext.data.Store}.{@link Ext.data.Store#exception exception},\r
+         * so any Store instance may observe this event.</p>\r
+         * <p>In addition to being fired through the DataProxy instance that raised the event, this event is also fired\r
+         * through the Ext.data.DataProxy <i>class</i> to allow for centralized processing of exception events from <b>all</b>\r
+         * DataProxies by attaching a listener to the Ext.data.Proxy class itself.</p>\r
+         * <p>This event can be fired for one of two reasons:</p>\r
          * <div class="mdetail-params"><ul>\r
          * <li>remote-request <b>failed</b> : <div class="sub-desc">\r
          * The server did not return status === 200.\r
@@ -32290,7 +33051,10 @@ myStore.on({
         'loadexception',\r
         /**\r
          * @event beforewrite\r
-         * Fires before a request is generated for one of the actions Ext.data.Api.actions.create|update|destroy\r
+         * <p>Fires before a request is generated for one of the actions Ext.data.Api.actions.create|update|destroy</p>\r
+         * <p>In addition to being fired through the DataProxy instance that raised the event, this event is also fired\r
+         * through the Ext.data.DataProxy <i>class</i> to allow for centralized processing of beforewrite events from <b>all</b>\r
+         * DataProxies by attaching a listener to the Ext.data.Proxy class itself.</p>\r
          * @param {DataProxy} this The proxy for the request\r
          * @param {String} action [Ext.data.Api.actions.create|update|destroy]\r
          * @param {Record/Array[Record]} rs The Record(s) to create|update|destroy.\r
@@ -32299,7 +33063,10 @@ myStore.on({
         'beforewrite',\r
         /**\r
          * @event write\r
-         * Fires before the request-callback is called\r
+         * <p>Fires before the request-callback is called</p>\r
+         * <p>In addition to being fired through the DataProxy instance that raised the event, this event is also fired\r
+         * through the Ext.data.DataProxy <i>class</i> to allow for centralized processing of write events from <b>all</b>\r
+         * DataProxies by attaching a listener to the Ext.data.Proxy class itself.</p>\r
          * @param {DataProxy} this The proxy that sent the request\r
          * @param {String} action [Ext.data.Api.actions.create|upate|destroy]\r
          * @param {Object} data The data object extracted from the server-response\r
@@ -32310,6 +33077,17 @@ myStore.on({
         'write'\r
     );\r
     Ext.data.DataProxy.superclass.constructor.call(this);\r
+\r
+    // Prepare the proxy api.  Ensures all API-actions are defined with the Object-form.\r
+    try {\r
+        Ext.data.Api.prepare(this);\r
+    } catch (e) {\r
+        if (e instanceof Ext.data.Api.Error) {\r
+            e.toConsole();\r
+        }\r
+    }\r
+    // relay each proxy's events onto Ext.data.DataProxy class for centralized Proxy-listening\r
+    Ext.data.DataProxy.relayEvents(this, ['beforewrite', 'write', 'exception']);\r
 };\r
 \r
 Ext.extend(Ext.data.DataProxy, Ext.util.Observable, {\r
@@ -32328,7 +33106,7 @@ store: new Ext.data.Store({
     ...\r
 )}\r
      * </code></pre>\r
-     * There is no <code>{@link #api}</code> specified in the configuration of the proxy,\r
+     * If there is no <code>{@link #api}</code> specified in the configuration of the proxy,\r
      * all requests will be marshalled to a single RESTful url (/users) so the serverside\r
      * framework can inspect the HTTP Method and act accordingly:\r
      * <pre>\r
@@ -32338,6 +33116,18 @@ GET      /users     read
 PUT      /users/23  update\r
 DESTROY  /users/23  delete\r
      * </pre></p>\r
+     * <p>If set to <tt>true</tt>, a {@link Ext.data.Record#phantom non-phantom} record's\r
+     * {@link Ext.data.Record#id id} will be appended to the url. Some MVC (e.g., Ruby on Rails,\r
+     * Merb and Django) support segment based urls where the segments in the URL follow the\r
+     * Model-View-Controller approach:<pre><code>\r
+     * someSite.com/controller/action/id\r
+     * </code></pre>\r
+     * Where the segments in the url are typically:<div class="mdetail-params"><ul>\r
+     * <li>The first segment : represents the controller class that should be invoked.</li>\r
+     * <li>The second segment : represents the class function, or method, that should be called.</li>\r
+     * <li>The third segment : represents the ID (a variable typically passed to the method).</li>\r
+     * </ul></div></p>\r
+     * <br><p>Refer to <code>{@link Ext.data.DataProxy#api}</code> for additional information.</p>\r
      */\r
     restful: false,\r
 \r
@@ -32453,11 +33243,16 @@ proxy.setApi(Ext.data.Api.actions.read, '/users/new_load_url');
             throw new Ext.data.Api.Error('invalid-url', action);\r
         }\r
 \r
+        // look for urls having "provides" suffix (from Rails/Merb and others...),\r
+        // e.g.: /users.json, /users.xml, etc\r
+        // with restful routes, we need urls like:\r
+        // PUT /users/1.json\r
+        // DELETE /users/1.json\r
         var format = null;\r
-        var m = url.match(/(.*)(\.\w+)$/);  // <-- look for urls with "provides" suffix, e.g.: /users.json, /users.xml, etc\r
+        var m = url.match(/(.*)(\.json|\.xml|\.html)$/);\r
         if (m) {\r
-            format = m[2];\r
-            url = m[1];\r
+            format = m[2];  // eg ".json"\r
+            url = m[1];     // eg: "/users"\r
         }\r
         // prettyUrls is deprectated in favor of restful-config\r
         if ((this.prettyUrls === true || this.restful === true) && record instanceof Ext.data.Record && !record.phantom) {\r
@@ -32477,6 +33272,11 @@ proxy.setApi(Ext.data.Api.actions.read, '/users/new_load_url');
     }\r
 });\r
 \r
+// Apply the Observable prototype to the DataProxy class so that proxy instances can relay their\r
+// events to the class.  Allows for centralized listening of all proxy instances upon the DataProxy class.\r
+Ext.apply(Ext.data.DataProxy, Ext.util.Observable.prototype);\r
+Ext.util.Observable.call(Ext.data.DataProxy);\r
+\r
 /**\r
  * @class Ext.data.DataProxy.Error\r
  * @extends Ext.Error\r
@@ -32498,6 +33298,8 @@ Ext.apply(Ext.data.DataProxy.Error.prototype, {
         'api-invalid': 'Recieved an invalid API-configuration.  Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions.'\r
     }\r
 });\r
+\r
+\r
 /**\r
  * @class Ext.data.ScriptTagProxy\r
  * @extends Ext.data.DataProxy\r
@@ -32696,23 +33498,23 @@ Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, {
      * @param {Object} res The server response\r
      * @private\r
      */\r
-    onWrite : function(action, trans, res, rs) {\r
+    onWrite : function(action, trans, response, rs) {\r
         var reader = trans.reader;\r
         try {\r
             // though we already have a response object here in STP, run through readResponse to catch any meta-data exceptions.\r
-            reader.readResponse(action, res);\r
+            var res = reader.readResponse(action, response);\r
         } catch (e) {\r
             this.fireEvent('exception', this, 'response', action, trans, res, e);\r
             trans.callback.call(trans.scope||window, null, res, false);\r
             return;\r
         }\r
-        if(!res[reader.meta.successProperty] === true){\r
+        if(!res.success === true){\r
             this.fireEvent('exception', this, 'remote', action, trans, res, rs);\r
             trans.callback.call(trans.scope||window, null, res, false);\r
             return;\r
         }\r
-        this.fireEvent("write", this, action, res[reader.meta.root], res, rs, trans.arg );\r
-        trans.callback.call(trans.scope||window, res[reader.meta.root], res, true);\r
+        this.fireEvent("write", this, action, res.data, res, rs, trans.arg );\r
+        trans.callback.call(trans.scope||window, res.data, res, true);\r
     },\r
 \r
     // private\r
@@ -32804,13 +33606,13 @@ Ext.data.HttpProxy = function(conn){
 \r
     // nullify the connection url.  The url param has been copied to 'this' above.  The connection\r
     // url will be set during each execution of doRequest when buildUrl is called.  This makes it easier for users to override the\r
-    // connection url during beforeaction events (ie: beforeload, beforesave, etc).  The connection url will be nullified\r
-    // after each request as well.  Url is always re-defined during doRequest.\r
+    // connection url during beforeaction events (ie: beforeload, beforewrite, etc).\r
+    // Url is always re-defined during doRequest.\r
     this.conn.url = null;\r
 \r
     this.useAjax = !conn || !conn.events;\r
 \r
-    //private.  A hash containing active requests, keyed on action [Ext.data.Api.actions.create|read|update|destroy]\r
+    // A hash containing active requests, keyed on action [Ext.data.Api.actions.create|read|update|destroy]\r
     var actions = Ext.data.Api.actions;\r
     this.activeRequest = {};\r
     for (var verb in actions) {\r
@@ -32819,40 +33621,6 @@ Ext.data.HttpProxy = function(conn){
 };\r
 \r
 Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {\r
-    /**\r
-     * @cfg {Boolean} restful\r
-     * <p>If set to <tt>true</tt>, a {@link Ext.data.Record#phantom non-phantom} record's\r
-     * {@link Ext.data.Record#id id} will be appended to the url (defaults to <tt>false</tt>).</p><br>\r
-     * <p>The url is built based upon the action being executed <tt>[load|create|save|destroy]</tt>\r
-     * using the commensurate <tt>{@link #api}</tt> property, or if undefined default to the\r
-     * configured {@link Ext.data.Store}.{@link Ext.data.Store#url url}.</p><br>\r
-     * <p>Some MVC (e.g., Ruby on Rails, Merb and Django) support this style of segment based urls\r
-     * where the segments in the URL follow the Model-View-Controller approach.</p><pre><code>\r
-     * someSite.com/controller/action/id\r
-     * </code></pre>\r
-     * Where the segments in the url are typically:<div class="mdetail-params"><ul>\r
-     * <li>The first segment : represents the controller class that should be invoked.</li>\r
-     * <li>The second segment : represents the class function, or method, that should be called.</li>\r
-     * <li>The third segment : represents the ID (a variable typically passed to the method).</li>\r
-     * </ul></div></p>\r
-     * <p>For example:</p>\r
-     * <pre><code>\r
-api: {\r
-    load :    '/controller/load',\r
-    create :  '/controller/new',  // Server MUST return idProperty of new record\r
-    save :    '/controller/update',\r
-    destroy : '/controller/destroy_action'\r
-}\r
-\r
-// Alternatively, one can use the object-form to specify each API-action\r
-api: {\r
-    load: {url: 'read.php', method: 'GET'},\r
-    create: 'create.php',\r
-    destroy: 'destroy.php',\r
-    save: 'update.php'\r
-}\r
-     */\r
-\r
     /**\r
      * Return the {@link Ext.data.Connection} object being used by this Proxy.\r
      * @return {Connection} The Connection object. This object may be used to subscribe to events on\r
@@ -32876,6 +33644,7 @@ api: {
         this.conn.url = url;\r
         if (makePermanent === true) {\r
             this.url = url;\r
+            this.api = null;\r
             Ext.data.Api.prepare(this);\r
         }\r
     },\r
@@ -32909,10 +33678,14 @@ api: {
             callback : this.createCallback(action, rs),\r
             scope: this\r
         };\r
-        // Sample the request data:  If it's an object, then it hasn't been json-encoded yet.\r
-        // Transmit data using jsonData config of Ext.Ajax.request\r
-        if (typeof(params[reader.meta.root]) === 'object') {\r
-            o.jsonData = params;\r
+\r
+        // If possible, transmit data using jsonData || xmlData on Ext.Ajax.request (An installed DataWriter would have written it there.).\r
+        // Use std HTTP params otherwise.\r
+        // TODO wrap into 1 Ext.apply now?\r
+        if (params.jsonData) {\r
+            o.jsonData = params.jsonData;\r
+        } else if (params.xmlData) {\r
+            o.xmlData = params.xmlData;\r
         } else {\r
             o.params = params || {};\r
         }\r
@@ -32922,7 +33695,7 @@ api: {
         if (this.conn.url === null) {\r
             this.conn.url = this.buildUrl(action, rs);\r
         }\r
-        else if (this.restful === true && rs instanceof Ext.data.Record && !rs.phantom) {\r
+        else if (this.restful === true && rs instanceof Ext.data.Record && !rs.phantom) { // <-- user must have intervened with #setApi or #setUrl\r
             this.conn.url += '/' + rs.id;\r
         }\r
         if(this.useAjax){\r
@@ -32931,7 +33704,10 @@ api: {
 \r
             // If a currently running request is found for this action, abort it.\r
             if (this.activeRequest[action]) {\r
+                ////\r
                 // Disabled aborting activeRequest while implementing REST.  activeRequest[action] will have to become an array\r
+                // TODO ideas anyone?\r
+                //\r
                 //Ext.Ajax.abort(this.activeRequest[action]);\r
             }\r
             this.activeRequest[action] = Ext.Ajax.request(o);\r
@@ -32955,6 +33731,7 @@ api: {
             if (!success) {\r
                 if (action === Ext.data.Api.actions.read) {\r
                     // @deprecated: fire loadexception for backwards compat.\r
+                    // TODO remove in 3.1\r
                     this.fireEvent('loadexception', this, o, response);\r
                 }\r
                 this.fireEvent('exception', this, 'response', action, o, response);\r
@@ -32974,6 +33751,9 @@ api: {
      * @param {String} action Action name as per {@link Ext.data.Api.actions#read}.\r
      * @param {Object} o The request transaction object\r
      * @param {Object} res The server response\r
+     * @fires loadexception (deprecated)\r
+     * @fires exception\r
+     * @fires load\r
      * @private\r
      */\r
     onRead : function(action, o, response) {\r
@@ -32982,13 +33762,16 @@ api: {
             result = o.reader.read(response);\r
         }catch(e){\r
             // @deprecated: fire old loadexception for backwards-compat.\r
+            // TODO remove in 3.1\r
             this.fireEvent('loadexception', this, o, response, e);\r
+\r
             this.fireEvent('exception', this, 'response', action, o, response, e);\r
             o.request.callback.call(o.request.scope, null, o.request.arg, false);\r
             return;\r
         }\r
         if (result.success === false) {\r
             // @deprecated: fire old loadexception for backwards-compat.\r
+            // TODO remove in 3.1\r
             this.fireEvent('loadexception', this, o, response);\r
 \r
             // Get DataReader read-back a response-object to pass along to exception event\r
@@ -32998,6 +33781,9 @@ api: {
         else {\r
             this.fireEvent('load', this, o, o.request.arg);\r
         }\r
+        // TODO refactor onRead, onWrite to be more generalized now that we're dealing with Ext.data.Response instance\r
+        // the calls to request.callback(...) in each will have to be made identical.\r
+        // NOTE reader.readResponse does not currently return Ext.data.Response\r
         o.request.callback.call(o.request.scope, result, o.request.arg, result.success);\r
     },\r
     /**\r
@@ -33005,6 +33791,8 @@ api: {
      * @param {String} action [Ext.data.Api.actions.create|read|update|destroy]\r
      * @param {Object} trans The request transaction object\r
      * @param {Object} res The server response\r
+     * @fires exception\r
+     * @fires write\r
      * @private\r
      */\r
     onWrite : function(action, o, response, rs) {\r
@@ -33017,12 +33805,15 @@ api: {
             o.request.callback.call(o.request.scope, null, o.request.arg, false);\r
             return;\r
         }\r
-        if (res[reader.meta.successProperty] === false) {\r
+        if (res.success === false) {\r
             this.fireEvent('exception', this, 'remote', action, o, res, rs);\r
         } else {\r
-            this.fireEvent('write', this, action, res[reader.meta.root], res, rs, o.request.arg);\r
+            this.fireEvent('write', this, action, res.data, res, rs, o.request.arg);\r
         }\r
-        o.request.callback.call(o.request.scope, res[reader.meta.root], res, res[reader.meta.successProperty]);\r
+        // TODO refactor onRead, onWrite to be more generalized now that we're dealing with Ext.data.Response instance\r
+        // the calls to request.callback(...) in each will have to be made similar.\r
+        // NOTE reader.readResponse does not currently return Ext.data.Response\r
+        o.request.callback.call(o.request.scope, res.data, res, res.success);\r
     },\r
 \r
     // inherit docs\r
@@ -33108,14 +33899,16 @@ Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {
  */
 Ext.data.JsonWriter = function(config) {
     Ext.data.JsonWriter.superclass.constructor.call(this, config);
+
     // careful to respect "returnJson", renamed to "encode"
+    // TODO: remove after v3 final release
     if (this.returnJson != undefined) {
         this.encode = this.returnJson;
     }
 }
 Ext.extend(Ext.data.JsonWriter, Ext.data.DataWriter, {
     /**
-     * @cfg {Boolean} returnJson <b>Deprecated.  Use {@link Ext.data.JsonWriter#encode} instead.
+     * @cfg {Boolean} returnJson <b>Deprecated</b>.  Use {@link Ext.data.JsonWriter#encode} instead.
      */
     returnJson : undefined,
     /**
@@ -33125,7 +33918,8 @@ Ext.extend(Ext.data.JsonWriter, Ext.data.DataWriter, {
      * its own json-encoding.  In addition, if you're using {@link Ext.data.HttpProxy}, setting to <tt>false</tt>
      * will cause HttpProxy to transmit data using the <b>jsonData</b> configuration-params of {@link Ext.Ajax#request}
      * instead of <b>params</b>.  When using a {@link Ext.data.Store#restful} Store, some serverside frameworks are
-     * tuned to expect data through the jsonData mechanism.  In those cases, one will want to set <b>encode: <tt>false</tt></b>
+     * tuned to expect data through the jsonData mechanism.  In those cases, one will want to set <b>encode: <tt>false</tt></b>, as in
+     * let the lower-level connection object (eg: Ext.Ajax) do the encoding.
      */
     encode : true,
 
@@ -33137,36 +33931,37 @@ Ext.extend(Ext.data.JsonWriter, Ext.data.DataWriter, {
      * @param {Object} data object populated according to DataReader meta-data "root" and "idProperty"
      */
     render : function(action, rs, params, data) {
-        Ext.apply(params, data);
-
-        if (this.encode === true) { // <-- @deprecated returnJson
-            if (Ext.isArray(rs) && data[this.meta.idProperty]) {
-                params[this.meta.idProperty] = Ext.encode(params[this.meta.idProperty]);
-            }
-            params[this.meta.root] = Ext.encode(params[this.meta.root]);
+        if (this.encode === true) {
+            params[this.meta.root] = Ext.encode(data);
+        } else {
+            params.jsonData = {};
+            params.jsonData[this.meta.root] = data;
         }
     },
     /**
-     * createRecord
+     * Implements abstract Ext.data.DataWriter#createRecord
      * @protected
      * @param {Ext.data.Record} rec
+     * @return {Object}
      */
     createRecord : function(rec) {
-        return this.toHash(rec);
+       return this.toHash(rec);
     },
     /**
-     * updateRecord
+     * Implements abstract Ext.data.DataWriter#updateRecord
      * @protected
      * @param {Ext.data.Record} rec
+     * @return {Object}
      */
     updateRecord : function(rec) {
         return this.toHash(rec);
 
     },
     /**
-     * destroyRecord
+     * Implements abstract Ext.data.DataWriter#destroyRecord
      * @protected
      * @param {Ext.data.Record} rec
+     * @return {Object}
      */
     destroyRecord : function(rec) {
         return rec.id;
@@ -33174,90 +33969,101 @@ Ext.extend(Ext.data.JsonWriter, Ext.data.DataWriter, {
 });/**
  * @class Ext.data.JsonReader
  * @extends Ext.data.DataReader
- * <p>Data reader class to create an Array of {@link Ext.data.Record} objects from a JSON response
- * based on mappings in a provided {@link Ext.data.Record} constructor.</p>
+ * <p>Data reader class to create an Array of {@link Ext.data.Record} objects
+ * from a JSON packet based on mappings in a provided {@link Ext.data.Record}
+ * constructor.</p>
  * <p>Example code:</p>
  * <pre><code>
-var Employee = Ext.data.Record.create([
-    {name: 'firstname'},                  // map the Record's "firstname" field to the row object's key of the same name
-    {name: 'job', mapping: 'occupation'}  // map the Record's "job" field to the row object's "occupation" key
-]);
-var myReader = new Ext.data.JsonReader(
-    {                             // The metadata property, with configuration options:
-        totalProperty: "results", //   the property which contains the total dataset size (optional)
-        root: "rows",             //   the property which contains an Array of record data objects
-        idProperty: "id"          //   the property within each row object that provides an ID for the record (optional)
-    },
-    Employee  // {@link Ext.data.Record} constructor that provides mapping for JSON object
-);
+var myReader = new Ext.data.JsonReader({
+    // metadata configuration options:
+    {@link #idProperty}: 'id'
+    {@link #root}: 'rows',
+    {@link #totalProperty}: 'results',
+    {@link Ext.data.DataReader#messageProperty}: "msg"  // The element within the response that provides a user-feedback message (optional)
+
+    // the fields config option will internally create an {@link Ext.data.Record}
+    // constructor that provides mapping for reading the record data objects
+    {@link Ext.data.DataReader#fields fields}: [
+        // map Record&#39;s 'firstname' field to data object&#39;s key of same name
+        {name: 'name'},
+        // map Record&#39;s 'job' field to data object&#39;s 'occupation' key
+        {name: 'job', mapping: 'occupation'}
+    ]
+});
 </code></pre>
  * <p>This would consume a JSON data object of the form:</p><pre><code>
 {
-    results: 2,  // Reader's configured totalProperty
-    rows: [      // Reader's configured root
-        { id: 1, firstname: 'Bill', occupation: 'Gardener' },         // a row object
-        { id: 2, firstname: 'Ben' , occupation: 'Horticulturalist' }  // another row object
+    results: 2000, // Reader&#39;s configured {@link #totalProperty}
+    rows: [        // Reader&#39;s configured {@link #root}
+        // record data objects:
+        { {@link #idProperty id}: 1, firstname: 'Bill', occupation: 'Gardener' },
+        { {@link #idProperty id}: 2, firstname: 'Ben' , occupation: 'Horticulturalist' },
+        ...
     ]
 }
 </code></pre>
  * <p><b><u>Automatic configuration using metaData</u></b></p>
- * <p>It is possible to change a JsonReader's metadata at any time by including a <b><tt>metaData</tt></b>
- * property in the JSON data object. If the JSON data object has a <b><tt>metaData</tt></b> property, a
- * {@link Ext.data.Store Store} object using this Reader will reconfigure itself to use the newly provided
- * field definition and fire its {@link Ext.data.Store#metachange metachange} event. The metachange event
- * handler may interrogate the <b><tt>metaData</tt></b> property to perform any configuration required.
- * Note that reconfiguring a Store potentially invalidates objects which may refer to Fields or Records
- * which no longer exist.</p>
- * <p>The <b><tt>metaData</tt></b> property in the JSON data object may contain:</p>
- * <div class="mdetail-params"><ul>
- * <li>any of the configuration options for this class</li>
- * <li>a <b><tt>{@link Ext.data.Record#fields fields}</tt></b> property which the JsonReader will
- * use as an argument to the {@link Ext.data.Record#create data Record create method} in order to
- * configure the layout of the Records it will produce.</li>
- * <li>a <b><tt>{@link Ext.data.Store#sortInfo sortInfo}</tt></b> property which the JsonReader will
- * use to set the {@link Ext.data.Store}'s {@link Ext.data.Store#sortInfo sortInfo} property</li>
- * <li>any user-defined properties needed</li>
- * </ul></div>
- * <p>To use this facility to send the same data as the example above (without having to code the creation
- * of the Record constructor), you would create the JsonReader like this:</p><pre><code>
+ * <p>It is possible to change a JsonReader's metadata at any time by including
+ * a <b><tt>metaData</tt></b> property in the JSON data object. If the JSON data
+ * object has a <b><tt>metaData</tt></b> property, a {@link Ext.data.Store Store}
+ * object using this Reader will reconfigure itself to use the newly provided
+ * field definition and fire its {@link Ext.data.Store#metachange metachange}
+ * event. The metachange event handler may interrogate the <b><tt>metaData</tt></b>
+ * property to perform any configuration required.</p>
+ * <p>Note that reconfiguring a Store potentially invalidates objects which may
+ * refer to Fields or Records which no longer exist.</p>
+ * <p>To use this facility you would create the JsonReader like this:</p><pre><code>
 var myReader = new Ext.data.JsonReader();
 </code></pre>
- * <p>The first data packet from the server would configure the reader by containing a
- * <b><tt>metaData</tt></b> property <b>and</b> the data. For example, the JSON data object might take
- * the form:</p>
-<pre><code>
+ * <p>The first data packet from the server would configure the reader by
+ * containing a <b><tt>metaData</tt></b> property <b>and</b> the data. For
+ * example, the JSON data object might take the form:</p><pre><code>
 {
     metaData: {
-        idProperty: 'id',
-        root: 'rows',
-        totalProperty: 'results',
-        fields: [
-            {name: 'name'},
-            {name: 'job', mapping: 'occupation'}
+        "{@link #idProperty}": "id",
+        "{@link #root}": "rows",
+        "{@link #totalProperty}": "results"
+        "{@link #successProperty}": "success",
+        "{@link Ext.data.DataReader#fields fields}": [
+            {"name": "name"},
+            {"name": "job", "mapping": "occupation"}
         ],
-        sortInfo: {field: 'name', direction:'ASC'}, // used by store to set its sortInfo
-        foo: 'bar' // custom property
-    },
-    results: 2,
-    rows: [ // an Array
-        { 'id': 1, 'name': 'Bill', occupation: 'Gardener' },
-        { 'id': 2, 'name': 'Ben', occupation: 'Horticulturalist' }
+        // used by store to set its sortInfo
+        "sortInfo":{
+           "field": "name",
+           "direction": "ASC"
+        },
+        // {@link Ext.PagingToolbar paging data} (if applicable)
+        "start": 0,
+        "limit": 2,
+        // custom property
+        "foo": "bar"
+    },
+    // Reader&#39;s configured {@link #successProperty}
+    "success": true,
+    // Reader&#39;s configured {@link #totalProperty}
+    "results": 2000,
+    // Reader&#39;s configured {@link #root}
+    // (this data simulates 2 results {@link Ext.PagingToolbar per page})
+    "rows": [ // <b>*Note:</b> this must be an Array
+        { "id": 1, "name": "Bill", "occupation": "Gardener" },
+        { "id": 2, "name":  "Ben", "occupation": "Horticulturalist" }
     ]
 }
-</code></pre>
- * @cfg {String} totalProperty [total] Name of the property from which to retrieve the total number of records
- * in the dataset. This is only needed if the whole dataset is not passed in one go, but is being
- * paged from the remote server.  Defaults to <tt>total</tt>.
- * @cfg {String} successProperty [success] Name of the property from which to
- * retrieve the success attribute. Defaults to <tt>success</tt>.  See
- * {@link Ext.data.DataProxy}.{@link Ext.data.DataProxy#exception exception}
- * for additional information.
- * @cfg {String} root [undefined] <b>Required</b>.  The name of the property
- * which contains the Array of row objects.  Defaults to <tt>undefined</tt>.
- * An exception will be thrown if the root property is undefined. The data packet
- * value for this property should be an empty array to clear the data or show
- * no data.
- * @cfg {String} idProperty [id] Name of the property within a row object that contains a record identifier value.  Defaults to <tt>id</tt>
+ * </code></pre>
+ * <p>The <b><tt>metaData</tt></b> property in the JSON data object should contain:</p>
+ * <div class="mdetail-params"><ul>
+ * <li>any of the configuration options for this class</li>
+ * <li>a <b><tt>{@link Ext.data.Record#fields fields}</tt></b> property which
+ * the JsonReader will use as an argument to the
+ * {@link Ext.data.Record#create data Record create method} in order to
+ * configure the layout of the Records it will produce.</li>
+ * <li>a <b><tt>{@link Ext.data.Store#sortInfo sortInfo}</tt></b> property
+ * which the JsonReader will use to set the {@link Ext.data.Store}'s
+ * {@link Ext.data.Store#sortInfo sortInfo} property</li>
+ * <li>any custom properties needed</li>
+ * </ul></div>
+ *
  * @constructor
  * Create a new JsonReader
  * @param {Object} meta Metadata configuration options.
@@ -33268,8 +34074,29 @@ var myReader = new Ext.data.JsonReader();
  */
 Ext.data.JsonReader = function(meta, recordType){
     meta = meta || {};
-
-    // default idProperty, successProperty & totalProperty -> "id", "success", "total"
+    /**
+     * @cfg {String} idProperty [id] Name of the property within a row object
+     * that contains a record identifier value.  Defaults to <tt>id</tt>
+     */
+    /**
+     * @cfg {String} successProperty [success] Name of the property from which to
+     * retrieve the success attribute. Defaults to <tt>success</tt>.  See
+     * {@link Ext.data.DataProxy}.{@link Ext.data.DataProxy#exception exception}
+     * for additional information.
+     */
+    /**
+     * @cfg {String} totalProperty [total] Name of the property from which to
+     * retrieve the total number of records in the dataset. This is only needed
+     * if the whole dataset is not passed in one go, but is being paged from
+     * the remote server.  Defaults to <tt>total</tt>.
+     */
+    /**
+     * @cfg {String} root [undefined] <b>Required</b>.  The name of the property
+     * which contains the Array of row objects.  Defaults to <tt>undefined</tt>.
+     * An exception will be thrown if the root property is undefined. The data
+     * packet value for this property should be an empty array to clear the data
+     * or show no data.
+     */
     Ext.applyIf(meta, {
         idProperty: 'id',
         successProperty: 'success',
@@ -33295,39 +34122,50 @@ Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
         var json = response.responseText;
         var o = Ext.decode(json);
         if(!o) {
-            throw {message: "JsonReader.read: Json object not found"};
+            throw {message: 'JsonReader.read: Json object not found'};
         }
         return this.readRecords(o);
     },
 
-    // private function a store will implement
-    onMetaChange : function(meta, recordType, o){
-
-    },
-
     /**
-     * @ignore
+     * Decode a json response from server.
+     * @param {String} action [Ext.data.Api.actions.create|read|update|destroy]
+     * @param {Object} response
+     * TODO: refactor code between JsonReader#readRecords, #readResponse into 1 method.
+     * there's ugly duplication going on due to maintaining backwards compat. with 2.0.  It's time to do this.
      */
-    simpleAccess: function(obj, subsc) {
-        return obj[subsc];
-    },
+    readResponse : function(action, response) {
+        var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response;
+        if(!o) {
+            throw new Ext.data.JsonReader.Error('response');
+        }
 
-    /**
-     * @ignore
-     */
-    getJsonAccessor: function(){
-        var re = /[\[\.]/;
-        return function(expr) {
-            try {
-                return(re.test(expr)) ?
-                new Function("obj", "return obj." + expr) :
-                function(obj){
-                    return obj[expr];
-                };
-            } catch(e){}
-            return Ext.emptyFn;
-        };
-    }(),
+        var root = this.getRoot(o);
+        if (action === Ext.data.Api.actions.create) {
+            var def = Ext.isDefined(root);
+            if (def && Ext.isEmpty(root)) {
+                throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
+            }
+            else if (!def) {
+                throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
+            }
+        }
+
+        // instantiate response object
+        var res = new Ext.data.Response({
+            action: action,
+            success: this.getSuccess(o),
+            data: this.extractData(root),
+            message: this.getMessage(o),
+            raw: o
+        });
+
+        // blow up if no successProperty
+        if (Ext.isEmpty(res.success)) {
+            throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty);
+        }
+        return res;
+    },
 
     /**
      * Create a data block containing Ext.data.Records from a JSON object.
@@ -33345,16 +34183,11 @@ Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
          */
         this.jsonData = o;
         if(o.metaData){
-            delete this.ef;
-            this.meta = o.metaData;
-            this.recordType = Ext.data.Record.create(o.metaData.fields);
-            this.onMetaChange(this.meta, this.recordType, o);
+            this.onMetaChange(o.metaData);
         }
         var s = this.meta, Record = this.recordType,
             f = Record.prototype.fields, fi = f.items, fl = f.length, v;
 
-        // Generate extraction functions for the totalProperty, the root, the id, and for each field
-        this.buildExtractors();
         var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
         if(s.totalProperty){
             v = parseInt(this.getTotal(o), 10);
@@ -33369,16 +34202,10 @@ Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
             }
         }
 
-        var records = [];
-        for(var i = 0; i < c; i++){
-            var n = root[i];
-            var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
-            record.json = n;
-            records[i] = record;
-        }
+        // TODO return Ext.data.Response instance instead.  @see #readResponse
         return {
             success : success,
-            records : records,
+            records : this.extractData(root, true), // <-- true to return [Ext.data.Record]
             totalRecords : totalRecords
         };
     },
@@ -33392,17 +34219,20 @@ Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
             f = Record.prototype.fields, fi = f.items, fl = f.length;
 
         if(s.totalProperty) {
-            this.getTotal = this.getJsonAccessor(s.totalProperty);
+            this.getTotal = this.createAccessor(s.totalProperty);
         }
         if(s.successProperty) {
-            this.getSuccess = this.getJsonAccessor(s.successProperty);
+            this.getSuccess = this.createAccessor(s.successProperty);
+        }
+        if (s.messageProperty) {
+            this.getMessage = this.createAccessor(s.messageProperty);
         }
-        this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
+        this.getRoot = s.root ? this.createAccessor(s.root) : function(p){return p;};
         if (s.id || s.idProperty) {
-            var g = this.getJsonAccessor(s.id || s.idProperty);
+            var g = this.createAccessor(s.id || s.idProperty);
             this.getId = function(rec) {
                 var r = g(rec);
-                return (r === undefined || r === "") ? null : r;
+                return (r === undefined || r === '') ? null : r;
             };
         } else {
             this.getId = function(){return null;};
@@ -33411,47 +34241,85 @@ Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
         for(var i = 0; i < fl; i++){
             f = fi[i];
             var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
-            ef.push(this.getJsonAccessor(map));
+            ef.push(this.createAccessor(map));
         }
         this.ef = ef;
     },
 
-    // private extractValues
-    extractValues: function(data, items, len) {
-        var f, values = {};
-        for(var j = 0; j < len; j++){
-            f = items[j];
-            var v = this.ef[j](data);
-            values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
-        }
-        return values;
+    /**
+     * @ignore
+     * TODO This isn't used anywhere??  Don't we want to use this where possible instead of complex #createAccessor?
+     */
+    simpleAccess : function(obj, subsc) {
+        return obj[subsc];
     },
 
     /**
-     * Decode a json response from server.
-     * @param {String} action [Ext.data.Api.actions.create|read|update|destroy]
-     * @param {Object} response
+     * @ignore
      */
-    readResponse : function(action, response) {
-        var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response;
-        if(!o) {
-            throw new Ext.data.JsonReader.Error('response');
-        }
-        if (Ext.isEmpty(o[this.meta.successProperty])) {
-            throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty);
-        }
-        // TODO, separate empty and undefined exceptions.
-        if ((action === Ext.data.Api.actions.create || action === Ext.data.Api.actions.update)) {
-            if (Ext.isEmpty(o[this.meta.root])) {
-                throw new Ext.data.JsonReader.Error('root-emtpy', this.meta.root);
+    createAccessor : function(){
+        var re = /[\[\.]/;
+        return function(expr) {
+            try {
+                return(re.test(expr)) ?
+                new Function('obj', 'return obj.' + expr) :
+                function(obj){
+                    return obj[expr];
+                };
+            } catch(e){}
+            return Ext.emptyFn;
+        };
+    }(),
+
+    /**
+     * returns extracted, type-cast rows of data.  Iterates to call #extractValues for each row
+     * @param {Object[]/Object} data-root from server response
+     * @param {Boolean} returnRecords [false] Set true to return instances of Ext.data.Record
+     * @private
+     */
+    extractData : function(root, returnRecords) {
+        var rs = undefined;
+        if (this.isData(root)) {
+            root = [root];
+        }
+        if (Ext.isArray(root)) {
+            var f       = this.recordType.prototype.fields,
+                fi      = f.items,
+                fl      = f.length,
+                rs      = [];
+            if (returnRecords === true) {
+                var Record = this.recordType;
+                for (var i = 0; i < root.length; i++) {
+                    var n = root[i];
+                    var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
+                    record.json = n;
+                    rs.push(record);
+                }
             }
-            else if (o[this.meta.root] === undefined) {
-                throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
+            else {
+                for (var i = 0; i < root.length; i++) {
+                    rs.push(this.extractValues(root[i], fi, fl));
+                }
             }
         }
-        // make sure extraction functions are defined.
-        this.ef = this.buildExtractors();
-        return o;
+        return rs;
+    },
+
+    /**
+     * type-casts a single row of raw-data from server
+     * @param {Object} data
+     * @param {Array} items
+     * @param {Integer} len
+     * @private
+     */
+    extractValues : function(data, items, len) {
+        var f, values = {};
+        for(var j = 0; j < len; j++){
+            f = items[j];
+            var v = this.ef[j](data);
+            values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
+        }
+        return values;
     }
 });
 
@@ -33468,12 +34336,11 @@ Ext.data.JsonReader.Error = Ext.extend(Ext.Error, {
 });
 Ext.apply(Ext.data.JsonReader.Error.prototype, {
     lang: {
-        'response': "An error occurred while json-decoding your server response",
+        'response': 'An error occurred while json-decoding your server response',
         'successProperty-response': 'Could not locate your "successProperty" in your server response.  Please review your JsonReader config to ensure the config-property "successProperty" matches the property in your server-response.  See the JsonReader docs.',
-        'root-undefined-response': 'Could not locate your "root" property in your server response.  Please review your JsonReader config to ensure the config-property "root" matches the property your server-response.  See the JsonReader docs.',
         'root-undefined-config': 'Your JsonReader was configured without a "root" property.  Please review your JsonReader config and make sure to define the root property.  See the JsonReader docs.',
         'idProperty-undefined' : 'Your JsonReader was configured without an "idProperty"  Please review your JsonReader configuration and ensure the "idProperty" is set (e.g.: "id").  See the JsonReader docs.',
-        'root-emtpy': 'Data was expected to be returned by the server in the "root" property of the response.  Please review your JsonReader configuration to ensure the "root" property matches that returned in the server-response.  See JsonReader docs.'
+        'root-empty': 'Data was expected to be returned by the server in the "root" property of the response.  Please review your JsonReader configuration to ensure the "root" property matches that returned in the server-response.  See JsonReader docs.'
     }
 });
 /**
@@ -33541,13 +34408,13 @@ Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
 
         var root = this.getRoot(o);
 
-        for(var i = 0; i < root.length; i++) {
-            var n = root[i];
-            var values = {};
-            var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
+        for(var i = 0, len = root.length; i < len; i++) {
+            var n = root[i],
+                values = {},
+                id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
             for(var j = 0, jlen = fields.length; j < jlen; j++) {
-                var f = fields.items[j];
-                var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
+                var f = fields.items[j],
+                    k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
                 v = n[k] !== undefined ? n[k] : f.defaultValue;
                 v = f.convert(v, n);
                 values[f.name] = v;
@@ -33647,7 +34514,7 @@ var store = new Ext.data.JsonStore({
     storeId: 'myStore',
     // reader configs
     root: 'images',
-    idProperty: 'name',  
+    idProperty: 'name',
     fields: ['name', 'url', {name:'size', type: 'float'}, {name:'lastmod', type:'date'}]
 });
  * </code></pre></p>
@@ -33660,7 +34527,7 @@ var store = new Ext.data.JsonStore({
 }
  * </code></pre>
  * An object literal of this form could also be used as the {@link #data} config option.</p>
- * <p><b>*Note:</b> Although not listed here, this class accepts all of the configuration options of 
+ * <p><b>*Note:</b> Although not listed here, this class accepts all of the configuration options of
  * <b>{@link Ext.data.JsonReader JsonReader}</b>.</p>
  * @constructor
  * @param {Object} config
@@ -33681,40 +34548,129 @@ Ext.reg('jsonstore', Ext.data.JsonStore);/**
  * @extends Ext.data.DataWriter
  * DataWriter extension for writing an array or single {@link Ext.data.Record} object(s) in preparation for executing a remote CRUD action via XML.
  */
-Ext.data.XmlWriter = Ext.extend(Ext.data.DataWriter, {
+Ext.data.XmlWriter = function(params) {
+    Ext.data.XmlWriter.superclass.constructor.apply(this, arguments);
+    this.tpl = new Ext.XTemplate(this.tpl).compile();
+};
+Ext.extend(Ext.data.XmlWriter, Ext.data.DataWriter, {
+    /**
+     * @cfg {String} root [records] The name of the root element when writing <b>multiple</b> records to the server.  Each
+     * xml-record written to the server will be wrapped in an element named after {@link Ext.data.XmlReader#record} property.
+     * eg:
+<code><pre>
+&lt;?xml version="1.0" encoding="UTF-8"?>
+&lt;user>&lt;first>Barney&lt;/first>&lt;/user>
+</code></pre>
+     * However, when <b>multiple</b> records are written in a batch-operation, these records must be wrapped in a containing
+     * Element.
+     * eg:
+<code><pre>
+&lt;?xml version="1.0" encoding="UTF-8"?>
+    &lt;records>
+        &lt;first>Barney&lt;/first>&lt;/user>
+        &lt;records>&lt;first>Barney&lt;/first>&lt;/user>
+    &lt;/records>
+</code></pre>
+     * Defaults to <tt>records</tt>
+     */
+    root: 'records',
+    /**
+     * @cfg {String} xmlVersion [1.0] The <tt>version</tt> written to header of xml documents.
+<code><pre>&lt;?xml version="1.0" encoding="ISO-8859-15"?></pre></code>
+     */
+    xmlVersion : '1.0',
+    /**
+     * @cfg {String} xmlEncoding [ISO-8859-15] The <tt>encoding</tt> written to header of xml documents.
+<code><pre>&lt;?xml version="1.0" encoding="ISO-8859-15"?></pre></code>
+     */
+    xmlEncoding: 'ISO-8859-15',
+    /**
+     * @cfg {String} tpl The xml template.  Defaults to
+<code><pre>
+&lt;?xml version="{version}" encoding="{encoding}"?>
+    &lt;tpl if="{[values.nodes.length>1]}">&lt;{root}}>',
+    &lt;tpl for="records">
+        &lt;{parent.record}>
+        &lt;tpl for="fields">
+            &lt;{name}>{value}&lt;/{name}>
+        &lt;/tpl>
+        &lt;/{parent.record}>
+    &lt;/tpl>
+    &lt;tpl if="{[values.records.length>1]}">&lt;/{root}}>&lt;/tpl>
+</pre></code>
+     */
+    // Break up encoding here in case it's being included by some kind of page that will parse it (eg. PHP)
+    tpl: '<tpl for="."><' + '?xml version="{version}" encoding="{encoding}"?' + '><tpl if="documentRoot"><{documentRoot}><tpl for="baseParams"><tpl for="."><{name}>{value}</{name}</tpl></tpl></tpl><tpl if="records.length&gt;1"><{root}></tpl><tpl for="records"><{parent.record}><tpl for="."><{name}>{value}</{name}></tpl></{parent.record}></tpl><tpl if="records.length&gt;1"></{root}></tpl><tpl if="documentRoot"></{documentRoot}></tpl></tpl>',
+
     /**
      * Final action of a write event.  Apply the written data-object to params.
      * @param {String} action [Ext.data.Api.create|read|update|destroy]
-     * @param {Record[]} rs
+     * @param {Ext.data.Record/Ext.data.Record[]} rs
      * @param {Object} http params
-     * @param {Object} data object populated according to DataReader meta-data "root" and "idProperty"
+     * @param {Object/Object[]} rendered data.
      */
     render : function(action, rs, params, data) {
-        // no impl.
+        params.xmlData = this.tpl.applyTemplate({
+            version: this.xmlVersion,
+            encoding: this.xmlEncoding,
+            record: this.meta.record,
+            root: this.root,
+            records: (Ext.isArray(rs)) ? data : [data]
+        });
+    },
+
+    /**
+     * Converts an Ext.data.Record to xml
+     * @param {Ext.data.Record} rec
+     * @return {String} rendered xml-element
+     * @private
+     */
+    toXml : function(data) {
+        var fields = [];
+        Ext.iterate(data, function(k, v) {
+            fields.push({
+                name: k,
+                value: v
+            });
+        },this);
+        return {
+            fields: fields
+        };
     },
+
     /**
      * createRecord
      * @param {Ext.data.Record} rec
+     * @return {String} xml element
+     * @private
      */
     createRecord : function(rec) {
-        // no impl
+        return this.toXml(this.toHash(rec));
     },
+
     /**
      * updateRecord
      * @param {Ext.data.Record} rec
+     * @return {String} xml element
+     * @private
      */
     updateRecord : function(rec) {
-        // no impl.
+        return this.toXml(this.toHash(rec));
 
     },
     /**
      * destroyRecord
      * @param {Ext.data.Record} rec
+     * @return {String} xml element
      */
     destroyRecord : function(rec) {
-        // no impl
+        var data = {};
+        data[this.meta.idProperty] = rec.id;
+        return this.toXml(data);
     }
-});/**
+});
+
+/**
  * @class Ext.data.XmlReader
  * @extends Ext.data.DataReader
  * <p>Data reader class to create an Array of {@link Ext.data.Record} objects from an XML document
@@ -33728,9 +34684,10 @@ var Employee = Ext.data.Record.create([
    {name: 'occupation'}                 // This field will use "occupation" as the mapping.
 ]);
 var myReader = new Ext.data.XmlReader({
-   totalRecords: "results", // The element which contains the total dataset size (optional)
+   totalProperty: "results", // The element which contains the total dataset size (optional)
    record: "row",           // The repeated element which contains row information
-   id: "id"                 // The element within the row that provides an ID for the record (optional)
+   idProperty: "id"         // The element within the row that provides an ID for the record (optional)
+   messageProperty: "msg"   // The element within the response that provides a user-feedback message (optional)
 }, Employee);
 </code></pre>
  * <p>
@@ -33751,11 +34708,12 @@ var myReader = new Ext.data.XmlReader({
  &lt;/row>
 &lt;/dataset>
 </code></pre>
- * @cfg {String} totalRecords The DomQuery path from which to retrieve the total number of records
+ * @cfg {String} totalProperty The DomQuery path from which to retrieve the total number of records
  * in the dataset. This is only needed if the whole dataset is not passed in one go, but is being
  * paged from the remote server.
  * @cfg {String} record The DomQuery path to the repeated element which contains record information.
- * @cfg {String} success The DomQuery path to the success attribute used by forms.
+ * @cfg {String} record The DomQuery path to the repeated element which contains record information.
+ * @cfg {String} successProperty The DomQuery path to the success attribute used by forms.
  * @cfg {String} idPath The DomQuery path relative from the record element to the element that contains
  * a record identifier value.
  * @constructor
@@ -33766,6 +34724,10 @@ var myReader = new Ext.data.XmlReader({
  */
 Ext.data.XmlReader = function(meta, recordType){
     meta = meta || {};
+
+    // backwards compat, convert idPath to idProperty
+    meta.idProperty = meta.idProperty || meta.idPath;
+
     Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);
 };
 Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
@@ -33796,36 +34758,22 @@ Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
          * @type XMLDocument
          */
         this.xmlData = doc;
-        var root = doc.documentElement || doc;
-        var q = Ext.DomQuery;
-        var recordType = this.recordType, fields = recordType.prototype.fields;
-        var sid = this.meta.idPath || this.meta.id;
-        var totalRecords = 0, success = true;
-        if(this.meta.totalRecords){
-            totalRecords = q.selectNumber(this.meta.totalRecords, root, 0);
-        }
-
-        if(this.meta.success){
-            var sv = q.selectValue(this.meta.success, root, true);
-            success = sv !== false && sv !== 'false';
-        }
-        var records = [];
-        var ns = q.select(this.meta.record, root);
-        for(var i = 0, len = ns.length; i < len; i++) {
-            var n = ns[i];
-            var values = {};
-            var id = sid ? q.selectValue(sid, n) : undefined;
-            for(var j = 0, jlen = fields.length; j < jlen; j++){
-                var f = fields.items[j];
-                var v = q.selectValue(Ext.value(f.mapping, f.name, true), n, f.defaultValue);
-                v = f.convert(v, n);
-                values[f.name] = v;
-            }
-            var record = new recordType(values, id);
-            record.node = n;
-            records[records.length] = record;
+
+        var root    = doc.documentElement || doc,
+            q       = Ext.DomQuery,
+            totalRecords = 0,
+            success = true;
+
+        if(this.meta.totalProperty){
+            totalRecords = this.getTotal(root, 0);
+        }
+        if(this.meta.successProperty){
+            success = this.getSuccess(root);
         }
 
+        var records = this.extractData(q.select(this.meta.record, root), true); // <-- true to return Ext.data.Record[]
+
+        // TODO return Ext.data.Response instance.  @see #readResponse
         return {
             success : success,
             records : records,
@@ -33833,8 +34781,167 @@ Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
         };
     },
 
-    // TODO: implement readResponse for XmlReader
-    readResponse : Ext.emptyFn
+    /**
+     * Decode a json response from server.
+     * @param {String} action [{@link Ext.data.Api#actions} create|read|update|destroy]
+     * @param {Ext.data.Response} response Returns an instance of {@link Ext.data.Response}
+     */
+    readResponse : function(action, response) {
+        var q   = Ext.DomQuery,
+        doc     = response.responseXML;
+
+        var res = new Ext.data.Response({
+            action: action,
+            success : this.getSuccess(doc),
+            message: this.getMessage(doc),
+            data: this.extractData(q.select(this.meta.record, doc) || q.select(this.meta.root, doc)),
+            raw: doc
+        });
+
+        if (Ext.isEmpty(res.success)) {
+            throw new Ext.data.DataReader.Error('successProperty-response', this.meta.successProperty);
+        }
+
+        if (action === Ext.data.Api.actions.create) {
+            var def = Ext.isDefined(res.data);
+            if (def && Ext.isEmpty(res.data)) {
+                throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
+            }
+            else if (!def) {
+                throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
+            }
+        }
+        return res;
+    },
+
+    getSuccess : function() {
+        return true;
+    },
+
+    /**
+     * build response-data extractor functions.
+     * @private
+     * @ignore
+     */
+    buildExtractors : function() {
+        if(this.ef){
+            return;
+        }
+        var s       = this.meta,
+            Record  = this.recordType,
+            f       = Record.prototype.fields,
+            fi      = f.items,
+            fl      = f.length;
+
+        if(s.totalProperty) {
+            this.getTotal = this.createAccessor(s.totalProperty);
+        }
+        if(s.successProperty) {
+            this.getSuccess = this.createAccessor(s.successProperty);
+        }
+        if (s.messageProperty) {
+            this.getMessage = this.createAccessor(s.messageProperty);
+        }
+        this.getRoot = function(res) {
+            return (!Ext.isEmpty(res[this.meta.record])) ? res[this.meta.record] : res[this.meta.root];
+        }
+        if (s.idPath || s.idProperty) {
+            var g = this.createAccessor(s.idPath || s.idProperty);
+            this.getId = function(rec) {
+                var id = g(rec) || rec.id;
+                return (id === undefined || id === '') ? null : id;
+            };
+        } else {
+            this.getId = function(){return null;};
+        }
+        var ef = [];
+        for(var i = 0; i < fl; i++){
+            f = fi[i];
+            var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
+            ef.push(this.createAccessor(map));
+        }
+        this.ef = ef;
+    },
+
+    /**
+     * Creates a function to return some particular key of data from a response.
+     * @param {String} key
+     * @return {Function}
+     * @private
+     * @ignore
+     */
+    createAccessor : function(){
+        var q = Ext.DomQuery;
+        return function(key) {
+            switch(key) {
+                case this.meta.totalProperty:
+                    return function(root, def){
+                        return q.selectNumber(key, root, def);
+                    }
+                    break;
+                case this.meta.successProperty:
+                    return function(root, def) {
+                        var sv = q.selectValue(key, root, true);
+                        var success = sv !== false && sv !== 'false';
+                        return success;
+                    }
+                    break;
+                default:
+                    return function(root, def) {
+                        return q.selectValue(key, root, def);
+                    }
+                    break;
+            }
+        };
+    }(),
+
+    /**
+     * Extracts rows of record-data from server.  iterates and calls #extractValues
+     * TODO I don't care much for method-names of #extractData, #extractValues.
+     * @param {Array} root
+     * @param {Boolean} returnRecords When true, will return instances of Ext.data.Record; otherwise just hashes.
+     * @private
+     * @ignore
+     */
+    extractData : function(root, returnRecords) {
+        var Record  = this.recordType,
+        records     = [],
+        f           = Record.prototype.fields,
+        fi          = f.items,
+        fl          = f.length;
+        if (returnRecords === true) {
+            for (var i = 0, len = root.length; i < len; i++) {
+                var data = root[i],
+                    record = new Record(this.extractValues(data, fi, fl), this.getId(data));
+                    
+                record.node = data;
+                records.push(record);
+            }
+        } else {
+            for (var i = 0, len = root.length; i < len; i++) {
+                records.push(this.extractValues(root[i], fi, fl));
+            }
+        }
+        return records;
+    },
+
+    /**
+     * extracts values and type-casts a row of data from server, extracted by #extractData
+     * @param {Hash} data
+     * @param {Ext.data.Field[]} items
+     * @param {Number} len
+     * @private
+     * @ignore
+     */
+    extractValues : function(data, items, len) {
+        var f, values = {};
+        for(var j = 0; j < len; j++){
+            f = items[j];
+            var v = this.ef[j](data);
+            values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
+        }
+        return values;
+    }
 });/**\r
  * @class Ext.data.XmlStore\r
  * @extends Ext.data.Store\r
@@ -34083,31 +35190,35 @@ paramOrder: 'param1|param2|param'
 \r
         switch (action) {\r
             case Ext.data.Api.actions.create:\r
-                args.push(params[reader.meta.root]);           // <-- create(Hash)\r
+                args.push(params.jsonData[reader.meta.root]);          // <-- create(Hash)\r
                 break;\r
             case Ext.data.Api.actions.read:\r
-                if(this.paramOrder){\r
-                    for(var i = 0, len = this.paramOrder.length; i < len; i++){\r
-                        args.push(params[this.paramOrder[i]]);\r
+                // If the method has no parameters, ignore the paramOrder/paramsAsHash.\r
+                if(directFn.directCfg.method.len > 0){\r
+                    if(this.paramOrder){\r
+                        for(var i = 0, len = this.paramOrder.length; i < len; i++){\r
+                            args.push(params[this.paramOrder[i]]);\r
+                        }\r
+                    }else if(this.paramsAsHash){\r
+                        args.push(params);\r
                     }\r
-                }else if(this.paramsAsHash){\r
-                    args.push(params);\r
                 }\r
                 break;\r
             case Ext.data.Api.actions.update:\r
-                args.push(params[reader.meta.idProperty]);  // <-- save(Integer/Integer[], Hash/Hash[])\r
-                args.push(params[reader.meta.root]);\r
+                args.push(params.jsonData[reader.meta.root]);        // <-- update(Hash/Hash[])\r
                 break;\r
             case Ext.data.Api.actions.destroy:\r
-                args.push(params[reader.meta.root]);        // <-- destroy(Int/Int[])\r
+                args.push(params.jsonData[reader.meta.root]);        // <-- destroy(Int/Int[])\r
                 break;\r
         }\r
 \r
         var trans = {\r
             params : params || {},\r
-            callback : callback,\r
-            scope : scope,\r
-            arg : options,\r
+            request: {\r
+                callback : callback,\r
+                scope : scope,\r
+                arg : options\r
+            },\r
             reader: reader\r
         };\r
 \r
@@ -34124,7 +35235,7 @@ paramOrder: 'param1|param2|param'
                     this.fireEvent("loadexception", this, trans, res, null);\r
                 }\r
                 this.fireEvent('exception', this, 'remote', action, trans, res, null);\r
-                trans.callback.call(trans.scope, null, trans.arg, false);\r
+                trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);\r
                 return;\r
             }\r
             if (action === Ext.data.Api.actions.read) {\r
@@ -34151,11 +35262,11 @@ paramOrder: 'param1|param2|param'
             this.fireEvent("loadexception", this, trans, res, ex);\r
 \r
             this.fireEvent('exception', this, 'response', action, trans, res, ex);\r
-            trans.callback.call(trans.scope, null, trans.arg, false);\r
+            trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);\r
             return;\r
         }\r
-        this.fireEvent("load", this, res, trans.arg);\r
-        trans.callback.call(trans.scope, records, trans.arg, true);\r
+        this.fireEvent("load", this, res, trans.request.arg);\r
+        trans.request.callback.call(trans.request.scope, records, trans.request.arg, true);\r
     },\r
     /**\r
      * Callback for write actions\r
@@ -34165,8 +35276,9 @@ paramOrder: 'param1|param2|param'
      * @private\r
      */\r
     onWrite : function(action, trans, result, res, rs) {\r
-        this.fireEvent("write", this, action, result, res, rs, trans.arg);\r
-        trans.callback.call(trans.scope, result, res, true);\r
+        var data = trans.reader.extractData(result);\r
+        this.fireEvent("write", this, action, data, res, rs, trans.request.arg);\r
+        trans.request.callback.call(trans.request.scope, data, res, true);\r
     }\r
 });\r
 \r
@@ -34881,9 +35993,15 @@ TestAction.multiply(
     \r
     /**\r
      * @cfg {Number} maxRetries\r
-     * Number of times to re-attempt delivery on failure of a call.\r
+     * Number of times to re-attempt delivery on failure of a call. Defaults to <tt>1</tt>.\r
      */\r
     maxRetries: 1,\r
+    \r
+    /**\r
+     * @cfg {Number} timeout\r
+     * The timeout to use for each request. Defaults to <tt>undefined</tt>.\r
+     */\r
+    timeout: undefined,\r
 \r
     constructor : function(config){\r
         Ext.direct.RemotingProvider.superclass.constructor.call(this, config);\r
@@ -34896,7 +36014,7 @@ TestAction.multiply(
              * @param {Ext.direct.RemotingProvider} provider\r
              * @param {Ext.Direct.Transaction} transaction\r
              */            \r
-            'beforecall',\r
+            'beforecall',            \r
             /**\r
              * @event call\r
              * Fires immediately after the request to the server-side is sent. This does\r
@@ -34906,7 +36024,7 @@ TestAction.multiply(
              */            \r
             'call'\r
         );\r
-        this.namespace = (typeof this.namespace === 'string') ? Ext.ns(this.namespace) : this.namespace || window;\r
+        this.namespace = (Ext.isString(this.namespace)) ? Ext.ns(this.namespace) : this.namespace || window;\r
         this.transactions = {};\r
         this.callBuffer = [];\r
     },\r
@@ -34915,8 +36033,8 @@ TestAction.multiply(
     initAPI : function(){\r
         var o = this.actions;\r
         for(var c in o){\r
-            var cls = this.namespace[c] || (this.namespace[c] = {});\r
-            var ms = o[c];\r
+            var cls = this.namespace[c] || (this.namespace[c] = {}),\r
+                ms = o[c];\r
             for(var i = 0, len = ms.length; i < len; i++){\r
                 var m = ms[i];\r
                 cls[m.name] = this.createMethod(c, m);\r
@@ -34950,8 +36068,8 @@ TestAction.multiply(
         if(success){\r
             var events = this.getEvents(xhr);\r
             for(var i = 0, len = events.length; i < len; i++){\r
-                var e = events[i];\r
-                var t = this.getTransaction(e);\r
+                var e = events[i],\r
+                    t = this.getTransaction(e);\r
                 this.fireEvent('data', this, e);\r
                 if(t){\r
                     this.doCallback(t, e, true);\r
@@ -34997,11 +36115,10 @@ TestAction.multiply(
             url: this.url,\r
             callback: this.onData,\r
             scope: this,\r
-            ts: data\r
-        };\r
+            ts: data,\r
+            timeout: this.timeout\r
+        }, callData;\r
 \r
-        // send only needed data\r
-        var callData;\r
         if(Ext.isArray(data)){\r
             callData = [];\r
             for(var i = 0, len = data.length; i < len; i++){\r
@@ -35013,7 +36130,7 @@ TestAction.multiply(
 \r
         if(this.enableUrlEncode){\r
             var params = {};\r
-            params[typeof this.enableUrlEncode == 'string' ? this.enableUrlEncode : 'data'] = Ext.encode(callData);\r
+            params[Ext.isString(this.enableUrlEncode) ? this.enableUrlEncode : 'data'] = Ext.encode(callData);\r
             o.params = params;\r
         }else{\r
             o.jsonData = callData;\r
@@ -35039,7 +36156,7 @@ TestAction.multiply(
             if(!this.callTask){\r
                 this.callTask = new Ext.util.DelayedTask(this.combineAndSend, this);\r
             }\r
-            this.callTask.delay(typeof this.enableBuffer == 'number' ? this.enableBuffer : 10);\r
+            this.callTask.delay(Ext.isNumber(this.enableBuffer) ? this.enableBuffer : 10);\r
         }else{\r
             this.combineAndSend();\r
         }\r
@@ -35138,8 +36255,8 @@ TestAction.multiply(
     doCallback: function(t, e){\r
         var fn = e.status ? 'success' : 'failure';\r
         if(t && t.cb){\r
-            var hs = t.cb;\r
-            var result = e.result || e.data;\r
+            var hs = t.cb,\r
+                result = Ext.isDefined(e.result) ? e.result : e.data;\r
             if(Ext.isFunction(hs)){\r
                 hs(result, e);\r
             } else{\r
@@ -35909,7 +37026,7 @@ Ext.Resizable.Handle.prototype = {
  * <p>A specialized panel intended for use as an application window.  Windows are floated, {@link #resizable}, and
  * {@link #draggable} by default.  Windows can be {@link #maximizable maximized} to fill the viewport,
  * restored to their prior size, and can be {@link #minimize}d.</p>
- * <p>Windows can also be linked to a {@link Ext.WindowGroup} or managed by the {@link Ext.WindowMgr} to provide 
+ * <p>Windows can also be linked to a {@link Ext.WindowGroup} or managed by the {@link Ext.WindowMgr} to provide
  * grouping, activation, to front, to back and other application-specific behavior.</p>
  * <p>By default, Windows will be rendered to document.body. To {@link #constrain} a Window to another element
  * specify {@link Ext.Component#renderTo renderTo}.</p>
@@ -35961,15 +37078,15 @@ Ext.Window = Ext.extend(Ext.Panel, {
     */
     /**
      * @cfg {Boolean} collapsed
-     * True to render the window collapsed, false to render it expanded (defaults to false). Note that if 
-     * {@link #expandOnShow} is true (the default) it will override the <tt>collapsed</tt> config and the window 
+     * True to render the window collapsed, false to render it expanded (defaults to false). Note that if
+     * {@link #expandOnShow} is true (the default) it will override the <tt>collapsed</tt> config and the window
      * will always be expanded when shown.
      */
     /**
      * @cfg {Boolean} maximized
      * True to initially display the window in a maximized state. (Defaults to false).
      */
-    
+
     /**
     * @cfg {String} baseCls
     * The base CSS class to apply to this panel's element (defaults to 'x-window').
@@ -36021,15 +37138,15 @@ Ext.Window = Ext.extend(Ext.Panel, {
     /**
      * @cfg {Boolean} constrain
      * True to constrain the window within its containing element, false to allow it to fall outside of its
-     * containing element. By default the window will be rendered to document.body.  To render and constrain the 
+     * containing element. By default the window will be rendered to document.body.  To render and constrain the
      * window within another element specify {@link #renderTo}.
      * (defaults to false).  Optionally the header only can be constrained using {@link #constrainHeader}.
      */
     constrain : false,
     /**
      * @cfg {Boolean} constrainHeader
-     * True to constrain the window header within its containing element (allowing the window body to fall outside 
-     * of its containing element) or false to allow the header to fall outside its containing element (defaults to 
+     * True to constrain the window header within its containing element (allowing the window body to fall outside
+     * of its containing element) or false to allow the header to fall outside its containing element (defaults to
      * false). Optionally the entire window can be constrained using {@link #constrain}.
      */
     constrainHeader : false,
@@ -36079,8 +37196,17 @@ Ext.Window = Ext.extend(Ext.Panel, {
     /**
      * @cfg {Boolean} initHidden
      * True to hide the window until show() is explicitly called (defaults to true).
+     * @deprecated
+     */
+    initHidden : undefined,
+    
+    /**
+     * @cfg {Boolean} hidden
+     * Render this component hidden (default is <tt>true</tt>). If <tt>true</tt>, the
+     * {@link #hide} method will be called internally.
      */
-    initHidden : true,
+    hidden : true,
+    
     /**
     * @cfg {Boolean} monitorResize @hide
     * This is automatically managed based on the value of constrain and constrainToHeader
@@ -36100,16 +37226,17 @@ Ext.Window = Ext.extend(Ext.Panel, {
 
     // private
     initComponent : function(){
+        this.initTools();
         Ext.Window.superclass.initComponent.call(this);
         this.addEvents(
             /**
              * @event activate
-             * Fires after the window has been visually activated via {@link setActive}.
+             * Fires after the window has been visually activated via {@link #setActive}.
              * @param {Ext.Window} this
              */
             /**
              * @event deactivate
-             * Fires after the window has been visually deactivated via {@link setActive}.
+             * Fires after the window has been visually deactivated via {@link #setActive}.
              * @param {Ext.Window} this
              */
             /**
@@ -36139,10 +37266,13 @@ Ext.Window = Ext.extend(Ext.Panel, {
              */
             'restore'
         );
-        if(this.initHidden === false){
-            this.show();
-        }else{
+        // for backwards compat, this should be removed at some point
+        if(Ext.isDefined(this.initHidden)){
+            this.hidden = this.initHidden;
+        }
+        if(this.hidden === false){
             this.hidden = true;
+            this.show();
         }
     },
 
@@ -36174,7 +37304,9 @@ Ext.Window = Ext.extend(Ext.Panel, {
             this.mask.hide();
             this.mon(this.mask, 'click', this.focus, this);
         }
-        this.initTools();
+        if(this.maximizable){
+            this.mon(this.header, 'dblclick', this.toggleMaximize, this);
+        }
     },
 
     // private
@@ -36273,7 +37405,6 @@ Ext.Window = Ext.extend(Ext.Panel, {
                 handler: this.restore.createDelegate(this, []),
                 hidden:true
             });
-            this.mon(this.header, 'dblclick', this.toggleMaximize, this);
         }
         if(this.closable){
             this.addTool({
@@ -36318,7 +37449,6 @@ Ext.Window = Ext.extend(Ext.Panel, {
         this.updateHandles();
         this.saveState();
         this.doLayout();
-        this.fireEvent('resize', this, box.width, box.height);
     },
 
     /**
@@ -36327,10 +37457,10 @@ Ext.Window = Ext.extend(Ext.Panel, {
      */
     focus : function(){
         var f = this.focusEl, db = this.defaultButton, t = typeof db;
-        if(t != 'undefined'){
-            if(t == 'number' && this.fbar){
+        if(Ext.isDefined(db)){
+            if(Ext.isNumber(db) && this.fbar){
                 f = this.fbar.items.get(db);
-            }else if(t == 'string'){
+            }else if(Ext.isString(db)){
                 f = Ext.getCmp(db);
             }else{
                 f = db;
@@ -36395,7 +37525,7 @@ Ext.Window = Ext.extend(Ext.Panel, {
             this.on('show', cb, scope, {single:true});
         }
         this.hidden = false;
-        if(animateTarget !== undefined){
+        if(Ext.isDefined(animateTarget)){
             this.setAnimateTarget(animateTarget);
         }
         this.beforeShow();
@@ -36441,15 +37571,15 @@ Ext.Window = Ext.extend(Ext.Panel, {
         this.proxy.show();
         this.proxy.setBox(this.animateTarget.getBox());
         this.proxy.setOpacity(0);
-        var b = this.getBox(false);
-        b.callback = this.afterShow.createDelegate(this, [true], false);
-        b.scope = this;
-        b.duration = 0.25;
-        b.easing = 'easeNone';
-        b.opacity = 0.5;
-        b.block = true;
+        var b = this.getBox();
         this.el.setStyle('display', 'none');
-        this.proxy.shift(b);
+        this.proxy.shift(Ext.apply(b, {
+            callback: this.afterShow.createDelegate(this, [true], false),
+            scope: this,
+            easing: 'easeNone',
+            duration: 0.25,
+            opacity: 0.5
+        }));
     },
 
     /**
@@ -36503,14 +37633,13 @@ Ext.Window = Ext.extend(Ext.Panel, {
         var tb = this.getBox(false);
         this.proxy.setBox(tb);
         this.el.hide();
-        var b = this.animateTarget.getBox();
-        b.callback = this.afterHide;
-        b.scope = this;
-        b.duration = 0.25;
-        b.easing = 'easeNone';
-        b.block = true;
-        b.opacity = 0;
-        this.proxy.shift(b);
+        this.proxy.shift(Ext.apply(this.animateTarget.getBox(), {
+            callback: this.afterHide,
+            scope: this,
+            duration: 0.25,
+            easing: 'easeNone',
+            opacity: 0
+        }));
     },
 
     // private
@@ -36603,12 +37732,19 @@ Ext.Window = Ext.extend(Ext.Panel, {
      */
     close : function(){
         if(this.fireEvent('beforeclose', this) !== false){
-            this.hide(null, function(){
-                this.fireEvent('close', this);
-                this.destroy();
-            }, this);
+            if(this.hidden){
+                this.doClose();
+            }else{
+                this.hide(null, this.doClose, this);
+            }
         }
     },
+    
+    // private
+    doClose : function(){
+        this.fireEvent('close', this);
+        this.destroy();
+    },
 
     /**
      * Fits the window within its current container and automatically replaces
@@ -36739,7 +37875,7 @@ Ext.Window = Ext.extend(Ext.Panel, {
           this.alignTo(el, alignment, offsets);
       };
       Ext.EventManager.onWindowResize(this.doAnchor, this);
-      
+
       var tm = typeof monitorScroll;
       if(tm != 'undefined'){
           Ext.EventManager.on(window, 'scroll', this.doAnchor, this,
@@ -36765,7 +37901,8 @@ Ext.Window = Ext.extend(Ext.Panel, {
 
     /**
      * Makes this the active window by showing its shadow, or deactivates it by hiding its shadow.  This method also
-     * fires the {@link #activate} or {@link #deactivate} event depending on which action occurred.
+     * fires the {@link #activate} or {@link #deactivate} event depending on which action occurred. This method is
+     * called internally by {@link Ext.WindowMgr}.
      * @param {Boolean} active True to activate the window, false to deactivate it (defaults to false)
      */
     setActive : function(active){
@@ -37018,698 +38155,704 @@ Ext.WindowGroup = function(){
  * with separate z-order stacks, create additional instances of {@link Ext.WindowGroup} as needed.
  * @singleton
  */
-Ext.WindowMgr = new Ext.WindowGroup();/**
- * @class Ext.MessageBox
- * <p>Utility class for generating different styles of message boxes.  The alias Ext.Msg can also be used.<p/>
- * <p>Note that the MessageBox is asynchronous.  Unlike a regular JavaScript <code>alert</code> (which will halt
- * browser execution), showing a MessageBox will not cause the code to stop.  For this reason, if you have code
- * that should only run <em>after</em> some user feedback from the MessageBox, you must use a callback function
- * (see the <code>function</code> parameter for {@link #show} for more details).</p>
- * <p>Example usage:</p>
- *<pre><code>
-// Basic alert:
-Ext.Msg.alert('Status', 'Changes saved successfully.');
-
-// Prompt for user data and process the result using a callback:
-Ext.Msg.prompt('Name', 'Please enter your name:', function(btn, text){
-    if (btn == 'ok'){
-        // process text value and close...
-    }
-});
-
-// Show a dialog using config options:
-Ext.Msg.show({
-   title:'Save Changes?',
-   msg: 'You are closing a tab that has unsaved changes. Would you like to save your changes?',
-   buttons: Ext.Msg.YESNOCANCEL,
-   fn: processResult,
-   animEl: 'elId',
-   icon: Ext.MessageBox.QUESTION
-});
-</code></pre>
- * @singleton
- */
-Ext.MessageBox = function(){
-    var dlg, opt, mask, waitTimer;
-    var bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl;
-    var buttons, activeTextEl, bwidth, iconCls = '';
-
-    // private
-    var handleButton = function(button){
-        if(dlg.isVisible()){
-            dlg.hide();
-            handleHide();
-            Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 1);
-        }
-    };
-
-    // private
-    var handleHide = function(){
-        if(opt && opt.cls){
-            dlg.el.removeClass(opt.cls);
-        }
-        progressBar.reset();
-    };
-
-    // private
-    var handleEsc = function(d, k, e){
-        if(opt && opt.closable !== false){
-            dlg.hide();
-            handleHide();
-        }
-        if(e){
-            e.stopEvent();
-        }
-    };
-
-    // private
-    var updateButtons = function(b){
-        var width = 0;
-        if(!b){
-            buttons["ok"].hide();
-            buttons["cancel"].hide();
-            buttons["yes"].hide();
-            buttons["no"].hide();
-            return width;
-        }
-        dlg.footer.dom.style.display = '';
-        for(var k in buttons){
-            if(typeof buttons[k] != "function"){
-                if(b[k]){
-                    buttons[k].show();
-                    buttons[k].setText(typeof b[k] == "string" ? b[k] : Ext.MessageBox.buttonText[k]);
-                    width += buttons[k].el.getWidth()+15;
-                }else{
-                    buttons[k].hide();
-                }
-            }
-        }
-        return width;
-    };
-
-    return {
-        /**
-         * Returns a reference to the underlying {@link Ext.Window} element
-         * @return {Ext.Window} The window
-         */
-        getDialog : function(titleText){
-           if(!dlg){
-                dlg = new Ext.Window({
-                    autoCreate : true,
-                    title:titleText,
-                    resizable:false,
-                    constrain:true,
-                    constrainHeader:true,
-                    minimizable : false,
-                    maximizable : false,
-                    stateful: false,
-                    modal: true,
-                    shim:true,
-                    buttonAlign:"center",
-                    width:400,
-                    height:100,
-                    minHeight: 80,
-                    plain:true,
-                    footer:true,
-                    closable:true,
-                    close : function(){
-                        if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
-                            handleButton("no");
-                        }else{
-                            handleButton("cancel");
-                        }
-                    }
-                });
-                buttons = {};
-                var bt = this.buttonText;
-                //TODO: refactor this block into a buttons config to pass into the Window constructor
-                buttons["ok"] = dlg.addButton(bt["ok"], handleButton.createCallback("ok"));
-                buttons["yes"] = dlg.addButton(bt["yes"], handleButton.createCallback("yes"));
-                buttons["no"] = dlg.addButton(bt["no"], handleButton.createCallback("no"));
-                buttons["cancel"] = dlg.addButton(bt["cancel"], handleButton.createCallback("cancel"));
-                buttons["ok"].hideMode = buttons["yes"].hideMode = buttons["no"].hideMode = buttons["cancel"].hideMode = 'offsets';
-                dlg.render(document.body);
-                dlg.getEl().addClass('x-window-dlg');
-                mask = dlg.mask;
-                bodyEl = dlg.body.createChild({
-                    html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><div class="ext-mb-fix-cursor"><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div></div>'
-                });
-                iconEl = Ext.get(bodyEl.dom.firstChild);
-                var contentEl = bodyEl.dom.childNodes[1];
-                msgEl = Ext.get(contentEl.firstChild);
-                textboxEl = Ext.get(contentEl.childNodes[2].firstChild);
-                textboxEl.enableDisplayMode();
-                textboxEl.addKeyListener([10,13], function(){
-                    if(dlg.isVisible() && opt && opt.buttons){
-                        if(opt.buttons.ok){
-                            handleButton("ok");
-                        }else if(opt.buttons.yes){
-                            handleButton("yes");
-                        }
-                    }
-                });
-                textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);
-                textareaEl.enableDisplayMode();
-                progressBar = new Ext.ProgressBar({
-                    renderTo:bodyEl
-                });
-               bodyEl.createChild({cls:'x-clear'});
-            }
-            return dlg;
-        },
-
-        /**
-         * Updates the message box body text
-         * @param {String} text (optional) Replaces the message box element's innerHTML with the specified string (defaults to
-         * the XHTML-compliant non-breaking space character '&amp;#160;')
-         * @return {Ext.MessageBox} this
-         */
-        updateText : function(text){
-            if(!dlg.isVisible() && !opt.width){
-                dlg.setSize(this.maxWidth, 100); // resize first so content is never clipped from previous shows
-            }
-            msgEl.update(text || '&#160;');
-
-            var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0;
-            var mw = msgEl.getWidth() + msgEl.getMargins('lr');
-            var fw = dlg.getFrameWidth('lr');
-            var bw = dlg.body.getFrameWidth('lr');
-            if (Ext.isIE && iw > 0){
-                //3 pixels get subtracted in the icon CSS for an IE margin issue,
-                //so we have to add it back here for the overall width to be consistent
-                iw += 3;
-            }
-            var w = Math.max(Math.min(opt.width || iw+mw+fw+bw, this.maxWidth),
-                        Math.max(opt.minWidth || this.minWidth, bwidth || 0));
-
-            if(opt.prompt === true){
-                activeTextEl.setWidth(w-iw-fw-bw);
-            }
-            if(opt.progress === true || opt.wait === true){
-                progressBar.setSize(w-iw-fw-bw);
-            }
-            if(Ext.isIE && w == bwidth){
-                w += 4; //Add offset when the content width is smaller than the buttons.    
-            }
-            dlg.setSize(w, 'auto').center();
-            return this;
-        },
-
-        /**
-         * Updates a progress-style message box's text and progress bar. Only relevant on message boxes
-         * initiated via {@link Ext.MessageBox#progress} or {@link Ext.MessageBox#wait},
-         * or by calling {@link Ext.MessageBox#show} with progress: true.
-         * @param {Number} value Any number between 0 and 1 (e.g., .5, defaults to 0)
-         * @param {String} progressText The progress text to display inside the progress bar (defaults to '')
-         * @param {String} msg The message box's body text is replaced with the specified string (defaults to undefined
-         * so that any existing body text will not get overwritten by default unless a new value is passed in)
-         * @return {Ext.MessageBox} this
-         */
-        updateProgress : function(value, progressText, msg){
-            progressBar.updateProgress(value, progressText);
-            if(msg){
-                this.updateText(msg);
-            }
-            return this;
-        },
-
-        /**
-         * Returns true if the message box is currently displayed
-         * @return {Boolean} True if the message box is visible, else false
-         */
-        isVisible : function(){
-            return dlg && dlg.isVisible();
-        },
-
-        /**
-         * Hides the message box if it is displayed
-         * @return {Ext.MessageBox} this
-         */
-        hide : function(){
-            var proxy = dlg ? dlg.activeGhost : null;
-            if(this.isVisible() || proxy){
-                dlg.hide();
-                handleHide();
-                if (proxy){
-                    // unghost is a private function, but i saw no better solution
-                    // to fix the locking problem when dragging while it closes
-                    dlg.unghost(false, false);
-                } 
-            }
-            return this;
-        },
-
-        /**
-         * Displays a new message box, or reinitializes an existing message box, based on the config options
-         * passed in. All display functions (e.g. prompt, alert, etc.) on MessageBox call this function internally,
-         * although those calls are basic shortcuts and do not support all of the config options allowed here.
-         * @param {Object} config The following config options are supported: <ul>
-         * <li><b>animEl</b> : String/Element<div class="sub-desc">An id or Element from which the message box should animate as it
-         * opens and closes (defaults to undefined)</div></li>
-         * <li><b>buttons</b> : Object/Boolean<div class="sub-desc">A button config object (e.g., Ext.MessageBox.OKCANCEL or {ok:'Foo',
-         * cancel:'Bar'}), or false to not show any buttons (defaults to false)</div></li>
-         * <li><b>closable</b> : Boolean<div class="sub-desc">False to hide the top-right close button (defaults to true). Note that
-         * progress and wait dialogs will ignore this property and always hide the close button as they can only
-         * be closed programmatically.</div></li>
-         * <li><b>cls</b> : String<div class="sub-desc">A custom CSS class to apply to the message box's container element</div></li>
-         * <li><b>defaultTextHeight</b> : Number<div class="sub-desc">The default height in pixels of the message box's multiline textarea
-         * if displayed (defaults to 75)</div></li>
-         * <li><b>fn</b> : Function<div class="sub-desc">A callback function which is called when the dialog is dismissed either
-         * by clicking on the configured buttons, or on the dialog close button, or by pressing
-         * the return button to enter input.
-         * <p>Progress and wait dialogs will ignore this option since they do not respond to user
-         * actions and can only be closed programmatically, so any required function should be called
-         * by the same code after it closes the dialog. Parameters passed:<ul>
-         * <li><b>buttonId</b> : String<div class="sub-desc">The ID of the button pressed, one of:<div class="sub-desc"><ul>
-         * <li><tt>ok</tt></li>
-         * <li><tt>yes</tt></li>
-         * <li><tt>no</tt></li>
-         * <li><tt>cancel</tt></li>
-         * </ul></div></div></li>
-         * <li><b>text</b> : String<div class="sub-desc">Value of the input field if either <tt><a href="#show-option-prompt" ext:member="show-option-prompt" ext:cls="Ext.MessageBox">prompt</a></tt>
-         * or <tt><a href="#show-option-multiline" ext:member="show-option-multiline" ext:cls="Ext.MessageBox">multiline</a></tt> is true</div></li>
-         * <li><b>opt</b> : Object<div class="sub-desc">The config object passed to show.</div></li>
-         * </ul></p></div></li>
-         * <li><b>scope</b> : Object<div class="sub-desc">The scope of the callback function</div></li>
-         * <li><b>icon</b> : String<div class="sub-desc">A CSS class that provides a background image to be used as the body icon for the
-         * dialog (e.g. Ext.MessageBox.WARNING or 'custom-class') (defaults to '')</div></li>
-         * <li><b>iconCls</b> : String<div class="sub-desc">The standard {@link Ext.Window#iconCls} to
-         * add an optional header icon (defaults to '')</div></li>
-         * <li><b>maxWidth</b> : Number<div class="sub-desc">The maximum width in pixels of the message box (defaults to 600)</div></li>
-         * <li><b>minWidth</b> : Number<div class="sub-desc">The minimum width in pixels of the message box (defaults to 100)</div></li>
-         * <li><b>modal</b> : Boolean<div class="sub-desc">False to allow user interaction with the page while the message box is
-         * displayed (defaults to true)</div></li>
-         * <li><b>msg</b> : String<div class="sub-desc">A string that will replace the existing message box body text (defaults to the
-         * XHTML-compliant non-breaking space character '&amp;#160;')</div></li>
-         * <li><a id="show-option-multiline"></a><b>multiline</b> : Boolean<div class="sub-desc">
-         * True to prompt the user to enter multi-line text (defaults to false)</div></li>
-         * <li><b>progress</b> : Boolean<div class="sub-desc">True to display a progress bar (defaults to false)</div></li>
-         * <li><b>progressText</b> : String<div class="sub-desc">The text to display inside the progress bar if progress = true (defaults to '')</div></li>
-         * <li><a id="show-option-prompt"></a><b>prompt</b> : Boolean<div class="sub-desc">True to prompt the user to enter single-line text (defaults to false)</div></li>
-         * <li><b>proxyDrag</b> : Boolean<div class="sub-desc">True to display a lightweight proxy while dragging (defaults to false)</div></li>
-         * <li><b>title</b> : String<div class="sub-desc">The title text</div></li>
-         * <li><b>value</b> : String<div class="sub-desc">The string value to set into the active textbox element if displayed</div></li>
-         * <li><b>wait</b> : Boolean<div class="sub-desc">True to display a progress bar (defaults to false)</div></li>
-         * <li><b>waitConfig</b> : Object<div class="sub-desc">A {@link Ext.ProgressBar#waitConfig} object (applies only if wait = true)</div></li>
-         * <li><b>width</b> : Number<div class="sub-desc">The width of the dialog in pixels</div></li>
-         * </ul>
-         * Example usage:
-         * <pre><code>
-Ext.Msg.show({
-   title: 'Address',
-   msg: 'Please enter your address:',
-   width: 300,
-   buttons: Ext.MessageBox.OKCANCEL,
-   multiline: true,
-   fn: saveAddress,
-   animEl: 'addAddressBtn',
-   icon: Ext.MessageBox.INFO
-});
-</code></pre>
-         * @return {Ext.MessageBox} this
-         */
-        show : function(options){
-            if(this.isVisible()){
-                this.hide();
-            }
-            opt = options;
-            var d = this.getDialog(opt.title || "&#160;");
-
-            d.setTitle(opt.title || "&#160;");
-            var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
-            d.tools.close.setDisplayed(allowClose);
-            activeTextEl = textboxEl;
-            opt.prompt = opt.prompt || (opt.multiline ? true : false);
-            if(opt.prompt){
-                if(opt.multiline){
-                    textboxEl.hide();
-                    textareaEl.show();
-                    textareaEl.setHeight(typeof opt.multiline == "number" ?
-                        opt.multiline : this.defaultTextHeight);
-                    activeTextEl = textareaEl;
-                }else{
-                    textboxEl.show();
-                    textareaEl.hide();
-                }
-            }else{
-                textboxEl.hide();
-                textareaEl.hide();
-            }
-            activeTextEl.dom.value = opt.value || "";
-            if(opt.prompt){
-                d.focusEl = activeTextEl;
-            }else{
-                var bs = opt.buttons;
-                var db = null;
-                if(bs && bs.ok){
-                    db = buttons["ok"];
-                }else if(bs && bs.yes){
-                    db = buttons["yes"];
-                }
-                if (db){
-                    d.focusEl = db;
-                }
-            }
-            if(opt.iconCls){
-              d.setIconClass(opt.iconCls);
-            }
-            this.setIcon(opt.icon);
-            if(opt.cls){
-                d.el.addClass(opt.cls);
-            }
-            d.proxyDrag = opt.proxyDrag === true;
-            d.modal = opt.modal !== false;
-            d.mask = opt.modal !== false ? mask : false;
-            
-            d.on('show', function(){
-                //workaround for window internally enabling keymap in afterShow
-                d.keyMap.setDisabled(allowClose !== true);
-                d.doLayout();
-                this.setIcon(opt.icon);
-                bwidth = updateButtons(opt.buttons);
-                progressBar.setVisible(opt.progress === true || opt.wait === true);
-                this.updateProgress(0, opt.progressText);
-                this.updateText(opt.msg);
-                if(opt.wait === true){
-                    progressBar.wait(opt.waitConfig);
-                }
-
-            }, this, {single:true});
-            if(!d.isVisible()){
-                // force it to the end of the z-index stack so it gets a cursor in FF
-                document.body.appendChild(dlg.el.dom);
-                d.setAnimateTarget(opt.animEl);
-                d.show(opt.animEl);
-            }
-            return this;
-        },
-
-        /**
-         * Adds the specified icon to the dialog.  By default, the class 'ext-mb-icon' is applied for default
-         * styling, and the class passed in is expected to supply the background image url. Pass in empty string ('')
-         * to clear any existing icon.  The following built-in icon classes are supported, but you can also pass
-         * in a custom class name:
-         * <pre>
-Ext.MessageBox.INFO
-Ext.MessageBox.WARNING
-Ext.MessageBox.QUESTION
-Ext.MessageBox.ERROR
-         *</pre>
-         * @param {String} icon A CSS classname specifying the icon's background image url, or empty string to clear the icon
-         * @return {Ext.MessageBox} this
-         */
-        setIcon : function(icon){
-            if(icon && icon != ''){
-                iconEl.removeClass('x-hidden');
-                iconEl.replaceClass(iconCls, icon);
-                bodyEl.addClass('x-dlg-icon');
-                iconCls = icon;
-            }else{
-                iconEl.replaceClass(iconCls, 'x-hidden');
-                bodyEl.removeClass('x-dlg-icon');
-                iconCls = '';
-            }
-            return this;
-        },
-
-        /**
-         * Displays a message box with a progress bar.  This message box has no buttons and is not closeable by
-         * the user.  You are responsible for updating the progress bar as needed via {@link Ext.MessageBox#updateProgress}
-         * and closing the message box when the process is complete.
-         * @param {String} title The title bar text
-         * @param {String} msg The message box body text
-         * @param {String} progressText (optional) The text to display inside the progress bar (defaults to '')
-         * @return {Ext.MessageBox} this
-         */
-        progress : function(title, msg, progressText){
-            this.show({
-                title : title,
-                msg : msg,
-                buttons: false,
-                progress:true,
-                closable:false,
-                minWidth: this.minProgressWidth,
-                progressText: progressText
-            });
-            return this;
-        },
-
-        /**
-         * Displays a message box with an infinitely auto-updating progress bar.  This can be used to block user
-         * interaction while waiting for a long-running process to complete that does not have defined intervals.
-         * You are responsible for closing the message box when the process is complete.
-         * @param {String} msg The message box body text
-         * @param {String} title (optional) The title bar text
-         * @param {Object} config (optional) A {@link Ext.ProgressBar#waitConfig} object
-         * @return {Ext.MessageBox} this
-         */
-        wait : function(msg, title, config){
-            this.show({
-                title : title,
-                msg : msg,
-                buttons: false,
-                closable:false,
-                wait:true,
-                modal:true,
-                minWidth: this.minProgressWidth,
-                waitConfig: config
-            });
-            return this;
-        },
-
-        /**
-         * Displays a standard read-only message box with an OK button (comparable to the basic JavaScript alert prompt).
-         * If a callback function is passed it will be called after the user clicks the button, and the
-         * id of the button that was clicked will be passed as the only parameter to the callback
-         * (could also be the top-right close button).
-         * @param {String} title The title bar text
-         * @param {String} msg The message box body text
-         * @param {Function} fn (optional) The callback function invoked after the message box is closed
-         * @param {Object} scope (optional) The scope of the callback function
-         * @return {Ext.MessageBox} this
-         */
-        alert : function(title, msg, fn, scope){
-            this.show({
-                title : title,
-                msg : msg,
-                buttons: this.OK,
-                fn: fn,
-                scope : scope
-            });
-            return this;
-        },
-
-        /**
-         * Displays a confirmation message box with Yes and No buttons (comparable to JavaScript's confirm).
-         * If a callback function is passed it will be called after the user clicks either button,
-         * and the id of the button that was clicked will be passed as the only parameter to the callback
-         * (could also be the top-right close button).
-         * @param {String} title The title bar text
-         * @param {String} msg The message box body text
-         * @param {Function} fn (optional) The callback function invoked after the message box is closed
-         * @param {Object} scope (optional) The scope of the callback function
-         * @return {Ext.MessageBox} this
-         */
-        confirm : function(title, msg, fn, scope){
-            this.show({
-                title : title,
-                msg : msg,
-                buttons: this.YESNO,
-                fn: fn,
-                scope : scope,
-                icon: this.QUESTION
-            });
-            return this;
-        },
-
-        /**
-         * Displays a message box with OK and Cancel buttons prompting the user to enter some text (comparable to JavaScript's prompt).
-         * The prompt can be a single-line or multi-line textbox.  If a callback function is passed it will be called after the user
-         * clicks either button, and the id of the button that was clicked (could also be the top-right
-         * close button) and the text that was entered will be passed as the two parameters to the callback.
-         * @param {String} title The title bar text
-         * @param {String} msg The message box body text
-         * @param {Function} fn (optional) The callback function invoked after the message box is closed
-         * @param {Object} scope (optional) The scope of the callback function
-         * @param {Boolean/Number} multiline (optional) True to create a multiline textbox using the defaultTextHeight
-         * property, or the height in pixels to create the textbox (defaults to false / single-line)
-         * @param {String} value (optional) Default value of the text input element (defaults to '')
-         * @return {Ext.MessageBox} this
-         */
-        prompt : function(title, msg, fn, scope, multiline, value){
-            this.show({
-                title : title,
-                msg : msg,
-                buttons: this.OKCANCEL,
-                fn: fn,
-                minWidth:250,
-                scope : scope,
-                prompt:true,
-                multiline: multiline,
-                value: value
-            });
-            return this;
-        },
-
-        /**
-         * Button config that displays a single OK button
-         * @type Object
-         */
-        OK : {ok:true},
-        /**
-         * Button config that displays a single Cancel button
-         * @type Object
-         */
-        CANCEL : {cancel:true},
-        /**
-         * Button config that displays OK and Cancel buttons
-         * @type Object
-         */
-        OKCANCEL : {ok:true, cancel:true},
-        /**
-         * Button config that displays Yes and No buttons
-         * @type Object
-         */
-        YESNO : {yes:true, no:true},
-        /**
-         * Button config that displays Yes, No and Cancel buttons
-         * @type Object
-         */
-        YESNOCANCEL : {yes:true, no:true, cancel:true},
-        /**
-         * The CSS class that provides the INFO icon image
-         * @type String
-         */
-        INFO : 'ext-mb-info',
-        /**
-         * The CSS class that provides the WARNING icon image
-         * @type String
-         */
-        WARNING : 'ext-mb-warning',
-        /**
-         * The CSS class that provides the QUESTION icon image
-         * @type String
-         */
-        QUESTION : 'ext-mb-question',
-        /**
-         * The CSS class that provides the ERROR icon image
-         * @type String
-         */
-        ERROR : 'ext-mb-error',
-
-        /**
-         * The default height in pixels of the message box's multiline textarea if displayed (defaults to 75)
-         * @type Number
-         */
-        defaultTextHeight : 75,
-        /**
-         * The maximum width in pixels of the message box (defaults to 600)
-         * @type Number
-         */
-        maxWidth : 600,
-        /**
-         * The minimum width in pixels of the message box (defaults to 110)
-         * @type Number
-         */
-        minWidth : 110,
-        /**
-         * The minimum width in pixels of the message box if it is a progress-style dialog.  This is useful
-         * for setting a different minimum width than text-only dialogs may need (defaults to 250)
-         * @type Number
-         */
-        minProgressWidth : 250,
-        /**
-         * An object containing the default button text strings that can be overriden for localized language support.
-         * Supported properties are: ok, cancel, yes and no.  Generally you should include a locale-specific
-         * resource file for handling language support across the framework.
-         * Customize the default text like so: Ext.MessageBox.buttonText.yes = "oui"; //french
-         * @type Object
-         */
-        buttonText : {
-            ok : "OK",
-            cancel : "Cancel",
-            yes : "Yes",
-            no : "No"
-        }
-    };
-}();
-
-/**
- * Shorthand for {@link Ext.MessageBox}
- */
-Ext.Msg = Ext.MessageBox;/**\r
- * @class Ext.dd.PanelProxy\r
- * A custom drag proxy implementation specific to {@link Ext.Panel}s. This class is primarily used internally\r
- * for the Panel's drag drop implementation, and should never need to be created directly.\r
- * @constructor\r
- * @param panel The {@link Ext.Panel} to proxy for\r
- * @param config Configuration options\r
- */\r
-Ext.dd.PanelProxy = function(panel, config){\r
-    this.panel = panel;\r
-    this.id = this.panel.id +'-ddproxy';\r
-    Ext.apply(this, config);\r
-};\r
-\r
-Ext.dd.PanelProxy.prototype = {\r
-    /**\r
-     * @cfg {Boolean} insertProxy True to insert a placeholder proxy element while dragging the panel,\r
-     * false to drag with no proxy (defaults to true).\r
-     */\r
-    insertProxy : true,\r
+Ext.WindowMgr = new Ext.WindowGroup();/**\r
+ * @class Ext.MessageBox\r
+ * <p>Utility class for generating different styles of message boxes.  The alias Ext.Msg can also be used.<p/>\r
+ * <p>Note that the MessageBox is asynchronous.  Unlike a regular JavaScript <code>alert</code> (which will halt\r
+ * browser execution), showing a MessageBox will not cause the code to stop.  For this reason, if you have code\r
+ * that should only run <em>after</em> some user feedback from the MessageBox, you must use a callback function\r
+ * (see the <code>function</code> parameter for {@link #show} for more details).</p>\r
+ * <p>Example usage:</p>\r
+ *<pre><code>\r
+// Basic alert:\r
+Ext.Msg.alert('Status', 'Changes saved successfully.');\r
+\r
+// Prompt for user data and process the result using a callback:\r
+Ext.Msg.prompt('Name', 'Please enter your name:', function(btn, text){\r
+    if (btn == 'ok'){\r
+        // process text value and close...\r
+    }\r
+});\r
 \r
-    // private overrides\r
-    setStatus : Ext.emptyFn,\r
-    reset : Ext.emptyFn,\r
-    update : Ext.emptyFn,\r
-    stop : Ext.emptyFn,\r
-    sync: Ext.emptyFn,\r
+// Show a dialog using config options:\r
+Ext.Msg.show({\r
+   title:'Save Changes?',\r
+   msg: 'You are closing a tab that has unsaved changes. Would you like to save your changes?',\r
+   buttons: Ext.Msg.YESNOCANCEL,\r
+   fn: processResult,\r
+   animEl: 'elId',\r
+   icon: Ext.MessageBox.QUESTION\r
+});\r
+</code></pre>\r
+ * @singleton\r
+ */\r
+Ext.MessageBox = function(){\r
+    var dlg, opt, mask, waitTimer,\r
+        bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl,\r
+        buttons, activeTextEl, bwidth, bufferIcon = '', iconCls = '';\r
 \r
-    /**\r
-     * Gets the proxy's element\r
-     * @return {Element} The proxy's element\r
-     */\r
-    getEl : function(){\r
-        return this.ghost;\r
-    },\r
+    // private\r
+    var handleButton = function(button){\r
+        if(dlg.isVisible()){\r
+            dlg.hide();\r
+            handleHide();\r
+            Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 1);\r
+        }\r
+    };\r
 \r
-    /**\r
-     * Gets the proxy's ghost element\r
-     * @return {Element} The proxy's ghost element\r
-     */\r
-    getGhost : function(){\r
-        return this.ghost;\r
-    },\r
+    // private\r
+    var handleHide = function(){\r
+        if(opt && opt.cls){\r
+            dlg.el.removeClass(opt.cls);\r
+        }\r
+        progressBar.reset();\r
+    };\r
 \r
-    /**\r
-     * Gets the proxy's element\r
-     * @return {Element} The proxy's element\r
-     */\r
-    getProxy : function(){\r
-        return this.proxy;\r
-    },\r
+    // private\r
+    var handleEsc = function(d, k, e){\r
+        if(opt && opt.closable !== false){\r
+            dlg.hide();\r
+            handleHide();\r
+        }\r
+        if(e){\r
+            e.stopEvent();\r
+        }\r
+    };\r
 \r
-    /**\r
-     * Hides the proxy\r
-     */\r
-    hide : function(){\r
-        if(this.ghost){\r
-            if(this.proxy){\r
-                this.proxy.remove();\r
-                delete this.proxy;\r
+    // private\r
+    var updateButtons = function(b){\r
+        var width = 0;\r
+        if(!b){\r
+            buttons["ok"].hide();\r
+            buttons["cancel"].hide();\r
+            buttons["yes"].hide();\r
+            buttons["no"].hide();\r
+            return width;\r
+        }\r
+        dlg.footer.dom.style.display = '';\r
+        for(var k in buttons){\r
+            if(!Ext.isFunction(buttons[k])){\r
+                if(b[k]){\r
+                    buttons[k].show();\r
+                    buttons[k].setText(Ext.isString(b[k]) ? b[k] : Ext.MessageBox.buttonText[k]);\r
+                    width += buttons[k].el.getWidth()+15;\r
+                }else{\r
+                    buttons[k].hide();\r
+                }\r
             }\r
-            this.panel.el.dom.style.display = '';\r
-            this.ghost.remove();\r
-            delete this.ghost;\r
         }\r
-    },\r
+        return width;\r
+    };\r
 \r
-    /**\r
-     * Shows the proxy\r
-     */\r
-    show : function(){\r
-        if(!this.ghost){\r
-            this.ghost = this.panel.createGhost(undefined, undefined, Ext.getBody());\r
+    return {\r
+        /**\r
+         * Returns a reference to the underlying {@link Ext.Window} element\r
+         * @return {Ext.Window} The window\r
+         */\r
+        getDialog : function(titleText){\r
+           if(!dlg){\r
+                dlg = new Ext.Window({\r
+                    autoCreate : true,\r
+                    title:titleText,\r
+                    resizable:false,\r
+                    constrain:true,\r
+                    constrainHeader:true,\r
+                    minimizable : false,\r
+                    maximizable : false,\r
+                    stateful: false,\r
+                    modal: true,\r
+                    shim:true,\r
+                    buttonAlign:"center",\r
+                    width:400,\r
+                    height:100,\r
+                    minHeight: 80,\r
+                    plain:true,\r
+                    footer:true,\r
+                    closable:true,\r
+                    close : function(){\r
+                        if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){\r
+                            handleButton("no");\r
+                        }else{\r
+                            handleButton("cancel");\r
+                        }\r
+                    }\r
+                });\r
+                buttons = {};\r
+                var bt = this.buttonText;\r
+                //TODO: refactor this block into a buttons config to pass into the Window constructor\r
+                buttons["ok"] = dlg.addButton(bt["ok"], handleButton.createCallback("ok"));\r
+                buttons["yes"] = dlg.addButton(bt["yes"], handleButton.createCallback("yes"));\r
+                buttons["no"] = dlg.addButton(bt["no"], handleButton.createCallback("no"));\r
+                buttons["cancel"] = dlg.addButton(bt["cancel"], handleButton.createCallback("cancel"));\r
+                buttons["ok"].hideMode = buttons["yes"].hideMode = buttons["no"].hideMode = buttons["cancel"].hideMode = 'offsets';\r
+                dlg.render(document.body);\r
+                dlg.getEl().addClass('x-window-dlg');\r
+                mask = dlg.mask;\r
+                bodyEl = dlg.body.createChild({\r
+                    html:'<div class="ext-mb-icon"></div><div class="ext-mb-content"><span class="ext-mb-text"></span><br /><div class="ext-mb-fix-cursor"><input type="text" class="ext-mb-input" /><textarea class="ext-mb-textarea"></textarea></div></div>'\r
+                });\r
+                iconEl = Ext.get(bodyEl.dom.firstChild);\r
+                var contentEl = bodyEl.dom.childNodes[1];\r
+                msgEl = Ext.get(contentEl.firstChild);\r
+                textboxEl = Ext.get(contentEl.childNodes[2].firstChild);\r
+                textboxEl.enableDisplayMode();\r
+                textboxEl.addKeyListener([10,13], function(){\r
+                    if(dlg.isVisible() && opt && opt.buttons){\r
+                        if(opt.buttons.ok){\r
+                            handleButton("ok");\r
+                        }else if(opt.buttons.yes){\r
+                            handleButton("yes");\r
+                        }\r
+                    }\r
+                });\r
+                textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);\r
+                textareaEl.enableDisplayMode();\r
+                progressBar = new Ext.ProgressBar({\r
+                    renderTo:bodyEl\r
+                });\r
+               bodyEl.createChild({cls:'x-clear'});\r
+            }\r
+            return dlg;\r
+        },\r
+\r
+        /**\r
+         * Updates the message box body text\r
+         * @param {String} text (optional) Replaces the message box element's innerHTML with the specified string (defaults to\r
+         * the XHTML-compliant non-breaking space character '&amp;#160;')\r
+         * @return {Ext.MessageBox} this\r
+         */\r
+        updateText : function(text){\r
+            if(!dlg.isVisible() && !opt.width){\r
+                dlg.setSize(this.maxWidth, 100); // resize first so content is never clipped from previous shows\r
+            }\r
+            msgEl.update(text || '&#160;');\r
+\r
+            var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0;\r
+            var mw = msgEl.getWidth() + msgEl.getMargins('lr');\r
+            var fw = dlg.getFrameWidth('lr');\r
+            var bw = dlg.body.getFrameWidth('lr');\r
+            if (Ext.isIE && iw > 0){\r
+                //3 pixels get subtracted in the icon CSS for an IE margin issue,\r
+                //so we have to add it back here for the overall width to be consistent\r
+                iw += 3;\r
+            }\r
+            var w = Math.max(Math.min(opt.width || iw+mw+fw+bw, this.maxWidth),\r
+                        Math.max(opt.minWidth || this.minWidth, bwidth || 0));\r
+\r
+            if(opt.prompt === true){\r
+                activeTextEl.setWidth(w-iw-fw-bw);\r
+            }\r
+            if(opt.progress === true || opt.wait === true){\r
+                progressBar.setSize(w-iw-fw-bw);\r
+            }\r
+            if(Ext.isIE && w == bwidth){\r
+                w += 4; //Add offset when the content width is smaller than the buttons.    \r
+            }\r
+            dlg.setSize(w, 'auto').center();\r
+            return this;\r
+        },\r
+\r
+        /**\r
+         * Updates a progress-style message box's text and progress bar. Only relevant on message boxes\r
+         * initiated via {@link Ext.MessageBox#progress} or {@link Ext.MessageBox#wait},\r
+         * or by calling {@link Ext.MessageBox#show} with progress: true.\r
+         * @param {Number} value Any number between 0 and 1 (e.g., .5, defaults to 0)\r
+         * @param {String} progressText The progress text to display inside the progress bar (defaults to '')\r
+         * @param {String} msg The message box's body text is replaced with the specified string (defaults to undefined\r
+         * so that any existing body text will not get overwritten by default unless a new value is passed in)\r
+         * @return {Ext.MessageBox} this\r
+         */\r
+        updateProgress : function(value, progressText, msg){\r
+            progressBar.updateProgress(value, progressText);\r
+            if(msg){\r
+                this.updateText(msg);\r
+            }\r
+            return this;\r
+        },\r
+\r
+        /**\r
+         * Returns true if the message box is currently displayed\r
+         * @return {Boolean} True if the message box is visible, else false\r
+         */\r
+        isVisible : function(){\r
+            return dlg && dlg.isVisible();\r
+        },\r
+\r
+        /**\r
+         * Hides the message box if it is displayed\r
+         * @return {Ext.MessageBox} this\r
+         */\r
+        hide : function(){\r
+            var proxy = dlg ? dlg.activeGhost : null;\r
+            if(this.isVisible() || proxy){\r
+                dlg.hide();\r
+                handleHide();\r
+                if (proxy){\r
+                    // unghost is a private function, but i saw no better solution\r
+                    // to fix the locking problem when dragging while it closes\r
+                    dlg.unghost(false, false);\r
+                } \r
+            }\r
+            return this;\r
+        },\r
+\r
+        /**\r
+         * Displays a new message box, or reinitializes an existing message box, based on the config options\r
+         * passed in. All display functions (e.g. prompt, alert, etc.) on MessageBox call this function internally,\r
+         * although those calls are basic shortcuts and do not support all of the config options allowed here.\r
+         * @param {Object} config The following config options are supported: <ul>\r
+         * <li><b>animEl</b> : String/Element<div class="sub-desc">An id or Element from which the message box should animate as it\r
+         * opens and closes (defaults to undefined)</div></li>\r
+         * <li><b>buttons</b> : Object/Boolean<div class="sub-desc">A button config object (e.g., Ext.MessageBox.OKCANCEL or {ok:'Foo',\r
+         * cancel:'Bar'}), or false to not show any buttons (defaults to false)</div></li>\r
+         * <li><b>closable</b> : Boolean<div class="sub-desc">False to hide the top-right close button (defaults to true). Note that\r
+         * progress and wait dialogs will ignore this property and always hide the close button as they can only\r
+         * be closed programmatically.</div></li>\r
+         * <li><b>cls</b> : String<div class="sub-desc">A custom CSS class to apply to the message box's container element</div></li>\r
+         * <li><b>defaultTextHeight</b> : Number<div class="sub-desc">The default height in pixels of the message box's multiline textarea\r
+         * if displayed (defaults to 75)</div></li>\r
+         * <li><b>fn</b> : Function<div class="sub-desc">A callback function which is called when the dialog is dismissed either\r
+         * by clicking on the configured buttons, or on the dialog close button, or by pressing\r
+         * the return button to enter input.\r
+         * <p>Progress and wait dialogs will ignore this option since they do not respond to user\r
+         * actions and can only be closed programmatically, so any required function should be called\r
+         * by the same code after it closes the dialog. Parameters passed:<ul>\r
+         * <li><b>buttonId</b> : String<div class="sub-desc">The ID of the button pressed, one of:<div class="sub-desc"><ul>\r
+         * <li><tt>ok</tt></li>\r
+         * <li><tt>yes</tt></li>\r
+         * <li><tt>no</tt></li>\r
+         * <li><tt>cancel</tt></li>\r
+         * </ul></div></div></li>\r
+         * <li><b>text</b> : String<div class="sub-desc">Value of the input field if either <tt><a href="#show-option-prompt" ext:member="show-option-prompt" ext:cls="Ext.MessageBox">prompt</a></tt>\r
+         * or <tt><a href="#show-option-multiline" ext:member="show-option-multiline" ext:cls="Ext.MessageBox">multiline</a></tt> is true</div></li>\r
+         * <li><b>opt</b> : Object<div class="sub-desc">The config object passed to show.</div></li>\r
+         * </ul></p></div></li>\r
+         * <li><b>scope</b> : Object<div class="sub-desc">The scope of the callback function</div></li>\r
+         * <li><b>icon</b> : String<div class="sub-desc">A CSS class that provides a background image to be used as the body icon for the\r
+         * dialog (e.g. Ext.MessageBox.WARNING or 'custom-class') (defaults to '')</div></li>\r
+         * <li><b>iconCls</b> : String<div class="sub-desc">The standard {@link Ext.Window#iconCls} to\r
+         * add an optional header icon (defaults to '')</div></li>\r
+         * <li><b>maxWidth</b> : Number<div class="sub-desc">The maximum width in pixels of the message box (defaults to 600)</div></li>\r
+         * <li><b>minWidth</b> : Number<div class="sub-desc">The minimum width in pixels of the message box (defaults to 100)</div></li>\r
+         * <li><b>modal</b> : Boolean<div class="sub-desc">False to allow user interaction with the page while the message box is\r
+         * displayed (defaults to true)</div></li>\r
+         * <li><b>msg</b> : String<div class="sub-desc">A string that will replace the existing message box body text (defaults to the\r
+         * XHTML-compliant non-breaking space character '&amp;#160;')</div></li>\r
+         * <li><a id="show-option-multiline"></a><b>multiline</b> : Boolean<div class="sub-desc">\r
+         * True to prompt the user to enter multi-line text (defaults to false)</div></li>\r
+         * <li><b>progress</b> : Boolean<div class="sub-desc">True to display a progress bar (defaults to false)</div></li>\r
+         * <li><b>progressText</b> : String<div class="sub-desc">The text to display inside the progress bar if progress = true (defaults to '')</div></li>\r
+         * <li><a id="show-option-prompt"></a><b>prompt</b> : Boolean<div class="sub-desc">True to prompt the user to enter single-line text (defaults to false)</div></li>\r
+         * <li><b>proxyDrag</b> : Boolean<div class="sub-desc">True to display a lightweight proxy while dragging (defaults to false)</div></li>\r
+         * <li><b>title</b> : String<div class="sub-desc">The title text</div></li>\r
+         * <li><b>value</b> : String<div class="sub-desc">The string value to set into the active textbox element if displayed</div></li>\r
+         * <li><b>wait</b> : Boolean<div class="sub-desc">True to display a progress bar (defaults to false)</div></li>\r
+         * <li><b>waitConfig</b> : Object<div class="sub-desc">A {@link Ext.ProgressBar#waitConfig} object (applies only if wait = true)</div></li>\r
+         * <li><b>width</b> : Number<div class="sub-desc">The width of the dialog in pixels</div></li>\r
+         * </ul>\r
+         * Example usage:\r
+         * <pre><code>\r
+Ext.Msg.show({\r
+   title: 'Address',\r
+   msg: 'Please enter your address:',\r
+   width: 300,\r
+   buttons: Ext.MessageBox.OKCANCEL,\r
+   multiline: true,\r
+   fn: saveAddress,\r
+   animEl: 'addAddressBtn',\r
+   icon: Ext.MessageBox.INFO\r
+});\r
+</code></pre>\r
+         * @return {Ext.MessageBox} this\r
+         */\r
+        show : function(options){\r
+            if(this.isVisible()){\r
+                this.hide();\r
+            }\r
+            opt = options;\r
+            var d = this.getDialog(opt.title || "&#160;");\r
+\r
+            d.setTitle(opt.title || "&#160;");\r
+            var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);\r
+            d.tools.close.setDisplayed(allowClose);\r
+            activeTextEl = textboxEl;\r
+            opt.prompt = opt.prompt || (opt.multiline ? true : false);\r
+            if(opt.prompt){\r
+                if(opt.multiline){\r
+                    textboxEl.hide();\r
+                    textareaEl.show();\r
+                    textareaEl.setHeight(Ext.isNumber(opt.multiline) ? opt.multiline : this.defaultTextHeight);\r
+                    activeTextEl = textareaEl;\r
+                }else{\r
+                    textboxEl.show();\r
+                    textareaEl.hide();\r
+                }\r
+            }else{\r
+                textboxEl.hide();\r
+                textareaEl.hide();\r
+            }\r
+            activeTextEl.dom.value = opt.value || "";\r
+            if(opt.prompt){\r
+                d.focusEl = activeTextEl;\r
+            }else{\r
+                var bs = opt.buttons;\r
+                var db = null;\r
+                if(bs && bs.ok){\r
+                    db = buttons["ok"];\r
+                }else if(bs && bs.yes){\r
+                    db = buttons["yes"];\r
+                }\r
+                if (db){\r
+                    d.focusEl = db;\r
+                }\r
+            }\r
+            if(opt.iconCls){\r
+              d.setIconClass(opt.iconCls);\r
+            }\r
+            this.setIcon(Ext.isDefined(opt.icon) ? opt.icon : bufferIcon);\r
+            bwidth = updateButtons(opt.buttons);\r
+            progressBar.setVisible(opt.progress === true || opt.wait === true);\r
+            this.updateProgress(0, opt.progressText);\r
+            this.updateText(opt.msg);\r
+            if(opt.cls){\r
+                d.el.addClass(opt.cls);\r
+            }\r
+            d.proxyDrag = opt.proxyDrag === true;\r
+            d.modal = opt.modal !== false;\r
+            d.mask = opt.modal !== false ? mask : false;\r
+            if(!d.isVisible()){\r
+                // force it to the end of the z-index stack so it gets a cursor in FF\r
+                document.body.appendChild(dlg.el.dom);\r
+                d.setAnimateTarget(opt.animEl);\r
+                d.show(opt.animEl);\r
+            }\r
+\r
+            //workaround for window internally enabling keymap in afterShow\r
+            d.on('show', function(){\r
+                if(allowClose === true){\r
+                    d.keyMap.enable();\r
+                }else{\r
+                    d.keyMap.disable();\r
+                }\r
+            }, this, {single:true});\r
+\r
+            if(opt.wait === true){\r
+                progressBar.wait(opt.waitConfig);\r
+            }\r
+            return this;\r
+        },\r
+\r
+        /**\r
+         * Adds the specified icon to the dialog.  By default, the class 'ext-mb-icon' is applied for default\r
+         * styling, and the class passed in is expected to supply the background image url. Pass in empty string ('')\r
+         * to clear any existing icon. This method must be called before the MessageBox is shown.\r
+         * The following built-in icon classes are supported, but you can also pass in a custom class name:\r
+         * <pre>\r
+Ext.MessageBox.INFO\r
+Ext.MessageBox.WARNING\r
+Ext.MessageBox.QUESTION\r
+Ext.MessageBox.ERROR\r
+         *</pre>\r
+         * @param {String} icon A CSS classname specifying the icon's background image url, or empty string to clear the icon\r
+         * @return {Ext.MessageBox} this\r
+         */\r
+        setIcon : function(icon){\r
+            if(!dlg){\r
+                bufferIcon = icon;\r
+                return;\r
+            }\r
+            bufferIcon = undefined;\r
+            if(icon && icon != ''){\r
+                iconEl.removeClass('x-hidden');\r
+                iconEl.replaceClass(iconCls, icon);\r
+                bodyEl.addClass('x-dlg-icon');\r
+                iconCls = icon;\r
+            }else{\r
+                iconEl.replaceClass(iconCls, 'x-hidden');\r
+                bodyEl.removeClass('x-dlg-icon');\r
+                iconCls = '';\r
+            }\r
+            return this;\r
+        },\r
+\r
+        /**\r
+         * Displays a message box with a progress bar.  This message box has no buttons and is not closeable by\r
+         * the user.  You are responsible for updating the progress bar as needed via {@link Ext.MessageBox#updateProgress}\r
+         * and closing the message box when the process is complete.\r
+         * @param {String} title The title bar text\r
+         * @param {String} msg The message box body text\r
+         * @param {String} progressText (optional) The text to display inside the progress bar (defaults to '')\r
+         * @return {Ext.MessageBox} this\r
+         */\r
+        progress : function(title, msg, progressText){\r
+            this.show({\r
+                title : title,\r
+                msg : msg,\r
+                buttons: false,\r
+                progress:true,\r
+                closable:false,\r
+                minWidth: this.minProgressWidth,\r
+                progressText: progressText\r
+            });\r
+            return this;\r
+        },\r
+\r
+        /**\r
+         * Displays a message box with an infinitely auto-updating progress bar.  This can be used to block user\r
+         * interaction while waiting for a long-running process to complete that does not have defined intervals.\r
+         * You are responsible for closing the message box when the process is complete.\r
+         * @param {String} msg The message box body text\r
+         * @param {String} title (optional) The title bar text\r
+         * @param {Object} config (optional) A {@link Ext.ProgressBar#waitConfig} object\r
+         * @return {Ext.MessageBox} this\r
+         */\r
+        wait : function(msg, title, config){\r
+            this.show({\r
+                title : title,\r
+                msg : msg,\r
+                buttons: false,\r
+                closable:false,\r
+                wait:true,\r
+                modal:true,\r
+                minWidth: this.minProgressWidth,\r
+                waitConfig: config\r
+            });\r
+            return this;\r
+        },\r
+\r
+        /**\r
+         * Displays a standard read-only message box with an OK button (comparable to the basic JavaScript alert prompt).\r
+         * If a callback function is passed it will be called after the user clicks the button, and the\r
+         * id of the button that was clicked will be passed as the only parameter to the callback\r
+         * (could also be the top-right close button).\r
+         * @param {String} title The title bar text\r
+         * @param {String} msg The message box body text\r
+         * @param {Function} fn (optional) The callback function invoked after the message box is closed\r
+         * @param {Object} scope (optional) The scope of the callback function\r
+         * @return {Ext.MessageBox} this\r
+         */\r
+        alert : function(title, msg, fn, scope){\r
+            this.show({\r
+                title : title,\r
+                msg : msg,\r
+                buttons: this.OK,\r
+                fn: fn,\r
+                scope : scope\r
+            });\r
+            return this;\r
+        },\r
+\r
+        /**\r
+         * Displays a confirmation message box with Yes and No buttons (comparable to JavaScript's confirm).\r
+         * If a callback function is passed it will be called after the user clicks either button,\r
+         * and the id of the button that was clicked will be passed as the only parameter to the callback\r
+         * (could also be the top-right close button).\r
+         * @param {String} title The title bar text\r
+         * @param {String} msg The message box body text\r
+         * @param {Function} fn (optional) The callback function invoked after the message box is closed\r
+         * @param {Object} scope (optional) The scope of the callback function\r
+         * @return {Ext.MessageBox} this\r
+         */\r
+        confirm : function(title, msg, fn, scope){\r
+            this.show({\r
+                title : title,\r
+                msg : msg,\r
+                buttons: this.YESNO,\r
+                fn: fn,\r
+                scope : scope,\r
+                icon: this.QUESTION\r
+            });\r
+            return this;\r
+        },\r
+\r
+        /**\r
+         * Displays a message box with OK and Cancel buttons prompting the user to enter some text (comparable to JavaScript's prompt).\r
+         * The prompt can be a single-line or multi-line textbox.  If a callback function is passed it will be called after the user\r
+         * clicks either button, and the id of the button that was clicked (could also be the top-right\r
+         * close button) and the text that was entered will be passed as the two parameters to the callback.\r
+         * @param {String} title The title bar text\r
+         * @param {String} msg The message box body text\r
+         * @param {Function} fn (optional) The callback function invoked after the message box is closed\r
+         * @param {Object} scope (optional) The scope of the callback function\r
+         * @param {Boolean/Number} multiline (optional) True to create a multiline textbox using the defaultTextHeight\r
+         * property, or the height in pixels to create the textbox (defaults to false / single-line)\r
+         * @param {String} value (optional) Default value of the text input element (defaults to '')\r
+         * @return {Ext.MessageBox} this\r
+         */\r
+        prompt : function(title, msg, fn, scope, multiline, value){\r
+            this.show({\r
+                title : title,\r
+                msg : msg,\r
+                buttons: this.OKCANCEL,\r
+                fn: fn,\r
+                minWidth:250,\r
+                scope : scope,\r
+                prompt:true,\r
+                multiline: multiline,\r
+                value: value\r
+            });\r
+            return this;\r
+        },\r
+\r
+        /**\r
+         * Button config that displays a single OK button\r
+         * @type Object\r
+         */\r
+        OK : {ok:true},\r
+        /**\r
+         * Button config that displays a single Cancel button\r
+         * @type Object\r
+         */\r
+        CANCEL : {cancel:true},\r
+        /**\r
+         * Button config that displays OK and Cancel buttons\r
+         * @type Object\r
+         */\r
+        OKCANCEL : {ok:true, cancel:true},\r
+        /**\r
+         * Button config that displays Yes and No buttons\r
+         * @type Object\r
+         */\r
+        YESNO : {yes:true, no:true},\r
+        /**\r
+         * Button config that displays Yes, No and Cancel buttons\r
+         * @type Object\r
+         */\r
+        YESNOCANCEL : {yes:true, no:true, cancel:true},\r
+        /**\r
+         * The CSS class that provides the INFO icon image\r
+         * @type String\r
+         */\r
+        INFO : 'ext-mb-info',\r
+        /**\r
+         * The CSS class that provides the WARNING icon image\r
+         * @type String\r
+         */\r
+        WARNING : 'ext-mb-warning',\r
+        /**\r
+         * The CSS class that provides the QUESTION icon image\r
+         * @type String\r
+         */\r
+        QUESTION : 'ext-mb-question',\r
+        /**\r
+         * The CSS class that provides the ERROR icon image\r
+         * @type String\r
+         */\r
+        ERROR : 'ext-mb-error',\r
+\r
+        /**\r
+         * The default height in pixels of the message box's multiline textarea if displayed (defaults to 75)\r
+         * @type Number\r
+         */\r
+        defaultTextHeight : 75,\r
+        /**\r
+         * The maximum width in pixels of the message box (defaults to 600)\r
+         * @type Number\r
+         */\r
+        maxWidth : 600,\r
+        /**\r
+         * The minimum width in pixels of the message box (defaults to 100)\r
+         * @type Number\r
+         */\r
+        minWidth : 100,\r
+        /**\r
+         * The minimum width in pixels of the message box if it is a progress-style dialog.  This is useful\r
+         * for setting a different minimum width than text-only dialogs may need (defaults to 250)\r
+         * @type Number\r
+         */\r
+        minProgressWidth : 250,\r
+        /**\r
+         * An object containing the default button text strings that can be overriden for localized language support.\r
+         * Supported properties are: ok, cancel, yes and no.  Generally you should include a locale-specific\r
+         * resource file for handling language support across the framework.\r
+         * Customize the default text like so: Ext.MessageBox.buttonText.yes = "oui"; //french\r
+         * @type Object\r
+         */\r
+        buttonText : {\r
+            ok : "OK",\r
+            cancel : "Cancel",\r
+            yes : "Yes",\r
+            no : "No"\r
+        }\r
+    };\r
+}();\r
+\r
+/**\r
+ * Shorthand for {@link Ext.MessageBox}\r
+ */\r
+Ext.Msg = Ext.MessageBox;/**\r
+ * @class Ext.dd.PanelProxy\r
+ * A custom drag proxy implementation specific to {@link Ext.Panel}s. This class is primarily used internally\r
+ * for the Panel's drag drop implementation, and should never need to be created directly.\r
+ * @constructor\r
+ * @param panel The {@link Ext.Panel} to proxy for\r
+ * @param config Configuration options\r
+ */\r
+Ext.dd.PanelProxy = function(panel, config){\r
+    this.panel = panel;\r
+    this.id = this.panel.id +'-ddproxy';\r
+    Ext.apply(this, config);\r
+};\r
+\r
+Ext.dd.PanelProxy.prototype = {\r
+    /**\r
+     * @cfg {Boolean} insertProxy True to insert a placeholder proxy element while dragging the panel,\r
+     * false to drag with no proxy (defaults to true).\r
+     */\r
+    insertProxy : true,\r
+\r
+    // private overrides\r
+    setStatus : Ext.emptyFn,\r
+    reset : Ext.emptyFn,\r
+    update : Ext.emptyFn,\r
+    stop : Ext.emptyFn,\r
+    sync: Ext.emptyFn,\r
+\r
+    /**\r
+     * Gets the proxy's element\r
+     * @return {Element} The proxy's element\r
+     */\r
+    getEl : function(){\r
+        return this.ghost;\r
+    },\r
+\r
+    /**\r
+     * Gets the proxy's ghost element\r
+     * @return {Element} The proxy's ghost element\r
+     */\r
+    getGhost : function(){\r
+        return this.ghost;\r
+    },\r
+\r
+    /**\r
+     * Gets the proxy's element\r
+     * @return {Element} The proxy's element\r
+     */\r
+    getProxy : function(){\r
+        return this.proxy;\r
+    },\r
+\r
+    /**\r
+     * Hides the proxy\r
+     */\r
+    hide : function(){\r
+        if(this.ghost){\r
+            if(this.proxy){\r
+                this.proxy.remove();\r
+                delete this.proxy;\r
+            }\r
+            this.panel.el.dom.style.display = '';\r
+            this.ghost.remove();\r
+            delete this.ghost;\r
+        }\r
+    },\r
+\r
+    /**\r
+     * Shows the proxy\r
+     */\r
+    show : function(){\r
+        if(!this.ghost){\r
+            this.ghost = this.panel.createGhost(undefined, undefined, Ext.getBody());\r
             this.ghost.setXY(this.panel.el.getXY())\r
             if(this.insertProxy){\r
                 this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});\r
@@ -37853,17 +38996,19 @@ Ext.extend(Ext.state.Provider, Ext.util.Observable, {
                 return (v == "1");
             case "a":
                 var all = [];
-                var values = v.split("^");
-                for(var i = 0, len = values.length; i < len; i++){
-                    all.push(this.decodeValue(values[i]));
+                if(v != ''){
+                    Ext.each(v.split('^'), function(val){
+                        all.push(this.decodeValue(val));
+                    }, this);
                 }
                 return all;
            case "o":
                 var all = {};
-                var values = v.split("^");
-                for(var i = 0, len = values.length; i < len; i++){
-                    var kv = values[i].split("=");
-                    all[kv[0]] = this.decodeValue(kv[1]);
+                if(v != ''){
+                    Ext.each(v.split('^'), function(val){
+                        var kv = val.split('=');
+                        all[kv[0]] = this.decodeValue(kv[1]);
+                    }, this);
                 }
                 return all;
            default:
@@ -38364,16 +39509,18 @@ Ext.DataView = Ext.extend(Ext.BoxComponent, {
     // private
     onUpdate : function(ds, record){
         var index = this.store.indexOf(record);
-        var sel = this.isSelected(index);
-        var original = this.all.elements[index];
-        var node = this.bufferRender([record], index)[0];
+        if(index > -1){
+            var sel = this.isSelected(index);
+            var original = this.all.elements[index];
+            var node = this.bufferRender([record], index)[0];
 
-        this.all.replaceElement(index, node, true);
-        if(sel){
-            this.selected.replaceElement(original, node);
-            this.all.item(index).addClass(this.selectedClass);
+            this.all.replaceElement(index, node, true);
+            if(sel){
+                this.selected.replaceElement(original, node);
+                this.all.item(index).addClass(this.selectedClass);
+            }
+            this.updateIndexes(index, index);
         }
-        this.updateIndexes(index, index);
     },
 
     // private
@@ -38435,14 +39582,18 @@ Ext.DataView = Ext.extend(Ext.BoxComponent, {
      */
     bindStore : function(store, initial){
         if(!initial && this.store){
-            this.store.un("beforeload", this.onBeforeLoad, this);
-            this.store.un("datachanged", this.refresh, this);
-            this.store.un("add", this.onAdd, this);
-            this.store.un("remove", this.onRemove, this);
-            this.store.un("update", this.onUpdate, this);
-            this.store.un("clear", this.refresh, this);
             if(store !== this.store && this.store.autoDestroy){
                 this.store.destroy();
+            }else{
+                this.store.un("beforeload", this.onBeforeLoad, this);
+                this.store.un("datachanged", this.refresh, this);
+                this.store.un("add", this.onAdd, this);
+                this.store.un("remove", this.onRemove, this);
+                this.store.un("update", this.onUpdate, this);
+                this.store.un("clear", this.refresh, this);
+            }
+            if(!store){
+                this.store = null;
             }
         }
         if(store){
@@ -38927,9 +40078,10 @@ Ext.ListView = Ext.extend(Ext.DataView, {
      */\r
     /**\r
      * @cfg {Number} scrollOffset The amount of space to reserve for the scrollbar (defaults to\r
-     * <tt>19</tt> pixels)\r
+     * <tt>undefined</tt>). If an explicit value isn't specified, this will be automatically\r
+     * calculated.\r
      */\r
-    scrollOffset : 19,\r
+    scrollOffset : undefined,\r
     /**\r
      * @cfg {Boolean/Object} columnResize\r
      * Specify <tt>true</tt> or specify a configuration object for {@link Ext.ListView.ColumnResizer}\r
@@ -38977,6 +40129,11 @@ Ext.ListView = Ext.extend(Ext.DataView, {
      * The template to be used for the header row.  See {@link #tpl} for more details.\r
      */\r
 \r
+    /*\r
+     * IE has issues when setting percentage based widths to 100%. Default to 99.\r
+     */\r
+    maxWidth: Ext.isIE ? 99 : 100,\r
+    \r
     initComponent : function(){\r
         if(this.columnResize){\r
             this.colResizer = new Ext.ListView.ColumnResizer(this.colResizer);\r
@@ -39014,9 +40171,13 @@ Ext.ListView = Ext.extend(Ext.DataView, {
                 '</tpl>'\r
             );\r
         };\r
-        var cs = this.columns, allocatedWidth = 0, colsWithWidth = 0, len = cs.length;\r
+        var cs = this.columns, \r
+            allocatedWidth = 0, \r
+            colsWithWidth = 0, \r
+            len = cs.length, \r
+            columns = [];\r
         for(var i = 0; i < len; i++){\r
-            var c = cs[i];\r
+            var c = Ext.apply({}, cs[i]);\r
             if(!c.tpl){\r
                 c.tpl = new Ext.XTemplate('{' + c.dataIndex + '}');\r
             }else if(Ext.isString(c.tpl)){\r
@@ -39028,12 +40189,14 @@ Ext.ListView = Ext.extend(Ext.DataView, {
                 allocatedWidth += c.width;\r
                 colsWithWidth++;\r
             }\r
+            columns.push(c);\r
         }\r
+        cs = this.columns = columns;\r
         // auto calculate missing column widths\r
         if(colsWithWidth < len){\r
             var remaining = len - colsWithWidth;\r
-            if(allocatedWidth < 100){\r
-                var perCol = ((100-allocatedWidth) / remaining);\r
+            if(allocatedWidth < this.maxWidth){\r
+                var perCol = ((this.maxWidth-allocatedWidth) / remaining);\r
                 for(var j = 0; j < len; j++){\r
                     var c = cs[j];\r
                     if(!Ext.isNumber(c.width)){\r
@@ -39046,6 +40209,9 @@ Ext.ListView = Ext.extend(Ext.DataView, {
     },\r
 \r
     onRender : function(){\r
+        this.autoEl = {\r
+            cls: 'x-list-wrap'  \r
+        };\r
         Ext.ListView.superclass.onRender.apply(this, arguments);\r
 \r
         this.internalTpl.overwrite(this.el, {columns: this.columns});\r
@@ -39099,7 +40265,7 @@ Ext.ListView = Ext.extend(Ext.DataView, {
         }\r
         var bdp = bd.parentNode;\r
         if(Ext.isNumber(w)){\r
-            var sw = w - this.scrollOffset;\r
+            var sw = w - Ext.num(this.scrollOffset, Ext.getScrollBarWidth());\r
             if(this.reserveScrollOffset || ((bdp.offsetWidth - bdp.clientWidth) > 10)){\r
                 bd.style.width = sw + 'px';\r
                 hd.style.width = sw + 'px';\r
@@ -39114,7 +40280,7 @@ Ext.ListView = Ext.extend(Ext.DataView, {
                 }, 10);\r
             }\r
         }\r
-        if(Ext.isNumber(h == 'number')){\r
+        if(Ext.isNumber(h)){\r
             bdp.style.height = (h - hd.parentNode.offsetHeight) + 'px';\r
         }\r
     },\r
@@ -39180,13 +40346,13 @@ Ext.ListView.ColumnResizer = Ext.extend(Ext.util.Observable, {
     },\r
 \r
     handleHdMove : function(e, t){\r
-        var hw = 5;\r
-        var x = e.getPageX();\r
-        var hd = e.getTarget('em', 3, true);\r
+        var hw = 5,\r
+            x = e.getPageX(),\r
+            hd = e.getTarget('em', 3, true);\r
         if(hd){\r
-            var r = hd.getRegion();\r
-            var ss = hd.dom.style;\r
-            var pn = hd.dom.parentNode;\r
+            var r = hd.getRegion(),\r
+                ss = hd.dom.style,\r
+                pn = hd.dom.parentNode;\r
 \r
             if(x - r.left <= hw && pn != pn.parentNode.firstChild){\r
                 this.activeHd = Ext.get(pn.previousSibling.firstChild);\r
@@ -39211,8 +40377,8 @@ Ext.ListView.ColumnResizer = Ext.extend(Ext.util.Observable, {
         this.proxy = this.view.el.createChild({cls:'x-list-resizer'});\r
         this.proxy.setHeight(this.view.el.getHeight());\r
 \r
-        var x = this.tracker.getXY()[0];\r
-        var w = this.view.innerHd.getWidth();\r
+        var x = this.tracker.getXY()[0],\r
+            w = this.view.innerHd.getWidth();\r
 \r
         this.hdX = this.dragHd.getX();\r
         this.hdIndex = this.view.findHeaderIndex(this.dragHd);\r
@@ -39233,18 +40399,20 @@ Ext.ListView.ColumnResizer = Ext.extend(Ext.util.Observable, {
         var nw = this.proxy.getWidth();\r
         this.proxy.remove();\r
 \r
-        var index = this.hdIndex;\r
-        var vw = this.view, cs = vw.columns, len = cs.length;\r
-        var w = this.view.innerHd.getWidth(), minPct = this.minPct * 100;\r
-\r
-        var pct = Math.ceil((nw*100) / w);\r
-        var diff = cs[index].width - pct;\r
-        var each = Math.floor(diff / (len-1-index));\r
-        var mod = diff - (each * (len-1-index));\r
+        var index = this.hdIndex,\r
+            vw = this.view, \r
+            cs = vw.columns, \r
+            len = cs.length,\r
+            w = this.view.innerHd.getWidth(), \r
+            minPct = this.minPct * 100;\r
+            pct = Math.ceil((nw * vw.maxWidth) / w),\r
+            diff = cs[index].width - pct,\r
+            each = Math.floor(diff / (len-1-index)),\r
+            mod = diff - (each * (len-1-index));\r
 \r
         for(var i = index+1; i < len; i++){\r
-            var cw = cs[i].width + each;\r
-            var ncw = Math.max(minPct, cw);\r
+            var cw = cs[i].width + each,\r
+                ncw = Math.max(minPct, cw);\r
             if(cw != ncw){\r
                 mod += cw - ncw;\r
             }\r
@@ -39253,8 +40421,8 @@ Ext.ListView.ColumnResizer = Ext.extend(Ext.util.Observable, {
         cs[index].width = pct;\r
         cs[index+1].width += mod;\r
         delete this.dragHd;\r
-        this.view.setHdWidths();\r
-        this.view.refresh();\r
+        vw.setHdWidths();\r
+        vw.refresh();\r
         setTimeout(function(){\r
             vw.disableHeaders = false;\r
         }, 100);\r
@@ -39743,11 +40911,11 @@ new Ext.TabPanel({
     // private
     initEvents : function(){
         Ext.TabPanel.superclass.initEvents.call(this);
-        this.on('add', this.onAdd, this, {target: this});
-        this.on('remove', this.onRemove, this, {target: this});
-
-        this.mon(this.strip, 'mousedown', this.onStripMouseDown, this);
-        this.mon(this.strip, 'contextmenu', this.onStripContextMenu, this);
+        this.mon(this.strip, {
+            scope: this,
+            mousedown: this.onStripMouseDown,
+            contextmenu: this.onStripContextMenu
+        });
         if(this.enableTabScroll){
             this.mon(this.strip, 'mousewheel', this.onWheel, this);
         }
@@ -39784,6 +40952,7 @@ new Ext.TabPanel({
         if(t.close){
             if (t.item.fireEvent('beforeclose', t.item) !== false) {
                 t.item.fireEvent('close', t.item);
+                delete t.item.tabEl;
                 this.remove(t.item);
             }
             return;
@@ -39881,12 +41050,16 @@ new Ext.TabPanel({
     },
 
     // private
-    onAdd : function(tp, item, index){
-        this.initTab(item, index);
-        if(this.items.getCount() == 1){
-            this.syncSize();
+    onAdd : function(c){
+        Ext.TabPanel.superclass.onAdd.call(this, c);
+        if(this.rendered){
+            var items = this.items;
+            this.initTab(c, items.indexOf(c));
+            if(items.getCount() == 1){
+                this.syncSize();
+            }
+            this.delegateUpdates();
         }
-        this.delegateUpdates();
     },
 
     // private
@@ -39903,15 +41076,16 @@ new Ext.TabPanel({
     },
 
     // private
-    onRemove : function(tp, item){
-        Ext.destroy(Ext.get(this.getTabEl(item)));
-        this.stack.remove(item);
-        item.un('disable', this.onItemDisabled, this);
-        item.un('enable', this.onItemEnabled, this);
-        item.un('titlechange', this.onItemTitleChanged, this);
-        item.un('iconchange', this.onItemIconChanged, this);
-        item.un('beforeshow', this.onBeforeShowItem, this);
-        if(item == this.activeTab){
+    onRemove : function(c){
+        Ext.TabPanel.superclass.onRemove.call(this, c);
+        Ext.destroy(Ext.get(this.getTabEl(c)));
+        this.stack.remove(c);
+        c.un('disable', this.onItemDisabled, this);
+        c.un('enable', this.onItemEnabled, this);
+        c.un('titlechange', this.onItemTitleChanged, this);
+        c.un('iconchange', this.onItemIconChanged, this);
+        c.un('beforeshow', this.onBeforeShowItem, this);
+        if(c == this.activeTab){
             var next = this.stack.next();
             if(next){
                 this.setActiveTab(next);
@@ -39961,7 +41135,9 @@ new Ext.TabPanel({
     onItemIconChanged : function(item, iconCls, oldCls){
         var el = this.getTabEl(item);
         if(el){
-            Ext.fly(el).child('span.x-tab-strip-text').replaceClass(oldCls, iconCls);
+            el = Ext.get(el);
+            el.child('span.x-tab-strip-text').replaceClass(oldCls, iconCls);
+            el[Ext.isEmpty(iconCls) ? 'removeClass' : 'addClass']('x-tab-with-icon');
         }
     },
 
@@ -40348,7 +41524,7 @@ new Ext.TabPanel({
      * @hide
      */
     /**
-     * @property title
+     * @cfg title
      * @hide
      */
     /**
@@ -40415,7 +41591,8 @@ Ext.TabPanel.AccessStack = function(){
             return items.pop();
         }
     };
-};/**
+};
+/**
  * @class Ext.Button
  * @extends Ext.BoxComponent
  * Simple Button class
@@ -40427,7 +41604,6 @@ Ext.TabPanel.AccessStack = function(){
  * <li><code>b</code> : Button<div class="sub-desc">This Button.</div></li>
  * <li><code>e</code> : EventObject<div class="sub-desc">The click event.</div></li>
  * </ul></div>
- * @cfg {Object} scope The scope (<tt><b>this</b></tt> reference) in which the handler is executed. Defaults to this Button.
  * @cfg {Number} minWidth The minimum width for this button (used to give a set of buttons a common width).
  * See also {@link Ext.Panel}.<tt>{@link Ext.Panel#minButtonWidth minButtonWidth}</tt>.
  * @cfg {String/Object} tooltip The tooltip for the button - can be a string to be used as innerHTML (html tags are accepted) or QuickTips config object
@@ -40458,12 +41634,6 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
      * @type Boolean
      */
     pressed : false,
-    /**
-     * The Button's owner {@link Ext.Panel} (defaults to undefined, and is set automatically when
-     * the Button is added to a container).  Read-only.
-     * @type Ext.Panel
-     * @property ownerCt
-     */
 
     /**
      * @cfg {Number} tabIndex Set a DOM tabIndex for this button (defaults to undefined)
@@ -40478,7 +41648,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
      * @cfg {Boolean} enableToggle
      * True to enable pressed/not pressed toggling (defaults to false)
      */
-    enableToggle: false,
+    enableToggle : false,
     /**
      * @cfg {Function} toggleHandler
      * Function called when a Button with {@link #enableToggle} set to true is clicked. Two arguments are passed:<ul class="mdetail-params">
@@ -40512,11 +41682,12 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     type : 'button',
 
     // private
-    menuClassTarget: 'tr:nth(2)',
+    menuClassTarget : 'tr:nth(2)',
 
     /**
      * @cfg {String} clickEvent
-     * The type of event to map to the button's event handler (defaults to 'click')
+     * The DOM event that will fire the handler of the button. This can be any valid event name (dblclick, contextmenu). 
+     * Defaults to <tt>'click'</tt>.
      */
     clickEvent : 'click',
 
@@ -40538,7 +41709,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
      * DOM structure created.</p>
      * <p>When a custom {@link #template} is used, you  must ensure that this selector results in the selection of
      * a focussable element.</p>
-     * <p>Defaults to <b><tt>"button:first-child"</tt></b>.</p>
+     * <p>Defaults to <b><tt>'button:first-child'</tt></b>.</p>
      */
     buttonSelector : 'button:first-child',
 
@@ -40552,7 +41723,13 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
      * </ul>
      * <p>Defaults to <b><tt>'small'</tt></b>.</p>
      */
-    scale: 'small',
+    scale : 'small',
+
+    /**
+     * @cfg {Object} scope The scope (<tt><b>this</b></tt> reference) in which the
+     * <code>{@link #handler}</code> and <code>{@link #toggleHandler}</code> is
+     * executed. Defaults to this Button.
+     */
 
     /**
      * @cfg {String} iconAlign
@@ -40744,7 +41921,12 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
         this.el = btn;
 
         if(this.id){
-            this.el.dom.id = this.el.id = this.id;
+            var d = this.el.dom,
+                c = Ext.Element.cache;
+                
+            delete c[d.id];
+            d.id = this.el.id = this.id;
+            c[d.id] = this.el;
         }
         if(this.icon){
             btnEl.setStyle('background-image', 'url(' +this.icon +')');
@@ -40762,7 +41944,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
                 mouseover: this.onMouseOver,
                 mousedown: this.onMouseDown
             });
-            
+
             // new functionality for monitoring on the document level
             //this.mon(btn, 'mouseout', this.onMouseOut, this);
         }
@@ -40779,7 +41961,6 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
             var repeater = new Ext.util.ClickRepeater(btn, Ext.isObject(this.repeat) ? this.repeat : {});
             this.mon(repeater, 'click', this.onClick, this);
         }
-        
         this.mon(btn, this.clickEvent, this.onClick, this);
     },
 
@@ -40829,16 +42010,16 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
         }
         return this;
     },
-    
+
     // private
-    clearTip: function(){
+    clearTip : function(){
         if(Ext.isObject(this.tooltip)){
             Ext.QuickTips.unregister(this.btnEl);
         }
     },
-    
+
     // private
-    beforeDestroy: function(){
+    beforeDestroy : function(){
         if(this.rendered){
             this.clearTip();
         }
@@ -40877,7 +42058,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     /**
      * Assigns this Button's click handler
      * @param {Function} handler The function to call when the button is clicked
-     * @param {Object} scope (optional) Scope for the function passed in
+     * @param {Object} scope (optional) Scope for the function passed in. Defaults to this Button.
      * @return {Ext.Button} this
      */
     setHandler : function(handler, scope){
@@ -40917,7 +42098,9 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     toggle : function(state, suppressEvent){
         state = state === undefined ? !this.pressed : !!state;
         if(state != this.pressed){
-            this.el[state ? 'addClass' : 'removeClass']('x-btn-pressed');
+            if(this.rendered){
+                this.el[state ? 'addClass' : 'removeClass']('x-btn-pressed');
+            }
             this.pressed = state;
             if(!suppressEvent){
                 this.fireEvent('toggle', this, state);
@@ -40945,7 +42128,7 @@ Ext.Button = Ext.extend(Ext.BoxComponent, {
     onEnable : function(){
         this.onDisableChange(false);
     },
-    
+
     onDisableChange : function(disabled){
         if(this.el){
             if(!Ext.isIE6 || !this.text){
@@ -41364,8 +42547,8 @@ Ext.CycleButton = Ext.extend(Ext.SplitButton, {
      * @param {Boolean} suppressEvent True to prevent the button's change event from firing (defaults to false)\r
      */\r
     setActiveItem : function(item, suppressEvent){\r
-        if(typeof item != 'object'){\r
-            item = this.menu.items.get(item);\r
+        if(!Ext.isObject(item)){\r
+            item = this.menu.getComponent(item);\r
         }\r
         if(item){\r
             if(!this.rendered){\r
@@ -41422,18 +42605,19 @@ Ext.CycleButton = Ext.extend(Ext.SplitButton, {
 \r
         this.menu = {cls:'x-cycle-menu', items:[]};\r
         var checked;\r
-        for(var i = 0, len = this.itemCount; i < len; i++){\r
-            var item = this.items[i];\r
-            item.group = item.group || this.id;\r
-            item.itemIndex = i;\r
-            item.checkHandler = this.checkHandler;\r
-            item.scope = this;\r
-            item.checked = item.checked || false;\r
+        Ext.each(this.items, function(item, i){\r
+            Ext.apply(item, {\r
+                group: item.group || this.id,\r
+                itemIndex: i,\r
+                checkHandler: this.checkHandler,\r
+                scope: this,\r
+                checked: item.checked || false\r
+            });\r
             this.menu.items.push(item);\r
             if(item.checked){\r
                 checked = item;\r
             }\r
-        }\r
+        }, this);\r
         this.setActiveItem(checked, true);\r
         Ext.CycleButton.superclass.initComponent.call(this);\r
 \r
@@ -41453,13 +42637,18 @@ Ext.CycleButton = Ext.extend(Ext.SplitButton, {
      * the active item will be set to the first item in the menu.\r
      */\r
     toggleSelected : function(){\r
-        this.menu.render();\r
+        var m = this.menu;\r
+        m.render();\r
+        // layout if we haven't before so the items are active\r
+        if(!m.hasLayout){\r
+            m.doLayout();\r
+        }\r
         \r
         var nextIdx, checkItem;\r
         for (var i = 1; i < this.itemCount; i++) {\r
             nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;\r
             // check the potential item\r
-            checkItem = this.menu.items.itemAt(nextIdx);\r
+            checkItem = m.items.itemAt(nextIdx);\r
             // if its not disabled then check it.\r
             if (!checkItem.disabled) {\r
                 checkItem.setChecked(true);\r
@@ -41651,7 +42840,7 @@ Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
     clearMenu : function(){\r
         var m = this.moreMenu;\r
         if(m && m.items){\r
-            this.moreMenu.items.each(function(item){\r
+            m.items.each(function(item){\r
                 delete item.menu;\r
             });\r
         }\r
@@ -41694,6 +42883,7 @@ Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
                     scope: this\r
                 }\r
             });\r
+            this.moreMenu.ownerCt = this.container;\r
             this.more = new Ext.Button({\r
                 iconCls: 'x-toolbar-more-icon',\r
                 cls: 'x-toolbar-more',\r
@@ -41831,6 +43021,15 @@ Ext.extend(T, Ext.Container, {
 \r
     defaultType: 'button',\r
 \r
+    /**\r
+     * @cfg {String/Object} layout\r
+     * This class assigns a default layout (<code>layout:'<b>toolbar</b>'</code>).\r
+     * Developers <i>may</i> override this configuration option if another layout\r
+     * is required (the constructor must be passed a configuration object in this\r
+     * case instead of an array).\r
+     * See {@link Ext.Container#layout} for additional information.\r
+     */\r
+\r
     trackMenus : true,\r
     internalDefaults: {removeMode: 'container', hideParent: true},\r
     toolbarCls: 'x-toolbar',\r
@@ -41856,12 +43055,14 @@ Ext.extend(T, Ext.Container, {
                 };\r
             }\r
             this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);\r
+            Ext.Toolbar.superclass.onRender.apply(this, arguments);\r
         }\r
     },\r
 \r
     /**\r
-     * Adds element(s) to the toolbar -- this function takes a variable number of\r
-     * arguments of mixed type and adds them to the toolbar.\r
+     * <p>Adds element(s) to the toolbar -- this function takes a variable number of\r
+     * arguments of mixed type and adds them to the toolbar.</p>\r
+     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>\r
      * @param {Mixed} arg1 The following types of arguments are all valid:<br />\r
      * <ul>\r
      * <li>{@link Ext.Button} config: A valid button config object (equivalent to {@link #addButton})</li>\r
@@ -41928,6 +43129,7 @@ Ext.extend(T, Ext.Container, {
 \r
     /**\r
      * Adds a separator\r
+     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>\r
      * @return {Ext.Toolbar.Item} The separator {@link Ext.Toolbar.Item item}\r
      */\r
     addSeparator : function(){\r
@@ -41936,6 +43138,7 @@ Ext.extend(T, Ext.Container, {
 \r
     /**\r
      * Adds a spacer element\r
+     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>\r
      * @return {Ext.Toolbar.Spacer} The spacer item\r
      */\r
     addSpacer : function(){\r
@@ -41944,6 +43147,7 @@ Ext.extend(T, Ext.Container, {
 \r
     /**\r
      * Forces subsequent additions into the float:right toolbar\r
+     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>\r
      */\r
     addFill : function(){\r
         this.add(new T.Fill());\r
@@ -41951,6 +43155,7 @@ Ext.extend(T, Ext.Container, {
 \r
     /**\r
      * Adds any standard HTML element to the toolbar\r
+     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>\r
      * @param {Mixed} el The element or id of the element to add\r
      * @return {Ext.Toolbar.Item} The element's item\r
      */\r
@@ -41960,15 +43165,17 @@ Ext.extend(T, Ext.Container, {
 \r
     /**\r
      * Adds any Toolbar.Item or subclass\r
+     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>\r
      * @param {Ext.Toolbar.Item} item\r
      * @return {Ext.Toolbar.Item} The item\r
      */\r
     addItem : function(item){\r
-        return Ext.Toolbar.superclass.add.apply(this, arguments);\r
+        return this.add.apply(this, arguments);\r
     },\r
 \r
     /**\r
      * Adds a button (or buttons). See {@link Ext.Button} for more info on the config.\r
+     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>\r
      * @param {Object/Array} config A button config or array of configs\r
      * @return {Ext.Button/Array}\r
      */\r
@@ -41985,6 +43192,7 @@ Ext.extend(T, Ext.Container, {
 \r
     /**\r
      * Adds text to the toolbar\r
+     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>\r
      * @param {String} text The text to add\r
      * @return {Ext.Toolbar.Item} The element's item\r
      */\r
@@ -41994,6 +43202,7 @@ Ext.extend(T, Ext.Container, {
 \r
     /**\r
      * Adds a new element to the toolbar from the passed {@link Ext.DomHelper} config\r
+     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>\r
      * @param {Object} config\r
      * @return {Ext.Toolbar.Item} The element's item\r
      */\r
@@ -42004,6 +43213,7 @@ Ext.extend(T, Ext.Container, {
     /**\r
      * Adds a dynamically rendered Ext.form field (TextField, ComboBox, etc). Note: the field should not have\r
      * been rendered yet. For a field that has already been rendered, use {@link #addElement}.\r
+     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>\r
      * @param {Ext.form.Field} field\r
      * @return {Ext.Toolbar.Item}\r
      */\r
@@ -42013,6 +43223,7 @@ Ext.extend(T, Ext.Container, {
 \r
     /**\r
      * Inserts any {@link Ext.Toolbar.Item}/{@link Ext.Button} at the specified index.\r
+     * <br><p><b>Note</b>: See the notes within {@link Ext.Container#add}.</p>\r
      * @param {Number} index The index where the item is to be inserted\r
      * @param {Object/Ext.Toolbar.Item/Ext.Button/Array} item The button, or button config object to be\r
      * inserted, or an array of buttons/configs.\r
@@ -42214,23 +43425,29 @@ new Ext.Panel({
  * @xtype tbtext\r
  */\r
 T.TextItem = Ext.extend(T.Item, {\r
+    /**\r
+     * @cfg {String} text The text to be used as innerHTML (html tags are accepted)\r
+     */ \r
+\r
     constructor: function(config){\r
-        if (Ext.isString(config)) {\r
-            config = { autoEl: {cls: 'xtb-text', html: config }};\r
-        } else {\r
-            config.autoEl = {cls: 'xtb-text', html: config.text || ''};\r
-        }\r
-        T.TextItem.superclass.constructor.call(this, config);\r
+        T.TextItem.superclass.constructor.call(this, Ext.isString(config) ? {text: config} : config);\r
+    },\r
+    \r
+    // private\r
+    onRender : function(ct, position) {\r
+        this.autoEl = {cls: 'xtb-text', html: this.text || ''};\r
+        T.TextItem.superclass.onRender.call(this, ct, position);\r
     },\r
+    \r
     /**\r
      * Updates this item's text, setting the text to be used as innerHTML.\r
      * @param {String} t The text to display (html accepted).\r
      */\r
     setText : function(t) {\r
-        if (this.rendered) {\r
-            this.el.dom.innerHTML = t;\r
-        } else {\r
-            this.autoEl.html = t;\r
+        if(this.rendered){\r
+            this.el.update(t);\r
+        }else{\r
+            this.text = t;\r
         }\r
     }\r
 });\r
@@ -42359,10 +43576,14 @@ Ext.reg('buttongroup', Ext.ButtonGroup);
 Ext.QuickTips.init(); // to display button quicktips
 
 var myStore = new Ext.data.Store({
+    reader: new Ext.data.JsonReader({
+        {@link Ext.data.JsonReader#totalProperty totalProperty}: 'results', 
+        ...
+    }),
     ...
 });
 
-var myPageSize = 25;  // server script should only send back 25 items
+var myPageSize = 25;  // server script should only send back 25 items at a time
 
 var grid = new Ext.grid.GridPanel({
     ...
@@ -42383,20 +43604,43 @@ var grid = new Ext.grid.GridPanel({
  * <pre><code>
 store.load({
     params: {
-        start: 0,          // specify params for the first page load if using paging
+        // specify params for the first page load if using paging
+        start: 0,          
         limit: myPageSize,
+        // other params
         foo:   'bar'
     }
 });
+ * </code></pre>
+ * 
+ * <p>If using {@link Ext.data.Store#autoLoad store's autoLoad} configuration:</p>
+ * <pre><code>
+var myStore = new Ext.data.Store({
+    {@link Ext.data.Store#autoLoad autoLoad}: {params:{start: 0, limit: 25}},
+    ...
+});
+ * </code></pre>
+ * 
+ * <p>The packet sent back from the server would have this form:</p>
+ * <pre><code>
+{
+    "success": true,
+    "results": 2000, 
+    "rows": [ // <b>*Note:</b> this must be an Array 
+        { "id":  1, "name": "Bill", "occupation": "Gardener" },
+        { "id":  2, "name":  "Ben", "occupation": "Horticulturalist" },
+        ...
+        { "id": 25, "name":  "Sue", "occupation": "Botanist" }
+    ]
+}
  * </code></pre>
  * <p><u>Paging with Local Data</u></p>
  * <p>Paging can also be accomplished with local data using extensions:</p>
  * <div class="mdetail-params"><ul>
- * <li><a href="http://extjs.com/forum/showthread.php?t=57386">Ext.ux.data.PagingStore</a></li>
+ * <li><a href="http://extjs.com/forum/showthread.php?t=71532">Ext.ux.data.PagingStore</a></li>
  * <li>Paging Memory Proxy (examples/ux/PagingMemoryProxy.js)</li>
  * </ul></div>
- * @constructor
- * Create a new PagingToolbar
+ * @constructor Create a new PagingToolbar
  * @param {Object} config The config object
  * @xtype paging
  */
@@ -42481,10 +43725,13 @@ Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
     refreshText : 'Refresh',
 
     /**
-     * @deprecated
-     * <b>The defaults for these should be set in the data store.</b>
-     * Object mapping of parameter names used for load calls, initially set to:
+     * <p><b>Deprecated</b>. <code>paramNames</code> should be set in the <b>data store</b>
+     * (see {@link Ext.data.Store#paramNames}).</p>
+     * <br><p>Object mapping of parameter names used for load calls, initially set to:</p>
      * <pre>{start: 'start', limit: 'limit'}</pre>
+     * @type Object
+     * @property paramNames
+     * @deprecated
      */
 
     /**
@@ -42550,7 +43797,7 @@ Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
             tooltip: this.refreshText,
             overflowText: this.refreshText,
             iconCls: 'x-tbar-loading',
-            handler: this.refresh,
+            handler: this.doRefresh,
             scope: this
         })];
 
@@ -42600,7 +43847,7 @@ Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
         );
         this.on('afterlayout', this.onFirstLayout, this, {single: true});
         this.cursor = 0;
-        this.bindStore(this.store);
+        this.bindStore(this.store, true);
     },
 
     // private
@@ -42725,6 +43972,12 @@ Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
         return this.paramNames || this.store.paramNames;
     },
 
+    // private
+    getParams : function(){
+        //retain backwards compat, allow params on the toolbar itself, if they exist.
+        return this.paramNames || this.store.paramNames;
+    },
+
     // private
     beforeLoad : function(){
         if(this.rendered && this.refresh){
@@ -42776,7 +44029,7 @@ Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
     /**
      * Refresh the current page, has the same effect as clicking the 'refresh' button.
      */
-    refresh : function(){
+    doRefresh : function(){
         this.doLoad(this.cursor);
     },
 
@@ -42788,11 +44041,15 @@ Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
     bindStore : function(store, initial){
         var doLoad;
         if(!initial && this.store){
-            this.store.un('beforeload', this.beforeLoad, this);
-            this.store.un('load', this.onLoad, this);
-            this.store.un('exception', this.onLoadError, this);
             if(store !== this.store && this.store.autoDestroy){
                 this.store.destroy();
+            }else{
+                this.store.un('beforeload', this.beforeLoad, this);
+                this.store.un('load', this.onLoad, this);
+                this.store.un('exception', this.onLoadError, this);
+            }
+            if(!store){
+                this.store = null;
             }
         }
         if(store){
@@ -42803,7 +44060,7 @@ Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
                 load: this.onLoad,
                 exception: this.onLoadError
             });
-            doLoad = store.getCount() > 0;
+            doLoad = true;
         }
         this.store = store;
         if(doLoad){
@@ -43034,6 +44291,7 @@ tabPanel.on('tabchange', function(tabPanel, tab){
 Ext.apply(Ext.History, new Ext.util.Observable());/**\r
  * @class Ext.Tip\r
  * @extends Ext.Panel\r
+ * @xtype tip\r
  * This is the base class for {@link Ext.QuickTip} and {@link Ext.Tooltip} that provides the basic layout and\r
  * positioning that all tip-based classes require. This class can be used directly for simple, statically-positioned\r
  * tips that are displayed programmatically, or it can be extended to provide custom tip implementations.\r
@@ -43162,6 +44420,8 @@ tip.showBy('my-el', 'tl-tr');
     }\r
 });\r
 \r
+Ext.reg('tip', Ext.Tip);\r
+\r
 // private - custom Tip DD implementation\r
 Ext.Tip.DD = function(tip, config){\r
     Ext.apply(this, config);\r
@@ -43185,69 +44445,85 @@ Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
  * @class Ext.ToolTip\r
  * @extends Ext.Tip\r
  * A standard tooltip implementation for providing additional information when hovering over a target element.\r
+ * @xtype tooltip\r
  * @constructor\r
  * Create a new Tooltip\r
  * @param {Object} config The configuration options\r
  */\r
 Ext.ToolTip = Ext.extend(Ext.Tip, {\r
     /**\r
-     * When a Tooltip is configured with the {@link #delegate} option to cause selected child elements of the {@link #target}\r
-     * Element to each trigger a seperate show event, this property is set to the DOM element which triggered the show.\r
+     * When a Tooltip is configured with the <code>{@link #delegate}</code>\r
+     * option to cause selected child elements of the <code>{@link #target}</code>\r
+     * Element to each trigger a seperate show event, this property is set to\r
+     * the DOM element which triggered the show.\r
      * @type DOMElement\r
      * @property triggerElement\r
      */\r
     /**\r
-     * @cfg {Mixed} target The target HTMLElement, Ext.Element or id to monitor for mouseover events to trigger\r
-     * showing this ToolTip.\r
+     * @cfg {Mixed} target The target HTMLElement, Ext.Element or id to monitor\r
+     * for mouseover events to trigger showing this ToolTip.\r
      */\r
     /**\r
-     * @cfg {Boolean} autoHide True to automatically hide the tooltip after the mouse exits the target element\r
-     * or after the {@link #dismissDelay} has expired if set (defaults to true).  If {@link closable} = true a close\r
-     * tool button will be rendered into the tooltip header.\r
+     * @cfg {Boolean} autoHide True to automatically hide the tooltip after the\r
+     * mouse exits the target element or after the <code>{@link #dismissDelay}</code>\r
+     * has expired if set (defaults to true).  If <code>{@link closable} = true</code>\r
+     * a close tool button will be rendered into the tooltip header.\r
      */\r
     /**\r
-     * @cfg {Number} showDelay Delay in milliseconds before the tooltip displays after the mouse enters the\r
-     * target element (defaults to 500)\r
+     * @cfg {Number} showDelay Delay in milliseconds before the tooltip displays\r
+     * after the mouse enters the target element (defaults to 500)\r
      */\r
-    showDelay: 500,\r
+    showDelay : 500,\r
     /**\r
-     * @cfg {Number} hideDelay Delay in milliseconds after the mouse exits the target element but before the\r
-     * tooltip actually hides (defaults to 200).  Set to 0 for the tooltip to hide immediately.\r
+     * @cfg {Number} hideDelay Delay in milliseconds after the mouse exits the\r
+     * target element but before the tooltip actually hides (defaults to 200).\r
+     * Set to 0 for the tooltip to hide immediately.\r
      */\r
-    hideDelay: 200,\r
+    hideDelay : 200,\r
     /**\r
-     * @cfg {Number} dismissDelay Delay in milliseconds before the tooltip automatically hides (defaults to 5000).\r
-     * To disable automatic hiding, set dismissDelay = 0.\r
+     * @cfg {Number} dismissDelay Delay in milliseconds before the tooltip\r
+     * automatically hides (defaults to 5000). To disable automatic hiding, set\r
+     * dismissDelay = 0.\r
      */\r
-    dismissDelay: 5000,\r
+    dismissDelay : 5000,\r
     /**\r
-     * @cfg {Array} mouseOffset An XY offset from the mouse position where the tooltip should be shown (defaults to [15,18]).\r
+     * @cfg {Array} mouseOffset An XY offset from the mouse position where the\r
+     * tooltip should be shown (defaults to [15,18]).\r
      */\r
     /**\r
-     * @cfg {Boolean} trackMouse True to have the tooltip follow the mouse as it moves over the target element (defaults to false).\r
+     * @cfg {Boolean} trackMouse True to have the tooltip follow the mouse as it\r
+     * moves over the target element (defaults to false).\r
      */\r
     trackMouse : false,\r
     /**\r
-     * @cfg {Boolean} anchorToTarget True to anchor the tooltip to the target element, false to\r
-     * anchor it relative to the mouse coordinates (defaults to true).  When anchorToTarget is\r
-     * true, use {@link #defaultAlign} to control tooltip alignment to the target element.  When\r
-     * anchorToTarget is false, use {@link #anchorPosition} instead to control alignment.\r
-     */\r
-    anchorToTarget: true,\r
-    /**\r
-     * @cfg {Number} anchorOffset A numeric pixel value used to offset the default position of the\r
-     * anchor arrow (defaults to 0).  When the anchor position is on the top or bottom of the tooltip,\r
-     * anchorOffset will be used as a horizontal offset.  Likewise, when the anchor position is on the\r
-     * left or right side, anchorOffset will be used as a vertical offset.\r
-     */\r
-    anchorOffset: 0,\r
-    /**\r
-     * @cfg {String} delegate <p>Optional. A {@link Ext.DomQuery DomQuery} selector which allows selection of individual elements\r
-     * within the {@link #target} element to trigger showing and hiding the ToolTip as the mouse moves within the target.</p>\r
-     * <p>When specified, the child element of the target which caused a show event is placed into the {@link #triggerElement} property\r
+     * @cfg {Boolean} anchorToTarget True to anchor the tooltip to the target\r
+     * element, false to anchor it relative to the mouse coordinates (defaults\r
+     * to true).  When <code>anchorToTarget</code> is true, use\r
+     * <code>{@link #defaultAlign}</code> to control tooltip alignment to the\r
+     * target element.  When <code>anchorToTarget</code> is false, use\r
+     * <code>{@link #anchorPosition}</code> instead to control alignment.\r
+     */\r
+    anchorToTarget : true,\r
+    /**\r
+     * @cfg {Number} anchorOffset A numeric pixel value used to offset the\r
+     * default position of the anchor arrow (defaults to 0).  When the anchor\r
+     * position is on the top or bottom of the tooltip, <code>anchorOffset</code>\r
+     * will be used as a horizontal offset.  Likewise, when the anchor position\r
+     * is on the left or right side, <code>anchorOffset</code> will be used as\r
+     * a vertical offset.\r
+     */\r
+    anchorOffset : 0,\r
+    /**\r
+     * @cfg {String} delegate <p>Optional. A {@link Ext.DomQuery DomQuery}\r
+     * selector which allows selection of individual elements within the\r
+     * <code>{@link #target}</code> element to trigger showing and hiding the\r
+     * ToolTip as the mouse moves within the target.</p>\r
+     * <p>When specified, the child element of the target which caused a show\r
+     * event is placed into the <code>{@link #triggerElement}</code> property\r
      * before the ToolTip is shown.</p>\r
-     * <p>This may be useful when a Component has regular, repeating elements in it, each of which need a Tooltip which contains\r
-     * information specific to that element. For example:</p><pre><code>\r
+     * <p>This may be useful when a Component has regular, repeating elements\r
+     * in it, each of which need a Tooltip which contains information specific\r
+     * to that element. For example:</p><pre><code>\r
 var myGrid = new Ext.grid.gridPanel(gridConfig);\r
 myGrid.on('render', function(grid) {\r
     var store = grid.getStore();  // Capture the Store.\r
@@ -43256,24 +44532,27 @@ myGrid.on('render', function(grid) {
         target: view.mainBody,    // The overall target element.\r
         delegate: '.x-grid3-row', // Each grid row causes its own seperate show and hide.\r
         trackMouse: true,         // Moving within the row should not hide the tip.\r
-        renderTo: document.body,  // Render immediately so that tip.body can be referenced prior to the first show.\r
-        listeners: {              // Change content dynamically depending on which element triggered the show.\r
+        renderTo: document.body,  // Render immediately so that tip.body can be\r
+                                  //  referenced prior to the first show.\r
+        listeners: {              // Change content dynamically depending on which element\r
+                                  //  triggered the show.\r
             beforeshow: function updateTipBody(tip) {\r
                 var rowIndex = view.findRowIndex(tip.triggerElement);\r
-                tip.body.dom.innerHTML = "Over Record ID " + store.getAt(rowIndex).id;\r
+                tip.body.dom.innerHTML = 'Over Record ID ' + store.getAt(rowIndex).id;\r
             }\r
         }\r
     });\r
-});</code></pre>\r
+});\r
+     *</code></pre>\r
      */\r
 \r
     // private\r
-    targetCounter: 0,\r
+    targetCounter : 0,\r
 \r
-    constrainPosition: false,\r
+    constrainPosition : false,\r
 \r
     // private\r
-    initComponent: function(){\r
+    initComponent : function(){\r
         Ext.ToolTip.superclass.initComponent.call(this);\r
         this.lastActive = new Date();\r
         this.initTarget(this.target);\r
@@ -43303,10 +44582,10 @@ myGrid.on('render', function(grid) {
         var t;\r
         if((t = Ext.get(target))){\r
             if(this.target){\r
-                this.target = Ext.get(this.target);\r
-                this.target.un('mouseover', this.onTargetOver, this);\r
-                this.target.un('mouseout', this.onTargetOut, this);\r
-                this.target.un('mousemove', this.onMouseMove, this);\r
+                var tg = Ext.get(this.target);\r
+                this.mun(tg, 'mouseover', this.onTargetOver, this);\r
+                this.mun(tg, 'mouseout', this.onTargetOut, this);\r
+                this.mun(tg, 'mousemove', this.onMouseMove, this);\r
             }\r
             this.mon(t, {\r
                 mouseover: this.onTargetOver,\r
@@ -43342,6 +44621,9 @@ myGrid.on('render', function(grid) {
 \r
     // private\r
     getTargetXY : function(){\r
+        if(this.delegate){\r
+            this.anchorTarget = this.triggerElement;\r
+        }\r
         if(this.anchor){\r
             this.targetCounter++;\r
             var offsets = this.getOffsets();\r
@@ -43419,7 +44701,7 @@ myGrid.on('render', function(grid) {
         }else{\r
             var m = this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);\r
             if(!m){\r
-               throw "AnchorTip.defaultAlign is invalid";\r
+               throw 'AnchorTip.defaultAlign is invalid';\r
             }\r
             this.tipAnchor = m[1].charAt(0);\r
         }\r
@@ -43443,7 +44725,7 @@ myGrid.on('render', function(grid) {
     },\r
 \r
     // private\r
-    getOffsets: function(){\r
+    getOffsets : function(){\r
         var offsets, ap = this.getAnchorPosition().charAt(0);\r
         if(this.anchorToTarget && !this.trackMouse){\r
             switch(ap){\r
@@ -43572,6 +44854,10 @@ myGrid.on('render', function(grid) {
         if(this.dismissDelay && this.autoHide !== false){\r
             this.dismissTimer = this.hide.defer(this.dismissDelay, this);\r
         }\r
+        if(this.anchor && !this.anchorEl.isVisible()){\r
+            this.syncAnchor();\r
+            this.anchorEl.show();\r
+        }\r
     },\r
 \r
     // private\r
@@ -43666,9 +44952,12 @@ myGrid.on('render', function(grid) {
         Ext.getDoc().un('mousedown', this.onDocMouseDown, this);\r
         Ext.ToolTip.superclass.onDestroy.call(this);\r
     }\r
-});/**\r
+});\r
+\r
+Ext.reg('tooltip', Ext.ToolTip);/**\r
  * @class Ext.QuickTip\r
  * @extends Ext.ToolTip\r
+ * @xtype quicktip\r
  * A specialized tooltip class for tooltips that can be specified in markup and automatically managed by the global\r
  * {@link Ext.QuickTips} instance.  See the QuickTips class header for additional usage details and examples.\r
  * @constructor\r
@@ -43758,6 +45047,23 @@ Ext.QuickTip = Ext.extend(Ext.ToolTip, {
         }\r
     },\r
 \r
+    // private\r
+    getTipCfg: function(e) {\r
+        var t = e.getTarget(), \r
+            ttp, \r
+            cfg;\r
+        if(this.interceptTitles && t.title){\r
+            ttp = t.title;\r
+            t.qtip = ttp;\r
+            t.removeAttribute("title");\r
+            e.preventDefault();\r
+        }else{\r
+            cfg = this.tagConfig;\r
+            ttp = t.qtip || Ext.fly(t).getAttribute(cfg.attribute, cfg.namespace);\r
+        }\r
+        return ttp;\r
+    },\r
+\r
     // private\r
     onTargetOver : function(e){\r
         if(this.disabled){\r
@@ -43768,7 +45074,7 @@ Ext.QuickTip = Ext.extend(Ext.ToolTip, {
         if(!t || t.nodeType !== 1 || t == document || t == document.body){\r
             return;\r
         }\r
-        if(this.activeTarget && t == this.activeTarget.el){\r
+        if(this.activeTarget && ((t == this.activeTarget.el) || Ext.fly(this.activeTarget.el).contains(t))){\r
             this.clearTimer('hide');\r
             this.show();\r
             return;\r
@@ -43783,18 +45089,8 @@ Ext.QuickTip = Ext.extend(Ext.ToolTip, {
             this.delayShow();\r
             return;\r
         }\r
-        \r
-        var ttp, et = Ext.fly(t), cfg = this.tagConfig;\r
-        var ns = cfg.namespace;\r
-        if(this.interceptTitles && t.title){\r
-            ttp = t.title;\r
-            t.qtip = ttp;\r
-            t.removeAttribute("title");\r
-            e.preventDefault();\r
-        } else{\r
-            ttp = t.qtip || et.getAttribute(cfg.attribute, ns);\r
-        }\r
-        if(ttp){\r
+        var ttp, et = Ext.fly(t), cfg = this.tagConfig, ns = cfg.namespace;\r
+        if(ttp = this.getTipCfg(e)){\r
             var autoHide = et.getAttribute(cfg.hide, ns);\r
             this.activeTarget = {\r
                 el: t,\r
@@ -43816,6 +45112,12 @@ Ext.QuickTip = Ext.extend(Ext.ToolTip, {
 \r
     // private\r
     onTargetOut : function(e){\r
+\r
+        // If moving within the current target, and it does not have a new tip, ignore the mouseout\r
+        if (this.activeTarget && e.within(this.activeTarget.el) && !this.getTipCfg(e)) {\r
+            return;\r
+        }\r
+\r
         this.clearTimer('show');\r
         if(this.autoHide !== false){\r
             this.delayHide();\r
@@ -43866,7 +45168,8 @@ Ext.QuickTip = Ext.extend(Ext.ToolTip, {
         delete this.activeTarget;\r
         Ext.QuickTip.superclass.hide.call(this);\r
     }\r
-});/**\r
+});\r
+Ext.reg('quicktip', Ext.QuickTip);/**\r
  * @class Ext.QuickTips\r
  * <p>Provides attractive and customizable tooltips for any element. The QuickTips\r
  * singleton is used to configure and manage tooltips globally for multiple elements\r
@@ -44137,6 +45440,13 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
     enableDD : false,\r
     hlDrop : Ext.enableFx,\r
     pathSeparator: "/",\r
+    \r
+    /**\r
+     * @cfg {Array} bubbleEvents\r
+     * <p>An array of events that, when fired, should be bubbled to any parent container.\r
+     * Defaults to <tt>['add', 'remove']</tt>.\r
+     */\r
+    bubbleEvents: [],\r
 \r
     initComponent : function(){\r
         Ext.tree.TreePanel.superclass.initComponent.call(this);\r
@@ -44322,6 +45632,13 @@ Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
             */\r
             "checkchange",\r
             /**\r
+            * @event beforedblclick\r
+            * Fires before double click processing on a node. Return false to cancel the default action.\r
+            * @param {Node} node The node\r
+            * @param {Ext.EventObject} e The event object\r
+            */\r
+            "beforedblclick",\r
+            /**\r
             * @event dblclick\r
             * Fires when a node is double clicked\r
             * @param {Node} node The node\r
@@ -44651,9 +45968,9 @@ new Ext.tree.TreePanel({
      */\r
     selectPath : function(path, attr, callback){\r
         attr = attr || "id";\r
-        var keys = path.split(this.pathSeparator);\r
-        var v = keys.pop();\r
-        if(keys.length > 0){\r
+        var keys = path.split(this.pathSeparator),\r
+            v = keys.pop();\r
+        if(keys.length > 1){\r
             var f = function(success, node){\r
                 if(success && node){\r
                     var n = node.findChild(attr, v);\r
@@ -44936,14 +46253,21 @@ Ext.reg('treepanel', Ext.tree.TreePanel);Ext.tree.TreeEventModel = function(tree
 \r
 Ext.tree.TreeEventModel.prototype = {\r
     initEvents : function(){\r
-        var el = this.tree.getTreeEl();\r
-        el.on('click', this.delegateClick, this);\r
-        if(this.tree.trackMouseOver !== false){\r
-            this.tree.innerCt.on('mouseover', this.delegateOver, this);\r
-            this.tree.innerCt.on('mouseout', this.delegateOut, this);\r
+        var t = this.tree;\r
+            \r
+        if(t.trackMouseOver !== false){\r
+            t.mon(t.innerCt, {\r
+                scope: this,\r
+                mouseover: this.delegateOver,\r
+                mouseout: this.delegateOut\r
+            });\r
         }\r
-        el.on('dblclick', this.delegateDblClick, this);\r
-        el.on('contextmenu', this.delegateContextMenu, this);\r
+        t.mon(t.getTreeEl(), {\r
+            scope: this,\r
+            click: this.delegateClick,\r
+            dblclick: this.delegateDblClick,\r
+            contextmenu: this.delegateContextMenu\r
+        });\r
     },\r
 \r
     getNode : function(e){\r
@@ -45125,7 +46449,7 @@ Ext.tree.DefaultSelectionModel = function(config){
 Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {\r
     init : function(tree){\r
         this.tree = tree;\r
-        tree.getTreeEl().on("keydown", this.onKeyDown, this);\r
+        tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);\r
         tree.on("click", this.onNodeClick, this);\r
     },\r
     \r
@@ -45138,7 +46462,11 @@ Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {
      * @param {TreeNode} node The node to select\r
      * @return {TreeNode} The selected node\r
      */\r
-    select : function(node){\r
+    select : function(node, /* private*/ selectNextNode){\r
+        // If node is hidden, select the next node in whatever direction was being moved in.\r
+        if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) {\r
+            return selectNextNode.call(this, node);\r
+        }\r
         var last = this.selNode;\r
         if(node == last){\r
             node.ui.onSelectedChange(true);\r
@@ -45197,24 +46525,24 @@ Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {
      * Selects the node above the selected node in the tree, intelligently walking the nodes\r
      * @return TreeNode The new selection\r
      */\r
-    selectPrevious : function(){\r
-        var s = this.selNode || this.lastSelNode;\r
-        if(!s){\r
+    selectPrevious : function(/* private */ s){\r
+        if(!(s = s || this.selNode || this.lastSelNode)){\r
             return null;\r
         }\r
+        // Here we pass in the current function to select to indicate the direction we're moving\r
         var ps = s.previousSibling;\r
         if(ps){\r
             if(!ps.isExpanded() || ps.childNodes.length < 1){\r
-                return this.select(ps);\r
+                return this.select(ps, this.selectPrevious);\r
             } else{\r
                 var lc = ps.lastChild;\r
-                while(lc && lc.isExpanded() && lc.childNodes.length > 0){\r
+                while(lc && lc.isExpanded() && Ext.fly(lc.ui.wrap).isVisible() && lc.childNodes.length > 0){\r
                     lc = lc.lastChild;\r
                 }\r
-                return this.select(lc);\r
+                return this.select(lc, this.selectPrevious);\r
             }\r
         } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){\r
-            return this.select(s.parentNode);\r
+            return this.select(s.parentNode, this.selectPrevious);\r
         }\r
         return null;\r
     },\r
@@ -45223,20 +46551,20 @@ Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {
      * Selects the node above the selected node in the tree, intelligently walking the nodes\r
      * @return TreeNode The new selection\r
      */\r
-    selectNext : function(){\r
-        var s = this.selNode || this.lastSelNode;\r
-        if(!s){\r
+    selectNext : function(/* private */ s){\r
+        if(!(s = s || this.selNode || this.lastSelNode)){\r
             return null;\r
         }\r
-        if(s.firstChild && s.isExpanded()){\r
-             return this.select(s.firstChild);\r
+        // Here we pass in the current function to select to indicate the direction we're moving\r
+        if(s.firstChild && s.isExpanded() && Ext.fly(s.ui.wrap).isVisible()){\r
+             return this.select(s.firstChild, this.selectNext);\r
          }else if(s.nextSibling){\r
-             return this.select(s.nextSibling);\r
+             return this.select(s.nextSibling, this.selectNext);\r
          }else if(s.parentNode){\r
             var newS = null;\r
             s.parentNode.bubble(function(){\r
                 if(this.nextSibling){\r
-                    newS = this.getOwnerTree().selModel.select(this.nextSibling);\r
+                    newS = this.getOwnerTree().selModel.select(this.nextSibling, this.selectNext);\r
                     return false;\r
                 }\r
             });\r
@@ -45308,7 +46636,7 @@ Ext.tree.MultiSelectionModel = function(config){
 Ext.extend(Ext.tree.MultiSelectionModel, Ext.util.Observable, {\r
     init : function(tree){\r
         this.tree = tree;\r
-        tree.getTreeEl().on("keydown", this.onKeyDown, this);\r
+        tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);\r
         tree.on("click", this.onNodeClick, this);\r
     },\r
     \r
@@ -46008,7 +47336,7 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
             if(t){\r
                 t.unregisterNode(this);\r
             }\r
-            this.id = id;\r
+            this.id = this.attributes.id = id;\r
             if(t){\r
                 t.registerNode(this);\r
             }\r
@@ -46208,7 +47536,7 @@ Ext.extend(Ext.data.Node, Ext.util.Observable, {
  */\r
 Ext.tree.TreeNode = function(attributes){\r
     attributes = attributes || {};\r
-    if(typeof attributes == "string"){\r
+    if(typeof attributes == 'string'){\r
         attributes = {text: attributes};\r
     }\r
     this.childrenRendered = false;\r
@@ -46220,7 +47548,7 @@ Ext.tree.TreeNode = function(attributes){
     this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;\r
 \r
     /**\r
-     * Read-only. The text for this node. To change it use setText().\r
+     * Read-only. The text for this node. To change it use <code>{@link #setText}</code>.\r
      * @type String\r
      */\r
     this.text = attributes.text;\r
@@ -46243,7 +47571,7 @@ Ext.tree.TreeNode = function(attributes){
         * @param {String} text The new text\r
         * @param {String} oldText The old text\r
         */\r
-        "textchange",\r
+        'textchange',\r
         /**\r
         * @event beforeexpand\r
         * Fires before this node is expanded, return false to cancel.\r
@@ -46251,7 +47579,7 @@ Ext.tree.TreeNode = function(attributes){
         * @param {Boolean} deep\r
         * @param {Boolean} anim\r
         */\r
-        "beforeexpand",\r
+        'beforeexpand',\r
         /**\r
         * @event beforecollapse\r
         * Fires before this node is collapsed, return false to cancel.\r
@@ -46259,67 +47587,74 @@ Ext.tree.TreeNode = function(attributes){
         * @param {Boolean} deep\r
         * @param {Boolean} anim\r
         */\r
-        "beforecollapse",\r
+        'beforecollapse',\r
         /**\r
         * @event expand\r
         * Fires when this node is expanded\r
         * @param {Node} this This node\r
         */\r
-        "expand",\r
+        'expand',\r
         /**\r
         * @event disabledchange\r
         * Fires when the disabled status of this node changes\r
         * @param {Node} this This node\r
         * @param {Boolean} disabled\r
         */\r
-        "disabledchange",\r
+        'disabledchange',\r
         /**\r
         * @event collapse\r
         * Fires when this node is collapsed\r
         * @param {Node} this This node\r
         */\r
-        "collapse",\r
+        'collapse',\r
         /**\r
         * @event beforeclick\r
         * Fires before click processing. Return false to cancel the default action.\r
         * @param {Node} this This node\r
         * @param {Ext.EventObject} e The event object\r
         */\r
-        "beforeclick",\r
+        'beforeclick',\r
         /**\r
         * @event click\r
         * Fires when this node is clicked\r
         * @param {Node} this This node\r
         * @param {Ext.EventObject} e The event object\r
         */\r
-        "click",\r
+        'click',\r
         /**\r
         * @event checkchange\r
         * Fires when a node with a checkbox's checked property changes\r
         * @param {Node} this This node\r
         * @param {Boolean} checked\r
         */\r
-        "checkchange",\r
+        'checkchange',\r
+        /**\r
+        * @event beforedblclick\r
+        * Fires before double click processing. Return false to cancel the default action.\r
+        * @param {Node} this This node\r
+        * @param {Ext.EventObject} e The event object\r
+        */\r
+        'beforedblclick',\r
         /**\r
         * @event dblclick\r
         * Fires when this node is double clicked\r
         * @param {Node} this This node\r
         * @param {Ext.EventObject} e The event object\r
         */\r
-        "dblclick",\r
+        'dblclick',\r
         /**\r
         * @event contextmenu\r
         * Fires when this node is right clicked\r
         * @param {Node} this This node\r
         * @param {Ext.EventObject} e The event object\r
         */\r
-        "contextmenu",\r
+        'contextmenu',\r
         /**\r
         * @event beforechildrenrendered\r
         * Fires right before the child nodes for this node are rendered\r
         * @param {Node} this This node\r
         */\r
-        "beforechildrenrendered"\r
+        'beforechildrenrendered'\r
     );\r
 \r
     var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;\r
@@ -46331,7 +47666,7 @@ Ext.tree.TreeNode = function(attributes){
     this.ui = new uiClass(this);\r
 };\r
 Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {\r
-    preventHScroll: true,\r
+    preventHScroll : true,\r
     /**\r
      * Returns true if this node is expanded\r
      * @return {Boolean}\r
@@ -46414,7 +47749,7 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
 \r
     // private override\r
     insertBefore : function(node, refNode){\r
-        if(!node.render){ \r
+        if(!node.render){\r
             node = this.getLoader().createNode(node);\r
         }\r
         var newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode);\r
@@ -46436,7 +47771,7 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
         if(this.rendered){ // event without subscribing\r
             this.ui.onTextChange(this, text, oldText);\r
         }\r
-        this.fireEvent("textchange", this, text, oldText);\r
+        this.fireEvent('textchange', this, text, oldText);\r
     },\r
 \r
     /**\r
@@ -46472,7 +47807,7 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
      */\r
     expand : function(deep, anim, callback, scope){\r
         if(!this.expanded){\r
-            if(this.fireEvent("beforeexpand", this, deep, anim) === false){\r
+            if(this.fireEvent('beforeexpand', this, deep, anim) === false){\r
                 return;\r
             }\r
             if(!this.childrenRendered){\r
@@ -46481,7 +47816,7 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
             this.expanded = true;\r
             if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){\r
                 this.ui.animExpand(function(){\r
-                    this.fireEvent("expand", this);\r
+                    this.fireEvent('expand', this);\r
                     this.runCallback(callback, scope || this, [this]);\r
                     if(deep === true){\r
                         this.expandChildNodes(true);\r
@@ -46490,7 +47825,7 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
                 return;\r
             }else{\r
                 this.ui.expand();\r
-                this.fireEvent("expand", this);\r
+                this.fireEvent('expand', this);\r
                 this.runCallback(callback, scope || this, [this]);\r
             }\r
         }else{\r
@@ -46500,8 +47835,8 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
             this.expandChildNodes(true);\r
         }\r
     },\r
-    \r
-    runCallback: function(cb, scope, args){\r
+\r
+    runCallback : function(cb, scope, args){\r
         if(Ext.isFunction(cb)){\r
             cb.apply(scope, args);\r
         }\r
@@ -46522,13 +47857,13 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
      */\r
     collapse : function(deep, anim, callback, scope){\r
         if(this.expanded && !this.isHiddenRoot()){\r
-            if(this.fireEvent("beforecollapse", this, deep, anim) === false){\r
+            if(this.fireEvent('beforecollapse', this, deep, anim) === false){\r
                 return;\r
             }\r
             this.expanded = false;\r
             if((this.getOwnerTree().animate && anim !== false) || anim){\r
                 this.ui.animCollapse(function(){\r
-                    this.fireEvent("collapse", this);\r
+                    this.fireEvent('collapse', this);\r
                     this.runCallback(callback, scope || this, [this]);\r
                     if(deep === true){\r
                         this.collapseChildNodes(true);\r
@@ -46537,7 +47872,7 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
                 return;\r
             }else{\r
                 this.ui.collapse();\r
-                this.fireEvent("collapse", this);\r
+                this.fireEvent('collapse', this);\r
                 this.runCallback(callback, scope || this, [this]);\r
             }\r
         }else if(!this.expanded){\r
@@ -46623,7 +47958,7 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
         if(this.rendered && this.ui.onDisableChange){ // event without subscribing\r
             this.ui.onDisableChange(this, true);\r
         }\r
-        this.fireEvent("disabledchange", this, true);\r
+        this.fireEvent('disabledchange', this, true);\r
     },\r
 \r
     /**\r
@@ -46634,13 +47969,13 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
         if(this.rendered && this.ui.onDisableChange){ // event without subscribing\r
             this.ui.onDisableChange(this, false);\r
         }\r
-        this.fireEvent("disabledchange", this, false);\r
+        this.fireEvent('disabledchange', this, false);\r
     },\r
 \r
     // private\r
     renderChildren : function(suppressEvent){\r
         if(suppressEvent !== false){\r
-            this.fireEvent("beforechildrenrendered", this);\r
+            this.fireEvent('beforechildrenrendered', this);\r
         }\r
         var cs = this.childNodes;\r
         for(var i = 0, len = cs.length; i < len; i++){\r
@@ -46709,9 +48044,9 @@ Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
             this.ui.destroy();\r
         }\r
     },\r
-    \r
+\r
     // private\r
-    onIdChange: function(id){\r
+    onIdChange : function(id){\r
         this.ui.onIdChange(id);\r
     }\r
 });\r
@@ -46953,10 +48288,7 @@ Ext.tree.TreeNodeUI.prototype = {
         this.node.on("move", this.onMove, this);\r
 \r
         if(this.node.disabled){\r
-            this.addClass("x-tree-node-disabled");\r
-                       if (this.checkbox) {\r
-                               this.checkbox.disabled = true;\r
-                       }            \r
+            this.onDisableChange(this.node, true);            \r
         }\r
         if(this.node.hidden){\r
             this.hide();\r
@@ -47041,13 +48373,15 @@ Ext.tree.TreeNodeUI.prototype = {
         if(this.disabled){\r
             return;\r
         }\r
-        if(this.checkbox){\r
-            this.toggleCheck();\r
-        }\r
-        if(!this.animating && this.node.isExpandable()){\r
-            this.node.toggle();\r
+        if(this.fireEvent("beforedblclick", this.node, e) !== false){\r
+            if(this.checkbox){\r
+                this.toggleCheck();\r
+            }\r
+            if(!this.animating && this.node.isExpandable()){\r
+                this.node.toggle();\r
+            }\r
+            this.fireEvent("dblclick", this.node, e);\r
         }\r
-        this.fireEvent("dblclick", this.node, e);\r
     },\r
 \r
     onOver : function(e){\r
@@ -47606,7 +48940,7 @@ paramOrder: 'param1|param2|param'
             }\r
         }\r
         if(this.doPreload(node)){ // preloaded json children\r
-            this.runCallback(callback, scope || node, []);\r
+            this.runCallback(callback, scope || node, [node]);\r
         }else if(this.directFn || this.dataUrl || this.url){\r
             this.requestData(node, callback, scope || node);\r
         }\r
@@ -47716,7 +49050,7 @@ paramOrder: 'param1|param2|param'
     * Example:<pre><code>\r
 new Ext.tree.TreePanel({\r
     ...\r
-    new Ext.tree.TreeLoader({\r
+    loader: new Ext.tree.TreeLoader({\r
         url: 'dataUrl',\r
         createNode: function(attr) {\r
 //          Allow consolidation consignments to have\r
@@ -47725,7 +49059,7 @@ new Ext.tree.TreePanel({
                 attr.iconCls = 'x-consol',\r
                 attr.allowDrop = true;\r
             }\r
-            return Ext.tree.TreeLoader.prototype.call(this, attr);\r
+            return Ext.tree.TreeLoader.prototype.createNode.call(this, attr);\r
         }\r
     }),\r
     ...\r
@@ -47738,7 +49072,7 @@ new Ext.tree.TreePanel({
         if(this.baseAttrs){\r
             Ext.applyIf(attr, this.baseAttrs);\r
         }\r
-        if(this.applyLoader !== false){\r
+        if(this.applyLoader !== false && !attr.loader){\r
             attr.loader = this;\r
         }\r
         if(typeof attr.uiProvider == 'string'){\r
@@ -49334,6 +50668,19 @@ Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {
      * The wmode of the flash object. This can be used to control layering. Defaults to <tt>'opaque'</tt>.
      */
     wmode: 'opaque',
+    
+    /**
+     * @cfg {Object} flashVars
+     * A set of key value pairs to be passed to the flash object as flash variables. Defaults to <tt>undefined</tt>.
+     */
+    flashVars: undefined,
+    
+    /**
+     * @cfg {Object} flashParams
+     * A set of key value pairs to be passed to the flash object as parameters. Possible parameters can be found here:
+     * http://kb2.adobe.com/cps/127/tn_12701.html Defaults to <tt>undefined</tt>.
+     */
+    flashParams: undefined,
 
     /**
      * @cfg {String} url
@@ -49360,15 +50707,15 @@ Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {
     onRender : function(){
         Ext.FlashComponent.superclass.onRender.apply(this, arguments);
 
-        var params = {
+        var params = Ext.apply({
             allowScriptAccess: 'always',
             bgcolor: this.backgroundColor,
             wmode: this.wmode
-        }, vars = {
+        }, this.flashParams), vars = Ext.apply({
             allowedDomain: document.location.hostname,
             elementID: this.getId(),
             eventHandler: 'Ext.FlashEventProxy.onEvent'
-        };
+        }, this.flashVars);
 
         new swfobject.embedSWF(this.url, this.id, this.swfWidth, this.swfHeight, this.flashVersion,
             this.expressInstall ? Ext.FlashComponent.EXPRESS_INSTALL_URL : undefined, vars, params);
@@ -49572,13 +50919,14 @@ Ext.FlashEventProxy = {
      */\r
     bindStore : function(store, initial){\r
         if(!initial && this.store){\r
-            this.store.un("datachanged", this.refresh, this);\r
-            this.store.un("add", this.delayRefresh, this);\r
-            this.store.un("remove", this.delayRefresh, this);\r
-            this.store.un("update", this.delayRefresh, this);\r
-            this.store.un("clear", this.refresh, this);\r
             if(store !== this.store && this.store.autoDestroy){\r
                 this.store.destroy();\r
+            }else{\r
+                this.store.un("datachanged", this.refresh, this);\r
+                this.store.un("add", this.delayRefresh, this);\r
+                this.store.un("remove", this.delayRefresh, this);\r
+                this.store.un("update", this.delayRefresh, this);\r
+                this.store.un("clear", this.refresh, this);\r
             }\r
         }\r
         if(store){\r
@@ -49603,7 +50951,7 @@ Ext.FlashEventProxy = {
         this.swf.setType(this.type);\r
 \r
         if(this.chartStyle){\r
-            this.setStyles(Ext.apply(this.extraStyle || {}, this.chartStyle));\r
+            this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));\r
         }\r
 \r
         if(this.categoryNames){\r
@@ -49685,7 +51033,11 @@ Ext.FlashEventProxy = {
     \r
     onDestroy: function(){\r
         Ext.chart.Chart.superclass.onDestroy.call(this);\r
-        delete window[this.tipFnName];\r
+        this.bindStore(null);\r
+        var tip = this.tipFnName;\r
+        if(!Ext.isEmpty(tip)){\r
+            delete window[tip];\r
+        }\r
     }\r
 });\r
 Ext.reg('chart', Ext.chart.Chart);\r
@@ -50153,10 +51505,13 @@ Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
  * <p>Layout manager used by {@link Ext.menu.Menu}. Generally this class should not need to be used directly.</p>\r
  */\r
  Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, {\r
-    monitorResize: true,\r
+    monitorResize : true,\r
 \r
     setContainer : function(ct){\r
         this.monitorResize = !ct.floating;\r
+        // This event is only fired by the menu in IE, used so we don't couple\r
+        // the menu with the layout.\r
+        ct.on('autosize', this.doAutoSize, this);\r
         Ext.layout.MenuLayout.superclass.setContainer.call(this, ct);\r
     },\r
 \r
@@ -50183,13 +51538,14 @@ Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
                 this.itemTpl.append(target, a, true));\r
 \r
 //          Link the containing <li> to the item.\r
-            c.positionEl.menuItemId = c.itemId || c.id;\r
+            c.positionEl.menuItemId = c.getItemId();\r
 \r
 //          If rendering a regular Component, and it needs an icon,\r
 //          move the Component rightwards.\r
             if (!a.isMenuItem && a.needsIcon) {\r
                 c.positionEl.addClass('x-menu-list-item-indent');\r
             }\r
+            this.configureItem(c, position);\r
         }else if(c && !this.isValidParent(c, target)){\r
             if(Ext.isNumber(position)){\r
                 position = target.dom.childNodes[position];\r
@@ -50198,7 +51554,7 @@ Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
         }\r
     },\r
 \r
-    getItemArgs: function(c) {\r
+    getItemArgs : function(c) {\r
         var isMenuItem = c instanceof Ext.menu.Item;\r
         return {\r
             isMenuItem: isMenuItem,\r
@@ -50206,12 +51562,12 @@ Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
             icon: c.icon || Ext.BLANK_IMAGE_URL,\r
             iconCls: 'x-menu-item-icon ' + (c.iconCls || ''),\r
             itemId: 'x-menu-el-' + c.id,\r
-            itemCls: 'x-menu-list-item ' + (this.extraCls || '')\r
+            itemCls: 'x-menu-list-item '\r
         };\r
     },\r
 \r
 //  Valid if the Component is in a <li> which is part of our target <ul>\r
-    isValidParent: function(c, target) {\r
+    isValidParent : function(c, target) {\r
         return c.el.up('li.x-menu-list-item', 5).dom.parentNode === (target.dom || target);\r
     },\r
 \r
@@ -50268,20 +51624,20 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
      */\r
     minWidth : 120,\r
     /**\r
-     * @cfg {Boolean/String} shadow True or "sides" for the default effect, "frame" for 4-way shadow, and "drop"\r
-     * for bottom-right shadow (defaults to "sides")\r
+     * @cfg {Boolean/String} shadow True or 'sides' for the default effect, 'frame' for 4-way shadow, and 'drop'\r
+     * for bottom-right shadow (defaults to 'sides')\r
      */\r
-    shadow : "sides",\r
+    shadow : 'sides',\r
     /**\r
      * @cfg {String} subMenuAlign The {@link Ext.Element#alignTo} anchor position value to use for submenus of\r
-     * this menu (defaults to "tl-tr?")\r
+     * this menu (defaults to 'tl-tr?')\r
      */\r
-    subMenuAlign : "tl-tr?",\r
+    subMenuAlign : 'tl-tr?',\r
     /**\r
      * @cfg {String} defaultAlign The default {@link Ext.Element#alignTo} anchor position value for this menu\r
-     * relative to its element of origin (defaults to "tl-bl?")\r
+     * relative to its element of origin (defaults to 'tl-bl?')\r
      */\r
-    defaultAlign : "tl-bl?",\r
+    defaultAlign : 'tl-bl?',\r
     /**\r
      * @cfg {Boolean} allowOtherMenus True to allow multiple menus to be displayed at the same time (defaults to false)\r
      */\r
@@ -50294,43 +51650,59 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
     /**\r
      * @cfg {Boolean} enableScrolling True to allow the menu container to have scroller controls if the menu is too long (defaults to true).\r
      */\r
-    enableScrolling: true,\r
+    enableScrolling : true,\r
     /**\r
      * @cfg {Number} maxHeight The maximum height of the menu. Only applies when enableScrolling is set to True (defaults to null).\r
      */\r
-    maxHeight: null,\r
+    maxHeight : null,\r
     /**\r
      * @cfg {Number} scrollIncrement The amount to scroll the menu. Only applies when enableScrolling is set to True (defaults to 24).\r
      */\r
-    scrollIncrement: 24,\r
+    scrollIncrement : 24,\r
     /**\r
      * @cfg {Boolean} showSeparator True to show the icon separator. (defaults to true).\r
      */\r
-    showSeparator: true,\r
+    showSeparator : true,\r
     /**\r
      * @cfg {Array} defaultOffsets An array specifying the [x, y] offset in pixels by which to\r
      * change the default Menu popup position after aligning according to the {@link #defaultAlign}\r
      * configuration. Defaults to <tt>[0, 0]</tt>.\r
      */\r
     defaultOffsets : [0, 0],\r
-\r
+    \r
+    /**\r
+     * @cfg {Boolean} plain\r
+     * True to remove the incised line down the left side of the menu. Defaults to <tt>false</tt>.\r
+     */\r
+    plain : false,\r
 \r
     /**\r
      * @cfg {Boolean} floating\r
-     * May be specified as false to create a Menu which may be used as a child item of another Container\r
-     * instead of a free-floating {@link Ext.Layer Layer}. (defaults to true).\r
+     * <p>By default, a Menu configured as <b><code>floating:true</code></b>\r
+     * will be rendered as an {@link Ext.Layer} (an absolutely positioned,\r
+     * floating Component with zindex=15000).\r
+     * If configured as <b><code>floating:false</code></b>, the Menu may be\r
+     * used as child item of another Container instead of a free-floating\r
+     * {@link Ext.Layer Layer}.\r
      */\r
-    floating: true,         // Render as a Layer by default\r
+    floating : true,\r
 \r
     // private\r
-    hidden: true,\r
-    layout: 'menu',\r
-    hideMode: 'offsets',    // Important for laying out Components\r
-    scrollerHeight: 8,\r
-    autoLayout: true,       // Provided for backwards compat\r
-    defaultType: 'menuitem',\r
+    hidden : true,\r
 \r
-    initComponent: function(){\r
+    /**\r
+     * @cfg {String/Object} layout\r
+     * This class assigns a default layout (<code>layout:'<b>menu</b>'</code>).\r
+     * Developers <i>may</i> override this configuration option if another layout is required.\r
+     * See {@link Ext.Container#layout} for additional information.\r
+     */\r
+    layout : 'menu',\r
+    hideMode : 'offsets',    // Important for laying out Components\r
+    scrollerHeight : 8,\r
+    autoLayout : true,       // Provided for backwards compat\r
+    defaultType : 'menuitem',\r
+\r
+    initComponent : function(){\r
         if(Ext.isArray(this.initialConfig)){\r
             Ext.apply(this, {items:this.initialConfig});\r
         }\r
@@ -50443,7 +51815,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
 \r
     // private\r
     findTargetItem : function(e){\r
-        var t = e.getTarget(".x-menu-list-item", this.ul, true);\r
+        var t = e.getTarget('.x-menu-list-item', this.ul, true);\r
         if(t && t.menuItemId){\r
             return this.items.get(t.menuItemId);\r
         }\r
@@ -50455,13 +51827,13 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
         if(t){\r
             if(t.isFormField){\r
                 this.setActiveItem(t);\r
-            }else{\r
+            }else if(t instanceof Ext.menu.BaseItem){\r
                 if(t.menu && this.ignoreParentClicks){\r
                     t.expandMenu();\r
                     e.preventDefault();\r
                 }else if(t.onClick){\r
                     t.onClick(e);\r
-                    this.fireEvent("click", this, t, e);\r
+                    this.fireEvent('click', this, t, e);\r
                 }\r
             }\r
         }\r
@@ -50481,7 +51853,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
         }\r
     },\r
 \r
-    deactivateActive: function(){\r
+    deactivateActive : function(){\r
         var a = this.activeItem;\r
         if(a){\r
             if(a.isFormField){\r
@@ -50518,7 +51890,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
             }\r
         }\r
         this.over = true;\r
-        this.fireEvent("mouseover", this, e, t);\r
+        this.fireEvent('mouseover', this, e, t);\r
     },\r
 \r
     // private\r
@@ -50531,11 +51903,11 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
             }\r
         }\r
         this.over = false;\r
-        this.fireEvent("mouseout", this, e, t);\r
+        this.fireEvent('mouseout', this, e, t);\r
     },\r
 \r
     // private\r
-    onScroll: function(e, t){\r
+    onScroll : function(e, t){\r
         if(e){\r
             e.stopEvent();\r
         }\r
@@ -50547,7 +51919,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
     },\r
 \r
     // private\r
-    onScrollerIn: function(e, t){\r
+    onScrollerIn : function(e, t){\r
         var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');\r
         if(top ? ul.scrollTop > 0 : ul.scrollTop + this.activeMax < ul.scrollHeight){\r
             Ext.fly(t).addClass(['x-menu-item-active', 'x-menu-scroller-active']);\r
@@ -50555,12 +51927,13 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
     },\r
 \r
     // private\r
-    onScrollerOut: function(e, t){\r
+    onScrollerOut : function(e, t){\r
         Ext.fly(t).removeClass(['x-menu-item-active', 'x-menu-scroller-active']);\r
     },\r
 \r
     /**\r
-     * Displays this menu relative to another element\r
+     * If <code>{@link #floating}=true</code>, shows this menu relative to\r
+     * another element using {@link #showat}, otherwise uses {@link Ext.Component#show}.\r
      * @param {Mixed} element The element to align to\r
      * @param {String} position (optional) The {@link Ext.Element#alignTo} anchor position to use in aligning to\r
      * the element (defaults to this.defaultAlign)\r
@@ -50573,42 +51946,51 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
                 this.render();\r
                 this.doLayout(false, true);\r
             }\r
-            if(this.fireEvent('beforeshow', this) !== false){\r
-                this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign, this.defaultOffsets), parentMenu, false);\r
-            }\r
+            this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign, this.defaultOffsets), parentMenu);\r
         }else{\r
             Ext.menu.Menu.superclass.show.call(this);\r
         }\r
     },\r
 \r
     /**\r
-     * Displays this menu at a specific xy position\r
+     * Displays this menu at a specific xy position and fires the 'show' event if a\r
+     * handler for the 'beforeshow' event does not return false cancelling the operation.\r
      * @param {Array} xyPosition Contains X & Y [x, y] values for the position at which to show the menu (coordinates are page-based)\r
      * @param {Ext.menu.Menu} parentMenu (optional) This menu's parent menu, if applicable (defaults to undefined)\r
      */\r
-    showAt : function(xy, parentMenu, /* private: */_e){\r
-        this.parentMenu = parentMenu;\r
-        if(!this.el){\r
-            this.render();\r
-        }\r
-        this.el.setXY(xy);\r
-        if(this.enableScrolling){\r
-            this.constrainScroll(xy[1]);\r
-        }\r
-        this.el.show();\r
-        Ext.menu.Menu.superclass.onShow.call(this);\r
-        if(Ext.isIE){\r
-            this.layout.doAutoSize();\r
-            if(!Ext.isIE8){\r
-                this.el.repaint();\r
+    showAt : function(xy, parentMenu){\r
+        if(this.fireEvent('beforeshow', this) !== false){\r
+            this.parentMenu = parentMenu;\r
+            if(!this.el){\r
+                this.render();\r
+            }\r
+            if(this.enableScrolling){\r
+                // set the position so we can figure out the constrain value.\r
+                this.el.setXY(xy);\r
+                //constrain the value, keep the y coordinate the same\r
+                this.constrainScroll(xy[1]);\r
+                xy = [this.el.adjustForConstraints(xy)[0], xy[1]];\r
+            }else{\r
+                //constrain to the viewport.\r
+                xy = this.el.adjustForConstraints(xy);\r
+            }\r
+            this.el.setXY(xy);\r
+            this.el.show();\r
+            Ext.menu.Menu.superclass.onShow.call(this);\r
+            if(Ext.isIE){\r
+                // internal event, used so we don't couple the layout to the menu\r
+                this.fireEvent('autosize', this);\r
+                if(!Ext.isIE8){\r
+                    this.el.repaint();\r
+                }\r
             }\r
+            this.hidden = false;\r
+            this.focus();\r
+            this.fireEvent('show', this);\r
         }\r
-        this.hidden = false;\r
-        this.focus();\r
-        this.fireEvent("show", this);\r
     },\r
 \r
-    constrainScroll: function(y){\r
+    constrainScroll : function(y){\r
         var max, full = this.ul.setHeight('auto').getHeight();\r
         if(this.floating){\r
             max = this.maxHeight ? this.maxHeight : Ext.fly(this.el.dom.parentNode).getViewSize().height - y;\r
@@ -50627,7 +52009,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
         this.ul.dom.scrollTop = 0;\r
     },\r
 \r
-    createScrollers: function(){\r
+    createScrollers : function(){\r
         if(!this.scroller){\r
             this.scroller = {\r
                 pos: 0,\r
@@ -50657,7 +52039,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
         }\r
     },\r
 \r
-    onLayout: function(){\r
+    onLayout : function(){\r
         if(this.isVisible()){\r
             if(this.enableScrolling){\r
                 this.constrainScroll(this.el.getTop());\r
@@ -50691,19 +52073,24 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
     },\r
 \r
     // private\r
-    onHide: function(){\r
+    onHide : function(){\r
         Ext.menu.Menu.superclass.onHide.call(this);\r
         this.deactivateActive();\r
         if(this.el && this.floating){\r
             this.el.hide();\r
         }\r
-        if(this.deepHide === true && this.parentMenu){\r
-            this.parentMenu.hide(true);\r
+        var pm = this.parentMenu;\r
+        if(this.deepHide === true && pm){\r
+            if(pm.floating){\r
+                pm.hide(true);\r
+            }else{\r
+                pm.deactivateActive();\r
+            }\r
         }\r
     },\r
 \r
     // private\r
-    lookupComponent: function(c){\r
+    lookupComponent : function(c){\r
          if(Ext.isString(c)){\r
             c = (c == 'separator' || c == '-') ? new Ext.menu.Separator() : new Ext.menu.TextItem(c);\r
              this.applyDefaults(c);\r
@@ -50736,7 +52123,7 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
     },\r
 \r
     // private\r
-    getMenuItem: function(config){\r
+    getMenuItem : function(config){\r
        if(!config.isXType){\r
             if(!config.xtype && Ext.isBoolean(config.checked)){\r
                 return new Ext.menu.CheckItem(config)\r
@@ -50802,6 +52189,11 @@ Ext.menu.Menu = Ext.extend(Ext.Container, {
         if(s){\r
             Ext.destroy(s.topRepeater, s.bottomRepeater, s.top, s.bottom);\r
         }\r
+        Ext.destroy(\r
+            this.el,\r
+            this.focusEl,\r
+            this.ul\r
+        );\r
     }\r
 });\r
 \r
@@ -50820,7 +52212,7 @@ Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){
         }\r
     }\r
     return {\r
-        constructor: function(menu){\r
+        constructor : function(menu){\r
             Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);\r
             this.scope = this.menu = menu;\r
         },\r
@@ -50868,12 +52260,13 @@ Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){
             if(m.activeItem){\r
                 e.stopPropagation();\r
                 m.activeItem.onClick(e);\r
-                m.fireEvent("click", this, m.activeItem);\r
+                m.fireEvent('click', this, m.activeItem);\r
                 return true;\r
             }\r
         }\r
     };\r
-}());/**
+}());\r
+/**
  * @class Ext.menu.MenuMgr
  * Provides a common registry of all menu items on a page so that they can be easily accessed by id.
  * @singleton
@@ -51220,8 +52613,13 @@ Ext.extend(Ext.menu.BaseItem, Ext.Component, {
 
     // private
     handleClick : function(e){
+        var pm = this.parentMenu;
         if(this.hideOnClick){
-            this.parentMenu.hide.defer(this.clickHideDelay, this.parentMenu, [true]);
+            if(pm.floating){
+                pm.hide.defer(this.clickHideDelay, pm, [true]);
+            }else{
+                pm.deactivateActive();
+            }
         }
     },
 
@@ -51623,7 +53021,15 @@ Ext.extend(Ext.menu.CheckItem, Ext.menu.Item, {
 Ext.reg('menucheckitem', Ext.menu.CheckItem);/**\r
  * @class Ext.menu.DateMenu\r
  * @extends Ext.menu.Menu\r
- * A menu containing a {@link Ext.DatePicker} Component.\r
+ * <p>A menu containing an {@link Ext.DatePicker} Component.</p>\r
+ * <p>Notes:</p><div class="mdetail-params"><ul>\r
+ * <li>Although not listed here, the <b>constructor</b> for this class\r
+ * accepts all of the configuration options of <b>{@link Ext.DatePicker}</b>.</li>\r
+ * <li>If subclassing DateMenu, any configuration options for the DatePicker must be\r
+ * applied to the <tt><b>initialConfig</b></tt> property of the DateMenu.\r
+ * Applying {@link Ext.DatePicker DatePicker} configuration settings to\r
+ * <b><tt>this</tt></b> will <b>not</b> affect the DatePicker's configuration.</li>\r
+ * </ul></div>\r
  * @xtype datemenu\r
  */\r
  Ext.menu.DateMenu = Ext.extend(Ext.menu.Menu, {\r
@@ -51631,13 +53037,31 @@ Ext.reg('menucheckitem', Ext.menu.CheckItem);/**
      * @cfg {Boolean} enableScrolling\r
      * @hide \r
      */\r
-    enableScrolling: false,\r
-    \r
+    enableScrolling : false,\r
+    /**\r
+     * @cfg {Function} handler\r
+     * Optional. A function that will handle the select event of this menu.\r
+     * The handler is passed the following parameters:<div class="mdetail-params"><ul>\r
+     * <li><code>picker</code> : DatePicker<div class="sub-desc">The Ext.DatePicker.</div></li>\r
+     * <li><code>date</code> : Date<div class="sub-desc">The selected date.</div></li>\r
+     * </ul></div>\r
+     */\r
+    /**\r
+     * @cfg {Object} scope\r
+     * The scope (<tt><b>this</b></tt> reference) in which the <code>{@link #handler}</code>\r
+     * function will be called.  Defaults to this DateMenu instance.\r
+     */    \r
     /** \r
      * @cfg {Boolean} hideOnClick\r
      * False to continue showing the menu after a date is selected, defaults to true.\r
      */\r
-    hideOnClick: true,\r
+    hideOnClick : true,\r
+    \r
+    /** \r
+     * @cfg {String} pickerId\r
+     * An id to assign to the underlying date picker. Defaults to <tt>null</tt>.\r
+     */\r
+    pickerId : null,\r
     \r
     /** \r
      * @cfg {Number} maxHeight\r
@@ -51648,11 +53072,11 @@ Ext.reg('menucheckitem', Ext.menu.CheckItem);/**
      * @hide \r
      */\r
     /**\r
+     * The {@link Ext.DatePicker} instance for this DateMenu\r
      * @property picker\r
      * @type DatePicker\r
-     * The {@link Ext.DatePicker} instance for this DateMenu\r
      */\r
-    cls: 'x-date-menu',\r
+    cls : 'x-date-menu',\r
     \r
     /**\r
      * @event click\r
@@ -51664,7 +53088,7 @@ Ext.reg('menucheckitem', Ext.menu.CheckItem);/**
      * @hide\r
      */\r
 \r
-    initComponent: function(){\r
+    initComponent : function(){\r
         this.on('beforeshow', this.onBeforeShow, this);\r
         if(this.strict = (Ext.isIE7 && Ext.isStrict)){\r
             this.on('show', this.onShow, this, {single: true, delay: 20});\r
@@ -51672,41 +53096,57 @@ Ext.reg('menucheckitem', Ext.menu.CheckItem);/**
         Ext.apply(this, {\r
             plain: true,\r
             showSeparator: false,\r
-            items: this.picker = new Ext.DatePicker(Ext.apply({\r
+            items: this.picker = new Ext.DatePicker(Ext.applyIf({\r
                 internalRender: this.strict || !Ext.isIE,\r
-                ctCls: 'x-menu-date-item'\r
+                ctCls: 'x-menu-date-item',\r
+                id: this.pickerId\r
             }, this.initialConfig))\r
         });\r
         this.picker.purgeListeners();\r
         Ext.menu.DateMenu.superclass.initComponent.call(this);\r
-        this.relayEvents(this.picker, ["select"]);\r
+        /**\r
+         * @event select\r
+         * Fires when a date is selected from the {@link #picker Ext.DatePicker}\r
+         * @param {DatePicker} picker The {@link #picker Ext.DatePicker}\r
+         * @param {Date} date The selected date\r
+         */\r
+        this.relayEvents(this.picker, ['select']);\r
         this.on('select', this.menuHide, this);\r
         if(this.handler){\r
             this.on('select', this.handler, this.scope || this);\r
         }\r
     },\r
 \r
-    menuHide: function() {\r
+    menuHide : function() {\r
         if(this.hideOnClick){\r
             this.hide(true);\r
         }\r
     },\r
 \r
-    onBeforeShow: function(){\r
+    onBeforeShow : function(){\r
         if(this.picker){\r
             this.picker.hideMonthPicker(true);\r
         }\r
     },\r
 \r
-    onShow: function(){\r
+    onShow : function(){\r
         var el = this.picker.getEl();\r
         el.setWidth(el.getWidth()); //nasty hack for IE7 strict mode\r
     }\r
  });\r
- Ext.reg('datemenu', Ext.menu.DateMenu);/**\r
+ Ext.reg('datemenu', Ext.menu.DateMenu);\r
+ /**\r
  * @class Ext.menu.ColorMenu\r
  * @extends Ext.menu.Menu\r
- * A menu containing a {@link Ext.ColorPalette} Component.\r
+ * <p>A menu containing a {@link Ext.ColorPalette} Component.</p>\r
+ * <p>Notes:</p><div class="mdetail-params"><ul>\r
+ * <li>Although not listed here, the <b>constructor</b> for this class\r
+ * accepts all of the configuration options of <b>{@link Ext.ColorPalette}</b>.</li>\r
+ * <li>If subclassing ColorMenu, any configuration options for the ColorPalette must be\r
+ * applied to the <tt><b>initialConfig</b></tt> property of the ColorMenu.\r
+ * Applying {@link Ext.ColorPalette ColorPalette} configuration settings to\r
+ * <b><tt>this</tt></b> will <b>not</b> affect the ColorPalette's configuration.</li>\r
+ * </ul></div> * \r
  * @xtype colormenu\r
  */\r
  Ext.menu.ColorMenu = Ext.extend(Ext.menu.Menu, {\r
@@ -51714,13 +53154,34 @@ Ext.reg('menucheckitem', Ext.menu.CheckItem);/**
      * @cfg {Boolean} enableScrolling\r
      * @hide \r
      */\r
-    enableScrolling: false,\r
+    enableScrolling : false,\r
+    /**\r
+     * @cfg {Function} handler\r
+     * Optional. A function that will handle the select event of this menu.\r
+     * The handler is passed the following parameters:<div class="mdetail-params"><ul>\r
+     * <li><code>palette</code> : ColorPalette<div class="sub-desc">The {@link #palette Ext.ColorPalette}.</div></li>\r
+     * <li><code>color</code> : String<div class="sub-desc">The 6-digit color hex code (without the # symbol).</div></li>\r
+     * </ul></div>\r
+     */\r
+    /**\r
+     * @cfg {Object} scope\r
+     * The scope (<tt><b>this</b></tt> reference) in which the <code>{@link #handler}</code>\r
+     * function will be called.  Defaults to this ColorMenu instance.\r
+     */    \r
     \r
     /** \r
      * @cfg {Boolean} hideOnClick\r
      * False to continue showing the menu after a color is selected, defaults to true.\r
      */\r
-    hideOnClick: true,\r
+    hideOnClick : true,\r
+    \r
+    cls : 'x-color-menu',\r
+    \r
+    /** \r
+     * @cfg {String} paletteId\r
+     * An id to assign to the underlying color palette. Defaults to <tt>null</tt>.\r
+     */\r
+    paletteId : null,\r
     \r
     /** \r
      * @cfg {Number} maxHeight\r
@@ -51747,28 +53208,37 @@ Ext.reg('menucheckitem', Ext.menu.CheckItem);/**
      * @hide\r
      */\r
     \r
-    initComponent: function(){\r
+    initComponent : function(){\r
         Ext.apply(this, {\r
             plain: true,\r
             showSeparator: false,\r
-            items: this.palette = new Ext.ColorPalette(this.initialConfig)\r
+            items: this.palette = new Ext.ColorPalette(Ext.applyIf({\r
+                id: this.paletteId\r
+            }, this.initialConfig))\r
         });\r
         this.palette.purgeListeners();\r
         Ext.menu.ColorMenu.superclass.initComponent.call(this);\r
+        /**\r
+         * @event select\r
+         * Fires when a color is selected from the {@link #palette Ext.ColorPalette}\r
+         * @param {Ext.ColorPalette} palette The {@link #palette Ext.ColorPalette}\r
+         * @param {String} color The 6-digit color hex code (without the # symbol)\r
+         */\r
         this.relayEvents(this.palette, ['select']);\r
         this.on('select', this.menuHide, this);\r
         if(this.handler){\r
-            this.on('select', this.handler, this.scope || this)\r
+            this.on('select', this.handler, this.scope || this);\r
         }\r
     },\r
 \r
-    menuHide: function(){\r
+    menuHide : function(){\r
         if(this.hideOnClick){\r
             this.hide(true);\r
         }\r
     }\r
 });\r
-Ext.reg('colormenu', Ext.menu.ColorMenu);/**
+Ext.reg('colormenu', Ext.menu.ColorMenu);\r
+/**
  * @class Ext.form.Field
  * @extends Ext.BoxComponent
  * Base class for form fields that provides default event handling, sizing, value handling and other functionality.
@@ -51780,7 +53250,7 @@ Ext.reg('colormenu', Ext.menu.ColorMenu);/**
 Ext.form.Field = Ext.extend(Ext.BoxComponent,  {
     /**
      * @cfg {String} inputType The type attribute for input fields -- e.g. radio, text, password, file (defaults
-     * to "text"). The types "file" and "password" must be used to render those field types currently -- there are
+     * to 'text'). The types 'file' and 'password' must be used to render those field types currently -- there are
      * no separate Ext components for those. Note that if you use <tt>inputType:'file'</tt>, {@link #emptyText}
      * is not supported and should be avoided.
      */
@@ -51792,32 +53262,37 @@ Ext.form.Field = Ext.extend(Ext.BoxComponent,  {
      * @cfg {Mixed} value A value to initialize this field with (defaults to undefined).
      */
     /**
-     * @cfg {String} name The field's HTML name attribute (defaults to "").
+     * @cfg {String} name The field's HTML name attribute (defaults to '').
      * <b>Note</b>: this property must be set if this field is to be automatically included with
      * {@link Ext.form.BasicForm#submit form submit()}.
      */
     /**
-     * @cfg {String} cls A custom CSS class to apply to the field's underlying element (defaults to "").
+     * @cfg {String} cls A custom CSS class to apply to the field's underlying element (defaults to '').
      */
 
     /**
-     * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to "x-form-invalid")
+     * @cfg {String} invalidClass The CSS class to use when marking a field invalid (defaults to 'x-form-invalid')
      */
-    invalidClass : "x-form-invalid",
+    invalidClass : 'x-form-invalid',
     /**
      * @cfg {String} invalidText The error text to use when marking a field invalid and no message is provided
-     * (defaults to "The value in this field is invalid")
+     * (defaults to 'The value in this field is invalid')
+     */
+    invalidText : 'The value in this field is invalid',
+    /**
+     * @cfg {String} focusClass The CSS class to use when the field receives focus (defaults to 'x-form-focus')
      */
-    invalidText : "The value in this field is invalid",
+    focusClass : 'x-form-focus',
     /**
-     * @cfg {String} focusClass The CSS class to use when the field receives focus (defaults to "x-form-focus")
+     * @cfg {Boolean} preventMark
+     * <tt>true</tt> to disable {@link #markInvalid marking the field invalid}.
+     * Defaults to <tt>false</tt>.
      */
-    focusClass : "x-form-focus",
     /**
      * @cfg {String/Boolean} validationEvent The event that should initiate field validation. Set to false to disable
-      automatic validation (defaults to "keyup").
+      automatic validation (defaults to 'keyup').
      */
-    validationEvent : "keyup",
+    validationEvent : 'keyup',
     /**
      * @cfg {Boolean} validateOnBlur Whether the field should validate when it loses focus (defaults to true).
      */
@@ -51831,13 +53306,13 @@ Ext.form.Field = Ext.extend(Ext.BoxComponent,  {
      * @cfg {String/Object} autoCreate <p>A {@link Ext.DomHelper DomHelper} element spec, or true for a default
      * element spec. Used to create the {@link Ext.Component#getEl Element} which will encapsulate this Component.
      * See <tt>{@link Ext.Component#autoEl autoEl}</tt> for details.  Defaults to:</p>
-     * <pre><code>{tag: "input", type: "text", size: "20", autocomplete: "off"}</code></pre>
+     * <pre><code>{tag: 'input', type: 'text', size: '20', autocomplete: 'off'}</code></pre>
      */
-    defaultAutoCreate : {tag: "input", type: "text", size: "20", autocomplete: "off"},
+    defaultAutoCreate : {tag: 'input', type: 'text', size: '20', autocomplete: 'off'},
     /**
-     * @cfg {String} fieldClass The default CSS class for the field (defaults to "x-form-field")
+     * @cfg {String} fieldClass The default CSS class for the field (defaults to 'x-form-field')
      */
-    fieldClass : "x-form-field",
+    fieldClass : 'x-form-field',
     /**
      * @cfg {String} msgTarget The location where error text should display.  Should be one of the following values
      * (defaults to 'qtip'):
@@ -51877,6 +53352,9 @@ side          Add an error icon to the right of the field with a popup on hover
     // private
     isFormField : true,
 
+    // private
+    msgDisplay: '',
+
     // private
     hasFocus : false,
 
@@ -51957,9 +53435,9 @@ var form = new Ext.form.FormPanel({
     /**
      * Returns the {@link Ext.form.Field#name name} or {@link Ext.form.ComboBox#hiddenName hiddenName}
      * attribute of the field if available.
-     * @return {String} name The field {@link Ext.form.Field#name name} or {@link Ext.form.ComboBox#hiddenName hiddenName}  
+     * @return {String} name The field {@link Ext.form.Field#name name} or {@link Ext.form.ComboBox#hiddenName hiddenName}
      */
-    getName: function(){
+    getName : function(){
         return this.rendered && this.el.dom.name ? this.el.dom.name : this.name || this.id || '';
     },
 
@@ -51977,7 +53455,7 @@ var form = new Ext.form.FormPanel({
             this.autoEl = cfg;
         }
         Ext.form.Field.superclass.onRender.call(this, ct, position);
-        
+
         var type = this.el.dom.type;
         if(type){
             if(type == 'password'){
@@ -51997,7 +53475,7 @@ var form = new Ext.form.FormPanel({
 
     // private
     getItemCt : function(){
-        return this.el.up('.x-form-item', 4);
+        return this.itemCt;
     },
 
     // private
@@ -52044,7 +53522,7 @@ var form = new Ext.form.FormPanel({
     // private
     fireKey : function(e){
         if(e.isSpecialKey()){
-            this.fireEvent("specialkey", this, e);
+            this.fireEvent('specialkey', this, e);
         }
     },
 
@@ -52059,23 +53537,27 @@ var form = new Ext.form.FormPanel({
 
     // private
     initEvents : function(){
-        this.mon(this.el, Ext.EventManager.useKeydown ? "keydown" : "keypress", this.fireKey,  this);
+        this.mon(this.el, Ext.EventManager.useKeydown ? 'keydown' : 'keypress', this.fireKey,  this);
         this.mon(this.el, 'focus', this.onFocus, this);
 
-        // fix weird FF/Win editor issue when changing OS window focus
-        var o = this.inEditor && Ext.isWindows && Ext.isGecko ? {buffer:10} : null;
-        this.mon(this.el, 'blur', this.onBlur, this, o);
+        // standardise buffer across all browsers + OS-es for consistent event order.
+        // (the 10ms buffer for Editors fixes a weird FF/Win editor issue when changing OS window focus)
+        this.mon(this.el, 'blur', this.onBlur, this, this.inEditor ? {buffer:10} : null);
     },
 
+    // private
+    preFocus: Ext.emptyFn,
+
     // private
     onFocus : function(){
+        this.preFocus();
         if(this.focusClass){
             this.el.addClass(this.focusClass);
         }
         if(!this.hasFocus){
             this.hasFocus = true;
             this.startValue = this.getValue();
-            this.fireEvent("focus", this);
+            this.fireEvent('focus', this);
         }
     },
 
@@ -52089,18 +53571,24 @@ var form = new Ext.form.FormPanel({
             this.el.removeClass(this.focusClass);
         }
         this.hasFocus = false;
-        if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
+        if(this.validationEvent !== false && (this.validateOnBlur || this.validationEvent != 'blur')){
             this.validate();
         }
         var v = this.getValue();
         if(String(v) !== String(this.startValue)){
             this.fireEvent('change', this, v, this.startValue);
         }
-        this.fireEvent("blur", this);
+        this.fireEvent('blur', this);
+        this.postBlur();
     },
 
+    // private
+    postBlur : Ext.emptyFn,
+
     /**
-     * Returns whether or not the field value is currently valid
+     * Returns whether or not the field value is currently valid by
+     * {@link #validateValue validating} the {@link #processValue processed value}
+     * of the field. <b>Note</b>: {@link #disabled} fields are ignored.
      * @param {Boolean} preventMark True to disable marking the field invalid
      * @return {Boolean} True if the value is valid, else false
      */
@@ -52127,20 +53615,31 @@ var form = new Ext.form.FormPanel({
         return false;
     },
 
-    // protected - should be overridden by subclasses if necessary to prepare raw values for validation
+    /**
+     * This method should only be overridden if necessary to prepare raw values
+     * for validation (see {@link #validate} and {@link #isValid}).  This method
+     * is expected to return the processed value for the field which will
+     * be used for validation (see validateValue method).
+     * @param {Mixed} value
+     */
     processValue : function(value){
         return value;
     },
 
-    // private
-    // Subclasses should provide the validation implementation by overriding this
+    /**
+     * @private
+     * Subclasses should provide the validation implementation by overriding this
+     * @param {Mixed} value
+     */
     validateValue : function(value){
         return true;
     },
 
     /**
-     * Mark this field as invalid, using {@link #msgTarget} to determine how to display the error and
-     * applying {@link #invalidClass} to the field's element.
+     * Mark this field as invalid, using {@link #msgTarget} to determine how to
+     * display the error and applying {@link #invalidClass} to the field's element.
+     * <b>Note</b>: this method does not actually make the field
+     * {@link #isValid invalid}.
      * @param {String} msg (optional) The validation message (defaults to {@link #invalidText})
      */
     markInvalid : function(msg){
@@ -52234,7 +53733,7 @@ var form = new Ext.form.FormPanel({
      * @return {Mixed} value The field value that is set
      */
     setRawValue : function(v){
-        return (this.el.dom.value = (Ext.isEmpty(v) ? '' : v));
+        return this.rendered ? (this.el.dom.value = (Ext.isEmpty(v) ? '' : v)) : '';
     },
 
     /**
@@ -52254,26 +53753,6 @@ var form = new Ext.form.FormPanel({
     // private, does not work for all fields
     append : function(v){
          this.setValue([this.getValue(), v].join(''));
-    },
-
-    // private
-    adjustSize : function(w, h){
-        var s = Ext.form.Field.superclass.adjustSize.call(this, w, h);
-        s.width = this.adjustWidth(this.el.dom.tagName, s.width);
-        if(this.offsetCt){
-            var ct = this.getItemCt();
-            s.width -= ct.getFrameWidth('lr');
-            s.height -= ct.getFrameWidth('tb');
-        }
-        return s;
-    },
-
-    // private
-    adjustWidth : function(tag, w){
-        if(typeof w == 'number' && (Ext.isIE && (Ext.isIE6 || !Ext.isStrict)) && /input|textarea/i.test(tag) && !this.inEditor){
-            return w - 3;
-        }
-        return w;
     }
 
     /**
@@ -52409,44 +53888,10 @@ Ext.reg('field', Ext.form.Field);
  * or as the base class for more sophisticated input controls (like {@link Ext.form.TextArea}
  * and {@link Ext.form.ComboBox}).</p>
  * <p><b><u>Validation</u></b></p>
- * <p>Field validation is processed in a particular order.  If validation fails at any particular
- * step the validation routine halts.</p>
+ * <p>The validation procedure is described in the documentation for {@link #validateValue}.</p>
+ * <p><b><u>Alter Validation Behavior</u></b></p>
+ * <p>Validation behavior for each field can be configured:</p>
  * <div class="mdetail-params"><ul>
- * <li><b>1. Field specific validator</b>
- * <div class="sub-desc">
- * <p>If a field is configured with a <code>{@link Ext.form.TextField#validator validator}</code> function,
- * it will be passed the current field value.  The <code>{@link Ext.form.TextField#validator validator}</code>
- * function is expected to return boolean <tt>true</tt> if the value is valid or return a string to
- * represent the invalid message if invalid.</p>
- * </div></li>
- * <li><b>2. Built in Validation</b>
- * <div class="sub-desc">
- * <p>Basic validation is affected with the following configuration properties:</p>
- * <pre>
- * <u>Validation</u>    <u>Invalid Message</u>
- * <code>{@link Ext.form.TextField#allowBlank allowBlank}    {@link Ext.form.TextField#emptyText emptyText}</code>
- * <code>{@link Ext.form.TextField#minLength minLength}     {@link Ext.form.TextField#minLengthText minLengthText}</code>
- * <code>{@link Ext.form.TextField#maxLength maxLength}     {@link Ext.form.TextField#maxLengthText maxLengthText}</code>
- * </pre>
- * </div></li>
- * <li><b>3. Preconfigured Validation Types (VTypes)</b>
- * <div class="sub-desc">
- * <p>Using VTypes offers a convenient way to reuse validation. If a field is configured with a
- * <code>{@link Ext.form.TextField#vtype vtype}</code>, the corresponding {@link Ext.form.VTypes VTypes}
- * validation function will be used for validation.  If invalid, either the field's
- * <code>{@link Ext.form.TextField#vtypeText vtypeText}</code> or the VTypes vtype Text property will be
- * used for the invalid message.  Keystrokes on the field will be filtered according to the VTypes
- * vtype Mask property.</p>
- * </div></li>
- * <li><b>4. Field specific regex test</b>
- * <div class="sub-desc">
- * <p>Each field may also specify a <code>{@link Ext.form.TextField#regex regex}</code> test.
- * The invalid message for this test is configured with
- * <code>{@link Ext.form.TextField#regexText regexText}</code>.</p>
- * </div></li>
- * <li><b>Alter Validation Behavior</b>
- * <div class="sub-desc">
- * <p>Validation behavior for each field can be configured:</p><ul>
  * <li><code>{@link Ext.form.TextField#invalidText invalidText}</code> : the default validation message to
  * show if any validation step above does not provide a message when invalid</li>
  * <li><code>{@link Ext.form.TextField#maskRe maskRe}</code> : filter out keystrokes before any validation occurs</li>
@@ -52456,12 +53901,11 @@ Ext.reg('field', Ext.form.Field);
  * <li><code>{@link Ext.form.Field#validateOnBlur validateOnBlur}</code>,
  * <code>{@link Ext.form.Field#validationDelay validationDelay}</code>, and
  * <code>{@link Ext.form.Field#validationEvent validationEvent}</code> : modify how/when validation is triggered</li>
- * </ul>
- * </div></li>
  * </ul></div>
- * @constructor
- * Creates a new TextField
+ * 
+ * @constructor Creates a new TextField
  * @param {Object} config Configuration options
+ * 
  * @xtype textfield
  */
 Ext.form.TextField = Ext.extend(Ext.form.Field,  {
@@ -52549,11 +53993,22 @@ var myField = new Ext.form.NumberField({
      */
     blankText : 'This field is required',
     /**
-     * @cfg {Function} validator A custom validation function to be called during field validation
+     * @cfg {Function} validator
+     * <p>A custom validation function to be called during field validation ({@link #validateValue})
      * (defaults to <tt>null</tt>). If specified, this function will be called first, allowing the
-     * developer to override the default validation process. This function will be passed the current
-     * field value and expected to return boolean <tt>true</tt> if the value is valid or a string
-     * error message if invalid.
+     * developer to override the default validation process.</p>
+     * <br><p>This function will be passed the following Parameters:</p>
+     * <div class="mdetail-params"><ul>
+     * <li><code>value</code>: <i>Mixed</i>
+     * <div class="sub-desc">The current field value</div></li>
+     * </ul></div>
+     * <br><p>This function is to Return:</p>
+     * <div class="mdetail-params"><ul>
+     * <li><code>true</code>: <i>Boolean</i>
+     * <div class="sub-desc"><code>true</code> if the value is valid</div></li>
+     * <li><code>msg</code>: <i>String</i>
+     * <div class="sub-desc">An error message if the value is invalid</div></li>
+     * </ul></div>
      */
     validator : null,
     /**
@@ -52632,22 +54087,13 @@ var myField = new Ext.form.NumberField({
             this.validationTask = new Ext.util.DelayedTask(this.validate, this);
             this.mon(this.el, 'keyup', this.filterValidation, this);
         }
-        else if(this.validationEvent !== false){
+        else if(this.validationEvent !== false && this.validationEvent != 'blur'){
                this.mon(this.el, this.validationEvent, this.validate, this, {buffer: this.validationDelay});
         }
-        if(this.selectOnFocus || this.emptyText){
-            this.on('focus', this.preFocus, this);
-            
-            this.mon(this.el, 'mousedown', function(){
-                if(!this.hasFocus){
-                    this.el.on('mouseup', function(e){
-                        e.preventDefault();
-                    }, this, {single:true});
-                }
-            }, this);
+        if(this.selectOnFocus || this.emptyText){            
+            this.mon(this.el, 'mousedown', this.onMouseDown, this);
             
             if(this.emptyText){
-                this.on('blur', this.postBlur, this);
                 this.applyEmptyText();
             }
         }
@@ -52659,9 +54105,18 @@ var myField = new Ext.form.NumberField({
                        this.mon(this.el, 'click', this.autoSize, this);
         }
         if(this.enableKeyEvents){
-               this.mon(this.el, 'keyup', this.onKeyUp, this);
-               this.mon(this.el, 'keydown', this.onKeyDown, this);
-               this.mon(this.el, 'keypress', this.onKeyPress, this);
+            this.mon(this.el, {
+                scope: this,
+                keyup: this.onKeyUp,
+                keydown: this.onKeyDown,
+                keypress: this.onKeyPress
+            });
+        }
+    },
+    
+    onMouseDown: function(e){
+        if(!this.hasFocus){
+            this.mon(this.el, 'mouseup', Ext.emptyFn, this, { single: true, preventDefault: true });
         }
     },
 
@@ -52747,9 +54202,7 @@ var myField = new Ext.form.NumberField({
             el.removeClass(this.emptyClass);
         }
         if(this.selectOnFocus){
-            (function(){
-                el.dom.select();
-            }).defer(this.inEditor && Ext.isIE ? 50 : 0);    
+            el.dom.select();
         }
     },
 
@@ -52781,8 +54234,70 @@ var myField = new Ext.form.NumberField({
     },
 
     /**
-     * Validates a value according to the field's validation rules and marks the field as invalid
-     * if the validation fails
+     * <p>Validates a value according to the field's validation rules and marks the field as invalid
+     * if the validation fails. Validation rules are processed in the following order:</p>
+     * <div class="mdetail-params"><ul>
+     * 
+     * <li><b>1. Field specific validator</b>
+     * <div class="sub-desc">
+     * <p>A validator offers a way to customize and reuse a validation specification.
+     * If a field is configured with a <code>{@link #validator}</code>
+     * function, it will be passed the current field value.  The <code>{@link #validator}</code>
+     * function is expected to return either:
+     * <div class="mdetail-params"><ul>
+     * <li>Boolean <tt>true</tt> if the value is valid (validation continues).</li>
+     * <li>a String to represent the invalid message if invalid (validation halts).</li>
+     * </ul></div>
+     * </div></li>
+     * 
+     * <li><b>2. Basic Validation</b>
+     * <div class="sub-desc">
+     * <p>If the <code>{@link #validator}</code> has not halted validation,
+     * basic validation proceeds as follows:</p>
+     * 
+     * <div class="mdetail-params"><ul>
+     * 
+     * <li><code>{@link #allowBlank}</code> : (Invalid message =
+     * <code>{@link #emptyText}</code>)<div class="sub-desc">
+     * Depending on the configuration of <code>{@link #allowBlank}</code>, a
+     * blank field will cause validation to halt at this step and return
+     * Boolean true or false accordingly.  
+     * </div></li>
+     * 
+     * <li><code>{@link #minLength}</code> : (Invalid message =
+     * <code>{@link #minLengthText}</code>)<div class="sub-desc">
+     * If the passed value does not satisfy the <code>{@link #minLength}</code>
+     * specified, validation halts.
+     * </div></li>
+     * 
+     * <li><code>{@link #maxLength}</code> : (Invalid message =
+     * <code>{@link #maxLengthText}</code>)<div class="sub-desc">
+     * If the passed value does not satisfy the <code>{@link #maxLength}</code>
+     * specified, validation halts.
+     * </div></li>
+     * 
+     * </ul></div>
+     * </div></li>
+     * 
+     * <li><b>3. Preconfigured Validation Types (VTypes)</b>
+     * <div class="sub-desc">
+     * <p>If none of the prior validation steps halts validation, a field
+     * configured with a <code>{@link #vtype}</code> will utilize the
+     * corresponding {@link Ext.form.VTypes VTypes} validation function.
+     * If invalid, either the field's <code>{@link #vtypeText}</code> or
+     * the VTypes vtype Text property will be used for the invalid message.
+     * Keystrokes on the field will be filtered according to the VTypes
+     * vtype Mask property.</p>
+     * </div></li>
+     * 
+     * <li><b>4. Field specific regex test</b>
+     * <div class="sub-desc">
+     * <p>If none of the prior validation steps halts validation, a field's
+     * configured <code>{@link #regex}</code> test will be processed.
+     * The invalid message for this test is configured with
+     * <code>{@link #regexText}</code>.</p>
+     * </div></li>
+     * 
      * @param {Mixed} value The value to validate
      * @return {Boolean} True if the value is valid, else false
      */
@@ -52887,327 +54402,347 @@ var myField = new Ext.form.NumberField({
        }
 });
 Ext.reg('textfield', Ext.form.TextField);
-/**
- * @class Ext.form.TriggerField
- * @extends Ext.form.TextField
- * Provides a convenient wrapper for TextFields that adds a clickable trigger button (looks like a combobox by default).
- * The trigger has no default action, so you must assign a function to implement the trigger click handler by
- * overriding {@link #onTriggerClick}. You can create a TriggerField directly, as it renders exactly like a combobox
- * for which you can provide a custom implementation.  For example:
- * <pre><code>
-var trigger = new Ext.form.TriggerField();
-trigger.onTriggerClick = myTriggerFn;
-trigger.applyToMarkup('my-field');
-</code></pre>
- *
- * However, in general you will most likely want to use TriggerField as the base class for a reusable component.
- * {@link Ext.form.DateField} and {@link Ext.form.ComboBox} are perfect examples of this.
- * 
- * @constructor
- * Create a new TriggerField.
- * @param {Object} config Configuration options (valid {@Ext.form.TextField} config options will also be applied
- * to the base TextField)
- * @xtype trigger
- */
-Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {
-    /**
-     * @cfg {String} triggerClass
-     * An additional CSS class used to style the trigger button.  The trigger will always get the
-     * class <tt>'x-form-trigger'</tt> by default and <tt>triggerClass</tt> will be <b>appended</b> if specified.
-     */
-    /**
-     * @cfg {Mixed} triggerConfig
-     * <p>A {@link Ext.DomHelper DomHelper} config object specifying the structure of the
-     * trigger element for this Field. (Optional).</p>
-     * <p>Specify this when you need a customized element to act as the trigger button for a TriggerField.</p>
-     * <p>Note that when using this option, it is the developer's responsibility to ensure correct sizing, positioning
-     * and appearance of the trigger.  Defaults to:</p>
-     * <pre><code>{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass}</code></pre>
-     */
-    /**
-     * @cfg {String/Object} autoCreate <p>A {@link Ext.DomHelper DomHelper} element spec, or true for a default
-     * element spec. Used to create the {@link Ext.Component#getEl Element} which will encapsulate this Component.
-     * See <tt>{@link Ext.Component#autoEl autoEl}</tt> for details.  Defaults to:</p>
-     * <pre><code>{tag: "input", type: "text", size: "16", autocomplete: "off"}</code></pre>
-     */
-    defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
-    /**
-     * @cfg {Boolean} hideTrigger <tt>true</tt> to hide the trigger element and display only the base
-     * text field (defaults to <tt>false</tt>)
-     */
-    hideTrigger:false,
-    /**
-     * @cfg {Boolean} editable <tt>false</tt> to prevent the user from typing text directly into the field,
-     * the field will only respond to a click on the trigger to set the value. (defaults to <tt>true</tt>)
-     */
-    editable: true,
-    /**
-     * @cfg {String} wrapFocusClass The class added to the to the wrap of the trigger element. Defaults to
-     * <tt>x-trigger-wrap-focus</tt>.
-     */
-    wrapFocusClass: 'x-trigger-wrap-focus',
-    /**
-     * @hide 
-     * @method autoSize
-     */
-    autoSize: Ext.emptyFn,
-    // private
-    monitorTab : true,
-    // private
-    deferHeight : true,
-    // private
-    mimicing : false,
-    
-    actionMode: 'wrap',
-
-    // private
-    onResize : function(w, h){
-        Ext.form.TriggerField.superclass.onResize.call(this, w, h);
-        if(typeof w == 'number'){
-            this.el.setWidth(this.adjustWidth('input', w - this.trigger.getWidth()));
-        }
-        this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
-    },
-
-    // private
-    adjustSize : Ext.BoxComponent.prototype.adjustSize,
-
-    // private
-    getResizeEl : function(){
-        return this.wrap;
-    },
-
-    // private
-    getPositionEl : function(){
-        return this.wrap;
-    },
-
-    // private
-    alignErrorIcon : function(){
-        if(this.wrap){
-            this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
-        }
-    },
-
-    // private
-    onRender : function(ct, position){
-        Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
-
-        this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'});
-        this.trigger = this.wrap.createChild(this.triggerConfig ||
-                {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
-        if(this.hideTrigger){
-            this.trigger.setDisplayed(false);
-        }
-        this.initTrigger();
-        if(!this.width){
-            this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
-        }
-        if(!this.editable){
-            this.editable = true;
-            this.setEditable(false);
-        }
-    },
-
-    afterRender : function(){
-        Ext.form.TriggerField.superclass.afterRender.call(this);
-    },
-
-    // private
-    initTrigger : function(){
-       this.mon(this.trigger, 'click', this.onTriggerClick, this, {preventDefault:true});
-        this.trigger.addClassOnOver('x-form-trigger-over');
-        this.trigger.addClassOnClick('x-form-trigger-click');
-    },
-
-    // private
-    onDestroy : function(){
-               Ext.destroy(this.trigger, this.wrap);
-        if (this.mimicing){
-            Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur, this);
-        }
-        Ext.form.TriggerField.superclass.onDestroy.call(this);
-    },
-
-    // private
-    onFocus : function(){
-        Ext.form.TriggerField.superclass.onFocus.call(this);
-        if(!this.mimicing){
-            this.wrap.addClass(this.wrapFocusClass);
-            this.mimicing = true;
-            Ext.get(Ext.isIE ? document.body : document).on("mousedown", this.mimicBlur, this, {delay: 10});
-            if(this.monitorTab){
-               this.el.on('keydown', this.checkTab, this);
-            }
-        }
-    },
-
-    // private
-    checkTab : function(e){
-        if(e.getKey() == e.TAB){
-            this.triggerBlur();
-        }
-    },
-
-    // private
-    onBlur : function(){
-        // do nothing
-    },
-
-    // private
-    mimicBlur : function(e){
-        if(!this.wrap.contains(e.target) && this.validateBlur(e)){
-            this.triggerBlur();
-        }
-    },
-
-    // private
-    triggerBlur : function(){
-        this.mimicing = false;
-        Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur, this);
-        if(this.monitorTab && this.el){
-            this.el.un("keydown", this.checkTab, this);
-        }
-        Ext.form.TriggerField.superclass.onBlur.call(this);
-        if(this.wrap){
-            this.wrap.removeClass(this.wrapFocusClass);
-        }
-    },
-
-    beforeBlur : Ext.emptyFn, 
-    
-    /**
-     * Allow or prevent the user from directly editing the field text.  If false is passed,
-     * the user will only be able to modify the field using the trigger.  This method
-     * is the runtime equivalent of setting the 'editable' config option at config time.
-     * @param {Boolean} value True to allow the user to directly edit the field text
-     */
-    setEditable : function(value){
-        if(value == this.editable){
-            return;
-        }
-        this.editable = value;
-        if(!value){
-            this.el.addClass('x-trigger-noedit').on('click', this.onTriggerClick, this).dom.setAttribute('readOnly', true);
-        }else{
-            this.el.removeClass('x-trigger-noedit').un('click', this.onTriggerClick,  this).dom.removeAttribute('readOnly');
-        }
-    },
-
-    // private
-    // This should be overriden by any subclass that needs to check whether or not the field can be blurred.
-    validateBlur : function(e){
-        return true;
-    },
-
-    /**
-     * The function that should handle the trigger's click event.  This method does nothing by default
-     * until overridden by an implementing function.  See Ext.form.ComboBox and Ext.form.DateField for
-     * sample implementations.
-     * @method
-     * @param {EventObject} e
-     */
-    onTriggerClick : Ext.emptyFn
-
-    /**
-     * @cfg {Boolean} grow @hide
-     */
-    /**
-     * @cfg {Number} growMin @hide
-     */
-    /**
-     * @cfg {Number} growMax @hide
-     */
-});
-
-/**
- * @class Ext.form.TwinTriggerField
- * @extends Ext.form.TriggerField
- * TwinTriggerField is not a public class to be used directly.  It is meant as an abstract base class
- * to be extended by an implementing class.  For an example of implementing this class, see the custom
- * SearchField implementation here:
- * <a href="http://extjs.com/deploy/ext/examples/form/custom.html">http://extjs.com/deploy/ext/examples/form/custom.html</a>
- */
-Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
-    /**
-     * @cfg {Mixed} triggerConfig
-     * <p>A {@link Ext.DomHelper DomHelper} config object specifying the structure of the trigger elements
-     * for this Field. (Optional).</p>
-     * <p>Specify this when you need a customized element to contain the two trigger elements for this Field.
-     * Each trigger element must be marked by the CSS class <tt>x-form-trigger</tt> (also see
-     * <tt>{@link #trigger1Class}</tt> and <tt>{@link #trigger2Class}</tt>).</p>
-     * <p>Note that when using this option, it is the developer's responsibility to ensure correct sizing,
-     * positioning and appearance of the triggers.</p>
-     */
-    /**
-     * @cfg {String} trigger1Class
-     * An additional CSS class used to style the trigger button.  The trigger will always get the
-     * class <tt>'x-form-trigger'</tt> by default and <tt>triggerClass</tt> will be <b>appended</b> if specified.
-     */
-    /**
-     * @cfg {String} trigger2Class
-     * An additional CSS class used to style the trigger button.  The trigger will always get the
-     * class <tt>'x-form-trigger'</tt> by default and <tt>triggerClass</tt> will be <b>appended</b> if specified.
-     */
-
-    initComponent : function(){
-        Ext.form.TwinTriggerField.superclass.initComponent.call(this);
-
-        this.triggerConfig = {
-            tag:'span', cls:'x-form-twin-triggers', cn:[
-            {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},
-            {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}
-        ]};
-    },
-
-    getTrigger : function(index){
-        return this.triggers[index];
-    },
-
-    initTrigger : function(){
-        var ts = this.trigger.select('.x-form-trigger', true);
-        this.wrap.setStyle('overflow', 'hidden');
-        var triggerField = this;
-        ts.each(function(t, all, index){
-            t.hide = function(){
-                var w = triggerField.wrap.getWidth();
-                this.dom.style.display = 'none';
-                triggerField.el.setWidth(w-triggerField.trigger.getWidth());
-            };
-            t.show = function(){
-                var w = triggerField.wrap.getWidth();
-                this.dom.style.display = '';
-                triggerField.el.setWidth(w-triggerField.trigger.getWidth());
-            };
-            var triggerIndex = 'Trigger'+(index+1);
-
-            if(this['hide'+triggerIndex]){
-                t.dom.style.display = 'none';
-            }
-            this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true});
-            t.addClassOnOver('x-form-trigger-over');
-            t.addClassOnClick('x-form-trigger-click');
-        }, this);
-        this.triggers = ts.elements;
-    },
-
-    /**
-     * The function that should handle the trigger's click event.  This method does nothing by default
-     * until overridden by an implementing function. See {@link Ext.form.TriggerField#onTriggerClick}
-     * for additional information.  
-     * @method
-     * @param {EventObject} e
-     */
-    onTrigger1Click : Ext.emptyFn,
-    /**
-     * The function that should handle the trigger's click event.  This method does nothing by default
-     * until overridden by an implementing function. See {@link Ext.form.TriggerField#onTriggerClick}
-     * for additional information.  
-     * @method
-     * @param {EventObject} e
-     */
-    onTrigger2Click : Ext.emptyFn
-});
+/**\r
+ * @class Ext.form.TriggerField\r
+ * @extends Ext.form.TextField\r
+ * Provides a convenient wrapper for TextFields that adds a clickable trigger button (looks like a combobox by default).\r
+ * The trigger has no default action, so you must assign a function to implement the trigger click handler by\r
+ * overriding {@link #onTriggerClick}. You can create a TriggerField directly, as it renders exactly like a combobox\r
+ * for which you can provide a custom implementation.  For example:\r
+ * <pre><code>\r
+var trigger = new Ext.form.TriggerField();\r
+trigger.onTriggerClick = myTriggerFn;\r
+trigger.applyToMarkup('my-field');\r
+</code></pre>\r
+ *\r
+ * However, in general you will most likely want to use TriggerField as the base class for a reusable component.\r
+ * {@link Ext.form.DateField} and {@link Ext.form.ComboBox} are perfect examples of this.\r
+ * \r
+ * @constructor\r
+ * Create a new TriggerField.\r
+ * @param {Object} config Configuration options (valid {@Ext.form.TextField} config options will also be applied\r
+ * to the base TextField)\r
+ * @xtype trigger\r
+ */\r
+Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {\r
+    /**\r
+     * @cfg {String} triggerClass\r
+     * An additional CSS class used to style the trigger button.  The trigger will always get the\r
+     * class <tt>'x-form-trigger'</tt> by default and <tt>triggerClass</tt> will be <b>appended</b> if specified.\r
+     */\r
+    /**\r
+     * @cfg {Mixed} triggerConfig\r
+     * <p>A {@link Ext.DomHelper DomHelper} config object specifying the structure of the\r
+     * trigger element for this Field. (Optional).</p>\r
+     * <p>Specify this when you need a customized element to act as the trigger button for a TriggerField.</p>\r
+     * <p>Note that when using this option, it is the developer's responsibility to ensure correct sizing, positioning\r
+     * and appearance of the trigger.  Defaults to:</p>\r
+     * <pre><code>{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass}</code></pre>\r
+     */\r
+    /**\r
+     * @cfg {String/Object} autoCreate <p>A {@link Ext.DomHelper DomHelper} element spec, or true for a default\r
+     * element spec. Used to create the {@link Ext.Component#getEl Element} which will encapsulate this Component.\r
+     * See <tt>{@link Ext.Component#autoEl autoEl}</tt> for details.  Defaults to:</p>\r
+     * <pre><code>{tag: "input", type: "text", size: "16", autocomplete: "off"}</code></pre>\r
+     */\r
+    defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},\r
+    /**\r
+     * @cfg {Boolean} hideTrigger <tt>true</tt> to hide the trigger element and display only the base\r
+     * text field (defaults to <tt>false</tt>)\r
+     */\r
+    hideTrigger:false,\r
+    /**\r
+     * @cfg {Boolean} editable <tt>false</tt> to prevent the user from typing text directly into the field,\r
+     * the field will only respond to a click on the trigger to set the value. (defaults to <tt>true</tt>)\r
+     */\r
+    editable: true,\r
+    /**\r
+     * @cfg {String} wrapFocusClass The class added to the to the wrap of the trigger element. Defaults to\r
+     * <tt>x-trigger-wrap-focus</tt>.\r
+     */\r
+    wrapFocusClass: 'x-trigger-wrap-focus',\r
+    /**\r
+     * @hide \r
+     * @method autoSize\r
+     */\r
+    autoSize: Ext.emptyFn,\r
+    // private\r
+    monitorTab : true,\r
+    // private\r
+    deferHeight : true,\r
+    // private\r
+    mimicing : false,\r
+    \r
+    actionMode: 'wrap',\r
+    \r
+    defaultTriggerWidth: 17,\r
+\r
+    // private\r
+    onResize : function(w, h){\r
+        Ext.form.TriggerField.superclass.onResize.call(this, w, h);\r
+        var tw = this.getTriggerWidth();\r
+        if(Ext.isNumber(w)){\r
+            this.el.setWidth(w - tw);\r
+        }\r
+        this.wrap.setWidth(this.el.getWidth() + tw);\r
+    },\r
+    \r
+    getTriggerWidth: function(){\r
+        var tw = this.trigger.getWidth();\r
+        if(!this.hideTrigger && tw === 0){\r
+            tw = this.defaultTriggerWidth;\r
+        }\r
+        return tw;\r
+    },\r
+\r
+    // private\r
+    alignErrorIcon : function(){\r
+        if(this.wrap){\r
+            this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);\r
+        }\r
+    },\r
+\r
+    // private\r
+    onRender : function(ct, position){\r
+        this.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc();\r
+        Ext.form.TriggerField.superclass.onRender.call(this, ct, position);\r
+\r
+        this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'});\r
+        this.trigger = this.wrap.createChild(this.triggerConfig ||\r
+                {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});\r
+        if(this.hideTrigger){\r
+            this.trigger.setDisplayed(false);\r
+        }\r
+        this.initTrigger();\r
+        if(!this.width){\r
+            this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());\r
+        }\r
+        if(!this.editable){\r
+            this.editable = true;\r
+            this.setEditable(false);\r
+        }\r
+        this.resizeEl = this.positionEl = this.wrap;\r
+    },\r
+\r
+    afterRender : function(){\r
+        Ext.form.TriggerField.superclass.afterRender.call(this);\r
+    },\r
+\r
+    // private\r
+    initTrigger : function(){\r
+        this.mon(this.trigger, 'click', this.onTriggerClick, this, {preventDefault:true});\r
+        this.trigger.addClassOnOver('x-form-trigger-over');\r
+        this.trigger.addClassOnClick('x-form-trigger-click');\r
+    },\r
+\r
+    // private\r
+    onDestroy : function(){\r
+        Ext.destroy(this.trigger, this.wrap);\r
+        if (this.mimicing){\r
+            this.doc.un('mousedown', this.mimicBlur, this);\r
+        }\r
+        Ext.form.TriggerField.superclass.onDestroy.call(this);\r
+    },\r
+\r
+    // private\r
+    onFocus : function(){\r
+        Ext.form.TriggerField.superclass.onFocus.call(this);\r
+        if(!this.mimicing){\r
+            this.wrap.addClass(this.wrapFocusClass);\r
+            this.mimicing = true;\r
+            this.doc.on('mousedown', this.mimicBlur, this, {delay: 10});\r
+            if(this.monitorTab){\r
+                this.on('specialkey', this.checkTab, this);\r
+            }\r
+        }\r
+    },\r
+\r
+    // private\r
+    checkTab : function(me, e){\r
+        if(e.getKey() == e.TAB){\r
+            this.triggerBlur();\r
+        }\r
+    },\r
+\r
+    // private\r
+    onBlur : Ext.emptyFn,\r
+\r
+    // private\r
+    mimicBlur : function(e){\r
+        if(!this.isDestroyed && !this.wrap.contains(e.target) && this.validateBlur(e)){\r
+            this.triggerBlur();\r
+        }\r
+    },\r
+\r
+    // private\r
+    triggerBlur : function(){\r
+        this.mimicing = false;\r
+        this.doc.un('mousedown', this.mimicBlur, this);\r
+        if(this.monitorTab && this.el){\r
+            this.un('specialkey', this.checkTab, this);\r
+        }\r
+        Ext.form.TriggerField.superclass.onBlur.call(this);\r
+        if(this.wrap){\r
+            this.wrap.removeClass(this.wrapFocusClass);\r
+        }\r
+    },\r
+\r
+    beforeBlur : Ext.emptyFn, \r
+    \r
+    /**\r
+     * Allow or prevent the user from directly editing the field text.  If false is passed,\r
+     * the user will only be able to modify the field using the trigger.  This method\r
+     * is the runtime equivalent of setting the 'editable' config option at config time.\r
+     * @param {Boolean} value True to allow the user to directly edit the field text\r
+     */\r
+    setEditable : function(value){\r
+        if(value == this.editable){\r
+            return;\r
+        }\r
+        this.editable = value;\r
+        if(!value){\r
+            this.el.addClass('x-trigger-noedit').on('click', this.onTriggerClick, this).dom.setAttribute('readOnly', true);\r
+        }else{\r
+            this.el.removeClass('x-trigger-noedit').un('click', this.onTriggerClick,  this).dom.removeAttribute('readOnly');\r
+        }\r
+    },\r
+\r
+    // private\r
+    // This should be overriden by any subclass that needs to check whether or not the field can be blurred.\r
+    validateBlur : function(e){\r
+        return true;\r
+    },\r
+\r
+    /**\r
+     * The function that should handle the trigger's click event.  This method does nothing by default\r
+     * until overridden by an implementing function.  See Ext.form.ComboBox and Ext.form.DateField for\r
+     * sample implementations.\r
+     * @method\r
+     * @param {EventObject} e\r
+     */\r
+    onTriggerClick : Ext.emptyFn\r
+\r
+    /**\r
+     * @cfg {Boolean} grow @hide\r
+     */\r
+    /**\r
+     * @cfg {Number} growMin @hide\r
+     */\r
+    /**\r
+     * @cfg {Number} growMax @hide\r
+     */\r
+});\r
+\r
+/**\r
+ * @class Ext.form.TwinTriggerField\r
+ * @extends Ext.form.TriggerField\r
+ * TwinTriggerField is not a public class to be used directly.  It is meant as an abstract base class\r
+ * to be extended by an implementing class.  For an example of implementing this class, see the custom\r
+ * SearchField implementation here:\r
+ * <a href="http://extjs.com/deploy/ext/examples/form/custom.html">http://extjs.com/deploy/ext/examples/form/custom.html</a>\r
+ */\r
+Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {\r
+    /**\r
+     * @cfg {Mixed} triggerConfig\r
+     * <p>A {@link Ext.DomHelper DomHelper} config object specifying the structure of the trigger elements\r
+     * for this Field. (Optional).</p>\r
+     * <p>Specify this when you need a customized element to contain the two trigger elements for this Field.\r
+     * Each trigger element must be marked by the CSS class <tt>x-form-trigger</tt> (also see\r
+     * <tt>{@link #trigger1Class}</tt> and <tt>{@link #trigger2Class}</tt>).</p>\r
+     * <p>Note that when using this option, it is the developer's responsibility to ensure correct sizing,\r
+     * positioning and appearance of the triggers.</p>\r
+     */\r
+    /**\r
+     * @cfg {String} trigger1Class\r
+     * An additional CSS class used to style the trigger button.  The trigger will always get the\r
+     * class <tt>'x-form-trigger'</tt> by default and <tt>triggerClass</tt> will be <b>appended</b> if specified.\r
+     */\r
+    /**\r
+     * @cfg {String} trigger2Class\r
+     * An additional CSS class used to style the trigger button.  The trigger will always get the\r
+     * class <tt>'x-form-trigger'</tt> by default and <tt>triggerClass</tt> will be <b>appended</b> if specified.\r
+     */\r
+\r
+    initComponent : function(){\r
+        Ext.form.TwinTriggerField.superclass.initComponent.call(this);\r
+\r
+        this.triggerConfig = {\r
+            tag:'span', cls:'x-form-twin-triggers', cn:[\r
+            {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},\r
+            {tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}\r
+        ]};\r
+    },\r
+\r
+    getTrigger : function(index){\r
+        return this.triggers[index];\r
+    },\r
+\r
+    initTrigger : function(){\r
+        var ts = this.trigger.select('.x-form-trigger', true);\r
+        var triggerField = this;\r
+        ts.each(function(t, all, index){\r
+            var triggerIndex = 'Trigger'+(index+1);\r
+            t.hide = function(){\r
+                var w = triggerField.wrap.getWidth();\r
+                this.dom.style.display = 'none';\r
+                triggerField.el.setWidth(w-triggerField.trigger.getWidth());\r
+                this['hidden' + triggerIndex] = true;\r
+            };\r
+            t.show = function(){\r
+                var w = triggerField.wrap.getWidth();\r
+                this.dom.style.display = '';\r
+                triggerField.el.setWidth(w-triggerField.trigger.getWidth());\r
+                this['hidden' + triggerIndex] = false;\r
+            };\r
+            \r
+            if(this['hide'+triggerIndex]){\r
+                t.dom.style.display = 'none';\r
+                this['hidden' + triggerIndex] = true;\r
+            }\r
+            this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true});\r
+            t.addClassOnOver('x-form-trigger-over');\r
+            t.addClassOnClick('x-form-trigger-click');\r
+        }, this);\r
+        this.triggers = ts.elements;\r
+    },\r
+    \r
+    getTriggerWidth: function(){\r
+        var tw = 0;\r
+        Ext.each(this.triggers, function(t, index){\r
+            var triggerIndex = 'Trigger' + (index + 1),\r
+                w = t.getWidth();\r
+            if(w === 0 && !this['hidden' + triggerIndex]){\r
+                tw += this.defaultTriggerWidth;\r
+            }else{\r
+                tw += w;\r
+            }\r
+        }, this);\r
+        return tw;\r
+    },\r
+    \r
+    // private\r
+    onDestroy : function() {\r
+        Ext.destroy(this.triggers);\r
+        Ext.form.TwinTriggerField.superclass.onDestroy.call(this);\r
+    },\r
+\r
+    /**\r
+     * The function that should handle the trigger's click event.  This method does nothing by default\r
+     * until overridden by an implementing function. See {@link Ext.form.TriggerField#onTriggerClick}\r
+     * for additional information.  \r
+     * @method\r
+     * @param {EventObject} e\r
+     */\r
+    onTrigger1Click : Ext.emptyFn,\r
+    /**\r
+     * The function that should handle the trigger's click event.  This method does nothing by default\r
+     * until overridden by an implementing function. See {@link Ext.form.TriggerField#onTriggerClick}\r
+     * for additional information.  \r
+     * @method\r
+     * @param {EventObject} e\r
+     */\r
+    onTrigger2Click : Ext.emptyFn\r
+});\r
 Ext.reg('trigger', Ext.form.TriggerField);/**
  * @class Ext.form.TextArea
  * @extends Ext.form.TextField
@@ -53236,7 +54771,8 @@ Ext.form.TextArea = Ext.extend(Ext.form.TextField,  {
 
     /**
      * @cfg {Boolean} preventScrollbars <tt>true</tt> to prevent scrollbars from appearing regardless of how much text is
-     * in the field (equivalent to setting overflow: hidden, defaults to <tt>false</tt>)
+     * in the field. This option is only relevant when {@link #grow} is <tt>true</tt>. Equivalent to setting overflow: hidden, defaults to 
+     * <tt>false</tt>.
      */
     preventScrollbars: false,
     /**
@@ -53924,1231 +55460,1245 @@ Ext.form.DisplayField = Ext.extend(Ext.form.Field,  {
 });\r
 \r
 Ext.reg('displayfield', Ext.form.DisplayField);\r
-/**
- * @class Ext.form.ComboBox
- * @extends Ext.form.TriggerField
- * <p>A combobox control with support for autocomplete, remote-loading, paging and many other features.</p>
- * <p>A ComboBox works in a similar manner to a traditional HTML &lt;select> field. The difference is
- * that to submit the {@link #valueField}, you must specify a {@link #hiddenName} to create a hidden input
- * field to hold the value of the valueField. The <i>{@link #displayField}</i> is shown in the text field
- * which is named according to the {@link #name}.</p>
- * <p><b><u>Events</u></b></p>
- * <p>To do something when something in ComboBox is selected, configure the select event:<pre><code>
-var cb = new Ext.form.ComboBox({
-    // all of your config options
-    listeners:{
-         scope: yourScope,
-         'select': yourFunction
-    }
-});
-
-// Alternatively, you can assign events after the object is created:
-var cb = new Ext.form.ComboBox(yourOptions);
-cb.on('select', yourFunction, yourScope);
- * </code></pre></p>
- *
- * <p><b><u>ComboBox in Grid</u></b></p>
- * <p>If using a ComboBox in an {@link Ext.grid.EditorGridPanel Editor Grid} a {@link Ext.grid.Column#renderer renderer}
- * will be needed to show the displayField when the editor is not active.  Set up the renderer manually, or implement
- * a reusable render, for example:<pre><code>
-// create reusable renderer
-Ext.util.Format.comboRenderer = function(combo){
-    return function(value){
-        var record = combo.findRecord(combo.{@link #valueField}, value);
-        return record ? record.get(combo.{@link #displayField}) : combo.{@link #valueNotFoundText};
-    }
-}
-
-// create the combo instance
-var combo = new Ext.form.ComboBox({
-    {@link #typeAhead}: true,
-    {@link #triggerAction}: 'all',
-    {@link #lazyRender}:true,
-    {@link #mode}: 'local',
-    {@link #store}: new Ext.data.ArrayStore({
-        id: 0,
-        fields: [
-            'myId',
-            'displayText'
-        ],
-        data: [[1, 'item1'], [2, 'item2']]
-    }),
-    {@link #valueField}: 'myId',
-    {@link #displayField}: 'displayText'
-});
-
-// snippet of column model used within grid
-var cm = new Ext.grid.ColumnModel([{
-       ...
-    },{
-       header: "Some Header",
-       dataIndex: 'whatever',
-       width: 130,
-       editor: combo, // specify reference to combo instance
-       renderer: Ext.util.Format.comboRenderer(combo) // pass combo instance to reusable renderer
-    },
-    ...
-]);
- * </code></pre></p>
- *
- * <p><b><u>Filtering</u></b></p>
- * <p>A ComboBox {@link #doQuery uses filtering itself}, for information about filtering the ComboBox
- * store manually see <tt>{@link #lastQuery}</tt>.</p>
- * @constructor
- * Create a new ComboBox.
- * @param {Object} config Configuration options
- * @xtype combo
- */
-Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
-    /**
-     * @cfg {Mixed} transform The id, DOM node or element of an existing HTML SELECT to convert to a ComboBox.
-     * Note that if you specify this and the combo is going to be in an {@link Ext.form.BasicForm} or
-     * {@link Ext.form.FormPanel}, you must also set <tt>{@link #lazyRender} = true</tt>.
-     */
-    /**
-     * @cfg {Boolean} lazyRender <tt>true</tt> to prevent the ComboBox from rendering until requested
-     * (should always be used when rendering into an {@link Ext.Editor} (e.g. {@link Ext.grid.EditorGridPanel Grids}),
-     * defaults to <tt>false</tt>).
-     */
-    /**
-     * @cfg {String/Object} autoCreate <p>A {@link Ext.DomHelper DomHelper} element spec, or <tt>true</tt> for a default
-     * element spec. Used to create the {@link Ext.Component#getEl Element} which will encapsulate this Component.
-     * See <tt>{@link Ext.Component#autoEl autoEl}</tt> for details.  Defaults to:</p>
-     * <pre><code>{tag: "input", type: "text", size: "24", autocomplete: "off"}</code></pre>
-     */
-    /**
-     * @cfg {Ext.data.Store/Array} store The data source to which this combo is bound (defaults to <tt>undefined</tt>).
-     * Acceptable values for this property are:
-     * <div class="mdetail-params"><ul>
-     * <li><b>any {@link Ext.data.Store Store} subclass</b></li>
-     * <li><b>an Array</b> : Arrays will be converted to a {@link Ext.data.ArrayStore} internally.
-     * <div class="mdetail-params"><ul>
-     * <li><b>1-dimensional array</b> : (e.g., <tt>['Foo','Bar']</tt>)<div class="sub-desc">
-     * A 1-dimensional array will automatically be expanded (each array item will be the combo
-     * {@link #valueField value} and {@link #displayField text})</div></li>
-     * <li><b>2-dimensional array</b> : (e.g., <tt>[['f','Foo'],['b','Bar']]</tt>)<div class="sub-desc">
-     * For a multi-dimensional array, the value in index 0 of each item will be assumed to be the combo
-     * {@link #valueField value}, while the value at index 1 is assumed to be the combo {@link #displayField text}.
-     * </div></li></ul></div></li></ul></div>
-     * <p>See also <tt>{@link #mode}</tt>.</p>
-     */
-    /**
-     * @cfg {String} title If supplied, a header element is created containing this text and added into the top of
-     * the dropdown list (defaults to undefined, with no header element)
-     */
-
-    // private
-    defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
-    /**
-     * @cfg {Number} listWidth The width (used as a parameter to {@link Ext.Element#setWidth}) of the dropdown
-     * list (defaults to the width of the ComboBox field).  See also <tt>{@link #minListWidth}
-     */
-    /**
-     * @cfg {String} displayField The underlying {@link Ext.data.Field#name data field name} to bind to this
-     * ComboBox (defaults to undefined if <tt>{@link #mode} = 'remote'</tt> or <tt>'text'</tt> if
-     * {@link #transform transforming a select} a select).
-     * <p>See also <tt>{@link #valueField}</tt>.</p>
-     * <p><b>Note</b>: if using a ComboBox in an {@link Ext.grid.EditorGridPanel Editor Grid} a
-     * {@link Ext.grid.Column#renderer renderer} will be needed to show the displayField when the editor is not
-     * active.</p>
-     */
-    /**
-     * @cfg {String} valueField The underlying {@link Ext.data.Field#name data value name} to bind to this
-     * ComboBox (defaults to undefined if <tt>{@link #mode} = 'remote'</tt> or <tt>'value'</tt> if
-     * {@link #transform transforming a select}).
-     * <p><b>Note</b>: use of a <tt>valueField</tt> requires the user to make a selection in order for a value to be
-     * mapped.  See also <tt>{@link #hiddenName}</tt>, <tt>{@link #hiddenValue}</tt>, and <tt>{@link #displayField}</tt>.</p>
-     */
-    /**
-     * @cfg {String} hiddenName If specified, a hidden form field with this name is dynamically generated to store the
-     * field's data value (defaults to the underlying DOM element's name). Required for the combo's value to automatically
-     * post during a form submission.  See also {@link #valueField}.
-     * <p><b>Note</b>: the hidden field's id will also default to this name if {@link #hiddenId} is not specified.
-     * The ComboBox {@link Ext.Component#id id} and the <tt>{@link #hiddenId}</tt> <b>should be different</b>, since
-     * no two DOM nodes should share the same id.  So, if the ComboBox <tt>{@link Ext.form.Field#name name}</tt> and
-     * <tt>hiddenName</tt> are the same, you should specify a unique <tt>{@link #hiddenId}</tt>.</p>
-     */
-    /**
-     * @cfg {String} hiddenId If <tt>{@link #hiddenName}</tt> is specified, <tt>hiddenId</tt> can also be provided
-     * to give the hidden field a unique id (defaults to the <tt>{@link #hiddenName}</tt>).  The <tt>hiddenId</tt>
-     * and combo {@link Ext.Component#id id} should be different, since no two DOM
-     * nodes should share the same id.
-     */
-    /**
-     * @cfg {String} hiddenValue Sets the initial value of the hidden field if {@link #hiddenName} is
-     * specified to contain the selected {@link #valueField}, from the Store. Defaults to the configured
-     * <tt>{@link Ext.form.Field#value value}</tt>.
-     */
-    /**
-     * @cfg {String} listClass The CSS class to add to the predefined <tt>'x-combo-list'</tt> class
-     * applied the dropdown list element (defaults to '').
-     */
-    listClass : '',
-    /**
-     * @cfg {String} selectedClass CSS class to apply to the selected item in the dropdown list
-     * (defaults to <tt>'x-combo-selected'</tt>)
-     */
-    selectedClass : 'x-combo-selected',
-    /**
-     * @cfg {String} listEmptyText The empty text to display in the data view if no items are found.
-     * (defaults to '')
-     */
-    listEmptyText: '',
-    /**
-     * @cfg {String} triggerClass An additional CSS class used to style the trigger button.  The trigger will always
-     * get the class <tt>'x-form-trigger'</tt> and <tt>triggerClass</tt> will be <b>appended</b> if specified
-     * (defaults to <tt>'x-form-arrow-trigger'</tt> which displays a downward arrow icon).
-     */
-    triggerClass : 'x-form-arrow-trigger',
-    /**
-     * @cfg {Boolean/String} shadow <tt>true</tt> or <tt>"sides"</tt> for the default effect, <tt>"frame"</tt> for
-     * 4-way shadow, and <tt>"drop"</tt> for bottom-right
-     */
-    shadow : 'sides',
-    /**
-     * @cfg {String} listAlign A valid anchor position value. See <tt>{@link Ext.Element#alignTo}</tt> for details
-     * on supported anchor positions (defaults to <tt>'tl-bl?'</tt>)
-     */
-    listAlign : 'tl-bl?',
-    /**
-     * @cfg {Number} maxHeight The maximum height in pixels of the dropdown list before scrollbars are shown
-     * (defaults to <tt>300</tt>)
-     */
-    maxHeight : 300,
-    /**
-     * @cfg {Number} minHeight The minimum height in pixels of the dropdown list when the list is constrained by its
-     * distance to the viewport edges (defaults to <tt>90</tt>)
-     */
-    minHeight : 90,
-    /**
-     * @cfg {String} triggerAction The action to execute when the trigger is clicked.
-     * <div class="mdetail-params"><ul>
-     * <li><b><tt>'query'</tt></b> : <b>Default</b>
-     * <p class="sub-desc">{@link #doQuery run the query} using the {@link Ext.form.Field#getRawValue raw value}.</p></li>
-     * <li><b><tt>'all'</tt></b> :
-     * <p class="sub-desc">{@link #doQuery run the query} specified by the <tt>{@link #allQuery}</tt> config option</p></li>
-     * </ul></div>
-     * <p>See also <code>{@link #queryParam}</code>.</p>
-     */
-    triggerAction : 'query',
-    /**
-     * @cfg {Number} minChars The minimum number of characters the user must type before autocomplete and
-     * {@link #typeAhead} activate (defaults to <tt>4</tt> if <tt>{@link #mode} = 'remote'</tt> or <tt>0</tt> if
-     * <tt>{@link #mode} = 'local'</tt>, does not apply if
-     * <tt>{@link Ext.form.TriggerField#editable editable} = false</tt>).
-     */
-    minChars : 4,
-    /**
-     * @cfg {Boolean} typeAhead <tt>true</tt> to populate and autoselect the remainder of the text being
-     * typed after a configurable delay ({@link #typeAheadDelay}) if it matches a known value (defaults
-     * to <tt>false</tt>)
-     */
-    typeAhead : false,
-    /**
-     * @cfg {Number} queryDelay The length of time in milliseconds to delay between the start of typing and
-     * sending the query to filter the dropdown list (defaults to <tt>500</tt> if <tt>{@link #mode} = 'remote'</tt>
-     * or <tt>10</tt> if <tt>{@link #mode} = 'local'</tt>)
-     */
-    queryDelay : 500,
-    /**
-     * @cfg {Number} pageSize If greater than <tt>0</tt>, a {@link Ext.PagingToolbar} is displayed in the
-     * footer of the dropdown list and the {@link #doQuery filter queries} will execute with page start and
-     * {@link Ext.PagingToolbar#pageSize limit} parameters. Only applies when <tt>{@link #mode} = 'remote'</tt>
-     * (defaults to <tt>0</tt>).
-     */
-    pageSize : 0,
-    /**
-     * @cfg {Boolean} selectOnFocus <tt>true</tt> to select any existing text in the field immediately on focus.
-     * Only applies when <tt>{@link Ext.form.TriggerField#editable editable} = true</tt> (defaults to
-     * <tt>false</tt>).
-     */
-    selectOnFocus : false,
-    /**
-     * @cfg {String} queryParam Name of the query ({@link Ext.data.Store#baseParam baseParam} name for the store)
-     * as it will be passed on the querystring (defaults to <tt>'query'</tt>)
-     */
-    queryParam : 'query',
-    /**
-     * @cfg {String} loadingText The text to display in the dropdown list while data is loading.  Only applies
-     * when <tt>{@link #mode} = 'remote'</tt> (defaults to <tt>'Loading...'</tt>)
-     */
-    loadingText : 'Loading...',
-    /**
-     * @cfg {Boolean} resizable <tt>true</tt> to add a resize handle to the bottom of the dropdown list
-     * (creates an {@link Ext.Resizable} with 'se' {@link Ext.Resizable#pinned pinned} handles).
-     * Defaults to <tt>false</tt>.
-     */
-    resizable : false,
-    /**
-     * @cfg {Number} handleHeight The height in pixels of the dropdown list resize handle if
-     * <tt>{@link #resizable} = true</tt> (defaults to <tt>8</tt>)
-     */
-    handleHeight : 8,
-    /**
-     * @cfg {String} allQuery The text query to send to the server to return all records for the list
-     * with no filtering (defaults to '')
-     */
-    allQuery: '',
-    /**
-     * @cfg {String} mode Acceptable values are:
-     * <div class="mdetail-params"><ul>
-     * <li><b><tt>'remote'</tt></b> : <b>Default</b>
-     * <p class="sub-desc">Automatically loads the <tt>{@link #store}</tt> the <b>first</b> time the trigger
-     * is clicked. If you do not want the store to be automatically loaded the first time the trigger is
-     * clicked, set to <tt>'local'</tt> and manually load the store.  To force a requery of the store
-     * <b>every</b> time the trigger is clicked see <tt>{@link #lastQuery}</tt>.</p></li>
-     * <li><b><tt>'local'</tt></b> :
-     * <p class="sub-desc">ComboBox loads local data</p>
-     * <pre><code>
-var combo = new Ext.form.ComboBox({
-    renderTo: document.body,
-    mode: 'local',
-    store: new Ext.data.ArrayStore({
-        id: 0,
-        fields: [
-            'myId',  // numeric value is the key
-            'displayText'
-        ],
-        data: [[1, 'item1'], [2, 'item2']]  // data is local
-    }),
-    valueField: 'myId',
-    displayField: 'displayText',
-    triggerAction: 'all'
-});
-     * </code></pre></li>
-     * </ul></div>
-     */
-    mode: 'remote',
-    /**
-     * @cfg {Number} minListWidth The minimum width of the dropdown list in pixels (defaults to <tt>70</tt>, will
-     * be ignored if <tt>{@link #listWidth}</tt> has a higher value)
-     */
-    minListWidth : 70,
-    /**
-     * @cfg {Boolean} forceSelection <tt>true</tt> to restrict the selected value to one of the values in the list,
-     * <tt>false</tt> to allow the user to set arbitrary text into the field (defaults to <tt>false</tt>)
-     */
-    forceSelection : false,
-    /**
-     * @cfg {Number} typeAheadDelay The length of time in milliseconds to wait until the typeahead text is displayed
-     * if <tt>{@link #typeAhead} = true</tt> (defaults to <tt>250</tt>)
-     */
-    typeAheadDelay : 250,
-    /**
-     * @cfg {String} valueNotFoundText When using a name/value combo, if the value passed to setValue is not found in
-     * the store, valueNotFoundText will be displayed as the field text if defined (defaults to undefined). If this
-     * default text is used, it means there is no value set and no validation will occur on this field.
-     */
-
-    /**
-     * @cfg {Boolean} lazyInit <tt>true</tt> to not initialize the list for this combo until the field is focused
-     * (defaults to <tt>true</tt>)
-     */
-    lazyInit : true,
-
-    /**
-     * The value of the match string used to filter the store. Delete this property to force a requery.
-     * Example use:
-     * <pre><code>
-var combo = new Ext.form.ComboBox({
-    ...
-    mode: 'remote',
-    ...
-    listeners: {
-        // delete the previous query in the beforequery event or set
-        // combo.lastQuery = null (this will reload the store the next time it expands)
-        beforequery: function(qe){
-            delete qe.combo.lastQuery;
-        }
-    }
-});
-     * </code></pre>
-     * To make sure the filter in the store is not cleared the first time the ComboBox trigger is used
-     * configure the combo with <tt>lastQuery=''</tt>. Example use:
-     * <pre><code>
-var combo = new Ext.form.ComboBox({
-    ...
-    mode: 'local',
-    triggerAction: 'all',
-    lastQuery: ''
-});
-     * </code></pre>
-     * @property lastQuery
-     * @type String
-     */
-
-    // private
-    initComponent : function(){
-        Ext.form.ComboBox.superclass.initComponent.call(this);
-        this.addEvents(
-            /**
-             * @event expand
-             * Fires when the dropdown list is expanded
-             * @param {Ext.form.ComboBox} combo This combo box
-             */
-            'expand',
-            /**
-             * @event collapse
-             * Fires when the dropdown list is collapsed
-             * @param {Ext.form.ComboBox} combo This combo box
-             */
-            'collapse',
-            /**
-             * @event beforeselect
-             * Fires before a list item is selected. Return false to cancel the selection.
-             * @param {Ext.form.ComboBox} combo This combo box
-             * @param {Ext.data.Record} record The data record returned from the underlying store
-             * @param {Number} index The index of the selected item in the dropdown list
-             */
-            'beforeselect',
-            /**
-             * @event select
-             * Fires when a list item is selected
-             * @param {Ext.form.ComboBox} combo This combo box
-             * @param {Ext.data.Record} record The data record returned from the underlying store
-             * @param {Number} index The index of the selected item in the dropdown list
-             */
-            'select',
-            /**
-             * @event beforequery
-             * Fires before all queries are processed. Return false to cancel the query or set the queryEvent's
-             * cancel property to true.
-             * @param {Object} queryEvent An object that has these properties:<ul>
-             * <li><code>combo</code> : Ext.form.ComboBox <div class="sub-desc">This combo box</div></li>
-             * <li><code>query</code> : String <div class="sub-desc">The query</div></li>
-             * <li><code>forceAll</code> : Boolean <div class="sub-desc">True to force "all" query</div></li>
-             * <li><code>cancel</code> : Boolean <div class="sub-desc">Set to true to cancel the query</div></li>
-             * </ul>
-             */
-            'beforequery'
-        );
-        if(this.transform){
-            var s = Ext.getDom(this.transform);
-            if(!this.hiddenName){
-                this.hiddenName = s.name;
-            }
-            if(!this.store){
-                this.mode = 'local';
-                var d = [], opts = s.options;
-                for(var i = 0, len = opts.length;i < len; i++){
-                    var o = opts[i],
-                        value = (o.hasAttribute ? o.hasAttribute('value') : o.getAttributeNode('value').specified) ? o.value : o.text;
-                    if(o.selected && Ext.isEmpty(this.value, true)) {
-                        this.value = value;
-                    }
-                    d.push([value, o.text]);
-                }
-                this.store = new Ext.data.ArrayStore({
-                    'id': 0,
-                    fields: ['value', 'text'],
-                    data : d,
-                    autoDestroy: true
-                });
-                this.valueField = 'value';
-                this.displayField = 'text';
-            }
-            s.name = Ext.id(); // wipe out the name in case somewhere else they have a reference
-            if(!this.lazyRender){
-                this.target = true;
-                this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
-                this.render(this.el.parentNode, s);
-                Ext.removeNode(s); // remove it
-            }else{
-                Ext.removeNode(s); // remove it
-            }
-        }
-        //auto-configure store from local array data
-        else if(this.store){
-            this.store = Ext.StoreMgr.lookup(this.store);
-            if(this.store.autoCreated){
-                this.displayField = this.valueField = 'field1';
-                if(!this.store.expandData){
-                    this.displayField = 'field2';
-                }
-                this.mode = 'local';
-            }
-        }
-
-        this.selectedIndex = -1;
-        if(this.mode == 'local'){
-            if(!Ext.isDefined(this.initialConfig.queryDelay)){
-                this.queryDelay = 10;
-            }
-            if(!Ext.isDefined(this.initialConfig.minChars)){
-                this.minChars = 0;
-            }
-        }
-    },
-
-    // private
-    onRender : function(ct, position){
-        Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
-        if(this.hiddenName){
-            this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
-                    id: (this.hiddenId||this.hiddenName)}, 'before', true);
-
-            // prevent input submission
-            this.el.dom.removeAttribute('name');
-        }
-        if(Ext.isGecko){
-            this.el.dom.setAttribute('autocomplete', 'off');
-        }
-
-        if(!this.lazyInit){
-            this.initList();
-        }else{
-            this.on('focus', this.initList, this, {single: true});
-        }
-    },
-
-    // private
-    initValue : function(){
-        Ext.form.ComboBox.superclass.initValue.call(this);
-        if(this.hiddenField){
-            this.hiddenField.value =
-                Ext.isDefined(this.hiddenValue) ? this.hiddenValue :
-                Ext.isDefined(this.value) ? this.value : '';
-        }
-    },
-
-    // private
-    initList : function(){
-        if(!this.list){
-            var cls = 'x-combo-list';
-
-            this.list = new Ext.Layer({
-                parentEl: this.getListParent(),
-                shadow: this.shadow,
-                cls: [cls, this.listClass].join(' '),
-                constrain:false
-            });
-
-            var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
-            this.list.setSize(lw, 0);
-            this.list.swallowEvent('mousewheel');
-            this.assetHeight = 0;
-            if(this.syncFont !== false){
-                this.list.setStyle('font-size', this.el.getStyle('font-size'));
-            }
-            if(this.title){
-                this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
-                this.assetHeight += this.header.getHeight();
-            }
-
-            this.innerList = this.list.createChild({cls:cls+'-inner'});
-            this.mon(this.innerList, 'mouseover', this.onViewOver, this);
-            this.mon(this.innerList, 'mousemove', this.onViewMove, this);
-            this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
-
-            if(this.pageSize){
-                this.footer = this.list.createChild({cls:cls+'-ft'});
-                this.pageTb = new Ext.PagingToolbar({
-                    store: this.store,
-                    pageSize: this.pageSize,
-                    renderTo:this.footer
-                });
-                this.assetHeight += this.footer.getHeight();
-            }
-
-            if(!this.tpl){
-                /**
-                * @cfg {String/Ext.XTemplate} tpl <p>The template string, or {@link Ext.XTemplate} instance to
-                * use to display each item in the dropdown list. The dropdown list is displayed in a
-                * DataView. See {@link #view}.</p>
-                * <p>The default template string is:</p><pre><code>
-                  '&lt;tpl for=".">&lt;div class="x-combo-list-item">{' + this.displayField + '}&lt;/div>&lt;/tpl>'
-                * </code></pre>
-                * <p>Override the default value to create custom UI layouts for items in the list.
-                * For example:</p><pre><code>
-                  '&lt;tpl for=".">&lt;div ext:qtip="{state}. {nick}" class="x-combo-list-item">{state}&lt;/div>&lt;/tpl>'
-                * </code></pre>
-                * <p>The template <b>must</b> contain one or more substitution parameters using field
-                * names from the Combo's</b> {@link #store Store}. In the example above an
-                * <pre>ext:qtip</pre> attribute is added to display other fields from the Store.</p>
-                * <p>To preserve the default visual look of list items, add the CSS class name
-                * <pre>x-combo-list-item</pre> to the template's container element.</p>
-                * <p>Also see {@link #itemSelector} for additional details.</p>
-                */
-                this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
-                /**
-                 * @cfg {String} itemSelector
-                 * <p>A simple CSS selector (e.g. div.some-class or span:first-child) that will be
-                 * used to determine what nodes the {@link #view Ext.DataView} which handles the dropdown
-                 * display will be working with.</p>
-                 * <p><b>Note</b>: this setting is <b>required</b> if a custom XTemplate has been
-                 * specified in {@link #tpl} which assigns a class other than <pre>'x-combo-list-item'</pre>
-                 * to dropdown list items</b>
-                 */
-            }
-
-            /**
-            * The {@link Ext.DataView DataView} used to display the ComboBox's options.
-            * @type Ext.DataView
-            */
-            this.view = new Ext.DataView({
-                applyTo: this.innerList,
-                tpl: this.tpl,
-                singleSelect: true,
-                selectedClass: this.selectedClass,
-                itemSelector: this.itemSelector || '.' + cls + '-item',
-                emptyText: this.listEmptyText
-            });
-
-            this.mon(this.view, 'click', this.onViewClick, this);
-
-            this.bindStore(this.store, true);
-
-            if(this.resizable){
-                this.resizer = new Ext.Resizable(this.list,  {
-                   pinned:true, handles:'se'
-                });
-                this.mon(this.resizer, 'resize', function(r, w, h){
-                    this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
-                    this.listWidth = w;
-                    this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
-                    this.restrictHeight();
-                }, this);
-
-                this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
-            }
-        }
-    },
-
-    /**
-     * <p>Returns the element used to house this ComboBox's pop-up list. Defaults to the document body.</p>
-     * A custom implementation may be provided as a configuration option if the floating list needs to be rendered
-     * to a different Element. An example might be rendering the list inside a Menu so that clicking
-     * the list does not hide the Menu:<pre><code>
-var store = new Ext.data.ArrayStore({
-    autoDestroy: true,
-    fields: ['initials', 'fullname'],
-    data : [
-        ['FF', 'Fred Flintstone'],
-        ['BR', 'Barney Rubble']
-    ]
-});
-
-var combo = new Ext.form.ComboBox({
-    store: store,
-    displayField: 'fullname',
-    emptyText: 'Select a name...',
-    forceSelection: true,
-    getListParent: function() {
-        return this.el.up('.x-menu');
-    },
-    iconCls: 'no-icon', //use iconCls if placing within menu to shift to right side of menu
-    mode: 'local',
-    selectOnFocus: true,
-    triggerAction: 'all',
-    typeAhead: true,
-    width: 135
-});
-
-var menu = new Ext.menu.Menu({
-    id: 'mainMenu',
-    items: [
-        combo // A Field in a Menu
-    ]
-});
-</code></pre>
-     */
-    getListParent : function() {
-        return document.body;
-    },
-
-    /**
-     * Returns the store associated with this combo.
-     * @return {Ext.data.Store} The store
-     */
-    getStore : function(){
-        return this.store;
-    },
-
-    // private
-    bindStore : function(store, initial){
-        if(this.store && !initial){
-            this.store.un('beforeload', this.onBeforeLoad, this);
-            this.store.un('load', this.onLoad, this);
-            this.store.un('exception', this.collapse, this);
-            if(this.store !== store && this.store.autoDestroy){
-                this.store.destroy();
-            }
-            if(!store){
-                this.store = null;
-                if(this.view){
-                    this.view.bindStore(null);
-                }
-            }
-        }
-        if(store){
-            if(!initial) {
-                this.lastQuery = null;
-                if(this.pageTb) {
-                    this.pageTb.bindStore(store);
-                }
-            }
-
-            this.store = Ext.StoreMgr.lookup(store);
-            this.store.on({
-                scope: this,
-                beforeload: this.onBeforeLoad,
-                load: this.onLoad,
-                exception: this.collapse
-            });
-
-            if(this.view){
-                this.view.bindStore(store);
-            }
-        }
-    },
-
-    // private
-    initEvents : function(){
-        Ext.form.ComboBox.superclass.initEvents.call(this);
-
-        this.keyNav = new Ext.KeyNav(this.el, {
-            "up" : function(e){
-                this.inKeyMode = true;
-                this.selectPrev();
-            },
-
-            "down" : function(e){
-                if(!this.isExpanded()){
-                    this.onTriggerClick();
-                }else{
-                    this.inKeyMode = true;
-                    this.selectNext();
-                }
-            },
-
-            "enter" : function(e){
-                this.onViewClick();
-                this.delayedCheck = true;
-                this.unsetDelayCheck.defer(10, this);
-            },
-
-            "esc" : function(e){
-                this.collapse();
-            },
-
-            "tab" : function(e){
-                this.onViewClick(false);
-                return true;
-            },
-
-            scope : this,
-
-            doRelay : function(foo, bar, hname){
-                if(hname == 'down' || this.scope.isExpanded()){
-                   return Ext.KeyNav.prototype.doRelay.apply(this, arguments);
-                }
-                return true;
-            },
-
-            forceKeyDown : true
-        });
-        this.queryDelay = Math.max(this.queryDelay || 10,
-                this.mode == 'local' ? 10 : 250);
-        this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
-        if(this.typeAhead){
-            this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
-        }
-        if(this.editable !== false && !this.enableKeyEvents){
-            this.mon(this.el, 'keyup', this.onKeyUp, this);
-        }
-    },
-
-    // private
-    onDestroy : function(){
-        if (this.dqTask){
-            this.dqTask.cancel();
-            this.dqTask = null;
-        }
-        this.bindStore(null);
-        Ext.destroy(
-            this.resizer,
-            this.view,
-            this.pageTb,
-            this.list
-        );
-        Ext.form.ComboBox.superclass.onDestroy.call(this);
-    },
-
-    // private
-    unsetDelayCheck : function(){
-        delete this.delayedCheck;
-    },
-
-    // private
-    fireKey : function(e){
-        var fn = function(ev){
-            if (ev.isNavKeyPress() && !this.isExpanded() && !this.delayedCheck) {
-                this.fireEvent("specialkey", this, ev);
-            }
-        };
-        //For some reason I can't track down, the events fire in a different order in webkit.
-        //Need a slight delay here
-        if(this.inEditor && Ext.isWebKit && e.getKey() == e.TAB){
-            fn.defer(10, this, [new Ext.EventObjectImpl(e)]);
-        }else{
-            fn.call(this, e);
-        }
-    },
-
-    // private
-    onResize : function(w, h){
-        Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
-        if(this.list && !Ext.isDefined(this.listWidth)){
-            var lw = Math.max(w, this.minListWidth);
-            this.list.setWidth(lw);
-            this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
-        }
-    },
-
-    // private
-    onEnable : function(){
-        Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
-        if(this.hiddenField){
-            this.hiddenField.disabled = false;
-        }
-    },
-
-    // private
-    onDisable : function(){
-        Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
-        if(this.hiddenField){
-            this.hiddenField.disabled = true;
-        }
-    },
-
-    // private
-    onBeforeLoad : function(){
-        if(!this.hasFocus){
-            return;
-        }
-        this.innerList.update(this.loadingText ?
-               '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
-        this.restrictHeight();
-        this.selectedIndex = -1;
-    },
-
-    // private
-    onLoad : function(){
-        if(!this.hasFocus){
-            return;
-        }
-        if(this.store.getCount() > 0){
-            this.expand();
-            this.restrictHeight();
-            if(this.lastQuery == this.allQuery){
-                if(this.editable){
-                    this.el.dom.select();
-                }
-                if(!this.selectByValue(this.value, true)){
-                    this.select(0, true);
-                }
-            }else{
-                this.selectNext();
-                if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
-                    this.taTask.delay(this.typeAheadDelay);
-                }
-            }
-        }else{
-            this.onEmptyResults();
-        }
-        //this.el.focus();
-    },
-
-    // private
-    onTypeAhead : function(){
-        if(this.store.getCount() > 0){
-            var r = this.store.getAt(0);
-            var newValue = r.data[this.displayField];
-            var len = newValue.length;
-            var selStart = this.getRawValue().length;
-            if(selStart != len){
-                this.setRawValue(newValue);
-                this.selectText(selStart, newValue.length);
-            }
-        }
-    },
-
-    // private
-    onSelect : function(record, index){
-        if(this.fireEvent('beforeselect', this, record, index) !== false){
-            this.setValue(record.data[this.valueField || this.displayField]);
-            this.collapse();
-            this.fireEvent('select', this, record, index);
-        }
-    },
-
-    // inherit docs
-    getName: function(){
-        var hf = this.hiddenField;
-        return hf && hf.name ? hf.name : this.hiddenName || Ext.form.ComboBox.superclass.getName.call(this);
-    },
-
-    /**
-     * Returns the currently selected field value or empty string if no value is set.
-     * @return {String} value The selected value
-     */
-    getValue : function(){
-        if(this.valueField){
-            return Ext.isDefined(this.value) ? this.value : '';
-        }else{
-            return Ext.form.ComboBox.superclass.getValue.call(this);
-        }
-    },
-
-    /**
-     * Clears any text/value currently set in the field
-     */
-    clearValue : function(){
-        if(this.hiddenField){
-            this.hiddenField.value = '';
-        }
-        this.setRawValue('');
-        this.lastSelectionText = '';
-        this.applyEmptyText();
-        this.value = '';
-    },
-
-    /**
-     * Sets the specified value into the field.  If the value finds a match, the corresponding record text
-     * will be displayed in the field.  If the value does not match the data value of an existing item,
-     * and the valueNotFoundText config option is defined, it will be displayed as the default field text.
-     * Otherwise the field will be blank (although the value will still be set).
-     * @param {String} value The value to match
-     * @return {Ext.form.Field} this
-     */
-    setValue : function(v){
-        var text = v;
-        if(this.valueField){
-            var r = this.findRecord(this.valueField, v);
-            if(r){
-                text = r.data[this.displayField];
-            }else if(Ext.isDefined(this.valueNotFoundText)){
-                text = this.valueNotFoundText;
-            }
-        }
-        this.lastSelectionText = text;
-        if(this.hiddenField){
-            this.hiddenField.value = v;
-        }
-        Ext.form.ComboBox.superclass.setValue.call(this, text);
-        this.value = v;
-        return this;
-    },
-
-    // private
-    findRecord : function(prop, value){
-        var record;
-        if(this.store.getCount() > 0){
-            this.store.each(function(r){
-                if(r.data[prop] == value){
-                    record = r;
-                    return false;
-                }
-            });
-        }
-        return record;
-    },
-
-    // private
-    onViewMove : function(e, t){
-        this.inKeyMode = false;
-    },
-
-    // private
-    onViewOver : function(e, t){
-        if(this.inKeyMode){ // prevent key nav and mouse over conflicts
-            return;
-        }
-        var item = this.view.findItemFromChild(t);
-        if(item){
-            var index = this.view.indexOf(item);
-            this.select(index, false);
-        }
-    },
-
-    // private
-    onViewClick : function(doFocus){
-        var index = this.view.getSelectedIndexes()[0];
-        var r = this.store.getAt(index);
-        if(r){
-            this.onSelect(r, index);
-        }
-        if(doFocus !== false){
-            this.el.focus();
-        }
-    },
-
-    // private
-    restrictHeight : function(){
-        this.innerList.dom.style.height = '';
-        var inner = this.innerList.dom;
-        var pad = this.list.getFrameWidth('tb')+(this.resizable?this.handleHeight:0)+this.assetHeight;
-        var h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight);
-        var ha = this.getPosition()[1]-Ext.getBody().getScroll().top;
-        var hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height;
-        var space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5;
-        h = Math.min(h, space, this.maxHeight);
-
-        this.innerList.setHeight(h);
-        this.list.beginUpdate();
-        this.list.setHeight(h+pad);
-        this.list.alignTo(this.wrap, this.listAlign);
-        this.list.endUpdate();
-    },
-
-    // private
-    onEmptyResults : function(){
-        this.collapse();
-    },
-
-    /**
-     * Returns true if the dropdown list is expanded, else false.
-     */
-    isExpanded : function(){
-        return this.list && this.list.isVisible();
-    },
-
-    /**
-     * Select an item in the dropdown list by its data value. This function does NOT cause the select event to fire.
-     * The store must be loaded and the list expanded for this function to work, otherwise use setValue.
-     * @param {String} value The data value of the item to select
-     * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the
-     * selected item if it is not currently in view (defaults to true)
-     * @return {Boolean} True if the value matched an item in the list, else false
-     */
-    selectByValue : function(v, scrollIntoView){
-        if(!Ext.isEmpty(v, true)){
-            var r = this.findRecord(this.valueField || this.displayField, v);
-            if(r){
-                this.select(this.store.indexOf(r), scrollIntoView);
-                return true;
-            }
-        }
-        return false;
-    },
-
-    /**
-     * Select an item in the dropdown list by its numeric index in the list. This function does NOT cause the select event to fire.
-     * The store must be loaded and the list expanded for this function to work, otherwise use setValue.
-     * @param {Number} index The zero-based index of the list item to select
-     * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the
-     * selected item if it is not currently in view (defaults to true)
-     */
-    select : function(index, scrollIntoView){
-        this.selectedIndex = index;
-        this.view.select(index);
-        if(scrollIntoView !== false){
-            var el = this.view.getNode(index);
-            if(el){
-                this.innerList.scrollChildIntoView(el, false);
-            }
-        }
-    },
-
-    // private
-    selectNext : function(){
-        var ct = this.store.getCount();
-        if(ct > 0){
-            if(this.selectedIndex == -1){
-                this.select(0);
-            }else if(this.selectedIndex < ct-1){
-                this.select(this.selectedIndex+1);
-            }
-        }
-    },
-
-    // private
-    selectPrev : function(){
-        var ct = this.store.getCount();
-        if(ct > 0){
-            if(this.selectedIndex == -1){
-                this.select(0);
-            }else if(this.selectedIndex !== 0){
-                this.select(this.selectedIndex-1);
-            }
-        }
-    },
-
-    // private
-    onKeyUp : function(e){
-        var k = e.getKey();
-        if(this.editable !== false && (k == e.BACKSPACE || !e.isSpecialKey())){
-            this.lastKey = k;
-            this.dqTask.delay(this.queryDelay);
-        }
-        Ext.form.ComboBox.superclass.onKeyUp.call(this, e);
-    },
-
-    // private
-    validateBlur : function(){
-        return !this.list || !this.list.isVisible();
-    },
-
-    // private
-    initQuery : function(){
-        this.doQuery(this.getRawValue());
-    },
-
-    // private
-    beforeBlur : function(){
-        var val = this.getRawValue();
-        if(this.forceSelection){
-            if(val.length > 0 && val != this.emptyText){
-               this.el.dom.value = Ext.isDefined(this.lastSelectionText) ? this.lastSelectionText : '';
-                this.applyEmptyText();
-            }else{
-                this.clearValue();
-            }
-        }else{
-            var rec = this.findRecord(this.displayField, val);
-            if(rec){
-                val = rec.get(this.valueField || this.displayField);
-            }
-            this.setValue(val);
-        }
-    },
-
-    /**
-     * Execute a query to filter the dropdown list.  Fires the {@link #beforequery} event prior to performing the
-     * query allowing the query action to be canceled if needed.
-     * @param {String} query The SQL query to execute
-     * @param {Boolean} forceAll <tt>true</tt> to force the query to execute even if there are currently fewer
-     * characters in the field than the minimum specified by the <tt>{@link #minChars}</tt> config option.  It
-     * also clears any filter previously saved in the current store (defaults to <tt>false</tt>)
-     */
-    doQuery : function(q, forceAll){
-        q = Ext.isEmpty(q) ? '' : q;
-        var qe = {
-            query: q,
-            forceAll: forceAll,
-            combo: this,
-            cancel:false
-        };
-        if(this.fireEvent('beforequery', qe)===false || qe.cancel){
-            return false;
-        }
-        q = qe.query;
-        forceAll = qe.forceAll;
-        if(forceAll === true || (q.length >= this.minChars)){
-            if(this.lastQuery !== q){
-                this.lastQuery = q;
-                if(this.mode == 'local'){
-                    this.selectedIndex = -1;
-                    if(forceAll){
-                        this.store.clearFilter();
-                    }else{
-                        this.store.filter(this.displayField, q);
-                    }
-                    this.onLoad();
-                }else{
-                    this.store.baseParams[this.queryParam] = q;
-                    this.store.load({
-                        params: this.getParams(q)
-                    });
-                    this.expand();
-                }
-            }else{
-                this.selectedIndex = -1;
-                this.onLoad();
-            }
-        }
-    },
-
-    // private
-    getParams : function(q){
-        var p = {};
-        //p[this.queryParam] = q;
-        if(this.pageSize){
-            p.start = 0;
-            p.limit = this.pageSize;
-        }
-        return p;
-    },
-
-    /**
-     * Hides the dropdown list if it is currently expanded. Fires the {@link #collapse} event on completion.
-     */
-    collapse : function(){
-        if(!this.isExpanded()){
-            return;
-        }
-        this.list.hide();
-        Ext.getDoc().un('mousewheel', this.collapseIf, this);
-        Ext.getDoc().un('mousedown', this.collapseIf, this);
-        this.fireEvent('collapse', this);
-    },
-
-    // private
-    collapseIf : function(e){
-        if(!e.within(this.wrap) && !e.within(this.list)){
-            this.collapse();
-        }
-    },
-
-    /**
-     * Expands the dropdown list if it is currently hidden. Fires the {@link #expand} event on completion.
-     */
-    expand : function(){
-        if(this.isExpanded() || !this.hasFocus){
-            return;
-        }
-        this.list.alignTo(this.wrap, this.listAlign);
-        this.list.show();
-        if(Ext.isGecko2){
-            this.innerList.setOverflow('auto'); // necessary for FF 2.0/Mac
-        }
-        Ext.getDoc().on({
-            scope: this,
-            mousewheel: this.collapseIf,
-            mousedown: this.collapseIf
-        });
-        this.fireEvent('expand', this);
-    },
-
-    /**
-     * @method onTriggerClick
-     * @hide
-     */
-    // private
-    // Implements the default empty TriggerField.onTriggerClick function
-    onTriggerClick : function(){
-        if(this.disabled){
-            return;
-        }
-        if(this.isExpanded()){
-            this.collapse();
-            this.el.focus();
-        }else {
-            this.onFocus({});
-            if(this.triggerAction == 'all') {
-                this.doQuery(this.allQuery, true);
-            } else {
-                this.doQuery(this.getRawValue());
-            }
-            this.el.focus();
-        }
-    }
-
-    /**
-     * @hide
-     * @method autoSize
-     */
-    /**
-     * @cfg {Boolean} grow @hide
-     */
-    /**
-     * @cfg {Number} growMin @hide
-     */
-    /**
-     * @cfg {Number} growMax @hide
-     */
-
-});
+/**\r
+ * @class Ext.form.ComboBox\r
+ * @extends Ext.form.TriggerField\r
+ * <p>A combobox control with support for autocomplete, remote-loading, paging and many other features.</p>\r
+ * <p>A ComboBox works in a similar manner to a traditional HTML &lt;select> field. The difference is\r
+ * that to submit the {@link #valueField}, you must specify a {@link #hiddenName} to create a hidden input\r
+ * field to hold the value of the valueField. The <i>{@link #displayField}</i> is shown in the text field\r
+ * which is named according to the {@link #name}.</p>\r
+ * <p><b><u>Events</u></b></p>\r
+ * <p>To do something when something in ComboBox is selected, configure the select event:<pre><code>\r
+var cb = new Ext.form.ComboBox({\r
+    // all of your config options\r
+    listeners:{\r
+         scope: yourScope,\r
+         'select': yourFunction\r
+    }\r
+});\r
+\r
+// Alternatively, you can assign events after the object is created:\r
+var cb = new Ext.form.ComboBox(yourOptions);\r
+cb.on('select', yourFunction, yourScope);\r
+ * </code></pre></p>\r
+ *\r
+ * <p><b><u>ComboBox in Grid</u></b></p>\r
+ * <p>If using a ComboBox in an {@link Ext.grid.EditorGridPanel Editor Grid} a {@link Ext.grid.Column#renderer renderer}\r
+ * will be needed to show the displayField when the editor is not active.  Set up the renderer manually, or implement\r
+ * a reusable render, for example:<pre><code>\r
+// create reusable renderer\r
+Ext.util.Format.comboRenderer = function(combo){\r
+    return function(value){\r
+        var record = combo.findRecord(combo.{@link #valueField}, value);\r
+        return record ? record.get(combo.{@link #displayField}) : combo.{@link #valueNotFoundText};\r
+    }\r
+}\r
+\r
+// create the combo instance\r
+var combo = new Ext.form.ComboBox({\r
+    {@link #typeAhead}: true,\r
+    {@link #triggerAction}: 'all',\r
+    {@link #lazyRender}:true,\r
+    {@link #mode}: 'local',\r
+    {@link #store}: new Ext.data.ArrayStore({\r
+        id: 0,\r
+        fields: [\r
+            'myId',\r
+            'displayText'\r
+        ],\r
+        data: [[1, 'item1'], [2, 'item2']]\r
+    }),\r
+    {@link #valueField}: 'myId',\r
+    {@link #displayField}: 'displayText'\r
+});\r
+\r
+// snippet of column model used within grid\r
+var cm = new Ext.grid.ColumnModel([{\r
+       ...\r
+    },{\r
+       header: "Some Header",\r
+       dataIndex: 'whatever',\r
+       width: 130,\r
+       editor: combo, // specify reference to combo instance\r
+       renderer: Ext.util.Format.comboRenderer(combo) // pass combo instance to reusable renderer\r
+    },\r
+    ...\r
+]);\r
+ * </code></pre></p>\r
+ *\r
+ * <p><b><u>Filtering</u></b></p>\r
+ * <p>A ComboBox {@link #doQuery uses filtering itself}, for information about filtering the ComboBox\r
+ * store manually see <tt>{@link #lastQuery}</tt>.</p>\r
+ * @constructor\r
+ * Create a new ComboBox.\r
+ * @param {Object} config Configuration options\r
+ * @xtype combo\r
+ */\r
+Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {\r
+    /**\r
+     * @cfg {Mixed} transform The id, DOM node or element of an existing HTML SELECT to convert to a ComboBox.\r
+     * Note that if you specify this and the combo is going to be in an {@link Ext.form.BasicForm} or\r
+     * {@link Ext.form.FormPanel}, you must also set <tt>{@link #lazyRender} = true</tt>.\r
+     */\r
+    /**\r
+     * @cfg {Boolean} lazyRender <tt>true</tt> to prevent the ComboBox from rendering until requested\r
+     * (should always be used when rendering into an {@link Ext.Editor} (e.g. {@link Ext.grid.EditorGridPanel Grids}),\r
+     * defaults to <tt>false</tt>).\r
+     */\r
+    /**\r
+     * @cfg {String/Object} autoCreate <p>A {@link Ext.DomHelper DomHelper} element spec, or <tt>true</tt> for a default\r
+     * element spec. Used to create the {@link Ext.Component#getEl Element} which will encapsulate this Component.\r
+     * See <tt>{@link Ext.Component#autoEl autoEl}</tt> for details.  Defaults to:</p>\r
+     * <pre><code>{tag: "input", type: "text", size: "24", autocomplete: "off"}</code></pre>\r
+     */\r
+    /**\r
+     * @cfg {Ext.data.Store/Array} store The data source to which this combo is bound (defaults to <tt>undefined</tt>).\r
+     * Acceptable values for this property are:\r
+     * <div class="mdetail-params"><ul>\r
+     * <li><b>any {@link Ext.data.Store Store} subclass</b></li>\r
+     * <li><b>an Array</b> : Arrays will be converted to a {@link Ext.data.ArrayStore} internally,\r
+     * automatically generating {@link Ext.data.Field#name field names} to work with all data components.\r
+     * <div class="mdetail-params"><ul>\r
+     * <li><b>1-dimensional array</b> : (e.g., <tt>['Foo','Bar']</tt>)<div class="sub-desc">\r
+     * A 1-dimensional array will automatically be expanded (each array item will be used for both the combo\r
+     * {@link #valueField} and {@link #displayField})</div></li>\r
+     * <li><b>2-dimensional array</b> : (e.g., <tt>[['f','Foo'],['b','Bar']]</tt>)<div class="sub-desc">\r
+     * For a multi-dimensional array, the value in index 0 of each item will be assumed to be the combo\r
+     * {@link #valueField}, while the value at index 1 is assumed to be the combo {@link #displayField}.\r
+     * </div></li></ul></div></li></ul></div>\r
+     * <p>See also <tt>{@link #mode}</tt>.</p>\r
+     */\r
+    /**\r
+     * @cfg {String} title If supplied, a header element is created containing this text and added into the top of\r
+     * the dropdown list (defaults to undefined, with no header element)\r
+     */\r
+\r
+    // private\r
+    defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},\r
+    /**\r
+     * @cfg {Number} listWidth The width (used as a parameter to {@link Ext.Element#setWidth}) of the dropdown\r
+     * list (defaults to the width of the ComboBox field).  See also <tt>{@link #minListWidth}\r
+     */\r
+    /**\r
+     * @cfg {String} displayField The underlying {@link Ext.data.Field#name data field name} to bind to this\r
+     * ComboBox (defaults to undefined if <tt>{@link #mode} = 'remote'</tt> or <tt>'field1'</tt> if\r
+     * {@link #transform transforming a select} or if the {@link #store field name is autogenerated based on\r
+     * the store configuration}).\r
+     * <p>See also <tt>{@link #valueField}</tt>.</p>\r
+     * <p><b>Note</b>: if using a ComboBox in an {@link Ext.grid.EditorGridPanel Editor Grid} a\r
+     * {@link Ext.grid.Column#renderer renderer} will be needed to show the displayField when the editor is not\r
+     * active.</p>\r
+     */\r
+    /**\r
+     * @cfg {String} valueField The underlying {@link Ext.data.Field#name data value name} to bind to this\r
+     * ComboBox (defaults to undefined if <tt>{@link #mode} = 'remote'</tt> or <tt>'field2'</tt> if\r
+     * {@link #transform transforming a select} or if the {@link #store field name is autogenerated based on\r
+     * the store configuration}).\r
+     * <p><b>Note</b>: use of a <tt>valueField</tt> requires the user to make a selection in order for a value to be\r
+     * mapped.  See also <tt>{@link #hiddenName}</tt>, <tt>{@link #hiddenValue}</tt>, and <tt>{@link #displayField}</tt>.</p>\r
+     */\r
+    /**\r
+     * @cfg {String} hiddenName If specified, a hidden form field with this name is dynamically generated to store the\r
+     * field's data value (defaults to the underlying DOM element's name). Required for the combo's value to automatically\r
+     * post during a form submission.  See also {@link #valueField}.\r
+     * <p><b>Note</b>: the hidden field's id will also default to this name if {@link #hiddenId} is not specified.\r
+     * The ComboBox {@link Ext.Component#id id} and the <tt>{@link #hiddenId}</tt> <b>should be different</b>, since\r
+     * no two DOM nodes should share the same id.  So, if the ComboBox <tt>{@link Ext.form.Field#name name}</tt> and\r
+     * <tt>hiddenName</tt> are the same, you should specify a unique <tt>{@link #hiddenId}</tt>.</p>\r
+     */\r
+    /**\r
+     * @cfg {String} hiddenId If <tt>{@link #hiddenName}</tt> is specified, <tt>hiddenId</tt> can also be provided\r
+     * to give the hidden field a unique id (defaults to the <tt>{@link #hiddenName}</tt>).  The <tt>hiddenId</tt>\r
+     * and combo {@link Ext.Component#id id} should be different, since no two DOM\r
+     * nodes should share the same id.\r
+     */\r
+    /**\r
+     * @cfg {String} hiddenValue Sets the initial value of the hidden field if {@link #hiddenName} is\r
+     * specified to contain the selected {@link #valueField}, from the Store. Defaults to the configured\r
+     * <tt>{@link Ext.form.Field#value value}</tt>.\r
+     */\r
+    /**\r
+     * @cfg {String} listClass The CSS class to add to the predefined <tt>'x-combo-list'</tt> class\r
+     * applied the dropdown list element (defaults to '').\r
+     */\r
+    listClass : '',\r
+    /**\r
+     * @cfg {String} selectedClass CSS class to apply to the selected item in the dropdown list\r
+     * (defaults to <tt>'x-combo-selected'</tt>)\r
+     */\r
+    selectedClass : 'x-combo-selected',\r
+    /**\r
+     * @cfg {String} listEmptyText The empty text to display in the data view if no items are found.\r
+     * (defaults to '')\r
+     */\r
+    listEmptyText: '',\r
+    /**\r
+     * @cfg {String} triggerClass An additional CSS class used to style the trigger button.  The trigger will always\r
+     * get the class <tt>'x-form-trigger'</tt> and <tt>triggerClass</tt> will be <b>appended</b> if specified\r
+     * (defaults to <tt>'x-form-arrow-trigger'</tt> which displays a downward arrow icon).\r
+     */\r
+    triggerClass : 'x-form-arrow-trigger',\r
+    /**\r
+     * @cfg {Boolean/String} shadow <tt>true</tt> or <tt>"sides"</tt> for the default effect, <tt>"frame"</tt> for\r
+     * 4-way shadow, and <tt>"drop"</tt> for bottom-right\r
+     */\r
+    shadow : 'sides',\r
+    /**\r
+     * @cfg {String} listAlign A valid anchor position value. See <tt>{@link Ext.Element#alignTo}</tt> for details\r
+     * on supported anchor positions (defaults to <tt>'tl-bl?'</tt>)\r
+     */\r
+    listAlign : 'tl-bl?',\r
+    /**\r
+     * @cfg {Number} maxHeight The maximum height in pixels of the dropdown list before scrollbars are shown\r
+     * (defaults to <tt>300</tt>)\r
+     */\r
+    maxHeight : 300,\r
+    /**\r
+     * @cfg {Number} minHeight The minimum height in pixels of the dropdown list when the list is constrained by its\r
+     * distance to the viewport edges (defaults to <tt>90</tt>)\r
+     */\r
+    minHeight : 90,\r
+    /**\r
+     * @cfg {String} triggerAction The action to execute when the trigger is clicked.\r
+     * <div class="mdetail-params"><ul>\r
+     * <li><b><tt>'query'</tt></b> : <b>Default</b>\r
+     * <p class="sub-desc">{@link #doQuery run the query} using the {@link Ext.form.Field#getRawValue raw value}.</p></li>\r
+     * <li><b><tt>'all'</tt></b> :\r
+     * <p class="sub-desc">{@link #doQuery run the query} specified by the <tt>{@link #allQuery}</tt> config option</p></li>\r
+     * </ul></div>\r
+     * <p>See also <code>{@link #queryParam}</code>.</p>\r
+     */\r
+    triggerAction : 'query',\r
+    /**\r
+     * @cfg {Number} minChars The minimum number of characters the user must type before autocomplete and\r
+     * {@link #typeAhead} activate (defaults to <tt>4</tt> if <tt>{@link #mode} = 'remote'</tt> or <tt>0</tt> if\r
+     * <tt>{@link #mode} = 'local'</tt>, does not apply if\r
+     * <tt>{@link Ext.form.TriggerField#editable editable} = false</tt>).\r
+     */\r
+    minChars : 4,\r
+    /**\r
+     * @cfg {Boolean} typeAhead <tt>true</tt> to populate and autoselect the remainder of the text being\r
+     * typed after a configurable delay ({@link #typeAheadDelay}) if it matches a known value (defaults\r
+     * to <tt>false</tt>)\r
+     */\r
+    typeAhead : false,\r
+    /**\r
+     * @cfg {Number} queryDelay The length of time in milliseconds to delay between the start of typing and\r
+     * sending the query to filter the dropdown list (defaults to <tt>500</tt> if <tt>{@link #mode} = 'remote'</tt>\r
+     * or <tt>10</tt> if <tt>{@link #mode} = 'local'</tt>)\r
+     */\r
+    queryDelay : 500,\r
+    /**\r
+     * @cfg {Number} pageSize If greater than <tt>0</tt>, a {@link Ext.PagingToolbar} is displayed in the\r
+     * footer of the dropdown list and the {@link #doQuery filter queries} will execute with page start and\r
+     * {@link Ext.PagingToolbar#pageSize limit} parameters. Only applies when <tt>{@link #mode} = 'remote'</tt>\r
+     * (defaults to <tt>0</tt>).\r
+     */\r
+    pageSize : 0,\r
+    /**\r
+     * @cfg {Boolean} selectOnFocus <tt>true</tt> to select any existing text in the field immediately on focus.\r
+     * Only applies when <tt>{@link Ext.form.TriggerField#editable editable} = true</tt> (defaults to\r
+     * <tt>false</tt>).\r
+     */\r
+    selectOnFocus : false,\r
+    /**\r
+     * @cfg {String} queryParam Name of the query ({@link Ext.data.Store#baseParam baseParam} name for the store)\r
+     * as it will be passed on the querystring (defaults to <tt>'query'</tt>)\r
+     */\r
+    queryParam : 'query',\r
+    /**\r
+     * @cfg {String} loadingText The text to display in the dropdown list while data is loading.  Only applies\r
+     * when <tt>{@link #mode} = 'remote'</tt> (defaults to <tt>'Loading...'</tt>)\r
+     */\r
+    loadingText : 'Loading...',\r
+    /**\r
+     * @cfg {Boolean} resizable <tt>true</tt> to add a resize handle to the bottom of the dropdown list\r
+     * (creates an {@link Ext.Resizable} with 'se' {@link Ext.Resizable#pinned pinned} handles).\r
+     * Defaults to <tt>false</tt>.\r
+     */\r
+    resizable : false,\r
+    /**\r
+     * @cfg {Number} handleHeight The height in pixels of the dropdown list resize handle if\r
+     * <tt>{@link #resizable} = true</tt> (defaults to <tt>8</tt>)\r
+     */\r
+    handleHeight : 8,\r
+    /**\r
+     * @cfg {String} allQuery The text query to send to the server to return all records for the list\r
+     * with no filtering (defaults to '')\r
+     */\r
+    allQuery: '',\r
+    /**\r
+     * @cfg {String} mode Acceptable values are:\r
+     * <div class="mdetail-params"><ul>\r
+     * <li><b><tt>'remote'</tt></b> : <b>Default</b>\r
+     * <p class="sub-desc">Automatically loads the <tt>{@link #store}</tt> the <b>first</b> time the trigger\r
+     * is clicked. If you do not want the store to be automatically loaded the first time the trigger is\r
+     * clicked, set to <tt>'local'</tt> and manually load the store.  To force a requery of the store\r
+     * <b>every</b> time the trigger is clicked see <tt>{@link #lastQuery}</tt>.</p></li>\r
+     * <li><b><tt>'local'</tt></b> :\r
+     * <p class="sub-desc">ComboBox loads local data</p>\r
+     * <pre><code>\r
+var combo = new Ext.form.ComboBox({\r
+    renderTo: document.body,\r
+    mode: 'local',\r
+    store: new Ext.data.ArrayStore({\r
+        id: 0,\r
+        fields: [\r
+            'myId',  // numeric value is the key\r
+            'displayText'\r
+        ],\r
+        data: [[1, 'item1'], [2, 'item2']]  // data is local\r
+    }),\r
+    valueField: 'myId',\r
+    displayField: 'displayText',\r
+    triggerAction: 'all'\r
+});\r
+     * </code></pre></li>\r
+     * </ul></div>\r
+     */\r
+    mode: 'remote',\r
+    /**\r
+     * @cfg {Number} minListWidth The minimum width of the dropdown list in pixels (defaults to <tt>70</tt>, will\r
+     * be ignored if <tt>{@link #listWidth}</tt> has a higher value)\r
+     */\r
+    minListWidth : 70,\r
+    /**\r
+     * @cfg {Boolean} forceSelection <tt>true</tt> to restrict the selected value to one of the values in the list,\r
+     * <tt>false</tt> to allow the user to set arbitrary text into the field (defaults to <tt>false</tt>)\r
+     */\r
+    forceSelection : false,\r
+    /**\r
+     * @cfg {Number} typeAheadDelay The length of time in milliseconds to wait until the typeahead text is displayed\r
+     * if <tt>{@link #typeAhead} = true</tt> (defaults to <tt>250</tt>)\r
+     */\r
+    typeAheadDelay : 250,\r
+    /**\r
+     * @cfg {String} valueNotFoundText When using a name/value combo, if the value passed to setValue is not found in\r
+     * the store, valueNotFoundText will be displayed as the field text if defined (defaults to undefined). If this\r
+     * default text is used, it means there is no value set and no validation will occur on this field.\r
+     */\r
+\r
+    /**\r
+     * @cfg {Boolean} lazyInit <tt>true</tt> to not initialize the list for this combo until the field is focused\r
+     * (defaults to <tt>true</tt>)\r
+     */\r
+    lazyInit : true,\r
+\r
+    /**\r
+     * The value of the match string used to filter the store. Delete this property to force a requery.\r
+     * Example use:\r
+     * <pre><code>\r
+var combo = new Ext.form.ComboBox({\r
+    ...\r
+    mode: 'remote',\r
+    ...\r
+    listeners: {\r
+        // delete the previous query in the beforequery event or set\r
+        // combo.lastQuery = null (this will reload the store the next time it expands)\r
+        beforequery: function(qe){\r
+            delete qe.combo.lastQuery;\r
+        }\r
+    }\r
+});\r
+     * </code></pre>\r
+     * To make sure the filter in the store is not cleared the first time the ComboBox trigger is used\r
+     * configure the combo with <tt>lastQuery=''</tt>. Example use:\r
+     * <pre><code>\r
+var combo = new Ext.form.ComboBox({\r
+    ...\r
+    mode: 'local',\r
+    triggerAction: 'all',\r
+    lastQuery: ''\r
+});\r
+     * </code></pre>\r
+     * @property lastQuery\r
+     * @type String\r
+     */\r
+\r
+    // private\r
+    initComponent : function(){\r
+        Ext.form.ComboBox.superclass.initComponent.call(this);\r
+        this.addEvents(\r
+            /**\r
+             * @event expand\r
+             * Fires when the dropdown list is expanded\r
+             * @param {Ext.form.ComboBox} combo This combo box\r
+             */\r
+            'expand',\r
+            /**\r
+             * @event collapse\r
+             * Fires when the dropdown list is collapsed\r
+             * @param {Ext.form.ComboBox} combo This combo box\r
+             */\r
+            'collapse',\r
+            /**\r
+             * @event beforeselect\r
+             * Fires before a list item is selected. Return false to cancel the selection.\r
+             * @param {Ext.form.ComboBox} combo This combo box\r
+             * @param {Ext.data.Record} record The data record returned from the underlying store\r
+             * @param {Number} index The index of the selected item in the dropdown list\r
+             */\r
+            'beforeselect',\r
+            /**\r
+             * @event select\r
+             * Fires when a list item is selected\r
+             * @param {Ext.form.ComboBox} combo This combo box\r
+             * @param {Ext.data.Record} record The data record returned from the underlying store\r
+             * @param {Number} index The index of the selected item in the dropdown list\r
+             */\r
+            'select',\r
+            /**\r
+             * @event beforequery\r
+             * Fires before all queries are processed. Return false to cancel the query or set the queryEvent's\r
+             * cancel property to true.\r
+             * @param {Object} queryEvent An object that has these properties:<ul>\r
+             * <li><code>combo</code> : Ext.form.ComboBox <div class="sub-desc">This combo box</div></li>\r
+             * <li><code>query</code> : String <div class="sub-desc">The query</div></li>\r
+             * <li><code>forceAll</code> : Boolean <div class="sub-desc">True to force "all" query</div></li>\r
+             * <li><code>cancel</code> : Boolean <div class="sub-desc">Set to true to cancel the query</div></li>\r
+             * </ul>\r
+             */\r
+            'beforequery'\r
+        );\r
+        if(this.transform){\r
+            var s = Ext.getDom(this.transform);\r
+            if(!this.hiddenName){\r
+                this.hiddenName = s.name;\r
+            }\r
+            if(!this.store){\r
+                this.mode = 'local';\r
+                var d = [], opts = s.options;\r
+                for(var i = 0, len = opts.length;i < len; i++){\r
+                    var o = opts[i],\r
+                        value = (o.hasAttribute ? o.hasAttribute('value') : o.getAttributeNode('value').specified) ? o.value : o.text;\r
+                    if(o.selected && Ext.isEmpty(this.value, true)) {\r
+                        this.value = value;\r
+                    }\r
+                    d.push([value, o.text]);\r
+                }\r
+                this.store = new Ext.data.ArrayStore({\r
+                    'id': 0,\r
+                    fields: ['value', 'text'],\r
+                    data : d,\r
+                    autoDestroy: true\r
+                });\r
+                this.valueField = 'value';\r
+                this.displayField = 'text';\r
+            }\r
+            s.name = Ext.id(); // wipe out the name in case somewhere else they have a reference\r
+            if(!this.lazyRender){\r
+                this.target = true;\r
+                this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);\r
+                this.render(this.el.parentNode, s);\r
+                Ext.removeNode(s); // remove it\r
+            }else{\r
+                Ext.removeNode(s); // remove it\r
+            }\r
+        }\r
+        //auto-configure store from local array data\r
+        else if(this.store){\r
+            this.store = Ext.StoreMgr.lookup(this.store);\r
+            if(this.store.autoCreated){\r
+                this.displayField = this.valueField = 'field1';\r
+                if(!this.store.expandData){\r
+                    this.displayField = 'field2';\r
+                }\r
+                this.mode = 'local';\r
+            }\r
+        }\r
+\r
+        this.selectedIndex = -1;\r
+        if(this.mode == 'local'){\r
+            if(!Ext.isDefined(this.initialConfig.queryDelay)){\r
+                this.queryDelay = 10;\r
+            }\r
+            if(!Ext.isDefined(this.initialConfig.minChars)){\r
+                this.minChars = 0;\r
+            }\r
+        }\r
+    },\r
+\r
+    // private\r
+    onRender : function(ct, position){\r
+        Ext.form.ComboBox.superclass.onRender.call(this, ct, position);\r
+        if(this.hiddenName){\r
+            this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,\r
+                    id: (this.hiddenId||this.hiddenName)}, 'before', true);\r
+\r
+            // prevent input submission\r
+            this.el.dom.removeAttribute('name');\r
+        }\r
+        if(Ext.isGecko){\r
+            this.el.dom.setAttribute('autocomplete', 'off');\r
+        }\r
+\r
+        if(!this.lazyInit){\r
+            this.initList();\r
+        }else{\r
+            this.on('focus', this.initList, this, {single: true});\r
+        }\r
+    },\r
+\r
+    // private\r
+    initValue : function(){\r
+        Ext.form.ComboBox.superclass.initValue.call(this);\r
+        if(this.hiddenField){\r
+            this.hiddenField.value =\r
+                Ext.isDefined(this.hiddenValue) ? this.hiddenValue :\r
+                Ext.isDefined(this.value) ? this.value : '';\r
+        }\r
+    },\r
+\r
+    // private\r
+    initList : function(){\r
+        if(!this.list){\r
+            var cls = 'x-combo-list';\r
+\r
+            this.list = new Ext.Layer({\r
+                parentEl: this.getListParent(),\r
+                shadow: this.shadow,\r
+                cls: [cls, this.listClass].join(' '),\r
+                constrain:false\r
+            });\r
+\r
+            var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);\r
+            this.list.setSize(lw, 0);\r
+            this.list.swallowEvent('mousewheel');\r
+            this.assetHeight = 0;\r
+            if(this.syncFont !== false){\r
+                this.list.setStyle('font-size', this.el.getStyle('font-size'));\r
+            }\r
+            if(this.title){\r
+                this.header = this.list.createChild({cls:cls+'-hd', html: this.title});\r
+                this.assetHeight += this.header.getHeight();\r
+            }\r
+\r
+            this.innerList = this.list.createChild({cls:cls+'-inner'});\r
+            this.mon(this.innerList, 'mouseover', this.onViewOver, this);\r
+            this.mon(this.innerList, 'mousemove', this.onViewMove, this);\r
+            this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));\r
+\r
+            if(this.pageSize){\r
+                this.footer = this.list.createChild({cls:cls+'-ft'});\r
+                this.pageTb = new Ext.PagingToolbar({\r
+                    store: this.store,\r
+                    pageSize: this.pageSize,\r
+                    renderTo:this.footer\r
+                });\r
+                this.assetHeight += this.footer.getHeight();\r
+            }\r
+\r
+            if(!this.tpl){\r
+                /**\r
+                * @cfg {String/Ext.XTemplate} tpl <p>The template string, or {@link Ext.XTemplate} instance to\r
+                * use to display each item in the dropdown list. The dropdown list is displayed in a\r
+                * DataView. See {@link #view}.</p>\r
+                * <p>The default template string is:</p><pre><code>\r
+                  '&lt;tpl for=".">&lt;div class="x-combo-list-item">{' + this.displayField + '}&lt;/div>&lt;/tpl>'\r
+                * </code></pre>\r
+                * <p>Override the default value to create custom UI layouts for items in the list.\r
+                * For example:</p><pre><code>\r
+                  '&lt;tpl for=".">&lt;div ext:qtip="{state}. {nick}" class="x-combo-list-item">{state}&lt;/div>&lt;/tpl>'\r
+                * </code></pre>\r
+                * <p>The template <b>must</b> contain one or more substitution parameters using field\r
+                * names from the Combo's</b> {@link #store Store}. In the example above an\r
+                * <pre>ext:qtip</pre> attribute is added to display other fields from the Store.</p>\r
+                * <p>To preserve the default visual look of list items, add the CSS class name\r
+                * <pre>x-combo-list-item</pre> to the template's container element.</p>\r
+                * <p>Also see {@link #itemSelector} for additional details.</p>\r
+                */\r
+                this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';\r
+                /**\r
+                 * @cfg {String} itemSelector\r
+                 * <p>A simple CSS selector (e.g. div.some-class or span:first-child) that will be\r
+                 * used to determine what nodes the {@link #view Ext.DataView} which handles the dropdown\r
+                 * display will be working with.</p>\r
+                 * <p><b>Note</b>: this setting is <b>required</b> if a custom XTemplate has been\r
+                 * specified in {@link #tpl} which assigns a class other than <pre>'x-combo-list-item'</pre>\r
+                 * to dropdown list items</b>\r
+                 */\r
+            }\r
+\r
+            /**\r
+            * The {@link Ext.DataView DataView} used to display the ComboBox's options.\r
+            * @type Ext.DataView\r
+            */\r
+            this.view = new Ext.DataView({\r
+                applyTo: this.innerList,\r
+                tpl: this.tpl,\r
+                singleSelect: true,\r
+                selectedClass: this.selectedClass,\r
+                itemSelector: this.itemSelector || '.' + cls + '-item',\r
+                emptyText: this.listEmptyText\r
+            });\r
+\r
+            this.mon(this.view, 'click', this.onViewClick, this);\r
+\r
+            this.bindStore(this.store, true);\r
+\r
+            if(this.resizable){\r
+                this.resizer = new Ext.Resizable(this.list,  {\r
+                   pinned:true, handles:'se'\r
+                });\r
+                this.mon(this.resizer, 'resize', function(r, w, h){\r
+                    this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;\r
+                    this.listWidth = w;\r
+                    this.innerList.setWidth(w - this.list.getFrameWidth('lr'));\r
+                    this.restrictHeight();\r
+                }, this);\r
+\r
+                this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');\r
+            }\r
+        }\r
+    },\r
+\r
+    /**\r
+     * <p>Returns the element used to house this ComboBox's pop-up list. Defaults to the document body.</p>\r
+     * A custom implementation may be provided as a configuration option if the floating list needs to be rendered\r
+     * to a different Element. An example might be rendering the list inside a Menu so that clicking\r
+     * the list does not hide the Menu:<pre><code>\r
+var store = new Ext.data.ArrayStore({\r
+    autoDestroy: true,\r
+    fields: ['initials', 'fullname'],\r
+    data : [\r
+        ['FF', 'Fred Flintstone'],\r
+        ['BR', 'Barney Rubble']\r
+    ]\r
+});\r
+\r
+var combo = new Ext.form.ComboBox({\r
+    store: store,\r
+    displayField: 'fullname',\r
+    emptyText: 'Select a name...',\r
+    forceSelection: true,\r
+    getListParent: function() {\r
+        return this.el.up('.x-menu');\r
+    },\r
+    iconCls: 'no-icon', //use iconCls if placing within menu to shift to right side of menu\r
+    mode: 'local',\r
+    selectOnFocus: true,\r
+    triggerAction: 'all',\r
+    typeAhead: true,\r
+    width: 135\r
+});\r
+\r
+var menu = new Ext.menu.Menu({\r
+    id: 'mainMenu',\r
+    items: [\r
+        combo // A Field in a Menu\r
+    ]\r
+});\r
+</code></pre>\r
+     */\r
+    getListParent : function() {\r
+        return document.body;\r
+    },\r
+\r
+    /**\r
+     * Returns the store associated with this combo.\r
+     * @return {Ext.data.Store} The store\r
+     */\r
+    getStore : function(){\r
+        return this.store;\r
+    },\r
+\r
+    // private\r
+    bindStore : function(store, initial){\r
+        if(this.store && !initial){\r
+            if(this.store !== store && this.store.autoDestroy){\r
+                this.store.destroy();\r
+            }else{\r
+                this.store.un('beforeload', this.onBeforeLoad, this);\r
+                this.store.un('load', this.onLoad, this);\r
+                this.store.un('exception', this.collapse, this);\r
+            }\r
+            if(!store){\r
+                this.store = null;\r
+                if(this.view){\r
+                    this.view.bindStore(null);\r
+                }\r
+                if(this.pageTb){\r
+                    this.pageTb.bindStore(null);\r
+                }\r
+            }\r
+        }\r
+        if(store){\r
+            if(!initial) {\r
+                this.lastQuery = null;\r
+                if(this.pageTb) {\r
+                    this.pageTb.bindStore(store);\r
+                }\r
+            }\r
+\r
+            this.store = Ext.StoreMgr.lookup(store);\r
+            this.store.on({\r
+                scope: this,\r
+                beforeload: this.onBeforeLoad,\r
+                load: this.onLoad,\r
+                exception: this.collapse\r
+            });\r
+\r
+            if(this.view){\r
+                this.view.bindStore(store);\r
+            }\r
+        }\r
+    },\r
+\r
+    // private\r
+    initEvents : function(){\r
+        Ext.form.ComboBox.superclass.initEvents.call(this);\r
+\r
+        this.keyNav = new Ext.KeyNav(this.el, {\r
+            "up" : function(e){\r
+                this.inKeyMode = true;\r
+                this.selectPrev();\r
+            },\r
+\r
+            "down" : function(e){\r
+                if(!this.isExpanded()){\r
+                    this.onTriggerClick();\r
+                }else{\r
+                    this.inKeyMode = true;\r
+                    this.selectNext();\r
+                }\r
+            },\r
+\r
+            "enter" : function(e){\r
+                this.onViewClick();\r
+            },\r
+\r
+            "esc" : function(e){\r
+                this.collapse();\r
+            },\r
+\r
+            "tab" : function(e){\r
+                this.onViewClick(false);\r
+                return true;\r
+            },\r
+\r
+            scope : this,\r
+\r
+            doRelay : function(e, h, hname){\r
+                if(hname == 'down' || this.scope.isExpanded()){\r
+                    // this MUST be called before ComboBox#fireKey()\r
+                    var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments);\r
+                    if(!Ext.isIE && Ext.EventManager.useKeydown){\r
+                        // call Combo#fireKey() for browsers which use keydown event (except IE)\r
+                        this.scope.fireKey(e);\r
+                    }\r
+                    return relay;\r
+                }\r
+                return true;\r
+            },\r
+\r
+            forceKeyDown : true,\r
+            defaultEventAction: 'stopEvent'\r
+        });\r
+        this.queryDelay = Math.max(this.queryDelay || 10,\r
+                this.mode == 'local' ? 10 : 250);\r
+        this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);\r
+        if(this.typeAhead){\r
+            this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);\r
+        }\r
+        if(this.editable !== false && !this.enableKeyEvents){\r
+            this.mon(this.el, 'keyup', this.onKeyUp, this);\r
+        }\r
+    },\r
+\r
+    // private\r
+    onDestroy : function(){\r
+        if (this.dqTask){\r
+            this.dqTask.cancel();\r
+            this.dqTask = null;\r
+        }\r
+        this.bindStore(null);\r
+        Ext.destroy(\r
+            this.resizer,\r
+            this.view,\r
+            this.pageTb,\r
+            this.list\r
+        );\r
+        Ext.form.ComboBox.superclass.onDestroy.call(this);\r
+    },\r
+\r
+    // private\r
+    fireKey : function(e){\r
+        if (!this.isExpanded()) {\r
+            Ext.form.ComboBox.superclass.fireKey.call(this, e);\r
+        }\r
+    },\r
+\r
+    // private\r
+    onResize : function(w, h){\r
+        Ext.form.ComboBox.superclass.onResize.apply(this, arguments);\r
+        if(this.isVisible() && this.list){\r
+            this.doResize(w);\r
+        }else{\r
+            this.bufferSize = w;\r
+        }\r
+    },\r
+    \r
+    doResize: function(w){\r
+        if(!Ext.isDefined(this.listWidth)){\r
+            var lw = Math.max(w, this.minListWidth);\r
+            this.list.setWidth(lw);\r
+            this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));\r
+        }    \r
+    },\r
+\r
+    // private\r
+    onEnable : function(){\r
+        Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);\r
+        if(this.hiddenField){\r
+            this.hiddenField.disabled = false;\r
+        }\r
+    },\r
+\r
+    // private\r
+    onDisable : function(){\r
+        Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);\r
+        if(this.hiddenField){\r
+            this.hiddenField.disabled = true;\r
+        }\r
+    },\r
+\r
+    // private\r
+    onBeforeLoad : function(){\r
+        if(!this.hasFocus){\r
+            return;\r
+        }\r
+        this.innerList.update(this.loadingText ?\r
+               '<div class="loading-indicator">'+this.loadingText+'</div>' : '');\r
+        this.restrictHeight();\r
+        this.selectedIndex = -1;\r
+    },\r
+\r
+    // private\r
+    onLoad : function(){\r
+        if(!this.hasFocus){\r
+            return;\r
+        }\r
+        if(this.store.getCount() > 0 || this.listEmptyText){\r
+            this.expand();\r
+            this.restrictHeight();\r
+            if(this.lastQuery == this.allQuery){\r
+                if(this.editable){\r
+                    this.el.dom.select();\r
+                }\r
+                if(!this.selectByValue(this.value, true)){\r
+                    this.select(0, true);\r
+                }\r
+            }else{\r
+                this.selectNext();\r
+                if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){\r
+                    this.taTask.delay(this.typeAheadDelay);\r
+                }\r
+            }\r
+        }else{\r
+            this.onEmptyResults();\r
+        }\r
+        //this.el.focus();\r
+    },\r
+\r
+    // private\r
+    onTypeAhead : function(){\r
+        if(this.store.getCount() > 0){\r
+            var r = this.store.getAt(0);\r
+            var newValue = r.data[this.displayField];\r
+            var len = newValue.length;\r
+            var selStart = this.getRawValue().length;\r
+            if(selStart != len){\r
+                this.setRawValue(newValue);\r
+                this.selectText(selStart, newValue.length);\r
+            }\r
+        }\r
+    },\r
+\r
+    // private\r
+    onSelect : function(record, index){\r
+        if(this.fireEvent('beforeselect', this, record, index) !== false){\r
+            this.setValue(record.data[this.valueField || this.displayField]);\r
+            this.collapse();\r
+            this.fireEvent('select', this, record, index);\r
+        }\r
+    },\r
+\r
+    // inherit docs\r
+    getName: function(){\r
+        var hf = this.hiddenField;\r
+        return hf && hf.name ? hf.name : this.hiddenName || Ext.form.ComboBox.superclass.getName.call(this);\r
+    },\r
+\r
+    /**\r
+     * Returns the currently selected field value or empty string if no value is set.\r
+     * @return {String} value The selected value\r
+     */\r
+    getValue : function(){\r
+        if(this.valueField){\r
+            return Ext.isDefined(this.value) ? this.value : '';\r
+        }else{\r
+            return Ext.form.ComboBox.superclass.getValue.call(this);\r
+        }\r
+    },\r
+\r
+    /**\r
+     * Clears any text/value currently set in the field\r
+     */\r
+    clearValue : function(){\r
+        if(this.hiddenField){\r
+            this.hiddenField.value = '';\r
+        }\r
+        this.setRawValue('');\r
+        this.lastSelectionText = '';\r
+        this.applyEmptyText();\r
+        this.value = '';\r
+    },\r
+\r
+    /**\r
+     * Sets the specified value into the field.  If the value finds a match, the corresponding record text\r
+     * will be displayed in the field.  If the value does not match the data value of an existing item,\r
+     * and the valueNotFoundText config option is defined, it will be displayed as the default field text.\r
+     * Otherwise the field will be blank (although the value will still be set).\r
+     * @param {String} value The value to match\r
+     * @return {Ext.form.Field} this\r
+     */\r
+    setValue : function(v){\r
+        var text = v;\r
+        if(this.valueField){\r
+            var r = this.findRecord(this.valueField, v);\r
+            if(r){\r
+                text = r.data[this.displayField];\r
+            }else if(Ext.isDefined(this.valueNotFoundText)){\r
+                text = this.valueNotFoundText;\r
+            }\r
+        }\r
+        this.lastSelectionText = text;\r
+        if(this.hiddenField){\r
+            this.hiddenField.value = v;\r
+        }\r
+        Ext.form.ComboBox.superclass.setValue.call(this, text);\r
+        this.value = v;\r
+        return this;\r
+    },\r
+\r
+    // private\r
+    findRecord : function(prop, value){\r
+        var record;\r
+        if(this.store.getCount() > 0){\r
+            this.store.each(function(r){\r
+                if(r.data[prop] == value){\r
+                    record = r;\r
+                    return false;\r
+                }\r
+            });\r
+        }\r
+        return record;\r
+    },\r
+\r
+    // private\r
+    onViewMove : function(e, t){\r
+        this.inKeyMode = false;\r
+    },\r
+\r
+    // private\r
+    onViewOver : function(e, t){\r
+        if(this.inKeyMode){ // prevent key nav and mouse over conflicts\r
+            return;\r
+        }\r
+        var item = this.view.findItemFromChild(t);\r
+        if(item){\r
+            var index = this.view.indexOf(item);\r
+            this.select(index, false);\r
+        }\r
+    },\r
+\r
+    // private\r
+    onViewClick : function(doFocus){\r
+        var index = this.view.getSelectedIndexes()[0],\r
+            s = this.store,\r
+            r = s.getAt(index);\r
+        if(r){\r
+            this.onSelect(r, index);\r
+        }else if(s.getCount() === 0){\r
+            this.onEmptyResults();\r
+        }\r
+        if(doFocus !== false){\r
+            this.el.focus();\r
+        }\r
+    },\r
+\r
+    // private\r
+    restrictHeight : function(){\r
+        this.innerList.dom.style.height = '';\r
+        var inner = this.innerList.dom,\r
+            pad = this.list.getFrameWidth('tb') + (this.resizable ? this.handleHeight : 0) + this.assetHeight,\r
+            h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight),\r
+            ha = this.getPosition()[1]-Ext.getBody().getScroll().top,\r
+            hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height,\r
+            space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5;\r
+            \r
+        h = Math.min(h, space, this.maxHeight);\r
+\r
+        this.innerList.setHeight(h);\r
+        this.list.beginUpdate();\r
+        this.list.setHeight(h+pad);\r
+        this.list.alignTo(this.wrap, this.listAlign);\r
+        this.list.endUpdate();\r
+    },\r
+\r
+    // private\r
+    onEmptyResults : function(){\r
+        this.collapse();\r
+    },\r
+\r
+    /**\r
+     * Returns true if the dropdown list is expanded, else false.\r
+     */\r
+    isExpanded : function(){\r
+        return this.list && this.list.isVisible();\r
+    },\r
+\r
+    /**\r
+     * Select an item in the dropdown list by its data value. This function does NOT cause the select event to fire.\r
+     * The store must be loaded and the list expanded for this function to work, otherwise use setValue.\r
+     * @param {String} value The data value of the item to select\r
+     * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the\r
+     * selected item if it is not currently in view (defaults to true)\r
+     * @return {Boolean} True if the value matched an item in the list, else false\r
+     */\r
+    selectByValue : function(v, scrollIntoView){\r
+        if(!Ext.isEmpty(v, true)){\r
+            var r = this.findRecord(this.valueField || this.displayField, v);\r
+            if(r){\r
+                this.select(this.store.indexOf(r), scrollIntoView);\r
+                return true;\r
+            }\r
+        }\r
+        return false;\r
+    },\r
+\r
+    /**\r
+     * Select an item in the dropdown list by its numeric index in the list. This function does NOT cause the select event to fire.\r
+     * The store must be loaded and the list expanded for this function to work, otherwise use setValue.\r
+     * @param {Number} index The zero-based index of the list item to select\r
+     * @param {Boolean} scrollIntoView False to prevent the dropdown list from autoscrolling to display the\r
+     * selected item if it is not currently in view (defaults to true)\r
+     */\r
+    select : function(index, scrollIntoView){\r
+        this.selectedIndex = index;\r
+        this.view.select(index);\r
+        if(scrollIntoView !== false){\r
+            var el = this.view.getNode(index);\r
+            if(el){\r
+                this.innerList.scrollChildIntoView(el, false);\r
+            }\r
+        }\r
+    },\r
+\r
+    // private\r
+    selectNext : function(){\r
+        var ct = this.store.getCount();\r
+        if(ct > 0){\r
+            if(this.selectedIndex == -1){\r
+                this.select(0);\r
+            }else if(this.selectedIndex < ct-1){\r
+                this.select(this.selectedIndex+1);\r
+            }\r
+        }\r
+    },\r
+\r
+    // private\r
+    selectPrev : function(){\r
+        var ct = this.store.getCount();\r
+        if(ct > 0){\r
+            if(this.selectedIndex == -1){\r
+                this.select(0);\r
+            }else if(this.selectedIndex !== 0){\r
+                this.select(this.selectedIndex-1);\r
+            }\r
+        }\r
+    },\r
+\r
+    // private\r
+    onKeyUp : function(e){\r
+        var k = e.getKey();\r
+        if(this.editable !== false && (k == e.BACKSPACE || !e.isSpecialKey())){\r
+            this.lastKey = k;\r
+            this.dqTask.delay(this.queryDelay);\r
+        }\r
+        Ext.form.ComboBox.superclass.onKeyUp.call(this, e);\r
+    },\r
+\r
+    // private\r
+    validateBlur : function(){\r
+        return !this.list || !this.list.isVisible();\r
+    },\r
+\r
+    // private\r
+    initQuery : function(){\r
+        this.doQuery(this.getRawValue());\r
+    },\r
+\r
+    // private\r
+    beforeBlur : function(){\r
+        var val = this.getRawValue(),\r
+            rec = this.findRecord(this.displayField, val);\r
+        if(!rec && this.forceSelection){\r
+            if(val.length > 0 && val != this.emptyText){\r
+                this.el.dom.value = Ext.isDefined(this.lastSelectionText) ? this.lastSelectionText : '';\r
+                this.applyEmptyText();\r
+            }else{\r
+                this.clearValue();\r
+            }\r
+        }else{\r
+            if(rec){\r
+                val = rec.get(this.valueField || this.displayField);\r
+            }\r
+            this.setValue(val);\r
+        }\r
+    },\r
+\r
+    /**\r
+     * Execute a query to filter the dropdown list.  Fires the {@link #beforequery} event prior to performing the\r
+     * query allowing the query action to be canceled if needed.\r
+     * @param {String} query The SQL query to execute\r
+     * @param {Boolean} forceAll <tt>true</tt> to force the query to execute even if there are currently fewer\r
+     * characters in the field than the minimum specified by the <tt>{@link #minChars}</tt> config option.  It\r
+     * also clears any filter previously saved in the current store (defaults to <tt>false</tt>)\r
+     */\r
+    doQuery : function(q, forceAll){\r
+        q = Ext.isEmpty(q) ? '' : q;\r
+        var qe = {\r
+            query: q,\r
+            forceAll: forceAll,\r
+            combo: this,\r
+            cancel:false\r
+        };\r
+        if(this.fireEvent('beforequery', qe)===false || qe.cancel){\r
+            return false;\r
+        }\r
+        q = qe.query;\r
+        forceAll = qe.forceAll;\r
+        if(forceAll === true || (q.length >= this.minChars)){\r
+            if(this.lastQuery !== q){\r
+                this.lastQuery = q;\r
+                if(this.mode == 'local'){\r
+                    this.selectedIndex = -1;\r
+                    if(forceAll){\r
+                        this.store.clearFilter();\r
+                    }else{\r
+                        this.store.filter(this.displayField, q);\r
+                    }\r
+                    this.onLoad();\r
+                }else{\r
+                    this.store.baseParams[this.queryParam] = q;\r
+                    this.store.load({\r
+                        params: this.getParams(q)\r
+                    });\r
+                    this.expand();\r
+                }\r
+            }else{\r
+                this.selectedIndex = -1;\r
+                this.onLoad();\r
+            }\r
+        }\r
+    },\r
+\r
+    // private\r
+    getParams : function(q){\r
+        var p = {};\r
+        //p[this.queryParam] = q;\r
+        if(this.pageSize){\r
+            p.start = 0;\r
+            p.limit = this.pageSize;\r
+        }\r
+        return p;\r
+    },\r
+\r
+    /**\r
+     * Hides the dropdown list if it is currently expanded. Fires the {@link #collapse} event on completion.\r
+     */\r
+    collapse : function(){\r
+        if(!this.isExpanded()){\r
+            return;\r
+        }\r
+        this.list.hide();\r
+        Ext.getDoc().un('mousewheel', this.collapseIf, this);\r
+        Ext.getDoc().un('mousedown', this.collapseIf, this);\r
+        this.fireEvent('collapse', this);\r
+    },\r
+\r
+    // private\r
+    collapseIf : function(e){\r
+        if(!e.within(this.wrap) && !e.within(this.list)){\r
+            this.collapse();\r
+        }\r
+    },\r
+\r
+    /**\r
+     * Expands the dropdown list if it is currently hidden. Fires the {@link #expand} event on completion.\r
+     */\r
+    expand : function(){\r
+        if(this.isExpanded() || !this.hasFocus){\r
+            return;\r
+        }\r
+        if(this.bufferSize){\r
+            this.doResize(this.bufferSize);\r
+            delete this.bufferSize;\r
+        }\r
+        this.list.alignTo(this.wrap, this.listAlign);\r
+        this.list.show();\r
+        if(Ext.isGecko2){\r
+            this.innerList.setOverflow('auto'); // necessary for FF 2.0/Mac\r
+        }\r
+        Ext.getDoc().on({\r
+            scope: this,\r
+            mousewheel: this.collapseIf,\r
+            mousedown: this.collapseIf\r
+        });\r
+        this.fireEvent('expand', this);\r
+    },\r
+\r
+    /**\r
+     * @method onTriggerClick\r
+     * @hide\r
+     */\r
+    // private\r
+    // Implements the default empty TriggerField.onTriggerClick function\r
+    onTriggerClick : function(){\r
+        if(this.disabled){\r
+            return;\r
+        }\r
+        if(this.isExpanded()){\r
+            this.collapse();\r
+            this.el.focus();\r
+        }else {\r
+            this.onFocus({});\r
+            if(this.triggerAction == 'all') {\r
+                this.doQuery(this.allQuery, true);\r
+            } else {\r
+                this.doQuery(this.getRawValue());\r
+            }\r
+            this.el.focus();\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @hide\r
+     * @method autoSize\r
+     */\r
+    /**\r
+     * @cfg {Boolean} grow @hide\r
+     */\r
+    /**\r
+     * @cfg {Number} growMin @hide\r
+     */\r
+    /**\r
+     * @cfg {Number} growMax @hide\r
+     */\r
+\r
+});\r
 Ext.reg('combo', Ext.form.ComboBox);/**
  * @class Ext.form.Checkbox
  * @extends Ext.form.Field
@@ -55193,546 +56743,563 @@ Ext.form.Checkbox = Ext.extend(Ext.form.Field,  {
     /**
      * @cfg {Object} scope An object to use as the scope ('this' reference) of the {@link #handler} function
      * (defaults to this Checkbox).
-     */
-
-    // private
-    actionMode : 'wrap',
-    
-       // private
-    initComponent : function(){
-        Ext.form.Checkbox.superclass.initComponent.call(this);
-        this.addEvents(
-            /**
-             * @event check
-             * Fires when the checkbox is checked or unchecked.
-             * @param {Ext.form.Checkbox} this This checkbox
-             * @param {Boolean} checked The new checked value
-             */
-            'check'
-        );
-    },
-
-    // private
-    onResize : function(){
-        Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
-        if(!this.boxLabel && !this.fieldLabel){
-            this.el.alignTo(this.wrap, 'c-c');
-        }
-    },
-
-    // private
-    initEvents : function(){
-        Ext.form.Checkbox.superclass.initEvents.call(this);
-        this.mon(this.el, 'click', this.onClick, this);
-        this.mon(this.el, 'change', this.onClick, this);
-    },
-
-       // private
-    getResizeEl : function(){
-        return this.wrap;
-    },
-
-    // private
-    getPositionEl : function(){
-        return this.wrap;
-    },
-
-    /**
-     * @hide
-     * Overridden and disabled. The editor element does not support standard valid/invalid marking.
-     * @method
-     */
-    markInvalid : Ext.emptyFn,
-    /**
-     * @hide
-     * Overridden and disabled. The editor element does not support standard valid/invalid marking.
-     * @method
-     */
-    clearInvalid : Ext.emptyFn,
-
-    // private
-    onRender : function(ct, position){
-        Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
-        if(this.inputValue !== undefined){
-            this.el.dom.value = this.inputValue;
-        }
-        this.wrap = this.el.wrap({cls: 'x-form-check-wrap'});
-        if(this.boxLabel){
-            this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
-        }
-        if(this.checked){
-            this.setValue(true);
-        }else{
-            this.checked = this.el.dom.checked;
-        }
-    },
-
-    // private
-    onDestroy : function(){
-        Ext.destroy(this.wrap);
-        Ext.form.Checkbox.superclass.onDestroy.call(this);
-    },
-
-    // private
-    initValue : function() {
-        this.originalValue = this.getValue();
-    },
-
-    /**
-     * Returns the checked state of the checkbox.
-     * @return {Boolean} True if checked, else false
-     */
-    getValue : function(){
-        if(this.rendered){
-            return this.el.dom.checked;
-        }
-        return false;
-    },
-
-       // private
-    onClick : function(){
-        if(this.el.dom.checked != this.checked){
-            this.setValue(this.el.dom.checked);
-        }
-    },
-
-    /**
-     * Sets the checked state of the checkbox, fires the 'check' event, and calls a
-     * <code>{@link #handler}</code> (if configured).
-     * @param {Boolean/String} checked The following values will check the checkbox:
-     * <code>true, 'true', '1', or 'on'</code>. Any other value will uncheck the checkbox.
-     * @return {Ext.form.Field} this
-     */
-    setValue : function(v){
-        var checked = this.checked ;
-        this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
-        if(this.rendered){
-            this.el.dom.checked = this.checked;
-            this.el.dom.defaultChecked = this.checked;
-        }
-        if(checked != this.checked){
-            this.fireEvent('check', this, this.checked);
-            if(this.handler){
-                this.handler.call(this.scope || this, this, this.checked);
-            }
-        }
-        return this;
-    }
-});
-Ext.reg('checkbox', Ext.form.Checkbox);
-/**
- * @class Ext.form.CheckboxGroup
- * @extends Ext.form.Field
- * <p>A grouping container for {@link Ext.form.Checkbox} controls.</p>
- * <p>Sample usage:</p>
- * <pre><code>
-var myCheckboxGroup = new Ext.form.CheckboxGroup({
-    id:'myGroup',
-    xtype: 'checkboxgroup',
-    fieldLabel: 'Single Column',
-    itemCls: 'x-check-group-alt',
-    // Put all controls in a single column with width 100%
-    columns: 1,
-    items: [
-        {boxLabel: 'Item 1', name: 'cb-col-1'},
-        {boxLabel: 'Item 2', name: 'cb-col-2', checked: true},
-        {boxLabel: 'Item 3', name: 'cb-col-3'}
-    ]
-});
- * </code></pre>
- * @constructor
- * Creates a new CheckboxGroup
- * @param {Object} config Configuration options
- * @xtype checkboxgroup
- */
-Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
-    /**
-     * @cfg {Array} items An Array of {@link Ext.form.Checkbox Checkbox}es or Checkbox config objects
-     * to arrange in the group.
-     */
-    /**
-     * @cfg {String/Number/Array} columns Specifies the number of columns to use when displaying grouped
-     * checkbox/radio controls using automatic layout.  This config can take several types of values:
-     * <ul><li><b>'auto'</b> : <p class="sub-desc">The controls will be rendered one per column on one row and the width
-     * of each column will be evenly distributed based on the width of the overall field container. This is the default.</p></li>
-     * <li><b>Number</b> : <p class="sub-desc">If you specific a number (e.g., 3) that number of columns will be 
-     * created and the contained controls will be automatically distributed based on the value of {@link #vertical}.</p></li>
-     * <li><b>Array</b> : Object<p class="sub-desc">You can also specify an array of column widths, mixing integer
-     * (fixed width) and float (percentage width) values as needed (e.g., [100, .25, .75]). Any integer values will
-     * be rendered first, then any float values will be calculated as a percentage of the remaining space. Float
-     * values do not have to add up to 1 (100%) although if you want the controls to take up the entire field
-     * container you should do so.</p></li></ul>
-     */
-    columns : 'auto',
-    /**
-     * @cfg {Boolean} vertical True to distribute contained controls across columns, completely filling each column 
-     * top to bottom before starting on the next column.  The number of controls in each column will be automatically
-     * calculated to keep columns as even as possible.  The default value is false, so that controls will be added
-     * to columns one at a time, completely filling each row left to right before starting on the next row.
-     */
-    vertical : false,
-    /**
-     * @cfg {Boolean} allowBlank False to validate that at least one item in the group is checked (defaults to true).
-     * If no items are selected at validation time, {@link @blankText} will be used as the error text.
-     */
-    allowBlank : true,
-    /**
-     * @cfg {String} blankText Error text to display if the {@link #allowBlank} validation fails (defaults to "You must 
-     * select at least one item in this group")
-     */
-    blankText : "You must select at least one item in this group",
-    
-    // private
-    defaultType : 'checkbox',
-    
-    // private
-    groupCls : 'x-form-check-group',
-    
-    // private
-    initComponent: function(){
-        this.addEvents(
-            /**
-             * @event change
-             * Fires when the state of a child checkbox changes.
-             * @param {Ext.form.CheckboxGroup} this
-             * @param {Array} checked An array containing the checked boxes.
-             */
-            'change'
-        );   
-        Ext.form.CheckboxGroup.superclass.initComponent.call(this);
-    },
-    
-    // private
-    onRender : function(ct, position){
-        if(!this.el){
-            var panelCfg = {
-                cls: this.groupCls,
-                layout: 'column',
-                border: false,
-                renderTo: ct
-            };
-            var colCfg = {
-                defaultType: this.defaultType,
-                layout: 'form',
-                border: false,
-                defaults: {
-                    hideLabel: true,
-                    anchor: '100%'
-                }
-            };
-            
-            if(this.items[0].items){
-                
-                // The container has standard ColumnLayout configs, so pass them in directly
-                
-                Ext.apply(panelCfg, {
-                    layoutConfig: {columns: this.items.length},
-                    defaults: this.defaults,
-                    items: this.items
-                });
-                for(var i=0, len=this.items.length; i<len; i++){
-                    Ext.applyIf(this.items[i], colCfg);
-                }
-                
-            }else{
-                
-                // The container has field item configs, so we have to generate the column
-                // panels first then move the items into the columns as needed.
-                
-                var numCols, cols = [];
-                
-                if(typeof this.columns == 'string'){ // 'auto' so create a col per item
-                    this.columns = this.items.length;
-                }
-                if(!Ext.isArray(this.columns)){
-                    var cs = [];
-                    for(var i=0; i<this.columns; i++){
-                        cs.push((100/this.columns)*.01); // distribute by even %
-                    }
-                    this.columns = cs;
-                }
-                
-                numCols = this.columns.length;
-                
-                // Generate the column configs with the correct width setting
-                for(var i=0; i<numCols; i++){
-                    var cc = Ext.apply({items:[]}, colCfg);
-                    cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];
-                    if(this.defaults){
-                        cc.defaults = Ext.apply(cc.defaults || {}, this.defaults)
-                    }
-                    cols.push(cc);
-                };
-                
-                // Distribute the original items into the columns
-                if(this.vertical){
-                    var rows = Math.ceil(this.items.length / numCols), ri = 0;
-                    for(var i=0, len=this.items.length; i<len; i++){
-                        if(i>0 && i%rows==0){
-                            ri++;
-                        }
-                        if(this.items[i].fieldLabel){
-                            this.items[i].hideLabel = false;
-                        }
-                        cols[ri].items.push(this.items[i]);
-                    };
-                }else{
-                    for(var i=0, len=this.items.length; i<len; i++){
-                        var ci = i % numCols;
-                        if(this.items[i].fieldLabel){
-                            this.items[i].hideLabel = false;
-                        }
-                        cols[ci].items.push(this.items[i]);
-                    };
-                }
-                
-                Ext.apply(panelCfg, {
-                    layoutConfig: {columns: numCols},
-                    items: cols
-                });
-            }
-            
-            this.panel = new Ext.Panel(panelCfg);
-            this.panel.ownerCt = this;
-            this.el = this.panel.getEl();
-            
-            if(this.forId && this.itemCls){
-                var l = this.el.up(this.itemCls).child('label', true);
-                if(l){
-                    l.setAttribute('htmlFor', this.forId);
-                }
-            }
-            
-            var fields = this.panel.findBy(function(c){
-                return c.isFormField;
-            }, this);
-            
-            this.items = new Ext.util.MixedCollection();
-            this.items.addAll(fields);
-        }
-        Ext.form.CheckboxGroup.superclass.onRender.call(this, ct, position);
-    },
-    
-    afterRender : function(){
-        Ext.form.CheckboxGroup.superclass.afterRender.call(this);
-        if(this.values){
-            this.setValue.apply(this, this.values);
-            delete this.values;
-        }
-        this.eachItem(function(item){
-            item.on('check', this.fireChecked, this);
-            item.inGroup = true;
-        });
-    },
-    
-    // private
-    doLayout: function(){
-        //ugly method required to layout hidden items
-        if(this.rendered){
-            this.panel.forceLayout = this.ownerCt.forceLayout;
-            this.panel.doLayout();
-        }
-    },
-    
-    // private
-    fireChecked: function(){
-        var arr = [];
-        this.eachItem(function(item){
-            if(item.checked){
-                arr.push(item);
-            }
-        });
-        this.fireEvent('change', this, arr);
-    },
-    
-    // private
-    validateValue : function(value){
-        if(!this.allowBlank){
-            var blank = true;
-            this.eachItem(function(f){
-                if(f.checked){
-                    return (blank = false);
-                }
-            });
-            if(blank){
-                this.markInvalid(this.blankText);
-                return false;
-            }
-        }
-        return true;
-    },
-    
-    // private
-    onDisable : function(){
-        this.eachItem(function(item){
-            item.disable();
-        });
-    },
+     */
 
     // private
-    onEnable : function(){
-        this.eachItem(function(item){
-            item.enable();
-        });
-    },
+    actionMode : 'wrap',
     
+       // private
+    initComponent : function(){
+        Ext.form.Checkbox.superclass.initComponent.call(this);
+        this.addEvents(
+            /**
+             * @event check
+             * Fires when the checkbox is checked or unchecked.
+             * @param {Ext.form.Checkbox} this This checkbox
+             * @param {Boolean} checked The new checked value
+             */
+            'check'
+        );
+    },
+
     // private
-    doLayout: function(){
-        if(this.rendered){
-            this.panel.forceLayout = this.ownerCt.forceLayout;
-            this.panel.doLayout();
+    onResize : function(){
+        Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
+        if(!this.boxLabel && !this.fieldLabel){
+            this.el.alignTo(this.wrap, 'c-c');
         }
     },
-    
+
     // private
-    onResize : function(w, h){
-        this.panel.setSize(w, h);
-        this.panel.doLayout();
-    },
-    
-    // inherit docs from Field
-    reset : function(){
-        Ext.form.CheckboxGroup.superclass.reset.call(this);
-        this.eachItem(function(c){
-            if(c.reset){
-                c.reset();
-            }
+    initEvents : function(){
+        Ext.form.Checkbox.superclass.initEvents.call(this);
+        this.mon(this.el, {
+            scope: this,
+            click: this.onClick,
+            change: this.onClick
         });
     },
-    
+
     /**
-     * {@link Ext.form.Checkbox#setValue Set the value(s)} of an item or items
-     * in the group. Examples illustrating how this method may be called:
-     * <pre><code>
-// call with name and value
-myCheckboxGroup.setValue('cb-col-1', true);
-// call with an array of boolean values 
-myCheckboxGroup.setValue([true, false, false]);
-// call with an object literal specifying item:value pairs
-myCheckboxGroup.setValue({
-    'cb-col-2': false,
-    'cb-col-3': true
-});
-// use comma separated string to set items with name to true (checked)
-myCheckboxGroup.setValue('cb-col-1,cb-col-3');
-     * </code></pre>
-     * See {@link Ext.form.Checkbox#setValue} for additional information.
-     * @param {Mixed} id The checkbox to check, or as described by example shown.
-     * @param {Boolean} value (optional) The value to set the item.
-     * @return {Ext.form.CheckboxGroup} this
+     * @hide
+     * Overridden and disabled. The editor element does not support standard valid/invalid marking.
+     * @method
      */
-    setValue : function(id, value){
-        if(this.rendered){
-            if(arguments.length == 1){
-                if(Ext.isArray(id)){
-                    //an array of boolean values
-                    Ext.each(id, function(val, idx){
-                        var item = this.items.itemAt(idx);
-                        if(item){
-                            item.setValue(val);
-                        }
-                    }, this);
-                }else if(Ext.isObject(id)){
-                    //set of name/value pairs
-                    for(var i in id){
-                        var f = this.getBox(i);
-                        if(f){
-                            f.setValue(id[i]);
-                        }
-                    }
-                }else{
-                    this.setValueForItem(id);
-                }
-            }else{
-                var f = this.getBox(id);
-                if(f){
-                    f.setValue(value);
-                }
-            }
+    markInvalid : Ext.emptyFn,
+    /**
+     * @hide
+     * Overridden and disabled. The editor element does not support standard valid/invalid marking.
+     * @method
+     */
+    clearInvalid : Ext.emptyFn,
+
+    // private
+    onRender : function(ct, position){
+        Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
+        if(this.inputValue !== undefined){
+            this.el.dom.value = this.inputValue;
+        }
+        this.wrap = this.el.wrap({cls: 'x-form-check-wrap'});
+        if(this.boxLabel){
+            this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
+        }
+        if(this.checked){
+            this.setValue(true);
         }else{
-            this.values = arguments;
+            this.checked = this.el.dom.checked;
         }
-        return this;
+        // Need to repaint for IE, otherwise positioning is broken
+        if(Ext.isIE){
+            this.wrap.repaint();
+        }
+        this.resizeEl = this.positionEl = this.wrap;
     },
-    
-    // private
-    onDestroy: function(){
-        Ext.destroy(this.panel);
-        Ext.form.CheckboxGroup.superclass.onDestroy.call(this);
 
+    // private
+    onDestroy : function(){
+        Ext.destroy(this.wrap);
+        Ext.form.Checkbox.superclass.onDestroy.call(this);
     },
-    
-    setValueForItem : function(val){
-        val = String(val).split(',');
-        this.eachItem(function(item){
-            if(val.indexOf(item.inputValue)> -1){
-                item.setValue(true);
-            }
-        });
-    },
-    
+
     // private
-    getBox : function(id){
-        var box = null;
-        this.eachItem(function(f){
-            if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){
-                box = f;
-                return false;
-            }
-        });
-        return box;
+    initValue : function() {
+        this.originalValue = this.getValue();
     },
-    
+
     /**
-     * Gets an array of the selected {@link Ext.form.Checkbox} in the group.
-     * @return {Array} An array of the selected checkboxes.
+     * Returns the checked state of the checkbox.
+     * @return {Boolean} True if checked, else false
      */
     getValue : function(){
-        var out = [];
-        this.eachItem(function(item){
-            if(item.checked){
-                out.push(item);
-            }
-        });
-        return out;
+        if(this.rendered){
+            return this.el.dom.checked;
+        }
+        return this.checked;
     },
-    
-    // private
-    eachItem: function(fn){
-        if(this.items && this.items.each){
-            this.items.each(fn, this);
+
+       // private
+    onClick : function(){
+        if(this.el.dom.checked != this.checked){
+            this.setValue(this.el.dom.checked);
         }
     },
-    
-    /**
-     * @cfg {String} name
-     * @hide
-     */
-    /**
-     * @method initValue
-     * @hide
-     */
-    initValue : Ext.emptyFn,
-    /**
-     * @method getValue
-     * @hide
-     */
-    getValue : Ext.emptyFn,
-    /**
-     * @method getRawValue
-     * @hide
-     */
-    getRawValue : Ext.emptyFn,
-    
+
     /**
-     * @method setRawValue
-     * @hide
+     * Sets the checked state of the checkbox, fires the 'check' event, and calls a
+     * <code>{@link #handler}</code> (if configured).
+     * @param {Boolean/String} checked The following values will check the checkbox:
+     * <code>true, 'true', '1', or 'on'</code>. Any other value will uncheck the checkbox.
+     * @return {Ext.form.Field} this
      */
-    setRawValue : Ext.emptyFn
-    
+    setValue : function(v){
+        var checked = this.checked ;
+        this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
+        if(this.rendered){
+            this.el.dom.checked = this.checked;
+            this.el.dom.defaultChecked = this.checked;
+        }
+        if(checked != this.checked){
+            this.fireEvent('check', this, this.checked);
+            if(this.handler){
+                this.handler.call(this.scope || this, this, this.checked);
+            }
+        }
+        return this;
+    }
 });
-
-Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);
+Ext.reg('checkbox', Ext.form.Checkbox);
+/**\r
+ * @class Ext.form.CheckboxGroup\r
+ * @extends Ext.form.Field\r
+ * <p>A grouping container for {@link Ext.form.Checkbox} controls.</p>\r
+ * <p>Sample usage:</p>\r
+ * <pre><code>\r
+var myCheckboxGroup = new Ext.form.CheckboxGroup({\r
+    id:'myGroup',\r
+    xtype: 'checkboxgroup',\r
+    fieldLabel: 'Single Column',\r
+    itemCls: 'x-check-group-alt',\r
+    // Put all controls in a single column with width 100%\r
+    columns: 1,\r
+    items: [\r
+        {boxLabel: 'Item 1', name: 'cb-col-1'},\r
+        {boxLabel: 'Item 2', name: 'cb-col-2', checked: true},\r
+        {boxLabel: 'Item 3', name: 'cb-col-3'}\r
+    ]\r
+});\r
+ * </code></pre>\r
+ * @constructor\r
+ * Creates a new CheckboxGroup\r
+ * @param {Object} config Configuration options\r
+ * @xtype checkboxgroup\r
+ */\r
+Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {\r
+    /**\r
+     * @cfg {Array} items An Array of {@link Ext.form.Checkbox Checkbox}es or Checkbox config objects\r
+     * to arrange in the group.\r
+     */\r
+    /**\r
+     * @cfg {String/Number/Array} columns Specifies the number of columns to use when displaying grouped\r
+     * checkbox/radio controls using automatic layout.  This config can take several types of values:\r
+     * <ul><li><b>'auto'</b> : <p class="sub-desc">The controls will be rendered one per column on one row and the width\r
+     * of each column will be evenly distributed based on the width of the overall field container. This is the default.</p></li>\r
+     * <li><b>Number</b> : <p class="sub-desc">If you specific a number (e.g., 3) that number of columns will be \r
+     * created and the contained controls will be automatically distributed based on the value of {@link #vertical}.</p></li>\r
+     * <li><b>Array</b> : Object<p class="sub-desc">You can also specify an array of column widths, mixing integer\r
+     * (fixed width) and float (percentage width) values as needed (e.g., [100, .25, .75]). Any integer values will\r
+     * be rendered first, then any float values will be calculated as a percentage of the remaining space. Float\r
+     * values do not have to add up to 1 (100%) although if you want the controls to take up the entire field\r
+     * container you should do so.</p></li></ul>\r
+     */\r
+    columns : 'auto',\r
+    /**\r
+     * @cfg {Boolean} vertical True to distribute contained controls across columns, completely filling each column \r
+     * top to bottom before starting on the next column.  The number of controls in each column will be automatically\r
+     * calculated to keep columns as even as possible.  The default value is false, so that controls will be added\r
+     * to columns one at a time, completely filling each row left to right before starting on the next row.\r
+     */\r
+    vertical : false,\r
+    /**\r
+     * @cfg {Boolean} allowBlank False to validate that at least one item in the group is checked (defaults to true).\r
+     * If no items are selected at validation time, {@link @blankText} will be used as the error text.\r
+     */\r
+    allowBlank : true,\r
+    /**\r
+     * @cfg {String} blankText Error text to display if the {@link #allowBlank} validation fails (defaults to "You must \r
+     * select at least one item in this group")\r
+     */\r
+    blankText : "You must select at least one item in this group",\r
+    \r
+    // private\r
+    defaultType : 'checkbox',\r
+    \r
+    // private\r
+    groupCls : 'x-form-check-group',\r
+    \r
+    // private\r
+    initComponent: function(){\r
+        this.addEvents(\r
+            /**\r
+             * @event change\r
+             * Fires when the state of a child checkbox changes.\r
+             * @param {Ext.form.CheckboxGroup} this\r
+             * @param {Array} checked An array containing the checked boxes.\r
+             */\r
+            'change'\r
+        );   \r
+        Ext.form.CheckboxGroup.superclass.initComponent.call(this);\r
+    },\r
+    \r
+    // private\r
+    onRender : function(ct, position){\r
+        if(!this.el){\r
+            var panelCfg = {\r
+                id: this.id,\r
+                cls: this.groupCls,\r
+                layout: 'column',\r
+                border: false,\r
+                renderTo: ct,\r
+                bufferResize: false // Default this to false, since it doesn't really have a proper ownerCt.\r
+            };\r
+            var colCfg = {\r
+                defaultType: this.defaultType,\r
+                layout: 'form',\r
+                border: false,\r
+                defaults: {\r
+                    hideLabel: true,\r
+                    anchor: '100%'\r
+                }\r
+            };\r
+            \r
+            if(this.items[0].items){\r
+                \r
+                // The container has standard ColumnLayout configs, so pass them in directly\r
+                \r
+                Ext.apply(panelCfg, {\r
+                    layoutConfig: {columns: this.items.length},\r
+                    defaults: this.defaults,\r
+                    items: this.items\r
+                });\r
+                for(var i=0, len=this.items.length; i<len; i++){\r
+                    Ext.applyIf(this.items[i], colCfg);\r
+                }\r
+                \r
+            }else{\r
+                \r
+                // The container has field item configs, so we have to generate the column\r
+                // panels first then move the items into the columns as needed.\r
+                \r
+                var numCols, cols = [];\r
+                \r
+                if(typeof this.columns == 'string'){ // 'auto' so create a col per item\r
+                    this.columns = this.items.length;\r
+                }\r
+                if(!Ext.isArray(this.columns)){\r
+                    var cs = [];\r
+                    for(var i=0; i<this.columns; i++){\r
+                        cs.push((100/this.columns)*.01); // distribute by even %\r
+                    }\r
+                    this.columns = cs;\r
+                }\r
+                \r
+                numCols = this.columns.length;\r
+                \r
+                // Generate the column configs with the correct width setting\r
+                for(var i=0; i<numCols; i++){\r
+                    var cc = Ext.apply({items:[]}, colCfg);\r
+                    cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];\r
+                    if(this.defaults){\r
+                        cc.defaults = Ext.apply(cc.defaults || {}, this.defaults)\r
+                    }\r
+                    cols.push(cc);\r
+                };\r
+                \r
+                // Distribute the original items into the columns\r
+                if(this.vertical){\r
+                    var rows = Math.ceil(this.items.length / numCols), ri = 0;\r
+                    for(var i=0, len=this.items.length; i<len; i++){\r
+                        if(i>0 && i%rows==0){\r
+                            ri++;\r
+                        }\r
+                        if(this.items[i].fieldLabel){\r
+                            this.items[i].hideLabel = false;\r
+                        }\r
+                        cols[ri].items.push(this.items[i]);\r
+                    };\r
+                }else{\r
+                    for(var i=0, len=this.items.length; i<len; i++){\r
+                        var ci = i % numCols;\r
+                        if(this.items[i].fieldLabel){\r
+                            this.items[i].hideLabel = false;\r
+                        }\r
+                        cols[ci].items.push(this.items[i]);\r
+                    };\r
+                }\r
+                \r
+                Ext.apply(panelCfg, {\r
+                    layoutConfig: {columns: numCols},\r
+                    items: cols\r
+                });\r
+            }\r
+            \r
+            this.panel = new Ext.Panel(panelCfg);\r
+            this.panel.ownerCt = this;\r
+            this.el = this.panel.getEl();\r
+            \r
+            if(this.forId && this.itemCls){\r
+                var l = this.el.up(this.itemCls).child('label', true);\r
+                if(l){\r
+                    l.setAttribute('htmlFor', this.forId);\r
+                }\r
+            }\r
+            \r
+            var fields = this.panel.findBy(function(c){\r
+                return c.isFormField;\r
+            }, this);\r
+            \r
+            this.items = new Ext.util.MixedCollection();\r
+            this.items.addAll(fields);\r
+        }\r
+        Ext.form.CheckboxGroup.superclass.onRender.call(this, ct, position);\r
+    },\r
+    \r
+    initValue : function(){\r
+        if(this.value){\r
+            this.setValue.apply(this, this.buffered ? this.value : [this.value]);\r
+            delete this.buffered;\r
+            delete this.value;\r
+        }\r
+    },\r
+    \r
+    afterRender : function(){\r
+        Ext.form.CheckboxGroup.superclass.afterRender.call(this);\r
+        this.eachItem(function(item){\r
+            item.on('check', this.fireChecked, this);\r
+            item.inGroup = true;\r
+        });\r
+    },\r
+    \r
+    // private\r
+    doLayout: function(){\r
+        //ugly method required to layout hidden items\r
+        if(this.rendered){\r
+            this.panel.forceLayout = this.ownerCt.forceLayout;\r
+            this.panel.doLayout();\r
+        }\r
+    },\r
+    \r
+    // private\r
+    fireChecked: function(){\r
+        var arr = [];\r
+        this.eachItem(function(item){\r
+            if(item.checked){\r
+                arr.push(item);\r
+            }\r
+        });\r
+        this.fireEvent('change', this, arr);\r
+    },\r
+    \r
+    // private\r
+    validateValue : function(value){\r
+        if(!this.allowBlank){\r
+            var blank = true;\r
+            this.eachItem(function(f){\r
+                if(f.checked){\r
+                    return (blank = false);\r
+                }\r
+            });\r
+            if(blank){\r
+                this.markInvalid(this.blankText);\r
+                return false;\r
+            }\r
+        }\r
+        return true;\r
+    },\r
+    \r
+    // private\r
+    isDirty: function(){\r
+        //override the behaviour to check sub items.\r
+        if (this.disabled || !this.rendered) {\r
+            return false;\r
+        }\r
+\r
+        var dirty = false;\r
+        this.eachItem(function(item){\r
+            if(item.isDirty()){\r
+                dirty = true;\r
+                return false;\r
+            }\r
+        });\r
+        return dirty;\r
+    },\r
+    \r
+    // private\r
+    onDisable : function(){\r
+        this.eachItem(function(item){\r
+            item.disable();\r
+        });\r
+    },\r
+\r
+    // private\r
+    onEnable : function(){\r
+        this.eachItem(function(item){\r
+            item.enable();\r
+        });\r
+    },\r
+    \r
+    // private\r
+    doLayout: function(){\r
+        if(this.rendered){\r
+            this.panel.forceLayout = this.ownerCt.forceLayout;\r
+            this.panel.doLayout();\r
+        }\r
+    },\r
+    \r
+    // private\r
+    onResize : function(w, h){\r
+        this.panel.setSize(w, h);\r
+        this.panel.doLayout();\r
+    },\r
+    \r
+    // inherit docs from Field\r
+    reset : function(){\r
+        Ext.form.CheckboxGroup.superclass.reset.call(this);\r
+        this.eachItem(function(c){\r
+            if(c.reset){\r
+                c.reset();\r
+            }\r
+        });\r
+    },\r
+    \r
+    /**\r
+     * {@link Ext.form.Checkbox#setValue Set the value(s)} of an item or items\r
+     * in the group. Examples illustrating how this method may be called:\r
+     * <pre><code>\r
+// call with name and value\r
+myCheckboxGroup.setValue('cb-col-1', true);\r
+// call with an array of boolean values \r
+myCheckboxGroup.setValue([true, false, false]);\r
+// call with an object literal specifying item:value pairs\r
+myCheckboxGroup.setValue({\r
+    'cb-col-2': false,\r
+    'cb-col-3': true\r
+});\r
+// use comma separated string to set items with name to true (checked)\r
+myCheckboxGroup.setValue('cb-col-1,cb-col-3');\r
+     * </code></pre>\r
+     * See {@link Ext.form.Checkbox#setValue} for additional information.\r
+     * @param {Mixed} id The checkbox to check, or as described by example shown.\r
+     * @param {Boolean} value (optional) The value to set the item.\r
+     * @return {Ext.form.CheckboxGroup} this\r
+     */\r
+    setValue: function(){\r
+        if(this.rendered){\r
+            this.onSetValue.apply(this, arguments);\r
+        }else{\r
+            this.buffered = true;\r
+            this.value = arguments;\r
+        }\r
+        return this;\r
+    },\r
+    \r
+    onSetValue: function(id, value){\r
+        if(arguments.length == 1){\r
+            if(Ext.isArray(id)){\r
+                // an array of boolean values\r
+                Ext.each(id, function(val, idx){\r
+                    var item = this.items.itemAt(idx);\r
+                    if(item){\r
+                        item.setValue(val);\r
+                    }\r
+                }, this);\r
+            }else if(Ext.isObject(id)){\r
+                // set of name/value pairs\r
+                for(var i in id){\r
+                    var f = this.getBox(i);\r
+                    if(f){\r
+                        f.setValue(id[i]);\r
+                    }\r
+                }\r
+            }else{\r
+                this.setValueForItem(id);\r
+            }\r
+        }else{\r
+            var f = this.getBox(id);\r
+            if(f){\r
+                f.setValue(value);\r
+            }\r
+        }\r
+    },\r
+    \r
+    // private\r
+    onDestroy: function(){\r
+        Ext.destroy(this.panel);\r
+        Ext.form.CheckboxGroup.superclass.onDestroy.call(this);\r
+\r
+    },\r
+    \r
+    setValueForItem : function(val){\r
+        val = String(val).split(',');\r
+        this.eachItem(function(item){\r
+            if(val.indexOf(item.inputValue)> -1){\r
+                item.setValue(true);\r
+            }\r
+        });\r
+    },\r
+    \r
+    // private\r
+    getBox : function(id){\r
+        var box = null;\r
+        this.eachItem(function(f){\r
+            if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){\r
+                box = f;\r
+                return false;\r
+            }\r
+        });\r
+        return box;\r
+    },\r
+    \r
+    /**\r
+     * Gets an array of the selected {@link Ext.form.Checkbox} in the group.\r
+     * @return {Array} An array of the selected checkboxes.\r
+     */\r
+    getValue : function(){\r
+        var out = [];\r
+        this.eachItem(function(item){\r
+            if(item.checked){\r
+                out.push(item);\r
+            }\r
+        });\r
+        return out;\r
+    },\r
+    \r
+    // private\r
+    eachItem: function(fn){\r
+        if(this.items && this.items.each){\r
+            this.items.each(fn, this);\r
+        }\r
+    },\r
+    \r
+    /**\r
+     * @cfg {String} name\r
+     * @hide\r
+     */\r
+\r
+    /**\r
+     * @method getRawValue\r
+     * @hide\r
+     */\r
+    getRawValue : Ext.emptyFn,\r
+    \r
+    /**\r
+     * @method setRawValue\r
+     * @hide\r
+     */\r
+    setRawValue : Ext.emptyFn\r
+    \r
+});\r
+\r
+Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);\r
 /**
  * @class Ext.form.Radio
  * @extends Ext.form.Checkbox
@@ -55808,116 +57375,118 @@ Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
     }
 });
 Ext.reg('radio', Ext.form.Radio);
-/**
- * @class Ext.form.RadioGroup
- * @extends Ext.form.CheckboxGroup
- * A grouping container for {@link Ext.form.Radio} controls.
- * @constructor
- * Creates a new RadioGroup
- * @param {Object} config Configuration options
- * @xtype radiogroup
- */
-Ext.form.RadioGroup = Ext.extend(Ext.form.CheckboxGroup, {
-    /**
-     * @cfg {Boolean} allowBlank True to allow every item in the group to be blank (defaults to true).
-     * If allowBlank = false and no items are selected at validation time, {@link @blankText} will
-     * be used as the error text.
-     */
-    allowBlank : true,
-    /**
-     * @cfg {String} blankText Error text to display if the {@link #allowBlank} validation fails
-     * (defaults to 'You must select one item in this group')
-     */
-    blankText : 'You must select one item in this group',
-    
-    // private
-    defaultType : 'radio',
-    
-    // private
-    groupCls : 'x-form-radio-group',
-    
-    /**
-     * @event change
-     * Fires when the state of a child radio changes.
-     * @param {Ext.form.RadioGroup} this
-     * @param {Ext.form.Radio} checked The checked radio
-     */
-    
-    /**
-     * Gets the selected {@link Ext.form.Radio} in the group, if it exists.
-     * @return {Ext.form.Radio} The selected radio.
-     */
-    getValue : function(){
-        var out = null;
-        this.eachItem(function(item){
-            if(item.checked){
-                out = item;
-                return false;
-            }
-        });
-        return out;
-    },
-    
-    /**
-     * Sets the checked radio in the group.
-     * @param {String/Ext.form.Radio} id The radio to check.
-     * @param {Boolean} value The value to set the radio.
-     * @return {Ext.form.RadioGroup} this
-     */
-    setValue : function(id, value){
-        if(this.rendered){
-            if(arguments.length > 1){
-                var f = this.getBox(id);
-                if(f){
-                    f.setValue(value);
-                    if(f.checked){
-                        this.eachItem(function(item){
-                            if (item !== f){
-                                item.setValue(false);
-                            }
-                        });
-                    }
-                }
-            }else{
-                this.setValueForItem(id);
-            }
-        }else{
-            this.values = arguments;
-        }
-        return this;
-    },
-    
-    // private
-    fireChecked : function(){
-        if(!this.checkTask){
-            this.checkTask = new Ext.util.DelayedTask(this.bufferChecked, this);
-        }
-        this.checkTask.delay(10);
-    },
-    
-    // private
-    bufferChecked : function(){
-        var out = null;
-        this.eachItem(function(item){
-            if(item.checked){
-                out = item;
-                return false;
-            }
-        });
-        this.fireEvent('change', this, out);
-    },
-    
-    onDestroy : function(){
-        if(this.checkTask){
-            this.checkTask.cancel();
-            this.checkTask = null;
-        }
-        Ext.form.RadioGroup.superclass.onDestroy.call(this);
-    }
-
-});
-
-Ext.reg('radiogroup', Ext.form.RadioGroup);
+/**\r
+ * @class Ext.form.RadioGroup\r
+ * @extends Ext.form.CheckboxGroup\r
+ * A grouping container for {@link Ext.form.Radio} controls.\r
+ * @constructor\r
+ * Creates a new RadioGroup\r
+ * @param {Object} config Configuration options\r
+ * @xtype radiogroup\r
+ */\r
+Ext.form.RadioGroup = Ext.extend(Ext.form.CheckboxGroup, {\r
+    /**\r
+     * @cfg {Boolean} allowBlank True to allow every item in the group to be blank (defaults to true).\r
+     * If allowBlank = false and no items are selected at validation time, {@link @blankText} will\r
+     * be used as the error text.\r
+     */\r
+    allowBlank : true,\r
+    /**\r
+     * @cfg {String} blankText Error text to display if the {@link #allowBlank} validation fails\r
+     * (defaults to 'You must select one item in this group')\r
+     */\r
+    blankText : 'You must select one item in this group',\r
+    \r
+    // private\r
+    defaultType : 'radio',\r
+    \r
+    // private\r
+    groupCls : 'x-form-radio-group',\r
+    \r
+    /**\r
+     * @event change\r
+     * Fires when the state of a child radio changes.\r
+     * @param {Ext.form.RadioGroup} this\r
+     * @param {Ext.form.Radio} checked The checked radio\r
+     */\r
+    \r
+    /**\r
+     * Gets the selected {@link Ext.form.Radio} in the group, if it exists.\r
+     * @return {Ext.form.Radio} The selected radio.\r
+     */\r
+    getValue : function(){\r
+        var out = null;\r
+        this.eachItem(function(item){\r
+            if(item.checked){\r
+                out = item;\r
+                return false;\r
+            }\r
+        });\r
+        return out;\r
+    },\r
+    \r
+    /**\r
+     * Sets the checked radio in the group.\r
+     * @param {String/Ext.form.Radio} id The radio to check.\r
+     * @param {Boolean} value The value to set the radio.\r
+     * @return {Ext.form.RadioGroup} this\r
+     */\r
+    onSetValue : function(id, value){\r
+        if(arguments.length > 1){\r
+            var f = this.getBox(id);\r
+            if(f){\r
+                f.setValue(value);\r
+                if(f.checked){\r
+                    this.eachItem(function(item){\r
+                        if (item !== f){\r
+                            item.setValue(false);\r
+                        }\r
+                    });\r
+                }\r
+            }\r
+        }else{\r
+            this.setValueForItem(id);\r
+        }\r
+    },\r
+    \r
+    setValueForItem : function(val){\r
+        val = String(val).split(',')[0];\r
+        this.eachItem(function(item){\r
+            item.setValue(val == item.inputValue);\r
+        });\r
+    },\r
+    \r
+    // private\r
+    fireChecked : function(){\r
+        if(!this.checkTask){\r
+            this.checkTask = new Ext.util.DelayedTask(this.bufferChecked, this);\r
+        }\r
+        this.checkTask.delay(10);\r
+    },\r
+    \r
+    // private\r
+    bufferChecked : function(){\r
+        var out = null;\r
+        this.eachItem(function(item){\r
+            if(item.checked){\r
+                out = item;\r
+                return false;\r
+            }\r
+        });\r
+        this.fireEvent('change', this, out);\r
+    },\r
+    \r
+    onDestroy : function(){\r
+        if(this.checkTask){\r
+            this.checkTask.cancel();\r
+            this.checkTask = null;\r
+        }\r
+        Ext.form.RadioGroup.superclass.onDestroy.call(this);\r
+    }\r
+\r
+});\r
+\r
+Ext.reg('radiogroup', Ext.form.RadioGroup);\r
 /**\r
  * @class Ext.form.Hidden\r
  * @extends Ext.form.Field\r
@@ -55985,13 +57554,13 @@ Ext.form.BasicForm = function(el, config){
     if(Ext.isString(this.paramOrder)){
         this.paramOrder = this.paramOrder.split(/[\s,|]/);
     }
-    /*
+    /**
      * @property items
      * A {@link Ext.util.MixedCollection MixedCollection) containing all the Ext.form.Fields in this form.
      * @type MixedCollection
      */
     this.items = new Ext.util.MixedCollection(false, function(o){
-        return o.itemId || o.id || (o.id = Ext.id());
+        return o.getItemId();
     });
     this.addEvents(
         /**
@@ -56130,6 +57699,11 @@ paramOrder: 'param1|param2|param'
      */
     paramsAsHash: false,
 
+    /**
+     * @cfg {String} waitTitle
+     * The default title to show for the waiting message box (defaults to <tt>'Please Wait...'</tt>)
+     */
+    waitTitle: 'Please Wait...',
 
     // private
     activeAction : null,
@@ -56141,23 +57715,21 @@ paramOrder: 'param1|param2|param'
     trackResetOnLoad : false,
 
     /**
-     * @cfg {Boolean} standardSubmit If set to true, standard HTML form submits are used instead of XHR (Ajax) style
-     * form submissions. (defaults to false)<br>
-     * <p><b>Note:</b> When using standardSubmit, the options to {@link #submit} are ignored because Ext's
-     * Ajax infrastracture is bypassed. To pass extra parameters (baseParams and params), you will need to
-     * create hidden fields within the form.</p>
-     * <p>The url config option is also bypassed, so set the action as well:</p>
-     * <pre><code>
-PANEL.getForm().getEl().dom.action = 'URL'
-     * </code></pre>
-     * An example encapsulating the above:
+     * @cfg {Boolean} standardSubmit
+     * <p>If set to <tt>true</tt>, standard HTML form submits are used instead
+     * of XHR (Ajax) style form submissions. Defaults to <tt>false</tt>.</p>
+     * <br><p><b>Note:</b> When using <code>standardSubmit</code>, the
+     * <code>options</code> to <code>{@link #submit}</code> are ignored because
+     * Ext's Ajax infrastracture is bypassed. To pass extra parameters (e.g.
+     * <code>baseParams</code> and <code>params</code>), utilize hidden fields
+     * to submit extra data, for example:</p>
      * <pre><code>
 new Ext.FormPanel({
     standardSubmit: true,
     baseParams: {
         foo: 'bar'
     },
-    url: 'myProcess.php',
+    {@link url}: 'myProcess.php',
     items: [{
         xtype: 'textfield',
         name: 'userName'
@@ -56165,21 +57737,25 @@ new Ext.FormPanel({
     buttons: [{
         text: 'Save',
         handler: function(){
-            var O = this.ownerCt;
-            if (O.getForm().isValid()) {
-                if (O.url)
-                    O.getForm().getEl().dom.action = O.url;
-                if (O.baseParams) {
-                    for (i in O.baseParams) {
-                        O.add({
+            var fp = this.ownerCt.ownerCt,
+                form = fp.getForm();
+            if (form.isValid()) {
+                // check if there are baseParams and if
+                // hiddent items have been added already
+                if (fp.baseParams && !fp.paramsAdded) {
+                    // add hidden items for all baseParams
+                    for (i in fp.baseParams) {
+                        fp.add({
                             xtype: 'hidden',
                             name: i,
-                            value: O.baseParams[i]
-                        })
+                            value: fp.baseParams[i]
+                        });
                     }
-                    O.doLayout();
+                    fp.doLayout();
+                    // set a custom flag to prevent re-adding
+                    fp.paramsAdded = true;
                 }
-                O.getForm().submit();
+                form.{@link #submit}();
             }
         }
     }]
@@ -56376,7 +57952,11 @@ myFormPanel.getForm().submit({
         if(this.standardSubmit){
             var v = this.isValid();
             if(v){
-                this.el.dom.submit();
+                var el = this.el.dom;
+                if(this.url && Ext.isEmpty(el.action)){
+                    el.action = this.url;
+                }
+                el.submit();
             }
             return v;
         }
@@ -56436,7 +58016,7 @@ myFormPanel.getForm().submit({
                 this.waitMsgTarget = Ext.get(this.waitMsgTarget);
                 this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
             }else{
-                Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle || 'Please Wait...');
+                Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle);
             }
         }
     },
@@ -56831,19 +58411,8 @@ Ext.FormPanel = Ext.extend(Ext.Panel, {
         var fn = function(c){
             if(formPanel.isField(c)){
                 f.add(c);
-            }if(c.isFieldWrap){
-                Ext.applyIf(c, {
-                    labelAlign: c.ownerCt.labelAlign,
-                    labelWidth: c.ownerCt.labelWidth,
-                    itemCls: c.ownerCt.itemCls
-                });
-                f.add(c.field);
-            }else if(c.doLayout && c != formPanel){
-                Ext.applyIf(c, {
-                    labelAlign: c.ownerCt.labelAlign,
-                    labelWidth: c.ownerCt.labelWidth,
-                    itemCls: c.ownerCt.itemCls
-                });
+            }else if(c.findBy && c != formPanel){
+                formPanel.applySettings(c);
                 //each check required for check/radio groups.
                 if(c.items && c.items.each){
                     c.items.each(fn, this);
@@ -56852,6 +58421,16 @@ Ext.FormPanel = Ext.extend(Ext.Panel, {
         };
         this.items.each(fn, this);
     },
+    
+    // private
+    applySettings: function(c){
+        var ct = c.ownerCt;
+        Ext.applyIf(c, {
+            labelAlign: ct.labelAlign,
+            labelWidth: ct.labelWidth,
+            itemCls: ct.itemCls
+        });
+    },
 
     // private
     getLayoutTarget : function(){
@@ -56894,37 +58473,61 @@ Ext.FormPanel = Ext.extend(Ext.Panel, {
     // private
     initEvents : function(){
         Ext.FormPanel.superclass.initEvents.call(this);
-        this.on('remove', this.onRemove, this);
-        this.on('add', this.onAdd, this);
+        // Listeners are required here to catch bubbling events from children.
+        this.on({
+            scope: this,
+            add: this.onAddEvent,
+            remove: this.onRemoveEvent
+        });
         if(this.monitorValid){ // initialize after render
             this.startMonitoring();
         }
     },
     
     // private
-    onAdd : function(ct, c) {
+    onAdd: function(c){
+        Ext.FormPanel.superclass.onAdd.call(this, c);  
+        this.processAdd(c);
+    },
+    
+    // private
+    onAddEvent: function(ct, c){
+        if(ct !== this){
+            this.processAdd(c);
+        }
+    },
+    
+    // private
+    processAdd : function(c){
                // If a single form Field, add it
-        if (this.isField(c)) {
+        if(this.isField(c)){
             this.form.add(c);
                // If a Container, add any Fields it might contain
-        } else if (c.findBy) {
-            Ext.applyIf(c, {
-                labelAlign: c.ownerCt.labelAlign,
-                labelWidth: c.ownerCt.labelWidth,
-                itemCls: c.ownerCt.itemCls
-            });
+        }else if(c.findBy){
+            this.applySettings(c);
             this.form.add.apply(this.form, c.findBy(this.isField));
         }
     },
+    
+    // private
+    onRemove: function(c){
+        Ext.FormPanel.superclass.onRemove.call(this, c);
+        this.processRemove(c);
+    },
+    
+    onRemoveEvent: function(ct, c){
+        if(ct !== this){
+            this.processRemove(c);
+        }
+    },
        
     // private
-    onRemove : function(ct, c) {
+    processRemove : function(c){
                // If a single form Field, remove it
-        if (this.isField(c)) {
-            Ext.destroy(c.container.up('.x-form-item'));
+        if(this.isField(c)){
                this.form.remove(c);
                // If a Container, remove any Fields it might contain
-        } else if (c.findByType) {
+        }else if(c.findBy){
             Ext.each(c.findBy(this.isField), this.form.remove, this.form);
         }
     },
@@ -57240,14 +58843,6 @@ Ext.form.FieldSet = Ext.extend(Ext.Panel, {
      * @cfg {Object/Array} tbar\r
      * @hide\r
      */\r
-    /**\r
-     * @cfg {String} tabTip\r
-     * @hide\r
-     */\r
-    /**\r
-     * @cfg {Boolean} titleCollapse\r
-     * @hide\r
-     */\r
     /**\r
      * @cfg {Array} tools\r
      * @hide\r
@@ -57404,7 +58999,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
     /**\r
      * @cfg {String} defaultValue A default value to be put into the editor to resolve focus issues (defaults to &#8203; (Zero-width space), &nbsp; (Non-breaking space) in Opera and IE6).\r
      */\r
-    defaultValue: (Ext.isOpera || Ext.isIE6) ? '&nbsp;' : '&#8203;',\r
+    defaultValue: (Ext.isOpera || Ext.isIE6) ? '&#160;' : '&#8203;',\r
 \r
     // private properties\r
     actionMode: 'wrap',\r
@@ -57704,13 +59299,14 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
             var sz = this.el.getSize();\r
             this.setSize(sz.width, this.height || sz.height);\r
         }\r
+        this.resizeEl = this.positionEl = this.wrap;\r
     },\r
 \r
     createIFrame: function(){\r
         var iframe = document.createElement('iframe');\r
         iframe.name = Ext.id();\r
         iframe.frameBorder = '0';\r
-        iframe.src = Ext.isIE ? Ext.SSL_SECURE_URL : "javascript:;";\r
+        iframe.src = Ext.SSL_SECURE_URL;\r
         this.wrap.dom.appendChild(iframe);\r
 \r
         this.iframe = iframe;\r
@@ -57764,7 +59360,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
             this.fontSelect.dom.disabled = disabled;\r
         }\r
         this.tb.items.each(function(item){\r
-            if(item.itemId != 'sourceedit'){\r
+            if(item.getItemId() != 'sourceedit'){\r
                 item.setDisabled(disabled);\r
             }\r
         });\r
@@ -57774,15 +59370,15 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
     onResize : function(w, h){\r
         Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);\r
         if(this.el && this.iframe){\r
-            if(typeof w == 'number'){\r
+            if(Ext.isNumber(w)){\r
                 var aw = w - this.wrap.getFrameWidth('lr');\r
-                this.el.setWidth(this.adjustWidth('textarea', aw));\r
+                this.el.setWidth(aw);\r
                 this.tb.setWidth(aw);\r
                 this.iframe.style.width = Math.max(aw, 0) + 'px';\r
             }\r
-            if(typeof h == 'number'){\r
+            if(Ext.isNumber(h)){\r
                 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();\r
-                this.el.setHeight(this.adjustWidth('textarea', ah));\r
+                this.el.setHeight(ah);\r
                 this.iframe.style.height = Math.max(ah, 0) + 'px';\r
                 if(this.doc){\r
                     this.getEditorBody().style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';\r
@@ -57840,19 +59436,6 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
         }\r
     },\r
 \r
-    // private (for BoxComponent)\r
-    adjustSize : Ext.BoxComponent.prototype.adjustSize,\r
-\r
-    // private (for BoxComponent)\r
-    getResizeEl : function(){\r
-        return this.wrap;\r
-    },\r
-\r
-    // private (for BoxComponent)\r
-    getPositionEl : function(){\r
-        return this.wrap;\r
-    },\r
-\r
     // private\r
     initEvents : function(){\r
         this.originalValue = this.getValue();\r
@@ -57883,15 +59466,19 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
      * @param {String} html The HTML to be cleaned\r
      * @return {String} The cleaned HTML\r
      */\r
-    cleanHtml : function(html){\r
+    cleanHtml: function(html) {\r
         html = String(html);\r
-        if(html.length > 5){\r
-            if(Ext.isWebKit){ // strip safari nonsense\r
-                html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');\r
-            }\r
+        if(Ext.isWebKit){ // strip safari nonsense\r
+            html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');\r
         }\r
-        if(html == this.defaultValue){\r
-            html = '';\r
+        \r
+        /*\r
+         * Neat little hack. Strips out all the non-digit characters from the default\r
+         * value and compares it to the character code of the first character in the string\r
+         * because it can cause encoding issues when posted to the server.\r
+         */\r
+        if(html.charCodeAt(0) == this.defaultValue.replace(/\D/g, '')){\r
+            html = html.substring(1);\r
         }\r
         return html;\r
     },\r
@@ -58056,7 +59643,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
 \r
     // private\r
     adjustFont: function(btn){\r
-        var adjust = btn.itemId == 'increasefontsize' ? 1 : -1;\r
+        var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1;\r
 \r
         var v = parseInt(this.doc.queryCommandValue('FontSize') || 2, 10);\r
         if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){\r
@@ -58132,7 +59719,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
 \r
     // private\r
     relayBtnCmd : function(btn){\r
-        this.relayCmd(btn.itemId);\r
+        this.relayCmd(btn.getItemId());\r
     },\r
 \r
     /**\r
@@ -58206,13 +59793,10 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
                 this.syncValue();\r
                 this.deferFocus();\r
             }\r
-        }else if(Ext.isGecko || Ext.isOpera){\r
+        }else{\r
             this.win.focus();\r
             this.execCmd('InsertHTML', text);\r
             this.deferFocus();\r
-        }else if(Ext.isWebKit){\r
-            this.execCmd('InsertText', text);\r
-            this.deferFocus();\r
         }\r
     },\r
 \r
@@ -58259,6 +59843,10 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
                     e.stopEvent();\r
                     this.execCmd('InsertText','\t');\r
                     this.deferFocus();\r
+                }else if(k == e.ENTER){\r
+                    e.stopEvent();\r
+                    this.execCmd('InsertHtml','<br /><br />');\r
+                    this.deferFocus();\r
                 }\r
              };\r
         }\r
@@ -58616,684 +60204,809 @@ Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
      * @hide\r
      * @method autoSize\r
      */\r
-});\r
-Ext.reg('timefield', Ext.form.TimeField);/**
- * @class Ext.form.Label
- * @extends Ext.BoxComponent
- * Basic Label field.
- * @constructor
- * Creates a new Label
- * @param {Ext.Element/String/Object} config The configuration options.  If an element is passed, it is set as the internal
- * element and its id used as the component id.  If a string is passed, it is assumed to be the id of an existing element
- * and is used as the component id.  Otherwise, it is assumed to be a standard config object and is applied to the component.
- * @xtype label
- */
-Ext.form.Label = Ext.extend(Ext.BoxComponent, {
-    /**
-     * @cfg {String} text The plain text to display within the label (defaults to ''). If you need to include HTML
-     * tags within the label's innerHTML, use the {@link #html} config instead.
-     */
-    /**
-     * @cfg {String} forId The id of the input element to which this label will be bound via the standard HTML 'for'
-     * attribute. If not specified, the attribute will not be added to the label.
-     */
-    /**
-     * @cfg {String} html An HTML fragment that will be used as the label's innerHTML (defaults to '').
-     * Note that if {@link #text} is specified it will take precedence and this value will be ignored.
-     */
-
-    // private
-    onRender : function(ct, position){
-        if(!this.el){
-            this.el = document.createElement('label');
-            this.el.id = this.getId();
-            this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
-            if(this.forId){
-                this.el.setAttribute('for', this.forId);
-            }
-        }
-        Ext.form.Label.superclass.onRender.call(this, ct, position);
-    },
-
-    /**
-     * Updates the label's innerHTML with the specified string.
-     * @param {String} text The new label text
-     * @param {Boolean} encode (optional) False to skip HTML-encoding the text when rendering it
-     * to the label (defaults to true which encodes the value). This might be useful if you want to include
-     * tags in the label's innerHTML rather than rendering them as string literals per the default logic.
-     * @return {Label} this
-     */
-    setText : function(t, encode){
-        var e = encode === false;
-        this[!e ? 'text' : 'html'] = t;
-        delete this[e ? 'text' : 'html'];
-        if(this.rendered){
-            this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t;
-        }
-        return this;
-    }
-});
-
-Ext.reg('label', Ext.form.Label);/**
- * @class Ext.form.Action
- * <p>The subclasses of this class provide actions to perform upon {@link Ext.form.BasicForm Form}s.</p>
- * <p>Instances of this class are only created by a {@link Ext.form.BasicForm Form} when
- * the Form needs to perform an action such as submit or load. The Configuration options
- * listed for this class are set through the Form's action methods: {@link Ext.form.BasicForm#submit submit},
- * {@link Ext.form.BasicForm#load load} and {@link Ext.form.BasicForm#doAction doAction}</p>
- * <p>The instance of Action which performed the action is passed to the success
- * and failure callbacks of the Form's action methods ({@link Ext.form.BasicForm#submit submit},
- * {@link Ext.form.BasicForm#load load} and {@link Ext.form.BasicForm#doAction doAction}),
- * and to the {@link Ext.form.BasicForm#actioncomplete actioncomplete} and
- * {@link Ext.form.BasicForm#actionfailed actionfailed} event handlers.</p>
- */
-Ext.form.Action = function(form, options){
-    this.form = form;
-    this.options = options || {};
-};
-
-/**
- * Failure type returned when client side validation of the Form fails
- * thus aborting a submit action. Client side validation is performed unless
- * {@link #clientValidation} is explicitly set to <tt>false</tt>.
- * @type {String}
- * @static
- */
-Ext.form.Action.CLIENT_INVALID = 'client';
-/**
- * <p>Failure type returned when server side processing fails and the {@link #result}'s
- * <tt style="font-weight:bold">success</tt> property is set to <tt>false</tt>.</p>
- * <p>In the case of a form submission, field-specific error messages may be returned in the
- * {@link #result}'s <tt style="font-weight:bold">errors</tt> property.</p>
- * @type {String}
- * @static
- */
-Ext.form.Action.SERVER_INVALID = 'server';
-/**
- * Failure type returned when a communication error happens when attempting
- * to send a request to the remote server. The {@link #response} may be examined to
- * provide further information.
- * @type {String}
- * @static
- */
-Ext.form.Action.CONNECT_FAILURE = 'connect';
-/**
- * Failure type returned when the response's <tt style="font-weight:bold">success</tt>
- * property is set to <tt>false</tt>, or no field values are returned in the response's
- * <tt style="font-weight:bold">data</tt> property.
- * @type {String}
- * @static
- */
-Ext.form.Action.LOAD_FAILURE = 'load';
-
-Ext.form.Action.prototype = {
-/**
- * @cfg {String} url The URL that the Action is to invoke.
- */
-/**
- * @cfg {Boolean} reset When set to <tt><b>true</b></tt>, causes the Form to be
- * {@link Ext.form.BasicForm.reset reset} on Action success. If specified, this happens
- * <b>before</b> the {@link #success} callback is called and before the Form's
- * {@link Ext.form.BasicForm.actioncomplete actioncomplete} event fires.
- */
-/**
- * @cfg {String} method The HTTP method to use to access the requested URL. Defaults to the
- * {@link Ext.form.BasicForm}'s method, or if that is not specified, the underlying DOM form's method.
- */
-/**
- * @cfg {Mixed} params <p>Extra parameter values to pass. These are added to the Form's
- * {@link Ext.form.BasicForm#baseParams} and passed to the specified URL along with the Form's
- * input fields.</p>
- * <p>Parameters are encoded as standard HTTP parameters using {@link Ext#urlEncode}.</p>
- */
-/**
- * @cfg {Number} timeout The number of seconds to wait for a server response before
- * failing with the {@link #failureType} as {@link #Action.CONNECT_FAILURE}. If not specified,
- * defaults to the configured <tt>{@link Ext.form.BasicForm#timeout timeout}</tt> of the
- * {@link Ext.form.BasicForm form}.
- */
-/**
- * @cfg {Function} success The function to call when a valid success return packet is recieved.
- * The function is passed the following parameters:<ul class="mdetail-params">
- * <li><b>form</b> : Ext.form.BasicForm<div class="sub-desc">The form that requested the action</div></li>
- * <li><b>action</b> : Ext.form.Action<div class="sub-desc">The Action class. The {@link #result}
- * property of this object may be examined to perform custom postprocessing.</div></li>
- * </ul>
- */
-/**
- * @cfg {Function} failure The function to call when a failure packet was recieved, or when an
- * error ocurred in the Ajax communication.
- * The function is passed the following parameters:<ul class="mdetail-params">
- * <li><b>form</b> : Ext.form.BasicForm<div class="sub-desc">The form that requested the action</div></li>
- * <li><b>action</b> : Ext.form.Action<div class="sub-desc">The Action class. If an Ajax
- * error ocurred, the failure type will be in {@link #failureType}. The {@link #result}
- * property of this object may be examined to perform custom postprocessing.</div></li>
- * </ul>
- */
-/**
- * @cfg {Object} scope The scope in which to call the callback functions (The <tt>this</tt> reference
- * for the callback functions).
- */
-/**
- * @cfg {String} waitMsg The message to be displayed by a call to {@link Ext.MessageBox#wait}
- * during the time the action is being processed.
- */
-/**
- * @cfg {String} waitTitle The title to be displayed by a call to {@link Ext.MessageBox#wait}
- * during the time the action is being processed.
- */
-
-/**
- * The type of action this Action instance performs.
- * Currently only "submit" and "load" are supported.
- * @type {String}
- */
-    type : 'default',
-/**
- * The type of failure detected will be one of these: {@link #CLIENT_INVALID},
- * {@link #SERVER_INVALID}, {@link #CONNECT_FAILURE}, or {@link #LOAD_FAILURE}.  Usage:
- * <pre><code>
-var fp = new Ext.form.FormPanel({
-...
-buttons: [{
-    text: 'Save',
-    formBind: true,
-    handler: function(){
-        if(fp.getForm().isValid()){
-            fp.getForm().submit({
-                url: 'form-submit.php',
-                waitMsg: 'Submitting your data...',
-                success: function(form, action){
-                    // server responded with success = true
-                    var result = action.{@link #result};
-                },
-                failure: function(form, action){
-                    if (action.{@link #failureType} === Ext.form.Action.{@link #CONNECT_FAILURE}) {
-                        Ext.Msg.alert('Error',
-                            'Status:'+action.{@link #response}.status+': '+
-                            action.{@link #response}.statusText);
-                    }
-                    if (action.failureType === Ext.form.Action.{@link #SERVER_INVALID}){
-                        // server responded with success = false
-                        Ext.Msg.alert('Invalid', action.{@link #result}.errormsg);
-                    }
-                }
-            });
-        }
-    }
-},{
-    text: 'Reset',
-    handler: function(){
-        fp.getForm().reset();
-    }
-}]
- * </code></pre>
- * @property failureType
- * @type {String}
- */
- /**
- * The XMLHttpRequest object used to perform the action.
- * @property response
- * @type {Object}
- */
- /**
- * The decoded response object containing a boolean <tt style="font-weight:bold">success</tt> property and
- * other, action-specific properties.
- * @property result
- * @type {Object}
- */
-
-    // interface method
-    run : function(options){
-
-    },
-
-    // interface method
-    success : function(response){
-
-    },
-
-    // interface method
-    handleResponse : function(response){
-
-    },
-
-    // default connection failure
-    failure : function(response){
-        this.response = response;
-        this.failureType = Ext.form.Action.CONNECT_FAILURE;
-        this.form.afterAction(this, false);
-    },
-
-    // private
-    // shared code among all Actions to validate that there was a response
-    // with either responseText or responseXml
-    processResponse : function(response){
-        this.response = response;
-        if(!response.responseText && !response.responseXML){
-            return true;
-        }
-        this.result = this.handleResponse(response);
-        return this.result;
-    },
-
-    // utility functions used internally
-    getUrl : function(appendParams){
-        var url = this.options.url || this.form.url || this.form.el.dom.action;
-        if(appendParams){
-            var p = this.getParams();
-            if(p){
-                url = Ext.urlAppend(url, p);
-            }
-        }
-        return url;
-    },
-
-    // private
-    getMethod : function(){
-        return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
-    },
-
-    // private
-    getParams : function(){
-        var bp = this.form.baseParams;
-        var p = this.options.params;
-        if(p){
-            if(typeof p == "object"){
-                p = Ext.urlEncode(Ext.applyIf(p, bp));
-            }else if(typeof p == 'string' && bp){
-                p += '&' + Ext.urlEncode(bp);
-            }
-        }else if(bp){
-            p = Ext.urlEncode(bp);
-        }
-        return p;
-    },
-
-    // private
-    createCallback : function(opts){
-        var opts = opts || {};
-        return {
-            success: this.success,
-            failure: this.failure,
-            scope: this,
-            timeout: (opts.timeout*1000) || (this.form.timeout*1000),
-            upload: this.form.fileUpload ? this.success : undefined
-        };
-    }
-};
-
-/**
- * @class Ext.form.Action.Submit
- * @extends Ext.form.Action
- * <p>A class which handles submission of data from {@link Ext.form.BasicForm Form}s
- * and processes the returned response.</p>
- * <p>Instances of this class are only created by a {@link Ext.form.BasicForm Form} when
- * {@link Ext.form.BasicForm#submit submit}ting.</p>
- * <p><u><b>Response Packet Criteria</b></u></p>
- * <p>A response packet may contain:
- * <div class="mdetail-params"><ul>
- * <li><b><code>success</code></b> property : Boolean
- * <div class="sub-desc">The <code>success</code> property is required.</div></li>
- * <li><b><code>errors</code></b> property : Object
- * <div class="sub-desc"><div class="sub-desc">The <code>errors</code> property,
- * which is optional, contains error messages for invalid fields.</div></li>
- * </ul></div>
- * <p><u><b>JSON Packets</b></u></p>
- * <p>By default, response packets are assumed to be JSON, so a typical response
- * packet may look like this:</p><pre><code>
-{
-    success: false,
-    errors: {
-        clientCode: "Client not found",
-        portOfLoading: "This field must not be null"
-    }
-}</code></pre>
- * <p>Other data may be placed into the response for processing by the {@link Ext.form.BasicForm}'s callback
- * or event handler methods. The object decoded from this JSON is available in the
- * {@link Ext.form.Action#result result} property.</p>
- * <p>Alternatively, if an {@link #errorReader} is specified as an {@link Ext.data.XmlReader XmlReader}:</p><pre><code>
-    errorReader: new Ext.data.XmlReader({
-            record : 'field',
-            success: '@success'
-        }, [
-            'id', 'msg'
-        ]
-    )
-</code></pre>
- * <p>then the results may be sent back in XML format:</p><pre><code>
-&lt;?xml version="1.0" encoding="UTF-8"?&gt;
-&lt;message success="false"&gt;
-&lt;errors&gt;
-    &lt;field&gt;
-        &lt;id&gt;clientCode&lt;/id&gt;
-        &lt;msg&gt;&lt;![CDATA[Code not found. &lt;br /&gt;&lt;i&gt;This is a test validation message from the server &lt;/i&gt;]]&gt;&lt;/msg&gt;
-    &lt;/field&gt;
-    &lt;field&gt;
-        &lt;id&gt;portOfLoading&lt;/id&gt;
-        &lt;msg&gt;&lt;![CDATA[Port not found. &lt;br /&gt;&lt;i&gt;This is a test validation message from the server &lt;/i&gt;]]&gt;&lt;/msg&gt;
-    &lt;/field&gt;
-&lt;/errors&gt;
-&lt;/message&gt;
-</code></pre>
- * <p>Other elements may be placed into the response XML for processing by the {@link Ext.form.BasicForm}'s callback
- * or event handler methods. The XML document is available in the {@link #errorReader}'s {@link Ext.data.XmlReader#xmlData xmlData} property.</p>
- */
-Ext.form.Action.Submit = function(form, options){
-    Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
-};
-
-Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
-    /**
-     * @cfg {Ext.data.DataReader} errorReader <p><b>Optional. JSON is interpreted with
-     * no need for an errorReader.</b></p>
-     * <p>A Reader which reads a single record from the returned data. The DataReader's
-     * <b>success</b> property specifies how submission success is determined. The Record's
-     * data provides the error messages to apply to any invalid form Fields.</p>
-     */
-    /**
-     * @cfg {boolean} clientValidation Determines whether a Form's fields are validated
-     * in a final call to {@link Ext.form.BasicForm#isValid isValid} prior to submission.
-     * Pass <tt>false</tt> in the Form's submit options to prevent this. If not defined, pre-submission field validation
-     * is performed.
-     */
-    type : 'submit',
-
-    // private
-    run : function(){
-        var o = this.options;
-        var method = this.getMethod();
-        var isGet = method == 'GET';
-        if(o.clientValidation === false || this.form.isValid()){
-            Ext.Ajax.request(Ext.apply(this.createCallback(o), {
-                form:this.form.el.dom,
-                url:this.getUrl(isGet),
-                method: method,
-                headers: o.headers,
-                params:!isGet ? this.getParams() : null,
-                isUpload: this.form.fileUpload
-            }));
-        }else if (o.clientValidation !== false){ // client validation failed
-            this.failureType = Ext.form.Action.CLIENT_INVALID;
-            this.form.afterAction(this, false);
-        }
-    },
-
-    // private
-    success : function(response){
-        var result = this.processResponse(response);
-        if(result === true || result.success){
-            this.form.afterAction(this, true);
-            return;
-        }
-        if(result.errors){
-            this.form.markInvalid(result.errors);
-            this.failureType = Ext.form.Action.SERVER_INVALID;
-        }
-        this.form.afterAction(this, false);
-    },
-
-    // private
-    handleResponse : function(response){
-        if(this.form.errorReader){
-            var rs = this.form.errorReader.read(response);
-            var errors = [];
-            if(rs.records){
-                for(var i = 0, len = rs.records.length; i < len; i++) {
-                    var r = rs.records[i];
-                    errors[i] = r.data;
-                }
-            }
-            if(errors.length < 1){
-                errors = null;
-            }
-            return {
-                success : rs.success,
-                errors : errors
-            };
-        }
-        return Ext.decode(response.responseText);
-    }
-});
-
-
-/**
- * @class Ext.form.Action.Load
- * @extends Ext.form.Action
- * <p>A class which handles loading of data from a server into the Fields of an {@link Ext.form.BasicForm}.</p>
- * <p>Instances of this class are only created by a {@link Ext.form.BasicForm Form} when
- * {@link Ext.form.BasicForm#load load}ing.</p>
- * <p><u><b>Response Packet Criteria</b></u></p>
- * <p>A response packet <b>must</b> contain:
- * <div class="mdetail-params"><ul>
- * <li><b><code>success</code></b> property : Boolean</li>
- * <li><b><code>data</code></b> property : Object</li>
- * <div class="sub-desc">The <code>data</code> property contains the values of Fields to load.
- * The individual value object for each Field is passed to the Field's
- * {@link Ext.form.Field#setValue setValue} method.</div></li>
- * </ul></div>
- * <p><u><b>JSON Packets</b></u></p>
- * <p>By default, response packets are assumed to be JSON, so for the following form load call:<pre><code>
-var myFormPanel = new Ext.form.FormPanel({
-    title: 'Client and routing info',
-    items: [{
-        fieldLabel: 'Client',
-        name: 'clientName'
-    }, {
-        fieldLabel: 'Port of loading',
-        name: 'portOfLoading'
-    }, {
-        fieldLabel: 'Port of discharge',
-        name: 'portOfDischarge'
-    }]
-});
-myFormPanel.{@link Ext.form.FormPanel#getForm getForm}().{@link Ext.form.BasicForm#load load}({
-    url: '/getRoutingInfo.php',
-    params: {
-        consignmentRef: myConsignmentRef
-    },
-    failure: function(form, action() {
-        Ext.Msg.alert("Load failed", action.result.errorMessage);
-    }
-});
-</code></pre>
- * a <b>success response</b> packet may look like this:</p><pre><code>
-{
-    success: true,
-    data: {
-        clientName: "Fred. Olsen Lines",
-        portOfLoading: "FXT",
-        portOfDischarge: "OSL"
-    }
-}</code></pre>
- * while a <b>failure response</b> packet may look like this:</p><pre><code>
-{
-    success: false,
-    errorMessage: "Consignment reference not found"
-}</code></pre>
- * <p>Other data may be placed into the response for processing the {@link Ext.form.BasicForm Form}'s
- * callback or event handler methods. The object decoded from this JSON is available in the
- * {@link Ext.form.Action#result result} property.</p>
- */
-Ext.form.Action.Load = function(form, options){
-    Ext.form.Action.Load.superclass.constructor.call(this, form, options);
-    this.reader = this.form.reader;
-};
-
-Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
-    // private
-    type : 'load',
-
-    // private
-    run : function(){
-        Ext.Ajax.request(Ext.apply(
-                this.createCallback(this.options), {
-                    method:this.getMethod(),
-                    url:this.getUrl(false),
-                    headers: this.options.headers,
-                    params:this.getParams()
-        }));
-    },
-
-    // private
-    success : function(response){
-        var result = this.processResponse(response);
-        if(result === true || !result.success || !result.data){
-            this.failureType = Ext.form.Action.LOAD_FAILURE;
-            this.form.afterAction(this, false);
-            return;
-        }
-        this.form.clearInvalid();
-        this.form.setValues(result.data);
-        this.form.afterAction(this, true);
-    },
-
-    // private
-    handleResponse : function(response){
-        if(this.form.reader){
-            var rs = this.form.reader.read(response);
-            var data = rs.records && rs.records[0] ? rs.records[0].data : null;
-            return {
-                success : rs.success,
-                data : data
-            };
-        }
-        return Ext.decode(response.responseText);
-    }
-});
-
-
-
-/**
- * @class Ext.form.Action.DirectLoad
- * @extends Ext.form.Action.Load
- * Provides Ext.direct support for loading form data. This example illustrates usage
- * of Ext.Direct to load a submit a form through Ext.Direct.
- * <pre><code>
-var myFormPanel = new Ext.form.FormPanel({
-    // configs for FormPanel
-    title: 'Basic Information',
-    border: false,
-    padding: 10,
-    buttons:[{
-        text: 'Submit',
-        handler: function(){
-            basicInfo.getForm().submit({
-                params: {
-                    uid: 5
-                }
-            });
-        }
-    }],
-    
-    // configs apply to child items
-    defaults: {anchor: '100%'},
-    defaultType: 'textfield',
-    items: [
-        // form fields go here
-    ],
-    
-    // configs for BasicForm
-    api: {
-        load: Profile.getBasicInfo,
-        // The server-side must mark the submit handler as a 'formHandler'
-        submit: Profile.updateBasicInfo
-    },    
-    paramOrder: ['uid']
-});
-
-// load the form
-myFormPanel.getForm().load({
-    params: {
-        uid: 5
-    }
-});
- * </code></pre>
+});\r
+Ext.reg('timefield', Ext.form.TimeField);/**
+ * @class Ext.form.Label
+ * @extends Ext.BoxComponent
+ * Basic Label field.
+ * @constructor
+ * Creates a new Label
+ * @param {Ext.Element/String/Object} config The configuration options.  If an element is passed, it is set as the internal
+ * element and its id used as the component id.  If a string is passed, it is assumed to be the id of an existing element
+ * and is used as the component id.  Otherwise, it is assumed to be a standard config object and is applied to the component.
+ * @xtype label
  */
-Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, {
-    constructor: function(form, opts) {        
-        Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts);
-    },
-    type: 'directload',
-    
-    run : function(){
-        var args = this.getParams();
-        args.push(this.success, this);                
-        this.form.api.load.apply(window, args);
-    },
-    
-    getParams: function() {
-        var buf = [], o = {};
-        var bp = this.form.baseParams;
-        var p = this.options.params;
-        Ext.apply(o, p, bp);
-        var paramOrder = this.form.paramOrder;
-        if(paramOrder){
-            for(var i = 0, len = paramOrder.length; i < len; i++){
-                buf.push(o[paramOrder[i]]);
+Ext.form.Label = Ext.extend(Ext.BoxComponent, {
+    /**
+     * @cfg {String} text The plain text to display within the label (defaults to ''). If you need to include HTML
+     * tags within the label's innerHTML, use the {@link #html} config instead.
+     */
+    /**
+     * @cfg {String} forId The id of the input element to which this label will be bound via the standard HTML 'for'
+     * attribute. If not specified, the attribute will not be added to the label.
+     */
+    /**
+     * @cfg {String} html An HTML fragment that will be used as the label's innerHTML (defaults to '').
+     * Note that if {@link #text} is specified it will take precedence and this value will be ignored.
+     */
+
+    // private
+    onRender : function(ct, position){
+        if(!this.el){
+            this.el = document.createElement('label');
+            this.el.id = this.getId();
+            this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
+            if(this.forId){
+                this.el.setAttribute('for', this.forId);
             }
-        }else if(this.form.paramsAsHash){
-            buf.push(o);
         }
-        return buf;
+        Ext.form.Label.superclass.onRender.call(this, ct, position);
     },
-    // Direct actions have already been processed and therefore
-    // we can directly set the result; Direct Actions do not have
-    // a this.response property.
-    processResponse: function(result) {
-        this.result = result;
-        return result;          
-    }
-});
 
-/**
- * @class Ext.form.Action.DirectSubmit
- * @extends Ext.form.Action.Submit
- * Provides Ext.direct support for submitting form data.
- * See {@link Ext.form.Action.DirectLoad}.
- */
-Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, {
-    constructor: function(form, opts) {
-        Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts);
-    },
-    type: 'directsubmit',
-    // override of Submit
-    run : function(){
-        var o = this.options;
-        if(o.clientValidation === false || this.form.isValid()){
-            // tag on any additional params to be posted in the
-            // form scope
-            this.success.params = this.getParams();
-            this.form.api.submit(this.form.el.dom, this.success, this);
-        }else if (o.clientValidation !== false){ // client validation failed
-            this.failureType = Ext.form.Action.CLIENT_INVALID;
-            this.form.afterAction(this, false);
+    /**
+     * Updates the label's innerHTML with the specified string.
+     * @param {String} text The new label text
+     * @param {Boolean} encode (optional) False to skip HTML-encoding the text when rendering it
+     * to the label (defaults to true which encodes the value). This might be useful if you want to include
+     * tags in the label's innerHTML rather than rendering them as string literals per the default logic.
+     * @return {Label} this
+     */
+    setText : function(t, encode){
+        var e = encode === false;
+        this[!e ? 'text' : 'html'] = t;
+        delete this[e ? 'text' : 'html'];
+        if(this.rendered){
+            this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t;
         }
-    },
-    
-    getParams: function() {
-        var o = {};
-        var bp = this.form.baseParams;
-        var p = this.options.params;
-        Ext.apply(o, p, bp);
-        return o;
-    },    
-    // Direct actions have already been processed and therefore
-    // we can directly set the result; Direct Actions do not have
-    // a this.response property.
-    processResponse: function(result) {
-        this.result = result;
-        return result;          
+        return this;
     }
 });
 
-
-Ext.form.Action.ACTION_TYPES = {
-    'load' : Ext.form.Action.Load,
-    'submit' : Ext.form.Action.Submit,
-    'directload': Ext.form.Action.DirectLoad,
-    'directsubmit': Ext.form.Action.DirectSubmit
-};
+Ext.reg('label', Ext.form.Label);/**\r
+ * @class Ext.form.Action\r
+ * <p>The subclasses of this class provide actions to perform upon {@link Ext.form.BasicForm Form}s.</p>\r
+ * <p>Instances of this class are only created by a {@link Ext.form.BasicForm Form} when\r
+ * the Form needs to perform an action such as submit or load. The Configuration options\r
+ * listed for this class are set through the Form's action methods: {@link Ext.form.BasicForm#submit submit},\r
+ * {@link Ext.form.BasicForm#load load} and {@link Ext.form.BasicForm#doAction doAction}</p>\r
+ * <p>The instance of Action which performed the action is passed to the success\r
+ * and failure callbacks of the Form's action methods ({@link Ext.form.BasicForm#submit submit},\r
+ * {@link Ext.form.BasicForm#load load} and {@link Ext.form.BasicForm#doAction doAction}),\r
+ * and to the {@link Ext.form.BasicForm#actioncomplete actioncomplete} and\r
+ * {@link Ext.form.BasicForm#actionfailed actionfailed} event handlers.</p>\r
+ */\r
+Ext.form.Action = function(form, options){\r
+    this.form = form;\r
+    this.options = options || {};\r
+};\r
+\r
+/**\r
+ * Failure type returned when client side validation of the Form fails\r
+ * thus aborting a submit action. Client side validation is performed unless\r
+ * {@link #clientValidation} is explicitly set to <tt>false</tt>.\r
+ * @type {String}\r
+ * @static\r
+ */\r
+Ext.form.Action.CLIENT_INVALID = 'client';\r
+/**\r
+ * <p>Failure type returned when server side processing fails and the {@link #result}'s\r
+ * <tt style="font-weight:bold">success</tt> property is set to <tt>false</tt>.</p>\r
+ * <p>In the case of a form submission, field-specific error messages may be returned in the\r
+ * {@link #result}'s <tt style="font-weight:bold">errors</tt> property.</p>\r
+ * @type {String}\r
+ * @static\r
+ */\r
+Ext.form.Action.SERVER_INVALID = 'server';\r
+/**\r
+ * Failure type returned when a communication error happens when attempting\r
+ * to send a request to the remote server. The {@link #response} may be examined to\r
+ * provide further information.\r
+ * @type {String}\r
+ * @static\r
+ */\r
+Ext.form.Action.CONNECT_FAILURE = 'connect';\r
+/**\r
+ * Failure type returned when the response's <tt style="font-weight:bold">success</tt>\r
+ * property is set to <tt>false</tt>, or no field values are returned in the response's\r
+ * <tt style="font-weight:bold">data</tt> property.\r
+ * @type {String}\r
+ * @static\r
+ */\r
+Ext.form.Action.LOAD_FAILURE = 'load';\r
+\r
+Ext.form.Action.prototype = {\r
+/**\r
+ * @cfg {String} url The URL that the Action is to invoke.\r
+ */\r
+/**\r
+ * @cfg {Boolean} reset When set to <tt><b>true</b></tt>, causes the Form to be\r
+ * {@link Ext.form.BasicForm.reset reset} on Action success. If specified, this happens\r
+ * <b>before</b> the {@link #success} callback is called and before the Form's\r
+ * {@link Ext.form.BasicForm.actioncomplete actioncomplete} event fires.\r
+ */\r
+/**\r
+ * @cfg {String} method The HTTP method to use to access the requested URL. Defaults to the\r
+ * {@link Ext.form.BasicForm}'s method, or if that is not specified, the underlying DOM form's method.\r
+ */\r
+/**\r
+ * @cfg {Mixed} params <p>Extra parameter values to pass. These are added to the Form's\r
+ * {@link Ext.form.BasicForm#baseParams} and passed to the specified URL along with the Form's\r
+ * input fields.</p>\r
+ * <p>Parameters are encoded as standard HTTP parameters using {@link Ext#urlEncode}.</p>\r
+ */\r
+/**\r
+ * @cfg {Number} timeout The number of seconds to wait for a server response before\r
+ * failing with the {@link #failureType} as {@link #Action.CONNECT_FAILURE}. If not specified,\r
+ * defaults to the configured <tt>{@link Ext.form.BasicForm#timeout timeout}</tt> of the\r
+ * {@link Ext.form.BasicForm form}.\r
+ */\r
+/**\r
+ * @cfg {Function} success The function to call when a valid success return packet is recieved.\r
+ * The function is passed the following parameters:<ul class="mdetail-params">\r
+ * <li><b>form</b> : Ext.form.BasicForm<div class="sub-desc">The form that requested the action</div></li>\r
+ * <li><b>action</b> : Ext.form.Action<div class="sub-desc">The Action class. The {@link #result}\r
+ * property of this object may be examined to perform custom postprocessing.</div></li>\r
+ * </ul>\r
+ */\r
+/**\r
+ * @cfg {Function} failure The function to call when a failure packet was recieved, or when an\r
+ * error ocurred in the Ajax communication.\r
+ * The function is passed the following parameters:<ul class="mdetail-params">\r
+ * <li><b>form</b> : Ext.form.BasicForm<div class="sub-desc">The form that requested the action</div></li>\r
+ * <li><b>action</b> : Ext.form.Action<div class="sub-desc">The Action class. If an Ajax\r
+ * error ocurred, the failure type will be in {@link #failureType}. The {@link #result}\r
+ * property of this object may be examined to perform custom postprocessing.</div></li>\r
+ * </ul>\r
+ */\r
+/**\r
+ * @cfg {Object} scope The scope in which to call the callback functions (The <tt>this</tt> reference\r
+ * for the callback functions).\r
+ */\r
+/**\r
+ * @cfg {String} waitMsg The message to be displayed by a call to {@link Ext.MessageBox#wait}\r
+ * during the time the action is being processed.\r
+ */\r
+/**\r
+ * @cfg {String} waitTitle The title to be displayed by a call to {@link Ext.MessageBox#wait}\r
+ * during the time the action is being processed.\r
+ */\r
+\r
+/**\r
+ * The type of action this Action instance performs.\r
+ * Currently only "submit" and "load" are supported.\r
+ * @type {String}\r
+ */\r
+    type : 'default',\r
+/**\r
+ * The type of failure detected will be one of these: {@link #CLIENT_INVALID},\r
+ * {@link #SERVER_INVALID}, {@link #CONNECT_FAILURE}, or {@link #LOAD_FAILURE}.  Usage:\r
+ * <pre><code>\r
+var fp = new Ext.form.FormPanel({\r
+...\r
+buttons: [{\r
+    text: 'Save',\r
+    formBind: true,\r
+    handler: function(){\r
+        if(fp.getForm().isValid()){\r
+            fp.getForm().submit({\r
+                url: 'form-submit.php',\r
+                waitMsg: 'Submitting your data...',\r
+                success: function(form, action){\r
+                    // server responded with success = true\r
+                    var result = action.{@link #result};\r
+                },\r
+                failure: function(form, action){\r
+                    if (action.{@link #failureType} === Ext.form.Action.{@link #CONNECT_FAILURE}) {\r
+                        Ext.Msg.alert('Error',\r
+                            'Status:'+action.{@link #response}.status+': '+\r
+                            action.{@link #response}.statusText);\r
+                    }\r
+                    if (action.failureType === Ext.form.Action.{@link #SERVER_INVALID}){\r
+                        // server responded with success = false\r
+                        Ext.Msg.alert('Invalid', action.{@link #result}.errormsg);\r
+                    }\r
+                }\r
+            });\r
+        }\r
+    }\r
+},{\r
+    text: 'Reset',\r
+    handler: function(){\r
+        fp.getForm().reset();\r
+    }\r
+}]\r
+ * </code></pre>\r
+ * @property failureType\r
+ * @type {String}\r
+ */\r
+ /**\r
+ * The XMLHttpRequest object used to perform the action.\r
+ * @property response\r
+ * @type {Object}\r
+ */\r
+ /**\r
+ * The decoded response object containing a boolean <tt style="font-weight:bold">success</tt> property and\r
+ * other, action-specific properties.\r
+ * @property result\r
+ * @type {Object}\r
+ */\r
+\r
+    // interface method\r
+    run : function(options){\r
+\r
+    },\r
+\r
+    // interface method\r
+    success : function(response){\r
+\r
+    },\r
+\r
+    // interface method\r
+    handleResponse : function(response){\r
+\r
+    },\r
+\r
+    // default connection failure\r
+    failure : function(response){\r
+        this.response = response;\r
+        this.failureType = Ext.form.Action.CONNECT_FAILURE;\r
+        this.form.afterAction(this, false);\r
+    },\r
+\r
+    // private\r
+    // shared code among all Actions to validate that there was a response\r
+    // with either responseText or responseXml\r
+    processResponse : function(response){\r
+        this.response = response;\r
+        if(!response.responseText && !response.responseXML){\r
+            return true;\r
+        }\r
+        this.result = this.handleResponse(response);\r
+        return this.result;\r
+    },\r
+\r
+    // utility functions used internally\r
+    getUrl : function(appendParams){\r
+        var url = this.options.url || this.form.url || this.form.el.dom.action;\r
+        if(appendParams){\r
+            var p = this.getParams();\r
+            if(p){\r
+                url = Ext.urlAppend(url, p);\r
+            }\r
+        }\r
+        return url;\r
+    },\r
+\r
+    // private\r
+    getMethod : function(){\r
+        return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();\r
+    },\r
+\r
+    // private\r
+    getParams : function(){\r
+        var bp = this.form.baseParams;\r
+        var p = this.options.params;\r
+        if(p){\r
+            if(typeof p == "object"){\r
+                p = Ext.urlEncode(Ext.applyIf(p, bp));\r
+            }else if(typeof p == 'string' && bp){\r
+                p += '&' + Ext.urlEncode(bp);\r
+            }\r
+        }else if(bp){\r
+            p = Ext.urlEncode(bp);\r
+        }\r
+        return p;\r
+    },\r
+\r
+    // private\r
+    createCallback : function(opts){\r
+        var opts = opts || {};\r
+        return {\r
+            success: this.success,\r
+            failure: this.failure,\r
+            scope: this,\r
+            timeout: (opts.timeout*1000) || (this.form.timeout*1000),\r
+            upload: this.form.fileUpload ? this.success : undefined\r
+        };\r
+    }\r
+};\r
+\r
+/**\r
+ * @class Ext.form.Action.Submit\r
+ * @extends Ext.form.Action\r
+ * <p>A class which handles submission of data from {@link Ext.form.BasicForm Form}s\r
+ * and processes the returned response.</p>\r
+ * <p>Instances of this class are only created by a {@link Ext.form.BasicForm Form} when\r
+ * {@link Ext.form.BasicForm#submit submit}ting.</p>\r
+ * <p><u><b>Response Packet Criteria</b></u></p>\r
+ * <p>A response packet may contain:\r
+ * <div class="mdetail-params"><ul>\r
+ * <li><b><code>success</code></b> property : Boolean\r
+ * <div class="sub-desc">The <code>success</code> property is required.</div></li>\r
+ * <li><b><code>errors</code></b> property : Object\r
+ * <div class="sub-desc"><div class="sub-desc">The <code>errors</code> property,\r
+ * which is optional, contains error messages for invalid fields.</div></li>\r
+ * </ul></div>\r
+ * <p><u><b>JSON Packets</b></u></p>\r
+ * <p>By default, response packets are assumed to be JSON, so a typical response\r
+ * packet may look like this:</p><pre><code>\r
+{\r
+    success: false,\r
+    errors: {\r
+        clientCode: "Client not found",\r
+        portOfLoading: "This field must not be null"\r
+    }\r
+}</code></pre>\r
+ * <p>Other data may be placed into the response for processing by the {@link Ext.form.BasicForm}'s callback\r
+ * or event handler methods. The object decoded from this JSON is available in the\r
+ * {@link Ext.form.Action#result result} property.</p>\r
+ * <p>Alternatively, if an {@link #errorReader} is specified as an {@link Ext.data.XmlReader XmlReader}:</p><pre><code>\r
+    errorReader: new Ext.data.XmlReader({\r
+            record : 'field',\r
+            success: '@success'\r
+        }, [\r
+            'id', 'msg'\r
+        ]\r
+    )\r
+</code></pre>\r
+ * <p>then the results may be sent back in XML format:</p><pre><code>\r
+&lt;?xml version="1.0" encoding="UTF-8"?&gt;\r
+&lt;message success="false"&gt;\r
+&lt;errors&gt;\r
+    &lt;field&gt;\r
+        &lt;id&gt;clientCode&lt;/id&gt;\r
+        &lt;msg&gt;&lt;![CDATA[Code not found. &lt;br /&gt;&lt;i&gt;This is a test validation message from the server &lt;/i&gt;]]&gt;&lt;/msg&gt;\r
+    &lt;/field&gt;\r
+    &lt;field&gt;\r
+        &lt;id&gt;portOfLoading&lt;/id&gt;\r
+        &lt;msg&gt;&lt;![CDATA[Port not found. &lt;br /&gt;&lt;i&gt;This is a test validation message from the server &lt;/i&gt;]]&gt;&lt;/msg&gt;\r
+    &lt;/field&gt;\r
+&lt;/errors&gt;\r
+&lt;/message&gt;\r
+</code></pre>\r
+ * <p>Other elements may be placed into the response XML for processing by the {@link Ext.form.BasicForm}'s callback\r
+ * or event handler methods. The XML document is available in the {@link #errorReader}'s {@link Ext.data.XmlReader#xmlData xmlData} property.</p>\r
+ */\r
+Ext.form.Action.Submit = function(form, options){\r
+    Ext.form.Action.Submit.superclass.constructor.call(this, form, options);\r
+};\r
+\r
+Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {\r
+    /**\r
+     * @cfg {Ext.data.DataReader} errorReader <p><b>Optional. JSON is interpreted with\r
+     * no need for an errorReader.</b></p>\r
+     * <p>A Reader which reads a single record from the returned data. The DataReader's\r
+     * <b>success</b> property specifies how submission success is determined. The Record's\r
+     * data provides the error messages to apply to any invalid form Fields.</p>\r
+     */\r
+    /**\r
+     * @cfg {boolean} clientValidation Determines whether a Form's fields are validated\r
+     * in a final call to {@link Ext.form.BasicForm#isValid isValid} prior to submission.\r
+     * Pass <tt>false</tt> in the Form's submit options to prevent this. If not defined, pre-submission field validation\r
+     * is performed.\r
+     */\r
+    type : 'submit',\r
+\r
+    // private\r
+    run : function(){\r
+        var o = this.options;\r
+        var method = this.getMethod();\r
+        var isGet = method == 'GET';\r
+        if(o.clientValidation === false || this.form.isValid()){\r
+            Ext.Ajax.request(Ext.apply(this.createCallback(o), {\r
+                form:this.form.el.dom,\r
+                url:this.getUrl(isGet),\r
+                method: method,\r
+                headers: o.headers,\r
+                params:!isGet ? this.getParams() : null,\r
+                isUpload: this.form.fileUpload\r
+            }));\r
+        }else if (o.clientValidation !== false){ // client validation failed\r
+            this.failureType = Ext.form.Action.CLIENT_INVALID;\r
+            this.form.afterAction(this, false);\r
+        }\r
+    },\r
+\r
+    // private\r
+    success : function(response){\r
+        var result = this.processResponse(response);\r
+        if(result === true || result.success){\r
+            this.form.afterAction(this, true);\r
+            return;\r
+        }\r
+        if(result.errors){\r
+            this.form.markInvalid(result.errors);\r
+        }\r
+        this.failureType = Ext.form.Action.SERVER_INVALID;\r
+        this.form.afterAction(this, false);\r
+    },\r
+\r
+    // private\r
+    handleResponse : function(response){\r
+        if(this.form.errorReader){\r
+            var rs = this.form.errorReader.read(response);\r
+            var errors = [];\r
+            if(rs.records){\r
+                for(var i = 0, len = rs.records.length; i < len; i++) {\r
+                    var r = rs.records[i];\r
+                    errors[i] = r.data;\r
+                }\r
+            }\r
+            if(errors.length < 1){\r
+                errors = null;\r
+            }\r
+            return {\r
+                success : rs.success,\r
+                errors : errors\r
+            };\r
+        }\r
+        return Ext.decode(response.responseText);\r
+    }\r
+});\r
+\r
+\r
+/**\r
+ * @class Ext.form.Action.Load\r
+ * @extends Ext.form.Action\r
+ * <p>A class which handles loading of data from a server into the Fields of an {@link Ext.form.BasicForm}.</p>\r
+ * <p>Instances of this class are only created by a {@link Ext.form.BasicForm Form} when\r
+ * {@link Ext.form.BasicForm#load load}ing.</p>\r
+ * <p><u><b>Response Packet Criteria</b></u></p>\r
+ * <p>A response packet <b>must</b> contain:\r
+ * <div class="mdetail-params"><ul>\r
+ * <li><b><code>success</code></b> property : Boolean</li>\r
+ * <li><b><code>data</code></b> property : Object</li>\r
+ * <div class="sub-desc">The <code>data</code> property contains the values of Fields to load.\r
+ * The individual value object for each Field is passed to the Field's\r
+ * {@link Ext.form.Field#setValue setValue} method.</div></li>\r
+ * </ul></div>\r
+ * <p><u><b>JSON Packets</b></u></p>\r
+ * <p>By default, response packets are assumed to be JSON, so for the following form load call:<pre><code>\r
+var myFormPanel = new Ext.form.FormPanel({\r
+    title: 'Client and routing info',\r
+    items: [{\r
+        fieldLabel: 'Client',\r
+        name: 'clientName'\r
+    }, {\r
+        fieldLabel: 'Port of loading',\r
+        name: 'portOfLoading'\r
+    }, {\r
+        fieldLabel: 'Port of discharge',\r
+        name: 'portOfDischarge'\r
+    }]\r
+});\r
+myFormPanel.{@link Ext.form.FormPanel#getForm getForm}().{@link Ext.form.BasicForm#load load}({\r
+    url: '/getRoutingInfo.php',\r
+    params: {\r
+        consignmentRef: myConsignmentRef\r
+    },\r
+    failure: function(form, action) {\r
+        Ext.Msg.alert("Load failed", action.result.errorMessage);\r
+    }\r
+});\r
+</code></pre>\r
+ * a <b>success response</b> packet may look like this:</p><pre><code>\r
+{\r
+    success: true,\r
+    data: {\r
+        clientName: "Fred. Olsen Lines",\r
+        portOfLoading: "FXT",\r
+        portOfDischarge: "OSL"\r
+    }\r
+}</code></pre>\r
+ * while a <b>failure response</b> packet may look like this:</p><pre><code>\r
+{\r
+    success: false,\r
+    errorMessage: "Consignment reference not found"\r
+}</code></pre>\r
+ * <p>Other data may be placed into the response for processing the {@link Ext.form.BasicForm Form}'s\r
+ * callback or event handler methods. The object decoded from this JSON is available in the\r
+ * {@link Ext.form.Action#result result} property.</p>\r
+ */\r
+Ext.form.Action.Load = function(form, options){\r
+    Ext.form.Action.Load.superclass.constructor.call(this, form, options);\r
+    this.reader = this.form.reader;\r
+};\r
+\r
+Ext.extend(Ext.form.Action.Load, Ext.form.Action, {\r
+    // private\r
+    type : 'load',\r
+\r
+    // private\r
+    run : function(){\r
+        Ext.Ajax.request(Ext.apply(\r
+                this.createCallback(this.options), {\r
+                    method:this.getMethod(),\r
+                    url:this.getUrl(false),\r
+                    headers: this.options.headers,\r
+                    params:this.getParams()\r
+        }));\r
+    },\r
+\r
+    // private\r
+    success : function(response){\r
+        var result = this.processResponse(response);\r
+        if(result === true || !result.success || !result.data){\r
+            this.failureType = Ext.form.Action.LOAD_FAILURE;\r
+            this.form.afterAction(this, false);\r
+            return;\r
+        }\r
+        this.form.clearInvalid();\r
+        this.form.setValues(result.data);\r
+        this.form.afterAction(this, true);\r
+    },\r
+\r
+    // private\r
+    handleResponse : function(response){\r
+        if(this.form.reader){\r
+            var rs = this.form.reader.read(response);\r
+            var data = rs.records && rs.records[0] ? rs.records[0].data : null;\r
+            return {\r
+                success : rs.success,\r
+                data : data\r
+            };\r
+        }\r
+        return Ext.decode(response.responseText);\r
+    }\r
+});\r
+\r
+\r
+\r
+/**\r
+ * @class Ext.form.Action.DirectLoad\r
+ * @extends Ext.form.Action.Load\r
+ * <p>Provides Ext.direct support for loading form data.</p>\r
+ * <p>This example illustrates usage of Ext.Direct to <b>load</b> a form through Ext.Direct.</p>\r
+ * <pre><code>\r
+var myFormPanel = new Ext.form.FormPanel({\r
+    // configs for FormPanel\r
+    title: 'Basic Information',\r
+    renderTo: document.body,\r
+    width: 300, height: 160,\r
+    padding: 10,\r
+\r
+    // configs apply to child items\r
+    defaults: {anchor: '100%'},\r
+    defaultType: 'textfield',\r
+    items: [{\r
+        fieldLabel: 'Name',\r
+        name: 'name'\r
+    },{\r
+        fieldLabel: 'Email',\r
+        name: 'email'\r
+    },{\r
+        fieldLabel: 'Company',\r
+        name: 'company'\r
+    }],\r
+\r
+    // configs for BasicForm\r
+    api: {\r
+        // The server-side method to call for load() requests\r
+        load: Profile.getBasicInfo,\r
+        // The server-side must mark the submit handler as a 'formHandler'\r
+        submit: Profile.updateBasicInfo\r
+    },\r
+    // specify the order for the passed params\r
+    paramOrder: ['uid', 'foo']\r
+});\r
+\r
+// load the form\r
+myFormPanel.getForm().load({\r
+    // pass 2 arguments to server side getBasicInfo method (len=2)\r
+    params: {\r
+        foo: 'bar',\r
+        uid: 34\r
+    }\r
+});\r
+ * </code></pre>\r
+ * The data packet sent to the server will resemble something like:\r
+ * <pre><code>\r
+[\r
+    {\r
+        "action":"Profile","method":"getBasicInfo","type":"rpc","tid":2,\r
+        "data":[34,"bar"] // note the order of the params\r
+    }\r
+]\r
+ * </code></pre>\r
+ * The form will process a data packet returned by the server that is similar\r
+ * to the following format:\r
+ * <pre><code>\r
+[\r
+    {\r
+        "action":"Profile","method":"getBasicInfo","type":"rpc","tid":2,\r
+        "result":{\r
+            "success":true,\r
+            "data":{\r
+                "name":"Fred Flintstone",\r
+                "company":"Slate Rock and Gravel",\r
+                "email":"fred.flintstone@slaterg.com"\r
+            }\r
+        }\r
+    }\r
+]\r
+ * </code></pre>\r
+ */\r
+Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, {\r
+    constructor: function(form, opts) {\r
+        Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts);\r
+    },\r
+    type : 'directload',\r
+\r
+    run : function(){\r
+        var args = this.getParams();\r
+        args.push(this.success, this);\r
+        this.form.api.load.apply(window, args);\r
+    },\r
+\r
+    getParams : function() {\r
+        var buf = [], o = {};\r
+        var bp = this.form.baseParams;\r
+        var p = this.options.params;\r
+        Ext.apply(o, p, bp);\r
+        var paramOrder = this.form.paramOrder;\r
+        if(paramOrder){\r
+            for(var i = 0, len = paramOrder.length; i < len; i++){\r
+                buf.push(o[paramOrder[i]]);\r
+            }\r
+        }else if(this.form.paramsAsHash){\r
+            buf.push(o);\r
+        }\r
+        return buf;\r
+    },\r
+    // Direct actions have already been processed and therefore\r
+    // we can directly set the result; Direct Actions do not have\r
+    // a this.response property.\r
+    processResponse : function(result) {\r
+        this.result = result;\r
+        return result;\r
+    },\r
+    \r
+    success : function(response, trans){\r
+        if(trans.type == Ext.Direct.exceptions.SERVER){\r
+            response = {};\r
+        }\r
+        Ext.form.Action.DirectLoad.superclass.success.call(this, response);\r
+    }\r
+});\r
+\r
+/**\r
+ * @class Ext.form.Action.DirectSubmit\r
+ * @extends Ext.form.Action.Submit\r
+ * <p>Provides Ext.direct support for submitting form data.</p>\r
+ * <p>This example illustrates usage of Ext.Direct to <b>submit</b> a form through Ext.Direct.</p>\r
+ * <pre><code>\r
+var myFormPanel = new Ext.form.FormPanel({\r
+    // configs for FormPanel\r
+    title: 'Basic Information',\r
+    renderTo: document.body,\r
+    width: 300, height: 160,\r
+    padding: 10,\r
+    buttons:[{\r
+        text: 'Submit',\r
+        handler: function(){\r
+            myFormPanel.getForm().submit({\r
+                params: {\r
+                    foo: 'bar',\r
+                    uid: 34\r
+                }\r
+            });\r
+        }\r
+    }],\r
+\r
+    // configs apply to child items\r
+    defaults: {anchor: '100%'},\r
+    defaultType: 'textfield',\r
+    items: [{\r
+        fieldLabel: 'Name',\r
+        name: 'name'\r
+    },{\r
+        fieldLabel: 'Email',\r
+        name: 'email'\r
+    },{\r
+        fieldLabel: 'Company',\r
+        name: 'company'\r
+    }],\r
+\r
+    // configs for BasicForm\r
+    api: {\r
+        // The server-side method to call for load() requests\r
+        load: Profile.getBasicInfo,\r
+        // The server-side must mark the submit handler as a 'formHandler'\r
+        submit: Profile.updateBasicInfo\r
+    },\r
+    // specify the order for the passed params\r
+    paramOrder: ['uid', 'foo']\r
+});\r
+ * </code></pre>\r
+ * The data packet sent to the server will resemble something like:\r
+ * <pre><code>\r
+{\r
+    "action":"Profile","method":"updateBasicInfo","type":"rpc","tid":"6",\r
+    "result":{\r
+        "success":true,\r
+        "id":{\r
+            "extAction":"Profile","extMethod":"updateBasicInfo",\r
+            "extType":"rpc","extTID":"6","extUpload":"false",\r
+            "name":"Aaron Conran","email":"aaron@extjs.com","company":"Ext JS, LLC"\r
+        }\r
+    }\r
+}\r
+ * </code></pre>\r
+ * The form will process a data packet returned by the server that is similar\r
+ * to the following:\r
+ * <pre><code>\r
+// sample success packet (batched requests)\r
+[\r
+    {\r
+        "action":"Profile","method":"updateBasicInfo","type":"rpc","tid":3,\r
+        "result":{\r
+            "success":true\r
+        }\r
+    }\r
+]\r
+\r
+// sample failure packet (one request)\r
+{\r
+        "action":"Profile","method":"updateBasicInfo","type":"rpc","tid":"6",\r
+        "result":{\r
+            "errors":{\r
+                "email":"already taken"\r
+            },\r
+            "success":false,\r
+            "foo":"bar"\r
+        }\r
+}\r
+ * </code></pre>\r
+ * Also see the discussion in {@link Ext.form.Action.DirectLoad}.\r
+ */\r
+Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, {\r
+    constructor : function(form, opts) {\r
+        Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts);\r
+    },\r
+    type : 'directsubmit',\r
+    // override of Submit\r
+    run : function(){\r
+        var o = this.options;\r
+        if(o.clientValidation === false || this.form.isValid()){\r
+            // tag on any additional params to be posted in the\r
+            // form scope\r
+            this.success.params = this.getParams();\r
+            this.form.api.submit(this.form.el.dom, this.success, this);\r
+        }else if (o.clientValidation !== false){ // client validation failed\r
+            this.failureType = Ext.form.Action.CLIENT_INVALID;\r
+            this.form.afterAction(this, false);\r
+        }\r
+    },\r
+\r
+    getParams : function() {\r
+        var o = {};\r
+        var bp = this.form.baseParams;\r
+        var p = this.options.params;\r
+        Ext.apply(o, p, bp);\r
+        return o;\r
+    },\r
+    // Direct actions have already been processed and therefore\r
+    // we can directly set the result; Direct Actions do not have\r
+    // a this.response property.\r
+    processResponse : function(result) {\r
+        this.result = result;\r
+        return result;\r
+    },\r
+    \r
+    success : function(response, trans){\r
+        if(trans.type == Ext.Direct.exceptions.SERVER){\r
+            response = {};\r
+        }\r
+        Ext.form.Action.DirectSubmit.superclass.success.call(this, response);\r
+    }\r
+});\r
+\r
+Ext.form.Action.ACTION_TYPES = {\r
+    'load' : Ext.form.Action.Load,\r
+    'submit' : Ext.form.Action.Submit,\r
+    'directload' : Ext.form.Action.DirectLoad,\r
+    'directsubmit' : Ext.form.Action.DirectSubmit\r
+};\r
 /**
  * @class Ext.form.VTypes
  * <p>This is a singleton object which contains a set of commonly used field validation functions.
@@ -59330,10 +61043,10 @@ Ext.apply(Ext.form.VTypes, {
  */
 Ext.form.VTypes = function(){
     // closure these in so they are only created once.
-    var alpha = /^[a-zA-Z_]+$/;
-    var alphanum = /^[a-zA-Z0-9_]+$/;
-    var email = /^(\w+)([-+.][\w]+)*@(\w[-\w]*\.){1,5}([A-Za-z]){2,4}$/;
-    var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
+    var alpha = /^[a-zA-Z_]+$/,
+        alphanum = /^[a-zA-Z0-9_]+$/,
+        email = /^(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,4}$/,
+        url = /(((^https?)|(^ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
 
     // All these messages and functions are configurable
     return {
@@ -59440,19 +61153,28 @@ Ext.form.VTypes = function(){
  * <p>Example usage:</p>\r
  * <pre><code>\r
 var grid = new Ext.grid.GridPanel({\r
-    {@link #store}: new (@link Ext.data.Store}({\r
+    {@link #store}: new {@link Ext.data.Store}({\r
         {@link Ext.data.Store#autoDestroy autoDestroy}: true,\r
         {@link Ext.data.Store#reader reader}: reader,\r
         {@link Ext.data.Store#data data}: xg.dummyData\r
     }),\r
-    {@link #columns}: [\r
-        {id: 'company', header: 'Company', width: 200, sortable: true, dataIndex: 'company'},\r
-        {header: 'Price', width: 120, sortable: true, renderer: Ext.util.Format.usMoney, dataIndex: 'price'},\r
-        {header: 'Change', width: 120, sortable: true, dataIndex: 'change'},\r
-        {header: '% Change', width: 120, sortable: true, dataIndex: 'pctChange'},\r
-        // instead of specifying renderer: Ext.util.Format.dateRenderer('m/d/Y') use xtype\r
-        {header: 'Last Updated', width: 135, sortable: true, dataIndex: 'lastChange', xtype: 'datecolumn', format: 'M d, Y'}\r
-    ],\r
+    {@link #colModel}: new {@link Ext.grid.ColumnModel}({\r
+        {@link Ext.grid.ColumnModel#defaults defaults}: {\r
+            width: 120,\r
+            sortable: true\r
+        },\r
+        {@link Ext.grid.ColumnModel#columns columns}: [\r
+            {id: 'company', header: 'Company', width: 200, sortable: true, dataIndex: 'company'},\r
+            {header: 'Price', renderer: Ext.util.Format.usMoney, dataIndex: 'price'},\r
+            {header: 'Change', dataIndex: 'change'},\r
+            {header: '% Change', dataIndex: 'pctChange'},\r
+            // instead of specifying renderer: Ext.util.Format.dateRenderer('m/d/Y') use xtype\r
+            {\r
+                header: 'Last Updated', width: 135, dataIndex: 'lastChange',\r
+                xtype: 'datecolumn', format: 'M d, Y'\r
+            }\r
+        ],\r
+    }),\r
     {@link #viewConfig}: {\r
         {@link Ext.grid.GridView#forceFit forceFit}: true,\r
 \r
@@ -59558,7 +61280,9 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
      * @cfg {Boolean} enableColumnResize <tt>false</tt> to turn off column resizing for the whole grid. Defaults to <tt>true</tt>.\r
      */\r
     /**\r
-     * @cfg {Boolean} enableColumnHide Defaults to <tt>true</tt> to enable hiding of columns with the header context menu.\r
+     * @cfg {Boolean} enableColumnHide\r
+     * Defaults to <tt>true</tt> to enable {@link Ext.grid.Column#hidden hiding of columns}\r
+     * with the {@link #enableHdMenu header menu}.\r
      */\r
     enableColumnHide : true,\r
     /**\r
@@ -59637,6 +61361,14 @@ Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
      * before a call to {@link Ext.Component#render render()}.\r
      */\r
     view : null,\r
+    \r
+    /**\r
+     * @cfg {Array} bubbleEvents\r
+     * <p>An array of events that, when fired, should be bubbled to any parent container.\r
+     * Defaults to <tt>[]</tt>.\r
+     */\r
+    bubbleEvents: [],\r
+    \r
     /**\r
      * @cfg {Object} viewConfig A config object that will be applied to the grid's UI view.  Any of\r
      * the config options available for {@link Ext.grid.GridView} can be specified here. This option\r
@@ -59892,26 +61624,24 @@ function(grid, rowIndex, columnIndex, e) {
     onRender : function(ct, position){\r
         Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);\r
 \r
-        var c = this.body;\r
+        var c = this.getGridEl();\r
 \r
         this.el.addClass('x-grid-panel');\r
 \r
-        var view = this.getView();\r
-        view.init(this);\r
-\r
         this.mon(c, {\r
+            scope: this,\r
             mousedown: this.onMouseDown,\r
             click: this.onClick,\r
             dblclick: this.onDblClick,\r
-            contextmenu: this.onContextMenu,\r
-            keydown: this.onKeyDown,\r
-            scope: this\r
+            contextmenu: this.onContextMenu\r
         });\r
 \r
-        this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress']);\r
+        this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress', 'keydown']);\r
 \r
+        var view = this.getView();\r
+        view.init(this);\r
+        view.render();\r
         this.getSelectionModel().init(this);\r
-        this.view.render();\r
     },\r
 \r
     // private\r
@@ -59930,8 +61660,8 @@ function(grid, rowIndex, columnIndex, e) {
     },\r
 \r
     applyState : function(state){\r
-        var cm = this.colModel;\r
-        var cs = state.columns;\r
+        var cm = this.colModel,\r
+            cs = state.columns;\r
         if(cs){\r
             for(var i = 0, len = cs.length; i < len; i++){\r
                 var s = cs[i];\r
@@ -59949,9 +61679,10 @@ function(grid, rowIndex, columnIndex, e) {
         if(state.sort && this.store){\r
             this.store[this.store.remoteSort ? 'setDefaultSort' : 'sort'](state.sort.field, state.sort.direction);\r
         }\r
-        delete state.columns;\r
-        delete state.sort;\r
-        Ext.grid.GridPanel.superclass.applyState.call(this, state);\r
+        var o = Ext.apply({}, state);\r
+        delete o.columns;\r
+        delete o.sort;\r
+        Ext.grid.GridPanel.superclass.applyState.call(this, o);\r
     },\r
 \r
     getState : function(){\r
@@ -59977,11 +61708,13 @@ function(grid, rowIndex, columnIndex, e) {
     // private\r
     afterRender : function(){\r
         Ext.grid.GridPanel.superclass.afterRender.call(this);\r
-        this.view.layout();\r
+        var v = this.view;\r
+        this.on('bodyresize', v.layout, v);\r
+        v.layout();\r
         if(this.deferRowRender){\r
-            this.view.afterRender.defer(10, this.view);\r
+            v.afterRender.defer(10, this.view);\r
         }else{\r
-            this.view.afterRender();\r
+            v.afterRender();\r
         }\r
         this.viewReady = true;\r
     },\r
@@ -60013,11 +61746,6 @@ function(grid, rowIndex, columnIndex, e) {
         this.fireEvent('reconfigure', this, store, colModel);\r
     },\r
 \r
-    // private\r
-    onKeyDown : function(e){\r
-        this.fireEvent('keydown', e);\r
-    },\r
-\r
     // private\r
     onDestroy : function(){\r
         if(this.rendered){\r
@@ -60389,7 +62117,7 @@ Ext.grid.GridView = function(config){
          * @param {Number} rowIndex The index of the row to be removed.
          * @param {Ext.data.Record} record The Record to be removed
          */
-        "beforerowremoved",
+        'beforerowremoved',
         /**
          * @event beforerowsinserted
          * Internal UI Event. Fired before rows are inserted.
@@ -60397,13 +62125,13 @@ Ext.grid.GridView = function(config){
          * @param {Number} firstRow The index of the first row to be inserted.
          * @param {Number} lastRow The index of the last row to be inserted.
          */
-        "beforerowsinserted",
+        'beforerowsinserted',
         /**
          * @event beforerefresh
          * Internal UI Event. Fired before the view is refreshed.
          * @param {Ext.grid.GridView} view
          */
-        "beforerefresh",
+        'beforerefresh',
         /**
          * @event rowremoved
          * Internal UI Event. Fired after a row is removed.
@@ -60411,7 +62139,7 @@ Ext.grid.GridView = function(config){
          * @param {Number} rowIndex The index of the row that was removed.
          * @param {Ext.data.Record} record The Record that was removed
          */
-        "rowremoved",
+        'rowremoved',
         /**
          * @event rowsinserted
          * Internal UI Event. Fired after rows are inserted.
@@ -60419,7 +62147,7 @@ Ext.grid.GridView = function(config){
          * @param {Number} firstRow The index of the first inserted.
          * @param {Number} lastRow The index of the last row inserted.
          */
-        "rowsinserted",
+        'rowsinserted',
         /**
          * @event rowupdated
          * Internal UI Event. Fired after a row has been updated.
@@ -60427,13 +62155,13 @@ Ext.grid.GridView = function(config){
          * @param {Number} firstRow The index of the row updated.
          * @param {Ext.data.record} record The Record backing the row updated.
          */
-        "rowupdated",
+        'rowupdated',
         /**
          * @event refresh
          * Internal UI Event. Fired after the GridView's body has been refreshed.
          * @param {Ext.grid.GridView} view
          */
-        "refresh"
+        'refresh'
     );
     Ext.grid.GridView.superclass.constructor.call(this);
 };
@@ -60516,9 +62244,10 @@ viewConfig: {
     deferEmptyText : true,
     /**
      * @cfg {Number} scrollOffset The amount of space to reserve for the vertical scrollbar
-     * (defaults to <tt>19</tt> pixels).
+     * (defaults to <tt>undefined</tt>). If an explicit value isn't specified, this will be automatically
+     * calculated.
      */
-    scrollOffset : 19,
+    scrollOffset : undefined,
     /**
      * @cfg {Boolean} autoFill
      * Defaults to <tt>false</tt>.  Specify <tt>true</tt> to have the column widths re-proportioned
@@ -60539,24 +62268,24 @@ viewConfig: {
      */
     forceFit : false,
     /**
-     * @cfg {Array} sortClasses The CSS classes applied to a header when it is sorted. (defaults to <tt>["sort-asc", "sort-desc"]</tt>)
+     * @cfg {Array} sortClasses The CSS classes applied to a header when it is sorted. (defaults to <tt>['sort-asc', 'sort-desc']</tt>)
      */
-    sortClasses : ["sort-asc", "sort-desc"],
+    sortClasses : ['sort-asc', 'sort-desc'],
     /**
-     * @cfg {String} sortAscText The text displayed in the "Sort Ascending" menu item (defaults to <tt>"Sort Ascending"</tt>)
+     * @cfg {String} sortAscText The text displayed in the 'Sort Ascending' menu item (defaults to <tt>'Sort Ascending'</tt>)
      */
-    sortAscText : "Sort Ascending",
+    sortAscText : 'Sort Ascending',
     /**
-     * @cfg {String} sortDescText The text displayed in the "Sort Descending" menu item (defaults to <tt>"Sort Descending"</tt>)
+     * @cfg {String} sortDescText The text displayed in the 'Sort Descending' menu item (defaults to <tt>'Sort Descending'</tt>)
      */
-    sortDescText : "Sort Descending",
+    sortDescText : 'Sort Descending',
     /**
-     * @cfg {String} columnsText The text displayed in the "Columns" menu item (defaults to <tt>"Columns"</tt>)
+     * @cfg {String} columnsText The text displayed in the 'Columns' menu item (defaults to <tt>'Columns'</tt>)
      */
-    columnsText : "Columns",
+    columnsText : 'Columns',
 
     /**
-     * @cfg {String} selectedRowClass The CSS class applied to a selected row (defaults to <tt>"x-grid3-row-selected"</tt>). An
+     * @cfg {String} selectedRowClass The CSS class applied to a selected row (defaults to <tt>'x-grid3-row-selected'</tt>). An
      * example overriding the default styling:
     <pre><code>
     .x-grid3-row-selected {background-color: yellow;}
@@ -60570,7 +62299,7 @@ viewConfig: {
     </code></pre>
      * @type String
      */
-    selectedRowClass : "x-grid3-row-selected",
+    selectedRowClass : 'x-grid3-row-selected',
 
     // private
     borderWidth : 2,
@@ -60665,7 +62394,7 @@ viewConfig: {
         }
 
         this.templates = ts;
-        this.colRe = new RegExp("x-grid3-td-([^\\s]+)", "");
+        this.colRe = new RegExp('x-grid3-td-([^\\s]+)', '');
     },
 
     // private
@@ -60712,7 +62441,7 @@ viewConfig: {
         this.mainBody = new E(this.scroller.dom.firstChild);
 
         this.focusEl = new E(this.scroller.dom.childNodes[1]);
-        this.focusEl.swallowEvent("click", true);
+        this.focusEl.swallowEvent('click', true);
 
         this.resizeMarker = new E(cs[1]);
         this.resizeProxy = new E(cs[2]);
@@ -60733,12 +62462,12 @@ viewConfig: {
         return this.fly(el).findParent(this.cellSelector, this.cellSelectorDepth);
     },
 
-/**
* <p>Return the index of the grid column which contains the passed element.</p>
- * See also {@link #findRowIndex}
* @param {Element} el The target element
* @return The column index, or <b>false</b> if the target element is not within a row of this GridView.
- */
+    /**
    * <p>Return the index of the grid column which contains the passed HTMLElement.</p>
    * See also {@link #findRowIndex}
    * @param {HTMLElement} el The target element
    * @return {Number} The column index, or <b>false</b> if the target element is not within a row of this GridView.
    */
     findCellIndex : function(el, requiredCls){
         var cell = this.findCell(el);
         if(cell && (!requiredCls || this.fly(cell).hasClass(requiredCls))){
@@ -60769,11 +62498,11 @@ viewConfig: {
         return this.findCellIndex(el, this.hdCls);
     },
 
-/**
- * Return the HtmlElement representing the grid row which contains the passed element.
* @param {Element} el The target element
* @return The row element, or null if the target element is not within a row of this GridView.
- */
+    /**
    * Return the HtmlElement representing the grid row which contains the passed element.
    * @param {HTMLElement} el The target HTMLElement
    * @return {HTMLElement} The row element, or null if the target element is not within a row of this GridView.
    */
     findRow : function(el){
         if(!el){
             return false;
@@ -60781,12 +62510,12 @@ viewConfig: {
         return this.fly(el).findParent(this.rowSelector, this.rowSelectorDepth);
     },
 
-/**
* <p>Return the index of the grid row which contains the passed element.</p>
- * See also {@link #findCellIndex}
* @param {Element} el The target element
* @return The row index, or <b>false</b> if the target element is not within a row of this GridView.
- */
+    /**
    * <p>Return the index of the grid row which contains the passed HTMLElement.</p>
    * See also {@link #findCellIndex}
    * @param {HTMLElement} el The target HTMLElement
    * @return {Number} The row index, or <b>false</b> if the target element is not within a row of this GridView.
    */
     findRowIndex : function(el){
         var r = this.findRow(el);
         return r ? r.rowIndex : false;
@@ -60794,30 +62523,30 @@ viewConfig: {
 
     // getter methods for fetching elements dynamically in the grid
 
-/**
- * Return the <tt>&lt;div></tt> HtmlElement which represents a Grid row for the specified index.
- * @param {Number} index The row index
- * @return {HtmlElement} The div element.
- */
+    /**
    * Return the <tt>&lt;div></tt> HtmlElement which represents a Grid row for the specified index.
    * @param {Number} index The row index
    * @return {HtmlElement} The div element.
    */
     getRow : function(row){
         return this.getRows()[row];
     },
 
-/**
- * Returns the grid's <tt>&lt;td></tt> HtmlElement at the specified coordinates.
- * @param {Number} row The row index in which to find the cell.
- * @param {Number} col The column index of the cell.
- * @return {HtmlElement} The td at the specified coordinates.
- */
+    /**
    * Returns the grid's <tt>&lt;td></tt> HtmlElement at the specified coordinates.
    * @param {Number} row The row index in which to find the cell.
    * @param {Number} col The column index of the cell.
    * @return {HtmlElement} The td at the specified coordinates.
    */
     getCell : function(row, col){
         return this.getRow(row).getElementsByTagName('td')[col];
     },
 
-/**
- * Return the <tt>&lt;td></tt> HtmlElement which represents the Grid's header cell for the specified column index.
- * @param {Number} index The column index
- * @return {HtmlElement} The td element.
- */
+    /**
    * Return the <tt>&lt;td></tt> HtmlElement which represents the Grid's header cell for the specified column index.
    * @param {Number} index The column index
    * @return {HtmlElement} The td element.
    */
     getHeaderCell : function(index){
       return this.mainHd.dom.getElementsByTagName('td')[index];
     },
@@ -60882,7 +62611,7 @@ viewConfig: {
     syncScroll : function(){
       this.syncHeaderScroll();
       var mb = this.scroller.dom;
-        this.grid.fireEvent("bodyscroll", mb.scrollLeft, mb.scrollTop);
+        this.grid.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop);
     },
 
     // private
@@ -60896,7 +62625,7 @@ viewConfig: {
     updateSortIcon : function(col, dir){
         var sc = this.sortClasses;
         var hds = this.mainHd.select('td').removeClass(sc);
-        hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
+        hds.item(col).addClass(sc[dir == 'DESC' ? 1 : 0]);
     },
 
     // private
@@ -60995,11 +62724,11 @@ viewConfig: {
                 c = cs[i];
                 p.id = c.id;
                 p.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
-                p.attr = p.cellAttr = "";
+                p.attr = p.cellAttr = '';
                 p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
                 p.style = c.style;
                 if(Ext.isEmpty(p.value)){
-                    p.value = "&#160;";
+                    p.value = '&#160;';
                 }
                 if(this.markDirty && r.dirty && typeof r.modified[c.name] !== 'undefined'){
                     p.css += ' x-grid3-dirty-cell';
@@ -61008,20 +62737,20 @@ viewConfig: {
             }
             var alt = [];
             if(stripe && ((rowIndex+1) % 2 === 0)){
-                alt[0] = "x-grid3-row-alt";
+                alt[0] = 'x-grid3-row-alt';
             }
             if(r.dirty){
-                alt[1] = " x-grid3-dirty-row";
+                alt[1] = ' x-grid3-dirty-row';
             }
             rp.cols = colCount;
             if(this.getRowClass){
                 alt[2] = this.getRowClass(r, rowIndex, rp, ds);
             }
-            rp.alt = alt.join(" ");
-            rp.cells = cb.join("");
+            rp.alt = alt.join(' ');
+            rp.cells = cb.join('');
             buf[buf.length] =  rt.apply(rp);
         }
-        return buf.join("");
+        return buf.join('');
     },
 
     // private
@@ -61034,11 +62763,13 @@ viewConfig: {
         startRow = startRow || 0;
         Ext.each(rows, function(row, idx){
             row.rowIndex = idx;
-            row.className = row.className.replace(this.rowClsRe, ' ');
-            if (!skipStripe && (idx + 1) % 2 === 0) {
-                row.className += ' x-grid3-row-alt';
+            if(!skipStripe){
+                row.className = row.className.replace(this.rowClsRe, ' ');
+                if ((idx + 1) % 2 === 0){
+                    row.className += ' x-grid3-row-alt';
+                }
             }
-        });
+        }, this);
         // add first/last-row classes
         if(startRow === 0){
             Ext.fly(rows[0]).addClass(this.firstRowCls);
@@ -61079,7 +62810,7 @@ viewConfig: {
         this.initElements();
 
         // get mousedowns early
-        Ext.fly(this.innerHd).on("click", this.handleHdDown, this);
+        Ext.fly(this.innerHd).on('click', this.handleHdDown, this);
         this.mainHd.on({
             scope: this,
             mouseover: this.handleHdOver,
@@ -61098,27 +62829,27 @@ viewConfig: {
         }
 
         if(g.enableHdMenu !== false){
-            this.hmenu = new Ext.menu.Menu({id: g.id + "-hctx"});
+            this.hmenu = new Ext.menu.Menu({id: g.id + '-hctx'});
             this.hmenu.add(
-                {itemId:"asc", text: this.sortAscText, cls: "xg-hmenu-sort-asc"},
-                {itemId:"desc", text: this.sortDescText, cls: "xg-hmenu-sort-desc"}
+                {itemId:'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'},
+                {itemId:'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'}
             );
             if(g.enableColumnHide !== false){
-                this.colMenu = new Ext.menu.Menu({id:g.id + "-hcols-menu"});
+                this.colMenu = new Ext.menu.Menu({id:g.id + '-hcols-menu'});
                 this.colMenu.on({
                     scope: this,
                     beforeshow: this.beforeColMenuShow,
                     itemclick: this.handleHdMenuClick
                 });
                 this.hmenu.add('-', {
-                    itemId:"columns",
+                    itemId:'columns',
                     hideOnClick: false,
                     text: this.columnsText,
                     menu: this.colMenu,
                     iconCls: 'x-cols-icon'
                 });
             }
-            this.hmenu.on("itemclick", this.handleHdMenuClick, this);
+            this.hmenu.on('itemclick', this.handleHdMenuClick, this);
         }
 
         if(g.trackMouseOver){
@@ -61224,7 +62955,11 @@ viewConfig: {
     
     // private 
     getOffsetWidth : function() {
-        return (this.cm.getTotalWidth() + this.scrollOffset) + 'px';
+        return (this.cm.getTotalWidth() + this.getScrollOffset()) + 'px';
+    },
+    
+    getScrollOffset: function(){
+        return Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
     },
 
     // private
@@ -61239,7 +62974,7 @@ viewConfig: {
             
         for(var i = 0; i < len; i++){
             p.id = cm.getColumnId(i);
-            p.value = cm.getColumnHeader(i) || "";
+            p.value = cm.getColumnHeader(i) || '';
             p.style = this.getColumnStyle(i, true);
             p.tooltip = this.getColumnTooltip(i);
             p.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
@@ -61250,7 +62985,7 @@ viewConfig: {
             }
             cb[cb.length] = ct.apply(p);
         }
-        return ts.header.apply({cells: cb.join(""), tstyle:'width:'+this.getTotalWidth()+';'});
+        return ts.header.apply({cells: cb.join(''), tstyle:'width:'+this.getTotalWidth()+';'});
     },
 
     // private
@@ -61263,7 +62998,7 @@ viewConfig: {
                 return 'title="'+tt+'"';
             }
         }
-        return "";
+        return '';
     },
 
     // private
@@ -61360,13 +63095,13 @@ viewConfig: {
             ctop += p.offsetTop;
             p = p.offsetParent;
         }
+        
         ctop -= this.mainHd.dom.offsetHeight;
-
+        stop = parseInt(c.scrollTop, 10);
+        
         var cbot = ctop + rowEl.offsetHeight,
             ch = c.clientHeight,
             sbot = stop + ch;
-            
-        stop = parseInt(c.scrollTop, 10);
         
 
         if(ctop < stop){
@@ -61397,7 +63132,7 @@ viewConfig: {
             this.refresh();
         }else{
             if(!isUpdate){
-                this.fireEvent("beforerowsinserted", this, firstRow, lastRow);
+                this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
             }
             var html = this.renderRows(firstRow, lastRow),
                 before = this.getRow(firstRow);
@@ -61414,7 +63149,7 @@ viewConfig: {
                 Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
             }
             if(!isUpdate){
-                this.fireEvent("rowsinserted", this, firstRow, lastRow);
+                this.fireEvent('rowsinserted', this, firstRow, lastRow);
                 this.processRows(firstRow);
             }else if(firstRow === 0 || firstRow >= last){
                 //ensure first/last row is kept after an update.
@@ -61429,12 +63164,12 @@ viewConfig: {
         if(dm.getRowCount()<1){
             this.refresh();
         }else{
-            this.fireEvent("beforerowsdeleted", this, firstRow, lastRow);
+            this.fireEvent('beforerowsdeleted', this, firstRow, lastRow);
 
             this.removeRows(firstRow, lastRow);
 
             this.processRows(firstRow);
-            this.fireEvent("rowsdeleted", this, firstRow, lastRow);
+            this.fireEvent('rowsdeleted', this, firstRow, lastRow);
         }
     },
 
@@ -61456,7 +63191,7 @@ viewConfig: {
     getColumnWidth : function(col){
         var w = this.cm.getColumnWidth(col);
         if(typeof w == 'number'){
-            return (Ext.isBorderBox ? w : (w-this.borderWidth > 0 ? w-this.borderWidth:0)) + 'px';
+            return (Ext.isBorderBox || (Ext.isWebKit && !Ext.isSafari2) ? w : (w - this.borderWidth > 0 ? w - this.borderWidth : 0)) + 'px';
         }
         return w;
     },
@@ -61470,7 +63205,7 @@ viewConfig: {
     fitColumns : function(preventRefresh, onlyExpand, omitColumn){
         var cm = this.cm, i;
         var tw = cm.getTotalWidth(false);
-        var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
+        var aw = this.grid.getGridEl().getWidth(true)-this.getScrollOffset();
 
         if(aw < 20){ // not initialized, so don't screw up the default widths
             return;
@@ -61527,7 +63262,7 @@ viewConfig: {
         var g = this.grid, cm = this.cm;
         if(!this.userResized && g.autoExpandColumn){
             var tw = cm.getTotalWidth(false);
-            var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
+            var aw = this.grid.getGridEl().getWidth(true)-this.getScrollOffset();
             if(tw != aw){
                 var ci = cm.getIndexById(g.autoExpandColumn);
                 var currentWidth = cm.getColumnWidth(ci);
@@ -61565,7 +63300,7 @@ viewConfig: {
         var colCount = cm.getColumnCount();
 
         if(ds.getCount() < 1){
-            return "";
+            return '';
         }
 
         var cs = this.getColumnData();
@@ -61603,7 +63338,7 @@ viewConfig: {
         this.insertRows(ds, index, index, true);
         this.getRow(index).rowIndex = index;
         this.onRemove(ds, record, index+1, true);
-        this.fireEvent("rowupdated", this, index, record);
+        this.fireEvent('rowupdated', this, index, record);
     },
 
     /**
@@ -61611,7 +63346,7 @@ viewConfig: {
      * @param {Boolean} headersToo (optional) True to also refresh the headers
      */
     refresh : function(headersToo){
-        this.fireEvent("beforerefresh", this);
+        this.fireEvent('beforerefresh', this);
         this.grid.stopEditing(true);
 
         var result = this.renderBody();
@@ -61623,7 +63358,7 @@ viewConfig: {
         this.processRows(0, true);
         this.layout();
         this.applyEmptyText();
-        this.fireEvent("refresh", this);
+        this.fireEvent('refresh', this);
     },
 
     // private
@@ -61662,41 +63397,75 @@ viewConfig: {
             this.hmenu.destroy();
             delete this.hmenu;
         }
+
+        this.initData(null, null);
+        this.purgeListeners();
+        Ext.fly(this.innerHd).un("click", this.handleHdDown, this);
+
         if(this.grid.enableColumnMove){
-            var dds = Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
-            if(dds){
-                for(var dd in dds){
-                    if(!dds[dd].config.isTarget && dds[dd].dragElId){
-                        var elid = dds[dd].dragElId;
-                        dds[dd].unreg();
-                        Ext.get(elid).remove();
-                    } else if(dds[dd].config.isTarget){
-                        dds[dd].proxyTop.remove();
-                        dds[dd].proxyBottom.remove();
-                        dds[dd].unreg();
-                    }
-                    if(Ext.dd.DDM.locationCache[dd]){
-                        delete Ext.dd.DDM.locationCache[dd];
-                    }
-                }
-                delete Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
+            Ext.destroy(
+                this.columnDrag.el,
+                this.columnDrag.proxy.ghost,
+                this.columnDrag.proxy.el,
+                this.columnDrop.el,
+                this.columnDrop.proxyTop,
+                this.columnDrop.proxyBottom,
+                this.columnDrag.dragData.ddel,
+                this.columnDrag.dragData.header
+            );
+            if (this.columnDrag.proxy.anim) {
+                Ext.destroy(this.columnDrag.proxy.anim);
             }
+            delete this.columnDrag.proxy.ghost;
+            delete this.columnDrag.dragData.ddel;
+            delete this.columnDrag.dragData.header;
+            this.columnDrag.destroy();
+            delete Ext.dd.DDM.locationCache[this.columnDrag.id];
+            delete this.columnDrag._domRef;
+
+            delete this.columnDrop.proxyTop;
+            delete this.columnDrop.proxyBottom;
+            this.columnDrop.destroy();
+            delete Ext.dd.DDM.locationCache["gridHeader" + this.grid.getGridEl().id];
+            delete this.columnDrop._domRef;
+            delete Ext.dd.DDM.ids[this.columnDrop.ddGroup];
         }
 
-        if(this.dragZone){
-            this.dragZone.unreg();
+        if (this.splitone){ // enableColumnResize
+            this.splitone.destroy();
+            delete this.splitone._domRef;
+            delete Ext.dd.DDM.ids["gridSplitters" + this.grid.getGridEl().id];
         }
-        
+
         Ext.fly(this.innerHd).removeAllListeners();
         Ext.removeNode(this.innerHd);
-        
-        Ext.destroy(this.resizeMarker, this.resizeProxy, this.focusEl, this.mainBody, 
-                    this.scroller, this.mainHd, this.mainWrap, this.dragZone, 
-                    this.splitZone, this.columnDrag, this.columnDrop);
+        delete this.innerHd;
+
+        Ext.destroy(
+            this.el,
+            this.mainWrap,
+            this.mainHd,
+            this.scroller,
+            this.mainBody,
+            this.focusEl,
+            this.resizeMarker,
+            this.resizeProxy,
+            this.activeHdBtn,
+            this.dragZone,
+            this.splitZone,
+            this._flyweight
+        );
+
+        delete this.grid.container;
+
+        if(this.dragZone){
+            this.dragZone.destroy();
+        }
+
+        Ext.dd.DDM.currentTarget = null;
+        delete Ext.dd.DDM.locationCache[this.grid.getGridEl().id];
 
-        this.initData(null, null);
         Ext.EventManager.removeResizeListener(this.onWindowResize, this);
-        this.purgeListeners();
     },
 
     // private
@@ -61729,12 +63498,12 @@ viewConfig: {
     // private
     initData : function(ds, cm){
         if(this.ds){
-            this.ds.un("load", this.onLoad, this);
-            this.ds.un("datachanged", this.onDataChange, this);
-            this.ds.un("add", this.onAdd, this);
-            this.ds.un("remove", this.onRemove, this);
-            this.ds.un("update", this.onUpdate, this);
-            this.ds.un("clear", this.onClear, this);
+            this.ds.un('load', this.onLoad, this);
+            this.ds.un('datachanged', this.onDataChange, this);
+            this.ds.un('add', this.onAdd, this);
+            this.ds.un('remove', this.onRemove, this);
+            this.ds.un('update', this.onUpdate, this);
+            this.ds.un('clear', this.onClear, this);
             if(this.ds !== ds && this.ds.autoDestroy){
                 this.ds.destroy();
             }
@@ -61753,11 +63522,11 @@ viewConfig: {
         this.ds = ds;
 
         if(this.cm){
-            this.cm.un("configchange", this.onColConfigChange, this);
-            this.cm.un("widthchange", this.onColWidthChange, this);
-            this.cm.un("headerchange", this.onHeaderChange, this);
-            this.cm.un("hiddenchange", this.onHiddenChange, this);
-            this.cm.un("columnmoved", this.onColumnMove, this);
+            this.cm.un('configchange', this.onColConfigChange, this);
+            this.cm.un('widthchange', this.onColWidthChange, this);
+            this.cm.un('headerchange', this.onHeaderChange, this);
+            this.cm.un('hiddenchange', this.onHiddenChange, this);
+            this.cm.un('columnmoved', this.onColumnMove, this);
         }
         if(cm){
             delete this.lastViewWidth;
@@ -61799,19 +63568,19 @@ viewConfig: {
     // private
     onRemove : function(ds, record, index, isUpdate){
         if(isUpdate !== true){
-            this.fireEvent("beforerowremoved", this, index, record);
+            this.fireEvent('beforerowremoved', this, index, record);
         }
         this.removeRow(index);
         if(isUpdate !== true){
             this.processRows(index);
             this.applyEmptyText();
-            this.fireEvent("rowremoved", this, index, record);
+            this.fireEvent('rowremoved', this, index, record);
         }
     },
 
     // private
     onLoad : function(){
-        this.scrollToTop();
+        this.scrollToTop.defer(Ext.isGecko ? 1 : 0, this);
     },
 
     // private
@@ -61849,7 +63618,7 @@ viewConfig: {
     /* -------------------- UI Events and Handlers ------------------------------ */
     // private
     initUI : function(grid){
-        grid.on("headerclick", this.onHeaderClick, this);
+        grid.on('headerclick', this.onHeaderClick, this);
     },
 
     // private
@@ -61869,7 +63638,7 @@ viewConfig: {
     onRowOver : function(e, t){
         var row;
         if((row = this.findRowIndex(t)) !== false){
-            this.addRowClass(row, "x-grid3-row-over");
+            this.addRowClass(row, 'x-grid3-row-over');
         }
     },
 
@@ -61877,7 +63646,7 @@ viewConfig: {
     onRowOut : function(e, t){
         var row;
         if((row = this.findRowIndex(t)) !== false && !e.within(this.getRow(row), true)){
-            this.removeRowClass(row, "x-grid3-row-over");
+            this.removeRowClass(row, 'x-grid3-row-over');
         }
     },
 
@@ -61900,7 +63669,7 @@ viewConfig: {
     onCellSelect : function(row, col){
         var cell = this.getCell(row, col);
         if(cell){
-            this.fly(cell).addClass("x-grid3-cell-selected");
+            this.fly(cell).addClass('x-grid3-cell-selected');
         }
     },
 
@@ -61908,7 +63677,7 @@ viewConfig: {
     onCellDeselect : function(row, col){
         var cell = this.getCell(row, col);
         if(cell){
-            this.fly(cell).removeClass("x-grid3-cell-selected");
+            this.fly(cell).removeClass('x-grid3-cell-selected');
         }
     },
 
@@ -61926,22 +63695,24 @@ viewConfig: {
             this.syncHeaderScroll();
         }
 
-        this.grid.fireEvent("columnresize", i, w);
+        this.grid.fireEvent('columnresize', i, w);
     },
 
     // private
     handleHdMenuClick : function(item){
-        var index = this.hdCtxIndex;
-        var cm = this.cm, ds = this.ds;
-        switch(item.itemId){
-            case "asc":
-                ds.sort(cm.getDataIndex(index), "ASC");
+        var index = this.hdCtxIndex,
+            cm = this.cm, 
+            ds = this.ds,
+            id = item.getItemId();
+        switch(id){
+            case 'asc':
+                ds.sort(cm.getDataIndex(index), 'ASC');
                 break;
-            case "desc":
-                ds.sort(cm.getDataIndex(index), "DESC");
+            case 'desc':
+                ds.sort(cm.getDataIndex(index), 'DESC');
                 break;
             default:
-                index = cm.getIndexById(item.itemId.substr(4));
+                index = cm.getIndexById(id.substr(4));
                 if(index != -1){
                     if(item.checked && cm.getColumnsBy(this.isHideableColumn, this).length <= 1){
                         this.onDenyColumnHide();
@@ -61965,7 +63736,7 @@ viewConfig: {
         for(var i = 0; i < colCount; i++){
             if(cm.config[i].fixed !== true && cm.config[i].hideable !== false){
                 this.colMenu.add(new Ext.menu.CheckItem({
-                    itemId: "col-"+cm.getColumnId(i),
+                    itemId: 'col-'+cm.getColumnId(i),
                     text: cm.getColumnHeader(i),
                     checked: !cm.isHidden(i),
                     hideOnClick:false,
@@ -61984,12 +63755,12 @@ viewConfig: {
             var index = this.getCellIndex(hd);
             this.hdCtxIndex = index;
             var ms = this.hmenu.items, cm = this.cm;
-            ms.get("asc").setDisabled(!cm.isSortable(index));
-            ms.get("desc").setDisabled(!cm.isSortable(index));
-            this.hmenu.on("hide", function(){
+            ms.get('asc').setDisabled(!cm.isSortable(index));
+            ms.get('desc').setDisabled(!cm.isSortable(index));
+            this.hmenu.on('hide', function(){
                 Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
             }, this, {single:true});
-            this.hmenu.show(t, "tl-bl?");
+            this.hmenu.show(t, 'tl-bl?');
         }
     },
 
@@ -61997,12 +63768,12 @@ viewConfig: {
     handleHdOver : function(e, t){
         var hd = this.findHeaderCell(t);
         if(hd && !this.headersDisabled){
-            this.activeHd = hd;
+            this.activeHdRef = t;
             this.activeHdIndex = this.getCellIndex(hd);
             var fly = this.fly(hd);
             this.activeHdRegion = fly.getRegion();
             if(!this.cm.isMenuDisabled(this.activeHdIndex)){
-                fly.addClass("x-grid3-hd-over");
+                fly.addClass('x-grid3-hd-over');
                 this.activeHdBtn = fly.child('.x-grid3-hd-btn');
                 if(this.activeHdBtn){
                     this.activeHdBtn.dom.style.height = (hd.firstChild.offsetHeight-1)+'px';
@@ -62013,18 +63784,21 @@ viewConfig: {
 
     // private
     handleHdMove : function(e, t){
-        if(this.activeHd && !this.headersDisabled){
-            var hw = this.splitHandleWidth || 5;
-            var r = this.activeHdRegion;
-            var x = e.getPageX();
-            var ss = this.activeHd.style;
-            if(x - r.left <= hw && this.cm.isResizable(this.activeHdIndex-1)){
-                ss.cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize'; // col-resize not always supported
-            }else if(r.right - x <= (!this.activeHdBtn ? hw : 2) && this.cm.isResizable(this.activeHdIndex)){
-                ss.cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
-            }else{
-                ss.cursor = '';
+        var hd = this.findHeaderCell(this.activeHdRef);
+        if(hd && !this.headersDisabled){
+            var hw = this.splitHandleWidth || 5,
+                r = this.activeHdRegion,
+                x = e.getPageX(),
+                ss = hd.style,
+                cur = '';
+            if(this.grid.enableColumnResize !== false){
+                if(x - r.left <= hw && this.cm.isResizable(this.activeHdIndex-1)){
+                    cur = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize'; // col-resize not always supported
+                }else if(r.right - x <= (!this.activeHdBtn ? hw : 2) && this.cm.isResizable(this.activeHdIndex)){
+                    cur = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
+                }
             }
+            ss.cursor = cur;
         }
     },
 
@@ -62032,8 +63806,8 @@ viewConfig: {
     handleHdOut : function(e, t){
         var hd = this.findHeaderCell(t);
         if(hd && (!Ext.isIE || !e.within(hd, true))){
-            this.activeHd = null;
-            this.fly(hd).removeClass("x-grid3-hd-over");
+            this.activeHdRef = null;
+            this.fly(hd).removeClass('x-grid3-hd-over');
             hd.style.cursor = '';
         }
     },
@@ -62059,7 +63833,7 @@ Ext.grid.GridView.SplitDragZone = function(grid, hd){
     this.marker = this.view.resizeMarker;
     this.proxy = this.view.resizeProxy;
     Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
-        "gridSplitters" + this.grid.getGridEl().id, {
+        'gridSplitters' + this.grid.getGridEl().id, {
         dragElId : Ext.id(this.proxy.dom), resizeFrame:false
     });
     this.scroll = false;
@@ -62308,7 +64082,6 @@ Ext.extend(Ext.grid.HeaderDropZone, Ext.dd.DropZone, {
                 newIndex--;\r
             }\r
             cm.moveColumn(oldIndex, newIndex);\r
-            this.grid.fireEvent("columnmove", oldIndex, newIndex);\r
             return true;\r
         }\r
         return false;\r
@@ -62504,7 +64277,7 @@ Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
  * {@link Ext.grid.Column} column configuration object within the specified Array defines the initial
  * order of the column display.  A Column's display may be initially hidden using the
  * <tt>{@link Ext.grid.Column#hidden hidden}</tt></b> config property (and then shown using the column
- * header menu).  Field's that are not included in the ColumnModel will not be displayable at all.</p>
+ * header menu).  Fields that are not included in the ColumnModel will not be displayable at all.</p>
  * <p>How each column in the grid correlates (maps) to the {@link Ext.data.Record} field in the
  * {@link Ext.data.Store Store} the column draws its data from is configured through the
  * <b><tt>{@link Ext.grid.Column#dataIndex dataIndex}</tt></b>.  If the
@@ -62683,12 +64456,16 @@ Ext.extend(Ext.grid.ColumnModel, Ext.util.Observable, {
 
         this.config = config;
         this.lookup = {};
-        // if no id, create one
+
         for(i = 0, len = config.length; i < len; i++){
             c = Ext.applyIf(config[i], this.defaults);
+            // if no id, create one using column's ordinal position
+            if(typeof c.id == 'undefined'){
+                c.id = i;
+            }
             if(!c.isColumn){
-                var cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
-                c = new cls(c);
+                var Cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
+                c = new Cls(c);
                 config[i] = c;
             }
             this.lookup[c.id] = c;
@@ -62782,7 +64559,7 @@ var columns = grid.getColumnModel().getColumnsBy(function(c){
      * @return {Boolean}
      */
     isSortable : function(col){
-        return this.config[col].sortable;
+        return !!this.config[col].sortable;
     },
 
     /**
@@ -62989,22 +64766,24 @@ var grid = new Ext.grid.GridPanel({
         this.config[col].editable = editable;
     },
 
-
     /**
-     * Returns true if the column is hidden.
+     * Returns <tt>true</tt> if the column is <code>{@link Ext.grid.Column#hidden hidden}</code>,
+     * <tt>false</tt> otherwise.
      * @param {Number} colIndex The column index
      * @return {Boolean}
      */
     isHidden : function(colIndex){
-        return this.config[colIndex].hidden;
+        return !!this.config[colIndex].hidden; // ensure returns boolean
     },
 
-
     /**
-     * Returns true if the column width cannot be changed
+     * Returns <tt>true</tt> if the column is <code>{@link Ext.grid.Column#fixed fixed}</code>,
+     * <tt>false</tt> otherwise.
+     * @param {Number} colIndex The column index
+     * @return {Boolean}
      */
     isFixed : function(colIndex){
-        return this.config[colIndex].fixed;
+        return !!this.config[colIndex].fixed;
     },
 
     /**
@@ -63133,7 +64912,7 @@ Ext.grid.RowSelectionModel = function(config){
          * Fires when the selection changes
          * @param {SelectionModel} this
          */
-        "selectionchange",
+        'selectionchange',
         /**
          * @event beforerowselect
          * Fires before a row is selected, return false to cancel the selection.
@@ -63142,7 +64921,7 @@ Ext.grid.RowSelectionModel = function(config){
          * @param {Boolean} keepExisting False if other selections will be cleared
          * @param {Record} record The record to be selected
          */
-        "beforerowselect",
+        'beforerowselect',
         /**
          * @event rowselect
          * Fires when a row is selected.
@@ -63150,7 +64929,7 @@ Ext.grid.RowSelectionModel = function(config){
          * @param {Number} rowIndex The selected index
          * @param {Ext.data.Record} r The selected record
          */
-        "rowselect",
+        'rowselect',
         /**
          * @event rowdeselect
          * Fires when a row is deselected.  To prevent deselection
@@ -63159,7 +64938,7 @@ Ext.grid.RowSelectionModel = function(config){
          * @param {Number} rowIndex
          * @param {Record} record
          */
-        "rowdeselect"
+        'rowdeselect'
     );
 
     Ext.grid.RowSelectionModel.superclass.constructor.call(this);
@@ -63182,18 +64961,11 @@ Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel,  {
     initEvents : function(){
 
         if(!this.grid.enableDragDrop && !this.grid.enableDrag){
-            this.grid.on("rowmousedown", this.handleMouseDown, this);
-        }else{ // allow click to work like normal
-            this.grid.on("rowclick", function(grid, rowIndex, e) {
-                if(e.button === 0 && !e.shiftKey && !e.ctrlKey) {
-                    this.selectRow(rowIndex, false);
-                    grid.view.focusRow(rowIndex);
-                }
-            }, this);
+            this.grid.on('rowmousedown', this.handleMouseDown, this);
         }
 
         this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
-            "up" : function(e){
+            'up' : function(e){
                 if(!e.shiftKey || this.singleSelect){
                     this.selectPrevious(false);
                 }else if(this.last !== false && this.lastActive !== false){
@@ -63207,7 +64979,7 @@ Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel,  {
                     this.selectFirstRow();
                 }
             },
-            "down" : function(e){
+            'down' : function(e){
                 if(!e.shiftKey || this.singleSelect){
                     this.selectNext(false);
                 }else if(this.last !== false && this.lastActive !== false){
@@ -63224,10 +64996,12 @@ Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel,  {
             scope: this
         });
 
-        var view = this.grid.view;
-        view.on("refresh", this.onRefresh, this);
-        view.on("rowupdated", this.onRowUpdated, this);
-        view.on("rowremoved", this.onRemove, this);
+        this.grid.getView().on({
+            scope: this,
+            refresh: this.onRefresh,
+            rowupdated: this.onRowUpdated,
+            rowremoved: this.onRemove
+        });
     },
 
     // private
@@ -63242,7 +65016,7 @@ Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel,  {
             }
         }
         if(s.length != this.selections.getCount()){
-            this.fireEvent("selectionchange", this);
+            this.fireEvent('selectionchange', this);
         }
     },
 
@@ -63429,7 +65203,7 @@ Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel,  {
      * @return {Boolean}
      */
     isSelected : function(index){
-        var r = typeof index == "number" ? this.grid.store.getAt(index) : index;
+        var r = Ext.isNumber(index) ? this.grid.store.getAt(index) : index;
         return (r && this.selections.key(r.id) ? true : false);
     },
 
@@ -63538,7 +65312,7 @@ Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel,  {
             return;
         }
         var r = this.grid.store.getAt(index);
-        if(r && this.fireEvent("beforerowselect", this, index, keepExisting, r) !== false){
+        if(r && this.fireEvent('beforerowselect', this, index, keepExisting, r) !== false){
             if(!keepExisting || this.singleSelect){
                 this.clearSelections();
             }
@@ -63547,8 +65321,8 @@ Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel,  {
             if(!preventViewNotify){
                 this.grid.getView().onRowSelect(index);
             }
-            this.fireEvent("rowselect", this, index, r);
-            this.fireEvent("selectionchange", this);
+            this.fireEvent('rowselect', this, index, r);
+            this.fireEvent('selectionchange', this);
         }
     },
 
@@ -63577,8 +65351,8 @@ Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel,  {
             if(!preventViewNotify){
                 this.grid.getView().onRowDeselect(index);
             }
-            this.fireEvent("rowdeselect", this, index, r);
-            this.fireEvent("selectionchange", this);
+            this.fireEvent('rowdeselect', this, index, r);
+            this.fireEvent('selectionchange', this);
         }
     },
 
@@ -63596,7 +65370,12 @@ Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel,  {
 
     // private
     onEditorKey : function(field, e){
-        var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
+        var k = e.getKey(), 
+            newCell, 
+            g = this.grid, 
+            last = g.lastEdit,
+            ed = g.activeEditor,
+            ae, last, r, c;
         var shift = e.shiftKey;
         if(k == e.TAB){
             e.stopEvent();
@@ -63607,24 +65386,34 @@ Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel,  {
                 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
             }
         }else if(k == e.ENTER){
-            e.stopEvent();
-            ed.completeEdit();
             if(this.moveEditorOnEnter !== false){
                 if(shift){
-                    newCell = g.walkCells(ed.row - 1, ed.col, -1, this.acceptsNav, this);
+                    newCell = g.walkCells(last.row - 1, last.col, -1, this.acceptsNav, this);
                 }else{
-                    newCell = g.walkCells(ed.row + 1, ed.col, 1, this.acceptsNav, this);
+                    newCell = g.walkCells(last.row + 1, last.col, 1, this.acceptsNav, this);
                 }
             }
-        }else if(k == e.ESC){
-            ed.cancelEdit();
         }
         if(newCell){
-            g.startEditing(newCell[0], newCell[1]);
+            r = newCell[0];
+            c = newCell[1];
+
+            if(last.row != r){
+                this.selectRow(r); // *** highlight newly-selected cell and update selection
+            }
+
+            if(g.isEditor && g.editing){ // *** handle tabbing while editorgrid is in edit mode
+                ae = g.activeEditor;
+                if(ae && ae.field.triggerBlur){
+                    // *** if activeEditor is a TriggerField, explicitly call its triggerBlur() method
+                    ae.field.triggerBlur();
+                }
+            }
+            g.startEditing(r, c);
         }
     },
     
-    destroy: function(){
+    destroy : function(){
         if(this.rowNav){
             this.rowNav.disable();
             this.rowNav = null;
@@ -63641,7 +65430,7 @@ Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel,  {
 Ext.grid.Column = function(config){\r
     Ext.apply(this, config);\r
 \r
-    if(typeof this.renderer == 'string'){\r
+    if(Ext.isString(this.renderer)){\r
         this.renderer = Ext.util.Format[this.renderer];\r
     } else if(Ext.isObject(this.renderer)){\r
         this.scope = this.renderer.scope;\r
@@ -63649,16 +65438,11 @@ Ext.grid.Column = function(config){
     }\r
     this.renderer = this.renderer.createDelegate(this.scope || config);\r
 \r
-    if(this.id === undefined){\r
-        this.id = ++Ext.grid.Column.AUTO_ID;\r
-    }\r
     if(this.editor){\r
         this.editor = Ext.create(this.editor, 'textfield');\r
     }\r
 };\r
 \r
-Ext.grid.Column.AUTO_ID = 0;\r
-\r
 Ext.grid.Column.prototype = {\r
     /**\r
      * @cfg {Boolean} editable Optional. Defaults to <tt>true</tt>, enabling the configured\r
@@ -63743,8 +65527,8 @@ Ext.grid.Column.prototype = {
      */\r
     /**\r
      * @cfg {Boolean} sortable Optional. <tt>true</tt> if sorting is to be allowed on this column.\r
-     * Defaults to the value of the {@link #defaultSortable} property.\r
-     * Whether local/remote sorting is used is specified in {@link Ext.data.Store#remoteSort}.\r
+     * Defaults to the value of the <code>{@link Ext.grid.ColumnModel#defaultSortable}</code> property.\r
+     * Whether local/remote sorting is used is specified in <code>{@link Ext.data.Store#remoteSort}</code>.\r
      */\r
     /**\r
      * @cfg {Boolean} fixed Optional. <tt>true</tt> if the column width cannot be changed.  Defaults to <tt>false</tt>.\r
@@ -63756,7 +65540,10 @@ Ext.grid.Column.prototype = {
      * @cfg {Boolean} menuDisabled Optional. <tt>true</tt> to disable the column menu. Defaults to <tt>false</tt>.\r
      */\r
     /**\r
-     * @cfg {Boolean} hidden Optional. <tt>true</tt> to hide the column. Defaults to <tt>false</tt>.\r
+     * @cfg {Boolean} hidden\r
+     * Optional. <tt>true</tt> to initially hide this column. Defaults to <tt>false</tt>.\r
+     * A hidden column {@link Ext.grid.GridPanel#enableColumnHide may be shown via the header row menu}.\r
+     * If a column is never to be shown, simply do not include this column in the Column Model at all. \r
      */\r
     /**\r
      * @cfg {String} tooltip Optional. A text string to use as the column header's tooltip.  If Quicktips\r
@@ -63853,8 +65640,15 @@ var grid = new Ext.grid.GridPanel({
      * if editing is supported by the grid. See <tt>{@link #editable}</tt> also.\r
      */\r
 \r
-    // private. Used by ColumnModel to avoid reprocessing\r
+    /**\r
+     * @private\r
+     * @cfg {Boolean} isColumn\r
+     * Used by ColumnModel setConfig method to avoid reprocessing a Column\r
+     * if <code>isColumn</code> is not set ColumnModel will recreate a new Ext.grid.Column\r
+     * Defaults to true.\r
+     */\r
     isColumn : true,\r
+\r
     /**\r
      * Optional. A function which returns displayable data when passed the following parameters:\r
      * <div class="mdetail-params"><ul>\r
@@ -63874,7 +65668,7 @@ var grid = new Ext.grid.GridPanel({
      * @type Function\r
      */\r
     renderer : function(value){\r
-        if(typeof value == 'string' && value.length < 1){\r
+        if(Ext.isString(value) && value.length < 1){\r
             return '&#160;';\r
         }\r
         return value;\r
@@ -63910,8 +65704,8 @@ var grid = new Ext.grid.GridPanel({
 /**\r
  * @class Ext.grid.BooleanColumn\r
  * @extends Ext.grid.Column\r
- * <p>A Column definition class which renders boolean data fields.  See the {@link Ext.grid.ColumnModel#xtype xtype}\r
- * config option of {@link Ext.grid.ColumnModel} for more details.</p>\r
+ * <p>A Column definition class which renders boolean data fields.  See the {@link Ext.grid.Column#xtype xtype}\r
+ * config option of {@link Ext.grid.Column} for more details.</p>\r
  */\r
 Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, {\r
     /**\r
@@ -63950,7 +65744,7 @@ Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, {
  * @class Ext.grid.NumberColumn\r
  * @extends Ext.grid.Column\r
  * <p>A Column definition class which renders a numeric data field according to a {@link #format} string.  See the\r
- * {@link Ext.grid.ColumnModel#xtype xtype} config option of {@link Ext.grid.ColumnModel} for more details.</p>\r
+ * {@link Ext.grid.Column#xtype xtype} config option of {@link Ext.grid.Column} for more details.</p>\r
  */\r
 Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, {\r
     /**\r
@@ -63969,7 +65763,7 @@ Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, {
  * @class Ext.grid.DateColumn\r
  * @extends Ext.grid.Column\r
  * <p>A Column definition class which renders a passed date according to the default locale, or a configured\r
- * {@link #format}. See the {@link Ext.grid.ColumnModel#xtype xtype} config option of {@link Ext.grid.ColumnModel}\r
+ * {@link #format}. See the {@link Ext.grid.Column#xtype xtype} config option of {@link Ext.grid.Column}\r
  * for more details.</p>\r
  */\r
 Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, {\r
@@ -63990,7 +65784,7 @@ Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, {
  * @extends Ext.grid.Column\r
  * <p>A Column definition class which renders a value by processing a {@link Ext.data.Record Record}'s\r
  * {@link Ext.data.Record#data data} using a {@link #tpl configured} {@link Ext.XTemplate XTemplate}.\r
- * See the {@link Ext.grid.ColumnModel#xtype xtype} config option of {@link Ext.grid.ColumnModel} for more\r
+ * See the {@link Ext.grid.Column#xtype xtype} config option of {@link Ext.grid.Column} for more\r
  * details.</p>\r
  */\r
 Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, {\r
@@ -64001,7 +65795,7 @@ Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, {
      */\r
     constructor: function(cfg){\r
         Ext.grid.TemplateColumn.superclass.constructor.call(this, cfg);\r
-        var tpl = typeof Ext.isObject(this.tpl) ? this.tpl : new Ext.XTemplate(this.tpl);\r
+        var tpl = Ext.isObject(this.tpl) ? this.tpl : new Ext.XTemplate(this.tpl);\r
         this.renderer = function(value, p, r){\r
             return tpl.apply(r.data);\r
         };\r
@@ -64108,24 +65902,24 @@ Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
      * <tt>'Select Rows'</tt>), but the automatic check all/none behavior will only work if the\r
      * <tt>'x-grid3-hd-checker'</tt> class is supplied.\r
      */\r
-    header: '<div class="x-grid3-hd-checker">&#160;</div>',\r
+    header : '<div class="x-grid3-hd-checker">&#160;</div>',\r
     /**\r
      * @cfg {Number} width The default width in pixels of the checkbox column (defaults to <tt>20</tt>).\r
      */\r
-    width: 20,\r
+    width : 20,\r
     /**\r
      * @cfg {Boolean} sortable <tt>true</tt> if the checkbox column is sortable (defaults to\r
      * <tt>false</tt>).\r
      */\r
-    sortable: false,\r
+    sortable : false,\r
 \r
     // private\r
-    menuDisabled:true,\r
-    fixed:true,\r
-    dataIndex: '',\r
-    id: 'checker',\r
+    menuDisabled : true,\r
+    fixed : true,\r
+    dataIndex : '',\r
+    id : 'checker',\r
 \r
-    constructor: function(){\r
+    constructor : function(){\r
         Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this, arguments);\r
 \r
         if(this.checkOnly){\r
@@ -64236,15 +66030,17 @@ Ext.extend(Ext.grid.CellSelectionModel, Ext.grid.AbstractSelectionModel,  {
 
     /** @ignore */
     initEvents : function(){
-        this.grid.on("cellmousedown", this.handleMouseDown, this);
-        this.grid.getGridEl().on(Ext.EventManager.useKeydown ? "keydown" : "keypress", this.handleKeyDown, this);
-        var view = this.grid.view;
-        view.on("refresh", this.onViewChange, this);
-        view.on("rowupdated", this.onRowUpdated, this);
-        view.on("beforerowremoved", this.clearSelections, this);
-        view.on("beforerowsinserted", this.clearSelections, this);
+        this.grid.on('cellmousedown', this.handleMouseDown, this);
+        this.grid.on(Ext.EventManager.useKeydown ? 'keydown' : 'keypress', this.handleKeyDown, this);
+        this.grid.getView().on({
+            scope: this,
+            refresh: this.onViewChange,
+            rowupdated: this.onRowUpdated,
+            beforerowremoved: this.clearSelections,
+            beforerowsinserted: this.clearSelections
+        });
         if(this.grid.isEditor){
-            this.grid.on("beforeedit", this.beforeEdit,  this);
+            this.grid.on('beforeedit', this.beforeEdit,  this);
         }
     },
 
@@ -64355,85 +66151,107 @@ var data = record.get(fieldName);
     isSelectable : function(rowIndex, colIndex, cm){
         return !cm.isHidden(colIndex);
     },
+    
+    // private
+    onEditorKey: function(field, e){
+        if(e.getKey() == e.TAB){
+            this.handleKeyDown(e);
+        }
+    },
 
     /** @ignore */
     handleKeyDown : function(e){
         if(!e.isNavKeyPress()){
             return;
         }
-        var g = this.grid, s = this.selection;
+        
+        var k = e.getKey(),
+            g = this.grid,
+            s = this.selection,
+            sm = this,
+            walk = function(row, col, step){
+                return g.walkCells(
+                    row,
+                    col,
+                    step,
+                    g.isEditor && g.editing ? sm.acceptsNav : sm.isSelectable, // *** handle tabbing while editorgrid is in edit mode
+                    sm
+                );
+            },
+            cell, newCell, r, c, ae;
+
+        switch(k){
+            case e.ESC:
+            case e.PAGE_UP:
+            case e.PAGE_DOWN:
+                // do nothing
+                break;
+            default:
+                // *** call e.stopEvent() only for non ESC, PAGE UP/DOWN KEYS
+                e.stopEvent();
+                break;
+        }
+
         if(!s){
-            e.stopEvent();
-            var cell = g.walkCells(0, 0, 1, this.isSelectable,  this);
+            cell = walk(0, 0, 1); // *** use private walk() function defined above
             if(cell){
                 this.select(cell[0], cell[1]);
             }
             return;
         }
-        var sm = this;
-        var walk = function(row, col, step){
-            return g.walkCells(row, col, step, sm.isSelectable,  sm);
-        };
-        var k = e.getKey(), r = s.cell[0], c = s.cell[1];
-        var newCell;
 
+        cell = s.cell;  // currently selected cell
+        r = cell[0];    // current row
+        c = cell[1];    // current column
+        
         switch(k){
-             case e.TAB:
-                 if(e.shiftKey){
-                     newCell = walk(r, c-1, -1);
-                 }else{
-                     newCell = walk(r, c+1, 1);
-                 }
-             break;
-             case e.DOWN:
-                 newCell = walk(r+1, c, 1);
-             break;
-             case e.UP:
-                 newCell = walk(r-1, c, -1);
-             break;
-             case e.RIGHT:
-                 newCell = walk(r, c+1, 1);
-             break;
-             case e.LEFT:
-                 newCell = walk(r, c-1, -1);
-             break;
-             case e.ENTER:
-                 if(g.isEditor && !g.editing){
+            case e.TAB:
+                if(e.shiftKey){
+                    newCell = walk(r, c - 1, -1);
+                }else{
+                    newCell = walk(r, c + 1, 1);
+                }
+                break;
+            case e.DOWN:
+                newCell = walk(r + 1, c, 1);
+                break;
+            case e.UP:
+                newCell = walk(r - 1, c, -1);
+                break;
+            case e.RIGHT:
+                newCell = walk(r, c + 1, 1);
+                break;
+            case e.LEFT:
+                newCell = walk(r, c - 1, -1);
+                break;
+            case e.ENTER:
+                if (g.isEditor && !g.editing) {
                     g.startEditing(r, c);
-                    e.stopEvent();
                     return;
                 }
-             break;
+                break;
         }
+
         if(newCell){
-            this.select(newCell[0], newCell[1]);
-            e.stopEvent();
+            // *** reassign r & c variables to newly-selected cell's row and column
+            r = newCell[0];
+            c = newCell[1];
+
+            this.select(r, c); // *** highlight newly-selected cell and update selection
+
+            if(g.isEditor && g.editing){ // *** handle tabbing while editorgrid is in edit mode
+                ae = g.activeEditor;
+                if(ae && ae.field.triggerBlur){
+                    // *** if activeEditor is a TriggerField, explicitly call its triggerBlur() method
+                    ae.field.triggerBlur();
+                }
+                g.startEditing(r, c);
+            }
         }
     },
 
     acceptsNav : function(row, col, cm){
         return !cm.isHidden(col) && cm.isCellEditable(col, row);
-    },
-
-    onEditorKey : function(field, e){
-        var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
-        if(k == e.TAB){
-            if(e.shiftKey){
-                newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
-            }else{
-                newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
-            }
-            e.stopEvent();
-        }else if(k == e.ENTER){
-            ed.completeEdit();
-            e.stopEvent();
-        }else if(k == e.ESC){
-               e.stopEvent();
-            ed.cancelEdit();
-        }
-        if(newCell){
-            g.startEditing(newCell[0], newCell[1]);
-        }
     }
 });/**
  * @class Ext.grid.EditorGridPanel
@@ -64582,16 +66400,17 @@ grid.on('validateedit', function(e) {
     initEvents : function(){
         Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
 
-        this.on("bodyscroll", this.stopEditing, this, [true]);
-        this.on("columnresize", this.stopEditing, this, [true]);
+        this.getGridEl().on('mousewheel', this.stopEditing.createDelegate(this, [true]), this);
+        this.on('columnresize', this.stopEditing, this, [true]);
 
         if(this.clicksToEdit == 1){
             this.on("cellclick", this.onCellDblClick, this);
         }else {
-            if(this.clicksToEdit == 'auto' && this.view.mainBody){
-                this.view.mainBody.on("mousedown", this.onAutoEditClick, this);
+            var view = this.getView();
+            if(this.clicksToEdit == 'auto' && view.mainBody){
+                view.mainBody.on('mousedown', this.onAutoEditClick, this);
             }
-            this.on("celldblclick", this.onCellDblClick, this);
+            this.on('celldblclick', this.onCellDblClick, this);
         }
     },
 
@@ -64626,7 +66445,7 @@ grid.on('validateedit', function(e) {
     onEditComplete : function(ed, value, startValue){
         this.editing = false;
         this.activeEditor = null;
-        ed.un("specialkey", this.selModel.onEditorKey, this.selModel);
+        
                var r = ed.record;
         var field = this.colModel.getDataIndex(ed.col);
         value = this.postEditValue(value, startValue, r, field);
@@ -64677,22 +66496,35 @@ grid.on('validateedit', function(e) {
                     return;
                 }
                 if(!ed.rendered){
-                    ed.render(this.view.getEditorParent(ed));
+                    ed.parentEl = this.view.getEditorParent(ed);
+                    ed.on({
+                        scope: this,
+                        render: {
+                            fn: function(c){
+                                c.field.focus(false, true);
+                            },
+                            single: true,
+                            scope: this
+                        },
+                        specialkey: function(field, e){
+                            this.getSelectionModel().onEditorKey(field, e);
+                        },
+                        complete: this.onEditComplete,
+                        canceledit: this.stopEditing.createDelegate(this, [true])
+                    });
                 }
-                (function(){ // complex but required for focus issues in safari, ie and opera
-                    ed.row = row;
-                    ed.col = col;
-                    ed.record = r;
-                    ed.on("complete", this.onEditComplete, this, {single: true});
-                    ed.on("specialkey", this.selModel.onEditorKey, this.selModel);
-                    /**
-                     * The currently active editor or null
-                      * @type Ext.Editor
-                     */
-                    this.activeEditor = ed;
-                    var v = this.preEditValue(r, field);
-                    ed.startEdit(this.view.getCell(row, col).firstChild, v === undefined ? '' : v);
-                }).defer(50, this);
+                Ext.apply(ed, {
+                    row     : row,
+                    col     : col,
+                    record  : r
+                });
+                this.lastEdit = {
+                    row: row,
+                    col: col
+                };
+                this.activeEditor = ed;
+                var v = this.preEditValue(r, field);
+                ed.startEdit(this.view.getCell(row, col).firstChild, Ext.isDefined(v) ? v : '');
             }
         }
     },
@@ -64700,12 +66532,12 @@ grid.on('validateedit', function(e) {
     // private
     preEditValue : function(r, field){
         var value = r.data[field];
-        return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlDecode(value) : value;
+        return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlDecode(value) : value;
     },
 
     // private
        postEditValue : function(value, originalValue, r, field){
-               return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlEncode(value) : value;
+               return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlEncode(value) : value;
        },
 
     /**
@@ -64713,10 +66545,15 @@ grid.on('validateedit', function(e) {
      * @param {Boolean} cancel (optional) True to cancel any changes
      */
     stopEditing : function(cancel){
-        if(this.activeEditor){
-            this.activeEditor[cancel === true ? 'cancelEdit' : 'completeEdit']();
+        if(this.editing){
+            var ae = this.activeEditor;
+            if(ae){
+                ae[cancel === true ? 'cancelEdit' : 'completeEdit']();
+                this.view.focusCell(ae.row, ae.col);
+            }
+            this.activeEditor = null;
         }
-        this.activeEditor = null;
+        this.editing = false;
     }
 });
 Ext.reg('editorgrid', Ext.grid.EditorGridPanel);// private
@@ -64857,14 +66694,16 @@ Ext.grid.PropertyColumnModel = function(grid, store){
             {tag: 'option', value: 'false', html: 'false'}
         ]},
         getValue : function(){
-            return this.el.value == 'true';
+            return this.el.dom.value == 'true';
         }
     });
     this.editors = {
         'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})),
         'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})),
         'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})),
-        'boolean' : new g.GridEditor(bfield)
+        'boolean' : new g.GridEditor(bfield, {
+            autoSize: 'both'
+        })
     };
     this.renderCellDelegate = this.renderCell.createDelegate(this);
     this.renderPropDelegate = this.renderProp.createDelegate(this);
@@ -65232,6 +67071,13 @@ var grid = new Ext.grid.GridPanel({
      * </code></pre>\r
      */\r
     groupTextTpl : '{text}',\r
+    \r
+    /**\r
+     * @cfg {String} groupMode Indicates how to construct the group identifier. <tt>'value'</tt> constructs the id using\r
+     * raw value, <tt>'display'</tt> constructs the id using the rendered value. Defaults to <tt>'value'</tt>.\r
+     */\r
+    groupMode: 'value',\r
+    \r
     /**\r
      * @cfg {Function} groupRenderer This property must be configured in the {@link Ext.grid.Column} for\r
      * each column.\r
@@ -65408,7 +67254,7 @@ var grid = new Ext.grid.GridPanel({
     // private\r
     getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){\r
         var g = groupRenderer ? groupRenderer(v, {}, r, rowIndex, colIndex, ds) : String(v);\r
-        if(g === ''){\r
+        if(g === '' || g === '&#160;'){\r
             g = this.cm.config[colIndex].emptyGroupText || this.emptyGroupText;\r
         }\r
         return g;\r
@@ -65468,15 +67314,14 @@ var grid = new Ext.grid.GridPanel({
             return Ext.grid.GroupingView.superclass.doRender.apply(\r
                     this, arguments);\r
         }\r
-        var gstyle = 'width:'+this.getTotalWidth()+';';\r
+        var gstyle = 'width:' + this.getTotalWidth() + ';',\r
+            gidPrefix = this.grid.getGridEl().id,\r
+            cfg = this.cm.config[colIndex],\r
+            groupRenderer = cfg.groupRenderer || cfg.renderer,\r
+            prefix = this.showGroupName ? (cfg.groupName || cfg.header)+': ' : '',\r
+            groups = [],\r
+            curGroup, i, len, gid;\r
 \r
-        var gidPrefix = this.grid.getGridEl().id;\r
-        var cfg = this.cm.config[colIndex];\r
-        var groupRenderer = cfg.groupRenderer || cfg.renderer;\r
-        var prefix = this.showGroupName ?\r
-                     (cfg.groupName || cfg.header)+': ' : '';\r
-\r
-        var groups = [], curGroup, i, len, gid;\r
         for(i = 0, len = rs.length; i < len; i++){\r
             var rowIndex = startRow + i,\r
                 r = rs[i],\r
@@ -65484,7 +67329,7 @@ var grid = new Ext.grid.GridPanel({
                 \r
                 g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);\r
             if(!curGroup || curGroup.group != g){\r
-                gid = gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(g);\r
+                gid = this.constructId(gvalue, gidPrefix, groupField, colIndex);\r
                        // if state is defined use it, however state is in terms of expanded\r
                                // so negate it, otherwise use the default.\r
                                var isCollapsed  = typeof this.state[gid] !== 'undefined' ? !this.state[gid] : this.startCollapsed;\r
@@ -65524,13 +67369,17 @@ var grid = new Ext.grid.GridPanel({
      * @return {String} The group id\r
      */\r
     getGroupId : function(value){\r
-        var gidPrefix = this.grid.getGridEl().id;\r
-        var groupField = this.getGroupField();\r
-        var colIndex = this.cm.findColumnIndex(groupField);\r
-        var cfg = this.cm.config[colIndex];\r
-        var groupRenderer = cfg.groupRenderer || cfg.renderer;\r
-        var gtext = this.getGroup(value, {data:{}}, groupRenderer, 0, colIndex, this.ds);\r
-        return gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(value);\r
+        var field = this.getGroupField();\r
+        return this.constructId(value, this.grid.getGridEl().id, field, this.cm.findColumnIndex(field));\r
+    },\r
+    \r
+    // private\r
+    constructId : function(value, prefix, field, idx){\r
+        var cfg = this.cm.config[idx],\r
+            groupRenderer = cfg.groupRenderer || cfg.renderer,\r
+            val = (this.groupMode == 'value') ? value : this.getGroup(value, {data:{}}, groupRenderer, 0, idx, this.ds);\r
+            \r
+        return prefix + '-gp-' + field + '-' + Ext.util.Format.htmlEncode(val);\r
     },\r
 \r
     // private\r
@@ -65564,7 +67413,7 @@ var grid = new Ext.grid.GridPanel({
         if(!this.enableGrouping || !this.hasRows()){\r
             return;\r
         }\r
-        var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.scrollOffset) +'px';\r
+        var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.getScrollOffset()) +'px';\r
         var gs = this.getGroups();\r
         for(var i = 0, len = gs.length; i < len; i++){\r
             gs[i].firstChild.style.width = tw;\r