Merge mozilla-central to tracemonkey.
authorRobert Sayre <sayrer@gmail.com>
Mon, 28 Sep 2009 11:53:36 -0700
changeset 33543 7ef3bc8626675772e65d7446468bd813cff815d4
parent 33541 fb92e8e990cedcf31eb83c7393c0c7ad120b04fc (current diff)
parent 33249 29e8f7716f6da58aacb1e99e33a34cd97d70a348 (diff)
child 33544 33c00f847d8987d99bfde614defd82ec55bced46
push idunknown
push userunknown
push dateunknown
milestone1.9.3a1pre
Merge mozilla-central to tracemonkey.
browser/themes/pinstripe/browser/places/back-forward.png
browser/themes/pinstripe/browser/places/menubutton-end-pressed-rtl.png
browser/themes/pinstripe/browser/places/menubutton-end-pressed.png
browser/themes/pinstripe/browser/places/menubutton-end-rtl.png
browser/themes/pinstripe/browser/places/menubutton-end.png
browser/themes/pinstripe/browser/places/menubutton-mid-pressed.png
browser/themes/pinstripe/browser/places/menubutton-start-pressed-rtl.png
browser/themes/pinstripe/browser/places/menubutton-start-pressed.png
browser/themes/pinstripe/browser/places/menubutton-start-rtl.png
browser/themes/pinstripe/browser/places/menubutton-start.png
browser/themes/pinstripe/browser/places/toolbar-button-backup.png
browser/themes/pinstripe/browser/places/toolbar-button-organize.png
browser/themes/pinstripe/browser/places/toolbar-button-view.png
gfx/cairo/qpainter-type.patch
js/src/configure.in
js/src/jstracer.cpp
media/libtheora/455357_wince_local_variable_macro_clash_patch
media/libtheora/bug498770.patch
media/libtheora/bug498815.patch
media/libtheora/bug498824.patch
media/libtheora/bug504613.patch
media/libtheora/lib/dec/apiwrapper.c
media/libtheora/lib/dec/apiwrapper.h
media/libtheora/lib/dec/bitpack.c
media/libtheora/lib/dec/bitpack.h
media/libtheora/lib/dec/dct.h
media/libtheora/lib/dec/decapiwrapper.c
media/libtheora/lib/dec/decinfo.c
media/libtheora/lib/dec/decint.h
media/libtheora/lib/dec/decode.c
media/libtheora/lib/dec/dequant.c
media/libtheora/lib/dec/dequant.h
media/libtheora/lib/dec/fragment.c
media/libtheora/lib/dec/huffdec.c
media/libtheora/lib/dec/huffdec.h
media/libtheora/lib/dec/huffman.h
media/libtheora/lib/dec/idct.c
media/libtheora/lib/dec/idct.h
media/libtheora/lib/dec/info.c
media/libtheora/lib/dec/internal.c
media/libtheora/lib/dec/ocintrin.h
media/libtheora/lib/dec/quant.c
media/libtheora/lib/dec/quant.h
media/libtheora/lib/dec/state.c
media/libtheora/lib/dec/x86/mmxfrag.c
media/libtheora/lib/dec/x86/mmxidct.c
media/libtheora/lib/dec/x86/mmxstate.c
media/libtheora/lib/dec/x86/x86int.h
media/libtheora/lib/dec/x86/x86state.c
media/libtheora/lib/dec/x86_vc/mmxfrag.c
media/libtheora/lib/dec/x86_vc/mmxidct.c
media/libtheora/lib/dec/x86_vc/mmxloopfilter.c
media/libtheora/lib/dec/x86_vc/mmxstate.c
media/libtheora/lib/dec/x86_vc/x86int.h
media/libtheora/lib/dec/x86_vc/x86state.c
parser/html/java/htmlparser/Makefile
parser/html/java/javaparser/Makefile
parser/html/java/sync-files.sh
parser/html/java/sync-src.sh
parser/html/java/translator/Makefile
parser/html/java/translator/manifest.txt
parser/html/java/translator/named-character-references.html
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/AnnotationHelperVisitor.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/CppTypes.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/CppVisitor.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/GkAtomParser.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/HVisitor.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/LabelVisitor.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/LicenseExtractor.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/LocalSymbolTable.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/Main.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/NoCppInputStream.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/StringLiteralParser.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/StringPair.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/SymbolTable.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/SymbolTableVisitor.java
parser/html/java/translator/src/nu/validator/htmlparser/cpptranslate/Type.java
parser/html/java/translator/src/nu/validator/htmlparser/generator/GenerateNamedCharacters.java
parser/html/java/translator/src/nu/validator/htmlparser/generator/GenerateNamedCharactersCpp.java
toolkit/components/places/tests/unit/test_nodes_propertyBag.js
--- a/.hgignore
+++ b/.hgignore
@@ -24,9 +24,9 @@
 _DBG\.OBJ/
 _OPT\.OBJ/
 
 # SpiderMonkey configury
 ^js/src/configure$
 ^js/src/autom4te.cache$
 
 # Java HTML5 parser classes
-^parser/html/java/.*\.class$
+^parser/html/java/(html|java)parser/
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -378,18 +378,17 @@ NS_IMETHODIMP nsDocAccessible::TakeFocus
   PRUint32 state;
   GetStateInternal(&state, nsnull);
   if (0 == (state & nsIAccessibleStates::STATE_FOCUSABLE)) {
     return NS_ERROR_FAILURE; // Not focusable
   }
 
   nsCOMPtr<nsIFocusManager> fm = do_GetService(FOCUSMANAGER_CONTRACTID);
   if (fm) {
-    nsCOMPtr<nsIDOMDocument> domDocument;
-    mDOMNode->GetOwnerDocument(getter_AddRefs(domDocument));
+    nsCOMPtr<nsIDOMDocument> domDocument(do_QueryInterface(mDOMNode));
     nsCOMPtr<nsIDocument> document(do_QueryInterface(domDocument));
     if (document) {
       // focus the document
       nsCOMPtr<nsIDOMElement> newFocus;
       return fm->MoveFocus(document->GetWindow(), nsnull,
                            nsIFocusManager::MOVEFOCUS_ROOT, 0,
                            getter_AddRefs(newFocus));
     }
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -1191,30 +1191,31 @@ var PlacesStarButton = {
     this._batching = true;
   },
 
   onEndUpdateBatch: function PSB_onEndUpdateBatch() {
     this.updateState();
     this._batching = false;
   },
   
-  onItemAdded: function PSB_onItemAdded(aItemId, aFolder, aIndex) {
+  onItemAdded: function PSB_onItemAdded(aItemId, aFolder, aIndex, aItemType) {
     if (!this._batching && !this._starred)
       this.updateState();
   },
 
-  onBeforeItemRemoved: function PSB_onBeforeItemRemoved(aItemId) {
-  },
+  onBeforeItemRemoved: function() {},
 
-  onItemRemoved: function PSB_onItemRemoved(aItemId, aFolder, aIndex) {
+  onItemRemoved: function PSB_onItemRemoved(aItemId, aFolder, aIndex,
+                                            aItemType) {
     if (!this._batching)
       this.updateState();
   },
 
   onItemChanged: function PSB_onItemChanged(aItemId, aProperty,
-                                            aIsAnnotationProperty, aValue) {
+                                            aIsAnnotationProperty, aNewValue,
+                                            aLastModified, aItemType) {
     if (!this._batching && aProperty == "uri")
       this.updateState();
   },
 
   onItemVisited: function() { },
   onItemMoved: function() { }
 };
--- a/browser/base/content/browser.xul
+++ b/browser/base/content/browser.xul
@@ -291,16 +291,17 @@
 #ifdef WINCE
            defaulticonsize="small" iconsize="small"
 #endif
            defaultmode="icons">
     <!-- Menu -->
     <toolbar type="menubar" id="toolbar-menubar" class="chromeclass-menubar" customizable="true"
              defaultset="menubar-items"
              mode="icons" iconsize="small" defaulticonsize="small"
+             lockiconsize="true"
 #ifdef XP_WIN
              toolbarname="&menubarCmd.label;"
              accesskey="&menubarCmd.accesskey;"
 #endif
              context="toolbar-context-menu">
       <toolbaritem id="menubar-items" align="center">
 # The entire main menubar is placed into browser-menubar.inc, so that it can be shared by 
 # hiddenWindow.xul.
@@ -544,16 +545,17 @@
                        oncommand="BrowserTryToCloseWindow();"/>
       </hbox>
     </toolbar>
 
     <toolbarset id="customToolbars" context="toolbar-context-menu"/>
 
     <toolbar id="PersonalToolbar"
              mode="icons" iconsize="small" defaulticonsize="small"
+             lockiconsize="true"
              class="chromeclass-directories"
              context="toolbar-context-menu"
              defaultset="personal-bookmarks"
              toolbarname="&personalbarCmd.label;" accesskey="&personalbarCmd.accesskey;"
 #ifdef WINCE
              collapsed="true"
 #endif
              customizable="true"/>
--- a/browser/base/content/test/browser_sanitize-download-history.js
+++ b/browser/base/content/test/browser_sanitize-download-history.js
@@ -84,31 +84,28 @@ function test()
       target: testPath,
       startTime: 1180493839859230,
       endTime: 1180493839859239,
       state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED,
       currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0
     };
     let db = Cc["@mozilla.org/download-manager;1"].
              getService(Ci.nsIDownloadManager).DBConnection;
-    let rawStmt = db.createStatement(
+    let stmt = db.createStatement(
       "INSERT INTO moz_downloads (name, source, target, startTime, endTime, " +
         "state, currBytes, maxBytes, preferredAction, autoResume) " +
       "VALUES (:name, :source, :target, :startTime, :endTime, :state, " +
         ":currBytes, :maxBytes, :preferredAction, :autoResume)");
-    let stmt = Cc["@mozilla.org/storage/statement-wrapper;1"].
-               createInstance(Ci.mozIStorageStatementWrapper);
-    stmt.initialize(rawStmt);
     try {
       for (let prop in data)
         stmt.params[prop] = data[prop];
       stmt.execute();
     }
     finally {
-      stmt.statement.finalize();
+      stmt.finalize();
     }
 
     // Toggle history to get everything to update
     EventUtils.synthesizeMouse(history, 0, 0, {}, aWin);
     EventUtils.synthesizeMouse(history, 0, 0, {}, aWin);
 
     ok(!history.checked, "history checkbox is not checked");
     ok(!downloads.disabled, "downloads checkbox is not disabled");
--- a/browser/base/content/test/browser_sanitize-timespans.js
+++ b/browser/base/content/test/browser_sanitize-timespans.js
@@ -586,12 +586,12 @@ function downloadExists(aID)
 {
   let db = dm.DBConnection;
   let stmt = db.createStatement(
     "SELECT * " +
     "FROM moz_downloads " +
     "WHERE id = :id"
   );
   stmt.params.id = aID;
-  var rows = stmt.step();
+  var rows = stmt.executeStep();
   stmt.finalize();
   return rows;
 }
--- a/browser/base/content/test/browser_sanitizeDialog.js
+++ b/browser/base/content/test/browser_sanitizeDialog.js
@@ -737,17 +737,17 @@ function downloadExists(aID)
 {
   let db = dm.DBConnection;
   let stmt = db.createStatement(
     "SELECT * " +
     "FROM moz_downloads " +
     "WHERE id = :id"
   );
   stmt.params.id = aID;
-  let rows = stmt.step();
+  let rows = stmt.executeStep();
   stmt.finalize();
   return !!rows;
 }
 
 /**
  * Runs the next test in the gAllTests array.  If all tests have been run,
  * finishes the entire suite.
  */
--- a/browser/base/content/test/browser_sanitizeDialog_treeView.js
+++ b/browser/base/content/test/browser_sanitizeDialog_treeView.js
@@ -537,17 +537,17 @@ function downloadExists(aID)
 {
   let db = dm.DBConnection;
   let stmt = db.createStatement(
     "SELECT * " +
     "FROM moz_downloads " +
     "WHERE id = :id"
   );
   stmt.params.id = aID;
-  let rows = stmt.step();
+  let rows = stmt.executeStep();
   stmt.finalize();
   return !!rows;
 }
 
 /**
  * Runs the next test in the gAllTests array.  If all tests have been run,
  * finishes the entire suite.
  */
--- a/browser/components/about/AboutRedirector.cpp
+++ b/browser/components/about/AboutRedirector.cpp
@@ -76,17 +76,17 @@ static RedirEntry kRedirMap[] = {
     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
     nsIAboutModule::ALLOW_SCRIPT },
   { "feeds", "chrome://browser/content/feeds/subscribe.xhtml",
     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
     nsIAboutModule::ALLOW_SCRIPT },
   { "privatebrowsing", "chrome://browser/content/aboutPrivateBrowsing.xhtml",
     nsIAboutModule::ALLOW_SCRIPT },
   { "rights",
-#ifdef OFFICIAL_BUILD
+#ifdef MOZ_OFFICIAL_BRANDING
     "chrome://global/content/aboutRights.xhtml",
 #else
     "chrome://global/content/aboutRights-unbranded.xhtml",
 #endif
     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
     nsIAboutModule::ALLOW_SCRIPT },
   { "robots", "chrome://browser/content/aboutRobots.xhtml",
     nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
--- a/browser/components/about/Makefile.in
+++ b/browser/components/about/Makefile.in
@@ -53,13 +53,9 @@ endif
 EXPORTS_NAMESPACES = mozilla/browser
 
 EXPORTS_mozilla/browser = AboutRedirector.h
 
 CPPSRCS = AboutRedirector.cpp
 
 LOCAL_INCLUDES = -I$(srcdir)/../build
 
-ifdef MOZILLA_OFFICIAL
-DEFINES += -DOFFICIAL_BUILD=1
-endif
-
 include $(topsrcdir)/config/rules.mk
--- a/browser/components/places/content/controller.js
+++ b/browser/components/places/content/controller.js
@@ -146,37 +146,34 @@ PlacesController.prototype = {
     case "cmd_copy":
     case "placesCmd_copy":
       return this._view.hasSelection;
     case "cmd_paste":
     case "placesCmd_paste":
       return this._canInsert(true) && this._isClipboardDataPasteable();
     case "cmd_selectAll":
       if (this._view.selType != "single") {
-        var result = this._view.getResult();
-        if (result) {
-          var container = asContainer(result.root);
-          if (container.containerOpen && container.childCount > 0)
+        var rootNode = this._view.getResultNode();
+        if (rootNode.containerOpen && rootNode.childCount > 0)
             return true;
-        }
       }
       return false;
     case "placesCmd_open":
     case "placesCmd_open:window":
     case "placesCmd_open:tab":
       var selectedNode = this._view.selectedNode;
       return selectedNode && PlacesUtils.nodeIsURI(selectedNode);
     case "placesCmd_new:folder":
     case "placesCmd_new:livemark":
       return this._canInsert();
     case "placesCmd_new:bookmark":
       return this._canInsert();
     case "placesCmd_new:separator":
       return this._canInsert() &&
-             !asQuery(this._view.getResult().root).queryOptions.excludeItems &&
+             !asQuery(this._view.getResultNode()).queryOptions.excludeItems &&
              this._view.getResult().sortingMode ==
                  Ci.nsINavHistoryQueryOptions.SORT_BY_NONE;
     case "placesCmd_show:info":
       var selectedNode = this._view.selectedNode;
       if (selectedNode &&
           PlacesUtils.getConcreteItemId(selectedNode) != -1  &&
           !PlacesUtils.nodeIsLivemarkItem(selectedNode))
         return true;
@@ -444,17 +441,17 @@ PlacesController.prototype = {
    *          node are set on its corresponding object as properties.
    * Notes:
    *   1) This can be slow, so don't call it anywhere performance critical!
    *   2) A single-object array corresponding the root node is returned if
    *      there's no selection.
    */
   _buildSelectionMetadata: function PC__buildSelectionMetadata() {
     var metadata = [];
-    var root = this._view.getResult().root;
+    var root = this._view.getResultNode();
     var nodes = this._view.getSelectionNodes();
     if (nodes.length == 0)
       nodes.push(root); // See the second note above
 
     for (var i=0; i < nodes.length; i++) {
       var nodeData = {};
       var node = nodes[i];
       var nodeType = node.type;
@@ -1006,17 +1003,16 @@ PlacesController.prototype = {
    * Removes the set of selected ranges from history.
    */
   _removeRowsFromHistory: function PC__removeRowsFromHistory() {
     // Other containers are history queries, just delete from history
     // history deletes are not undoable.
     var nodes = this._view.getSelectionNodes();
     var URIs = [];
     var bhist = PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory);
-    var resultView = this._view.getResultView();
     var root = this._view.getResultNode();
 
     for (var i = 0; i < nodes.length; ++i) {
       var node = nodes[i];
       if (PlacesUtils.nodeIsURI(node)) {
         var uri = PlacesUtils._uri(node.uri);
         // avoid trying to delete the same url twice
         if (URIs.indexOf(uri) < 0) {
@@ -1082,17 +1078,17 @@ PlacesController.prototype = {
    *          as part of another operation.
    */
   remove: function PC_remove(aTxnName) {
     if (!this._hasRemovableSelection(false))
       return;
 
     NS_ASSERT(aTxnName !== undefined, "Must supply Transaction Name");
 
-    var root = this._view.getResult().root;
+    var root = this._view.getResultNode();
 
     if (PlacesUtils.nodeIsFolder(root)) 
       this._removeRowsFromBookmarks(aTxnName);
     else if (PlacesUtils.nodeIsQuery(root)) {
       var queryType = asQuery(root).queryOptions.queryType;
       if (queryType == Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS)
         this._removeRowsFromBookmarks(aTxnName);
       else if (queryType == Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY)
--- a/browser/components/places/content/editBookmarkOverlay.js
+++ b/browser/components/places/content/editBookmarkOverlay.js
@@ -1060,17 +1060,18 @@ var gEditItemOverlay = {
     case "unload":
       this.uninitPanel(false);
       break;
     }
   },
 
   // nsINavBookmarkObserver
   onItemChanged: function EIO_onItemChanged(aItemId, aProperty,
-                                            aIsAnnotationProperty, aValue) {
+                                            aIsAnnotationProperty, aValue,
+                                            aLastModified, aItemType) {
     if (this._itemId != aItemId) {
       if (aProperty == "title") {
         // If the title of a folder which is listed within the folders
         // menulist has been changed, we need to update the label of its
         // representing element.
         var menupopup = this._folderMenuList.menupopup;
         for (var i=0; i < menupopup.childNodes.length; i++) {
           if (menupopup.childNodes[i].folderId == aItemId) {
@@ -1140,29 +1141,29 @@ var gEditItemOverlay = {
       if (siteURI)
         siteURISpec = siteURI.spec;
       this._initTextField("siteLocationField", siteURISpec);
       break;
     }
   },
 
   onItemMoved: function EIO_onItemMoved(aItemId, aOldParent, aOldIndex,
-                                        aNewParent, aNewIndex) {
+                                        aNewParent, aNewIndex, aItemType) {
     if (aItemId != this._itemId ||
         aNewParent == this._getFolderIdFromMenuList())
       return;
 
     var folderItem = this._getFolderMenuItem(aNewParent);
 
     // just setting selectItem _does not_ trigger oncommand, so we don't
     // recurse
     this._folderMenuList.selectedItem = folderItem;
   },
 
-  onItemAdded: function EIO_onItemAdded(aItemId, aFolder, aIndex) {
+  onItemAdded: function EIO_onItemAdded(aItemId, aFolder, aIndex, aItemType) {
     this._lastNewItem = aItemId;
   },
 
   onBeginUpdateBatch: function() { },
   onEndUpdateBatch: function() { },
   onBeforeItemRemoved: function() { },
   onItemRemoved: function() { },
   onItemVisited: function() { },
--- a/browser/components/places/content/menu.xml
+++ b/browser/components/places/content/menu.xml
@@ -73,18 +73,16 @@
 
       <!-- markers for start and end of valid places items -->
       <field name="_startMarker">-1</field>
       <field name="_endMarker">-1</field>
 
       <!-- This is the view that manage the popup -->
       <field name="_rootView">PlacesUIUtils.getViewForNode(this);</field>
 
-      <field name="_built">false</field>
-
       <method name="onDragOver">
         <parameter name="aEvent"/>
         <parameter name="aFlavour"/>
         <parameter name="aDragSession"/>
         <body><![CDATA[
           PlacesControllerDragHelper.currentDropTarget = aEvent.target;
           // check if we have a valid dropPoint
           var dropPoint = this._getDropPoint(aEvent);
@@ -531,19 +529,19 @@
     </handlers>
   </binding>
 
 
   <binding id="places-menupopup"
            extends="chrome://browser/content/places/menu.xml#places-popup-base">
     <implementation>
       <destructor><![CDATA[
-        this._resultNode = null;
         if (this._result) {
-          this._result.root.containerOpen = false;
+          this._resultNode.containerOpen = false;
+          this._resultNode = null;
           this._result.viewer = null;
           this._result = null;
         }
       ]]></destructor>
 
       <field name="_initialized">false</field>
       <method name="_ensureInitialized">
         <body><![CDATA[
@@ -569,22 +567,23 @@
 
       <method name="onPopupShowing">
         <parameter name="aEvent"/>
         <body><![CDATA[
           var popup = aEvent.target;
           var resultNode = popup._resultNode;
           if (!resultNode.containerOpen)
             resultNode.containerOpen = true;
-          if (!popup._built)
+          if (!popup.parentNode._built)
             this._rebuild(popup);
         ]]></body>
       </method>
 
       <field name="_result">null</field>
+      <field name="_resultNode">null</field>
 
       <!-- nsIPlacesView -->
       <method name="getResult">
         <body><![CDATA[
           return this._result;
         ]]></body>
       </method>
 
@@ -594,44 +593,35 @@
           this._ensureInitialized();
           return this._resultNode;
         ]]></body>
       </method>
 
       <method name="removeItem">
         <parameter name="child"/>
         <body><![CDATA[
-          if (PlacesUtils.nodeIsContainer(child.node)) {
-            for (var i=0; i < this._containerNodesMap.length; i++) {
-              if (this._containerNodesMap[i].resultNode == child.node) {
-                this._containerNodesMap.splice(i, 1);
-                break;
-              }
-            }
-          }
-
           // if document.popupNode pointed to this child, null it out,
           // otherwise controller's command-updating may rely on the removed
           // item still being "selected".
           if (document.popupNode == child)
             document.popupNode = null;
+
           child.parentNode.removeChild(child);
 
           if (this._endMarker != -1)
             this._endMarker--;
         ]]></body>
       </method>
 
       <method name="insertNewItem">
         <parameter name="aChild"/>
         <parameter name="aParentPopup"/>
         <parameter name="aBefore"/>
         <body><![CDATA[
-          var element =
-            PlacesUIUtils.createMenuItemForNode(aChild, this._containerNodesMap);
+          var element = PlacesUIUtils.createMenuItemForNode(aChild);
 
           if (aBefore)
             aParentPopup.insertBefore(element, aBefore);
           else {
             // Add the new element to the menu.  If there is static content at
             // the end of the menu, add the element before that.  Otherwise,
             // just add to the end.
             if (aParentPopup._endMarker != -1) {
@@ -684,220 +674,220 @@
             }
           }
           else {
             // This menu is empty.  If there is no static content, add
             // an element to show it is empty.
             if (aPopup._startMarker == -1 && aPopup._endMarker == -1)
               this._showEmptyMenuItem(aPopup);
           }
-          aPopup._built = true;
+          aPopup.parentNode._built = true;
         ]]></body>
       </method>
 
       <!-- nsINavHistoryResultViewer -->
       <field name="_viewer"><![CDATA[({
         _self: this,
 
-        _getPopupForContainer:
-        function PMV__getPopupForContainer(aNode) {
-          if (this._self._resultNode == aNode)
-            return this._self;
-
-          for (var i=0; i < this._self._containerNodesMap.length; i++) {
-            if (this._self._containerNodesMap[i].resultNode == aNode)
-              return this._self._containerNodesMap[i].domNode;
-          }
-          throw("Container view not found");
-        },
-
         get result() {
           return this._self._result;
         },
 
         set result(val) {
           // some methods (e.g. getURLsFromContainer) temporarily null out the
           // viewer when they do temporary changes to the view, this does _not_
           // call setResult(null), but then, we're called again with the result
           // object which is already set for this viewer. At that point,
           // we should do nothing.
           if (this._self._result != val) {
             if (this._self._result)
-              this._self._result.root.containerOpen = false;
-            this._built = false;
-            this._self._containerNodesMap = [];
-            this._self._resultNode = val.root;
+              this._self._resultNode.containerOpen = false;
+
+            this._self.parentNode._built = false;
             this._self._result = val;
+            if (val) {
+              this._self._resultNode = val.root;
+              this._self._resultNode._DOMElement = this._self.parentNode;
+            }
+            else
+              this._self._resultNode = null;
           }
           return val;
         },
 
-        itemInserted: function PMV_itemInserted(aParentNode, aNode, aIndex) {
-          var popup = this._getPopupForContainer(aParentNode);
-          if (!popup._built)
+        nodeInserted: function PMV_nodeInserted(aParentNode, aNode, aIndex) {
+          let parentElt = aParentNode._DOMElement;
+          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
+
+          if (!parentElt._built)
             return;
 
-          var index = popup._startMarker + 1 + aIndex;
-          var before = popup.childNodes[index] || null;
+          // parentElt is the <menu> element for the container,
+          // we need the <menupopup>
+          let popup = parentElt.firstChild;
+
+          let index = popup._startMarker + 1 + aIndex;
+          let before = popup.childNodes[index] || null;
           this._self.insertNewItem(aNode, popup, before);
           if (popup._emptyMenuItem)
             popup._emptyMenuItem.hidden = true;
         },
 
-        itemRemoved: function PMV_itemRemoved(aParentNode, aNode, aIndex) {
-          var popup = this._getPopupForContainer(aParentNode);
-          if (!popup._built)
+        nodeRemoved: function PMV_nodeRemoved(aParentNode, aNode, aIndex) {
+          let parentElt = aParentNode._DOMElement;
+          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
+
+          if (!parentElt._built)
+            return;
+
+          // parentElt is the <menu> element for the container,
+          // we need the <menupopup>
+          let popup = parentElt.firstChild;
+
+          let nodeElt = aNode._DOMElement;
+          NS_ASSERT(nodeElt, "node must have _DOMElement set");
+          popup.removeChild(nodeElt);
+
+          // Figure out if we need to show the "<Empty>" menu-item.
+          // TODO Bug 517701: This doesn't seem to handle the case of an empty
+          // root (parentElt == this._self.parentNode).
+          if (!popup.hasChildNodes() ||
+              (popup.childNodes.length == 1 &&
+              popup.firstChild == popup._emptyMenuItem))
+            this._self._showEmptyMenuItem(popup);
+
+          if (popup._endMarker != -1)
+            popup._endMarker--;
+        },
+
+        nodeMoved:
+        function PMV_nodeMoved(aNode,
+                               aOldParent, aOldIndex,
+                               aNewParent, aNewIndex) {
+          // Note: the current implementation of moveItem does not actually
+          // use this notification when the item in question is moved from one
+          // folder to another.  Instead, it calls nodeRemoved and nodeInserted
+          // for the two folders.  Thus, we can assume aOldParent == aNewParent.
+
+          let nodeElt = aNode._DOMElement;
+          NS_ASSERT(nodeElt, "node must have _DOMElement set");
+
+          // If our root node is a folder, it might be moved. There's nothing
+          // we need to do in that case.
+          if (nodeElt == this._self.parentNode)
             return;
 
-          var children = popup.childNodes;
-          for (var i = popup._startMarker + 1; i < children.length; i++) {
-            if (children[i].node == aNode) {
-              this._self.removeItem(children[i]);
-              if (!popup.hasChildNodes() ||
-                  (popup.childNodes.length == 1 &&
-                   popup.firstChild == popup._emptyMenuItem)) {
-                this._self._showEmptyMenuItem(popup);
-              }
-              return;
-            }
-          }
+          // Move the node.
+          let popup = nodeElt.parentNode;
+          popup.removeChild(nodeElt);
+          popup.insertBefore(nodeElt, popup.childNodes[aNewIndex]);
+        },
+
+        nodeTitleChanged: function PMV__nodeTitleChanged(aNode, aNewTitle) {
+          let nodeElt = aNode._DOMElement;
+          NS_ASSERT(nodeElt, "node must have _DOMElement set");
+
+          // There's no UI representation for the root node, thus there's
+          // nothing to be done when the title changes.
+          if (nodeElt == this._self.parentNode)
+            return;
+
+          nodeElt.label = aNewTitle || PlacesUIUtils.getBestTitle(aNode);
+        },
+
+        nodeURIChanged: function PMV_nodeURIChanged(aNode, aURIString) {
+          let nodeElt = aNode._DOMElement;
+          NS_ASSERT(nodeElt, "node must have _DOMElement set");
+
+          nodeElt.setAttribute("scheme",
+                               PlacesUIUtils.guessUrlSchemeForUI(aURIString));
         },
 
-        itemMoved:
-        function PMV_itemMoved(aItem, aOldParent, aOldIndex, aNewParent,
-                               aNewIndex) {
-          // This cannot actually happen yet (see IDL)
-          if (aNewParent != aOldParent)
+        nodeIconChanged: function PMV_nodeIconChanged(aNode) {
+          let nodeElt = aNode._DOMElement;
+          NS_ASSERT(nodeElt, "node must have _DOMElement set");
+
+          // There's no UI representation for the root node, thus there's
+          // nothing to be done when the icon changes.
+          if (nodeElt == this._self.parentNode)
             return;
 
-          var popup = this._getPopupForContainer(aNewParent);
-          var index = popup._startMarker + 1 + aNewIndex;
-          var children = popup.childNodes;
-          for (var i = popup._startMarker + 1; i < children.length; i++) {
-            var menuItem = children[i];
-            if (menuItem.node == aItem) {
-              popup.removeChild(menuItem);
-              popup.insertBefore(menuItem, children[index]);
-              return;
-            }
+          var icon = aNode.icon;
+          if (icon) {
+            if (nodeElt.getAttribute("image") != icon)
+              nodeElt.setAttribute("image", icon);
+          }
+          else
+            nodeElt.removeAttribute("image");
+        },
+
+        nodeAnnotationChanged:
+        function PMV_nodeAnnotationChanged(aNode, aAnno) {
+          // Ensure the changed annotation is a livemark one.
+          if (/^livemark\//.test(aAnno) &&
+              PlacesUtils.nodeIsLivemarkContainer(aNode)) {
+            let nodeElt = aNode._DOMElement;
+            NS_ASSERT(nodeElt, "node must have _DOMElement set");
+
+            if (!nodeElt.hasAttribute("livemark"))
+              nodeElt.setAttribute("livemark", "true");
+
+            // Add or remove the livemark status menuitem.
+            PlacesUIUtils.ensureLivemarkStatusMenuItem(nodeElt.firstChild);
           }
         },
 
-        itemChanged: function PMV_itemChanged(aNode) {
-          // this check can be removed once we fix bug #382397
-          var parentNode = aNode.parent;
-          if (!parentNode)
-            return;
+        nodeHistoryDetailsChanged: function() { },
+        nodeTagsChanged: function() { },
+        nodeDateAddedChanged: function() { },
+        nodeLastModifiedChanged: function() { },
+        nodeKeywordChanged: function() { },
 
-          if (PlacesUtils.nodeIsSeparator(aNode)) {
-            // nothing to do when a separator changes
-            return;
-          }
+        nodeReplaced:
+        function PMV_nodeReplaced(aParentNode, aOldNode, aNewNode, aIndex) {
+          let parentElt = aParentNode._DOMElement;
+          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
 
-          var popup = this._getPopupForContainer(parentNode);
-          if (!popup._built)
+          if (!parentElt._built)
             return;
 
-          var children = popup.childNodes;
-          var menuitem;
-          for (var i = popup._startMarker + 1; i < children.length; i++) {
-            if (children[i].node == aNode) {
-              menuitem = children[i];
-              break;
-            }
-          }
-
-          var iconURI = aNode.icon;
-          if (iconURI) {
-            var spec = iconURI.spec;
-            if (menuitem.getAttribute("image") != spec)
-              menuitem.setAttribute("image", spec);
-          }
-          else
-            menuitem.removeAttribute("image");
-
-          var title = PlacesUIUtils.getBestTitle(aNode);
-          if (menuitem.getAttribute("label") != title)
-            menuitem.setAttribute("label", title);
+          // parentElt is the <menu> element for the container,
+          // we need the <menupopup>.
+          let popup = parentElt.firstChild;
 
-          if (PlacesUtils.nodeIsLivemarkContainer(aNode)) {
-            if (!menuitem.hasAttribute("livemark"))
-              menuitem.setAttribute("livemark", "true");
-            // If this is a livemark container check if the status menuitem has
-            // to be added or removed.
-            PlacesUIUtils.ensureLivemarkStatusMenuItem(menuitem.firstChild);
-          }
-          else if (PlacesUtils.nodeIsURI(aNode)) {
-              menuitem.setAttribute("scheme", PlacesUIUtils.guessUrlSchemeForUI(aNode.uri));
-          }
-        },
+          let nodeElt = aOldNode._DOMElement;
+          NS_ASSERT(nodeElt, "node must have _DOMElement set");
 
-        itemReplaced:
-        function PMV_itemReplaced(aParentNode, aOldNode, aNewNode, aIndex) {
-          var popup = this._getPopupForContainer(aParentNode);
-          if (!popup._built)
-            return;
-
-          var children = popup.childNodes;
-          for (var i = popup._startMarker + 1; i < children.length; i++) {
-            if (children[i].node == aOldNode) {
-              var next = children[i].nextSibling;
-              this._self.removeItem(children[i]);
-              this._self.insertNewItem(aNewNode, popup, next);
-              return;
-            }
-          }
+          // No worries: If nodeElt is the last item (i.e. no nextSibling),
+          // insertNewItem will insert the new element as the last item.
+          let next = nodeElt.nextSibling;
+          this._self.removeItem(nodeElt);
+          this._self.insertNewItem(aNewNode, popup, next);
         },
 
         containerOpened: function PMV_containerOpened(aNode) {
           this.invalidateContainer(aNode);
         },
 
         containerClosed: function PMV_containerClosed(aNode) {
           this.invalidateContainer(aNode);
         },
- 
+
         invalidateContainer: function PMV_invalidateContainer(aContainer) {
-          if (!this._self._built)
+          // Do nothing if the entire view is already marked un-built.
+          if (!this._self.parentNode._built)
             return;
 
-          function isChildOf(node, container) {
-            var parent = node.parent;
-            while (parent) {
-              if (parent == container)
-                return true;
-              parent = parent.parent;
-            }
-            return false;
-          }
-
-          var popupToRebuild = null;
-          for (var i=0; i < this._self._containerNodesMap.length; i++) {
-            var node = this._self._containerNodesMap[i].resultNode;
+          let containerNodeElt = aContainer._DOMElement;
+          NS_ASSERT(containerNodeElt, "node must have _DOMElement set");
+          containerNodeElt._built = false;
 
-            if (node == aContainer)
-              popupToRebuild = this._self._containerNodesMap[i].domNode;
-            if (isChildOf(node, aContainer)) {
-              this._self._containerNodesMap.splice(i,1);
-              i--;
-            }
-          }
-
-          if (!popupToRebuild)
-            popupToRebuild = this._self;
-          popupToRebuild._built = false;
-
-          // if the menupopup is open we should live-update it
-          if (popupToRebuild.parentNode.open)
-            this._self._rebuild(popupToRebuild);
-        },
-
-        invalidateAll: function PMV_invalidateAll() {
-          this._self._containerNodesMap.splice(0);
-          this._self._built = false;
+          // If the menupopup is open we should live-update it.
+          if (containerNodeElt.open)
+            this._self._rebuild(containerNodeElt.firstChild);
         },
 
         sortingChanged: function PMV_sortingChanged(aSortingMode) {
         }
       })]]></field>
 
       <!-- nsIPlacesView -->
       <property name="place">
@@ -909,16 +899,17 @@
           var queries = { }, options = { };
           PlacesUtils.history.queryStringToQueries(val, queries, { }, options);
           if (!queries.value.length)
             queries.value = [PlacesUtils.history.getNewQuery()];
           var result =
             PlacesUtils.history.executeQueries(queries.value,
                                                queries.value.length,
                                                options.value);
+
           result.viewer = this._viewer;
           return val;
         ]]></setter>
       </property>
 
       <!-- nsIPlacesView -->
       <property name="hasSelection">
         <getter><![CDATA[
--- a/browser/components/places/content/toolbar.xml
+++ b/browser/components/places/content/toolbar.xml
@@ -19,30 +19,31 @@
 # Portions created by the Initial Developer are Copyright (C) 2005-2006
 # the Initial Developer. All Rights Reserved.
 #
 # Contributor(s):
 #   Annie Sullivan <annie.sullivan@gmail.com>
 #   Ben Goodger <beng@google.com>
 #   Myk Melez <myk@mozilla.org>
 #   Marco Bonardo <mak77@bonardo.net>
+#   Asaf Romano <mano@mozilla.com>
 #
 # Alternatively, the contents of this file may be used under the terms of
 # either the GNU General Public License Version 2 or later (the "GPL"), or
 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 # in which case the provisions of the GPL or the LGPL are applicable instead
 # of those above. If you wish to allow use of your version of this file only
 # under the terms of either the GPL or the LGPL, and not to allow others to
 # use your version of this file under the terms of the MPL, indicate your
 # decision by deleting the provisions above and replace them with the notice
 # and other provisions required by the GPL or the LGPL. If you do not delete
 # the provisions above, a recipient may use your version of this file under
 # the terms of any one of the MPL, the GPL or the LGPL.
 #
-# ***** END LICENSE BLOCK ***** 
+# ***** END LICENSE BLOCK *****
 
 
 <!DOCTYPE bindings [
 <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd" >
 %browserDTD;
 ]>
 
 <bindings id="placesToolbarBindings"
@@ -94,38 +95,71 @@
       ]]></constructor>
 
       <destructor><![CDATA[
         this._scrollbox.removeEventListener("overflow", this, false);
         this._scrollbox.removeEventListener("underflow", this, false);
         window.removeEventListener("resize", this, false);
 
         if (this._result) {
+          this._resultNode.containerOpen = false;
+          this._resultNode = null;
           this._result.viewer = null;
           this._result = null;
         }
       ]]></destructor>
 
       <property name="controller"
                 readonly="true"
                 onget="return this._controller;"/>
 
       <method name="_init">
         <body><![CDATA[
-        this._controller = new PlacesController(this);
-        this.controllers.appendController(this._controller);
+          // XBL bug is in the middle...
+          // When toolbar customization is opened, this binding is attached
+          // again, as a result of adding the item under the wrapper.  However,
+          // the binding isn't detached from the "original" hbox element due
+          // to bug 83635.
+          //
+          // Then, when the customization dialog is closed, the binding is
+          // attached the third time, as a result of adding our element back to
+          // the toolbar.
+          //
+          // So, We'll just continue using the original binding, which was
+          // never removed, and avoid using the new bindings.  This means that
+          // this workaround will work just until bug 83635 is fixed.
+          //
+          // However, when the binding is "reconstructed", we do need to add
+          // back the event listeners and the places controller.
+          //
+          // Note: we could avoid part of this mess by moving the "Bookmark
+          // Toolbar Items" placeholder out of this binding.
 
-        this._scrollbox.addEventListener("overflow", this, false);
-        this._scrollbox.addEventListener("underflow", this, false);
-        window.addEventListener("resize", this, false);
+          // We also need to avoid initializing _result and _resultNode and
+          // _controller as XBL fields.  Otherwise, they'll be unset when the
+          // "extra" bindings are applied.
+
+          this._scrollbox.addEventListener("overflow", this, false);
+          this._scrollbox.addEventListener("underflow", this, false);
+          window.addEventListener("resize", this, false);
 
-        if (this.hasAttribute("place")) {
-          // Do the initial build.
-          this.place = this.place;
-        }
+          if (this._result === undefined) {
+            this._result = null;
+            this._resultNode = null;
+            if (this.hasAttribute("place")) {
+              // Do the initial build.
+              this.place = this.place;
+            }
+          }
+
+          // Attach the places controller.
+          if (!this._controller) 
+            this._controller = new PlacesController(this);
+
+          this.controllers.appendController(this._controller);
         ]]></body>
       </method>
 
       <field name="_scrollbox">
         document.getAnonymousElementByAttribute(this, "class",
                                                 "bookmarks-toolbar-items")
       </field>
       <field name="_dropIndicator">
@@ -137,139 +171,117 @@
       </field>
       <field name="_chevronPopup">
         document.getAnonymousElementByAttribute(this, "anonid", "chevronPopup")
       </field>
 
       <field name="_openedMenuButton">null</field>
       <field name="_allowPopupShowing">true</field>
 
-      <field name="_result">null</field>
-      <field name="_resultNode">null</field>
-
       <field name="_isRTL">
         document.defaultView.getComputedStyle(this.parentNode, "")
                             .direction == "rtl"
       </field>
 
       <!-- nsIPlacesView -->
       <method name="getResult">
         <body><![CDATA[
           return this._result;
         ]]></body>
       </method>
 
       <!-- nsIPlacesView -->
       <method name="getResultNode">
         <body><![CDATA[
-          return this._result.root;
+          return this._resultNode;
         ]]></body>
       </method>
 
       <method name="_rebuild">
         <body><![CDATA[
           // Clear out references to existing nodes, since they will be removed
           // and re-added.
           if (this._overFolder.node)
             this._clearOverFolder();
           this._openedMenuButton = null;
 
           while (this.hasChildNodes())
             this.removeChild(this.firstChild);
 
-          var rootNode = this._result.root;
-          var cc = rootNode.childCount;
+          let cc = this._resultNode.childCount;
           for (let i = 0; i < cc; ++i)
-            this.insertNewItem(rootNode.getChild(i), null);
+            this.insertNewItem(this._resultNode.getChild(i), null);
 
           if (this._chevronPopup.hasAttribute("type")) {
             // Chevron has already been initialized, but since we are forcing
             // a rebuild of the toolbar, it has to be rebuilt.
             // Otherwise, it will be initialized when the toolbar overflows.
             this._chevronPopup.place = this.place;
           }
-
-          while (chevronPopup.hasChildNodes())
-            this._chevronPopup.removeChild(this._chevronPopup.lastChild);
         ]]></body>
       </method>
 
       <method name="insertNewItem">
         <parameter name="aChild"/>
         <parameter name="aBefore"/>
         <body><![CDATA[
           var type = aChild.type;
           var button;
           if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR)
             button = document.createElement("toolbarseparator");
           else {
             button = document.createElement("toolbarbutton");
             button.className = "bookmark-item";
             button.setAttribute("label", aChild.title);
-            var iconURI = aChild.icon;
-            var iconURISpec = "";
-            if (iconURI) {
-              iconURISpec = iconURI.spec;
-              button.setAttribute("image", iconURISpec);
-            }
+            var icon = aChild.icon;
+            if (icon)
+              button.setAttribute("image", icon);
 
             if (PlacesUtils.containerTypes.indexOf(type) != -1) {
               button.setAttribute("type", "menu");
               button.setAttribute("container", "true");
 
               if (PlacesUtils.nodeIsQuery(aChild)) {
                 button.setAttribute("query", "true");
                 if (PlacesUtils.nodeIsTagQuery(aChild))
                   button.setAttribute("tagContainer", "true");
               }
               else if (PlacesUtils.nodeIsLivemarkContainer(aChild))
                 button.setAttribute("livemark", "true");
 
               var popup = document.createElement("menupopup");
               popup.setAttribute("placespopup", "true");
               button.appendChild(popup);
-              popup._result = this._result;
               popup._resultNode = asContainer(aChild);
 #ifndef XP_MACOSX
               popup.setAttribute("context", "placesContext");
 #endif
-              this._containerNodesMap.push({ resultNode: aChild,
-                                             domNode: popup });
             }
-            else if (PlacesUtils.nodeIsURI(aChild)) {
+            else if (PlacesUtils.nodeIsURI(aChild))
               button.setAttribute("scheme", PlacesUIUtils.guessUrlSchemeForUI(aChild.uri));
-            }
           }
 
           button.node = aChild;
-          button.node.viewIndex = 0;
+          aChild._DOMElement = button;
           if (aBefore)
             this.insertBefore(button, aBefore);
           else
             this.appendChild(button);
         ]]></body>
       </method>
 
       <method name="removeItem">
         <parameter name="child"/>
         <body><![CDATA[
-          if (PlacesUtils.nodeIsContainer(child.node)) {
-            for (let i = 0; i < this._containerNodesMap.length; i++) {
-              if (this._containerNodesMap[i].resultNode == child.node) {
-                this._containerNodesMap.splice(i, 1);
-                break;
-              }
-            }
-          }
-
           // if document.popupNode pointed to this child, null it out,
           // otherwise controller's command-updating may rely on the removed
           // item still being "selected".
           if (document.popupNode == child)
             document.popupNode = null;
+
           child.parentNode.removeChild(child);
         ]]></body>
       </method>
 
       <method name="_updateChevronPopupNodesVisibility">
         <body><![CDATA[
           for (let i = 0; i < this._chevronPopup.childNodes.length; i++) {
             this._chevronPopup.childNodes[i].hidden =
@@ -373,41 +385,41 @@
         ]]></body>
       </method>
 
       <!-- nsIPlacesView -->
       <property name="place">
         <getter><![CDATA[
           return this.getAttribute("place");
         ]]></getter>
-        <setter><![CDATA[ 
+        <setter><![CDATA[
           this.setAttribute("place", val);
 
           var history = PlacesUtils.history;
           var queries = { }, options = { };
           history.queryStringToQueries(val, queries, { }, options);
-          if (!queries.value.length) 
+          if (!queries.value.length)
             queries.value = [history.getNewQuery()];
           try {
             var result =
               history.executeQueries(queries.value, queries.value.length,
                                      options.value);
             result.viewer = this._viewer;
           }
           catch(ex) {
             // Invalid query, or had no results.
-            // This is valid, eg: user deletes their bookmarks toolbar folder. 
+            // This is valid, eg: user deletes his bookmarks toolbar folder.
           }
           return val;
         ]]></setter>
       </property>
 
       <!-- nsIPlacesView -->
       <property name="hasSelection">
-        <getter><![CDATA[ 
+        <getter><![CDATA[
           return this.selectedNode != null;
         ]]></getter>
       </property>
 
       <!-- nsIPlacesView -->
       <method name="getSelectionNodes">
         <body><![CDATA[
           var selectedNode = this.selectedNode;
@@ -448,19 +460,19 @@
           }
           return null;
         ]]></getter>
       </property>
 
       <!-- nsIPlacesView -->
       <property name="insertionPoint">
         <getter><![CDATA[
-          // By default, the insertion point is at the top level, at the end. 
+          // By default, the insertion point is at the top level, at the end.
           var index = PlacesUtils.bookmarks.DEFAULT_INDEX;
-          var container = this._result.root;
+          var container = this._resultNode;
           var orientation = Ci.nsITreeView.DROP_BEFORE;
           var isTag = false;
 
           var selectedNode = this.selectedNode;
           if (selectedNode) {
             var popupNode = document.popupNode;
             if (!popupNode.node) {
               // If a static menuitem is selected the insertion point
@@ -481,293 +493,274 @@
 
           return new InsertionPoint(PlacesUtils.getConcreteItemId(container),
                                     index, orientation, isTag);
         ]]></getter>
       </property>
 
       <!-- nsIPlacesView -->
       <method name="selectAll">
-        <body><![CDATA[ 
+        <body><![CDATA[
           // Nothing
         ]]></body>
       </method>
 
       <method name="selectItems">
         <body><![CDATA[
           // Nothing
         ]]></body>
       </method>
 
       <!-- nsINavHistoryResultViewer -->
       <field name="_viewer"><![CDATA[({
         _self: this,
 
-        _getPopupForContainer:
-        function PMV__getPopupForContainer(aNode) {
-          if (this._self._resultNode == aNode)
-            return this._self;
-
-          for (let i = 0; i < this._self._containerNodesMap.length; i++) {
-            if (this._self._containerNodesMap[i].resultNode == aNode)
-              return this._self._containerNodesMap[i].domNode;
-          }
-          throw("Container view not found");
-        },
-
         get result() {
           return this._self._result;
         },
 
         set result(val) {
           // some methods (e.g. getURLsFromContainer) temporarily null out the
           // viewer when they do temporary changes to the view, this does _not_
           // call setResult(null), but then, we're called again with the result
           // object which is already set for this viewer. At that point,
           // we should do nothing.
           if (this._self._result != val) {
             if (this._self._result)
-              this._self._result.root.containerOpen = false;
-            this._self._containerNodesMap = [];
+              this._self._resultNode.containerOpen = false;
+
             this._self._result = val;
-            if (val) // this calls _rebuild through invalidateContainer
-              val.root.containerOpen = true;
+            if (val) {
+              this._self._resultNode = val.root;
+              this._self._resultNode._DOMElement = this._self;
+              // This calls _rebuild through invalidateContainer.
+              this._self._resultNode.containerOpen = true;
+            }
+            else
+              this._self._resultNode = null;
           }
           return val;
         },
 
-        itemInserted: function TV_V_itemInserted(aParentNode, aNode, aIndex) {
-          // don't insert new items into the toolbar
-          // if the parent is not the root 
-          if (aParentNode == this._self.getResultNode()) {
-            var children = this._self.childNodes;
+        nodeInserted: function TV_V_nodeInserted(aParentNode, aNode, aIndex) {
+          let parentElt = aParentNode._DOMElement;
+          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
+
+          if (parentElt == this._self) {
+            // Node is on the toolbar.
+            let children = this._self.childNodes;
             this._self.insertNewItem(aNode,
               aIndex < children.length ? children[aIndex] : null);
             this._self.updateChevron();
           }
-          else {
-            var popup = this._getPopupForContainer(aParentNode);
-            if (!popup._built)
-              return;
-
-            var before = popup.childNodes[aIndex] || null;
+          else if (parentElt._built) {
+            // Node is within a built menu.
+            let popup = parentElt.firstChild;
+            let before = popup.childNodes[aIndex] || null;
             this._self.insertNewItemToPopup(aNode, popup, before);
             if (popup._emptyMenuItem)
               popup._emptyMenuItem.hidden = true;
           }
         },
 
-        itemRemoved: function TV_V_itemRemoved(aParentNode, aNode, aIndex) {
-          if (aParentNode == this._self.getResultNode()) {
-            var children = this._self.childNodes;
-            for (let i = 0; i < children.length; i++) {
-              if (children[i].node == aNode) {
-                this._self.removeItem(children[i]);
-                this._self.updateChevron();
-                return;
-              }
-            }
+        nodeRemoved: function TV_V_nodeRemoved(aParentNode, aNode, aIndex) {
+          let parentElt = aParentNode._DOMElement;
+          let nodeElt = aNode._DOMElement;
+
+          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
+          NS_ASSERT(nodeElt, "node must have _DOMElement set");
+
+          if (parentElt == this._self) {
+            // Node is on the toolbar.
+            this._self.removeChild(nodeElt);
+            this._self.updateChevron();
           }
-          else {
-            var popup = this._getPopupForContainer(aParentNode);
-            if (!popup._built)
-              return;
+          else if (parentElt._built) {
+            // Node is within a built menu.
+            var popup = parentElt.firstChild;
+            popup.removeChild(nodeElt);
+            if (!popup.hasChildNodes() ||
+                (popup.childNodes.length == 1 &&
+                popup.firstChild == popup._emptyMenuItem))
+              this._self._showEmptyMenuItem(popup);
 
-            var children = popup.childNodes;
-            for (let i = popup._startMarker + 1; i < children.length; i++) {
-              if (children[i].node == aNode) {
-                this._self.removeItem(children[i]);
-                if (!popup.hasChildNodes() ||
-                    (popup.childNodes.length == 1 &&
-                     popup.firstChild == popup._emptyMenuItem)) {
-                  this._self._showEmptyMenuItem(popup);
-                }
-                if (popup._endMarker != -1)
-                  popup._endMarker--;
-                return;
-              }
-            }
+            if (popup._endMarker != -1)
+              popup._endMarker--;
           }
         },
 
-        itemMoved:
-        function TV_V_itemMoved(aItem, aOldParent, aOldIndex, aNewParent,
-                                aNewIndex) {
-          // This cannot actually happen yet (see IDL)
-          if (aNewParent != aOldParent)
+        nodeMoved:
+        function TV_V_nodeMoved(aNode,
+                                aOldParent, aOldIndex,
+                                aNewParent, aNewIndex) {
+          // Note: the current implementation of moveItem does not actually
+          // use this notification when the item in question is moved from one
+          // folder to another.  Instead, it calls nodeRemoved and nodeInserted
+          // for the two folders.  Thus, we can assume aOldParent == aNewParent.
+
+          let nodeElt = aNode._DOMElement;
+          NS_ASSERT(nodeElt, "node must have _DOMElement set");
+
+          // If our root node is a folder, it might be moved. There's nothing
+          // we need to do in that case.
+          if (nodeElt == this._self)
             return;
 
-          if (aNewParent == this._self.getResultNode()) {
-            var children = this._self.childNodes;
-            for (let i = 0; i < children.length; i++) {
-              var button = children[i];
-              if (button.node == aItem) {
-                this._self.removeChild(button);
-                this._self.insertBefore(button, children[aNewIndex]);
-                // If the chevron popup is open, keep it in sync.
-                if (this._self._chevron.open) {
-                  var chevronPopup = this._self._chevronPopup;
-                  var menuitem = chevronPopup.childNodes[i];
-                  chevronPopup.removeChild(menuitem);
-                  chevronPopup.insertBefore(menuitem,
-                                            chevronPopup.childNodes[aNewIndex]);
-                }
-                this._self.updateChevron();
-                return;
-              }
+          let parentElt = aNewParent._DOMElement;
+          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
+
+          if (parentElt == this._self) {
+            // Container is on the toolbar.
+
+            // Move the node.
+            this._self.removeChild(nodeElt);
+            this._self.insertBefore(nodeElt, this._self.childNodes[aNewIndex]);
+
+            // If the chevron popup is open, keep it in sync.
+            if (this._self._chevron.open) {
+              let chevronPopup = this._self._chevronPopup;
+              let menuitem = chevronPopup.childNodes[aOldIndex];
+              chevronPopup.removeChild(menuitem);
+              chevronPopup.insertBefore(menuitem,
+                                        chevronPopup.childNodes[aNewIndex]);
             }
+            this._self.updateChevron();
+          }
+          else if (parentElt._built) {
+            // Container is within a built menu.
+
+            // parentElt is the <menu> element for the container,
+            // we need the <menupopup>.
+            var popup = parentElt.firstChild;
+
+            // Move the node.
+            popup.removeChild(nodeElt);
+            popup.insertBefore(nodeElt, popup.childNodes[aNewIndex]);
+          }
+        },
+
+        nodeTitleChanged: function TV_V_nodeTitleChanged(aNode, aNewTitle) {
+          let nodeElt = aNode._DOMElement;
+          NS_ASSERT(nodeElt, "node must have _DOMElement set");
+
+          // There's no UI representation for the root node, thus there's
+          // nothing to be done when the title changes.
+          if (nodeElt == this._self)
+            return;
+
+          if (nodeElt.parentNode == this._self) {
+            // Node is on the toolbar
+            nodeElt.label = aNewTitle;
+            this._self.updateChevron();
           }
           else {
-            var popup = this._getPopupForContainer(aNewParent);
-            var children = popup.childNodes;
-            for (let i = popup._startMarker + 1; i < children.length; i++) {
-              var menuItem = children[i];
-              if (menuItem.node == aItem) {
-                popup.removeChild(menuItem);
-                popup.insertBefore(menuItem, children[aNewIndex]);
-                return;
-              }
-            }
+            // Node is within a built menu.
+            nodeElt.label = aNewTitle || PlacesUIUtils.getBestTitle(aNode);
           }
         },
 
-        itemChanged: function TV_V_itemChanged(aNode) {
-          // this check can be removed once we fix bug #382397
-          var parentNode = aNode.parent;
-          if (!parentNode)
+        nodeURIChanged: function TV_V_nodeURIChanged(aNode, aURIString) {
+          let nodeElt = aNode._DOMElement;
+          NS_ASSERT(nodeElt, "node must have _DOMElement set");
+
+          nodeElt.setAttribute("scheme",
+                               PlacesUIUtils.guessUrlSchemeForUI(aURIString));
+        },
+
+        nodeIconChanged: function TV_V_nodeIconChanged(aNode) {
+          let nodeElt = aNode._DOMElement;
+          NS_ASSERT(nodeElt, "node must have _DOMElement set");
+
+          // There's no UI representation for the root node, thus there's
+          // nothing to be done when the icon changes.
+          if (nodeElt == this._self)
             return;
 
-          if (PlacesUtils.nodeIsSeparator(aNode)) {
-            // nothing to do when a separator changes
-            return;
-          }
-
-          var element;
-          var onToolbar = false;
-          if (parentNode == this._self.getResultNode()) {
-            onToolbar = true;
-            var children = this._self.childNodes;
-            for (let i = 0; i < children.length; i++) {
-              if (children[i].node == aNode) {
-                element = children[i];
-                break;
-              }
-            }
-            // Don't replace title on toolbarbuttons
-            var title = aNode.title;
-          }
-          else {
-            var popup = this._getPopupForContainer(parentNode);
-            if (!popup._built)
-              return;
-
-            var children = popup.childNodes;
-            for (let i = popup._startMarker + 1; i < children.length; i++) {
-              if (children[i].node == aNode) {
-                element = children[i];
-                break;
-              }
-            }
-            var title = PlacesUIUtils.getBestTitle(aNode);
-          }
-
-          var iconURI = aNode.icon;
-          if (iconURI) {
-            var spec = iconURI.spec;
-            if (element.getAttribute("image") != spec)
-              element.setAttribute("image", spec);
+          let icon = aNode.icon;
+          if (icon) {
+            if (nodeElt.getAttribute("image") != icon)
+              nodeElt.setAttribute("image", icon);
           }
           else
-            element.removeAttribute("image");
-
-          if (element.getAttribute("label") != title) {
-            element.setAttribute("label", title);
-            if (onToolbar)
-              this._self.updateChevron();
-          }
+            nodeElt.removeAttribute("image");
+        },
 
-          if (PlacesUtils.nodeIsLivemarkContainer(aNode)) {
-            if (!element.hasAttribute("livemark"))
-              element.setAttribute("livemark", "true");
-            // If this is a livemark container check if the status menuitem has
-            // to be added or removed.
-            PlacesUIUtils.ensureLivemarkStatusMenuItem(element.firstChild);
-          }
-          else if (PlacesUtils.nodeIsURI(aNode)) {
-            element.setAttribute("scheme", PlacesUIUtils.guessUrlSchemeForUI(aNode.uri));
+        nodeAnnotationChanged:
+        function TV_V_nodeAnnotationChanged(aNode, aAnno) {
+          // Ensure the changed annotation is a livemark one.
+          if (/^livemark\//.test(aAnno) &&
+              PlacesUtils.nodeIsLivemarkContainer(aNode)) {
+            let nodeElt = aNode._DOMElement;
+            NS_ASSERT(nodeElt, "node must have _DOMElement set");
+
+            if (!nodeElt.hasAttribute("livemark"))
+              nodeElt.setAttribute("livemark", "true");
+
+            // Add or remove the livemark status menuitem.
+            PlacesUIUtils.ensureLivemarkStatusMenuItem(nodeElt.firstChild);
           }
         },
 
-        itemReplaced:
-        function TV_V_itemReplaced(aParentNode, aOldNode, aNewNode, aIndex) {
-          if (aParentNode == this._self.getResultNode()) {
-            var children = this._self.childNodes;
-            for (let i = 0; i < children.length; i++) {
-              if (children[i].node == aOldNode) {
-                var next = children[i].nextSibling;
-                this._self.removeItem(children[i]);
-                this._self.insertNewItem(aNewNode, next);
-                this._self.updateChevron();
-                return;
-              }
-            }
+        nodeHistoryDetailsChanged: function() { },
+        nodeTagsChanged: function() { },
+        nodeDateAddedChanged: function() { },
+        nodeLastModifiedChanged: function() { },
+        nodeKeywordChanged: function() { },
+
+        nodeReplaced:
+        function TV_V_nodeReplaced(aParentNode, aOldNode, aNewNode, aIndex) {
+          let nodeElt = aOldNode._DOMElement;
+          NS_ASSERT(nodeElt, "node must have _DOMElement set");
+
+          // No worries: If nodeElt is the last item (i.e. no nextSibling),
+          // insertNewItem/insertNewItemToPopup will insert the new element as
+          // the last item.
+          let next = nodeElt.nextSibling;
+
+          let parentElt = aParentNode._DOMElement;
+          NS_ASSERT(parentElt, "parent node must have _DOMElement set");
+          if (parentElt == this._self) {
+            // Node is on the toolbar.
+            this._self.removeItem(nodeElt);
+            this._self.insertNewItem(aNewNode, next);
+            this._self.updateChevron();
+          }
+          else if (parentElt._built) {
+            // Node is within a built menu.
+            let popup = parentElt.firstChild;
+            popup.removeItem(nodeElt);
+            this._self.insertNewItemToPopup(aNewNode, popup, next);
           }
         },
 
-        containerOpened: function TV_V_containerOpened(aNode) {
-          this.invalidateContainer(aNode);
+        containerOpened: function TV_V_containerOpened(aContainer) {
+          this.invalidateContainer(aContainer);
         },
 
-        containerClosed: function TV_V_containerClosed(aNode) {
-          this.invalidateContainer(aNode);
+        containerClosed: function TV_V_containerClosed(aContainer) {
+          this.invalidateContainer(aContainer);
         },
 
         invalidateContainer: function TV_V_invalidateContainer(aContainer) {
-          if (aContainer == this._self.getResultNode()) {
-            this._self._containerNodesMap.splice(0);
-            this._self._rebuild();
-            return;
-          }
-
-          function isChildOf(node, container) {
-            var parent = node.parent;
-            while (parent) {
-              if (parent == container)
-                return true;
-              parent = parent.parent;
-            }
-            return false;
-          }
+          let containerNodeElt = aContainer._DOMElement;
+          NS_ASSERT(containerNodeElt, "node must have _DOMElement set");
 
-          var popupToRebuild = null;
-          for (let i = 0; i < this._self._containerNodesMap.length; i++) {
-            var node = this._self._containerNodesMap[i].resultNode;
-            
-            if (node == aContainer)
-              popupToRebuild = this._self._containerNodesMap[i].domNode;
-            if (isChildOf(node, aContainer)) {
-              this._self._containerNodesMap.splice(i,1);
-              i--;
-            }
+          if (containerNodeElt == this._self) {
+            // Container is the toolbar itself.
+            this._self._rebuild();
           }
-
-          if (popupToRebuild) {
-            popupToRebuild._built = false;
-
-            // if the menupopup is open we should live-update it
-            if (popupToRebuild.parentNode.open)
-              this._self._rebuildPopup(popupToRebuild);
+          else if (containerNodeElt._built) {
+            // Container is a built menu.
+            containerNodeElt._built = false;
+            // If the menupopup is open we should live-update it.
+            if (containerNodeElt.open)
+              this._self._rebuildPopup(containerNodeElt.firstChild);
           }
         },
 
-        invalidateAll: function TV_V_invalidateAll() {
-          this._self._containerNodesMap.splice(0);
-          this._self._rebuild();
-        },
-
         sortingChanged: function TV_V_sortingChanged(aSortingMode) {
         }
       })]]></field>
 
       <property name="selType" onget="return 'single';"/>
 
       <method name="buildContextMenu">
         <parameter name="aPopup"/>
@@ -803,18 +796,17 @@
         ]]></body>
       </method>
 
       <method name="insertNewItemToPopup">
         <parameter name="aChild"/>
         <parameter name="aParentPopup"/>
         <parameter name="aBefore"/>
         <body><![CDATA[
-          var element =
-            PlacesUIUtils.createMenuItemForNode(aChild, this._containerNodesMap);
+          var element = PlacesUIUtils.createMenuItemForNode(aChild);
 
           if (aBefore)
             aParentPopup.insertBefore(element, aBefore);
           else {
             // Add the new element to the menu.  If there is static content at
             // the end of the menu, add the element before that.  Otherwise,
             // just add to the end.
             if (aParentPopup._endMarker != -1) {
@@ -828,17 +820,17 @@
           if (aParentPopup._endMarker != -1)
             aParentPopup._endMarker++;
         ]]></body>
       </method>
 
       <method name="_containerPopupShowing">
         <parameter name="aPopup"/>
         <body><![CDATA[
-          if (!aPopup._built)
+          if (!aPopup.parentNode._built)
             this._rebuildPopup(aPopup);
         ]]></body>
       </method>
 
       <method name="_rebuildPopup">
         <parameter name="aPopup"/>
         <body><![CDATA[
           PlacesUIUtils.cleanPlacesPopup(aPopup);
@@ -863,17 +855,17 @@
             }
           }
           else {
             // This menu is empty.  If there is no static content, add
             // an element to show it is empty.
             if (aPopup._startMarker == -1 && aPopup._endMarker == -1)
               this._showEmptyMenuItem(aPopup);
           }
-          aPopup._built = true;
+          aPopup.parentNode._built = true;
         ]]></body>
       </method>
 
       <field name="_overFolder"><![CDATA[
        (
          // Menu buttons should be opened when the mouse drags over them, and
          // closed when the mouse drags off. This object manages opening and
          // closing of folders when the mouse hovers.
@@ -909,17 +901,17 @@
         <body><![CDATA[
           // This function returns information about where to drop when
           // dragging over the toolbar.
           // The returned object has 3 properties:
           // - ip: the insertion point for the bookmarks service.
           // - beforeIndex: child index to drop before, for the drop indicator.
           // - folderNode: the folder to drop into, if applicable.
           var result = this.getResult();
-          if (!PlacesUtils.nodeIsFolder(result.root))
+          if (!PlacesUtils.nodeIsFolder(this._resultNode))
             return null;
 
           var dropPoint = { ip: null, beforeIndex: null, folderNode: null };
           var xulNode = aEvent.target;
           if (xulNode.node) {
             let nodeRect = xulNode.getBoundingClientRect();
             let nodeIndex = Array.indexOf(this.childNodes, xulNode);
             if (PlacesUtils.nodeIsFolder(xulNode.node) &&
@@ -927,17 +919,17 @@
               // This is a folder.
               // If we are in the middle of it, drop inside it.
               // Otherwise, drop before it, with regards to RTL mode.
               let threshold = nodeRect.width * 0.25;
               if (this._isRTL ? (aEvent.clientX > nodeRect.right - threshold)
                               : (aEvent.clientX < nodeRect.left + threshold)) {
                 // Drop before this folder.
                 dropPoint.ip =
-                  new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
+                  new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
                                      nodeIndex, Ci.nsITreeView.DROP_BEFORE);
                 dropPoint.beforeIndex = nodeIndex;
               }
               else if (this._isRTL ? (aEvent.clientX > nodeRect.left + threshold)
                                    : (aEvent.clientX < nodeRect.right - threshold)) {
                 // Drop inside this folder.
                 dropPoint.ip =
                   new InsertionPoint(PlacesUtils.getConcreteItemId(xulNode.node),
@@ -946,49 +938,49 @@
                 dropPoint.beforeIndex = nodeIndex;
                 dropPoint.folderNode = xulNode;
               }
               else {
                 // Drop after this folder.
                 let beforeIndex =
                   (nodeIndex == this.childNodes.length - 1) ? -1 : nodeIndex + 1;
                 dropPoint.ip =
-                  new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
+                  new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
                                      beforeIndex, Ci.nsITreeView.DROP_BEFORE);
                 dropPoint.beforeIndex = beforeIndex;
               }
             }
             else {
               // This is a non-folder node or a read-only folder.
               // Drop before it with regards to RTL mode.
               let threshold = nodeRect.width * 0.5;
               if (this._isRTL ? (aEvent.clientX > nodeRect.left + threshold)
                               : (aEvent.clientX < nodeRect.left + threshold)) {
                 // Drop before this bookmark.
                 dropPoint.ip =
-	                new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
+	                new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
 	                                   nodeIndex, Ci.nsITreeView.DROP_BEFORE);
                 dropPoint.beforeIndex = nodeIndex;
               }
               else {
                 // Drop after this bookmark.
                 let beforeIndex =
                   nodeIndex == this.childNodes.length - 1 ? -1 : nodeIndex + 1;
                 dropPoint.ip =
-                  new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
+                  new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
                                      beforeIndex, Ci.nsITreeView.DROP_BEFORE);
                 dropPoint.beforeIndex = beforeIndex;
               }
             }
           }
           else {
             // We are most likely dragging on the empty area of the
             // toolbar, we should drop after the last node.
             dropPoint.ip =
-              new InsertionPoint(PlacesUtils.getConcreteItemId(result.root),
+              new InsertionPoint(PlacesUtils.getConcreteItemId(this._resultNode),
                                  -1, Ci.nsITreeView.DROP_BEFORE);
             dropPoint.beforeIndex = -1;
           }
 
           return dropPoint;
         ]]></body>
       </method>
 
@@ -1211,17 +1203,17 @@
         if (this._overFolder.node)
             this._overFolder.closeTimer = this._setTimer(this._overFolder.hoverTime);
       ]]></handler>
 
       <handler event="dragend"><![CDATA[
         this._draggedNode = null;
       ]]></handler>
 
-      <handler event="popupshowing" phase="capturing"><![CDATA[      
+      <handler event="popupshowing" phase="capturing"><![CDATA[
         if (!this._allowPopupShowing) {
           this._allowPopupShowing = true;
           event.preventDefault();
           return;
         }
 
         var popup = event.originalTarget;
 
--- a/browser/components/places/content/tree.xml
+++ b/browser/components/places/content/tree.xml
@@ -131,42 +131,27 @@
                                                   options);
           var callback;
           if (this.flatList) {
             var onOpenFlatContainer = this.onOpenFlatContainer;
             if (onOpenFlatContainer)
               callback = new Function("aContainer", onOpenFlatContainer);
           }
 
-          var treeView = new PlacesTreeView(this.showRoot, this.flatList, callback);
+          var treeView = new PlacesTreeView(this.flatList, callback);
           result.viewer = treeView;
           this.view = treeView;
           if (!this._controller) {
             this._controller = new PlacesController(this);
             this.controllers.appendController(this._controller);
           }
           this._cachedInsertionPoint = undefined;
         ]]></body>
       </method>
 
-      <property name="showRoot">
-        <getter><![CDATA[
-          return this.getAttribute("showRoot") == "true";
-        ]]></getter>
-        <setter><![CDATA[
-          if (this.showRoot != val) {
-            this.setAttribute("showRoot", val);
-            // reload with the last place set
-            if (this.place)
-              this.place = this.place;
-          }
-          return val;
-        ]]></setter>
-      </property>
-
       <property name="flatList">
         <getter><![CDATA[
           return this.getAttribute("flatList") == "true";
         ]]></getter>
         <setter><![CDATA[
           if (this.flatList != val) {
             this.setAttribute("flatList", val);
             // reload with the last place set
@@ -254,17 +239,17 @@
       <!-- 
         Causes a particular node to be selected in the tree, resulting in all 
         containers above the node in the hierarchy to be opened, so that the
         node is visible. 
         -->
       <method name="selectNode">
         <parameter name="node"/>
         <body><![CDATA[ 
-          var view = this.getResultView();
+          var view = this.view;
 
           var parent = node.parent;
           if (parent && !parent.containerOpen) {
             // Build a list of all of the nodes that are the parent of this one 
             // in the result. 
             var parents = [];
             var root = this.getResultNode();
             while (parent && parent != root) {
@@ -303,27 +288,16 @@
 
       <!-- nsIPlacesView -->
       <method name="getResultNode">
         <body><![CDATA[
           return this.getResult().root;
         ]]></body>
       </method>
 
-      <method name="getResultView">
-        <body><![CDATA[
-          try {
-            return this.view.QueryInterface(Ci.nsINavHistoryResultTreeViewer);
-          }
-          catch (e) {
-          }
-          return null;
-        ]]></body>
-      </method>
-
       <!-- nsIPlacesView -->
       <property name="place">
         <getter><![CDATA[
           return this.getAttribute("place");
         ]]></getter>
         <setter><![CDATA[
           this.setAttribute("place", val);
 
@@ -350,17 +324,17 @@
       </property>
       
       <!-- nsIPlacesView -->
       <method name="getSelectionNodes">
         <body><![CDATA[ 
           var selection = this.view.selection;
           var rc = selection.getRangeCount();
           var nodes = [];
-          var resultview = this.getResultView();
+          var resultview = this.view;
           for (var i = 0; i < rc; ++i) {
             var min = { }, max = { };
             selection.getRangeAt(i, min, max);
 
             for (var j = min.value; j <= max.value; ++j)
               nodes.push(resultview.nodeForTreeIndex(j));
           }
           return nodes;
@@ -391,17 +365,17 @@
           // ... returning http://www.bar.com/ as part of the selection is 
           // redundant because it is implied by removing "Some Folder". We 
           // filter out all such redundancies since some partial amount of
           // the folder's children may be selected.          
           //
           var selection = this.view.selection;
           var rc = selection.getRangeCount();
           var nodes = [];
-          var resultview = this.getResultView();
+          var resultview = this.view;
           // This list is kept independently of the range selected (i.e. OUTSIDE
           // the for loop) since the row index of a container is unique for the
           // entire view, and we could have some really wacky selection and we
           // don't want to blow up.
           var containers = { };
           for (var i = 0; i < rc; ++i) {
             var range = [];
             var min = { }, max = { };
@@ -432,17 +406,17 @@
           var view = this.view;
           if (view.selection.count != 1)
             return null;
 
           var selection = view.selection;
           var min = { }, max = { };
           selection.getRangeAt(0, min, max);
 
-          return this.getResultView().nodeForTreeIndex(min.value);
+          return this.view.nodeForTreeIndex(min.value);
         ]]></getter>
       </property>
 
       <!-- nsIPlacesView -->
       <property name="insertionPoint">
         <getter><![CDATA[
           // invalidated on selection and focus changes
           if (this._cachedInsertionPoint !== undefined)
@@ -473,17 +447,17 @@
           //
           // Warning: It may be tempting to use tree indexes in this code, but
           //          you must not, since the tree is nested and as your tree 
           //          index may change when folders before you are opened and
           //          closed. You must convert your tree index to a node, and
           //          then use getIndexOfNode to find your absolute index in
           //          the parent container instead. 
           //
-          var resultView = this.getResultView();
+          var resultView = this.view;
           var selection = resultView.selection;
           var rc = selection.getRangeCount();
           var min = { }, max = { };
           selection.getRangeAt(rc - 1, min, max);
           
           // If the sole selection is a container, and we are not in
           // a flatlist, insert into it.
           // Note that this only applies to _single_ selections,
@@ -504,17 +478,17 @@
         ]]></getter>
       </property>
 
       <method name="_getInsertionPoint">
         <parameter name="index"/>
         <parameter name="orientation"/>
         <body><![CDATA[ 
           var result = this.getResult();
-          var resultview = this.getResultView();
+          var resultview = this.view;
           var container = result.root;
           var dropNearItemId = -1;
           NS_ASSERT(container, "null container");
           // When there's no selection, assume the container is the container
           // the view is populated from (i.e. the result's itemId).
           if (index != -1) {
             var lastSelected = resultview.nodeForTreeIndex(index);
             if (resultview.isContainer(index) && orientation == Ci.nsITreeView.DROP_ON) {
@@ -668,17 +642,17 @@
           var result = this.getResult();
           var oldViewer = result.viewer;
           result.viewer = null;
           findNodes(this.getResultNode());
           result.viewer = oldViewer;
 
           // For all the nodes we've found, highlight the corresponding
           // index in the tree.
-          var resultview = this.getResultView();
+          var resultview = this.view;
           var selection = this.view.selection;
           selection.selectEventsSuppressed = true;
           selection.clearSelection();
           // Open nodes containing found items
           for (var i = 0; i < nodesToOpen.length; i++) {
             nodesToOpen[i].containerOpen = true;
           }
           for (var i = 0; i < nodes.length; i++) {
@@ -724,17 +698,17 @@
         <body><![CDATA[
           // Cache the dataTransfer for the view
           PlacesControllerDragHelper.currentDataTransfer = aEvent.dataTransfer;
 
           var row = { }, col = { }, child = { };
           this.treeBoxObject.getCellAt(aEvent.clientX, aEvent.clientY,
                                        row, col, child);
           var node = row.value != -1 ?
-                     this.getResultView().nodeForTreeIndex(row.value) :
+                     this.view.nodeForTreeIndex(row.value) :
                      this.getResultNode();
           // cache the dropTarget for the view
           PlacesControllerDragHelper.currentDropTarget = node;
 
           // We have to calculate the orientation since view.canDrop will use
           // it and we want to be consistent with the dropfeedback
           var tbo = this.treeBoxObject;
           var rowHeight = tbo.rowHeight;
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -72,119 +72,45 @@ PlacesTreeView.prototype = {
         aIID.equals(Ci.nsINavHistoryResultTreeViewer) ||
         aIID.equals(Ci.nsISupports))
       return this;
 
     throw Cr.NS_ERROR_NO_INTERFACE;
   },
 
   /**
-   * This is called when the result or tree may have changed.
-   * It reinitializes everything. Result and/or tree can be null
-   * when calling.
+   * This is called once both the result and the tree are set.
    */
   _finishInit: function PTV__finishInit() {
-    if (this._tree && this._result)
-      this.sortingChanged(this._result.sortingMode);
-
-    var qoInt = Ci.nsINavHistoryQueryOptions;
-    var options = asQuery(this._result.root).queryOptions;
-
-    // if there is no tree, BuildVisibleList will clear everything for us
-    this._buildVisibleList();
-  },
-
-  _computeShowSessions: function PTV__computeShowSessions() {
-    NS_ASSERT(this._result, "Must have a result to show sessions!");
-    this._showSessions = false;
-
-    var options = asQuery(this._result.root).queryOptions;
-    NS_ASSERT(options, "navHistoryResults must have valid options");
-
-    if (!options.showSessions)
-      return; // sessions are off
-
-    var resultType = options.resultType;
-    if (resultType != Ci.nsINavHistoryQueryOptions.RESULTS_AS_VISIT &&
-        resultType != Ci.nsINavHistoryQueryOptions.RESULTS_AS_FULL_VISIT)
-      return; // not visits
-
-    var sortType = this._result.sortingMode;
-    if (sortType != nsINavHistoryQueryOptions::SORT_BY_DATE_ASCENDING &&
-        sortType != nsINavHistoryQueryOptions::SORT_BY_DATE_DESCENDING)
-      return; // not date sorting
-
-    this._showSessions = true;
-  },
-
-  SESSION_STATUS_NONE: 0,
-  SESSION_STATUS_START: 1,
-  SESSION_STATUS_CONTINUE: 2,
-  _getRowSessionStatus: function PTV__getRowSessionStatus(aRow) {
-    var node = this._visibleElements[aRow].node;
-    if (!PlacesUtils.nodeIsVisit(node) || asVisit(node).sessionId == 0)
-      return this.SESSION_STATUS_NONE;
-
-    if (aRow == 0)
-      return this.SESSION_STATUS_START;
-
-    var previousNode = this._visibleElements[aRow - 1].node;
-    if (!PlacesUtils.nodeIsVisit(previousNode) ||
-        node.sessionId != asVisit(previousNode).sessionId)
-      return this.SESSION_STATUS_START;
-
-    return this.SESSION_STATUS_CONTINUE;
-  },
-
-  /**
-   * Call to completely rebuild the list of visible items. Note if there is no
-   * tree or root this will just clear out the list, so you can also call this
-   * when a tree is detached to clear the list.
-   */
-  _buildVisibleList: function PTV__buildVisibleList() {
     var selection = this.selection;
     if (selection)
       selection.selectEventsSuppressed = true;
 
-    if (this._result) {
-      // Any current visible elements need to be marked as invisible.
-      for (var i = 0; i < this._visibleElements.length; i++) {
-        this._visibleElements[i].node.viewIndex = -1;
-      }
+    this._rootNode._viewIndex = -1;
+    if (!this._rootNode.containerOpen) {
+      // This triggers containerOpened which then builds the visible section.
+      this._rootNode.containerOpen = true;
     }
-
-    var rootNode = this._result.root;
-    if (rootNode && this._tree) {
-      this._computeShowSessions();
+    else
+      this.invalidateContainer(this._rootNode);
 
-      asContainer(rootNode);
-      if (this._showRoot) {
-        // List the root node
-        this._visibleElements.push(
-          { node: this._result.root, properties: null });
-        this._tree.rowCountChanged(0, 1);
-        this._result.root.viewIndex = 0;
-      }
-      else if (!rootNode.containerOpen) {
-        // this triggers containerOpened which then builds the visible
-        // section
-        rootNode.containerOpen = true;
-      }
-      else
-        this.invalidateContainer(rootNode);
-    }
+    // "Activate" the sorting column and update commands.
+    this.sortingChanged(this._result.sortingMode);
+
     if (selection)
       selection.selectEventsSuppressed = false;
   },
 
+  _rootNode: null,
+
   /**
    * This takes a container and recursively appends visible elements to the
    * given array. This is used to build the visible element list (with
    * this._visibleElements passed as the array), or portions thereof (with
-   * a separate array that is merged with the main list later.
+   * a separate array that is merged with the main list later).
    *
    * aVisibleStartIndex is the visible index of the beginning of the 'aVisible'
    * array. When aVisible is this._visibleElements, this is 0. This is non-zero
    * when we are building up a sub-region for insertion. Then, this is the
    * index where the new array will be inserted into this._visibleElements.
    * It is used to compute each node's viewIndex.
    */
   _buildVisibleSection:
@@ -192,147 +118,148 @@ PlacesTreeView.prototype = {
   {
     if (!aContainer.containerOpen)
       return;  // nothing to do
 
     const openLiteral = PlacesUIUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open");
     const trueLiteral = PlacesUIUtils.RDF.GetLiteral("true");
 
     var cc = aContainer.childCount;
+    var sortingMode = this._result.sortingMode;
     for (var i=0; i < cc; i++) {
       var curChild = aContainer.getChild(i);
       var curChildType = curChild.type;
 
-      // don't display separators when sorted
+      // Don't display separators when sorted.
       if (curChildType == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR) {
-        if (this._result.sortingMode !=
-            Ci.nsINavHistoryQueryOptions.SORT_BY_NONE) {
-          curChild.viewIndex = -1;
+        if (sortingMode != Ci.nsINavHistoryQueryOptions.SORT_BY_NONE) {
+          curChild._viewIndex = -1;
           continue;
         }
       }
 
-      // add item
-      curChild.viewIndex = aVisibleStartIndex + aVisible.length;
-      aVisible.push({ node: curChild, properties: null });
+      // Add the node to the visible-nodes array and set its viewIndex.
+      curChild._viewIndex = aVisibleStartIndex + aVisible.length;
+      aVisible.push(curChild);
 
-      // recursively do containers
-      if (!this._flatList && PlacesUtils.containerTypes.indexOf(curChildType) != -1) {
-        asContainer(curChild);
-
+      // Recursively do containers.
+      if (!this._flatList &&
+          curChild instanceof Ci.nsINavHistoryContainerResultNode) {
         var resource = this._getResourceForNode(curChild);
         var isopen = resource != null &&
                      PlacesUIUtils.localStore.HasAssertion(resource, openLiteral,
                                                            trueLiteral, true);
         if (isopen != curChild.containerOpen)
           aToOpen.push(curChild);
         else if (curChild.containerOpen && curChild.childCount > 0)
           this._buildVisibleSection(curChild, aVisible, aToOpen, aVisibleStartIndex);
       }
     }
   },
 
   /**
-   * This counts how many rows an item takes in the tree, that is, the
-   * item itself plus any nodes following it with an increased indent.
-   * This allows you to figure out how many rows an item (=1) or a
-   * container with all of its children takes.
+   * This counts how many rows a node takes in the tree.  For containers it
+   * will count the node itself plus any child node following it.
    */
-  _countVisibleRowsForItem: function PTV__countVisibleRowsForItem(aNode) {
-    if (aNode == this._result.root)
+  _countVisibleRowsForNode: function PTV__countVisibleRowsForNode(aNode) {
+    if (aNode == this._rootNode)
       return this._visibleElements.length;
 
-    var viewIndex = aNode.viewIndex;
-    NS_ASSERT(viewIndex >= 0, "Item is not visible, no rows to count");
+    var viewIndex = aNode._viewIndex;
+    NS_ASSERT(viewIndex >= 0, "Node is not visible, no rows to count");
     var outerLevel = aNode.indentLevel;
     for (var i = viewIndex + 1; i < this._visibleElements.length; i++) {
-      if (this._visibleElements[i].node.indentLevel <= outerLevel)
+      if (this._visibleElements[i].indentLevel <= outerLevel)
         return i - viewIndex;
     }
     // this node plus its children occupy the bottom of the list
     return this._visibleElements.length - viewIndex;
   },
 
   /**
    * This is called by containers when they change and we need to update
    * everything about the container. We build a new visible section with
    * the container as a separate object so we first know how the list
-   * changes. This way we only have to do one realloc/memcpy to update
-   * the list.
+   * changes.
    *
    * We also try to be smart here about redrawing the screen.
    */
   _refreshVisibleSection: function PTV__refreshVisibleSection(aContainer) {
     NS_ASSERT(this._result, "Need to have a result to update");
     if (!this._tree)
       return;
 
-    // The root node is invisible if showRoot is not set. Otherwise aContainer
-    // must be visible
-    if (this._showRoot || aContainer != this._result.root) {
-      if (aContainer.viewIndex < 0 ||
-          aContainer.viewIndex > this._visibleElements.length)
+    // The root node is invisible.
+    if (aContainer != this._rootNode) {
+      if (aContainer._viewIndex < 0 ||
+          aContainer._viewIndex > this._visibleElements.length)
         throw "Trying to expand a node that is not visible";
 
-      NS_ASSERT(this._visibleElements[aContainer.viewIndex].node == aContainer,
+      NS_ASSERT(this._visibleElements[aContainer._viewIndex] == aContainer,
                 "Visible index is out of sync!");
     }
 
-    var startReplacement = aContainer.viewIndex + 1;
-    var replaceCount = this._countVisibleRowsForItem(aContainer);
+    var startReplacement = aContainer._viewIndex + 1;
+    var replaceCount = this._countVisibleRowsForNode(aContainer);
 
-    // We don't replace the container item itself so we decrease the
-    // replaceCount by 1. We don't do so though if there is no visible item
-    // for the container. This happens when aContainer is the root node and
-    // showRoot is not set.
-    if (aContainer.viewIndex != -1)
-      replaceCount-=1;
+    // We don't replace the container node itself so we should decrease the
+    // replaceCount by 1, unless the container is our root node, which isn't
+    // visible.
+    if (aContainer != this._rootNode)
+      replaceCount -= 1;
 
-    // Persist selection state
+    // Persist selection state.
     var previouslySelectedNodes = [];
     var selection = this.selection;
     var rc = selection.getRangeCount();
     for (var rangeIndex = 0; rangeIndex < rc; rangeIndex++) {
       var min = { }, max = { };
       selection.getRangeAt(rangeIndex, min, max);
       var lastIndex = Math.min(max.value, startReplacement + replaceCount -1);
-      // if this range does not overlap the replaced chunk we don't need to
+      // If this range does not overlap the replaced chunk, we don't need to
       // persist the selection.
       if (max.value < startReplacement || min.value > lastIndex)
         continue;
-      // if this range starts before the replaced chunk we should persist from
-      // startReplacement to lastIndex
+
+      // If this range starts before the replaced chunk, we should persist from
+      // startReplacement to lastIndex.
       var firstIndex = Math.max(min.value, startReplacement);
-      for (var nodeIndex = firstIndex; nodeIndex <= lastIndex; nodeIndex++)
+      for (var nodeIndex = firstIndex; nodeIndex <= lastIndex; nodeIndex++) {
+        // Mark the node invisible if we're about to remove it,
+        // otherwise we'll try to select it later.
+        var node = this._visibleElements[nodeIndex];
+        if (nodeIndex >= startReplacement &&
+            nodeIndex < startReplacement + replaceCount)
+          node._viewIndex = -1;
+
         previouslySelectedNodes.push(
-          { node: this._visibleElements[nodeIndex].node, oldIndex: nodeIndex });
+          { node: node, oldIndex: nodeIndex });
+      }
     }
 
-    // Mark the removes as invisible
-    for (var i = 0; i < replaceCount; i++)
-      this._visibleElements[startReplacement + i].node.viewIndex = -1;
-
     // Building the new list will set the new elements' visible indices.
     var newElements = [];
     var toOpenElements = [];
     this._buildVisibleSection(aContainer,
                               newElements, toOpenElements, startReplacement);
 
-    // actually update the visible list
+    // Actually update the visible list.
+    // XXX: We can probably make this more efficient using splice through
+    // Function.apply.
     this._visibleElements =
       this._visibleElements.slice(0, startReplacement).concat(newElements)
           .concat(this._visibleElements.slice(startReplacement + replaceCount,
                                               this._visibleElements.length));
 
     // If the new area has a different size, we'll have to renumber the
     // elements following the area.
     if (replaceCount != newElements.length) {
       for (var i = startReplacement + newElements.length;
-           i < this._visibleElements.length; i ++) {
-        this._visibleElements[i].node.viewIndex = i;
+           i < this._visibleElements.length; i++) {
+        this._visibleElements[i]._viewIndex = i;
       }
     }
 
     // now update the number of elements
     selection.selectEventsSuppressed = true;
     this._tree.beginUpdateBatch();
 
     if (replaceCount)
@@ -359,44 +286,49 @@ PlacesTreeView.prototype = {
     }
 
     this._tree.endUpdateBatch();
 
     // restore selection
     if (previouslySelectedNodes.length > 0) {
       for (var i = 0; i < previouslySelectedNodes.length; i++) {
         var nodeInfo = previouslySelectedNodes[i];
-        var index = nodeInfo.node.viewIndex;
+        var index = nodeInfo.node._viewIndex;
 
-        // if the same node was used (happens on sorting-changes),
-        // just use viewIndex
-        if (index == -1) { // otherwise, try to find an equal node
+        // If the nodes under the invalidated container were preserved, we can
+        // just use viewIndex.
+        if (index == -1) {
+          // Otherwise, try to find an equal node.
           var itemId = PlacesUtils.getConcreteItemId(nodeInfo.node);
-          if (itemId != 1) { // bookmark-nodes in queries case
+          if (itemId != 1) {
+            // Search by itemId.
             for (var j = 0; j < newElements.length && index == -1; j++) {
               if (PlacesUtils.getConcreteItemId(newElements[j]) == itemId)
-                index = newElements[j].viewIndex;
+                index = newElements[j]._viewIndex;
             }
           }
-          else { // history nodes
+          else {
+            // Search by uri.
             var uri = nodeInfo.node.uri;
             if (uri) {
               for (var j = 0; j < newElements.length && index == -1; j++) {
                 if (newElements[j].uri == uri)
-                  index = newElements[j].viewIndex;
+                  index = newElements[j]._viewIndex;
               }
             }
           }
         }
+
+        // Select the found node, if any.
         if (index != -1)
           selection.rangedSelect(index, index, true);
       }
 
-      // if only one node was previously selected and there's no selection now,
-      // select the node at its old-viewIndex, if any
+      // If only one node was previously selected and there's no selection now,
+      // select the node at its old viewIndex, if any.
       if (previouslySelectedNodes.length == 1 &&
           selection.getRangeCount() == 0 &&
           this._visibleElements.length > previouslySelectedNodes[0].oldIndex) {
         selection.rangedSelect(previouslySelectedNodes[0].oldIndex,
                                previouslySelectedNodes[0].oldIndex, true);
       }
     }
     selection.selectEventsSuppressed = false;
@@ -505,268 +437,320 @@ PlacesTreeView.prototype = {
         return [this.COLUMN_TYPE_TAGS, false];
       case Ci.nsINavHistoryQueryOptions.SORT_BY_TAGS_DESCENDING:
         return [this.COLUMN_TYPE_TAGS, true];
     }
     return [this.COLUMN_TYPE_UNKNOWN, false];
   },
 
   // nsINavHistoryResultViewer
-  itemInserted: function PTV_itemInserted(aParent, aItem, aNewIndex) {
+  nodeInserted: function PTV_nodeInserted(aParentNode, aNode, aNewIndex) {
     if (!this._tree)
       return;
     if (!this._result)
       throw Cr.NS_ERROR_UNEXPECTED;
 
-    if (PlacesUtils.nodeIsSeparator(aItem) &&
+    if (PlacesUtils.nodeIsSeparator(aNode) &&
         this._result.sortingMode != Ci.nsINavHistoryQueryOptions.SORT_BY_NONE) {
-      aItem.viewIndex = -1;
+      aNode._viewIndex = -1;
       return;
     }
 
-    // update parent when inserting the first item because twisty may
-    // have changed
-    if (aParent.childCount == 1)
-      this.itemChanged(aParent);
+    // Update parent when inserting the first item, since twisty may
+    // have changed.
+    if (aParentNode.childCount == 1)
+      this._tree.invalidateRow(aParentNode._viewIndex);
 
     // compute the new view index of the item
     var newViewIndex = -1;
     if (aNewIndex == 0) {
       // item is the first thing in our child list, it takes our index +1. Note
       // that this computation still works if the parent is an invisible root
       // node, because root_index + 1 = -1 + 1 = 0
-      newViewIndex = aParent.viewIndex + 1;
+      newViewIndex = aParentNode._viewIndex + 1;
     }
     else {
       // Here, we try to find the next visible element in the child list so we
       // can set the new visible index to be right before that. Note that we
       // have to search DOWN instead of up, because some siblings could have
       // children themselves that would be in the way.
-      for (var i = aNewIndex + 1; i < aParent.childCount; i ++) {
-        var viewIndex = aParent.getChild(i).viewIndex;
+      for (var i = aNewIndex + 1; i < aParentNode.childCount; i++) {
+        var viewIndex = aParentNode.getChild(i)._viewIndex;
         if (viewIndex >= 0) {
           // the view indices of subsequent children have not been shifted so
           // the next item will have what should be our index
           newViewIndex = viewIndex;
           break;
         }
       }
       if (newViewIndex < 0) {
         // At the end of the child list without finding a visible sibling: This
         // is a little harder because we don't know how many rows the last item
         // in our list takes up (it could be a container with many children).
-        var prevChild = aParent.getChild(aNewIndex - 1);
-        newViewIndex = prevChild.viewIndex + this._countVisibleRowsForItem(prevChild);
+        var prevChild = aParentNode.getChild(aNewIndex - 1);
+        newViewIndex = prevChild._viewIndex + this._countVisibleRowsForNode(prevChild);
       }
     }
 
-    aItem.viewIndex = newViewIndex;
-    this._visibleElements.splice(newViewIndex, 0, 
-                                 { node: aItem, properties: null });
+    aNode._viewIndex = newViewIndex;
+    this._visibleElements.splice(newViewIndex, 0, aNode);
     for (var i = newViewIndex + 1;
-         i < this._visibleElements.length; i ++) {
-      this._visibleElements[i].node.viewIndex = i;
+         i < this._visibleElements.length; i++) {
+      this._visibleElements[i]._viewIndex = i;
     }
     this._tree.rowCountChanged(newViewIndex, 1);
 
-    // Need to redraw the rows around this one because session boundaries
-    // may have changed. For example, if we add a page to a session, the
-    // previous page will need to be redrawn because its session border
-    // will disappear.
-    if (this._showSessions) {
-      if (newViewIndex > 0)
-        this._tree.invalidateRange(newViewIndex - 1, newViewIndex - 1);
-      if (newViewIndex < this._visibleElements.length -1)
-        this._tree.invalidateRange(newViewIndex + 1, newViewIndex + 1);
-    }
-
-    if (PlacesUtils.nodeIsContainer(aItem) && asContainer(aItem).containerOpen)
-      this._refreshVisibleSection(aItem);
+    if (PlacesUtils.nodeIsContainer(aNode) && asContainer(aNode).containerOpen)
+      this._refreshVisibleSection(aNode);
   },
 
-  // this is used in itemRemoved and itemMoved to fix viewIndex values
-  // throw if the item has an invalid viewIndex
-  _fixViewIndexOnRemove: function PTV_fixViewIndexOnRemove(aItem, aParent) {
-    var oldViewIndex = aItem.viewIndex;
+  // This is used in nodeRemoved and nodeMoved to fix viewIndex values.
+  // Throws if the node has an invalid viewIndex.
+  _fixViewIndexOnRemove: function PTV_fixViewIndexOnRemove(aNode,
+                                                           aParentNode) {
+    var oldViewIndex = aNode._viewIndex;
     // this may have been a container, in which case it has a lot of rows
-    var count = this._countVisibleRowsForItem(aItem);
+    var count = this._countVisibleRowsForNode(aNode);
 
     if (oldViewIndex > this._visibleElements.length)
-      throw("Trying to remove an item with an invalid viewIndex");
+      throw("Trying to remove a node with an invalid viewIndex");
 
     this._visibleElements.splice(oldViewIndex, count);
     for (var i = oldViewIndex; i < this._visibleElements.length; i++)
-      this._visibleElements[i].node.viewIndex = i;
+      this._visibleElements[i]._viewIndex = i;
 
     this._tree.rowCountChanged(oldViewIndex, -count);
 
     // redraw parent because twisty may have changed
-    if (!aParent.hasChildren)
-      this.itemChanged(aParent);
-
-    return;
+    if (!aParentNode.hasChildren)
+      this._tree.invalidateRow(aParentNode._viewIndex);
   },
 
   /**
    * THIS FUNCTION DOES NOT HANDLE cases where a collapsed node is being
    * removed but the node it is collapsed with is not being removed (this then
    * just swap out the removee with its collapsing partner). The only time
    * when we really remove things is when deleting URIs, which will apply to
    * all collapsees. This function is called sometimes when resorting items.
    * However, we won't do this when sorted by date because dates will never
    * change for visits, and date sorting is the only time things are collapsed.
    */
-  itemRemoved: function PTV_itemRemoved(aParent, aItem, aOldIndex) {
+  nodeRemoved: function PTV_nodeRemoved(aParentNode, aNode, aOldIndex) {
     NS_ASSERT(this._result, "Got a notification but have no result!");
     if (!this._tree)
       return; // nothing to do
 
-    var oldViewIndex = aItem.viewIndex;
-    if (oldViewIndex < 0)
-      return; // item was already invisible, nothing to do
+    var oldViewIndex = aNode._viewIndex;
+    if (oldViewIndex < 0) {
+      // There's nothing to do if the node was already invisible.
+      return;
+    }
 
-    // if the item was exclusively selected, the node next to it will be
-    // selected
+    // If the node was exclusively selected, the node next to it will be
+    // selected.
     var selectNext = false;
     var selection = this.selection;
     if (selection.getRangeCount() == 1) {
       var min = { }, max = { };
       selection.getRangeAt(0, min, max);
       if (min.value == max.value &&
-          this.nodeForTreeIndex(min.value) == aItem)
+          this.nodeForTreeIndex(min.value) == aNode)
         selectNext = true;
     }
 
-    // remove the item and fix viewIndex values
-    this._fixViewIndexOnRemove(aItem, aParent);
+    // Remove the node and fix viewIndex values.
+    this._fixViewIndexOnRemove(aNode, aParentNode);
 
-    // restore selection if the item was exclusively selected
+    // Restore selection if the node was exclusively selected.
     if (!selectNext)
       return;
-    // restore selection
+
+    // Restore selection
     if (this._visibleElements.length > oldViewIndex)
       selection.rangedSelect(oldViewIndex, oldViewIndex, true);    
     else if (this._visibleElements.length > 0) {
       // if we removed the last child, we select the new last child if exists
       selection.rangedSelect(this._visibleElements.length - 1,
                              this._visibleElements.length - 1, true);
     }
   },
 
   /**
    * Be careful, aOldIndex and aNewIndex specify the index in the
    * corresponding parent nodes, not the visible indexes.
    */
-  itemMoved:
-  function PTV_itemMoved(aItem, aOldParent, aOldIndex, aNewParent, aNewIndex) {
+  nodeMoved:
+  function PTV_nodeMoved(aNode, aOldParent, aOldIndex, aNewParent, aNewIndex) {
     NS_ASSERT(this._result, "Got a notification but have no result!");
     if (!this._tree)
       return; // nothing to do
 
-    var oldViewIndex = aItem.viewIndex;
-    if (oldViewIndex < 0)
-      return; // item was already invisible, nothing to do
+    var oldViewIndex = aNode._viewIndex;
+    if (oldViewIndex < 0) {
+      // There's nothing to do if the node was already invisible.
+      return;
+    }
 
-    // this may have been a container, in which case it has a lot of rows
-    var count = this._countVisibleRowsForItem(aItem);
+    // This may have been a container, in which case it has a lot of rows.
+    var count = this._countVisibleRowsForNode(aNode);
 
-    // Persist selection state
+    // Persist selection state.
     var nodesToSelect = [];
     var selection = this.selection;
     var rc = selection.getRangeCount();
     for (var rangeIndex = 0; rangeIndex < rc; rangeIndex++) {
       var min = { }, max = { };
       selection.getRangeAt(rangeIndex, min, max);
       var lastIndex = Math.min(max.value, oldViewIndex + count -1);
       if (min.value < oldViewIndex || min.value > lastIndex)
         continue;
 
       for (var nodeIndex = min.value; nodeIndex <= lastIndex; nodeIndex++)
-        nodesToSelect.push(this._visibleElements[nodeIndex].node);
+        nodesToSelect.push(this._visibleElements[nodeIndex]);
     }
     if (nodesToSelect.length > 0)
       selection.selectEventsSuppressed = true;
 
-    // remove item from the old position
-    this._fixViewIndexOnRemove(aItem, aOldParent);
+    // Remove node from the old position.
+    this._fixViewIndexOnRemove(aNode, aOldParent);
 
-    // insert the item into the new position
-    this.itemInserted(aNewParent, aItem, aNewIndex);
+    // Insert the node into the new position.
+    this.nodeInserted(aNewParent, aNode, aNewIndex);
 
-    // restore selection
+    // Restore selection.
     if (nodesToSelect.length > 0) {
       for (var i = 0; i < nodesToSelect.length; i++) {
         var node = nodesToSelect[i];
-        var index = node.viewIndex;
+        var index = node._viewIndex;
         selection.rangedSelect(index, index, true);
       }
       selection.selectEventsSuppressed = false;
     }
   },
 
   /**
-   * Be careful, the parameter 'aIndex' here specifies the index in the parent
-   * node of the item, not the visible index.
-   *
-   * This is called from the result when the item is replaced, but this object
-   * calls this function internally also when duplicate collapsing changes. In
-   * this case, aIndex will be 0, so we should be careful not to use the value.
+   * Be careful, the parameter 'aIndex' here specifies the node's index in the
+   * parent node, not the visible index.
    */
-  itemReplaced:
-  function PTV_itemReplaced(aParent, aOldItem, aNewItem, aIndexDoNotUse) {
+  nodeReplaced:
+  function PTV_nodeReplaced(aParentNode, aOldNode, aNewNode, aIndexDoNotUse) {
     if (!this._tree)
       return;
 
-    var viewIndex = aOldItem.viewIndex;
-    aNewItem.viewIndex = viewIndex;
+    var viewIndex = aOldNode._viewIndex;
+    aNewNode._viewIndex = viewIndex;
     if (viewIndex >= 0 &&
         viewIndex < this._visibleElements.length) {
-      this._visibleElements[viewIndex].node = aNewItem;
-      this._visibleElements[viewIndex].properties = null;
+      this._visibleElements[viewIndex] = aNewNode;
     }
-    aOldItem.viewIndex = -1;
+    aOldNode._viewIndex = -1;
     this._tree.invalidateRow(viewIndex);
   },
 
-  itemChanged: function PTV_itemChanged(aItem) {
+  _invalidateCellValue: function PTV__invalidateCellValue(aNode,
+                                                          aColumnType) {
     NS_ASSERT(this._result, "Got a notification but have no result!");
-    var viewIndex = aItem.viewIndex;
-    if (this._tree && viewIndex >= 0)
-      this._tree.invalidateRow(viewIndex);
+    let viewIndex = aNode._viewIndex;
+    if (viewIndex == -1) // invisible
+      return;
+
+    if (this._tree) {
+      let column = this._findColumnByType(aColumnType);
+      if (column && !column.element.hidden)
+        this._tree.invalidateCell(viewIndex, column);
+
+      // Last modified time is altered for almost all node changes.
+      if (aColumnType != this.COLUMN_TYPE_LASTMODIFIED) {
+        let lastModifiedColumn =
+          this._findColumnByType(this.COLUMN_TYPE_LASTMODIFIED);
+        if (lastModifiedColumn && !lastModifiedColumn.hidden)
+          this._tree.invalidateCell(viewIndex, lastModifiedColumn);
+      }
+    }
+  },
+
+  nodeTitleChanged: function PTV_nodeTitleChanged(aNode, aNewTitle) {
+    this._invalidateCellValue(aNode, this.COLUMN_TYPE_TITLE);
+  },
+
+  nodeURIChanged: function PTV_nodeURIChanged(aNode, aNewURI) {
+    this._invalidateCellValue(aNode, this.COLUMN_TYPE_URI);
+  },
+
+  nodeIconChanged: function PTV_nodeIconChanged(aNode) {
+    this._invalidateCellValue(aNode, this.COLUMN_TYPE_TITLE);
   },
 
-  containerOpened: function PTV_containerOpened(aItem) {
-    this.invalidateContainer(aItem);
+  nodeHistoryDetailsChanged:
+  function PTV_nodeHistoryDetailsChanged(aNode, aUpdatedVisitDate,
+                                         aUpdatedVisitCount) {
+    this._invalidateCellValue(aNode, this.COLUMN_TYPE_DATE);
+    this._invalidateCellValue(aNode, this.COLUMN_TYPE_VISITCOUNT);
+  },
+
+  nodeTagsChanged: function PTV_nodeTagsChanged(aNode) {
+    this._invalidateCellValue(aNode, this.COLUMN_TYPE_TAGS);
+  },
+
+  nodeKeywordChanged: function PTV_nodeKeywordChanged(aNode, aNewKeyword) {
+    this._invalidateCellValue(aNode, this.COLUMN_TYPE_KEYWORD);
   },
 
-  containerClosed: function PTV_containerClosed(aItem) {
-    this.invalidateContainer(aItem);
+  nodeAnnotationChanged: function PTV_nodeAnnotationChanged(aNode, aAnno) {
+    if (aAnno == DESCRIPTION_ANNO)
+      this._invalidateCellValue(aNode, this.COLUMN_TYPE_DESCRIPTION);
+  },
+
+  nodeDateAddedChanged: function PTV_nodeDateAddedChanged(aNode, aNewValue) {
+    this._invalidateCellValue(aNode, this.COLUMN_TYPE_DATEADDED);
   },
 
-  invalidateContainer: function PTV_invalidateContainer(aItem) {
+  nodeLastModifiedChanged:
+  function PTV_nodeLastModifiedChanged(aNode, aNewValue) {
+    this._invalidateCellValue(aNode, this.COLUMN_TYPE_LASTMODIFIED);
+  },
+
+  containerOpened: function PTV_containerOpened(aNode) {
+    this.invalidateContainer(aNode);
+  },
+
+  containerClosed: function PTV_containerClosed(aNode) {
+    this.invalidateContainer(aNode);
+  },
+
+  invalidateContainer: function PTV_invalidateContainer(aNode) {
     NS_ASSERT(this._result, "Got a notification but have no result!");
     if (!this._tree)
       return; // nothing to do, container is not visible
-    var viewIndex = aItem.viewIndex;
-    if (viewIndex >= this._visibleElements.length) {
+
+    if (aNode._viewIndex >= this._visibleElements.length) {
       // be paranoid about visible indices since others can change it
       throw Cr.NS_ERROR_UNEXPECTED;
     }
-    this._refreshVisibleSection(aItem);
+    this._refreshVisibleSection(aNode);
   },
 
-  invalidateAll: function PTV_invalidateAll() {
-    NS_ASSERT(this._result, "Got message but don't have a result!");
-    if (!this._tree)
-      return;
+  _columns: [],
+  _findColumnByType: function PTV__findColumnByType(aColumnType) {
+    if (this._columns[aColumnType])
+      return this._columns[aColumnType];
 
-    var oldRowCount = this._visibleElements.length;
+    var columns = this._tree.columns;
+    var colCount = columns.count;
+    for (var i = 0; i < colCount; i++) {
+      let column = columns.getColumnAt(i);
+      let columnType = this._getColumnType(column);
+      this._columns[columnType] = column;
+      if (columnType == aColumnType)
+        return column;
+    }
 
-    // update flat list to new contents
-    this._buildVisibleList();
+    // That's completely valid.  Most of our trees actually include just the
+    // title column.
+    return null;
   },
 
   sortingChanged: function PTV__sortingChanged(aSortingMode) {
     if (!this._tree || !this._result)
       return;
 
     // depending on the sort mode, certain commands may be disabled
     window.updateCommands("sort");
@@ -776,64 +760,64 @@ PlacesTreeView.prototype = {
     // clear old sorting indicator
     var sortedColumn = columns.getSortedColumn();
     if (sortedColumn)
       sortedColumn.element.removeAttribute("sortDirection");
 
     // set new sorting indicator by looking through all columns for ours
     if (aSortingMode == Ci.nsINavHistoryQueryOptions.SORT_BY_NONE)
       return;
+
     var [desiredColumn, desiredIsDescending] =
       this._sortTypeToColumnType(aSortingMode);
     var colCount = columns.count;
-    for (var i = 0; i < colCount; i ++) {
-      var column = columns.getColumnAt(i);
-      if (this._getColumnType(column) == desiredColumn) {
-        // found our desired one, set
-        if (desiredIsDescending)
-          column.element.setAttribute("sortDirection", "descending");
-        else
-          column.element.setAttribute("sortDirection", "ascending");
-        break;
-      }
+    var column = this._findColumnByType(desiredColumn);
+    if (column) {
+      let sortDir = desiredIsDescending ? "descending" : "ascending";
+      column.element.setAttribute("sortDirection", sortDir);
     }
   },
 
   get result() {
     return this._result;
   },
 
   set result(val) {
-    // some methods (e.g. getURLsFromContainer) temporarily null out the
+    // Some methods (e.g. getURLsFromContainer) temporarily null out the
     // viewer when they do temporary changes to the view, this does _not_
     // call setResult(null), but then, we're called again with the result
     // object which is already set for this viewer. At that point,
     // we should do nothing.
     if (this._result != val) {
       if (this._result)
-        this._result.root.containerOpen = false;
+        this._rootNode.containerOpen = false;
+
       this._result = val;
-      this._finishInit();
+      this._rootNode = val ? val.root : null;
+
+      // If the tree is not set yet, setTree will call finishInit.
+      if (this._tree && val)
+        this._finishInit();
     }
     return val;
   },
 
   nodeForTreeIndex: function PTV_nodeForTreeIndex(aIndex) {
     if (aIndex > this._visibleElements.length)
       throw Cr.NS_ERROR_INVALID_ARG;
 
-    return this._visibleElements[aIndex].node;
+    return this._visibleElements[aIndex];
   },
 
   treeIndexForNode: function PTV_treeNodeForIndex(aNode) {
-    var viewIndex = aNode.viewIndex;
+    var viewIndex = aNode._viewIndex;
     if (viewIndex < 0)
       return Ci.nsINavHistoryResultTreeViewer.INDEX_INVISIBLE;
 
-    NS_ASSERT(this._visibleElements[viewIndex].node == aNode,
+    NS_ASSERT(this._visibleElements[viewIndex] == aNode,
               "Node's visible index and array out of sync");
     return viewIndex;
   },
 
   _getResourceForNode: function PTV_getResourceForNode(aNode)
   {
     var uri = aNode.uri;
     NS_ASSERT(uri, "if there is no uri, we can't persist the open state");
@@ -848,35 +832,17 @@ PlacesTreeView.prototype = {
   get selection() {
     return this._selection;
   },
 
   set selection(val) {
     return this._selection = val;
   },
 
-  getRowProperties: function PTV_getRowProperties(aRow, aProperties) {
-    this._ensureValidRow(aRow);
-
-    // Handle properties for session information.
-    if (!this._showSessions)
-      return;
-
-    var status = this._getRowSessionStatus(aRow);
-    switch (status) {
-      case this.SESSION_STATUS_NONE:
-        break;
-      case this.SESSION_STATUS_START:
-        aProperties.AppendElement(this._getAtomFor("session-start"));
-        break;
-      case this.SESSION_STATUS_CONTINUE:
-        aProperties.AppendElement(this._getAtomFor("session-continue"));
-        break
-    }
-  },
+  getRowProperties: function PTV_getRowProperties(aRow, aProperties) { },
 
   getCellProperties: function PTV_getCellProperties(aRow, aColumn, aProperties) {
     this._ensureValidRow(aRow);
 
     // for anonid-trees, we need to add the column-type manually
     var columnType = aColumn.element.getAttribute("anonid");
     if (columnType)
       aProperties.AppendElement(this._getAtomFor(columnType));
@@ -885,21 +851,19 @@ PlacesTreeView.prototype = {
 
     // Set the "ltr" property on url cells
     if (columnType == "url")
       aProperties.AppendElement(this._getAtomFor("ltr"));
 
     if (columnType != "title")
       return;
 
-    var node = this._visibleElements[aRow].node;
-    var properties = this._visibleElements[aRow].properties;
-
-    if (!properties) {
-      properties = new Array();
+    var node = this._visibleElements[aRow];
+    if (!node._cellProperties) {
+      let properties = new Array();
       var itemId = node.itemId;
       var nodeType = node.type;
       if (PlacesUtils.containerTypes.indexOf(nodeType) != -1) {
         if (nodeType == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY) {
           properties.push(this._getAtomFor("query"));
           if (PlacesUtils.nodeIsTagQuery(node))
             properties.push(this._getAtomFor("tagContainer"));
           else if (PlacesUtils.nodeIsDay(node))
@@ -924,82 +888,71 @@ PlacesTreeView.prototype = {
       else if (PlacesUtils.nodeIsURI(node)) {
         properties.push(this._getAtomFor(PlacesUIUtils.guessUrlSchemeForUI(node.uri)));
         if (itemId != -1) {
           if (PlacesUtils.nodeIsLivemarkContainer(node.parent))
             properties.push(this._getAtomFor("livemarkItem"));
         }
       }
 
-      this._visibleElements[aRow].properties = properties;
+      node._cellProperties = properties;
     }
-    for (var i = 0; i < properties.length; i++)
-      aProperties.AppendElement(properties[i]);
+    for (var i = 0; i < node._cellProperties.length; i++)
+      aProperties.AppendElement(node._cellProperties[i]);
   },
 
   getColumnProperties: function(aColumn, aProperties) { },
 
   isContainer: function PTV_isContainer(aRow) {
     this._ensureValidRow(aRow);
 
-    var node = this._visibleElements[aRow].node;
+    var node = this._visibleElements[aRow];
     if (PlacesUtils.nodeIsContainer(node)) {
-      // the root node is always expandable
-      if (!node.parent)
-        return true;
-
       // Flat-lists may ignore expandQueries and other query options when
       // they are asked to open a container.
       if (this._flatList)
         return true;
 
       // treat non-expandable childless queries as non-containers
       if (PlacesUtils.nodeIsQuery(node)) {
         var parent = node.parent;
-        if((PlacesUtils.nodeIsQuery(parent) ||
-            PlacesUtils.nodeIsFolder(parent)) &&
-           !node.hasChildren)
+        if ((PlacesUtils.nodeIsQuery(parent) ||
+             PlacesUtils.nodeIsFolder(parent)) &&
+            !node.hasChildren)
           return asQuery(parent).queryOptions.expandQueries;
       }
       return true;
     }
     return false;
   },
 
   isContainerOpen: function PTV_isContainerOpen(aRow) {
     if (this._flatList)
       return false;
 
     this._ensureValidRow(aRow);
-    if (!PlacesUtils.nodeIsContainer(this._visibleElements[aRow].node))
-      throw Cr.NS_ERROR_INVALID_ARG;
-
-    return this._visibleElements[aRow].node.containerOpen;
+    return this._visibleElements[aRow].containerOpen;
   },
 
   isContainerEmpty: function PTV_isContainerEmpty(aRow) {
     if (this._flatList)
       return true;
 
     this._ensureValidRow(aRow);
-
-    if (!PlacesUtils.nodeIsContainer(this._visibleElements[aRow].node))
-      throw Cr.NS_ERROR_INVALID_ARG;
-
-    return !this._visibleElements[aRow].node.hasChildren;
+    return !this._visibleElements[aRow].hasChildren;
   },
 
   isSeparator: function PTV_isSeparator(aRow) {
     this._ensureValidRow(aRow);
-    return PlacesUtils.nodeIsSeparator(this._visibleElements[aRow].node);
+    return PlacesUtils.nodeIsSeparator(this._visibleElements[aRow]);
   },
 
   isSorted: function PTV_isSorted() {
     return this._result.sortingMode !=
-           Components.interfaces.nsINavHistoryQueryOptions.SORT_BY_NONE;
+           Ci.nsINavHistoryQueryOptions.SORT_BY_NONE;
   },
 
   canDrop: function PTV_canDrop(aRow, aOrientation) {
     if (!this._result)
       throw Cr.NS_ERROR_UNEXPECTED;
 
     // drop position into a sorted treeview would be wrong
     if (this.isSorted())
@@ -1020,18 +973,18 @@ PlacesTreeView.prototype = {
         // If the last selected item is an open container, append _into_
         // it, rather than insert adjacent to it. 
         container = lastSelected;
         index = -1;
       }
       else if (lastSelected.containerOpen &&
                orientation == Ci.nsITreeView.DROP_AFTER &&
                lastSelected.hasChildren) {
-        // If the last selected item is an open container and the user is
-        // trying to drag into it as a first item, really insert into it.
+        // If the last selected node is an open container and the user is
+        // trying to drag into it as a first node, really insert into it.
         container = lastSelected;
         orientation = Ci.nsITreeView.DROP_ON;
         index = 0;
       }
       else {
         // Use the last-selected node's container unless the root node
         // is selected, in which case we use the root node itself as the
         // insertion point.
@@ -1080,76 +1033,65 @@ PlacesTreeView.prototype = {
     var ip = this._getInsertionPoint(aRow, aOrientation);
     if (!ip)
       return;
     PlacesControllerDragHelper.onDrop(ip);
   },
 
   getParentIndex: function PTV_getParentIndex(aRow) {
     this._ensureValidRow(aRow);
-    var parent = this._visibleElements[aRow].node.parent;
-    if (!parent || parent.viewIndex < 0)
+    var parent = this._visibleElements[aRow].parent;
+    if (!parent || parent._viewIndex < 0)
       return -1;
 
-    return parent.viewIndex;
+    return parent._viewIndex;
   },
 
   hasNextSibling: function PTV_hasNextSibling(aRow, aAfterIndex) {
     this._ensureValidRow(aRow);
     if (aRow == this._visibleElements.length -1) {
       // this is the last thing in the list -> no next sibling
       return false;
     }
 
-    var thisLevel = this._visibleElements[aRow].node.indentLevel;
+    var thisLevel = this._visibleElements[aRow].indentLevel;
     for (var i = aAfterIndex + 1; i < this._visibleElements.length; ++i) {
-      var nextLevel = this._visibleElements[i].node.indentLevel;
+      var nextLevel = this._visibleElements[i].indentLevel;
       if (nextLevel == thisLevel)
         return true;
       if (nextLevel < thisLevel)
         break;
     }
     return false;
   },
 
   getLevel: function PTV_getLevel(aRow) {
     this._ensureValidRow(aRow);
 
-    // Level is 0 for items at the root level, 1 for its children and so on.
-    // If we don't show the result's root node, the level is simply the node's
-    // indentLevel; if we do, it is the node's indentLevel increased by 1.
-    // That is because nsNavHistoryResult uses -1 as the indent level for the
-    // root node regardless of our internal showRoot state.
-    if (this._showRoot)
-      return this._visibleElements[aRow].node.indentLevel + 1;
-
-    return this._visibleElements[aRow].node.indentLevel;
+    // Level is 0 for nodes at the root level, 1 for its children and so on.
+    return this._visibleElements[aRow].indentLevel;
   },
 
   getImageSrc: function PTV_getImageSrc(aRow, aColumn) {
     this._ensureValidRow(aRow);
 
     // only the title column has an image
     if (this._getColumnType(aColumn) != this.COLUMN_TYPE_TITLE)
       return "";
 
-    var node = this._visibleElements[aRow].node;
-    var icon = node.icon;
-    if (icon)
-      return icon.spec;
-    return "";
+    return this._visibleElements[aRow].icon;
   },
 
   getProgressMode: function(aRow, aColumn) { },
   getCellValue: function(aRow, aColumn) { },
 
   getCellText: function PTV_getCellText(aRow, aColumn) {
     this._ensureValidRow(aRow);
 
-    var node = this._visibleElements[aRow].node;
+    var node = this._visibleElements[aRow];
     var columnType = this._getColumnType(aColumn);
     switch (columnType) {
       case this.COLUMN_TYPE_TITLE:
         // normally, this is just the title, but we don't want empty items in
         // the tree view so return a special string if the title is empty.
         // Do it here so that callers can still get at the 0 length title
         // if they go through the "result" API.
         if (PlacesUtils.nodeIsSeparator(node))
@@ -1157,27 +1099,27 @@ PlacesTreeView.prototype = {
         return PlacesUIUtils.getBestTitle(node);
       case this.COLUMN_TYPE_TAGS:
         return node.tags;
       case this.COLUMN_TYPE_URI:
         if (PlacesUtils.nodeIsURI(node))
           return node.uri;
         return "";
       case this.COLUMN_TYPE_DATE:
-        if (node.time == 0 || !PlacesUtils.nodeIsURI(node)) {
+        let nodeTime = node.time;
+        if (nodeTime == 0 || !PlacesUtils.nodeIsURI(node)) {
           // hosts and days shouldn't have a value for the date column.
           // Actually, you could argue this point, but looking at the
           // results, seeing the most recently visited date is not what
           // I expect, and gives me no information I know how to use.
           // Only show this for URI-based items.
           return "";
         }
-        if (this._getRowSessionStatus(aRow) != this.SESSION_STATUS_CONTINUE)
-          return this._convertPRTimeToString(node.time);
-        return "";
+
+        return this._convertPRTimeToString(nodeTime);
       case this.COLUMN_TYPE_VISITCOUNT:
         return node.accessCount;
       case this.COLUMN_TYPE_KEYWORD:
         if (PlacesUtils.nodeIsBookmark(node))
           return PlacesUtils.bookmarks.getKeywordForBookmark(node.itemId);
         return "";
       case this.COLUMN_TYPE_DESCRIPTION:
         if (node.itemId != -1) {
@@ -1199,37 +1141,34 @@ PlacesTreeView.prototype = {
     }
     return "";
   },
 
   setTree: function PTV_setTree(aTree) {
     var hasOldTree = this._tree != null;
     this._tree = aTree;
 
-    // do this before detaching from result when there is no tree.
-    // This ensures that the visible indices of the elements in the
-    // result have been set to -1
-    this._finishInit();
-
-    if (!aTree && hasOldTree && this._result) {
-      // detach from result when we are detaching from the tree.
-      // This breaks the reference cycle between us and the result.
-      this._result.viewer = null;
+    if (this._result) {
+      if (hasOldTree) {
+        // detach from result when we are detaching from the tree.
+        // This breaks the reference cycle between us and the result.
+        if (!aTree)
+          this._result.viewer = null;
+      }
+      if (aTree)
+        this._finishInit();
     }
   },
 
   toggleOpenState: function PTV_toggleOpenState(aRow) {
     if (!this._result)
       throw Cr.NS_ERROR_UNEXPECTED;
     this._ensureValidRow(aRow);
 
-    var node = this._visibleElements[aRow].node;
-    if (!PlacesUtils.nodeIsContainer(node))
-      return; // not a container, nothing to do
-
+    var node = this._visibleElements[aRow];
     if (this._flatList && this._openContainerCallback) {
       this._openContainerCallback(node);
       return;
     }
 
     var resource = this._getResourceForNode(node);
     if (resource) {
       const openLiteral = PlacesUIUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open");
@@ -1396,21 +1335,16 @@ PlacesTreeView.prototype = {
   selectionChanged: function() { },
   cycleCell: function PTV_cycleCell(aRow, aColumn) { },
   isSelectable: function(aRow, aColumn) { return false; },
   performAction: function(aAction) { },
   performActionOnRow: function(aAction, aRow) { },
   performActionOnCell: function(aAction, aRow, aColumn) { }
 };
 
-function PlacesTreeView(aShowRoot, aFlatList, aOnOpenFlatContainer) {
-  if (aShowRoot && aFlatList)
-    throw("Flat-list mode is not supported when show-root is set");
-
+function PlacesTreeView(aFlatList, aOnOpenFlatContainer) {
   this._tree = null;
   this._result = null;
-  this._showSessions = false;
   this._selection = null;
   this._visibleElements = [];
-  this._showRoot = aShowRoot;
   this._flatList = aFlatList;
   this._openContainerCallback = aOnOpenFlatContainer;
 }
--- a/browser/components/places/content/utils.js
+++ b/browser/components/places/content/utils.js
@@ -997,27 +997,22 @@ var PlacesUIUtils = {
   guessUrlSchemeForUI: function PUU_guessUrlSchemeForUI(aUrlString) {
     return aUrlString.substr(0, aUrlString.indexOf(":"));
   },
 
   /**
    * Helper for the toolbar and menu views
    */
   createMenuItemForNode:
-  function PUU_createMenuItemForNode(aNode, aContainersMap) {
+  function PUU_createMenuItemForNode(aNode) {
     var element;
     var type = aNode.type;
     if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR)
       element = document.createElement("menuseparator");
     else {
-      var iconURI = aNode.icon;
-      var iconURISpec = "";
-      if (iconURI)
-        iconURISpec = iconURI.spec;
-
       if (PlacesUtils.uriTypes.indexOf(type) != -1) {
         element = document.createElement("menuitem");
         element.className = "menuitem-iconic bookmark-item";
         element.setAttribute("scheme", this.guessUrlSchemeForUI(aNode.uri));
       }
       else if (PlacesUtils.containerTypes.indexOf(type) != -1) {
         element = document.createElement("menu");
         element.setAttribute("container", "true");
@@ -1046,30 +1041,29 @@ var PlacesUIUtils = {
         // the popup correctly.
         popup._startMarker = -1;
         popup._endMarker = -1;
 #else
         // no context menu on mac
         popup.setAttribute("context", "placesContext");
 #endif
         element.appendChild(popup);
-        if (aContainersMap)
-          aContainersMap.push({ resultNode: aNode, domNode: popup });
         element.className = "menu-iconic bookmark-item";
       }
       else
         throw "Unexpected node";
 
       element.setAttribute("label", this.getBestTitle(aNode));
 
-      if (iconURISpec)
-        element.setAttribute("image", iconURISpec);
+      var icon = aNode.icon;
+      if (icon)
+        element.setAttribute("image", icon);
     }
     element.node = aNode;
-    element.node.viewIndex = 0;
+    element.node._DOMElement = element;
 
     return element;
   },
 
   cleanPlacesPopup: function PU_cleanPlacesPopup(aPopup) {
     // Remove places popup children and update markers to keep track of
     // their indices.
     var start = aPopup._startMarker != -1 ? aPopup._startMarker + 1 : 0;
--- a/browser/components/places/src/nsPlacesTransactionsService.js
+++ b/browser/components/places/src/nsPlacesTransactionsService.js
@@ -570,17 +570,17 @@ placesCreateLivemarkTransactions.prototy
       PlacesUtils.bookmarks.setItemGUID(this._id, this._GUID);
   },
 
   undoTransaction: function PCLT_undoTransaction() {
     // If a GUID exists for this item, preserve it before removing the item.
     if (PlacesUtils.annotations.itemHasAnnotation(this._id, GUID_ANNO))
       this._GUID = PlacesUtils.bookmarks.getItemGUID(this._id);
 
-    PlacesUtils.bookmarks.removeFolder(this._id);
+    PlacesUtils.bookmarks.removeItem(this._id);
   }
 };
 
 function placesRemoveLivemarkTransaction(aFolderId) {
   this.redoTransaction = this.doTransaction;
   this._id = aFolderId;
   this._title = PlacesUtils.bookmarks.getItemTitle(this._id);
   this._container = PlacesUtils.bookmarks.getFolderIdForItem(this._id);
--- a/browser/components/places/tests/browser/browser_views_liveupdate.js
+++ b/browser/components/places/tests/browser/browser_views_liveupdate.js
@@ -183,45 +183,48 @@ var bookmarksObserver = {
   QueryInterface: function PSB_QueryInterface(aIID) {
     if (aIID.equals(Ci.nsINavBookmarkObserver) ||
         aIID.equals(Ci.nsISupports))
       return this;
     throw Cr.NS_NOINTERFACE;
   },
 
   // nsINavBookmarkObserver
-  onItemAdded: function PSB_onItemAdded(aItemId, aFolderId, aIndex) {
+  onItemAdded: function PSB_onItemAdded(aItemId, aFolderId, aIndex,
+                                        aItemType) {
     var views = getViewsForFolder(aFolderId);
     ok(views.length > 0, "Found affected views: " + views);
 
     // Check that item has been added in the correct position.
     for (var i = 0; i < views.length; i++) {
       var node = null;
       var index = null;
       [node, index] = searchItemInView(aItemId, views[i]);
       isnot(node, null, "Found new Places node in " + views[i]);
       is(index, aIndex, "Node is at index " + index);
     }
   },
 
-  onItemRemoved: function PSB_onItemRemoved(aItemId, aFolder, aIndex) {
+  onItemRemoved: function PSB_onItemRemoved(aItemId, aFolder, aIndex,
+                                            aItemType) {
     var views = getViewsForFolder(aFolderId);
     ok(views.length > 0, "Found affected views: " + views);
     // Check that item has been removed.
     for (var i = 0; i < views.length; i++) {
       var node = null;
       var index = null;
       [node, index] = searchItemInView(aItemId, views[i]);
       is(node, null, "Places node not found in " + views[i]);
     }
   },
 
   onItemMoved: function(aItemId,
                         aOldFolderId, aOldIndex,
-                        aNewFolderId, aNewIndex) {
+                        aNewFolderId, aNewIndex,
+                        aItemType) {
     var views = getViewsForFolder(aNewFolderId);
     ok(views.length > 0, "Found affected views: " + views);
 
     // Check that item has been moved in the correct position.
     for (var i = 0; i < views.length; i++) {
       var node = null;
       var index = null;
       [node, index] = searchItemInView(aItemId, views[i]);
@@ -229,18 +232,17 @@ var bookmarksObserver = {
       is(index, aNewIndex, "Node is at index " + index);
     }
   },
 
   onBeginUpdateBatch: function PSB_onBeginUpdateBatch() {},
   onEndUpdateBatch: function PSB_onEndUpdateBatch() {},
   onBeforeItemRemoved: function PSB_onBeforeItemRemoved(aItemId) {},
   onItemVisited: function() {},
-  onItemChanged: function PSB_onItemChanged(aItemId, aProperty,
-                                            aIsAnnotationProperty, aValue) {}
+  onItemChanged: function PSB_onItemChanged() {}
 };
 
 /**
  * Search an item id in a view.
  *
  * @param aItemId
  *        item id of the item to search.
  * @param aView
@@ -286,17 +288,17 @@ function getNodeForToolbarItem(aItemId) 
       if (child.node.itemId == aItemId)
         return [child.node, i - staticNodes];
 
       // Don't search in queries, they could contain our item in a
       // different position.  Search only folders
       if (PlacesUtils.nodeIsFolder(child.node)) {
         var popup = child.lastChild;
         popup.showPopup(popup);
-        foundNode = findNode(popup);
+        var foundNode = findNode(popup);
         popup.hidePopup();
         if (foundNode[0] != null)
           return foundNode;
       }
     }
     return [null, null];
   }
 
@@ -329,17 +331,17 @@ function getNodeForMenuItem(aItemId) {
 
       // Don't search in queries, they could contain our item in a
       // different position.  Search only folders
       if (PlacesUtils.nodeIsFolder(child.node)) {
         var popup = child.lastChild;
         // XXX Why is this needed on Linux and Mac?
         popup.showPopup(popup);
         child.open = true;
-        foundNode = findNode(popup);
+        var foundNode = findNode(popup);
         popup.hidePopup();
         child.open = false;
         if (foundNode[0] != null)
           return foundNode;
       }
     }
     return [null, null];
   }
--- a/browser/components/places/tests/unit/test_placesTxn.js
+++ b/browser/components/places/tests/unit/test_placesTxn.js
@@ -86,40 +86,43 @@ try {
 // create and add bookmarks observer
 var observer = {
   onBeginUpdateBatch: function() {
     this._beginUpdateBatch = true;
   },
   onEndUpdateBatch: function() {
     this._endUpdateBatch = true;
   },
-  onItemAdded: function(id, folder, index) {
+  onItemAdded: function(id, folder, index, itemType) {
     this._itemAddedId = id;
     this._itemAddedParent = folder;
     this._itemAddedIndex = index;
+    this._itemAddedType = itemType;
   },
   onBeforeItemRemoved: function(id) {
   },
-  onItemRemoved: function(id, folder, index) {
+  onItemRemoved: function(id, folder, index, itemType) {
     this._itemRemovedId = id;
     this._itemRemovedFolder = folder;
     this._itemRemovedIndex = index;
   },
-  onItemChanged: function(id, property, isAnnotationProperty, value) {
+  onItemChanged: function(id, property, isAnnotationProperty, newValue,
+                          lastModified, itemType) {
     this._itemChangedId = id;
     this._itemChangedProperty = property;
     this._itemChanged_isAnnotationProperty = isAnnotationProperty;
-    this._itemChangedValue = value;
+    this._itemChangedValue = newValue;
   },
   onItemVisited: function(id, visitID, time) {
     this._itemVisitedId = id;
     this._itemVisitedVistId = visitID;
     this._itemVisitedTime = time;
   },
-  onItemMoved: function(id, oldParent, oldIndex, newParent, newIndex) {
+  onItemMoved: function(id, oldParent, oldIndex, newParent, newIndex,
+                        itemType) {
     this._itemMovedId = id
     this._itemMovedOldParent = oldParent;
     this._itemMovedOldIndex = oldIndex;
     this._itemMovedNewParent = newParent;
     this._itemMovedNewIndex = newIndex;
   },
   QueryInterface: function(iid) {
     if (iid.equals(Ci.nsINavBookmarkObserver) ||
@@ -145,28 +148,30 @@ function run_test() {
   var annos = [{ name: DESCRIPTION_ANNO,
                  type: annosvc.TYPE_STRING,
                 flags: 0,
                 value: TEST_DESCRIPTION,
               expires: annosvc.EXPIRE_NEVER }];
   var txn1 = ptSvc.createFolder("Testing folder", root, bmStartIndex, annos);
   ptSvc.doTransaction(txn1);
 
-  // the check check that calling undoTransaction on an "empty batch" doesn't undo
-  // the previous transaction
+  // This checks that calling undoTransaction on an "empty batch" doesn't
+  // undo the previous transaction (getItemTitle will fail)
   ptSvc.beginBatch();
   ptSvc.endBatch();
   ptSvc.undoTransaction();
 
-  var folderId = bmsvc.getChildFolder(root, "Testing folder");
-  do_check_eq(TEST_DESCRIPTION, 
-              annosvc.getItemAnnotation(folderId, DESCRIPTION_ANNO));
+  var folderId = observer._itemAddedId;
+  do_check_eq(bmsvc.getItemTitle(folderId), "Testing folder");
   do_check_eq(observer._itemAddedIndex, bmStartIndex);
   do_check_eq(observer._itemAddedParent, root);
   do_check_eq(observer._itemAddedId, folderId);
+  do_check_eq(TEST_DESCRIPTION, 
+              annosvc.getItemAnnotation(folderId, DESCRIPTION_ANNO));
+
   txn1.undoTransaction();
   do_check_eq(observer._itemRemovedId, folderId);
   do_check_eq(observer._itemRemovedFolder, root);
   do_check_eq(observer._itemRemovedIndex, bmStartIndex);
   txn1.redoTransaction();
   do_check_eq(observer._itemAddedIndex, bmStartIndex);
   do_check_eq(observer._itemAddedParent, root);
   do_check_eq(observer._itemAddedId, folderId);
@@ -196,17 +201,19 @@ function run_test() {
   txn2.undoTransaction();
   do_check_eq(observer._itemRemovedId, newId);
   do_check_eq(observer._itemRemovedFolder, root);
   do_check_eq(observer._itemRemovedIndex, bmStartIndex);
 
   // Create item to a folder
   var txn2a = ptSvc.createFolder("Folder", root, bmStartIndex);
   ptSvc.doTransaction(txn2a);
-  var fldrId = bmsvc.getChildFolder(root, "Folder");
+  var fldrId = observer._itemAddedId;
+  do_check_eq(bmsvc.getItemTitle(fldrId), "Folder");
+
   var txn2b = ptSvc.createItem(uri("http://www.example2.com"), fldrId, bmStartIndex, "Testing1b");
   ptSvc.doTransaction(txn2b);
   var b2 = (bmsvc.getBookmarkIdsForURI(uri("http://www.example2.com"), {}))[0];
   do_check_eq(observer._itemAddedId, b2);
   do_check_eq(observer._itemAddedIndex, bmStartIndex);
   do_check_true(bmsvc.isBookmarked(uri("http://www.example2.com")));
   txn2b.undoTransaction();
   do_check_eq(observer._itemRemovedId, b2);
@@ -282,17 +289,19 @@ function run_test() {
   do_check_eq(observer._itemMovedId, bkmk1Id);
   do_check_eq(observer._itemMovedOldParent, fldrId);
   do_check_eq(observer._itemMovedOldIndex, 1);
   do_check_eq(observer._itemMovedNewParent, root);
   do_check_eq(observer._itemMovedNewIndex, 1);
 
   // Test Removing a Folder
   ptSvc.doTransaction(ptSvc.createFolder("Folder2", root, -1));
-  var fldrId2 = bmsvc.getChildFolder(root, "Folder2");
+  var fldrId2 = observer._itemAddedId;
+  do_check_eq(bmsvc.getItemTitle(fldrId2), "Folder2");
+
   var txn4 = ptSvc.removeItem(fldrId2);
   txn4.doTransaction();
   do_check_eq(observer._itemRemovedId, fldrId2);
   do_check_eq(observer._itemRemovedFolder, root);
   do_check_eq(observer._itemRemovedIndex, 3);
   txn4.undoTransaction();
   do_check_eq(observer._itemAddedId, fldrId2);
   do_check_eq(observer._itemAddedParent, root);
@@ -544,17 +553,18 @@ function run_test() {
   do_check_true(annosvc.pageHasAnnotation(uri("http://www.mozilla.org/"), "testAnno/testInt"));
   genPageAnnoTxn.undoTransaction();
   do_check_false(annosvc.pageHasAnnotation(uri("http://www.mozilla.org/"), "testAnno/testInt"));
   genPageAnnoTxn.redoTransaction();
   do_check_true(annosvc.pageHasAnnotation(uri("http://www.mozilla.org/"), "testAnno/testInt"));
 
   // sortFolderByName
   ptSvc.doTransaction(ptSvc.createFolder("Sorting folder", root, bmStartIndex, [], null));
-  var srtFldId = bmsvc.getChildFolder(root, "Sorting folder");
+  var srtFldId = observer._itemAddedId;
+  do_check_eq(bmsvc.getItemTitle(srtFldId), "Sorting folder");
   ptSvc.doTransaction(ptSvc.createItem(uri("http://www.sortingtest.com"), srtFldId, -1, "c"));
   ptSvc.doTransaction(ptSvc.createItem(uri("http://www.sortingtest.com"), srtFldId, -1, "b"));   
   ptSvc.doTransaction(ptSvc.createItem(uri("http://www.sortingtest.com"), srtFldId, -1, "a"));
   var b = bmsvc.getBookmarkIdsForURI(uri("http://www.sortingtest.com"), {});
   b.sort();
   var b1 = b[0];
   var b2 = b[1];
   var b3 = b[2];
--- a/browser/components/privatebrowsing/test/unit/do_test_removeDataFromDomain.js
+++ b/browser/components/privatebrowsing/test/unit/do_test_removeDataFromDomain.js
@@ -192,17 +192,17 @@ function check_downloaded(aURIString, aI
     "SELECT * " +
     "FROM moz_downloads " +
     "WHERE source = :source"
   );
   stmt.params.source = aURIString;
 
   let checker = aIsDownloaded ? do_check_true : do_check_false;
   try {
-    checker(stmt.step());
+    checker(stmt.executeStep());
   }
   finally {
     stmt.finalize();
   }
 }
 
 /**
  * Adds a disabled host to the login manager.
--- a/browser/fuel/src/fuelApplication.js
+++ b/browser/fuel/src/fuelApplication.js
@@ -542,17 +542,17 @@ BookmarkFolder.prototype = {
 
   addFolder : function bmf_addfolder(aTitle) {
     var newFolderID = Utilities.bookmarks.createFolder(this._id, aTitle, Utilities.bookmarks.DEFAULT_INDEX);
     var newFolder = new BookmarkFolder(newFolderID, this);
     return newFolder;
   },
 
   remove : function bmf_remove() {
-    Utilities.bookmarks.removeFolder(this._id);
+    Utilities.bookmarks.removeItem(this._id);
   },
 
   // observer
   onBeginUpdateBatch : function bmf_obub() {
   },
 
   onEndUpdateBatch : function bmf_oeub() {
   },
--- a/browser/themes/pinstripe/browser/jar.mn
+++ b/browser/themes/pinstripe/browser/jar.mn
@@ -63,34 +63,22 @@ browser.jar:
   skin/classic/browser/places/allBookmarks.png              (places/allBookmarks.png)
 * skin/classic/browser/places/places.css                    (places/places.css)
 * skin/classic/browser/places/organizer.css                 (places/organizer.css)
   skin/classic/browser/places/query.png                     (places/query.png)
   skin/classic/browser/places/livemarkItem.png              (places/livemarkItem.png)
   skin/classic/browser/places/bookmarksMenu.png             (places/bookmarksMenu.png)
   skin/classic/browser/places/bookmarksToolbar.png          (places/bookmarksToolbar.png)
   skin/classic/browser/places/history.png                   (places/history.png)
-  skin/classic/browser/places/menubutton-end-pressed.png    (places/menubutton-end-pressed.png)
-  skin/classic/browser/places/menubutton-end-pressed-rtl.png (places/menubutton-end-pressed-rtl.png)
-  skin/classic/browser/places/menubutton-mid-pressed.png    (places/menubutton-mid-pressed.png)
-  skin/classic/browser/places/menubutton-start-pressed.png  (places/menubutton-start-pressed.png)
-  skin/classic/browser/places/menubutton-start-pressed-rtl.png (places/menubutton-start-pressed-rtl.png)
   skin/classic/browser/places/star-icons.png                (places/star-icons.png)
-  skin/classic/browser/places/toolbar-button-backup.png     (places/toolbar-button-backup.png)
-  skin/classic/browser/places/toolbar-button-organize.png   (places/toolbar-button-organize.png)
-  skin/classic/browser/places/toolbar-button-view.png       (places/toolbar-button-view.png)
+  skin/classic/browser/places/toolbar.png                   (places/toolbar.png)
   skin/classic/browser/places/toolbarDropMarker.png         (places/toolbarDropMarker.png)
   skin/classic/browser/places/folderDropArrow.png           (places/folderDropArrow.png)
   skin/classic/browser/places/livemarkFolder.png            (places/livemarkFolder.png)
-  skin/classic/browser/places/back-forward.png              (places/back-forward.png)
   skin/classic/browser/places/editBookmarkOverlay.css       (places/editBookmarkOverlay.css)
-  skin/classic/browser/places/menubutton-start.png          (places/menubutton-start.png)
-  skin/classic/browser/places/menubutton-start-rtl.png      (places/menubutton-start-rtl.png)
-  skin/classic/browser/places/menubutton-end.png            (places/menubutton-end.png)
-  skin/classic/browser/places/menubutton-end-rtl.png        (places/menubutton-end-rtl.png)
   skin/classic/browser/places/minus.png                     (places/minus.png)
   skin/classic/browser/places/minus-active.png              (places/minus-active.png)
   skin/classic/browser/places/plus.png                      (places/plus.png)
   skin/classic/browser/places/plus-active.png               (places/plus-active.png)
   skin/classic/browser/places/starPage.png                  (places/starPage.png)
   skin/classic/browser/places/pageStarred.png               (places/pageStarred.png)
   skin/classic/browser/places/searching_16.png              (places/searching_16.png)
   skin/classic/browser/places/starred48.png                 (places/starred48.png)
deleted file mode 100644
index ae33de5934a701a5b5b50b505d0955c0ceaee8f7..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index f2252246de7118ba042a5d52245a9ac62f5238ee..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index ec7d722dd12a2cca4f1a51ce93ac405ddf7e0123..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index a5c90d5a0150fc4abb9129eac4aa8d72419db1da..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index a885c9c7e3ed1564f8ccea3d3deec499c6306feb..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 8441993ed05c7ee09488305028af24822f726f57..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index a2af3b4e6a2bdc134e604e623a76e1484df820e4..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 9793ec83b1f944df3551e3bbf98943e08ede558b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 243bfd49a2d2751ba8c97b58e6c03e9f5238357c..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 9f374ba627291bb79da0627c2c5ba184f073112a..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
--- a/browser/themes/pinstripe/browser/places/organizer.css
+++ b/browser/themes/pinstripe/browser/places/organizer.css
@@ -1,22 +1,10 @@
 %include ../shared.inc
 
-/* Inactive Window */
-
-#places:not([active="true"]) > #placesToolbox > #placesToolbar > toolbarbutton,
-#places:not([active="true"]) > #placesToolbox > #placesToolbar > #searchFilter {
-  opacity: 0.7;
-}
-
-#places:not([active="true"]) > #placesView > #placesList {
-  background-color: #e8e8e8;
-}
-
-
 /* Places Organizer Sidebars */
 
 #placesList {
   -moz-appearance: none;
   border: none;
   margin: 0;
 }
 
@@ -90,155 +78,111 @@ window:not([active="true"]) #placesList 
 #placesView > splitter {
   -moz-border-start: none !important;
   -moz-border-end: 1px solid #404040;
   min-width: 1px;
   width: 1px;
   background-image: none !important;       
 }
 
-.toolbarbutton-1 {
-  list-style-image: url("chrome://browser/skin/places/back-forward.png");
-}
-
-/* back button */
-
-#back-button {
-  -moz-image-region: rect(0px, 34px, 23px, 0px);
-  -moz-margin-end: 0;
-  -moz-padding-end: 0;
-  border-left: none;
-  border-right: none;
-}
-
-#back-button:-moz-locale-dir(rtl) {
-  -moz-image-region: rect(0px, 67px, 23px, 34px);
-}
-
-#back-button[disabled="true"] {
- -moz-image-region: rect(23px, 34px, 46px, 0px) !important;
-}
-
-#back-button[disabled="true"]:-moz-locale-dir(rtl) {
- -moz-image-region: rect(23px, 67px, 46px, 34px) !important;
-}
-
-#back-button:hover:active,
-#back-button[buttondown="true"],
-#back-button[open="true"] {
-  -moz-image-region: rect(46px, 34px, 69px, 0px);
-}
-
-#back-button:hover:active:-moz-locale-dir(rtl),
-#back-button[buttondown="true"]:-moz-locale-dir(rtl),
-#back-button[open="true"]:-moz-locale-dir(rtl) {
-  -moz-image-region: rect(46px, 67px, 69px, 34px);
-}
-
-#back-button > .toolbarbutton-text,
-#forward-button > .toolbarbutton-text {
-  display: none;
-}
-
-/* forward button */
-
-#forward-button {
-  -moz-image-region: rect(0px, 67px, 23px, 34px);
-  -moz-margin-start: 0;
-  -moz-margin-end: 8px;
-  -moz-padding-start: 0;
-  border-left: none;
-  border-right: none;
-}
-
-#forward-button:-moz-locale-dir(rtl) {
-  -moz-image-region: rect(0px, 34px, 23px, 0px);
+#placesToolbar > toolbarbutton {
+  list-style-image: url("chrome://browser/skin/places/toolbar.png");
+  margin: 4px 6px 5px;
+  padding: 1px 5px;
+  -moz-border-radius: 100%;
+  border: 1px solid @toolbarbuttonBorderColor@;
+  -moz-box-shadow: @loweredShadow@;
+  background: @toolbarbuttonBackground@;
+  -moz-background-origin: border;
 }
 
-#forward-button[disabled="true"] {
-  -moz-image-region: rect(23px, 67px, 46px, 34px) !important;
-}
-
-#forward-button[disabled="true"]:-moz-locale-dir(rtl) {
-  -moz-image-region: rect(23px, 34px, 46px, 0px) !important;
-}
-
-#forward-button:hover:active,
-#forward-button[buttondown="true"],
-#forward-button[open="true"] {
-  -moz-image-region: rect(46px, 67px, 69px, 34px);
-}
-
-#forward-button:hover:active:-moz-locale-dir(rtl),
-#forward-button[buttondown="true"]:-moz-locale-dir(rtl),
-#forward-button[open="true"]:-moz-locale-dir(rtl) {
-  -moz-image-region: rect(46px, 34px, 69px, 0px);
-}
-
-#placesToolbar > toolbarbutton[type="menu"] {
-  -moz-margin-start: 5px;
-  -moz-padding-end: 10px;
-  background: url("chrome://browser/skin/places/menubutton-end.png") right center no-repeat;
-}
-#placesToolbar > toolbarbutton[type="menu"][open="true"] {
-  background: url("chrome://browser/skin/places/menubutton-end-pressed.png") right center no-repeat;
+#placesToolbar > toolbarbutton:not([disabled="true"]):active:hover,
+#placesToolbar > toolbarbutton[open="true"] {
+  background: rgba(0, 0, 0, 0.6);
+  border-color: transparent;
+  -moz-box-shadow: @toolbarbuttonPressedInnerShadow@,
+                   @loweredShadow@,
+                   inset 0 0 0 20px @toolbarbuttonPressedBackgroundColor@;
 }
 
-#placesToolbar:-moz-locale-dir(rtl) > toolbarbutton[type="menu"] {
-  background: url("chrome://browser/skin/places/menubutton-end-rtl.png") left center no-repeat;
-}
-#placesToolbar:-moz-locale-dir(rtl) > toolbarbutton[type="menu"][open="true"] {
-  background: url("chrome://browser/skin/places/menubutton-end-pressed-rtl.png") left center no-repeat;
-}
-
-#placesToolbar > toolbarbutton[type="menu"] > menupopup {
-  -moz-margin-start: 2px;
-  margin-top: -4px;
+:root:not([active]) #placesToolbar > toolbarbutton {
+  border-color: @toolbarbuttonInactiveBorderColor@;
+  background-image: @toolbarbuttonInactiveBackgroundImage@;
 }
 
-#placesToolbar > toolbarbutton[type="menu"] > .toolbarbutton-icon {
-  background: url("chrome://browser/skin/places/menubutton-start.png") left center no-repeat;
-  padding: 3px 0px 4px 0px;
-  -moz-padding-start: 10px;
-  -moz-padding-end: 4px;
-  height: 23px;
-}
-#placesToolbar > toolbarbutton[type="menu"][open="true"] > .toolbarbutton-icon {
-  background: url("chrome://browser/skin/places/menubutton-start-pressed.png") left center no-repeat;
+#placesToolbar > toolbarbutton[disabled="true"] > .toolbarbutton-icon,
+:root:not([active]) #placesToolbar > toolbarbutton > .toolbarbutton-icon,
+:root:not([active]) #placesToolbar > toolbarbutton > .toolbarbutton-menu-dropmarker {
+  opacity: 0.5; /* remove the second and third selector when we support click-through (bug 392188) */
 }
 
-#placesToolbar:-moz-locale-dir(rtl) > toolbarbutton[type="menu"] > .toolbarbutton-icon {
-  background: url("chrome://browser/skin/places/menubutton-start-rtl.png") right center no-repeat;
-}
-#placesToolbar:-moz-locale-dir(rtl) > toolbarbutton[type="menu"][open="true"] > .toolbarbutton-icon {
-  background: url("chrome://browser/skin/places/menubutton-start-pressed-rtl.png") right center no-repeat;
+#placesToolbar > toolbarbutton > .toolbarbutton-icon {
+  margin: 0 4px;
 }
 
-#placesToolbar > toolbarbutton[type="menu"] > .toolbarbutton-text {
-  display:  none;
+#placesToolbar > toolbarbutton > .toolbarbutton-text {
+  display: none;
 }
 
 #placesToolbar > toolbarbutton[type="menu"] > .toolbarbutton-menu-dropmarker {
   list-style-image: url("chrome://browser/skin/places/folderDropArrow.png");
   padding: 0;
+  margin-top: 1px;
+  -moz-margin-end: 3px;
+}
+
+/* back and forward button */
+#placesToolbar > #back-button {
+  -moz-margin-start: 3px;
+}
+
+#back-button:-moz-locale-dir(ltr),
+#forward-button:-moz-locale-dir(rtl) {
+  -moz-image-region: rect(0px, 16px, 16px, 0px);
+  -moz-border-radius-topright: 0;
+  -moz-border-radius-bottomright: 0;
+  margin-right: 0;
+  border-right: 0;
+}
+
+#forward-button:-moz-locale-dir(ltr),
+#back-button:-moz-locale-dir(rtl) {
+  -moz-image-region: rect(0px, 32px, 16px, 16px);
+  -moz-border-radius-topleft: 0;
+  -moz-border-radius-bottomleft: 0;
+  margin-left: 0;
+}
+
+#back-button > .toolbarbutton-icon {
+  -moz-margin-end: 2px !important;
+}
+
+#forward-button > .toolbarbutton-icon {
+  -moz-margin-start: 2px !important;
 }
 
 /* organize button */
 #organizeButton {
-  list-style-image: url("chrome://browser/skin/places/toolbar-button-organize.png");
+  -moz-image-region: rect(0px, 48px, 16px, 32px);
 }
 
 /* view button */
 #viewMenu {
-  list-style-image: url("chrome://browser/skin/places/toolbar-button-view.png");
+  -moz-image-region: rect(0px, 64px, 16px, 48px);
 }
 
 /* maintenance button */
 #maintenanceButton {
-  list-style-image: url("chrome://browser/skin/places/toolbar-button-backup.png");
+  -moz-image-region: rect(0px, 80px, 16px, 64px);
+}
+
+/* Search field */
+
+:root:not([active="true"]) #searchFilter {
+  opacity: 0.7; /* remove this when we support click-through (bug 392188) */
 }
 
 /* Root View */
 #placesView {
   border-top: 1px solid ThreeDDarkShadow;
   -moz-user-focus: ignore;
 }
 
@@ -250,16 +194,20 @@ window:not([active="true"]) #placesList 
 #placesList {
   -moz-appearance: none;
   background-color: #d2d8e2;
   width: 160px;
   margin: 0px;
   border: 0px;
 }
 
+#places:not([active="true"]) > #placesView > #placesList {
+  background-color: #e8e8e8;
+}
+
 #infoPaneBox {
   border-top: 1px solid #919191;
   background-color: #f0f0f0;
   padding: 10px;
 }
 
 #placeContent {
   -moz-appearance: none;
deleted file mode 100644
index 0b463b4715be864afe2e29f552c5331245808dad..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index 57f4477366df492521a038be2fcb75b45d3709ca..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
deleted file mode 100644
index ad30157df7b401090bcec93c7a518a85fefd5575..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
GIT binary patch
literal 0
Hc$@<O00001
new file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..168daf9cef766934a4be4a20c0db72ee8e36bc78
GIT binary patch
literal 2394
zc$|e(2{e>@8-E$g7{g4)J_s3WG9vpRV=gncF$lL3vTs9th?@+T+|gK4D!Oe5B|AyC
zEM>bb({huE1|_m32KOe*_pdp1zVn^)o$op4edc+e=lT7f-~XBS{~OiSK?0$OfFMYM
z>}XE|zf|y`;V|G^&%${SBsd;UBvQi<ABLdh*T)Ln!lb>G`fTWdXi8vp%uS)JBxb5(
zcY$`5sFO*r%gLy-aeI!VgN?o<COsPFOqX(2P%8Fl1G}pyRG4!67c~gQN=H8IEud*!
z4l}q(rC-fZP2T2<YARKB|KdMp)G?YmI=b*Bi<@8wZ^m7jbm$!jnHX8m7+EjyTbqVy
zw+G-avbPIsi!dgOc&lQ9W6xp@;meHU9h_mKTl4JD%0XAFgPY-|TgTTPkE{#A#maRJ
z7X)azhHe7YP3~xhnOONqM1znzl<nMg9*V;Z(a4_yGn{l2_KpbOOM+n-UeL9Y7@Xju
zRQ<-OsmvD4kT>FuqK|1;yNPLs>bpH<3TAEMDVsBcvUY8$qW7?KgU>C;hJAgMX9u}v
zaNDRusE3EkpqzWiW$Wk`F0y+P`)M=f#>&UD`(`)lp7K!ZSKefYw;D;k6?k9`IR>Ap
zJ2^$sDlI(fVUYSWPJQDS%T?@b*Yy`y4B{?`L0`rOr5~jU8+ngSZTbIAub)rq|C<<K
zGl;V|RQ`knVOGZeSk!&#nD=_MN~yT4m7v*|X{%@MUMI|QR4|{vvxC@J)ne>dp_ui&
zihBN<E{pntl{Z?)uztVYMg*DRwQoGAwC6l+@hK87_%?v7Tq2ZhTXXvE{TH^1ZQdp)
z^80qSraVhf3z@xK7w<59@(_Ci9l5kSXSb_^O_WOM++S?z{0W8tTC{k^NU~nJW;rV&
zz$C=Ijrx0k%Td-*V+3k@R{jGur|bYh<iGw*P7bqb)c!?UB)_17&HZZvvvXic>C%+E
zRa!a2?rm&_bKXND7V&&@I4#(wmCm^}FQ*4%CESYVTv#1hdH-s{{hY*`#9MbgY8Ggr
zN~~)cS6jz*oTEyHYUk>Z31_~x%tU;Q?yjIXD~4<%^-GE5Ya(270<8?^ou+k`H*zB_
z+nZGAKNCJzEo}DWH(o#fmJ;2z_D@Hu!Dqi?P^~yTS-$Vw5cuZBVjX?sAxIqa^$~zd
zF35jPCdTd!{eCqdkBgOc;9A5|ojpk)vGvV<1X5B`8X6i~-|a^p7?a8T&-|lDkN&HT
z?`vyojg5_eko5NU@@W+n6%`Z|WMpLcc`O#oU@-VG3WWkyek>^|$qytXBz{bnmX-!S
zK0bbUc(}5%^7{4b6B85i^73+Wa^>aapcEY)otvA><MDthRaMpE;^OM+YAThA!C-WB
zbllwB3JMB9($CK?J3BisFVDrr1ytSL-LtZ?Qc_aV($at)S6A2c^z@>lA}=p5FdAr%
zh=>3_GBOebK0ZD%F)_N|j7%oOU@!*<2ha(W11#uAAP^w1u&@AAK(K4qE^t_DYim<e
zQvk8GwFL}dC>RYm!HPg0G=mZdKo#_xnVEq+pAaYqSg=MM4yUK52TEWBXa@Ts5C{Om
zA1WjyBqk<?L?Qtv*b<m1D=P~&1FFi($|@=<>gwt{cI*HoT3TA#+S-6hUtizAzyOcO
z8yOjyn3w<!mX?-QR#t#kR8$n80EDj!P^qb@fmbj{TwEOR17;vkQ&SVLfhuSQ5Re3~
zKtE^(vp_Rn8ypVjYXd;=*Kclau0}8Uf&x2%=IQ|n2*QMs;5aDswr#R<@(Nfbpm)2f
zx;hT0simvG$Hdgkf?#cJOC%EQNhFekBiY%Ny3gC!cmIKd{{8`hfgz!x;W6~s_{5ad
z)U>p81|uW$*K8(}#bOl{pF3Al`unBJm&+<@8yXrK8=IS(TUuIgwYPV4b$8!?(9_e`
z*Wcei@aL03&hYREFz)F1_`8Y8|7}xW?Zbx;(|ntmnFTgC_i=&u%}$#vTmnZE2y}9=
zXJ>M|!@(W1C)@A!On%LJChCR>fO;221w<W5Xteu&;pTK7ZQ{(Tr&5)wE)o5J)h{a}
z9c&<)^SYQKGfa!hSI<Ez97&gHejB=!GEfn!GnqC}YDGWtS&J^YF1^09bIZQtqzIjB
z*!iK<U9}hM6ieT?=T2s&#Lal$f`{+>OCk@V`i^+gz0B+7PP1#*Rfm-3yq%|XrI{n)
zq%8rcqpdSXiFV^9u`uzrIy2CeB*Qr+&_j9ejf-c(AoKx95Tjek^>y*m6v~h}K#@4E
z5<*`tr(|+U+uF-?-i7_-;m{(Vd*-n-GJ$aS*lgUZ7RGPqcjN79%vp)QZiLz2XwW3u
z>NWfHTCmr4@dz)>LmH$7J8q|2uzunNvG+a8!`P*~WK3RoGSNJ8xtM&-683H(94k=M
zl($H7<G#A~VxF+N_GIbh)9Kfej7bej<kRPEdv9bL7h<TJj8;si$*lH?yJxCXHcCR*
zoOY%AU1~=lw}(^i9;>$|&A>`dt47?x-rvR@I_QL^`7^}R4_zGZbGUEX#EI(X!5-?V
z-)3TKD0!a(>6{`$CQqD~NhspPemYwibb27jn`N+yE$STCA=d;Xxm<mKscG{qTP!Rz
zZ;Fc@GZw39+nQO@T+-N7E2wu;Pj?9u_mv`@3i1@=NFl~ha$!@c4IENq<ij`I__6!?
z)*i^B0in2%KT6BA4$WDvY;--wvOAU!LI$;)wmp@I&QX~>rI?PSjek~mc&oH7h|p<v
z%!(S81SX}EC@-rAeUh7c4)^?$FR}zaE?ff1C*kms;DCf+{UG3=-FUpYKHf}!H{KI(
tW?^V(fj7~^<1O&`Ngtz??|^7}P<Y7E{{y%^P3i&wh)i;|ueI~f_%|?<6MFyv
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -2157,25 +2157,16 @@ echo-dirs:
 	@echo $(DIRS)
 
 echo-module:
 	@echo $(MODULE)
 
 echo-requires:
 	@echo $(REQUIRES)
 
-echo-requires-recursive::
-ifdef _REPORT_ALL_DIRS
-	@echo $(subst $(topsrcdir)/,,$(srcdir)): $(MODULE): $(REQUIRES)
-else
-	@$(if $(REQUIRES),echo $(subst $(topsrcdir)/,,$(srcdir)): $(MODULE): $(REQUIRES))
-endif
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-
 echo-depth-path:
 	@$(topsrcdir)/build/unix/print-depth-path.sh
 
 echo-module-name:
 	@$(topsrcdir)/build/package/rpm/print-module-name.sh
 
 echo-module-filelist:
 	@$(topsrcdir)/build/package/rpm/print-module-filelist.sh
--- a/configure.in
+++ b/configure.in
@@ -3142,26 +3142,22 @@ case "$target" in
 *-darwin*)
   AC_MSG_CHECKING([for Core Text])
   AC_TRY_COMPILE([#include <ApplicationServices/ApplicationServices.h>],
                  [CTLineRef lineRef;],
                   ac_cv_have_core_text="yes",
                   ac_cv_have_core_text="no")
   AC_MSG_RESULT([$ac_cv_have_core_text])
 
-  case "${target_cpu}" in
-  x86_64)
-    MOZ_CORETEXT=1
-    ;;
-  esac
-
-  MOZ_ARG_ENABLE_BOOL(coretext,
-[  --enable-coretext      Use CoreText instead of ATSUI for text rendering],
-    MOZ_CORETEXT=1,
-    MOZ_CORETEXT=)
+  MOZ_CORETEXT=1
+
+  MOZ_ARG_DISABLE_BOOL(coretext,
+[  --disable-coretext      Use ATSUI instead of Core Text for text rendering],
+    MOZ_CORETEXT=,
+    MOZ_CORETEXT=1)
 
   if test -n "$MOZ_CORETEXT"; then
     if test "$ac_cv_have_core_text" = "no"; then
       AC_MSG_ERROR([--enable-coretext requires MacOS SDK 10.5 or newer])
      fi
      AC_DEFINE(MOZ_CORETEXT)
   fi
   ;;
@@ -4751,18 +4747,16 @@ cairo-os2)
     TK_LIBS='$(MOZ_CAIRO_LIBS)'
     ;;
 
 cairo-cocoa)
     MOZ_WIDGET_TOOLKIT=cocoa
     AC_DEFINE(MOZ_WIDGET_COCOA)
     MOZ_USER_DIR="Mozilla"
     AC_DEFINE(XP_MACOSX)
-    AC_DEFINE(TARGET_CARBON)
-    AC_DEFINE(TARGET_API_MAC_CARBON)
     TK_LIBS='-framework Carbon -framework CoreAudio -framework AudioToolbox -framework AudioUnit -framework AddressBook'
     TK_CFLAGS="-DNO_X11"
     LDFLAGS="$LDFLAGS -framework Cocoa"
     CFLAGS="$CFLAGS $TK_CFLAGS"
     CXXFLAGS="$CXXFLAGS $TK_CFLAGS"
     LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS) $(LIBXUL_DIST)/bin/XUL -lobjc'
     MOZ_FS_LAYOUT=bundle
     ;;
@@ -7358,17 +7352,17 @@ if test "$MOZ_TREE_CAIRO"; then
         PS_SURFACE_FEATURE="#define CAIRO_HAS_PS_SURFACE 1"
         PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
         FT_FONT_FEATURE="#define CAIRO_HAS_FT_FONT 1"
         FC_FONT_FEATURE="#define CAIRO_HAS_FC_FONT 1"
         MOZ_ENABLE_CAIRO_FT=1
         CAIRO_FT_CFLAGS="$FT2_CFLAGS"
     fi
     if test "$MOZ_WIDGET_TOOLKIT" = "qt"; then
-        QPAINTER_SURFACE_FEATURE="#define CAIRO_HAS_QPAINTER_SURFACE 1"
+        QT_SURFACE_FEATURE="#define CAIRO_HAS_QT_SURFACE 1"
     fi
     if test "$MOZ_WIDGET_TOOLKIT" = "cocoa"; then
         QUARTZ_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_SURFACE 1"
         QUARTZ_IMAGE_SURFACE_FEATURE="#define CAIRO_HAS_QUARTZ_IMAGE_SURFACE 1"
         QUARTZ_FONT_FEATURE="#define CAIRO_HAS_QUARTZ_FONT 1"
     fi
     if test "$MOZ_WIDGET_TOOLKIT" = "windows"; then
         WIN32_SURFACE_FEATURE="#define CAIRO_HAS_WIN32_SURFACE 1"
@@ -7447,17 +7441,17 @@ if test "$MOZ_TREE_CAIRO"; then
     AC_SUBST(OS2_SURFACE_FEATURE)
     AC_SUBST(BEOS_SURFACE_FEATURE)
     AC_SUBST(DIRECTFB_SURFACE_FEATURE)
     AC_SUBST(FT_FONT_FEATURE)
     AC_SUBST(FC_FONT_FEATURE)
     AC_SUBST(WIN32_FONT_FEATURE)
     AC_SUBST(QUARTZ_FONT_FEATURE)
     AC_SUBST(PNG_FUNCTIONS_FEATURE)
-    AC_SUBST(QPAINTER_SURFACE_FEATURE)
+    AC_SUBST(QT_SURFACE_FEATURE)
 
     if test "$_WIN32_MSVC"; then
         MOZ_CAIRO_LIBS='$(DEPTH)/gfx/cairo/cairo/src/mozcairo.lib $(DEPTH)/gfx/cairo/libpixman/src/mozlibpixman.lib'
     else
         MOZ_CAIRO_LIBS='$(DEPTH)/gfx/cairo/cairo/src/$(LIB_PREFIX)mozcairo.$(LIB_SUFFIX) $(DEPTH)/gfx/cairo/libpixman/src/$(LIB_PREFIX)mozlibpixman.$(LIB_SUFFIX)'" $CAIRO_FT_LIBS"
 
         if test "$MOZ_X11"; then
             MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS $XLDFLAGS -lXrender -lfreetype -lfontconfig"
@@ -7631,20 +7625,24 @@ AC_SUBST(NECKO_COOKIES)
 if test "$NECKO_COOKIES"; then
     AC_DEFINE(NECKO_COOKIES)
 fi
 
 dnl
 dnl Build jsctypes on the platforms we can.
 dnl
 AC_SUBST(BUILD_CTYPES)
-if test "$OS_TEST" != "arm"; then
+case "$OS_TEST" in
+arm*)
+  ;;
+*)
   BUILD_CTYPES=1
   AC_DEFINE(BUILD_CTYPES)
-fi
+  ;;
+esac
 
 dnl NECKO_ configuration options are not global
 _NON_GLOBAL_ACDEFINES="$_NON_GLOBAL_ACDEFINES NECKO_"
 
 dnl Only build Mork if it's required
 AC_SUBST(MOZ_MORK)
 if test "$MOZ_MORK"; then
   AC_DEFINE(MOZ_MORK)
--- a/content/base/public/nsIDocumentEncoder.idl
+++ b/content/base/public/nsIDocumentEncoder.idl
@@ -39,17 +39,17 @@
 #include "nsISupports.idl"
 
 interface nsIDOMDocument;
 interface nsIDOMRange;
 interface nsISelection;
 interface nsIDOMNode;
 interface nsIOutputStream;
 
-[scriptable, uuid(3c556e41-0f73-4e1d-b724-1474884fe2e3)]
+[scriptable, uuid(c0da5b87-0ba7-4d7c-8cb3-fcb02af4253d)]
 interface nsIDocumentEncoderNodeFixup : nsISupports
 {
   /**
    * Create a fixed up version of a node. This method is called before
    * each node in a document is about to be persisted. The implementor
    * may return a new node with fixed up attributes or null. If null is
    * returned the node should be used as-is.
    * @param aNode Node to fixup.
@@ -202,16 +202,23 @@ interface nsIDocumentEncoder : nsISuppor
 
   /**
    * Normally &nbsp; is replaced with a space character when
    * encoding data as plain text, set this flag if that's
    * not desired.
    * Plaintext output only.
    */
   const unsigned long OutputPersistNBSP = (1 << 17);
+
+  /**
+   * Normally when serializing the whole document using the HTML or 
+   * XHTML serializer, the encoding declaration is rewritten to match.
+   * This flag suppresses that behavior.
+   */
+  const unsigned long OutputDontRewriteEncodingDeclaration = (1 << 18);
   
   /**
    * Initialize with a pointer to the document and the mime type.
    * @param aDocument Document to encode.
    * @param aMimeType MimeType to use. May also be set by SetMimeType.
    * @param aFlags Flags to use while encoding. May also be set by SetFlags.
    */
   void init(in nsIDOMDocument aDocument,
--- a/content/base/src/nsDOMSerializer.cpp
+++ b/content/base/src/nsDOMSerializer.cpp
@@ -74,32 +74,34 @@ NS_IMPL_RELEASE(nsDOMSerializer)
 static nsresult
 SetUpEncoder(nsIDOMNode *aRoot, const nsACString& aCharset,
              nsIDocumentEncoder **aEncoder)
 {
   *aEncoder = nsnull;
    
   nsresult rv;
   nsCOMPtr<nsIDocumentEncoder> encoder =
-    do_CreateInstance(NS_DOC_ENCODER_CONTRACTID_BASE "text/xml", &rv);
+    do_CreateInstance(NS_DOC_ENCODER_CONTRACTID_BASE "application/xhtml+xml", &rv);
   if (NS_FAILED(rv))
     return rv;
 
   PRBool entireDocument = PR_TRUE;
   nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(aRoot));
   if (!domDoc) {
     entireDocument = PR_FALSE;
     rv = aRoot->GetOwnerDocument(getter_AddRefs(domDoc));
     if (NS_FAILED(rv))
       return rv;
   }
 
   // This method will fail if no document
-  rv = encoder->Init(domDoc, NS_LITERAL_STRING("text/xml"),
-                     nsIDocumentEncoder::OutputEncodeBasicEntities);
+  rv = encoder->Init(domDoc, NS_LITERAL_STRING("application/xhtml+xml"),
+                     nsIDocumentEncoder::OutputRaw |
+                     nsIDocumentEncoder::OutputDontRewriteEncodingDeclaration);
+
   if (NS_FAILED(rv))
     return rv;
 
   nsCAutoString charset(aCharset);
   if (charset.IsEmpty()) {
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
     NS_ASSERTION(doc, "Need a document");
     charset = doc->GetDocumentCharacterSet();
--- a/content/base/src/nsDocumentEncoder.cpp
+++ b/content/base/src/nsDocumentEncoder.cpp
@@ -912,18 +912,18 @@ nsDocumentEncoder::EncodeToString(nsAStr
   nsCOMPtr<nsIAtom> charsetAtom;
   if (!mCharset.IsEmpty()) {
     if (!mCharsetConverterManager) {
       mCharsetConverterManager = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
   
-  PRBool isWholeDocument = !(mSelection || mRange || mNode);
-  mSerializer->Init(mFlags, mWrapColumn, mCharset.get(), mIsCopying, isWholeDocument);
+  PRBool rewriteEncodingDeclaration = !(mSelection || mRange || mNode) && !(mFlags & OutputDontRewriteEncodingDeclaration);
+  mSerializer->Init(mFlags, mWrapColumn, mCharset.get(), mIsCopying, rewriteEncodingDeclaration);
 
   if (mSelection) {
     nsCOMPtr<nsIDOMRange> range;
     PRInt32 i, count = 0;
 
     rv = mSelection->GetRangeCount(&count);
     NS_ENSURE_SUCCESS(rv, rv);
 
--- a/content/base/src/nsHTMLContentSerializer.cpp
+++ b/content/base/src/nsHTMLContentSerializer.cpp
@@ -190,17 +190,17 @@ nsHTMLContentSerializer::SerializeHTMLAt
         }
       }
       // Need to escape URI.
       nsAutoString tempURI(valueStr);
       if (!isJS && NS_FAILED(EscapeURI(aContent, tempURI, valueStr)))
         valueStr = tempURI;
     }
 
-    if (mIsWholeDocument && aTagName == nsGkAtoms::meta &&
+    if (mRewriteEncodingDeclaration && aTagName == nsGkAtoms::meta &&
         attrName == nsGkAtoms::content) {
       // If we're serializing a <meta http-equiv="content-type">,
       // use the proper value, rather than what's in the document.
       nsAutoString header;
       aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);
       if (header.LowerCaseEqualsLiteral("content-type")) {
         valueStr = NS_LITERAL_STRING("text/html; charset=") +
           NS_ConvertASCIItoUTF16(mCharset);
--- a/content/base/src/nsXHTMLContentSerializer.cpp
+++ b/content/base/src/nsXHTMLContentSerializer.cpp
@@ -94,34 +94,34 @@ nsXHTMLContentSerializer::nsXHTMLContent
 nsXHTMLContentSerializer::~nsXHTMLContentSerializer()
 {
   NS_ASSERTION(mOLStateStack.IsEmpty(), "Expected OL State stack to be empty");
 }
 
 NS_IMETHODIMP
 nsXHTMLContentSerializer::Init(PRUint32 aFlags, PRUint32 aWrapColumn,
                               const char* aCharSet, PRBool aIsCopying,
-                              PRBool aIsWholeDocument)
+                              PRBool aRewriteEncodingDeclaration)
 {
   // The previous version of the HTML serializer did implicit wrapping
   // when there is no flags, so we keep wrapping in order to keep
   // compatibility with the existing calling code
   // XXXLJ perhaps we should remove these two default settings later ?
   if (aFlags & nsIDocumentEncoder::OutputFormatted ) {
       aFlags = aFlags | nsIDocumentEncoder::OutputWrap;
   }
   else if (!(aFlags & nsIDocumentEncoder::OutputRaw)) {
       aFlags = aFlags | nsIDocumentEncoder::OutputWrap;
   }
 
   nsresult rv;
-  rv = nsXMLContentSerializer::Init(aFlags, aWrapColumn, aCharSet, aIsCopying, aIsWholeDocument);
+  rv = nsXMLContentSerializer::Init(aFlags, aWrapColumn, aCharSet, aIsCopying, aRewriteEncodingDeclaration);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  mIsWholeDocument = aIsWholeDocument;
+  mRewriteEncodingDeclaration = aRewriteEncodingDeclaration;
   mIsCopying = aIsCopying;
   mIsFirstChildOfOL = PR_FALSE;
   mInBody = 0;
   mDisableEntityEncoding = 0;
   mBodyOnly = (mFlags & nsIDocumentEncoder::OutputBodyOnly) ? PR_TRUE
                                                             : PR_FALSE;
 
   // set up entity converter if we are going to need it
@@ -415,17 +415,17 @@ nsXHTMLContentSerializer::SerializeAttri
           }
         }
         // Need to escape URI.
         nsAutoString tempURI(valueStr);
         if (!isJS && NS_FAILED(EscapeURI(aContent, tempURI, valueStr)))
           valueStr = tempURI;
       }
 
-      if (mIsWholeDocument && aTagName == nsGkAtoms::meta &&
+      if (mRewriteEncodingDeclaration && aTagName == nsGkAtoms::meta &&
           attrName == nsGkAtoms::content) {
         // If we're serializing a <meta http-equiv="content-type">,
         // use the proper value, rather than what's in the document.
         nsAutoString header;
         aContent->GetAttr(kNameSpaceID_None, nsGkAtoms::httpEquiv, header);
         if (header.LowerCaseEqualsLiteral("content-type")) {
           valueStr = NS_LITERAL_STRING("text/html; charset=") +
             NS_ConvertASCIItoUTF16(mCharset);
@@ -488,17 +488,17 @@ nsXHTMLContentSerializer::AppendEndOfEle
 
 void
 nsXHTMLContentSerializer::AfterElementStart(nsIContent * aContent,
                                             nsIDOMElement *aOriginalElement,
                                             nsAString& aStr)
 {
   nsIAtom *name = aContent->Tag();
   if (aContent->GetNameSpaceID() == kNameSpaceID_XHTML &&
-      mIsWholeDocument &&
+      mRewriteEncodingDeclaration &&
       name == nsGkAtoms::head) {
 
     // Check if there already are any content-type meta children.
     // If there are, they will be modified to use the correct charset.
     // If there aren't, we'll insert one here.
     PRBool hasMeta = PR_FALSE;
     PRUint32 i, childCount = aContent->GetChildCount();
     for (i = 0; i < childCount; ++i) {
--- a/content/base/src/nsXHTMLContentSerializer.h
+++ b/content/base/src/nsXHTMLContentSerializer.h
@@ -55,17 +55,17 @@ class nsIAtom;
 
 class nsXHTMLContentSerializer : public nsXMLContentSerializer {
  public:
   nsXHTMLContentSerializer();
   virtual ~nsXHTMLContentSerializer();
 
   NS_IMETHOD Init(PRUint32 flags, PRUint32 aWrapColumn,
                   const char* aCharSet, PRBool aIsCopying,
-                  PRBool aIsWholeDocument);
+                  PRBool aRewriteEncodingDeclaration);
 
   NS_IMETHOD AppendText(nsIDOMText* aText,
                         PRInt32 aStartOffset,
                         PRInt32 aEndOffset,
                         nsAString& aStr);
 
   NS_IMETHOD AppendDocumentStart(nsIDOMDocument *aDocument,
                                  nsAString& aStr);
@@ -165,17 +165,17 @@ class nsXHTMLContentSerializer : public 
    * element is defined as CDATA in the DTD, it simply means we'll
    * output the content of the element without doing any entity encoding
    * what so ever.
    */
   PRInt32 mDisableEntityEncoding;
 
   // This is to ensure that we only do meta tag fixups when dealing with
   // whole documents.
-  PRPackedBool  mIsWholeDocument;
+  PRPackedBool  mRewriteEncodingDeclaration;
 
   // To keep track of First LI child of OL in selected range 
   PRPackedBool  mIsFirstChildOfOL;
 
   // To keep track of startvalue of OL and first list item for nested lists
   struct olState {
     olState(PRInt32 aStart, PRBool aIsFirst)
       : startVal(aStart),
--- a/content/base/src/nsXMLContentSerializer.cpp
+++ b/content/base/src/nsXMLContentSerializer.cpp
@@ -102,17 +102,17 @@ nsXMLContentSerializer::~nsXMLContentSer
 {
 }
 
 NS_IMPL_ISUPPORTS1(nsXMLContentSerializer, nsIContentSerializer)
 
 NS_IMETHODIMP 
 nsXMLContentSerializer::Init(PRUint32 aFlags, PRUint32 aWrapColumn,
                              const char* aCharSet, PRBool aIsCopying,
-                             PRBool aIsWholeDocument)
+                             PRBool aRewriteEncodingDeclaration)
 {
   mCharset = aCharSet;
   mFlags = aFlags;
 
   // Set the line break character:
   if ((mFlags & nsIDocumentEncoder::OutputCRLineBreak)
       && (mFlags & nsIDocumentEncoder::OutputLFLineBreak)) { // Windows
     mLineBreak.AssignLiteral("\r\n");
--- a/content/base/src/nsXMLContentSerializer.h
+++ b/content/base/src/nsXMLContentSerializer.h
@@ -63,17 +63,17 @@ class nsXMLContentSerializer : public ns
  public:
   nsXMLContentSerializer();
   virtual ~nsXMLContentSerializer();
 
   NS_DECL_ISUPPORTS
 
   NS_IMETHOD Init(PRUint32 flags, PRUint32 aWrapColumn,
                   const char* aCharSet, PRBool aIsCopying,
-                  PRBool aIsWholeDocument);
+                  PRBool aRewriteEncodingDeclaration);
 
   NS_IMETHOD AppendText(nsIDOMText* aText, PRInt32 aStartOffset,
                         PRInt32 aEndOffset, nsAString& aStr);
 
   NS_IMETHOD AppendCDATASection(nsIDOMCDATASection* aCDATASection,
                                 PRInt32 aStartOffset, PRInt32 aEndOffset,
                                 nsAString& aStr);
 
--- a/content/base/test/Makefile.in
+++ b/content/base/test/Makefile.in
@@ -272,16 +272,17 @@ include $(topsrcdir)/config/rules.mk
 		file_xhtmlserializer_1_sibling_body_only_body.xhtml \
 		file_xhtmlserializer_1_no_body.xhtml \
 		test_bug422403-2.xhtml \
 		file_xhtmlserializer_2.xhtml \
 		file_xhtmlserializer_2_basic.xhtml \
 		file_xhtmlserializer_2_enthtml.xhtml \
 		file_xhtmlserializer_2_entw3c.xhtml \
 		file_xhtmlserializer_2_latin1.xhtml \
+		test_bug500937.html \
 		test_htmlcopyencoder.html \
 		test_htmlcopyencoder.xhtml \
 		test_bug270145.xhtml \
 		test_elementTraversal.html \
 		test_w3element_traversal.html \
 		test_w3element_traversal.xhtml \
 		test_bug469020.html \
 		test_w3element_traversal_svg.html \
new file mode 100644
--- /dev/null
+++ b/content/base/test/test_bug500937.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=500937
+-->
+<head>
+  <title>Test for Bug 500937</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=500937">Mozilla Bug 500937</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <iframe id=iframe src="about:blank"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 500937 **/
+
+var d = document.implementation.createDocument("http://www.w3.org/1999/xhtml", "html", null);
+var h = d.documentElement;
+h.appendChild(d.createElementNS("http://www.w3.org/1999/xhtml", "head"));
+var b = d.createElementNS("http://www.w3.org/1999/xhtml", "body");
+h.appendChild(b);
+
+b.appendChild(d.createElementNS("http://www.w3.org/1999/xhtml", "div"));
+b.appendChild(d.createElementNS("http://www.w3.org/1999/xhtml", "script"));
+b.appendChild(d.createElementNS("http://www.w3.org/1999/xhtml", "br"));
+b.appendChild(d.createElementNS("http://www.w3.org/1999/xhtml", "source"));
+b.appendChild(d.createElementNS("http://www.w3.org/1999/xhtml", "param"));
+b.appendChild(d.createTextNode("\u00A0"));
+
+is(new XMLSerializer().serializeToString(d), 
+   '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><div></div><script><\/script><br /><source /><param />\u00A0</body></html>', 
+   "XML DOM input to XMLSerializer");
+
+d = document.getElementById('iframe').contentWindow.document;
+
+while(d.documentElement.previousSibling) {
+  d.removeChild(d.documentElement.previousSibling);
+}
+
+d.replaceChild(h, d.documentElement);
+
+is(new XMLSerializer().serializeToString(d),  
+   '<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body><div></div><script><\/script><br /><source /><param />\u00A0</body></html>', 
+   "HTML DOM input to XMLSerializer");
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -1791,17 +1791,17 @@ nsHTMLDocument::SetCookie(const nsAStrin
 
 // XXX TBI: accepting arguments to the open method.
 nsresult
 nsHTMLDocument::OpenCommon(const nsACString& aContentType, PRBool aReplace)
 {
   if (!IsHTML()) {
     // No calling document.open() on XHTML
 
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+    return NS_ERROR_DOM_INVALID_ACCESS_ERR;
   }
 
   PRBool loadAsHtml5 = nsHtml5Module::sEnabled;
 
   nsresult rv = NS_OK;
 
   // If we already have a parser we ignore the document.open call.
   if (mParser) {
@@ -2051,17 +2051,17 @@ nsHTMLDocument::Clear()
 }
 
 NS_IMETHODIMP
 nsHTMLDocument::Close()
 {
   if (!IsHTML()) {
     // No calling document.close() on XHTML!
 
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+    return NS_ERROR_DOM_INVALID_ACCESS_ERR;
   }
 
   nsresult rv = NS_OK;
 
   if (mParser && mWriteState == eDocumentOpened) {
     mPendingScripts.RemoveElement(GenerateParserKey());
 
     mWriteState = mPendingScripts.IsEmpty() ? eDocumentClosed : ePendingClose;
@@ -2116,17 +2116,17 @@ nsHTMLDocument::WriteCommon(const nsAStr
 {
   mTooDeepWriteRecursion =
     (mWriteLevel > NS_MAX_DOCUMENT_WRITE_DEPTH || mTooDeepWriteRecursion);
   NS_ENSURE_STATE(!mTooDeepWriteRecursion);
 
   if (!IsHTML()) {
     // No calling document.write*() on XHTML!
 
-    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+    return NS_ERROR_DOM_INVALID_ACCESS_ERR;
   }
 
   nsresult rv = NS_OK;
 
   void *key = GenerateParserKey();
   if (mWriteState == eDocumentClosed ||
       (mWriteState == ePendingClose &&
        !mPendingScripts.Contains(key))) {
--- a/content/html/document/src/nsPluginDocument.cpp
+++ b/content/html/document/src/nsPluginDocument.cpp
@@ -187,21 +187,32 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_IN
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_ISUPPORTS_INHERITED1(nsPluginDocument, nsMediaDocument,
                              nsIPluginDocument)
 
 void
 nsPluginDocument::SetScriptGlobalObject(nsIScriptGlobalObject* aScriptGlobalObject)
 {
-  if (!aScriptGlobalObject) {
+  // Set the script global object on the superclass before doing
+  // anything that might require it....
+  nsMediaDocument::SetScriptGlobalObject(aScriptGlobalObject);
+
+  if (aScriptGlobalObject) {
+    if (!mPluginContent) {
+      // Create synthetic document
+#ifdef DEBUG
+      nsresult rv =
+#endif
+        CreateSyntheticPluginDocument();
+      NS_ASSERTION(NS_SUCCEEDED(rv), "failed to create synthetic document");
+    }
+  } else {
     mStreamListener = nsnull;
   }
-
-  nsMediaDocument::SetScriptGlobalObject(aScriptGlobalObject);
 }
 
 
 PRBool
 nsPluginDocument::CanSavePresentation(nsIRequest *aNewRequest)
 {
   // Full-page plugins cannot be cached, currently, because we don't have
   // the stream listener data to feed to the plugin instance.
@@ -213,58 +224,55 @@ nsresult
 nsPluginDocument::StartDocumentLoad(const char*         aCommand,
                                     nsIChannel*         aChannel,
                                     nsILoadGroup*       aLoadGroup,
                                     nsISupports*        aContainer,
                                     nsIStreamListener** aDocListener,
                                     PRBool              aReset,
                                     nsIContentSink*     aSink)
 {
+  // do not allow message panes to host full-page plugins
+  // returning an error causes helper apps to take over
+  nsCOMPtr<nsIDocShellTreeItem> dsti (do_QueryInterface(aContainer));
+  if (dsti) {
+    PRBool isMsgPane = PR_FALSE;
+    dsti->NameEquals(NS_LITERAL_STRING("messagepane").get(), &isMsgPane);
+    if (isMsgPane) {
+      return NS_ERROR_FAILURE;
+    }
+  }
+
   nsresult rv =
     nsMediaDocument::StartDocumentLoad(aCommand, aChannel, aLoadGroup,
                                        aContainer, aDocListener, aReset,
                                        aSink);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   rv = aChannel->GetContentType(mMimeType);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
-  // Create synthetic document
-  rv = CreateSyntheticPluginDocument();
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
   mStreamListener = new nsPluginStreamListener(this);
   if (!mStreamListener) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
   NS_ASSERTION(aDocListener, "null aDocListener");
   NS_ADDREF(*aDocListener = mStreamListener);
 
   return rv;
 }
 
 nsresult
 nsPluginDocument::CreateSyntheticPluginDocument()
 {
-  // do not allow message panes to host full-page plugins
-  // returning an error causes helper apps to take over
-  nsCOMPtr<nsIDocShellTreeItem> dsti (do_QueryReferent(mDocumentContainer));
-  if (dsti) {
-    PRBool isMsgPane = PR_FALSE;
-    dsti->NameEquals(NS_LITERAL_STRING("messagepane").get(), &isMsgPane);
-    if (isMsgPane) {
-      return NS_ERROR_FAILURE;
-    }
-  }
+  NS_ASSERTION(!GetPrimaryShell() || !GetPrimaryShell()->DidInitialReflow(),
+               "Creating synthetic plugin document content too late");
 
   // make our generic document
   nsresult rv = nsMediaDocument::CreateSyntheticDocument();
   NS_ENSURE_SUCCESS(rv, rv);
   // then attach our plugin
 
   nsIContent* body = GetBodyContent();
   if (!body) {
--- a/content/html/document/test/test_bug332848.xhtml
+++ b/content/html/document/test/test_bug332848.xhtml
@@ -23,33 +23,33 @@ https://bugzilla.mozilla.org/show_bug.cg
 // parseChecker will become true if we keep parsing after calling close().
 var parseChecker = false;
 
 function test() {
   try {
     document.open();
     is(0, 1, "document.open succeeded");
   } catch (e) {
-    is (e.code, DOMException.NOT_SUPPORTED_ERR,
+    is (e.code, DOMException.INVALID_ACCESS_ERR,
         "Wrong exception from document.open");
   }
 
   try {
     document.write("aaa");
     is(0, 1, "document.write succeeded");
   } catch (e) {
-    is (e.code, DOMException.NOT_SUPPORTED_ERR,
+    is (e.code, DOMException.INVALID_ACCESS_ERR,
         "Wrong exception from document.write");
   }
 
   try {
     document.close();
     is(0, 1, "document.close succeeded");
   } catch (e) {
-    is (e.code, DOMException.NOT_SUPPORTED_ERR,
+    is (e.code, DOMException.INVALID_ACCESS_ERR,
         "Wrong exception from document.close");
   }
 }
 
 function loadTest() {
   is(parseChecker, true, "Parsing stopped");
   test();
   SimpleTest.finish();
--- a/content/smil/nsISMILType.h
+++ b/content/smil/nsISMILType.h
@@ -195,17 +195,17 @@ public:
    * @param   aStartVal     The value defining the start of the interval of
    *                        interpolation.
    * @param   aEndVal       The value defining the end of the interval of
    *                        interpolation.
    * @param   aUnitDistance A number between 0.0 and 1.0 (inclusive) defining
    *                        the distance of the interpolated value in the
    *                        interval.
    * @param   aResult       The interpolated value.
-   * @result  NS_OK on success, NS_ERROR_FAILURE if this data type cannot be
+   * @return  NS_OK on success, NS_ERROR_FAILURE if this data type cannot be
    *          interpolated or NS_ERROR_OUT_OF_MEMORY if insufficient memory was
    *          available for storing the result.
    *
    * @pre aStartVal.mType == aEndVal.mType == aResult.mType == this
    */
   virtual nsresult Interpolate(const nsSMILValue& aStartVal,
                                const nsSMILValue& aEndVal,
                                double aUnitDistance,
--- a/content/test/unit/test_xml_serializer.js
+++ b/content/test/unit/test_xml_serializer.js
@@ -256,29 +256,29 @@ function test7() {
                         "http://www.w3.org/1999/xhtml");
   do_check_serialize(doc);
   do_check_eq(SerializeXML(doc),
               '<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' +
               '<child2/></child1></root>');
 
   doc = ParseXML('<root xmlns="http://www.w3.org/1999/xhtml">' +
                  '<child1 xmlns="">' +
-                 '<child2 xmlns="http://www.w3.org/1999/xhtml"/>' +
+                 '<child2 xmlns="http://www.w3.org/1999/xhtml"></child2>' +
                  '</child1></root>')
   root = doc.documentElement;
   // No interface flattening in xpcshell
   child1 = root.firstChild.QueryInterface(nsIDOMElement);
   var child2 = child1.firstChild.QueryInterface(nsIDOMElement);
   child1.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns",
                         "http://www.w3.org/1999/xhtml");
   child2.setAttributeNS("http://www.w3.org/2000/xmlns/", "xmlns", "");
   do_check_serialize(doc);
   do_check_eq(SerializeXML(doc),
               '<root xmlns="http://www.w3.org/1999/xhtml"><child1 xmlns="">' +
-              '<a0:child2 xmlns:a0="http://www.w3.org/1999/xhtml" xmlns=""/></child1></root>');
+              '<a0:child2 xmlns:a0="http://www.w3.org/1999/xhtml" xmlns=""></a0:child2></child1></root>');
 }
 
 function test8() {
   // Test behavior of serializing with a given charset.
   var str1 = '<?xml version="1.0" encoding="ISO-8859-1"?>'+LB+'<root/>';
   var str2 = '<?xml version="1.0" encoding="UTF8"?>'+LB+'<root/>';
   var doc1 = ParseXML(str1);
   var doc2 = ParseXML(str2);
--- a/dom/base/nsFocusManager.cpp
+++ b/dom/base/nsFocusManager.cpp
@@ -952,17 +952,17 @@ nsFocusManager::EnsureCurrentWidgetFocus
     nsCOMPtr<nsIPresShell> presShell;
     docShell->GetPresShell(getter_AddRefs(presShell));
     if (presShell) {
       nsIViewManager* vm = presShell->GetViewManager();
       if (vm) {
         nsCOMPtr<nsIWidget> widget;
         vm->GetRootWidget(getter_AddRefs(widget));
         if (widget)
-          widget->SetFocus(PR_TRUE);
+          widget->SetFocus(PR_FALSE);
       }
     }
   }
 }
 
 void
 nsFocusManager::SetFocusInner(nsIContent* aNewContent, PRInt32 aFlags,
                               PRBool aFocusChanged)
@@ -1366,17 +1366,17 @@ nsFocusManager::Blur(nsPIDOMWindow* aWin
       if (objectFrame) {
         // note that the presshell's widget is being retrieved here, not the one
         // for the object frame.
         nsIViewManager* vm = presShell->GetViewManager();
         if (vm) {
           nsCOMPtr<nsIWidget> widget;
           vm->GetRootWidget(getter_AddRefs(widget));
           if (widget)
-            widget->SetFocus(PR_TRUE);
+            widget->SetFocus(PR_FALSE);
         }
       }
     }
   }
 
   PRBool result = PR_TRUE;
   if (content && !isRootContent) {
     // if there is an active window, update commands. If there isn't an active
@@ -1449,17 +1449,17 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
                       PRUint32 aFlags,
                       PRBool aIsNewDocument,
                       PRBool aFocusChanged,
                       PRBool aWindowRaised)
 {
   if (!aWindow)
     return;
 
-  if (aContent && aContent == mFirstFocusEvent)
+  if (aContent && (aContent == mFirstFocusEvent || aContent == mFirstBlurEvent))
     return;
 
   // Keep a reference to the presShell since dispatching the DOM event may
   // cause the document to be destroyed.
   nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
   if (!docShell)
     return;
 
@@ -1513,17 +1513,17 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
   mFocusedWindow = aWindow;
 
   // update the system focus.
   nsIViewManager* vm = presShell->GetViewManager();
   if (vm) {
     nsCOMPtr<nsIWidget> widget;
     vm->GetRootWidget(getter_AddRefs(widget));
     if (widget)
-      widget->SetFocus(PR_TRUE);
+      widget->SetFocus(PR_FALSE);
   }
 
   // if switching to a new document, first fire the focus event on the
   // document and then the window.
   if (aIsNewDocument) {
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(aWindow->GetExtantDocument());
     if (doc)
       SendFocusOrBlurEvent(NS_FOCUS_CONTENT, presShell, doc,
@@ -1555,17 +1555,17 @@ nsFocusManager::Focus(nsPIDOMWindow* aWi
       presContext->EventStateManager()->SetContentState(aContent, NS_EVENT_STATE_FOCUS);  
 
       // if this is an object/plug-in, focus the plugin's widget
       nsIFrame* contentFrame = presShell->GetPrimaryFrameFor(aContent);
       nsIObjectFrame* objectFrame = do_QueryFrame(contentFrame);
       if (objectFrame) {
         nsIWidget* widget = objectFrame->GetWidget();
         if (widget)
-          widget->SetFocus(PR_TRUE);
+          widget->SetFocus(PR_FALSE);
       }
 
       nsIMEStateManager::OnChangeFocus(presContext, aContent);
 
       // as long as this focus wasn't because a window was raised, update the
       // commands
       // XXXndeakin P2 someone could adjust the focus during the update
       if (!aWindowRaised)
--- a/dom/interfaces/css/nsIDOMNSCSS2Properties.idl
+++ b/dom/interfaces/css/nsIDOMNSCSS2Properties.idl
@@ -35,17 +35,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMCSS2Properties.idl"
 
-[scriptable, uuid(8C31E4A6-8F3A-4BB9-B180-8385AC2A4080)]
+[scriptable, uuid(cc0a6325-770b-476d-8cb8-c2a02a43c348)]
 interface nsIDOMNSCSS2Properties : nsIDOMCSS2Properties
 {
            /* Non-DOM 2 extensions */
 
            /* Mozilla extension CSS properties */
            attribute DOMString        MozAppearance;
                                         // raises(DOMException) on setting
 
@@ -273,9 +273,12 @@ interface nsIDOMNSCSS2Properties : nsIDO
            attribute DOMString        MozTransitionTimingFunction;
                                         // raises(DOMException) on setting
 
            attribute DOMString        MozTransition;
                                         // raises(DOMException) on setting
 
            attribute DOMString        pointerEvents;
                                         // raises(DOMException) on setting
+
+           attribute DOMString        MozTabSize;
+                                        // raises(DOMException) on setting
 };
--- a/dom/tests/mochitest/chrome/window_focus.xul
+++ b/dom/tests/mochitest/chrome/window_focus.xul
@@ -734,16 +734,25 @@ function startTest()
   textbox2.tabIndex = 2;
   gLastFocusMethod = 0;
   expectFocusShift(function () textbox2.focus(),
                    null, textbox2.inputField, true, "focus on textbox with tabindex set");
   gLastFocusMethod = fm.FLAG_BYKEY;
   expectFocusShift(function () synthesizeKey("VK_TAB", { shiftKey: true }),
                    null, textbox1.inputField, true, "shift+tab on textbox with tabindex set");
 
+  // ---- test to check that refocusing an element during a blur event doesn't succeed
+
+  var t1 = getById("t1");
+  t1.addEventListener("blur", function() t1.focus(), true);
+  t1.focus();
+  var t2 = getById("t2");
+  synthesizeMouse(t2, 2, 2, { });
+  is(fm.focusedElement, t2, "focus during blur");
+
   setFocusTo("t9", window);
   gLastFocusMethod = -1;
   window.openDialog("focus_window2.xul", "_blank", "chrome", otherWindowFocused);
 }
 
 function doCommandDispatcherTests()
 {
   var t19 = getById("t19");
--- a/embedding/components/windowwatcher/src/nsPromptService.cpp
+++ b/embedding/components/windowwatcher/src/nsPromptService.cpp
@@ -53,17 +53,16 @@
 #include "nsIStringBundle.h"
 #include "nsXPIDLString.h"
 #include "nsISound.h"
 
 static const char kPromptURL[] = "chrome://global/content/commonDialog.xul";
 static const char kSelectPromptURL[] = "chrome://global/content/selectDialog.xul";
 static const char kQuestionIconClass[] = "question-icon";
 static const char kAlertIconClass[] = "alert-icon";
-static const char kWarningIconClass[] = "message-icon";
 // We include question-icon for backwards compatibility
 static const char kAuthenticationIconClass[] = "authentication-icon question-icon";
 
 #define kCommonDialogsProperties "chrome://global/locale/commonDialogs.properties"
 
 /****************************************************************
  ************************* ParamBlock ***************************
  ****************************************************************/
--- a/extensions/reporter/jar.mn
+++ b/extensions/reporter/jar.mn
@@ -1,9 +1,9 @@
-browser.jar:
+toolkit.jar:
 % content reporter %content/reporter/ xpcnativewrappers=yes
 % overlay chrome://browser/content/browser.xul         chrome://reporter/content/reporterOverlay.xul
 % overlay chrome://navigator/content/navigator.xul     chrome://reporter/content/reporterOverlay.xul
 % overlay chrome://global/content/customizeToolbar.xul chrome://reporter/content/reporterOverlay.xul
 % skin reporter classic/1.0 %skin/classic/reporter/
  content/reporter/reportWizard.xul                       (resources/content/reporter/reportWizard.xul)
  content/reporter/reportWizard.js                        (resources/content/reporter/reportWizard.js)
  content/reporter/reporterOverlay.xul                    (resources/content/reporter/reporterOverlay.xul)
--- a/gfx/cairo/README
+++ b/gfx/cairo/README
@@ -25,18 +25,16 @@ win32-logical-font-scale.patch: set CAIR
 nonfatal-assertions.patch: Make assertions non-fatal
 
 buggy-repeat.patch: Unconditionally turn on buggy-repeat handling to bandaid bug 413583.
 
 cairo-version-fixes.patch: fix up cairo-version.c/cairo-version.h for in-place builds
 
 win32-ddb-dib.patch: fix for bug 455513; not upstream yet pending feebdack
 
-qpainter-type.patch: add SURFACE_TYPE_QPAINTER to cairo.h
-
 wince-fixes.patch: stubs out win32 functions we use but are not supported on win32.  Also implements ExtSelectClipRgn in terms of other functions available on wince.
 
 win32-vertically-offset-glyph.patch: bug 454098; vertical positioning errors when drawing glyph runs including delta-y offsets on screen via GDI
 
 ignore-rank0.patch: bug 474886; Not redrawing the background when changing page on flickr
 
 win32-canvas-glyph-position.patch: bug 475092; horizontal positioning errors when drawing glyph runs with delta-y offsets to canvas through win32-font
 
--- a/gfx/cairo/cairo/src/cairo-features.h.in
+++ b/gfx/cairo/cairo/src/cairo-features.h.in
@@ -74,17 +74,17 @@
 @WIN32_SURFACE_FEATURE@
 
 @OS2_SURFACE_FEATURE@
 
 @BEOS_SURFACE_FEATURE@
 
 @DIRECTFB_SURFACE_FEATURE@
 
-@QPAINTER_SURFACE_FEATURE@
+@QT_SURFACE_FEATURE@
 
 @DDRAW_SURFACE_FEATURE@
 
 @OGLES_SURFACE_FEATURE@
 
 @FT_FONT_FEATURE@
 
 @WIN32_FONT_FEATURE@
--- a/gfx/cairo/cairo/src/cairo-qpainter-surface.cpp
+++ b/gfx/cairo/cairo/src/cairo-qpainter-surface.cpp
@@ -837,17 +837,17 @@ struct PatternToBrushConverter {
                 solid->color.blue,
                 solid->color.alpha);
 
             mBrush = QBrush(color);
         } else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
             cairo_surface_pattern_t *spattern = (cairo_surface_pattern_t*) pattern;
             cairo_surface_t *surface = spattern->surface;
 
-            if (surface->type == CAIRO_SURFACE_TYPE_QPAINTER) {
+            if (surface->type == CAIRO_SURFACE_TYPE_QT) {
                 cairo_qpainter_surface_t *qs = (cairo_qpainter_surface_t*) surface;
 
                 if (qs->image) {
                     mBrush = QBrush(*qs->image);
                 } else if (qs->pixmap) {
                     mBrush = QBrush(*qs->pixmap);
                 } else {
                     // do something smart
@@ -1143,17 +1143,17 @@ bool
                            cairo_antialias_t antialias = CAIRO_ANTIALIAS_NONE)
 {
     QImage *qsSrc_image = NULL;
     QPixmap *qsSrc_pixmap = NULL;
     std::auto_ptr<QImage> qsSrc_image_d;
 
     if (source->type == CAIRO_PATTERN_TYPE_SURFACE) {
         cairo_surface_pattern_t *spattern = (cairo_surface_pattern_t*) source;
-        if (spattern->surface->type == CAIRO_SURFACE_TYPE_QPAINTER) {
+        if (spattern->surface->type == CAIRO_SURFACE_TYPE_QT) {
             cairo_qpainter_surface_t *p = (cairo_qpainter_surface_t*) spattern->surface;
 
             qsSrc_image = p->image;
             qsSrc_pixmap = p->pixmap;
         } else if (spattern->surface->type == CAIRO_SURFACE_TYPE_IMAGE) {
             cairo_image_surface_t *p = (cairo_image_surface_t*) spattern->surface;
             qsSrc_image = new QImage((const uchar*) p->data,
                                      p->width,
@@ -1499,17 +1499,17 @@ static cairo_int_status_t
             qimg = new QImage ((const uchar *) isurf->data,
                                isurf->width,
                                isurf->height,
                                isurf->stride,
                                _qimage_format_from_cairo_format (isurf->format));
             qimg_d.reset(qimg);
         }
 
-        if (surface->type == CAIRO_SURFACE_TYPE_QPAINTER) {
+        if (surface->type == CAIRO_SURFACE_TYPE_QT) {
             cairo_qpainter_surface_t *qsrc = (cairo_qpainter_surface_t*) surface;
 
             if (qsrc->image)
                 qimg = qsrc->image;
             else if (qsrc->pixmap)
                 qpixmap = qsrc->pixmap;
         }
 
@@ -1552,17 +1552,17 @@ static cairo_status_t
     return CAIRO_STATUS_SUCCESS;
 }
 
 /**
  ** Backend struct
  **/
 
 static const cairo_surface_backend_t cairo_qpainter_surface_backend = {
-    CAIRO_SURFACE_TYPE_QPAINTER,
+    CAIRO_SURFACE_TYPE_QT,
     _cairo_qpainter_surface_create_similar,
     _cairo_qpainter_surface_finish,
     _cairo_qpainter_surface_acquire_source_image,
     _cairo_qpainter_surface_release_source_image,
     _cairo_qpainter_surface_acquire_dest_image,
     _cairo_qpainter_surface_release_dest_image,
     _cairo_qpainter_surface_clone_similar,
 
@@ -1771,39 +1771,39 @@ cairo_qpainter_surface_create_with_qpixm
     return &qs->base;
 }
 
 QPainter *
 cairo_qpainter_surface_get_qpainter (cairo_surface_t *surface)
 {
     cairo_qpainter_surface_t *qs = (cairo_qpainter_surface_t*) surface;
 
-    if (surface->type != CAIRO_SURFACE_TYPE_QPAINTER)
+    if (surface->type != CAIRO_SURFACE_TYPE_QT)
         return NULL;
 
     return qs->p;
 }
 
 QImage *
 cairo_qpainter_surface_get_qimage (cairo_surface_t *surface)
 {
     cairo_qpainter_surface_t *qs = (cairo_qpainter_surface_t*) surface;
 
-    if (surface->type != CAIRO_SURFACE_TYPE_QPAINTER)
+    if (surface->type != CAIRO_SURFACE_TYPE_QT)
         return NULL;
 
     return qs->image;
 }
 
 cairo_surface_t *
 cairo_qpainter_surface_get_image (cairo_surface_t *surface)
 {
     cairo_qpainter_surface_t *qs = (cairo_qpainter_surface_t*) surface;
 
-    if (surface->type != CAIRO_SURFACE_TYPE_QPAINTER)
+    if (surface->type != CAIRO_SURFACE_TYPE_QT)
         return NULL;
 
     return (cairo_surface_t*) qs->image_equiv;
 }
 
 /*
  * TODO:
  *
--- a/gfx/cairo/cairo/src/cairo-qpainter.h
+++ b/gfx/cairo/cairo/src/cairo-qpainter.h
@@ -34,17 +34,17 @@
  *      Vladimir Vukicevic <vladimir@mozilla.com>
  */
 
 #ifndef CAIRO_QPAINTER_H
 #define CAIRO_QPAINTER_H
 
 #include <cairo.h>
 
-#if CAIRO_HAS_QPAINTER_SURFACE
+#if CAIRO_HAS_QT_SURFACE
 
 class QPainter;
 class QImage;
 
 CAIRO_BEGIN_DECLS
 
 cairo_public cairo_surface_t *
 cairo_qpainter_surface_create (QPainter *painter);
@@ -65,15 +65,15 @@ cairo_qpainter_surface_get_qpainter (cai
 cairo_public cairo_surface_t *
 cairo_qpainter_surface_get_image (cairo_surface_t *surface);
 
 cairo_public QImage *
 cairo_qpainter_surface_get_qimage (cairo_surface_t *surface);
 
 CAIRO_END_DECLS
 
-#else /* CAIRO_HAS_QPAINTER_SURFACE */
+#else /* CAIRO_HAS_QT_SURFACE */
 
 # error Cairo was not compiled with support for the QPainter backend
 
-#endif /* CAIRO_HAS_QPAINTER_SURFACE */
+#endif /* CAIRO_HAS_QT_SURFACE */
 
 #endif /* CAIRO_QPAINTER_H_ */
--- a/gfx/cairo/cairo/src/cairoint.h
+++ b/gfx/cairo/cairo/src/cairoint.h
@@ -2529,17 +2529,17 @@ cairo_private void
 cairo_private cairo_bool_t
 _cairo_pattern_is_opaque_solid (const cairo_pattern_t *pattern);
 
 cairo_private cairo_bool_t
 _cairo_pattern_is_opaque (const cairo_pattern_t *abstract_pattern);
 
 enum {
     CAIRO_PATTERN_ACQUIRE_NONE = 0x0,
-    CAIRO_PATTERN_ACQUIRE_NO_REFLECT = 0x1,
+    CAIRO_PATTERN_ACQUIRE_NO_REFLECT = 0x1
 };
 cairo_private cairo_int_status_t
 _cairo_pattern_acquire_surface (const cairo_pattern_t	   *pattern,
 				cairo_surface_t		   *dst,
 				cairo_content_t		    content,
 				int			   x,
 				int			   y,
 				unsigned int		   width,
deleted file mode 100644
--- a/gfx/cairo/qpainter-type.patch
+++ /dev/null
@@ -1,21 +0,0 @@
-diff --git a/gfx/cairo/cairo/src/cairo.h b/gfx/cairo/cairo/src/cairo.h
---- a/gfx/cairo/cairo/src/cairo.h
-+++ b/gfx/cairo/cairo/src/cairo.h
-@@ -1875,6 +1875,7 @@
-  * @CAIRO_SURFACE_TYPE_OS2: The surface is of type os2
-  * @CAIRO_SURFACE_TYPE_WIN32_PRINTING: The surface is a win32 printing surface
-  * @CAIRO_SURFACE_TYPE_QUARTZ_IMAGE: The surface is of type quartz_image
-+ * @CAIRO_SURFACE_TYPE_QPAINTER: The surface is of type qpainter
-  *
-  * #cairo_surface_type_t is used to describe the type of a given
-  * surface. The surface types are also known as "backends" or "surface
-@@ -1913,7 +1914,8 @@
-     CAIRO_SURFACE_TYPE_SVG,
-     CAIRO_SURFACE_TYPE_OS2,
-     CAIRO_SURFACE_TYPE_WIN32_PRINTING,
--    CAIRO_SURFACE_TYPE_QUARTZ_IMAGE
-+    CAIRO_SURFACE_TYPE_QUARTZ_IMAGE,
-+    CAIRO_SURFACE_TYPE_QPAINTER
- } cairo_surface_type_t;
- 
- cairo_public cairo_surface_type_t
--- a/gfx/src/thebes/nsSystemFontsGTK2.cpp
+++ b/gfx/src/thebes/nsSystemFontsGTK2.cpp
@@ -216,17 +216,17 @@ nsSystemFontsGTK2::GetSystemFontInfo(Gtk
     aFontStyle->stretch = NS_FONT_STRETCH_NORMAL;
 
     float size = float(pango_font_description_get_size(desc)) / PANGO_SCALE;
 
     // |size| is now either pixels or pango-points (not Mozilla-points!)
 
     if (!MOZ_pango_font_description_get_size_is_absolute(desc)) {
         // |size| is in pango-points, so convert to pixels.
-        size *= float(gfxPlatform::GetDPI()) / POINTS_PER_INCH_FLOAT;
+        size *= float(gfxPlatformGtk::GetPlatformDPI()) / POINTS_PER_INCH_FLOAT;
     }
 
     // |size| is now pixels
 
     aFontStyle->size = size;
   
     pango_font_description_free(desc);
 
--- a/gfx/src/thebes/nsSystemFontsQt.cpp
+++ b/gfx/src/thebes/nsSystemFontsQt.cpp
@@ -74,17 +74,17 @@ nsSystemFontsQt::GetSystemFontInfo(const
     aFontStyle->style = FONT_STYLE_NORMAL;
     aFontStyle->systemFont = PR_TRUE;
     NS_NAMED_LITERAL_STRING(quote, "\"");
     nsString family((PRUnichar*)qFont.family().data());
     *aFontName = quote + family + quote;
     aFontStyle->weight = qFont.weight();
     // FIXME: Set aFontStyle->stretch correctly!
     aFontStyle->stretch = NS_FONT_STRETCH_NORMAL;
-    aFontStyle->size = qFont.pointSizeF() * float(gfxPlatform::GetDPI()) / 72.0f;
+    aFontStyle->size = qFont.pointSizeF() * float(gfxQtPlatform::GetPlatformDPI()) / 72.0f;
     return NS_OK;
 }
 
 
 nsresult
 nsSystemFontsQt::GetSystemFont(nsSystemFontID anID, nsString *aFontName,
                                  gfxFontStyle *aFontStyle) const
 {
--- a/gfx/thebes/public/gfxPlatformGtk.h
+++ b/gfx/thebes/public/gfxPlatformGtk.h
@@ -124,18 +124,27 @@ public:
 #ifndef MOZ_PANGO
     FT_Library GetFTLibrary();
 #endif
 
     void SetGdkDrawable(gfxASurface *target,
                         GdkDrawable *drawable);
     GdkDrawable *GetGdkDrawable(gfxASurface *target);
 
+    static PRInt32 GetPlatformDPI() {
+        if (sPlatformDPI < 0) {
+            gfxPlatformGtk::GetPlatform()->InitDisplayCaps();
+        }
+        NS_ASSERTION(sPlatformDPI > 0, "Something is wrong");
+        return sPlatformDPI;
+    }
+
 protected:
     void InitDisplayCaps();
 
+    static PRInt32 sPlatformDPI;
     static gfxFontconfigUtils *sFontconfigUtils;
 
 private:
     virtual qcms_profile *GetPlatformCMSOutputProfile();
 };
 
 #endif /* GFX_PLATFORM_GTK_H */
--- a/gfx/thebes/public/gfxQtPlatform.h
+++ b/gfx/thebes/public/gfxQtPlatform.h
@@ -80,19 +80,21 @@ public:
     FontFamily *FindFontFamily(const nsAString& aName);
     FontEntry *FindFontEntry(const nsAString& aFamilyName, const gfxFontStyle& aFontStyle);
     already_AddRefed<gfxFont> FindFontForChar(PRUint32 aCh, gfxFont *aFont);
     PRBool GetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<FontEntry> > *aFontEntryList);
     void SetPrefFontEntries(const nsCString& aLangGroup, nsTArray<nsRefPtr<FontEntry> >& aFontEntryList);
 
     FT_Library GetFTLibrary();
 
+    static PRInt32 GetPlatformDPI() {
+        return 96;
+    }
+
 protected:
-    void InitDisplayCaps();
-
     static gfxFontconfigUtils *sFontconfigUtils;
 
 private:
     virtual qcms_profile *GetPlatformCMSOutputProfile();
 };
 
 #endif /* GFX_PLATFORM_QT_H */
 
--- a/gfx/thebes/src/gfxASurface.cpp
+++ b/gfx/thebes/src/gfxASurface.cpp
@@ -54,17 +54,17 @@
 #include "gfxQuartzSurface.h"
 #include "gfxQuartzImageSurface.h"
 #endif
 
 #ifdef MOZ_DFB
 #include "gfxDirectFBSurface.h"
 #endif
 
-#ifdef CAIRO_HAS_QPAINTER_SURFACE
+#ifdef CAIRO_HAS_QT_SURFACE
 #include "gfxQPainterSurface.h"
 #endif
 
 #ifdef CAIRO_HAS_DDRAW_SURFACE
 #include "gfxDDrawSurface.h"
 #endif
 
 #include <stdio.h>
@@ -175,18 +175,18 @@ gfxASurface::Wrap (cairo_surface_t *csur
         result = new gfxQuartzImageSurface(csurf);
     }
 #endif
 #ifdef MOZ_DFB
     else if (stype == CAIRO_SURFACE_TYPE_DIRECTFB) {
         result = new gfxDirectFBSurface(csurf);
     }
 #endif
-#ifdef CAIRO_HAS_QPAINTER_SURFACE
-    else if (stype == CAIRO_SURFACE_TYPE_QPAINTER) {
+#ifdef CAIRO_HAS_QT_SURFACE
+    else if (stype == CAIRO_SURFACE_TYPE_QT) {
         result = new gfxQPainterSurface(csurf);
     }
 #endif
 #ifdef CAIRO_HAS_DDRAW_SURFACE
     else if (stype == CAIRO_SURFACE_TYPE_DDRAW) {
         result = new gfxDDrawSurface(csurf);
     }
 #endif
--- a/gfx/thebes/src/gfxPangoFonts.cpp
+++ b/gfx/thebes/src/gfxPangoFonts.cpp
@@ -782,17 +782,17 @@ gfx_pango_fc_font_describe(PangoFont *fo
     gfxPangoFcFont *self = GFX_PANGO_FC_FONT(font);
     PangoFcFont *fcFont = &self->parent_instance;
     PangoFontDescription *result =
         pango_font_description_copy(fcFont->description);
 
     gfxFcFont *gfxFont = gfxPangoFcFont::GfxFont(self);
     if (gfxFont) {
         double pixelsize = gfxFont->GetStyle()->size;
-        double dpi = gfxPlatform::GetDPI();
+        double dpi = gfxPlatformGtk::GetPlatformDPI();
         gint size = moz_pango_units_from_double(pixelsize * dpi / 72.0);
         pango_font_description_set_size(result, size);
     }
     return result;
 }
 
 static PangoFontDescription *
 gfx_pango_fc_font_describe_absolute(PangoFont *font)
@@ -1779,18 +1779,18 @@ gfx_pango_font_map_load_fontset(PangoFon
     return gfxPangoFontset::NewFontset(fontGroup, language);
 }
 
 static double
 gfx_pango_font_map_get_resolution(PangoFcFontMap *fcfontmap,
                                   PangoContext *context)
 {
     // This merely enables the FC_SIZE field of the pattern to be accurate.
-    // We use gfxPlatform::GetDPI() much of the time...
-    return gfxPlatform::GetDPI();
+    // We use gfxPlatformGtk::GetPlatformDPI() much of the time...
+    return gfxPlatformGtk::GetPlatformDPI();
 }
 
 #ifdef MOZ_WIDGET_GTK2
 static void ApplyGdkScreenFontOptions(FcPattern *aPattern);
 #endif
 
 // Apply user settings and defaults to pattern in preparation for matching.
 static void
--- a/gfx/thebes/src/gfxPlatformGtk.cpp
+++ b/gfx/thebes/src/gfxPlatformGtk.cpp
@@ -93,16 +93,17 @@
 
 #ifdef MOZ_PLATFORM_HILDON
 #include "nsCOMPtr.h"
 #include "nsILocalFile.h"
 #include "nsILineInputStream.h"
 #include "nsNetUtil.h"
 #endif
 
+PRInt32 gfxPlatformGtk::sPlatformDPI = -1;
 gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nsnull;
 
 #ifndef MOZ_PANGO
 typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
 typedef nsDataHashtable<nsCStringHashKey, nsTArray<nsRefPtr<FontEntry> > > PrefFontTable;
 static FontTable *gPlatformFonts = NULL;
 static FontTable *gPlatformFontAliases = NULL;
 static PrefFontTable *gPrefFonts = NULL;
@@ -525,52 +526,59 @@ gfxPlatformGtk::CreateFontGroup(const ns
     return new gfxFT2FontGroup(aFamilies, aStyle);
 }
 
 #endif
 
 void
 gfxPlatformGtk::InitDisplayCaps()
 {
+    GdkScreen *screen = gdk_screen_get_default();
+    gtk_settings_get_for_screen(screen); // Make sure init is run so we have a resolution
+    gfxPlatformGtk::sPlatformDPI = PRInt32(round(gdk_screen_get_resolution(screen)));
+
+    if (gfxPlatformGtk::sPlatformDPI <= 0) {
+        // Fall back to something sane
+        gfxPlatformGtk::sPlatformDPI = 96;
+    }
+
 #if defined(MOZ_PLATFORM_HILDON)
     // Check the cached value
     if (gfxPlatform::sDPI == -1) {
         nsresult rv;
         nsCOMPtr<nsILocalFile> file;
         rv = NS_NewLocalFile(NS_LITERAL_STRING("/proc/component_version"),
                              PR_TRUE, getter_AddRefs(file));
         if (NS_SUCCEEDED(rv)) {
             nsCOMPtr<nsIInputStream> fileStream;
-            NS_NewLocalFileInputStream(getter_AddRefs(fileStream), file);                
+            NS_NewLocalFileInputStream(getter_AddRefs(fileStream), file);
             nsCOMPtr<nsILineInputStream> lineStream = do_QueryInterface(fileStream);
             
             // Extract the product code from the component_version file
             nsCAutoString buffer;
             PRBool isMore = PR_TRUE;
-            if (NS_SUCCEEDED(lineStream->ReadLine(buffer, &isMore))) {
+            if (lineStream && NS_SUCCEEDED(lineStream->ReadLine(buffer, &isMore))) {
                 if (StringEndsWith(buffer, NS_LITERAL_CSTRING("RX-51"))) {
                     gfxPlatform::sDPI = 265; // It's an N900
                 }
                 else if (StringEndsWith(buffer, NS_LITERAL_CSTRING("RX-44")) ||
                          StringEndsWith(buffer, NS_LITERAL_CSTRING("RX-48")) ||
                          StringEndsWith(buffer, NS_LITERAL_CSTRING("RX-34"))) {
                     gfxPlatform::sDPI = 225; // It's an N810/N800
                 }
             }
         }
     }
 #else
-    GdkScreen *screen = gdk_screen_get_default();
-    gtk_settings_get_for_screen(screen); // Make sure init is run so we have a resolution
-    gfxPlatform::sDPI = PRInt32(round(gdk_screen_get_resolution(screen)));
+    gfxPlatform::sDPI = gfxPlatformGtk::sPlatformDPI;
 #endif
 
-    if (gfxPlatform::sDPI <= 0.0) {
+    if (gfxPlatform::sDPI <= 0) {
         // Fall back to something sane
-        gfxPlatform::sDPI = 96.0;
+        gfxPlatform::sDPI = 96;
     } else {
         // Minimum DPI is 96
         gfxPlatform::sDPI = PR_MAX(sDPI, 96);
     }
 }
 
 qcms_profile *
 gfxPlatformGtk::GetPlatformCMSOutputProfile()
--- a/js/ctypes/Function.cpp
+++ b/js/ctypes/Function.cpp
@@ -138,17 +138,17 @@ GetABI(PRUint16 aCallType, ffi_abi& aRes
 {
   // determine the ABI from the subset of those available on the
   // given platform. nsIForeignLibrary::DEFAULT specifies the default
   // C calling convention (cdecl) on each platform.
   switch (aCallType) {
   case nsIForeignLibrary::DEFAULT:
     aResult = FFI_DEFAULT_ABI;
     return true;
-#if defined(XP_WIN32)
+#if defined(_WIN32)
   case nsIForeignLibrary::STDCALL:
     aResult = FFI_STDCALL;
     return true;
 #endif
   default:
     return false;
   }
 }
--- a/js/ctypes/tests/unit/test_jsctypes.js.in
+++ b/js/ctypes/tests/unit/test_jsctypes.js.in
@@ -197,17 +197,17 @@ function run_int64_tests(library) {
   var test_i64 = library.declare("test_i64", Types.DEFAULT, Types.INT64);
   // JS represents 64 bit ints as doubles, so we have to be careful how many
   // significant digits we use
   do_check_eq(test_i64(), 0x28590a1c921de000);
 
   var test_i64_i64 = library.declare("test_i64_i64", Types.DEFAULT, Types.INT64, Types.INT64);
   do_check_eq(test_i64_i64(5), 5);
   do_check_eq(test_i64_i64(0), 0);
-  do_check_eq(test_i64_i64(0x7ffffffffffffc00), 0x7ffffffffffffc00);
+  do_check_eq(test_i64_i64(0x7ffffffffffff000), 0x7ffffffffffff000);
   do_check_eq(test_i64_i64(-0x8000000000000000), -0x8000000000000000);
   do_check_eq(1/test_i64_i64(-0), 1/0);  // that is, test_i64_i64(-0) is +0
   do_check_eq(test_i64_i64(true), 1);
   do_check_eq(test_i64_i64(false), 0);
 
   // don't convert anything else to an int64
   var vals = [0x8000000000000000, -0x8000000000001000, Infinity, -Infinity, NaN,
               null, undefined, "", "0", {}, [], new Number(16),
@@ -217,17 +217,19 @@ function run_int64_tests(library) {
     do_check_throws(function () { test_i64_i64(vals[i]); }, TypeError);
 
   var test_i64_i64_sum = library.declare("test_i64_i64_sum", Types.DEFAULT, Types.INT64, Types.INT64, Types.INT64);
   do_check_eq(test_i64_i64_sum(5, 5), 10);
 
   // test the range of unsigned. (we can reuse the signed C function
   // here, since it's binary-compatible.)
   var test_ui64_ui64 = library.declare("test_i64_i64", Types.DEFAULT, Types.UINT64, Types.UINT64);
-  do_check_eq(test_ui64_ui64(0xfffffffffffff800), 0xfffffffffffff800);
+#ifndef XP_WIN
+  do_check_eq(test_ui64_ui64(0xffffffffffff000), 0xfffffffffffff000);
+#endif
   do_check_throws(function () { test_ui64_ui64(0x10000000000000000); }, TypeError);
   do_check_throws(function () { test_ui64_ui64(-1); }, TypeError);
 }
 
 function run_float_tests(library) {
   var test_f = library.declare("test_f", Types.DEFAULT, Types.FLOAT);
   do_check_eq(test_f(), 123456.5);
 
--- a/js/src/config/autoconf.mk.in
+++ b/js/src/config/autoconf.mk.in
@@ -324,16 +324,17 @@ MOZ_QUANTIFY	= @MOZ_QUANTIFY@
 MSMANIFEST_TOOL = @MSMANIFEST_TOOL@
 WIN32_REDIST_DIR = @WIN32_REDIST_DIR@
 MOZ_MEMORY_LDFLAGS = @MOZ_MEMORY_LDFLAGS@
 
 # Codesighs tools option, enables win32 mapfiles.
 MOZ_MAPINFO	= @MOZ_MAPINFO@
 
 WINCE		= @WINCE@
+WINCE_WINDOWS_MOBILE = @WINCE_WINDOWS_MOBILE@
 
 MACOS_SDK_DIR	= @MACOS_SDK_DIR@
 NEXT_ROOT	= @NEXT_ROOT@
 GCC_VERSION	= @GCC_VERSION@
 XCODEBUILD_VERSION= @XCODEBUILD_VERSION@
 HAS_XCODE_2_1	= @HAS_XCODE_2_1@
 UNIVERSAL_BINARY= @UNIVERSAL_BINARY@
 HAVE_DTRACE= @HAVE_DTRACE@
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -2157,25 +2157,16 @@ echo-dirs:
 	@echo $(DIRS)
 
 echo-module:
 	@echo $(MODULE)
 
 echo-requires:
 	@echo $(REQUIRES)
 
-echo-requires-recursive::
-ifdef _REPORT_ALL_DIRS
-	@echo $(subst $(topsrcdir)/,,$(srcdir)): $(MODULE): $(REQUIRES)
-else
-	@$(if $(REQUIRES),echo $(subst $(topsrcdir)/,,$(srcdir)): $(MODULE): $(REQUIRES))
-endif
-	$(LOOP_OVER_PARALLEL_DIRS)
-	$(LOOP_OVER_DIRS)
-
 echo-depth-path:
 	@$(topsrcdir)/build/unix/print-depth-path.sh
 
 echo-module-name:
 	@$(topsrcdir)/build/package/rpm/print-module-name.sh
 
 echo-module-filelist:
 	@$(topsrcdir)/build/package/rpm/print-module-filelist.sh
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -1848,16 +1848,29 @@ case "$target" in
     AC_DEFINE(NEW_H, <new>)
     AC_DEFINE(WIN32_LEAN_AND_MEAN)
 
     TARGET_MD_ARCH=win32
     _PLATFORM_DEFAULT_TOOLKIT='windows'
     BIN_SUFFIX='.exe'
     MOZ_ENABLE_POSTSCRIPT=
     MOZ_USER_DIR="Mozilla"
+
+    dnl Default to Windows Mobile components enabled
+    WINCE_WINDOWS_MOBILE=1
+
+    MOZ_ARG_DISABLE_BOOL(windows-mobile-components,
+    [  --disable-windows-mobile-components
+         Disable Windows Mobile specific components from CE build],
+    WINCE_WINDOWS_MOBILE=,
+    WINCE_WINDOWS_MOBILE=1)
+ 
+    if test "$WINCE_WINDOWS_MOBILE"; then
+        AC_DEFINE(WINCE_WINDOWS_MOBILE)
+    fi
 ;;
 
 *-symbian*)
 
     AC_DEFINE(XP_UNIX)
     AC_DEFINE(SYMBIAN)
     AC_DEFINE(__arm__)
     AC_DEFINE(__SYMBIAN32__)
@@ -4860,16 +4873,17 @@ AC_SUBST(USE_DEPENDENT_LIBS)
 AC_SUBST(MOZ_BUILD_ROOT)
 AC_SUBST(MOZ_OS2_TOOLS)
 AC_SUBST(MOZ_OS2_USE_DECLSPEC)
 
 AC_SUBST(MOZ_POST_DSO_LIB_COMMAND)
 AC_SUBST(MOZ_POST_PROGRAM_COMMAND)
 AC_SUBST(MOZ_TIMELINE)
 AC_SUBST(WINCE)
+AC_SUBST(WINCE_WINDOWS_MOBILE)
 
 AC_SUBST(MOZ_APP_NAME)
 AC_SUBST(MOZ_APP_DISPLAYNAME)
 AC_SUBST(MOZ_APP_VERSION)
 
 AC_SUBST(MOZ_PKG_SPECIAL)
 
 AC_SUBST(MOZILLA_OFFICIAL)
--- a/js/src/jstracer.cpp
+++ b/js/src/jstracer.cpp
@@ -6921,24 +6921,28 @@ js_arm_check_arch() {
         arch = 7;
     } __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) {
     }
     return arch;
 }
 
 static bool
 js_arm_check_vfp() {
+#ifdef WINCE_WINDOWS_MOBILE
+    return false;
+#else
     bool ret = false;
     __try {
         js_arm_try_vfp_op();
         ret = true;
     } __except(GetExceptionCode() == EXCEPTION_ILLEGAL_INSTRUCTION) {
         ret = false;
     }
     return ret;
+#endif
 }
 
 #define HAVE_ENABLE_DISABLE_DEBUGGER_EXCEPTIONS 1
 
 /* See "Suppressing Exception Notifications while Debugging", at
  * http://msdn.microsoft.com/en-us/library/ms924252.aspx
  */
 static void
--- a/js/src/xpconnect/shell/xpcshell.cpp
+++ b/js/src/xpconnect/shell/xpcshell.cpp
@@ -645,27 +645,126 @@ Clear(JSContext *cx, JSObject *obj, uint
         JS_ClearScope(cx, JSVAL_TO_OBJECT(argv[0]));
     } else {
         JS_ReportError(cx, "'clear' requires an object");
         return JS_FALSE;
     }
     return JS_TRUE;
 }
 
+/*
+ * JSContext option name to flag map. The option names are in alphabetical
+ * order for better reporting.
+ */
+static const struct {
+    const char  *name;
+    uint32      flag;
+} js_options[] = {
+    {"anonfunfix",      JSOPTION_ANONFUNFIX},
+    {"atline",          JSOPTION_ATLINE},
+    {"jit",             JSOPTION_JIT},
+    {"relimit",         JSOPTION_RELIMIT},
+    {"strict",          JSOPTION_STRICT},
+    {"werror",          JSOPTION_WERROR},
+    {"xml",             JSOPTION_XML},
+};
+
+static uint32
+MapContextOptionNameToFlag(JSContext* cx, const char* name)
+{
+    for (size_t i = 0; i != JS_ARRAY_LENGTH(js_options); ++i) {
+        if (strcmp(name, js_options[i].name) == 0)
+            return js_options[i].flag;
+    }
+
+    char* msg = JS_sprintf_append(NULL,
+                                  "unknown option name '%s'."
+                                  " The valid names are ", name);
+    for (size_t i = 0; i != JS_ARRAY_LENGTH(js_options); ++i) {
+        if (!msg)
+            break;
+        msg = JS_sprintf_append(msg, "%s%s", js_options[i].name,
+                                (i + 2 < JS_ARRAY_LENGTH(js_options)
+                                 ? ", "
+                                 : i + 2 == JS_ARRAY_LENGTH(js_options)
+                                 ? " and "
+                                 : "."));
+    }
+    if (!msg) {
+        JS_ReportOutOfMemory(cx);
+    } else {
+        JS_ReportError(cx, msg);
+        free(msg);
+    }
+    return 0;
+}
+
+static JSBool
+Options(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+    uint32 optset, flag;
+    JSString *str;
+    const char *opt;
+    char *names;
+    JSBool found;
+
+    optset = 0;
+    for (uintN i = 0; i < argc; i++) {
+        str = JS_ValueToString(cx, argv[i]);
+        if (!str)
+            return JS_FALSE;
+        argv[i] = STRING_TO_JSVAL(str);
+        opt = JS_GetStringBytes(str);
+        if (!opt)
+            return JS_FALSE;
+        flag = MapContextOptionNameToFlag(cx,  opt);
+        if (!flag)
+            return JS_FALSE;
+        optset |= flag;
+    }
+    optset = JS_ToggleOptions(cx, optset);
+
+    names = NULL;
+    found = JS_FALSE;
+    for (size_t i = 0; i != JS_ARRAY_LENGTH(js_options); i++) {
+        if (js_options[i].flag & optset) {
+            found = JS_TRUE;
+            names = JS_sprintf_append(names, "%s%s",
+                                      names ? "," : "", js_options[i].name);
+            if (!names)
+                break;
+        }
+    }
+    if (!found)
+        names = strdup("");
+    if (!names) {
+        JS_ReportOutOfMemory(cx);
+        return JS_FALSE;
+    }
+    str = JS_NewString(cx, names, strlen(names));
+    if (!str) {
+        free(names);
+        return JS_FALSE;
+    }
+    *rval = STRING_TO_JSVAL(str);
+    return JS_TRUE;
+}
+
 static JSFunctionSpec glob_functions[] = {
     {"print",           Print,          0,0,0},
     {"readline",        ReadLine,       1,0,0},
     {"load",            Load,           1,0,0},
     {"quit",            Quit,           0,0,0},
     {"version",         Version,        1,0,0},
     {"build",           BuildDate,      0,0,0},
     {"dumpXPC",         DumpXPC,        1,0,0},
     {"dump",            Dump,           1,0,0},
     {"gc",              GC,             0,0,0},
     {"clear",           Clear,          1,0,0},
+    {"options",         Options,        0,0,0},
 #ifdef DEBUG
     {"dumpHeap",        DumpHeap,       5,0,0},
 #endif
 #ifdef MOZ_SHARK
     {"startShark",      js_StartShark,      0,0,0},
     {"stopShark",       js_StopShark,       0,0,0},
     {"connectShark",    js_ConnectShark,    0,0,0},
     {"disconnectShark", js_DisconnectShark, 0,0,0},
@@ -951,17 +1050,17 @@ Process(JSContext *cx, JSObject *obj, co
     if (file != stdin)
         fclose(file);
 }
 
 static int
 usage(void)
 {
     fprintf(gErrFile, "%s\n", JS_GetImplementationVersion());
-    fprintf(gErrFile, "usage: xpcshell [-g gredir] [-PswWxCij] [-v version] [-f scriptfile] [-e script] [scriptfile] [scriptarg...]\n");
+    fprintf(gErrFile, "usage: xpcshell [-g gredir] [-PsSwWxCij] [-v version] [-f scriptfile] [-e script] [scriptfile] [scriptarg...]\n");
     return 2;
 }
 
 extern JSClass global_class;
 
 static int
 ProcessArgs(JSContext *cx, JSObject *obj, char **argv, int argc)
 {
@@ -1038,16 +1137,18 @@ ProcessArgs(JSContext *cx, JSObject *obj
             JS_SetVersion(cx, JSVersion(atoi(argv[i])));
             break;
         case 'W':
             reportWarnings = JS_FALSE;
             break;
         case 'w':
             reportWarnings = JS_TRUE;
             break;
+        case 'S':
+            JS_ToggleOptions(cx, JSOPTION_WERROR);
         case 's':
             JS_ToggleOptions(cx, JSOPTION_STRICT);
             break;
         case 'x':
             JS_ToggleOptions(cx, JSOPTION_XML);
             break;
         case 'P':
             if (JS_GET_CLASS(cx, JS_GetPrototype(cx, obj)) != &global_class) {
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -4433,19 +4433,19 @@ PresShell::NotifyInvalidateForScrolledVi
 }
 
 NS_IMETHODIMP_(void)
 PresShell::DispatchSynthMouseMove(nsGUIEvent *aEvent,
                                   PRBool aFlushOnHoverChange)
 {
   PRUint32 hoverGenerationBefore = mFrameConstructor->GetHoverGeneration();
   nsEventStatus status;
-  nsIView* rootView;
-  mViewManager->GetRootView(rootView);
-  mViewManager->DispatchEvent(aEvent, rootView, &status);
+  nsIView* targetView;
+  targetView = nsIView::GetViewFor(aEvent->widget);
+  mViewManager->DispatchEvent(aEvent, targetView, &status);
   if (aFlushOnHoverChange &&
       hoverGenerationBefore != mFrameConstructor->GetHoverGeneration()) {
     // Flush so that the resulting reflow happens now so that our caller
     // can suppress any synthesized mouse moves caused by that reflow.
     FlushPendingNotifications(Flush_Layout);
   }
 }
 
@@ -5995,16 +5995,19 @@ PresShell::HandleEvent(nsIView         *
 #ifdef ACCESSIBILITY
   if (aEvent->eventStructType == NS_ACCESSIBLE_EVENT) {
     // Accessibility events come through OS requests and not from scripts,
     // so it is safe to handle here
     return HandleEventInternal(aEvent, aView, aEventStatus);
   }
 #endif
 
+  nsIContent* capturingContent =
+    NS_IS_MOUSE_EVENT(aEvent) ? GetCapturingContent() : nsnull;
+
   nsCOMPtr<nsIDocument> retargetEventDoc;
   // key and IME events must be targeted at the presshell for the focused frame
   if (!sDontRetargetEvents) {
     if (NS_IsEventTargetedAtFocusedWindow(aEvent)) {
       nsIFocusManager* fm = nsFocusManager::GetFocusManager();
       if (!fm)
          return NS_ERROR_FAILURE;
  
@@ -6015,20 +6018,20 @@ PresShell::HandleEvent(nsIView         *
       // at so just return
       nsCOMPtr<nsPIDOMWindow> piWindow = do_QueryInterface(window);
       if (!piWindow)
         return NS_OK;
 
       retargetEventDoc = do_QueryInterface(piWindow->GetExtantDocument());
       if (!retargetEventDoc)
         return NS_OK;
-    } else if (NS_IS_MOUSE_EVENT(aEvent) && GetCapturingContent()) {
+    } else if (capturingContent) {
       // if the mouse is being captured then retarget the mouse event at the
       // document that is being captured.
-      retargetEventDoc = gCaptureInfo.mContent->GetCurrentDoc();
+      retargetEventDoc = capturingContent->GetCurrentDoc();
     }
 
     if (retargetEventDoc) {
       nsIPresShell* presShell = retargetEventDoc->GetPrimaryShell();
       if (!presShell)
         return NS_OK;
 
       if (presShell != this) {
@@ -6088,53 +6091,17 @@ PresShell::HandleEvent(nsIView         *
       }
     }
     if (event && !mDelayedEvents.AppendElement(event)) {
       delete event;
     }
     return NS_OK;
   }
 
-  PRBool getDescendantPoint = PR_TRUE;
   nsIFrame* frame = static_cast<nsIFrame*>(aView->GetClientData());
-
-  if (NS_IS_MOUSE_EVENT(aEvent) && GetCapturingContent()) {
-    // if a node is capturing the mouse, get the frame for the capturing
-    // content and use that instead. However, if the content has no parent,
-    // such as the root frame, get the parent canvas frame instead. This
-    // ensures that positioned frames are included when hit-testing. Note
-    // that a check was already done above to ensure that capturingContent
-    // is in this presshell.
-    nsIContent* capturingContent = gCaptureInfo.mContent;
-    frame = GetPrimaryFrameFor(capturingContent);
-    if (frame) {
-      getDescendantPoint = !gCaptureInfo.mRetargetToElement;
-      if (!capturingContent->GetParent()) {
-        frame = frame->GetParent();
-      }
-      else {
-        // special case for <select> as it needs to capture on the dropdown list.
-        if (capturingContent->Tag() == nsGkAtoms::select &&
-            capturingContent->IsNodeOfType(nsINode::eHTML)) {
-          nsIFrame* childframe = frame->GetChildList(nsGkAtoms::selectPopupList).FirstChild();
-          if (childframe) {
-            frame = childframe;
-          }
-        }
-
-        // if the frame is a scrolling frame, get the inner scrolled frame instead.
-        nsIScrollableFrame* scrollFrame = do_QueryFrame(frame);
-        if (scrollFrame) {
-          frame = scrollFrame->GetScrolledFrame();
-        }
-      }
-      aView = frame->GetClosestView();
-    }
-  }
-
   PRBool dispatchUsingCoordinates = NS_IsEventUsingCoordinates(aEvent);
 
   // if this event has no frame, we need to retarget it at a parent
   // view that has a frame.
   if (!frame &&
       (dispatchUsingCoordinates || NS_IS_KEY_EVENT(aEvent) ||
        NS_IS_IME_EVENT(aEvent))) {
     nsIView* targetView = aView;
@@ -6177,31 +6144,69 @@ PresShell::HandleEvent(nsIView         *
             frame = popup;
             break;
           }
         }
       }
 #endif
     }
 
+    PRBool captureRetarget = PR_FALSE;
+    if (capturingContent) {
+      captureRetarget = gCaptureInfo.mRetargetToElement;
+      // special case for <select> as it needs to capture on the dropdown list,
+      // so get the frame for the dropdown list instead.
+      if (!captureRetarget && capturingContent->Tag() == nsGkAtoms::select &&
+          capturingContent->IsNodeOfType(nsINode::eHTML)) {
+        nsIFrame* selectFrame = GetPrimaryFrameFor(capturingContent);
+        if (selectFrame) {
+          nsIFrame* childframe = selectFrame->GetChildList(nsGkAtoms::selectPopupList).FirstChild();
+          if (childframe) {
+            frame = childframe;
+          }
+        }
+      }
+    }
+
+    // Get the frame at the event point. However, don't do this if we're
+    // capturing and retargeting the event because the captured frame will
+    // be used instead below.
     nsIFrame* targetFrame = nsnull;
-    if (getDescendantPoint) {
+    if (!captureRetarget) {
       nsPoint eventPoint
           = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, frame);
       {
         nsAutoDisableGetUsedXAssertions disableAssert;
         PRBool ignoreRootScrollFrame = PR_FALSE;
         if (aEvent->eventStructType == NS_MOUSE_EVENT) {
           ignoreRootScrollFrame = static_cast<nsMouseEvent*>(aEvent)->ignoreRootScrollFrame;
         }
         targetFrame = nsLayoutUtils::GetFrameForPoint(frame, eventPoint,
                                                       PR_FALSE, ignoreRootScrollFrame);
       }
     }
 
+    // if a node is capturing the mouse, check if the event needs to be
+    // retargeted at the capturing content instead. This will be the case when
+    // capture retargeting is being used, no frame was found or the frame's
+    // content is not a descendant of the capturing content.
+    if (capturingContent &&
+        (gCaptureInfo.mRetargetToElement ||
+         !targetFrame || !targetFrame->GetContent() ||
+         !nsContentUtils::ContentIsCrossDocDescendantOf(targetFrame->GetContent(),
+                                                        capturingContent))) {
+      // A check was already done above to ensure that capturingContent is
+      // in this presshell, so GetPrimaryFrameFor can just be called directly.
+      nsIFrame* capturingFrame = GetPrimaryFrameFor(capturingContent);
+      if (capturingFrame) {
+        targetFrame = capturingFrame;
+        aView = targetFrame->GetClosestView();
+      }
+    }
+
     if (targetFrame) {
       PresShell* shell =
           static_cast<PresShell*>(targetFrame->PresContext()->PresShell());
       if (shell != this) {
         // Handle the event in the correct shell.
         // Prevent deletion until we're done with event handling (bug 336582).
         nsCOMPtr<nsIPresShell> kungFuDeathGrip(shell);
         nsIView* subshellRootView;
--- a/layout/base/nsStyleConsts.h
+++ b/layout/base/nsStyleConsts.h
@@ -653,16 +653,19 @@
 #define NS_STYLE_VERTICAL_ALIGN_MIDDLE_WITH_BASELINE 19
 
 // See nsStyleDisplay
 #define NS_STYLE_VISIBILITY_HIDDEN              0
 #define NS_STYLE_VISIBILITY_VISIBLE             1
 #define NS_STYLE_VISIBILITY_COLLAPSE            2
 
 // See nsStyleText
+#define NS_STYLE_TABSIZE_INITIAL                8
+
+// See nsStyleText
 #define NS_STYLE_WHITESPACE_NORMAL              0
 #define NS_STYLE_WHITESPACE_PRE                 1
 #define NS_STYLE_WHITESPACE_NOWRAP              2
 #define NS_STYLE_WHITESPACE_PRE_WRAP            3
 #define NS_STYLE_WHITESPACE_PRE_LINE            4
 
 // See nsStyleText
 #define NS_STYLE_WORDWRAP_NORMAL                0
--- a/layout/generic/nsFrameSetFrame.cpp
+++ b/layout/generic/nsFrameSetFrame.cpp
@@ -1453,16 +1453,23 @@ nsHTMLFramesetFrame::StartMouseDrag(nsPr
   gDragInProgress = PR_TRUE;
 }
   
 
 void
 nsHTMLFramesetFrame::MouseDrag(nsPresContext* aPresContext, 
                                nsGUIEvent*     aEvent)
 {
+  // if the capture ended, reset the drag state
+  if (nsIPresShell::GetCapturingContent() != GetContent()) {
+    mDragger = nsnull;
+    gDragInProgress = PR_FALSE;
+    return;
+  }
+
   PRInt32 change; // measured positive from left-to-right or top-to-bottom
   nsWeakFrame weakFrame(this);
   if (mDragger->mVertical) {
     change = aPresContext->DevPixelsToAppUnits(aEvent->refPoint.x - mFirstDragPoint.x);
     if (change > mNextNeighborOrigSize - mMinDrag) {
       change = mNextNeighborOrigSize - mMinDrag;
     } else if (change <= mMinDrag - mPrevNeighborOrigSize) {
       change = mMinDrag - mPrevNeighborOrigSize;
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -3355,17 +3355,17 @@ static void InitializeEventRecord(EventR
 {
   memset(event, 0, sizeof(EventRecord));
   if (aMousePosition) {
     event->where = *aMousePosition;
   } else {
     ::GetGlobalMouse(&event->where);
   }
   event->when = ::TickCount();
-  event->modifiers = ::GetCurrentEventKeyModifiers();
+  event->modifiers = ::GetCurrentKeyModifiers();
 }
 #endif
 
 static void InitializeNPCocoaEvent(NPCocoaEvent* event)
 {
   memset(event, 0, sizeof(NPCocoaEvent));
 }
 
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -2429,16 +2429,20 @@ PropertyProvider::GetSpacingInternal(PRU
           FindClusterEnd(mTextRun, run.GetOriginalOffset() + run.GetRunLength(),
                          &iter);
           aSpacing[iter.GetSkippedOffset() - aStart].mAfter += mWordSpacing;
         }
       }
     }
   }
 
+  // Ignore tab spacing rather than computing it, if the tab size is 0
+  if (!aIgnoreTabs)
+    aIgnoreTabs = mFrame->GetStyleText()->mTabSize == 0;
+
   // Now add tab spacing, if there is any
   if (!aIgnoreTabs) {
     gfxFloat* tabs = GetTabWidths(aStart, aLength);
     if (tabs) {
       for (index = 0; index < aLength; ++index) {
         aSpacing[index].mAfter += tabs[index];
       }
     }
@@ -2480,34 +2484,37 @@ PropertyProvider::GetSpacingInternal(PRU
 
 static void TabWidthDestructor(void* aObject, nsIAtom* aProp, void* aValue,
                                void* aData)
 {
   delete static_cast<nsTArray<gfxFloat>*>(aValue);
 }
 
 static gfxFloat
-ComputeTabWidthAppUnits(nsIFrame* aLineContainer, gfxTextRun* aTextRun)
-{
+ComputeTabWidthAppUnits(nsIFrame* aFrame, gfxTextRun* aTextRun)
+{
+  // Get the number of spaces from CSS -moz-tab-size
+  const nsStyleText* textStyle = aFrame->GetStyleText();
+  
   // Round the space width when converting to appunits the same way
   // textruns do
   gfxFloat spaceWidthAppUnits =
     NS_roundf(GetFirstFontMetrics(
-                GetFontGroupForFrame(aLineContainer)).spaceWidth *
+                GetFontGroupForFrame(aFrame)).spaceWidth *
               aTextRun->GetAppUnitsPerDevUnit());
-  return 8*spaceWidthAppUnits;
+  return textStyle->mTabSize * spaceWidthAppUnits;
 }
 
 // aX and the result are in whole appunits.
 static gfxFloat
-AdvanceToNextTab(gfxFloat aX, nsIFrame* aLineContainer,
+AdvanceToNextTab(gfxFloat aX, nsIFrame* aFrame,
                  gfxTextRun* aTextRun, gfxFloat* aCachedTabWidth)
 {
   if (*aCachedTabWidth < 0) {
-    *aCachedTabWidth = ComputeTabWidthAppUnits(aLineContainer, aTextRun);
+    *aCachedTabWidth = ComputeTabWidthAppUnits(aFrame, aTextRun);
   }
 
   // Advance aX to the next multiple of *aCachedTabWidth. We must advance
   // by at least 1 appunit.
   // XXX should we make this 1 CSS pixel?
   return NS_ceil((aX + 1)/(*aCachedTabWidth))*(*aCachedTabWidth);
 }
 
@@ -2565,17 +2572,17 @@ PropertyProvider::GetTabWidths(PRUint32 
                  !mTextRun->IsClusterStart(clusterEnd)) {
             ++clusterEnd;
           }
           mOffsetFromBlockOriginForTabs +=
             mTextRun->GetAdvanceWidth(i, clusterEnd - i, nsnull);
         }
       } else {
         double nextTab = AdvanceToNextTab(mOffsetFromBlockOriginForTabs,
-                mLineContainer, mTextRun, &tabWidth);
+                mFrame, mTextRun, &tabWidth);
         (*mTabWidths)[i - startOffset] = nextTab - mOffsetFromBlockOriginForTabs;
         mOffsetFromBlockOriginForTabs = nextTab;
       }
 
       mOffsetFromBlockOriginForTabs += spacing.mAfter;
     }
   }
 
@@ -5685,17 +5692,17 @@ nsTextFrame::AddInlineMinWidthForFlow(ns
       }
     }
 
     if (preformattedTab) {
       PropertyProvider::Spacing spacing;
       provider.GetSpacing(i, 1, &spacing);
       aData->currentLine += nscoord(spacing.mBefore);
       gfxFloat afterTab =
-        AdvanceToNextTab(aData->currentLine, FindLineContainer(this),
+        AdvanceToNextTab(aData->currentLine, this,
                          mTextRun, &tabWidth);
       aData->currentLine = nscoord(afterTab + spacing.mAfter);
       wordStart = i + 1;
     } else if (i < flowEndInTextRun ||
         (i == mTextRun->GetLength() &&
          (mTextRun->GetFlags() & nsTextFrameUtils::TEXT_HAS_TRAILING_BREAK))) {
       if (preformattedNewline) {
         aData->ForceBreak(aRenderingContext);
@@ -5815,17 +5822,17 @@ nsTextFrame::AddInlinePrefWidthForFlow(n
       }
     }
 
     if (preformattedTab) {
       PropertyProvider::Spacing spacing;
       provider.GetSpacing(i, 1, &spacing);
       aData->currentLine += nscoord(spacing.mBefore);
       gfxFloat afterTab =
-        AdvanceToNextTab(aData->currentLine, FindLineContainer(this),
+        AdvanceToNextTab(aData->currentLine, this,
                          mTextRun, &tabWidth);
       aData->currentLine = nscoord(afterTab + spacing.mAfter);
       lineStart = i + 1;
     } else if (preformattedNewline) {
       aData->ForceBreak(aRenderingContext);
       lineStart = i;
     }
   }
--- a/layout/reftests/bidi/413928-1-ref.html
+++ b/layout/reftests/bidi/413928-1-ref.html
@@ -1,16 +1,16 @@
 <!DOCTYPE html>
 <html>
  <head>
   <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
   <title>Bug 413928</title>
   <style type="text/css">
 .li {
-  line-height: 24px;
+  line-height: 2em;
 }
 .list-number-he {
   direction: rtl;
   unicode-bidi: bidi-override;
 }
   </style>
  </head>
  <body>
--- a/layout/reftests/bidi/413928-1.html
+++ b/layout/reftests/bidi/413928-1.html
@@ -7,17 +7,17 @@
  ol {
    list-style-type: hebrew;
    list-style-position: inside;
    padding: 0;
    margin: 0;
 }
 
  li {
-   line-height: 24px;
+   line-height: 2em;
 }
   </style>
  </head>
  <body>
   <ol start="-3">
    <li></li>
    <li></li>
    <li></li>
--- a/layout/reftests/bidi/413928-2-ref.html
+++ b/layout/reftests/bidi/413928-2-ref.html
@@ -1,16 +1,16 @@
 <!DOCTYPE html>
 <html>
  <head>
   <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
   <title>Bug 413928</title>
   <style type="text/css">
 .li {
-  line-height: 24px;
+  line-height: 2em;
 }
 .list-number-he {
   direction: rtl;
   unicode-bidi: bidi-override;
 }
   </style>
  </head>
  <body dir="rtl">
--- a/layout/reftests/bidi/413928-2.html
+++ b/layout/reftests/bidi/413928-2.html
@@ -7,17 +7,17 @@
  ol {
    list-style-type: hebrew;
    list-style-position: inside;
    padding: 0;
    margin: 0;
 }
 
  li {
-   line-height: 24px;
+   line-height: 2em;
 }
   </style>
  </head>
  <body dir="rtl">
   <ol start="-3">
    <li></li>
    <li></li>
    <li></li>
--- a/layout/reftests/box-shadow/boxshadow-inner-basic-ref.html
+++ b/layout/reftests/box-shadow/boxshadow-inner-basic-ref.html
@@ -1,1 +1,12 @@
-<div style="background-color: grey; width: 300px; height: 300px; -moz-border-radius: 5px; position: absolute; top: 20px; left: 20px;">inset</div><div style="-moz-border-radius: 5px; width: 300px; height: 300px; background-color: white; position: absolute; top: 40px; left: 40px;">&nbsp;</div>
+<body style="font-size: 16px;">
+<div style="background-color: grey;
+  width: 15em; height: 15em;
+  -moz-border-radius: 0.5em;
+  position: absolute;
+  top: 1em; left: 1em;">inset</div>
+<div style="-moz-border-radius: 0.5em;
+  width: 15em; height: 15em;
+  background-color: white;
+  position: absolute;
+  top: 3em; left: 3em;">&nbsp;</div>
+</body>
--- a/layout/reftests/box-shadow/boxshadow-inner-basic.html
+++ b/layout/reftests/box-shadow/boxshadow-inner-basic.html
@@ -1,1 +1,7 @@
-<div style="-moz-box-shadow: 20px 20px grey inset; width: 300px; height: 300px; -moz-border-radius: 5px; position: absolute; top: 20px; left: 20px;">inset</div>
+<body style="font-size: 16px;">
+<div style="-moz-box-shadow: 2em 2em grey inset;
+  width: 15em; height: 15em;
+  -moz-border-radius: .5em;
+  position: absolute;
+  top: 1em; left: 1em;">inset</div>
+</body>
--- a/layout/reftests/bugs/134706-5-ref.html
+++ b/layout/reftests/bugs/134706-5-ref.html
@@ -1,16 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US">
 <head>
 	<title>Testcase, bug 134706</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 	<meta http-equiv="Content-Style-Type" content="text/css">
 	<style type="text/css">
 
+	body { font-size: 10px; }
+
 	</style>
 </head>
 <body>
 
 <div style="width: 300px; height: 40px;background: aqua">
   <div style="float:left; background:blue; width: 200px; height: 20px"></div>
   <div style="float:left; clear: left; background: yellow; width: 150px; height: 20px">50%</div>
 </div>
--- a/layout/reftests/bugs/134706-5.html
+++ b/layout/reftests/bugs/134706-5.html
@@ -1,16 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US">
 <head>
 	<title>Testcase, bug 134706</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 	<meta http-equiv="Content-Style-Type" content="text/css">
 	<style type="text/css">
 
+	body { font-size: 10px; }
+
 	table { margin: 0; border-spacing: 0; }
 	td, th { padding: 0; vertical-align: top; }
 
 	</style>
 </head>
 <body>
 
 <table width="300" style="background: aqua"><tr><td>
--- a/layout/reftests/bugs/134706-6-ref.html
+++ b/layout/reftests/bugs/134706-6-ref.html
@@ -1,16 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US">
 <head>
 	<title>Testcase, bug 134706</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 	<meta http-equiv="Content-Style-Type" content="text/css">
 	<style type="text/css">
 
+	body { font-size: 16px; }
+
 	table { margin: 0; border-spacing: 0; }
 	caption, td, th { padding: 0; vertical-align: top; text-align: left; }
 
 	.capref { background: yellow; }
 	.tabref { background: purple; }
 
 	</style>
 </head>
--- a/layout/reftests/bugs/134706-6.html
+++ b/layout/reftests/bugs/134706-6.html
@@ -1,16 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US">
 <head>
 	<title>Testcase, bug 134706</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 	<meta http-equiv="Content-Style-Type" content="text/css">
 	<style type="text/css">
 
+	body { font-size: 16px; }
+
 	table { margin: 0; border-spacing: 0; }
 	caption, td, th { padding: 0; vertical-align: top; text-align: left; }
 
 	table table caption { background: yellow; }
 	table table { background: purple; }
 
 	</style>
 </head>
--- a/layout/reftests/bugs/134706-6b-ref.html
+++ b/layout/reftests/bugs/134706-6b-ref.html
@@ -1,16 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US">
 <head>
 	<title>Testcase, bug 134706</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 	<meta http-equiv="Content-Style-Type" content="text/css">
 	<style type="text/css">
 
+	body { font-size: 16px; }
+
 	table { margin: 0; border-spacing: 0; }
 	caption, td, th { padding: 0; vertical-align: top; text-align: left; }
 
 	.capref { background: yellow; }
 	.tabref { background: purple; }
 
 	</style>
 </head>
--- a/layout/reftests/bugs/134706-6b.html
+++ b/layout/reftests/bugs/134706-6b.html
@@ -1,16 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US">
 <head>
 	<title>Testcase, bug 134706</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 	<meta http-equiv="Content-Style-Type" content="text/css">
 	<style type="text/css">
 
+	body { font-size: 16px; }
+
 	table { margin: 0; border-spacing: 0; }
 	caption, td, th { padding: 0; vertical-align: top; text-align: left; }
 
 	table table caption { background: yellow; }
 	table table { background: purple; }
 
 	</style>
 </head>
--- a/layout/reftests/bugs/134706-6c-ref.html
+++ b/layout/reftests/bugs/134706-6c-ref.html
@@ -1,16 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US">
 <head>
 	<title>Testcase, bug 134706</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 	<meta http-equiv="Content-Style-Type" content="text/css">
 	<style type="text/css">
 
+	body { font-size: 16px; }
+
 	table { margin: 0; border-spacing: 0; }
 	caption, td, th { padding: 0; vertical-align: top; text-align: left; }
 
 	.capref { background: yellow; }
 	.tabref { background: purple; }
 
 	</style>
 </head>
--- a/layout/reftests/bugs/134706-6c.html
+++ b/layout/reftests/bugs/134706-6c.html
@@ -1,16 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US">
 <head>
 	<title>Testcase, bug 134706</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 	<meta http-equiv="Content-Style-Type" content="text/css">
 	<style type="text/css">
 
+	body { font-size: 16px; }
+
 	table { margin: 0; border-spacing: 0; }
 	caption, td, th { padding: 0; vertical-align: top; text-align: left; }
 
 	table table caption { background: yellow; }
 	table table { background: purple; }
 
 	</style>
 </head>
--- a/layout/reftests/bugs/262151-1-ref.html
+++ b/layout/reftests/bugs/262151-1-ref.html
@@ -1,9 +1,9 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
 <head>
   <title>Bug 262151 Reference</title>
 </head>
-<body style="text-align: right">
+<body style="text-align: right; font-size: 16px;">
 <span>This text should all </span><span>be on one line.</span>
 </body>
 </html>
--- a/layout/reftests/bugs/262151-1.html
+++ b/layout/reftests/bugs/262151-1.html
@@ -1,15 +1,15 @@
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
 <html>
 <head>
   <title>Bug 262151</title>
   <style type="text/css">table {border-collapse: collapse} td {padding: 0px}</style>
 </head>
-<body>
+<body style="font-size: 16px;">
 <table width="100%">
   <tr>
     <td><div style="width: 20em"></div></td>
     <td>
       <table align="right">
         <tr><td>This text should all <script type="text/javascript">var v = document.body.offsetHeight;</script>be on one line.</td></tr>
       </table>
     </td>
--- a/layout/reftests/bugs/322436-1-ref.html
+++ b/layout/reftests/bugs/322436-1-ref.html
@@ -1,12 +1,16 @@
 <html>
 
 <head>
 
 </head>
 
 <body>
 There should be floating text here!  Look at the source!
-This text should show up
+This&nbsp;text&nbsp;should&nbsp;show&nbsp;up
+<!-- using non-breaking spaces here because the box in the testcase
+     will always wrap (or not) as a complete unit, depending on
+     font size and window width -->
+
 </body>
 
 </html>
--- a/layout/reftests/bugs/322436-1.html
+++ b/layout/reftests/bugs/322436-1.html
@@ -1,12 +1,14 @@
 <html>
 
 <head>
 
 </head>
 
 <body>
 There should be floating text here!  Look at the source!
-<div style="display: -moz-box;"><div style="float: left;">This text should show up</div></div>
+<div style="display: -moz-box;"><div style="float: left;">This&nbsp;text&nbsp;should&nbsp;show&nbsp;up</div></div>
+<!-- using non-breaking spaces here to match the reference -->
+
 </body>
 
 </html>
--- a/layout/reftests/bugs/388980-1-ref.html
+++ b/layout/reftests/bugs/388980-1-ref.html
@@ -1,14 +1,14 @@
 <html>
 <head>
 <title>Reftest for bug 388980</title></html>
 <script type="text/javascript">
 
-var text = '<html><head></head><body>'
+var text = '<html><head></head><body style="font-size:16px;">'
 	+ '<p style="background-color:red;">This paragraph should be red</p>'
 	+ '<p style="background-color:blue;">This paragraph should be blue</p>'
 	+ '<p>This paragraph should not be colored</p>'
 	+ '</body></html>';
 
 function initIFrame() {
 	var doc = document.getElementById('theIFrame').contentDocument;
 	doc.designMode = 'on';
--- a/layout/reftests/bugs/388980-1.html
+++ b/layout/reftests/bugs/388980-1.html
@@ -1,14 +1,14 @@
 <html>
 <head>
 <title>Reftest for bug 388980</title></html>
 <script type="text/javascript">
 
-var text = '<html><head></head><body>'
+var text = '<html><head></head><body style="font-size:16px;">'
 	+ '<p id="redpar">This paragraph should be red</p>'
 	+ '<p id="bluepar">This paragraph should be blue</p>'
 	+ '<p id="normalpar">This paragraph should not be colored</p>'
 	+'</body></html>';
 
 
 function colorPar(par, color) {
 	var doc = document.getElementById('theIFrame').contentDocument;
--- a/layout/reftests/bugs/404149-1-ref.xul
+++ b/layout/reftests/bugs/404149-1-ref.xul
@@ -4,15 +4,16 @@
 label {
   text-align: right;
   width: 60px;
   border: 1px solid black;
   height: 20px;
   padding: 0 2px 0;
   margin: 0 10px 0 -58px;
   font-family: Scheherazade;
+  font-size: 16px;
 }
 " ?>
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <box width="100">
     <label value="ف" accesskey="ف" />
   </box>
 </window>
--- a/layout/reftests/bugs/404149-1.xul
+++ b/layout/reftests/bugs/404149-1.xul
@@ -4,15 +4,16 @@
 label {
   text-align: right;
   width: 60px;
   border: 1px solid black;
   height: 20px;
   padding: 0 2px 0;
   margin: 0 10px 0 -58px;
   font-family: Scheherazade;
+  font-size: 16px;
 }
 " ?>
 <window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
   <box width="100">
     <label value="فایرفاکس" accesskey="ف" />
   </box>
 </window>
--- a/layout/reftests/bugs/410621-1-ref.html
+++ b/layout/reftests/bugs/410621-1-ref.html
@@ -6,17 +6,17 @@ td {
  border: 4px solid green;
 }
 table {
  border-collapse: collapse;
 }
 </style>
 </head>
 <body>
-<div style="height: 300px;">
+<div style="height: 20em;">
  <table align="left">
   <tr>
    <td>Entry 1</td>
    <td>Value 1</td>
   </tr>
   <tr>
    <td>Entry 2</td>
    <td>Value 2</td>
--- a/layout/reftests/bugs/410621-1.html
+++ b/layout/reftests/bugs/410621-1.html
@@ -6,17 +6,17 @@ td {
  border: 4px solid green;
 }
 table {
  border-collapse: collapse;
 }
 </style>
 </head>
 <body>
-<div style="overflow: auto; height: 300px;">
+<div style="overflow: auto; height: 20em;">
  <table align="left">
   <tr>
    <td>Entry 1</td>
    <td>Value 1</td>
   </tr>
   <tr>
    <td>Entry 2</td>
    <td>Value 2</td>
--- a/layout/reftests/bugs/413286-1a.html
+++ b/layout/reftests/bugs/413286-1a.html
@@ -1,12 +1,12 @@
 <html>
   <head>
     <style>
-      table     { width: 400px; height: 25px; }
+      table     { width: 400px; height: 25px; font-size: 10px; }
       td.blue   { background: lightblue;  color: rgba(0,0,0,0) }
       td.green  { background: lightgreen; color: rgba(0,0,0,0) }
       col.a     { width: 100px; }
       col.c     { width: 25%;   }
     </style>
   </head>
   <body>
     With colspan:
--- a/layout/reftests/bugs/413286-1b.html
+++ b/layout/reftests/bugs/413286-1b.html
@@ -1,12 +1,12 @@
 <html>
   <head>
     <style>
-      table     { width: 400px; height: 25px; }
+      table     { width: 400px; height: 25px; font-size: 10px; }
       td.blue   { background: lightblue;  color: rgba(0,0,0,0) }
       td.green  { background: lightgreen; color: rgba(0,0,0,0) }
       col.a     { width: 25%;   }
       col.c     { width: 25%;   }
     </style>
   </head>
   <body>
     With colspan:
--- a/layout/reftests/bugs/413286-1c.html
+++ b/layout/reftests/bugs/413286-1c.html
@@ -1,12 +1,12 @@
 <html>
   <head>
     <style>
-      table     { width: 400px; height: 25px; }
+      table     { width: 400px; height: 25px; font-size: 10px; }
       td.blue   { background: lightblue;  color: rgba(0,0,0,0) }
       td.green  { background: lightgreen; color: rgba(0,0,0,0) }
       col.a     { width: 100px; }
       col.c     { width: 100px; }
     </style>
   </head>
   <body>
     With colspan:
--- a/layout/reftests/bugs/417676-ref.html
+++ b/layout/reftests/bugs/417676-ref.html
@@ -1,18 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
 <html class="reftest-print">
 <title>Fixed Positioning Test</title>
 <style type="text/css">
   html, body { margin: 0; padding: 0; }
 </style>
 
-<div style="width: 3in; border: solid;">
+<div style="width: 3in; border: solid; font-size: 16px;">
 This box must be repeated at this same position on the first, second, and third pages.
 </div>
 
-<div style="page-break-before: always; width: 3in; border: solid;">
+<div style="page-break-before: always; width: 3in; border: solid; font-size: 16px;">
 This box must be repeated at this same position on the first, second, and third pages.
 </div>
 
-<div style="page-break-before: always; width: 3in; border: solid;">
+<div style="page-break-before: always; width: 3in; border: solid; font-size: 16px;">
 This box must be repeated at this same position on the first, second, and third pages.
 </div>
--- a/layout/reftests/bugs/417676.html
+++ b/layout/reftests/bugs/417676.html
@@ -1,9 +1,9 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
 <html class="reftest-print">
 <title>Fixed Positioning Test</title>
 
-<div style="position: fixed; left: 0; top: 0; width: 3in; border: solid;">
+<div style="position: fixed; left: 0; top: 0; width: 3in; border: solid; font-size: 16px;">
 This box must be repeated at this same position on the first, second, and third pages.
 </div>
 
 <p style="width: 0; height: 5in;">
\ No newline at end of file
--- a/layout/reftests/bugs/423599-1.html
+++ b/layout/reftests/bugs/423599-1.html
@@ -1,12 +1,14 @@
 <html>
   <head><style>
     select          { visibility: hidden; }
     select.unthemed { -moz-appearance: none; margin: 2px 0 2px 0}
   </style></head>
   <body>
     <div style="background: lightblue">
-      <select class="unthemed"></select>
-      <select></select>
+      <select class="unthemed"></select><!--
+        No space here to make this more robust
+        in the face of different default fonts 
+      --><select></select>
     </div>
   </body>
 </html>
--- a/layout/reftests/bugs/424236-9-ref.html
+++ b/layout/reftests/bugs/424236-9-ref.html
@@ -2,16 +2,17 @@
 	"http://www.w3.org/TR/html4/strict.dtd">
 <html lang="en-US">
 <head>
 	<title>reftest, bug 424236</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 	<meta http-equiv="Content-Style-Type" content="text/css">
 	<style type="text/css">
 
+	body { font-size: 16px; }
 	* { -moz-outline-offset: -1px; outline-offset: -1px; }
 	body > span { outline: 1px dotted black; }
 	/* can't compare to border combined with negative margin because of
 	   margin collapsing */
 	body > div { display: block; outline: 1px dotted black; width: -moz-max-content; width: max-content; }
 
 	</style>
 </head>
--- a/layout/reftests/bugs/430813-3-ref.html
+++ b/layout/reftests/bugs/430813-3-ref.html
@@ -2,13 +2,13 @@
 <html>
 <head>
 	<title>Testcase, bug 430813</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 </head>
 <body>
 <div style="margin-bottom: 1px">text</div>
 <div style="float:left;width:90px;height:300px"></div>
-<div style="margin-left:90px">
+<div style="margin-left:90px; font-size: 16px;">
 <span style="padding:0.2em;">This text should be near the top of the page, not pushed below the float.</span>
 </div>
 </body>
 </html>
--- a/layout/reftests/bugs/430813-3.html
+++ b/layout/reftests/bugs/430813-3.html
@@ -2,13 +2,14 @@
 <html>
 <head>
 	<title>Testcase, bug 430813</title>
 	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 </head>
 <body>
 <div style="margin-bottom: 1px">text</div>
 <div style="float:left;width:90px;height:300px"></div>
-<div style="overflow:hidden">
+<div style="overflow:hidden; font-size: 16px;">
+<!-- restrict size to prevent wrap, can lead to antialiasing problem in the test -->
 <span style="padding:0.2em;">This text should be near the top of the page, not pushed below the float.</span>
 </div>
 </body>
 </html>
--- a/layout/reftests/bugs/433640-1-ref.html
+++ b/layout/reftests/bugs/433640-1-ref.html
@@ -9,17 +9,17 @@
 
   div.cell {
     float: left;
     width: 100px;
   }
   
   body > div { height:100px; }
   
-  p { height:20px; }
+  p { font-size: 12px; height:20px; }
 </style>
 </head><body>
 
 <div>
 <div class="cell"><p>31    x 32</p><div style="width:31px; background-position:-16px -16px;"  class="image"></div></div>
 <div class="cell"><p>31.1  x 32</p><div style="width:31px; background-position:-16px -16px;"  class="image"></div></div>
 <div class="cell"><p>31.5  x 32</p><div style="width:32px; background-position:-16px -16px;"  class="image"></div></div>
 <div class="cell"><p>31.8  x 32</p><div style="width:32px; background-position:-16px -16px;"  class="image"></div></div>
--- a/layout/reftests/bugs/433640-1.html
+++ b/layout/reftests/bugs/433640-1.html
@@ -12,17 +12,17 @@
     float: left;
     width: 100px;
   }
 
   body > div { height:100px; }
 
   /* ensure that font heights do not affect image placement. Fractional image offsets can
      affect exactly which pixel rects get painted. */
-  p { height:20px; }
+  p { font-size: 12px; height:20px; }
 </style>
 </head><body>
 
 <div>
 <div class="cell"><p>31    x 32</p><div style="width:31px"    class="image"></div></div>
 <div class="cell"><p>31.1  x 32</p><div style="width:31.1px"  class="image"></div></div>
 <div class="cell"><p>31.5  x 32</p><div style="width:31.5px"  class="image"></div></div>
 <div class="cell"><p>31.8  x 32</p><div style="width:31.8px"  class="image"></div></div>
--- a/layout/reftests/bugs/433700-ref.html
+++ b/layout/reftests/bugs/433700-ref.html
@@ -1,15 +1,17 @@
 <html><head>
     <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
     <title>Testcase for bug 433700</title>
     <style type="text/css">
 
+body { font-size: 16px; }
+
 fieldset,legend { padding:0; margin:0; border-width:0; border-style:solid; }
-fieldset { border-right:7px solid blue; }
+fieldset { border-right:7px solid blue; font-size: 16px; }
 
 #test1 { position:fixed; }
 #test1 fieldset { background:lime;}
 #test1 .legend  { margin-left:30px; background:pink; }
 
 #test2 { position:fixed; top:3em; }
 #test2 fieldset { background:lime; width:260px; }
 #test2 .legend  { margin-left: 20px; background:pink; }
--- a/layout/reftests/bugs/433700.html
+++ b/layout/reftests/bugs/433700.html
@@ -1,15 +1,17 @@
 <html><head>
     <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
     <title>Testcase for bug 433700</title>
     <style type="text/css">
 
+body { font-size: 16px; }
+
 fieldset,legend { padding:0; margin:0; border-width:0; border-style:solid; }
-fieldset { border-right:7px solid blue; }
+fieldset { border-right:7px solid blue; font-size: 16px; }
 
 #test1 { position:fixed; }
 #test1 fieldset { padding-left:35px; border-left:25px solid lime; background:lime; }
 #test1 legend  { margin-left: -30px; background:pink; }
 
 #test2 { position:fixed; top:3em; }
 #test2 fieldset { padding-left:35px; border-left:25px solid lime; background:lime; width:200px; }
 #test2 legend  { margin-left: -20%; background:pink; }
--- a/layout/reftests/columns/column-balancing-004.html
+++ b/layout/reftests/columns/column-balancing-004.html
@@ -3,17 +3,17 @@
 
 <style type="text/css">
   .colset {
     -moz-column-count: 3;
     -moz-column-gap: 0;
     border: solid silver;
     width: 9em;
   }
-  p { margin: 0; min-height: 1.5em; }
+  p { margin: 0; min-height: 2em; }
 </style>
 
 
 
 <div class="colset">
 <p>one</p>
 <p>two three</p>
 <p>four five</p>
--- a/layout/reftests/columns/columnrule-basic-ref.html
+++ b/layout/reftests/columns/columnrule-basic-ref.html
@@ -1,2 +1,15 @@
-<div style="position: absolute; top: 20px; left: 517px; width: 6px; background-color: red; height: 100px;"></div>
-<div style="position: absolute; top: 20px; left: 20px; -moz-column-count:2; -moz-column-gap: 0px;"><div style="height:200px; width: 500px;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa. Sed commodo diam at mauris.</div></div>
+<div style="position: absolute;
+  top: 20px; left: 517px;
+  width: 6px;
+  background-color: red;
+  height: 100px;"></div>
+<div style="position: absolute;
+  top: 20px; left: 20px;
+  -moz-column-count:2;
+  -moz-column-gap: 0px;">
+<div style="height:200px;
+  width: 500px;
+  font-size: 16px;">
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa. Sed commodo diam at mauris.
+</div>
+</div>
--- a/layout/reftests/columns/columnrule-basic.html
+++ b/layout/reftests/columns/columnrule-basic.html
@@ -1,1 +1,11 @@
-<div style="position: absolute; top: 20px; left: 20px; -moz-column-count:2; -moz-column-gap: 0px; -moz-column-rule: 6px red solid;"><div style="height:200px; width: 500px;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa. Sed commodo diam at mauris.</div></div>
+<div style="position: absolute;
+  top: 20px; left: 20px;
+  -moz-column-count :2;
+  -moz-column-gap: 0px;
+  -moz-column-rule: 6px red solid;">
+<div style="height:200px;
+  width: 500px;
+  font-size: 16px;">
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa. Sed commodo diam at mauris.
+</div>
+</div>
--- a/layout/reftests/columns/columnrule-complex-ref.html
+++ b/layout/reftests/columns/columnrule-complex-ref.html
@@ -1,4 +1,27 @@
-<div style="position: absolute; top: 20px; left: 317px; width: 6px; background-color: red; height: 50px;"></div>
-<div style="position: absolute; top: 20px; left: 617px; width: 6px; background-color: red; height: 50px;"></div>
-<div style="position: absolute; top: 20px; left: 917px; width: 6px; background-color: red; height: 50px;"></div>
-<div style="position: absolute; top: 20px; left: 20px; -moz-column-count:4; -moz-column-gap: 0px;"><div style="height:200px; width: 300px;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa.</div></div>
+<div style="position: absolute;
+  top: 20px; left: 317px;
+  width: 6px;
+  background-color: red; height: 100px;">
+</div>
+<div style="position: absolute;
+  top: 20px; left: 617px;
+  width: 6px;
+  background-color: red;
+  height: 100px;">
+</div>
+<div style="position: absolute;
+  top: 20px; left: 917px;
+  width: 6px;
+  background-color: red;
+  height: 100px;">
+</div>
+<div style="position: absolute;
+  top: 20px; left: 20px;
+  -moz-column-count: 4;
+  -moz-column-gap: 0px;">
+<div style="height:400px;
+  width: 300px;
+  font-size: 16px;">
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa.
+</div>
+</div>
--- a/layout/reftests/columns/columnrule-complex.html
+++ b/layout/reftests/columns/columnrule-complex.html
@@ -1,1 +1,11 @@
-<div style="position: absolute; top: 20px; left: 20px; -moz-column-count:4; -moz-column-gap: 0px; -moz-column-rule: 6px red solid;"><div style="height:200px; width: 300px;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa.</div></div>
+<div style="position: absolute;
+  top: 20px; left: 20px;
+  -moz-column-count: 4;
+  -moz-column-gap: 0px;
+  -moz-column-rule: 6px red solid;
+  font-size: 16px;">
+<div style="height:400px;
+  width: 300px;">
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa.
+</div>
+</div>
--- a/layout/reftests/columns/columnrule-padding-ref.html
+++ b/layout/reftests/columns/columnrule-padding-ref.html
@@ -1,4 +1,28 @@
-<div style="position: absolute; top: 40px; left: 337px; width: 6px; background-color: red; height: 50px;"></div>
-<div style="position: absolute; top: 40px; left: 637px; width: 6px; background-color: red; height: 50px;"></div>
-<div style="position: absolute; top: 40px; left: 937px; width: 6px; background-color: red; height: 50px;"></div>
-<div style="position: absolute; top: 40px; left: 40px; -moz-column-count:4; -moz-column-gap: 0px;"><div style="height:200px; width: 300px;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa.</div></div>
+<div style="position: absolute;
+  top: 40px; left: 337px;
+  width: 6px;
+  background-color: red;
+  height: 100px;">
+</div>
+<div style="position: absolute;
+  top: 40px; left: 637px;
+  width: 6px;
+  background-color: red;
+  height: 100px;">
+</div>
+<div style="position: absolute;
+  top: 40px; left: 937px;
+  width: 6px;
+  background-color: red;
+  height: 100px;">
+</div>
+<div style="position: absolute;
+  top: 40px; left: 40px;
+  -moz-column-count: 4;
+  -moz-column-gap: 0px;">
+<div style="height:400px;
+  width: 300px;
+  font-size: 16px;">
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa.
+</div>
+</div>
--- a/layout/reftests/columns/columnrule-padding.html
+++ b/layout/reftests/columns/columnrule-padding.html
@@ -1,1 +1,12 @@
-<div style="padding: 20px; position: absolute; top: 20px; left: 20px; -moz-column-count:4; -moz-column-gap: 0px; -moz-column-rule: 6px red solid;"><div style="height:200px; width: 300px;">Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa.</div></div>
+<div style="padding: 20px;
+  position: absolute;
+  top: 20px; left: 20px;
+  -moz-column-count: 4;
+  -moz-column-gap: 0px;
+  -moz-column-rule: 6px red solid;">
+<div style="height:400px;
+  width: 300px;
+  font-size: 16px;">
+Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Sed feugiat libero vel diam. Pellentesque pulvinar commodo lacus. Sed fringilla. Sed lectus. Praesent laoreet orci vitae nisi. Duis venenatis tristique massa.
+</div>
+</div>
--- a/layout/reftests/margin-collapsing/inline-block-sibling-1-ref.html
+++ b/layout/reftests/margin-collapsing/inline-block-sibling-1-ref.html
@@ -1,24 +1,26 @@
 <!DOCTYPE html>
 <html>
 <head>
+<!-- specifying all heights in em units so that large font sizes
+     don't disrupt relationships; everything will scale together -->
 <style type="text/css">
 #a {
  width: 200px;
  background-color: green;
 }
 #b, #c {
  display: inline-block;
- height: 20px; width: 200px;
+ height: 2em; width: 200px;
  background-color: blue;
  vertical-align: bottom;
 }
 #b {
- margin-bottom: 20px;
+ margin-bottom: 2em;
 }
 </style>
 </head>
 <body>
 <div id="a">
  <div id="b"></div>
  <div id="c"></div>
 </div>
--- a/layout/reftests/margin-collapsing/inline-block-sibling-1a.html
+++ b/layout/reftests/margin-collapsing/inline-block-sibling-1a.html
@@ -3,25 +3,25 @@
 <head>
 <style type="text/css">
 #a {
  width: 200px;
  background-color: green;
 }
 #b, #c {
  display: inline-block;
- height: 20px; width: 200px;
+ height: 2em; width: 200px;
  background-color: blue;
  vertical-align: bottom;
 }
 #b {
- margin-bottom: 5px;
+ margin-bottom: .5em;
 }
 #c {
- margin-top: 15px;
+ margin-top: 1.5em;
 }
 </style>
 </head>
 <body>
 <div id="a">
  <div id="b"></div>
  <div id="c"></div>
 </div>
--- a/layout/reftests/margin-collapsing/inline-block-sibling-1b.html
+++ b/layout/reftests/margin-collapsing/inline-block-sibling-1b.html
@@ -3,25 +3,25 @@
 <head>
 <style type="text/css">
 #a {
  width: 200px;
  background-color: green;
 }
 #b, #c {
  display: inline-block;
- height: 20px; width: 200px;
+ height: 2em; width: 200px;
  background-color: blue;
  vertical-align: bottom;
 }
 #b {
- margin-bottom: 15px;
+ margin-bottom: 1.5em;
 }
 #c {
- margin-top: 5px;
+ margin-top: .5em;
 }
 </style>
 </head>
 <body>
 <div id="a">
  <div id="b"></div>
  <div id="c"></div>
 </div>
--- a/layout/reftests/margin-collapsing/inline-block-sibling-1c.html
+++ b/layout/reftests/margin-collapsing/inline-block-sibling-1c.html
@@ -3,25 +3,25 @@
 <head>
 <style type="text/css">
 #a {
  width: 200px;
  background-color: green;
 }
 #b, #c {
  display: inline-block;
- height: 20px; width: 200px;
+ height: 2em; width: 200px;
  background-color: blue;
  vertical-align: bottom;
 }
 #b {
- margin-bottom: 10px;
+ margin-bottom: 1em;
 }
 #c {
- margin-top: 10px;
+ margin-top: 1em;
 }
 </style>
 </head>
 <body>
 <div id="a">
  <div id="b"></div>
  <div id="c"></div>
 </div>
--- a/layout/reftests/marquee/413027-4-ref.html
+++ b/layout/reftests/marquee/413027-4-ref.html
@@ -1,10 +1,10 @@
 <html><head>
 <title>Testcase for bug 413027 - Marquee height is sized too small, clipping text vertically</title>
 </head>
 <body>
 
 <div style="background-color: lime; width: 600px; float:left;">
-  <div style="margin: 100px 0px;">text</div>
+  <div style="margin: 100px 0px; padding-left: 2px;">text</div>
 </div>
       
 </body></html>
--- a/layout/reftests/marquee/413027-4.html
+++ b/layout/reftests/marquee/413027-4.html
@@ -1,12 +1,15 @@
 <html><head>
 <title>Testcase for bug 413027 - Marquee height is sized too small, clipping text vertically</title>
 </head>
 <body>
 
 <marquee scrollamount="0" behavior="alternate" direction="right" style="background-color: lime; width: 600px;">
 <div>
-  <div style="margin: 100px 0px;">text</div>
+<!-- padding-left used to avoid risk of an antialiasing pixel that may
+     project to the left of the origin, causing a spurious test failure
+     (see bugs 476927, 475968) -->
+  <div style="margin: 100px 0px; padding-left: 2px;">text</div>
 </div>
 </marquee>
       
 </body></html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/native-theme/492155-1.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<div style="width: 200px; height: 200px; margin: 50px; -moz-transform: rotate(90deg); position: relative;">
+  <div style="height: 200px; overflow: auto;">
+    <div style="height: 400px;"></div>
+  </div>
+  <div style="position: absolute; top: -2px; right: -2px; bottom: -2px; width: 50px; background: white;"></div>
+</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/native-theme/492155-2.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<div style="width: 200px; height: 200px; margin: 50px; -moz-transform: scale(0.5); position: relative;">
+  <div style="height: 200px; overflow: auto;">
+    <div style="height: 400px;"></div>
+  </div>
+  <div style="position: absolute; top: -2px; right: -2px; bottom: -2px; width: 50px; background: white;"></div>
+</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/native-theme/492155-3.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<div style="width: 200px; height: 200px; margin: 50px; -moz-transform: skewY(30deg); position: relative;">
+  <div style="height: 200px; overflow: auto;">
+    <div style="height: 400px;"></div>
+  </div>
+  <div style="position: absolute; top: -2px; right: -2px; bottom: -2px; width: 50px; background: white;"></div>
+</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/native-theme/492155-4.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html style="height: 100%;"><body style="height: 100%; margin: 0;">
+<div style="height: 50%"></div>
+
+<div style="width: 200px; height: 200px; -moz-transform: scale(-1); position: relative;">
+  <div style="height: 200px; overflow: auto;">
+    <div style="height: 400px;"></div>
+  </div>
+</div>
+</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/native-theme/blank-window.xul
@@ -0,0 +1,5 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window title="Blank window"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"/>
--- a/layout/reftests/native-theme/reftest.list
+++ b/layout/reftests/native-theme/reftest.list
@@ -31,19 +31,29 @@
 
 # 403458 is a Windows-only bug
 skip-if(MOZ_WIDGET_TOOLKIT!="windows") != 403458-winmenu-ltr.xul 403458-winmenu-rtl.xul
 
 == 470711-1.xul 470711-1-ref.xul
 
 == 482955-1.xul 482955-1-ref.xul
 
+== 492155-1.html about:blank
+== 492155-2.html about:blank
+== 492155-3.html about:blank
+!= 492155-4.html about:blank
+
 == box-shadow-styling.html box-shadow-styling-ref.html
 
 # RTL mirroring tests
 == checkbox-not-mirrored-when-rtl.html checkbox-not-mirrored-when-rtl-ref.html
 skip-if(MOZ_WIDGET_TOOLKIT!="cocoa") == menulist-mirrored-when-rtl.xul menulist-mirrored-when-rtl-ref.xul
 skip-if(MOZ_WIDGET_TOOLKIT!="cocoa") == searchfield-mirrored-when-rtl.xul searchfield-mirrored-when-rtl-ref.xul
 skip-if(MOZ_WIDGET_TOOLKIT!="cocoa") == select-mirrored-when-rtl.html select-mirrored-when-rtl-ref.html
+!= resizer-bottomend.xul blank-window.xul
+== resizer-bottomend.xul resizer-bottomright.xul
+!= resizer-bottomend.xul resizer-bottomend-rtl.xul
+skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") != resizer-bottomend-rtl.xul blank-window.xul
+skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") == resizer-bottomend-rtl.xul resizer-bottomend-flipped.xul
 
 # Windows-only, depends on native scrollbar metrics
 skip-if(MOZ_WIDGET_TOOLKIT!="windows") == scroll-thumb-minimum-size-notheme.html scroll-thumb-minimum-size-notheme-ref.html
 # skip-if(MOZ_WIDGET_TOOLKIT!="windows") == scroll-thumb-minimum-size-theme.html scroll-thumb-minimum-size-theme-ref.html # Bug 502292.
new file mode 100644
--- /dev/null
+++ b/layout/reftests/native-theme/resizer-bottomend-flipped.xul
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window title="Resizer"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <hbox>
+    <resizer dir="bottomend" style="-moz-transform: scaleX(-1)"/>
+    <spacer flex="1"/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/native-theme/resizer-bottomend-rtl.xul
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window title="Resizer"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <hbox>
+    <resizer dir="bottomend" style="direction: rtl"/>
+    <spacer flex="1"/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/native-theme/resizer-bottomend.xul
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window title="Resizer"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <hbox>
+    <resizer dir="bottomend"/>
+    <spacer flex="1"/>
+  </hbox>
+</window>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/native-theme/resizer-bottomright.xul
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
+
+<window title="Resizer"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <hbox>
+    <resizer dir="bottomright"/>
+    <spacer flex="1"/>
+  </hbox>
+</window>
--- a/layout/reftests/pagination/content-inserted-000.ref.xhtml
+++ b/layout/reftests/pagination/content-inserted-000.ref.xhtml
@@ -1,14 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Content Appended in {ib} Pagination with Overflow Containers</title>
 
   <style type="text/css">
+    body {
+      font-size: 16px;
+    }
+
     #colset {
       height: 400px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
       border: 3px solid silver;
     }
 
--- a/layout/reftests/pagination/content-inserted-000.xhtml
+++ b/layout/reftests/pagination/content-inserted-000.xhtml
@@ -1,14 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Content Appended in {ib} Pagination with Overflow Containers</title>
 
   <style type="text/css">
+    body {
+      font-size: 16px;
+    }
+
     #colset {
       height: 400px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
       border: 3px solid silver;
     }
 
--- a/layout/reftests/pagination/content-inserted-001.ref.xhtml
+++ b/layout/reftests/pagination/content-inserted-001.ref.xhtml
@@ -1,14 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Content Appended in Paginated Element</title>
 
   <style type="text/css">
+    body {
+      font-size: 16px;
+    }
+
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
       border: 3px solid silver;
     }
 
--- a/layout/reftests/pagination/content-inserted-001.xhtml
+++ b/layout/reftests/pagination/content-inserted-001.xhtml
@@ -1,14 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Content Appended in Paginated Element</title>
 
   <style type="text/css">
+    body {
+      font-size: 16px;
+    }
+
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
       border: 3px solid silver;
     }
 
--- a/layout/reftests/pagination/content-inserted-002.ref.xhtml
+++ b/layout/reftests/pagination/content-inserted-002.ref.xhtml
@@ -1,14 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Content Appended in Pagination</title>
 
   <style type="text/css">
+    body {
+      font-size: 16px;
+    }
+
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
       border: 3px solid silver;
     }
 
--- a/layout/reftests/pagination/content-inserted-002.xhtml
+++ b/layout/reftests/pagination/content-inserted-002.xhtml
@@ -1,14 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Content Appended in Pagination before ::after</title>
 
   <style type="text/css">
+    body {
+      font-size: 16px;
+    }
+
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
       border: 3px solid silver;
     }
 
--- a/layout/reftests/pagination/content-inserted-003.xhtml
+++ b/layout/reftests/pagination/content-inserted-003.xhtml
@@ -1,14 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Content Appended in Pagination before ::after (alternate)</title>
 
   <style type="text/css">
+    body {
+      font-size: 16px;
+    }
+
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
       border: 3px solid silver;
     }
 
--- a/layout/reftests/pagination/content-inserted-004.xhtml
+++ b/layout/reftests/pagination/content-inserted-004.xhtml
@@ -1,14 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Content Inserted in Pagination after ::before</title>
 
   <style type="text/css">
+    body {
+      font-size: 16px;
+    }
+
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
       border: 3px solid silver;
     }
 
--- a/layout/reftests/pagination/content-inserted-005.xhtml
+++ b/layout/reftests/pagination/content-inserted-005.xhtml
@@ -1,14 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Content Appended in Pagination after ::before</title>
 
   <style type="text/css">
+    body {
+      font-size: 16px;
+    }
+
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
       border: 3px solid silver;
     }
 
--- a/layout/reftests/pagination/content-inserted-006.xhtml
+++ b/layout/reftests/pagination/content-inserted-006.xhtml
@@ -1,14 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Content Appended in Pagination before ::after (alternate)</title>
 
   <style type="text/css">
+    body {
+      font-size: 16px;
+    }
+
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
       border: 3px solid silver;
     }
 
--- a/layout/reftests/pagination/content-inserted-007.xhtml
+++ b/layout/reftests/pagination/content-inserted-007.xhtml
@@ -1,14 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Content Inserted in Pagination after ::before</title>
 
   <style type="text/css">
+    body {
+      font-size: 16px;
+    }
+
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
       border: 3px solid silver;
     }
 
--- a/layout/reftests/pagination/content-inserted-008.xhtml
+++ b/layout/reftests/pagination/content-inserted-008.xhtml
@@ -1,14 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Content Appended in Pagination before ::after</title>
 
   <style type="text/css">
+    body {
+      font-size: 16px;
+    }
+
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
       border: 3px solid silver;
     }
 
--- a/layout/reftests/pagination/content-inserted-009.xhtml
+++ b/layout/reftests/pagination/content-inserted-009.xhtml
@@ -1,14 +1,18 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
   <title>Content Appended in Pagination before ::after</title>
 
   <style type="text/css">
+    body {
+      font-size: 16px;
+    }
+
     #colset {
       height: 200px;
       width: 450px;
       -moz-column-width: 150px;
       -moz-column-gap: 0;
       border: 3px solid silver;
     }
 
--- a/layout/reftests/pagination/resize-reflow-001.inner.html
+++ b/layout/reftests/pagination/resize-reflow-001.inner.html
@@ -6,17 +6,17 @@
     html, body { margin: 0; padding: 0; }
     html { overflow: hidden }
   </style>
 </head>
 <body>
 
 <div style="-moz-column-width: 12em;
             border: silver solid;
-            height: 3em;">
+            height: 4em;">
   <div style="border: dotted;
               background: aqua;
               color: gray;">
         blah<br>
         blah<br>
         blah<br>
         blah
   </div>
--- a/layout/reftests/pagination/resize-reflow-001.ref.html
+++ b/layout/reftests/pagination/resize-reflow-001.ref.html
@@ -2,17 +2,17 @@
 <html>
 <head>
   <title>Resize Reflow Test</title>
 </head>
 <body style="width: 28em">
 
 <div style="-moz-column-width: 12em;
             border: silver solid;
-            height: 3em;">
+            height: 4em;">
   <div style="border: dotted;
               background: aqua;
               color: gray;">
         blah<br>
         blah<br>
         blah<br>
         blah
   </div>
--- a/layout/reftests/reftest.list
+++ b/layout/reftests/reftest.list
@@ -139,16 +139,19 @@ include pagination/reftest.list
 include selection/reftest.list
 
 # svg/
 include svg/reftest.list
 
 # svg-integration/
 include svg-integration/reftest.list
 
+# tab-size/
+include tab-size/reftest.list
+
 # table-anonymous-boxes/
 include table-anonymous-boxes/reftest.list
 
 # table-background/
 include table-background/reftest.list
 
 # table-bordercollapse/
 include table-bordercollapse/reftest.list
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/reftest.list
@@ -0,0 +1,9 @@
+== tab-size-8.html            tab-size-initial.html
+== tab-size-8.html            spaces-8.html
+== tab-size-4.html            spaces-4.html
+== tab-size-4-span.html       spaces-4.html
+== tab-size-4-spanoffset.html spaces-4-offset.html
+== tab-size-4-multiple.html   spaces-4-multiple.html
+== tab-size-1.html            spaces-1.html
+== tab-size-0.html            spaces-0.html
+== tab-size-negative.html     tab-size-initial.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/spaces-0.html
@@ -0,0 +1,1 @@
+<pre>AX</pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/spaces-1.html
@@ -0,0 +1,1 @@
+<pre>A X</pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/spaces-4-multiple.html
@@ -0,0 +1,1 @@
+<pre>A   XYZ MNO</pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/spaces-4-offset.html
@@ -0,0 +1,6 @@
+<pre>123456B Z
+1234567B    Z
+12345678B   Z
+123456789B  Z
+1234567890B Z
+12345678901B    Z</pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/spaces-4.html
@@ -0,0 +1,1 @@
+<pre>A   X</pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/spaces-8.html
@@ -0,0 +1,1 @@
+<pre>A       X</pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/tab-size-0.html
@@ -0,0 +1,2 @@
+<!-- this test will never insert a space -->
+<pre style="-moz-tab-size: 0">A&#9;X</pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/tab-size-1.html
@@ -0,0 +1,2 @@
+<!-- this test will always insert a space -->
+<pre style="-moz-tab-size: 1">A&#9;X</pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/tab-size-4-multiple.html
@@ -0,0 +1,1 @@
+<pre style="-moz-tab-size: 4">A&#9;XYZ&#9;MNO</pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/tab-size-4-span.html
@@ -0,0 +1,1 @@
+<pre><span style="-moz-tab-size: 4">A&#9;X</span></pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/tab-size-4-spanoffset.html
@@ -0,0 +1,6 @@
+<pre>123456<span style="-moz-tab-size: 4">B&#9;Z</span>
+1234567<span style="-moz-tab-size: 4">B&#9;Z</span>
+12345678<span style="-moz-tab-size: 4">B&#9;Z</span>
+123456789<span style="-moz-tab-size: 4">B&#9;Z</span>
+1234567890<span style="-moz-tab-size: 4">B&#9;Z</span>
+12345678901<span style="-moz-tab-size: 4">B&#9;Z</span></pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/tab-size-4.html
@@ -0,0 +1,1 @@
+<pre style="-moz-tab-size: 4">A&#9;X</pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/tab-size-8.html
@@ -0,0 +1,1 @@
+<pre style="-moz-tab-size: 8">A&#9;X</pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/tab-size-initial.html
@@ -0,0 +1,1 @@
+<pre>A&#9;X</pre>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/tab-size/tab-size-negative.html
@@ -0,0 +1,1 @@
+<pre style="-moz-tab-size: -4">A&#9;X</pre>
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -5939,16 +5939,18 @@ CSSParserImpl::ParseSingleValueProperty(
   case eCSSProperty_font_variant:
     return ParseVariant(aValue, VARIANT_HMK | VARIANT_SYSFONT,
                         nsCSSProps::kFontVariantKTable);
   case eCSSProperty_font_weight:
     return ParseFontWeight(aValue);
   case eCSSProperty_ime_mode:
     return ParseVariant(aValue, VARIANT_AHK | VARIANT_NORMAL,
                         nsCSSProps::kIMEModeKTable);
+  case eCSSProperty__moz_tab_size:
+    return ParseNonNegativeVariant(aValue, VARIANT_HI, nsnull);
   case eCSSProperty_letter_spacing:
   case eCSSProperty_word_spacing:
     return ParseVariant(aValue, VARIANT_HL | VARIANT_NORMAL, nsnull);
   case eCSSProperty_line_height:
     return ParseNonNegativeVariant(aValue, VARIANT_HLPN | VARIANT_KEYWORD | VARIANT_NORMAL | VARIANT_SYSFONT, nsCSSProps::kLineHeightKTable);
   case eCSSProperty_list_style_image:
     return ParseVariant(aValue, VARIANT_HUO, nsnull);
   case eCSSProperty_list_style_position:
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -394,16 +394,27 @@ CSS_PROP_OUTLINE(
     MozOutlineRadiusBottomleft,
     0,
     Margin,
     mOutlineRadius.mBottomLeft,
     eCSSType_ValuePair,
     nsnull,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
+CSS_PROP_TEXT(
+    -moz-tab-size,
+    _moz_tab_size,
+    MozTabSize,
+    0,
+    Text,
+    mTabSize,
+    eCSSType_Value,
+    nsnull,
+    offsetof(nsStyleText, mTabSize),
+    eStyleAnimType_None)
 #ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
 CSS_PROP_FONT(
     -x-system-font,
     _x_system_font,
     X,
     CSS_PROPERTY_APPLIES_TO_FIRST_LETTER_AND_FIRST_LINE,
     Font,
     mSystemFont,
--- a/layout/style/nsCSSStruct.h
+++ b/layout/style/nsCSSStruct.h
@@ -330,16 +330,17 @@ struct nsRuleDataColor : public nsCSSCol
 private:
   nsRuleDataColor(const nsRuleDataColor& aOther); // NOT IMPLEMENTED
 };
 
 struct nsCSSText : public nsCSSStruct  {
   nsCSSText(void);
   ~nsCSSText(void);
 
+  nsCSSValue mTabSize;
   nsCSSValue mWordSpacing;
   nsCSSValue mLetterSpacing;
   nsCSSValue mVerticalAlign;
   nsCSSValue mTextTransform;
   nsCSSValue mTextAlign;
   nsCSSValue mTextIndent;
   nsCSSValue mDecoration;
   nsCSSValueList* mTextShadow; // NEW
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -2549,16 +2549,27 @@ nsComputedDOMStyle::GetTextTransform(nsI
   } else {
     val->SetIdent(eCSSKeyword_none);
   }
 
   return CallQueryInterface(val, aValue);
 }
 
 nsresult
+nsComputedDOMStyle::GetMozTabSize(nsIDOMCSSValue** aValue)
+{
+  nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
+  NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
+
+  val->SetNumber(GetStyleText()->mTabSize);
+    
+  return CallQueryInterface(val, aValue);
+}
+
+nsresult
 nsComputedDOMStyle::GetLetterSpacing(nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue *val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
   SetValueToCoord(val, GetStyleText()->mLetterSpacing);
 
   return CallQueryInterface(val, aValue);
@@ -4733,16 +4744,17 @@ nsComputedDOMStyle::GetQueryableProperty
     COMPUTED_STYLE_MAP_ENTRY(float_edge,                    FloatEdge),
     COMPUTED_STYLE_MAP_ENTRY(force_broken_image_icon,  ForceBrokenImageIcon),
     COMPUTED_STYLE_MAP_ENTRY(image_region,                  ImageRegion),
     COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_outline_radius_bottomLeft, OutlineRadiusBottomLeft),
     COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_outline_radius_bottomRight,OutlineRadiusBottomRight),
     COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_outline_radius_topLeft,    OutlineRadiusTopLeft),
     COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_outline_radius_topRight,   OutlineRadiusTopRight),
     COMPUTED_STYLE_MAP_ENTRY(stack_sizing,                  StackSizing),
+    COMPUTED_STYLE_MAP_ENTRY(_moz_tab_size,                 MozTabSize),
     COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_transform,         MozTransform),
     COMPUTED_STYLE_MAP_ENTRY_LAYOUT(_moz_transform_origin,  MozTransformOrigin),
     COMPUTED_STYLE_MAP_ENTRY(user_focus,                    UserFocus),
     COMPUTED_STYLE_MAP_ENTRY(user_input,                    UserInput),
     COMPUTED_STYLE_MAP_ENTRY(user_modify,                   UserModify),
     COMPUTED_STYLE_MAP_ENTRY(user_select,                   UserSelect),
     COMPUTED_STYLE_MAP_ENTRY(transition_delay,              TransitionDelay),
     COMPUTED_STYLE_MAP_ENTRY(transition_duration,           TransitionDuration),
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -282,16 +282,17 @@ private:
   nsresult GetTextDecoration(nsIDOMCSSValue** aValue);
   nsresult GetTextIndent(nsIDOMCSSValue** aValue);
   nsresult GetTextTransform(nsIDOMCSSValue** aValue);
   nsresult GetTextShadow(nsIDOMCSSValue** aValue);
   nsresult GetLetterSpacing(nsIDOMCSSValue** aValue);
   nsresult GetWordSpacing(nsIDOMCSSValue** aValue);
   nsresult GetWhiteSpace(nsIDOMCSSValue** aValue);
   nsresult GetWordWrap(nsIDOMCSSValue** aValue);
+  nsresult GetMozTabSize(nsIDOMCSSValue** aValue);
 
   /* Visibility properties */
   nsresult GetOpacity(nsIDOMCSSValue** aValue);
   nsresult GetPointerEvents(nsIDOMCSSValue** aValue);
   nsresult GetVisibility(nsIDOMCSSValue** aValue);
 
   /* Direction properties */
   nsresult GetDirection(nsIDOMCSSValue** aValue);
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -3217,17 +3217,22 @@ nsRuleNode::ComputeTextData(void* aStart
                             const nsRuleDataStruct& aData, 
                             nsStyleContext* aContext, 
                             nsRuleNode* aHighestNode,
                             const RuleDetail aRuleDetail,
                             const PRBool aCanStoreInRuleTree)
 {
   COMPUTE_START_INHERITED(Text, (), text, parentText, Text, textData)
 
-    // letter-spacing: normal, length, inherit
+  // tab-size: integer, inherit
+  SetDiscrete(textData.mTabSize, text->mTabSize, canStoreInRuleTree,
+              SETDSC_INTEGER, parentText->mTabSize,
+              NS_STYLE_TABSIZE_INITIAL, 0, 0, 0, 0);
+  
+  // letter-spacing: normal, length, inherit
   SetCoord(textData.mLetterSpacing, text->mLetterSpacing, parentText->mLetterSpacing,
            SETCOORD_LH | SETCOORD_NORMAL | SETCOORD_INITIAL_NORMAL,
            aContext, mPresContext, canStoreInRuleTree);
 
   // text-shadow: none, list, inherit, initial
   nsCSSValueList* list = textData.mTextShadow;
   if (list) {
     text->mTextShadow = nsnull;
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -2340,28 +2340,30 @@ nsStyleText::nsStyleText(void)
   mWordWrap = NS_STYLE_WORDWRAP_NORMAL;
 
   mLetterSpacing.SetNormalValue();
   mLineHeight.SetNormalValue();
   mTextIndent.SetCoordValue(0);
   mWordSpacing = 0;
 
   mTextShadow = nsnull;
+  mTabSize = NS_STYLE_TABSIZE_INITIAL;
 }
 
 nsStyleText::nsStyleText(const nsStyleText& aSource)
   : mTextAlign(aSource.mTextAlign),
     mTextTransform(aSource.mTextTransform),
     mWhiteSpace(aSource.mWhiteSpace),
     mWordWrap(aSource.mWordWrap),
     mLetterSpacing(aSource.mLetterSpacing),
     mLineHeight(aSource.mLineHeight),
     mTextIndent(aSource.mTextIndent),
     mWordSpacing(aSource.mWordSpacing),
-    mTextShadow(aSource.mTextShadow)
+    mTextShadow(aSource.mTextShadow),
+    mTabSize(aSource.mTabSize)
 {
   MOZ_COUNT_CTOR(nsStyleText);
 }
 
 nsStyleText::~nsStyleText(void)
 {
   MOZ_COUNT_DTOR(nsStyleText);
 }
@@ -2375,17 +2377,18 @@ nsChangeHint nsStyleText::CalcDifference
 
   if ((mTextAlign != aOther.mTextAlign) ||
       (mTextTransform != aOther.mTextTransform) ||
       (mWhiteSpace != aOther.mWhiteSpace) ||
       (mWordWrap != aOther.mWordWrap) ||
       (mLetterSpacing != aOther.mLetterSpacing) ||
       (mLineHeight != aOther.mLineHeight) ||
       (mTextIndent != aOther.mTextIndent) ||
-      (mWordSpacing != aOther.mWordSpacing))
+      (mWordSpacing != aOther.mWordSpacing) ||
+      (mTabSize != aOther.mTabSize))
     return NS_STYLE_HINT_REFLOW;
 
   return CalcShadowDifference(mTextShadow, aOther.mTextShadow);
 }
 
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStyleText::MaxDifference()
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1061,16 +1061,17 @@ struct nsStyleText {
 #ifdef DEBUG
   static nsChangeHint MaxDifference();
 #endif
 
   PRUint8 mTextAlign;                   // [inherited] see nsStyleConsts.h
   PRUint8 mTextTransform;               // [inherited] see nsStyleConsts.h
   PRUint8 mWhiteSpace;                  // [inherited] see nsStyleConsts.h
   PRUint8 mWordWrap;                    // [inherited] see nsStyleConsts.h
+  PRInt32 mTabSize;                     // [inherited] see nsStyleConsts.h
 
   nsStyleCoord  mLetterSpacing;         // [inherited] coord, normal
   nsStyleCoord  mLineHeight;            // [inherited] coord, factor, normal
   nsStyleCoord  mTextIndent;            // [inherited] coord, percent
   nscoord mWordSpacing;                 // [inherited]
 
   nsRefPtr<nsCSSShadowArray> mTextShadow; // [inherited] NULL in case of a zero-length
   
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -530,16 +530,24 @@ var gCSSProperties = {
 		inherited: false,
 		type: CSS_TYPE_SHORTHAND_AND_LONGHAND,
 		get_computed: logical_box_prop_get_computed,
 		/* no subproperties */
 		initial_values: [ "0", "0px", "0%", "0em", "0ex" ],
 		other_values: [ "1px", "3em" ],
 		invalid_values: []
 	},
+	"-moz-tab-size": {
+		domProp: "MozTabSize",
+		inherited: true,
+		type: CSS_TYPE_LONGHAND,
+		initial_values: [ "8" ],
+		other_values: [ "0", "3", "99", "12000" ],
+		invalid_values: [ "-1", "-808", "3.0", "17.5" ]
+	},
 	"-moz-transform": {
 		domProp: "MozTransform",
 		inherited: false,
 		type: CSS_TYPE_LONGHAND,
 		initial_values: [ "none" ],
 		other_values: [ "translatex(1px)", "translatex(4em)", "translatex(-4px)", "translatex(3px)", "translatex(0px) translatex(1px) translatex(2px) translatex(3px) translatex(4px)", "translatey(4em)", "translate(3px)", "translate(10px, -3px)", "rotate(45deg)", "rotate(45grad)", "rotate(45rad)", "rotate(0)", "scalex(10)", "scaley(10)", "scale(10)", "scale(10, 20)", "skewx(30deg)", "skewx(0)", "skewy(0)", "skewx(30grad)", "skewx(30rad)", "skewy(30deg)", "skewy(30grad)", "skewy(30rad)", "matrix(1, 2, 3, 4, 5px, 6em)", "rotate(45deg) scale(2, 1)", "skewx(45deg) skewx(-50grad)", "translate(0, 0) scale(1, 1) skewx(0) skewy(0) matrix(1, 0, 0, 1, 0, 0)", "translatex(50%)", "translatey(50%)", "translate(50%)", "translate(3%, 5px)", "translate(5px, 3%)", "matrix(1, 2, 3, 4, 5px, 6%)", "matrix(1, 2, 3, 4, 5%, 6px)", "matrix(1, 2, 3, 4, 5%, 6%)"],
 		invalid_values: ["1px", "#0000ff", "red", "auto", "translatex(1px 1px)", "translatex(translatex(1px))", "translatex(#0000ff)", "translatex(red)", "translatey()", "matrix(1, 2, 3, 4, 5, 6)", "matrix(1px, 2px, 3px, 4px, 5px, 6px)", "scale(150%)", "skewx(red)", "matrix(1%, 0, 0, 0, 0px, 0px)", "matrix(0, 1%, 2, 3, 4px,5px)", "matrix(0, 1, 2%, 3, 4px, 5px)", "matrix(0, 1, 2, 3%, 4%, 5%)"]
 	},
deleted file mode 100644
--- a/media/libtheora/455357_wince_local_variable_macro_clash_patch
+++ /dev/null
@@ -1,40 +0,0 @@
-diff --git a/media/libtheora/lib/dec/decode.c b/media/libtheora/lib/dec/decode.c
---- a/media/libtheora/lib/dec/decode.c
-+++ b/media/libtheora/lib/dec/decode.c
-@@ -1803,8 +1803,8 @@
- 
- static void oc_dering_block(unsigned char *_idata,int _ystride,int _b,
-  int _dc_scale,int _sharp_mod,int _strong){
--  static const int     MOD_MAX[2]={24,32};
--  static const int     MOD_SHIFT[2]={1,0};
-+  static const int     OCDB_MOD_MAX[2]={24,32};
-+  static const int     OCDB_MOD_SHIFT[2]={1,0};
-   const unsigned char *psrc;
-   const unsigned char *src;
-   const unsigned char *nsrc;
-@@ -1814,14 +1814,14 @@
-   int                  mod_hi;
-   int                  by;
-   int                  bx;
--  mod_hi=OC_MINI(3*_dc_scale,MOD_MAX[_strong]);
-+  mod_hi=OC_MINI(3*_dc_scale,OCDB_MOD_MAX[_strong]);
-   dst=_idata;
-   src=dst;
-   psrc=src-(_ystride&-!(_b&4));
-   for(by=0;by<9;by++){
-     for(bx=0;bx<8;bx++){
-       int mod;
--      mod=32+_dc_scale-(abs(src[bx]-psrc[bx])<<MOD_SHIFT[_strong]);
-+      mod=32+_dc_scale-(abs(src[bx]-psrc[bx])<<OCDB_MOD_SHIFT[_strong]);
-       vmod[(by<<3)+bx]=mod<-64?_sharp_mod:OC_CLAMPI(0,mod,mod_hi);
-     }
-     psrc=src;
-@@ -1833,7 +1833,7 @@
-     src=nsrc;
-     for(by=0;by<8;by++){
-       int mod;
--      mod=32+_dc_scale-(abs(*src-*psrc)<<MOD_SHIFT[_strong]);
-+      mod=32+_dc_scale-(abs(*src-*psrc)<<OCDB_MOD_SHIFT[_strong]);
-       hmod[(bx<<3)+by]=mod<-64?_sharp_mod:OC_CLAMPI(0,mod,mod_hi);
-       psrc+=_ystride;
-       src+=_ystride;
--- a/media/libtheora/AUTHORS
+++ b/media/libtheora/AUTHORS
@@ -1,48 +1,47 @@
 Monty <monty@xiph.org>
 	- Original VP3 port
 
 Ralph Giles
-Timothy B. Terriberry 
+Timothy B. Terriberry
+Monty
 	- Ongoing development
-
+	
 Dan B. Miller
 	- Pre alpha3 development
-
+	
+Rudolf Marek
 Wim Tayman
 Dan Lenski
+Nils Pipenbrinck
+Monty
 	- MMX optimized functions
-
+	
 Aaron Colwell
 Thomas Vander Stichele
 Jan Gerber
 Conrad Parker
+Cristian Adam
+Sebastian Pippin
+Simon Hosie
 	- Bug fixes, enhancements, build systems.
-
+	
 Mauricio Piacentini
 	- Original win32 projects and example ports
-	- dump_video example
 	- VP3->Theora transcoder
 
 Silvia Pfeiffer
 	- Figures for the spec
 
-Vegard Nossum
-	- Original png2theora implementation
-
-Rudolf Marek
-Nils Pipenbrinck
-	- MMX optimizations
-
 Michael Smith
 Andre Pang
 calc
-ccheney
-brendan
+Chris Cheney
+Brendan Cully
 Edward Hervey
 Adam Moss
 Colin Ward
 Jeremy C. Reed
 Arc Riley
 Rodolphe Ortalo
 	- Bug fixes
 
--- a/media/libtheora/CHANGES
+++ b/media/libtheora/CHANGES
@@ -1,8 +1,66 @@
+libtheora 1.1.1 (unreleased snapshot)
+
+ - No changes have been recorded
+
+libtheora 1.1.0 (2009 September 24)
+
+ - Fix various small issues with the example and telemetry code
+ - Fix handing a zero-byte packet as the first frame
+ - Documentation cleanup
+ - Two minor build fixes
+
+libtheora 1.1beta3 (2009 August 22)
+
+ - Rate control fixes to smooth quality
+ - MSVC build now exports all of the 1.0 api
+ - Assorted small bug fixes
+
+libtheora 1.1beta2 (2009 August 12)
+
+ - Fix a rate control problem with difficult input
+ - Build fixes for OpenBSD and Apple Xcode
+ - Examples now all use the 1.0 api
+ - TH_ENCCTL_SET_SPLEVEL works again
+ - Various bug fixes and source tree rearrangement
+
+libtheora 1.1beta1 (2009 August 5)
+
+ - Support for two-pass encoding
+ - Performance optimization of both encoder and decoder
+ - Encoder supports dynamic adjustment of quality and 
+   bitrate targets
+ - Encoder is generally more configurable, and all
+   rate control modes perform better
+ - Encoder now accepts 4:2:2 and 4:4:4 chroma sampling
+ - Decoder telemetry output shows quantization choice
+   and a breakdown of bitrate usage in the frame
+ - MSVC assembly optimizations up to date and functional
+
+libtheora 1.1alpha2 (2009 May 26)
+
+ - Reduce lambda for small quantizers.
+ - New encoder fDCT does better on smooth gradients
+ - Use SATD for mode decisions (1-2% bitrate reduction)
+ - Assembly rewrite for new features and general speed up
+ - Share code between the encoder and decoder for performance
+ - Fix 4:2:2 decoding and telemetry
+ - MSVC project files updated, but assembly is disabled.
+ - New configure option --disable-spec to work around toolchain
+   detection failures.
+ - Limit symbol exports on MacOS X.
+ - Port remaining unit tests from the 1.0 release.
+
+libtheora 1.1alpha1 (2009 March 27)
+
+ - Encoder rewrite with much improved vbr quality/bitrate and
+   better tracking of the target rate in cbr mode.
+ - MSVC project files do not work in this release.
+
 libtheora 1.0 (2008 November 3)
 
  - Merge x86 assembly for forward DCT from Thusnelda branch.
  - Update 32 bit MMX with loop filter fix.
  - Check for an uninitialized state before dereferencing in propagating
    decode calls.
  - Remove all TH_DEBUG statements.
  - Rename the bitpacker source files copied from libogg to avoid
--- a/media/libtheora/COPYING
+++ b/media/libtheora/COPYING
@@ -1,22 +1,22 @@
-Copyright (C) 2002-2008 Xiph.Org Foundation and contributors.
+Copyright (C) 2002-2009 Xiph.org Foundation
 
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 
 - Redistributions of source code must retain the above copyright
 notice, this list of conditions and the following disclaimer.
 
 - Redistributions in binary form must reproduce the above copyright
 notice, this list of conditions and the following disclaimer in the
 documentation and/or other materials provided with the distribution.
 
-- Neither the name of the Xiph.Org Foundation nor the names of its
+- Neither the name of the Xiph.org Foundation nor the names of its
 contributors may be used to endorse or promote products derived from
 this software without specific prior written permission.
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION
 OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
--- a/media/libtheora/README
+++ b/media/libtheora/README
@@ -1,20 +1,26 @@
 -------------------------------------------------------------------------
-             The Xiph.org Foundation's libtheora 1.0 release
+             The Xiph.org Foundation's libtheora 1.1 beta release
 -------------------------------------------------------------------------
 
 *** What is Theora?
 
 Theora is Xiph.Org's first publicly released video codec, intended
 for use within the Foundation's Ogg multimedia streaming system.
-Theora is derived directly from On2's VP3 codec; Currently the 
-encoders are nearly identical, but Theora will make use of new
-features supported by the decoder to improve on what is possible
-with VP3.
+Theora is derived directly from On2's VP3 codec, adds new features
+while allow it a longer useful lifetime as an competitive codec.
+
+The 1.0 release decoder supports all the new features, but the
+encoder is nearly identical to the VP3 code.
+
+The 1.1 release features a completely rewritten encoder, offering
+better performance and compression, and making more complete use
+of the format's feature set. Files produced by both encoders can
+be decoded by either release.
 
 *** Where is Theora?
 
 Theora's main site is www.theora.org.  Theora and related libraries
 can be gotten from www.theora.org or the main Xiph.Org site at
 www.xiph.org.  Development source is kept in an open subversion 
 repository, see http://theora.org/svn/ for instructions.
 
@@ -53,17 +59,17 @@ Requirements summary:
 
 The provided build system is the GNU automake/autoconf system, and
 the main library, libtheora, should already build smoothly on any
 system.  Failure of libtheora to build on a GNU-enabled system is
 considered a bug; please report problems to theora-dev@xiph.org.
 
 Windows build support is included in the win32 directory.
 
-Project files for Apple XCode is included in the macosx directory.
+Project files for Apple XCode are included in the macosx directory.
 
 There is also an experimental scons build.
 
 *** How do I use the sample encoder?
 
 The sample encoder takes raw video in YUV4MPEG2 format, as used by
 lavtools, mjpeg-tools and other packages. The encoder expects audio,
 if any, in a separate wave WAV file. Try 'encoder_example -h' for a 
--- a/media/libtheora/README_MOZILLA
+++ b/media/libtheora/README_MOZILLA
@@ -1,18 +1,5 @@
-The source from this directory was copied from the libtheora-1.0
-source distribution using the update.sh script. The changes made were
-those applied by update.sh, the addition/update of Makefile.in files
-for the Mozilla build system and the patch in bug below.
+The source from this directory was copied from the theora subversion trunk
+using the update.sh script. The changes made were those applied by update.sh,
+the addition/update of Makefile.in files for the Mozilla build system.
 
-bug498770.patch - Enable optimized theora code in windows build
-Bug 455357 - WinCE LibTheora Pre-defined Macro usage in local variable
-  455357_wince_local_variable_macro_clash_patch
-  This patch is needed for building WinCE / WinMobile because the 
-  Mozilla WinCE Shunt Library currently includes windows.h header file,
-  which causes a conflict with local variables in the oc_dering_block()
-  function.  This issue should be cleared up soon, with a reworking of 
-  the WinCE Shunt Library (Bug 456788 - reduce windows ce shunt impact).  
-  Until then, this simple patch allows WinCE to finish compiling.
-
-bug498815.patch: Fix for this bug from libtheora svn r16143.
-bug498824.patch: Fix for this bug from libtheora thusnelda branch.
-bug504613.patch: Fix for this bug from libtheora svn r16557.
+The subversion revision used was r16584.
deleted file mode 100644
--- a/media/libtheora/bug498770.patch
+++ /dev/null
@@ -1,97 +0,0 @@
-Index: lib/dec/x86_vc/mmxfrag.c
-===================================================================
---- lib/dec/x86_vc/mmxfrag.c	(revision 16142)
-+++ lib/dec/x86_vc/mmxfrag.c	(working copy)
-@@ -27,12 +27,14 @@
- 
- void oc_frag_recon_intra_mmx(unsigned char *_dst,int _dst_ystride,
-  const ogg_int16_t *_residue){
-+  int _save_ebx;
-   /* ---------------------------------------------------------------------
-   This function does the inter reconstruction step with 8 iterations
-   unrolled. The iteration for each instruction is noted by the #id in the
-   comments (in case you want to reconstruct it)
-   --------------------------------------------------------------------- */
-   _asm{
-+    mov       [_save_ebx], ebx
-     mov       edi, [_residue]     /* load residue ptr     */
-     mov       eax, 0x00800080     /* generate constant    */
-     mov       ebx, [_dst_ystride] /* load dst-stride      */
-@@ -93,6 +95,7 @@
-     packuswb  mm3, mm4            /* #8 pack to byte      */
-     movq      [edx + ecx*2], mm1  /* #7 write row         */
-     movq      [edx + eax], mm3    /* #8 write row         */
-+    mov       ebx, [_save_ebx]
-   }
- }
- 
-@@ -100,6 +103,7 @@
- 
- void oc_frag_recon_inter_mmx (unsigned char *_dst, int _dst_ystride,
-  const unsigned char *_src, int _src_ystride, const ogg_int16_t *_residue){
-+  int _save_ebx;
-   /* ---------------------------------------------------------------------
-   This function does the inter reconstruction step with two iterations
-   running in parallel to hide some load-latencies and break the dependency
-@@ -107,6 +111,7 @@
-   comments (in case you want to reconstruct it)
-   --------------------------------------------------------------------- */
-   _asm{
-+    mov       [_save_ebx], ebx
-     pxor      mm0, mm0          /* generate constant 0 */
-     mov       esi, [_src]
-     mov       edi, [_residue]
-@@ -143,6 +148,7 @@
-     movq      [edx + ebx], mm7  /* #2 write row          */
-     lea       edx, [edx+ebx*2]  /* dst += stride * 2     */
-     jne       nextchunk
-+    mov       ebx, [_save_ebx]
-   }
- }
- 
-@@ -150,6 +156,7 @@
- void oc_frag_recon_inter2_mmx(unsigned char *_dst,  int _dst_ystride,
-  const unsigned char *_src1,  int _src1_ystride, const unsigned char *_src2,
-  int _src2_ystride,const ogg_int16_t *_residue){
-+  int _save_ebx;
-   /* ---------------------------------------------------------------------
-   This function does the inter2 reconstruction step.The building of the
-   average is done with a bit-twiddeling trick to avoid excessive register
-@@ -166,6 +173,7 @@
-   using the pavgb instruction let me know and I'll do the 3dnow codepath.
-   --------------------------------------------------------------------- */
-  _asm{
-+   mov        [_save_ebx], ebx
-    mov        eax, 0xfefefefe
-    mov        esi, [_src1]
-    mov        edi, [_src2]
-@@ -204,6 +212,7 @@
-    packuswb   mm2,  mm3           /* pack and saturate   */
-    movq       [edx], mm2          /* write row           */
-    jne        nextrow
-+   mov        ebx, [_save_ebx]
-  }
- }
- 
-Index: lib/dec/x86_vc/mmxloopfilter.c
-===================================================================
---- lib/dec/x86_vc/mmxloopfilter.c	(revision 16142)
-+++ lib/dec/x86_vc/mmxloopfilter.c	(working copy)
-@@ -38,7 +38,7 @@
-   _asm {
-     mov       eax,  [_pix]
-     mov       edx,  [_ystride]
--    mov       ebx,  [_ll]
-+    mov       ecx,  [_ll]
- 
-     /* _pix -= ystride */
-     sub       eax,   edx
-@@ -104,7 +104,7 @@
-     /*Free up mm5.*/
-     packuswb  mm4, mm5
-     /*mm0=L L L L*/
--    movq      mm0, [ebx]
-+    movq      mm0, [ecx]
-     /*if(R_i<-2L||R_i>2L)R_i=0:*/
-     movq      mm5, mm2
-     pxor      mm6, mm6
deleted file mode 100644
--- a/media/libtheora/bug498815.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-Index: decinfo.c
-===================================================================
---- decinfo.c   (revision 16127)
-+++ decinfo.c   (working copy)
-@@ -70,12 +70,8 @@
-   _info->pic_height=(ogg_uint32_t)val;
-   theorapackB_read(_opb,8,&val);
-   _info->pic_x=(ogg_uint32_t)val;
--  /*Note: The sense of pic_y is inverted in what we pass back to the
--     application compared to how it is stored in the bitstream.
--    This is because the bitstream uses a right-handed coordinate system, while
--     applications expect a left-handed one.*/
-   theorapackB_read(_opb,8,&val);
--  _info->pic_y=_info->frame_height-_info->pic_height-(ogg_uint32_t)val;
-+  _info->pic_y=(ogg_uint32_t)val;
-   theorapackB_read(_opb,32,&val);
-   _info->fps_numerator=(ogg_uint32_t)val;
-   theorapackB_read(_opb,32,&val);
-@@ -86,6 +82,11 @@
-    _info->fps_numerator==0||_info->fps_denominator==0){
-     return TH_EBADHEADER;
-   }
-+  /*Note: The sense of pic_y is inverted in what we pass back to the
-+     application compared to how it is stored in the bitstream.
-+    This is because the bitstream uses a right-handed coordinate system, while
-+     applications expect a left-handed one.*/
-+  _info->pic_y=_info->frame_height-_info->pic_height-_info->pic_y;
-   theorapackB_read(_opb,24,&val);
-   _info->aspect_numerator=(ogg_uint32_t)val;
-   theorapackB_read(_opb,24,&val);
deleted file mode 100644
--- a/media/libtheora/bug498824.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-diff --git a/media/libtheora/lib/dec/decinfo.c b/media/libtheora/lib/dec/decinfo.c
-index e51d63e..d08d6b6 100644
---- a/media/libtheora/lib/dec/decinfo.c
-+++ b/media/libtheora/lib/dec/decinfo.c
-@@ -11,7 +11,7 @@
-  ********************************************************************
- 
-   function:
--    last mod: $Id: decinfo.c 15400 2008-10-15 12:10:58Z tterribe $
-+    last mod: $Id$
- 
-  ********************************************************************/
- 
-@@ -111,14 +111,15 @@ static int oc_comment_unpack(oggpack_buffer *_opb,th_comment *_tc){
-   int  i;
-   /*Read the vendor string.*/
-   len=oc_unpack_length(_opb);
--  if(len<0||theorapackB_bytes(_opb)+len>_opb->storage)return TH_EBADHEADER;
-+  if(len<0||len>_opb->storage-theorapackB_bytes(_opb))return TH_EBADHEADER;
-   _tc->vendor=_ogg_malloc((size_t)len+1);
-   oc_unpack_octets(_opb,_tc->vendor,len);
-   _tc->vendor[len]='\0';
-   /*Read the user comments.*/
-   _tc->comments=(int)oc_unpack_length(_opb);
--  if(_tc->comments<0||_tc->comments>(LONG_MAX>>2)||
--   theorapackB_bytes(_opb)+((long)_tc->comments<<2)>_opb->storage){
-+  len=_tc->comments;
-+  if(len<0||len>(LONG_MAX>>2)||len<<2>_opb->storage-theorapackB_bytes(_opb)){
-+    _tc->comments=0;
-     return TH_EBADHEADER;
-   }
-   _tc->comment_lengths=(int *)_ogg_malloc(
-@@ -127,7 +128,7 @@ static int oc_comment_unpack(oggpack_buffer *_opb,th_comment *_tc){
-    _tc->comments*sizeof(_tc->user_comments[0]));
-   for(i=0;i<_tc->comments;i++){
-     len=oc_unpack_length(_opb);
--    if(len<0||theorapackB_bytes(_opb)+len>_opb->storage){
-+    if(len<0||len>_opb->storage-theorapackB_bytes(_opb)){
-       _tc->comments=i;
-       return TH_EBADHEADER;
-     }
-@@ -224,12 +225,10 @@ static int oc_dec_headerin(oggpack_buffer *_opb,th_info *_info,
- int th_decode_headerin(th_info *_info,th_comment *_tc,
-  th_setup_info **_setup,ogg_packet *_op){
-   oggpack_buffer opb;
--  int            ret;
-   if(_op==NULL)return TH_EBADHEADER;
-   if(_info==NULL)return TH_EFAULT;
-   theorapackB_readinit(&opb,_op->packet,_op->bytes);
--  ret=oc_dec_headerin(&opb,_info,_tc,_setup,_op);
--  return ret;
-+  return oc_dec_headerin(&opb,_info,_tc,_setup,_op);
- }
- 
- void th_setup_free(th_setup_info *_setup){
deleted file mode 100644
--- a/media/libtheora/bug504613.patch
+++ /dev/null
@@ -1,119 +0,0 @@
-# HG changeset patch
-# User Matthew Gregan <kinetik@flim.org>
-# Date 1252993590 -43200
-# Node ID 2fce745981185aecebad0366b4c2ff45e9f93e95
-# Parent  8dbe8de92cb46f64f8ff80d79f38961eb02e9cbd
-imported patch bug504613
-
-diff --git a/media/libtheora/lib/dec/decode.c b/media/libtheora/lib/dec/decode.c
---- a/media/libtheora/lib/dec/decode.c
-+++ b/media/libtheora/lib/dec/decode.c
-@@ -1846,16 +1846,40 @@ int th_decode_ctl(th_dec_ctx *_dec,int _
-       _dec->stripe_cb.ctx=cb->ctx;
-       _dec->stripe_cb.stripe_decoded=cb->stripe_decoded;
-       return 0;
-     }break;
-     default:return TH_EIMPL;
-   }
- }
- 
-+/*We're decoding an INTER frame, but have no initialized reference
-+   buffers (i.e., decoding did not start on a key frame).
-+  We initialize them to a solid gray here.*/
-+static void oc_dec_init_dummy_frame(th_dec_ctx *_dec){
-+  th_info *info;
-+  size_t   yplane_sz;
-+  size_t   cplane_sz;
-+  int      yhstride;
-+  int      yvstride;
-+  int      chstride;
-+  int      cvstride;
-+  _dec->state.ref_frame_idx[OC_FRAME_GOLD]=0;
-+  _dec->state.ref_frame_idx[OC_FRAME_PREV]=0;
-+  _dec->state.ref_frame_idx[OC_FRAME_SELF]=1;
-+  info=&_dec->state.info;
-+  yhstride=info->frame_width+2*OC_UMV_PADDING;
-+  yvstride=info->frame_height+2*OC_UMV_PADDING;
-+  chstride=yhstride>>!(info->pixel_fmt&1);
-+  cvstride=yvstride>>!(info->pixel_fmt&2);
-+  yplane_sz=(size_t)yhstride*yvstride;
-+  cplane_sz=(size_t)chstride*cvstride;
-+  memset(_dec->state.ref_frame_data,0x80,yplane_sz+2*cplane_sz);
-+}
-+
- int th_decode_packetin(th_dec_ctx *_dec,const ogg_packet *_op,
-  ogg_int64_t *_granpos){
-   int ret;
-   if(_dec==NULL||_op==NULL)return TH_EFAULT;
-   /*A completely empty packet indicates a dropped frame and is treated exactly
-      like an inter frame with no coded blocks.
-     Only proceed if we have a non-empty packet.*/
-   if(_op->bytes!=0){
-@@ -1869,37 +1893,19 @@ int th_decode_packetin(th_dec_ctx *_dec,
-     theorapackB_readinit(&_dec->opb,_op->packet,_op->bytes);
-     ret=oc_dec_frame_header_unpack(_dec);
-     if(ret<0)return ret;
-     /*Select a free buffer to use for the reconstructed version of this
-        frame.*/
-     if(_dec->state.frame_type!=OC_INTRA_FRAME&&
-      (_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0||
-      _dec->state.ref_frame_idx[OC_FRAME_PREV]<0)){
--      th_info *info;
--      size_t       yplane_sz;
--      size_t       cplane_sz;
--      int          yhstride;
--      int          yvstride;
--      int          chstride;
--      int          cvstride;
--      /*We're decoding an INTER frame, but have no initialized reference
--         buffers (i.e., decoding did not start on a key frame).
--        We initialize them to a solid gray here.*/
--      _dec->state.ref_frame_idx[OC_FRAME_GOLD]=0;
--      _dec->state.ref_frame_idx[OC_FRAME_PREV]=0;
--      _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi=1;
--      info=&_dec->state.info;
--      yhstride=info->frame_width+2*OC_UMV_PADDING;
--      yvstride=info->frame_height+2*OC_UMV_PADDING;
--      chstride=yhstride>>!(info->pixel_fmt&1);
--      cvstride=yvstride>>!(info->pixel_fmt&2);
--      yplane_sz=(size_t)yhstride*yvstride;
--      cplane_sz=(size_t)chstride*cvstride;
--      memset(_dec->state.ref_frame_data,0x80,yplane_sz+2*cplane_sz);
-+      /*No reference frames yet!*/
-+      oc_dec_init_dummy_frame(_dec);
-+      refi=_dec->state.ref_frame_idx[OC_FRAME_SELF];
-     }
-     else{
-       for(refi=0;refi==_dec->state.ref_frame_idx[OC_FRAME_GOLD]||
-        refi==_dec->state.ref_frame_idx[OC_FRAME_PREV];refi++);
-       _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi;
-     }
-     if(_dec->state.frame_type==OC_INTRA_FRAME){
-       oc_dec_mark_all_intra(_dec);
-@@ -2036,16 +2042,26 @@ int th_decode_packetin(th_dec_ctx *_dec,
-     }
- #if defined(OC_DUMP_IMAGES)
-     /*Don't dump images for dropped frames.*/
-     oc_state_dump_frame(&_dec->state,OC_FRAME_SELF,"dec");
- #endif
-     return 0;
-   }
-   else{
-+    if(_dec->state.ref_frame_idx[OC_FRAME_GOLD]<0||
-+     _dec->state.ref_frame_idx[OC_FRAME_PREV]<0){
-+      int refi;
-+      /*No reference frames yet!*/
-+      oc_dec_init_dummy_frame(_dec);
-+      refi=_dec->state.ref_frame_idx[OC_FRAME_PREV];
-+      _dec->state.ref_frame_idx[OC_FRAME_SELF]=refi;
-+      memcpy(_dec->pp_frame_buf,_dec->state.ref_frame_bufs[refi],
-+       sizeof(_dec->pp_frame_buf[0])*3);
-+    }
-     /*Just update the granule position and return.*/
-     _dec->state.granpos=
-      (_dec->state.keyframe_num<<_dec->state.info.keyframe_granule_shift)+
-      (_dec->state.curframe_num-_dec->state.keyframe_num);
-     _dec->state.curframe_num++;
-     if(_granpos!=NULL)*_granpos=_dec->state.granpos;
-     return TH_DUPFRAME;
-   }
--- a/media/libtheora/include/theora/Makefile.in
+++ b/media/libtheora/include/theora/Makefile.in
@@ -41,12 +41,13 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 EXPORTS_NAMESPACES = theora
 
 EXPORTS_theora = \
 		theora.h \
 		theoradec.h \
+		theoraenc.h \
 		codec.h \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/media/libtheora/include/theora/codec.h
+++ b/media/libtheora/include/theora/codec.h
@@ -1,16 +1,16 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  *                                                                  *
- * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
 
   function:
   last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $
 
  ********************************************************************/
@@ -19,20 +19,20 @@
  * 
  * \section intro Introduction
  *
  * This is the documentation for <tt>libtheora</tt> C API.
  * The current reference
  * implementation for <a href="http://www.theora.org/">Theora</a>, a free,
  * patent-unencumbered video codec.
  * Theora is derived from On2's VP3 codec with additional features and
- *  integration for Ogg multimedia formats by
+ *  integration with Ogg multimedia formats by
  *  <a href="http://www.xiph.org/">the Xiph.Org Foundation</a>.
  * Complete documentation of the format itself is available in
- * <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
+ * <a href="http://www.theora.org/doc/Theora.pdf">the Theora
  *  specification</a>.
  *
  * \subsection Organization
  *
  * The functions documented here are actually subdivided into three 
  * separate libraries:
  * - <tt>libtheoraenc</tt> contains the encoder interface,
  *   described in \ref encfuncs.
@@ -87,39 +87,39 @@ extern "C" {
 #define TH_EBADPACKET (-24)
 /**The decoded packet represented a dropped frame.
    The player can continue to display the current frame, as the contents of the
     decoded frame buffer have not changed.*/
 #define TH_DUPFRAME   (1)
 /*@}*/
 
 /**The currently defined color space tags.
- * See <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
- *  specification</a>, Chapter 4, for exact details on the meaning of each of
- *  these color spaces.*/
+ * See <a href="http://www.theora.org/doc/Theora.pdf">the Theora
+ *  specification</a>, Chapter 4, for exact details on the meaning
+ *  of each of these color spaces.*/
 typedef enum{
   /**The color space was not specified at the encoder.
       It may be conveyed by an external means.*/
   TH_CS_UNSPECIFIED,
   /**A color space designed for NTSC content.*/
   TH_CS_ITU_REC_470M,
   /**A color space designed for PAL/SECAM content.*/
   TH_CS_ITU_REC_470BG,
   /**The total number of currently defined color spaces.*/
   TH_CS_NSPACES
 }th_colorspace;
 
 /**The currently defined pixel format tags.
- * See <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
+ * See <a href="http://www.theora.org/doc/Theora.pdf">the Theora
  *  specification</a>, Section 4.4, for details on the precise sample
  *  locations.*/
 typedef enum{
   /**Chroma decimation by 2 in both the X and Y directions (4:2:0).
-     The Cb and Cr chroma planes are half the width and half the height of the
-      luma plane.*/
+     The Cb and Cr chroma planes are half the width and half the
+      height of the luma plane.*/
   TH_PF_420,
   /**Currently reserved.*/
   TH_PF_RSVD,
   /**Chroma decimation by 2 in the X direction (4:2:2).
      The Cb and Cr chroma planes are half the width of the luma plane, but full
       height.*/
   TH_PF_422,
   /**No chroma decimation (4:4:4).
@@ -128,46 +128,46 @@ typedef enum{
   /**The total number of currently defined pixel formats.*/
   TH_PF_NFORMATS
 }th_pixel_fmt;
 
 
 
 /**A buffer for a single color plane in an uncompressed image.
  * This contains the image data in a left-to-right, top-down format.
- * Each row of pixels is stored contiguously in memory, but successive rows
- *  need not be.
+ * Each row of pixels is stored contiguously in memory, but successive
+ *  rows need not be.
  * Use \a stride to compute the offset of the next row.
- * The encoder accepts both positive \a stride values (top-down in memory) and
- *  negative (bottom-up in memory).
+ * The encoder accepts both positive \a stride values (top-down in memory)
+ *  and negative (bottom-up in memory).
  * The decoder currently always generates images with positive strides.*/
 typedef struct{
   /**The width of this plane.*/
   int            width;
   /**The height of this plane.*/
   int            height;
   /**The offset in bytes between successive rows.*/
   int            stride;
   /**A pointer to the beginning of the first row.*/
   unsigned char *data;
 }th_img_plane;
 
 /**A complete image buffer for an uncompressed frame.
- * The chroma planes may be decimated by a factor of two in either direction,
- *  as indicated by th_info#pixel_fmt.
+ * The chroma planes may be decimated by a factor of two in either
+ *  direction, as indicated by th_info#pixel_fmt.
  * The width and height of the Y' plane must be multiples of 16.
- * They may need to be cropped for display, using the rectangle specified by
- *  th_info#pic_x, th_info#pic_y, th_info#pic_width, and
- *  th_info#pic_height.
+ * They may need to be cropped for display, using the rectangle
+ *  specified by th_info#pic_x, th_info#pic_y, th_info#pic_width,
+ *  and th_info#pic_height.
  * All samples are 8 bits.
  * \note The term YUV often used to describe a colorspace is ambiguous.
- * The exact parameters of the RGB to YUV conversion process aside, in many
- *  contexts the U and V channels actually have opposite meanings.
- * To avoid this confusion, we are explicit: the name of the color channels are
- *  Y'CbCr, and they appear in that order, always.
+ * The exact parameters of the RGB to YUV conversion process aside, in
+ *  many contexts the U and V channels actually have opposite meanings.
+ * To avoid this confusion, we are explicit: the name of the color
+ *  channels are Y'CbCr, and they appear in that order, always.
  * The prime symbol denotes that the Y channel is non-linear.
  * Cb and Cr stand for "Chroma blue" and "Chroma red", respectively.*/
 typedef th_img_plane th_ycbcr_buffer[3];
 
 /**Theora bitstream information.
  * This contains the basic playback parameters for a stream, and corresponds to 
  *  the initial 'info' header packet.
  * To initialize an encoder, the application fills in this structure and
@@ -187,17 +187,17 @@ typedef th_img_plane th_ycbcr_buffer[3];
  *  the cropped picture region, and the application does not need to fill them
  *  in.
  * The decoder <em>will</em> allocate storage for a full frame, but the
  *  application <em>should not</em> rely on the padding containing sensible
  *  data.
  *
  * It is also generally recommended that the offsets and sizes should still be
  *  multiples of 2 to avoid chroma sampling shifts when chroma is sub-sampled.
- * See <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
+ * See <a href="http://www.theora.org/doc/Theora.pdf">the Theora
  *  specification</a>, Section 4.4, for more details.
  *
  * Frame rate, in frames per second, is stored as a rational fraction, as is
  *  the pixel aspect ratio.
  * Note that this refers to the aspect ratio of the individual pixels, not of
  *  the overall frame itself.
  * The frame aspect ratio can be computed from pixel aspect ratio using the
  *  image dimensions.*/
@@ -225,18 +225,18 @@ typedef struct{
    * This must be no larger than #frame_width-#pic_width or 255, whichever is
    *  smaller.*/
   ogg_uint32_t  pic_x;
   /**The Y offset of the displayed picture.
    * This must be no larger than #frame_height-#pic_height, and
    *  #frame_height-#pic_height-#pic_y must be no larger than 255.
    * This slightly funny restriction is due to the fact that the offset is
    *  specified from the top of the image for consistency with the standard
-   *  graphics left-handed coordinate system used throughout this API, while it
-   *  is stored in the encoded stream as an offset from the bottom.*/
+   *  graphics left-handed coordinate system used throughout this API, while
+   *  it is stored in the encoded stream as an offset from the bottom.*/
   ogg_uint32_t  pic_y;
   /**\name Frame rate
    * The frame rate, as a fraction.
    * If either is 0, the frame rate is undefined.*/
   /*@{*/
   ogg_uint32_t  fps_numerator;
   ogg_uint32_t  fps_denominator;
   /*@}*/
@@ -254,19 +254,16 @@ typedef struct{
   /*@}*/
   /**The color space.*/
   th_colorspace colorspace;
   /**The pixel format.*/
   th_pixel_fmt  pixel_fmt;
   /**The target bit-rate in bits per second.
      If initializing an encoder with this struct, set this field to a non-zero
       value to activate CBR encoding by default.*/
-  /*TODO: Current encoder does not support CBR mode, or anything like it.
-    We also don't really know what nominal rate each quality level
-     corresponds to yet.*/
   int           target_bitrate;
   /**The target quality level.
      Valid values range from 0 to 63, inclusive, with higher values giving
       higher quality.
      If initializing an encoder with this struct, and #target_bitrate is set
       to zero, VBR encoding at this quality will be activated by default.*/
   /*Currently this is set so that a qi of 0 corresponds to distortions of 24
      times the JND, and each increase by 16 halves that value.
@@ -309,17 +306,17 @@ typedef struct{
  *  words, but not more than a short paragraph.
  *
  * The metadata is stored as a series of (tag, value) pairs, in
  *  length-encoded string vectors.
  * The first occurrence of the '=' character delimits the tag and value.
  * A particular tag may occur more than once, and order is significant.
  * The character set encoding for the strings is always UTF-8, but the tag
  *  names are limited to ASCII, and treated as case-insensitive.
- * See <a href="http://www.theora.org/doc/Theora_I_spec.pdf">the Theora
+ * See <a href="http://www.theora.org/doc/Theora.pdf">the Theora
  *  specification</a>, Section 6.3.3 for details.
  *
  * In filling in this structure, th_decode_headerin() will null-terminate
  *  the user_comment strings for safety.
  * However, the bitstream format itself treats them as 8-bit clean vectors,
  *  possibly containing null characters, and so the length array should be
  *  treated as their authoritative length.
  */
--- a/media/libtheora/include/theora/config.h
+++ b/media/libtheora/include/theora/config.h
@@ -1,11 +1,14 @@
 /* config.h.  Generated from config.h.in by configure.  */
 /* config.h.in.  Generated from configure.ac by autoheader.  */
 
+/* libcairo is available for visual debugging output */
+/* #undef HAVE_CAIRO */
+
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #define HAVE_DLFCN_H 1
 
 /* Define to 1 if you have the <inttypes.h> header file. */
 #define HAVE_INTTYPES_H 1
 
 /* Define to 1 if you have the <machine/soundcard.h> header file. */
 /* #undef HAVE_MACHINE_SOUNDCARD_H */
@@ -24,57 +27,64 @@
 
 /* Define to 1 if you have the <strings.h> header file. */
 #define HAVE_STRINGS_H 1
 
 /* Define to 1 if you have the <string.h> header file. */
 #define HAVE_STRING_H 1
 
 /* Define to 1 if you have the <sys/soundcard.h> header file. */
-#define HAVE_SYS_SOUNDCARD_H 1
+/* #undef HAVE_SYS_SOUNDCARD_H */
 
 /* Define to 1 if you have the <sys/stat.h> header file. */
 #define HAVE_SYS_STAT_H 1
 
 /* Define to 1 if you have the <sys/types.h> header file. */
 #define HAVE_SYS_TYPES_H 1
 
 /* Define to 1 if you have the <unistd.h> header file. */
 #define HAVE_UNISTD_H 1
 
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
 /* Define to 1 if your C compiler doesn't accept -c and -o together. */
 /* #undef NO_MINUS_C_MINUS_O */
 
-/* enable x86 assambler optimization */
- 
+/* make use of x86_64 asm optimization */
+/* #undef OC_X86_64_ASM */
+
+/* make use of x86 asm optimization */
+ /**/
 
 /* Name of package */
 #define PACKAGE "libtheora"
 
 /* Define to the address where bug reports for this package should be sent. */
 #define PACKAGE_BUGREPORT ""
 
 /* Define to the full name of this package. */
 #define PACKAGE_NAME "libtheora"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "libtheora 1.0"
+#define PACKAGE_STRING "libtheora 1.1.0"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "libtheora"
 
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "1.0"
+#define PACKAGE_VERSION "1.1.0"
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
 /* Define to exclude encode support from the build */
 /* #undef THEORA_DISABLE_ENCODE */
 
 /* Define to exclude floating point code from the build */
 /* #undef THEORA_DISABLE_FLOAT */
 
-/* make use of asm optimization */
- 
-
 /* Version number of package */
-#define VERSION "1.0"
+#define VERSION "1.1.0"
--- a/media/libtheora/include/theora/theora.h
+++ b/media/libtheora/include/theora/theora.h
@@ -1,16 +1,16 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  *                                                                  *
- * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
 
   function:
   last mod: $Id: theora.h,v 1.17 2003/12/06 18:06:19 arc Exp $
 
  ********************************************************************/
@@ -22,32 +22,32 @@
 extern "C"
 {
 #endif /* __cplusplus */
 
 #include <stddef.h>	/* for size_t */
 
 #include <ogg/ogg.h>
 
-/** \defgroup oldfuncs Legacy pre-1.0 C API */
-/*  @{ */
-
-/** \mainpage
- * 
+/** \file
+ * The libtheora pre-1.0 legacy C API.
+ *
+ * \ingroup oldfuncs
+ *
  * \section intro Introduction
  *
  * This is the documentation for the libtheora legacy C API, declared in 
  * the theora.h header, which describes the old interface used before
  * the 1.0 release. This API was widely deployed for several years and
  * remains supported, but for new code we recommend the cleaner API 
  * declared in theoradec.h and theoraenc.h.
  *
  * libtheora is the reference implementation for
  * <a href="http://www.theora.org/">Theora</a>, a free video codec.
- * Theora is derived from On2's VP3 codec with improved integration for
+ * Theora is derived from On2's VP3 codec with improved integration with
  * Ogg multimedia formats by <a href="http://www.xiph.org/">Xiph.Org</a>.
  * 
  * \section overview Overview
  *
  * This library will both decode and encode theora packets to/from raw YUV 
  * frames.  In either case, the packets will most likely either come from or
  * need to be embedded in an Ogg stream.  Use 
  * <a href="http://xiph.org/ogg/">libogg</a> or 
@@ -109,31 +109,21 @@ extern "C"
  *  - once you have found a theora b_o_s page then use the retrieved serial_no 
  *    to identify future packets belonging to the same theora stream.
  * 
  * Note that you \e cannot use theora_packet_isheader() to determine if a 
  * packet is a theora packet or not, as this function does not perform any
  * checking beyond whether a header bit is present.  Instead, use the
  * theora_decode_header() function and check the return value; or examine the
  * header bytes at the beginning of the Ogg page.
- *
- * \subsection example Example Decoder 
- *
- * See <a href="http://svn.xiph.org/trunk/theora/examples/dump_video.c">
- * examples/dump_video.c</a> for a simple decoder implementation.
- *
- * \section encoding Encoding Process
- *
- * See <a href="http://svn.xiph.org/trunk/theora/examples/encoder_example.c">
- * examples/encoder_example.c</a> for a simple encoder implementation.
  */
 
-/** \file
- * The libtheora pre-1.0 legacy C API.
- */
+
+/** \defgroup oldfuncs Legacy pre-1.0 C API */
+/*  @{ */
 
 /**
  * A YUV buffer for passing uncompressed frames to and from the codec.
  * This holds a Y'CbCr frame in planar format. The CbCr planes can be
  * subsampled and have their own separate dimensions and row stride
  * offsets. Note that the strides may be negative in some 
  * configurations. For theora the width and height of the largest plane
  * must be a multiple of 16. The actual meaningful picture size and 
@@ -287,24 +277,31 @@ typedef struct theora_comment{
   int   *comment_lengths;       /**< An array of corresponding string vector lengths in bytes */
   int    comments;              /**< The total number of comment string vectors */
   char  *vendor;                /**< The vendor string identifying the encoder, null terminated */
 
 } theora_comment;
 
 
 /**\name theora_control() codes */
-
-/**\anchor decctlcodes
+/* \anchor decctlcodes_old
  * These are the available request codes for theora_control()
  * when called with a decoder instance.
- * By convention, these are odd, to distinguish them from the
- *  \ref encctlcodes "encoder control codes".
+ * By convention decoder control codes are odd, to distinguish 
+ * them from \ref encctlcodes_old "encoder control codes" which
+ * are even.
+ *
+ * Note that since the 1.0 release, both the legacy and the final
+ * implementation accept all the same control codes, but only the
+ * final API declares the newer codes.
+ *
  * Keep any experimental or vendor-specific values above \c 0x8000.*/
 
+/*@{*/
+
 /**Get the maximum post-processing level.
  * The decoder supports a post-processing filter that can improve
  * the appearance of the decoded images. This returns the highest
  * level setting for this post-processor, corresponding to maximum
  * improvement and computational expense.
  */
 #define TH_DECCTL_GET_PPLEVEL_MAX (1)
 
@@ -319,57 +316,47 @@ typedef struct theora_comment{
  * This can be changed during an encode, but will be bounded by
  *  <tt>1<<th_info#keyframe_granule_shift</tt>.
  * If it is set before encoding begins, th_info#keyframe_granule_shift will
  *  be enlarged appropriately.
  *
  * \param[in]  buf <tt>ogg_uint32_t</tt>: The maximum distance between key
  *                   frames.
  * \param[out] buf <tt>ogg_uint32_t</tt>: The actual maximum distance set.
- * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
- * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>.
- * \retval TH_IMPL   Not supported by this implementation.*/
+ * \retval OC_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval OC_EINVAL \a buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>.
+ * \retval OC_IMPL   Not supported by this implementation.*/
 #define TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE (4)
 
 /**Set the granule position.
  * Call this after a seek, to update the internal granulepos
  * in the decoder, to insure that subsequent frames are marked
  * properly. If you track timestamps yourself and do not use
  * the granule postion returned by the decoder, then you do
  * not need to use this control.
  */
 #define TH_DECCTL_SET_GRANPOS (5)
 
+/**\anchor encctlcodes_old */
 
-/**\anchor encctlcodes
- * These are the available request codes for theora_control()
- * when called with an encoder instance.
- * By convention, these are even, to distinguish them from the
- *  \ref decctlcodes "decoder control codes".
- * Keep any experimental or vendor-specific values above \c 0x8000.*/
-/*@{*/
 /**Sets the quantization parameters to use.
  * The parameters are copied, not stored by reference, so they can be freed
  *  after this call.
  * <tt>NULL</tt> may be specified to revert to the default parameters.
- * For the current encoder, <tt>scale[ci!=0][qi]</tt> must be no greater than
- *  <tt>scale[ci!=0][qi-1]</tt> and <tt>base[qti][pli][qi][ci]</tt> must be no
- *  greater than <tt>base[qti][pli][qi-1][ci]</tt>.
- * These two conditions ensure that the actual quantizer for a given \a qti,
- *  \a pli, and \a ci does not increase as \a qi increases.
  *
  * \param[in] buf #th_quant_info
- * \retval TH_FAULT  \a theora_state is <tt>NULL</tt>.
- * \retval TH_EINVAL Encoding has already begun, the quantization parameters
- *                    do not meet one of the above stated conditions, \a buf
- *                    is <tt>NULL</tt> and \a buf_sz is not zero, or \a buf
- *                    is non-<tt>NULL</tt> and \a buf_sz is not
- *                    <tt>sizeof(#th_quant_info)</tt>.
- * \retval TH_IMPL   Not supported by this implementation.*/
+ * \retval OC_FAULT  \a theora_state is <tt>NULL</tt>.
+ * \retval OC_EINVAL Encoding has already begun, the quantization parameters
+ *                    are not acceptable to this version of the encoder, 
+ *                    \a buf is <tt>NULL</tt> and \a buf_sz is not zero, 
+ *                    or \a buf is non-<tt>NULL</tt> and \a buf_sz is 
+ *                    not <tt>sizeof(#th_quant_info)</tt>.
+ * \retval OC_IMPL   Not supported by this implementation.*/
 #define TH_ENCCTL_SET_QUANT_PARAMS (2)
+
 /**Disables any encoder features that would prevent lossless transcoding back
  *  to VP3.
  * This primarily means disabling block-level QI values and not using 4MV mode
  *  when any of the luma blocks in a macro block are not coded.
  * It also includes using the VP3 quantization tables and Huffman codes; if you
  *  set them explicitly after calling this function, the resulting stream will
  *  not be VP3-compatible.
  * If you enable VP3-compatibility when encoding 4:2:2 or 4:4:4 source
@@ -384,48 +371,51 @@ typedef struct theora_comment{
  * \param[in]  buf <tt>int</tt>: a non-zero value to enable VP3 compatibility,
  *                   or 0 to disable it (the default).
  * \param[out] buf <tt>int</tt>: 1 if all bitstream features required for
  *                   VP3-compatibility could be set, and 0 otherwise.
  *                  The latter will be returned if the pixel format is not
  *                   4:2:0, the picture region is smaller than the full frame,
  *                   or if encoding has begun, preventing the quantization
  *                   tables and codebooks from being set.
- * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
- * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
- * \retval TH_IMPL   Not supported by this implementation.*/
+ * \retval OC_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval OC_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval OC_IMPL   Not supported by this implementation.*/
 #define TH_ENCCTL_SET_VP3_COMPATIBLE (10)
+
 /**Gets the maximum speed level.
  * Higher speed levels favor quicker encoding over better quality per bit.
  * Depending on the encoding mode, and the internal algorithms used, quality
  *  may actually improve, but in this case bitrate will also likely increase.
  * In any case, overall rate/distortion performance will probably decrease.
  * The maximum value, and the meaning of each value, may change depending on
  *  the current encoding mode (VBR vs. CQI, etc.).
  *
  * \param[out] buf int: The maximum encoding speed level.
- * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
- * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
- * \retval TH_IMPL   Not supported by this implementation in the current
+ * \retval OC_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval OC_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval OC_IMPL   Not supported by this implementation in the current
  *                    encoding mode.*/
 #define TH_ENCCTL_GET_SPLEVEL_MAX (12)
+
 /**Sets the speed level.
  * By default a speed value of 1 is used.
  *
  * \param[in] buf int: The new encoding speed level.
  *                      0 is slowest, larger values use less CPU.
- * \retval TH_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
- * \retval TH_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>, or the
+ * \retval OC_FAULT  \a theora_state or \a buf is <tt>NULL</tt>.
+ * \retval OC_EINVAL \a buf_sz is not <tt>sizeof(int)</tt>, or the
  *                    encoding speed level is out of bounds.
  *                   The maximum encoding speed level may be
  *                    implementation- and encoding mode-specific, and can be
  *                    obtained via #TH_ENCCTL_GET_SPLEVEL_MAX.
- * \retval TH_IMPL   Not supported by this implementation in the current
+ * \retval OC_IMPL   Not supported by this implementation in the current
  *                    encoding mode.*/
 #define TH_ENCCTL_SET_SPLEVEL (14)
+
 /*@}*/
 
 #define OC_FAULT       -1       /**< General failure */
 #define OC_EINVAL      -10      /**< Library encountered invalid internal data */
 #define OC_DISABLED    -11      /**< Requested action is disabled */
 #define OC_BADHEADER   -20      /**< Header packet was corrupt/invalid */
 #define OC_NOTFORMAT   -21      /**< Packet is not a theora packet */
 #define OC_VERSION     -22      /**< Bitstream version is not handled */
@@ -774,18 +764,18 @@ extern int   theora_comment_query_count(
  * \param tc An allocated theora_comment structure.
  **/
 extern void  theora_comment_clear(theora_comment *tc);
 
 /**Encoder control function.
  * This is used to provide advanced control the encoding process.
  * \param th     A #theora_state handle.
  * \param req    The control code to process.
- *                See \ref encctlcodes "the list of available control codes"
- *                 for details.
+ *                See \ref encctlcodes_old "the list of available 
+ *			control codes" for details.
  * \param buf    The parameters for this control code.
  * \param buf_sz The size of the parameter buffer.*/
 extern int theora_control(theora_state *th,int req,void *buf,size_t buf_sz);
 
 /* @} */ /* end oldfuncs doxygen group */
 
 #ifdef __cplusplus
 }
--- a/media/libtheora/include/theora/theoradec.h
+++ b/media/libtheora/include/theora/theoradec.h
@@ -1,16 +1,16 @@
 /********************************************************************
  *                                                                  *
  * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
  * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
  * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
  * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
  *                                                                  *
- * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2007                *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
  * by the Xiph.Org Foundation http://www.xiph.org/                  *
  *                                                                  *
  ********************************************************************
 
   function:
   last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $
 
  ********************************************************************/
@@ -33,25 +33,33 @@ extern "C" {
 /**\name th_decode_ctl() codes
  * \anchor decctlcodes
  * These are the available request codes for th_decode_ctl().
  * By convention, these are odd, to distinguish them from the
  *  \ref encctlcodes "encoder control codes".
  * Keep any experimental or vendor-specific values above \c 0x8000.*/
 /*@{*/
 /**Gets the maximum post-processing level.
+ * The decoder supports a post-processing filter that can improve
+ * the appearance of the decoded images. This returns the highest
+ * level setting for this post-processor, corresponding to maximum
+ * improvement and computational expense.
  *
  * \param[out] _buf int: The maximum post-processing level.
  * \retval TH_EFAULT  \a _dec_ctx or \a _buf is <tt>NULL</tt>.
  * \retval TH_EINVAL  \a _buf_sz is not <tt>sizeof(int)</tt>.
  * \retval TH_EIMPL   Not supported by this implementation.*/
 #define TH_DECCTL_GET_PPLEVEL_MAX (1)
 /**Sets the post-processing level.
  * By default, post-processing is disabled.
  *
+ * Sets the level of post-processing to use when decoding the
+ * compressed stream. This must be a value between zero (off)
+ * and the maximum returned by TH_DECCTL_GET_PPLEVEL_MAX.
+ *
  * \param[in] _buf int: The new post-processing level.
  *                      0 to disable; larger values use more CPU.
  * \retval TH_EFAULT  \a _dec_ctx or \a _buf is <tt>NULL</tt>.
  * \retval TH_EINVAL  \a _buf_sz is not <tt>sizeof(int)</tt>, or the
  *                     post-processing level is out of bounds.
  *                    The maximum post-processing level may be
  *                     implementation-specific, and can be obtained via
  *                     #TH_DECCTL_GET_PPLEVEL_MAX.
@@ -78,16 +86,25 @@ extern "C" {
  * Enabling striped decode does not prevent you from calling
  *  th_decode_ycbcr_out() after the frame is fully decoded.
  *
  * \param[in]  _buf #th_stripe_callback: The callback parameters.
  * \retval TH_EFAULT  \a _dec_ctx or \a _buf is <tt>NULL</tt>.
  * \retval TH_EINVAL  \a _buf_sz is not
  *                     <tt>sizeof(th_stripe_callback)</tt>.*/
 #define TH_DECCTL_SET_STRIPE_CB (7)
+
+/**Enables telemetry and sets the macroblock display mode */
+#define TH_DECCTL_SET_TELEMETRY_MBMODE (9)
+/**Enables telemetry and sets the motion vector display mode */
+#define TH_DECCTL_SET_TELEMETRY_MV (11)
+/**Enables telemetry and sets the adaptive quantization display mode */
+#define TH_DECCTL_SET_TELEMETRY_QI (13)
+/**Enables telemetry and sets the bitstream breakdown visualization mode */
+#define TH_DECCTL_SET_TELEMETRY_BITS (15)
 /*@}*/
 
 
 
 /**A callback function for striped decode.
  * This is a function pointer to an application-provided function that will be
  *  called each time a section of the image is fully decoded in
  *  th_decode_packetin().
@@ -284,16 +301,17 @@ extern int th_decode_packetin(th_dec_ctx
  *               <tt>libtheoradec</tt> will fill in all the members of this
  *                structure, including the pointers to the uncompressed video
  *                data.
  *               The memory for this video data is owned by
  *                <tt>libtheoradec</tt>.
  *               It may be freed or overwritten without notification when
  *                subsequent frames are decoded.
  * \retval 0 Success
+ * \retval TH_EFAULT     \a _dec or \a _ycbcr was <tt>NULL</tt>.
  */
 extern int th_decode_ycbcr_out(th_dec_ctx *_dec,
  th_ycbcr_buffer _ycbcr);
 /**Frees an allocated decoder instance.
  * \param _dec A #th_dec_ctx handle.*/
 extern void th_decode_free(th_dec_ctx *_dec);
 /*@}*/
 /*@}*/
new file mode 100644
--- /dev/null
+++ b/media/libtheora/include/theora/theoraenc.h
@@ -0,0 +1,486 @@
+/********************************************************************
+ *                                                                  *
+ * THIS FILE IS PART OF THE OggTheora SOFTWARE CODEC SOURCE CODE.   *
+ * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS     *
+ * GOVERNED BY A BSD-STYLE SOURCE LICENSE INCLUDED WITH THIS SOURCE *
+ * IN 'COPYING'. PLEASE READ THESE TERMS BEFORE DISTRIBUTING.       *
+ *                                                                  *
+ * THE Theora SOURCE CODE IS COPYRIGHT (C) 2002-2009                *
+ * by the Xiph.Org Foundation http://www.xiph.org/                  *
+ *                                                                  *
+ ********************************************************************
+
+  function:
+  last mod: $Id: theora.h,v 1.8 2004/03/15 22:17:32 derf Exp $
+
+ ********************************************************************/
+
+/**\file
+ * The <tt>libtheoraenc</tt> C encoding API.*/
+
+#if !defined(_O_THEORA_THEORAENC_H_)
+# define _O_THEORA_THEORAENC_H_ (1)
+# include <stddef.h>
+# include <ogg/ogg.h>
+# include "codec.h"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+
+
+/**\name th_encode_ctl() codes
+ * \anchor encctlcodes
+ * These are the available request codes for th_encode_ctl().
+ * By convention, these are even, to distinguish them from the
+ *  \ref decctlcodes "decoder control codes".
+ * Keep any experimental or vendor-specific values above \c 0x8000.*/
+/*@{*/
+/**Sets the Huffman tables to use.
+ * The tables are copied, not stored by reference, so they can be freed after
+ *  this call.
+ * <tt>NULL</tt> may be specified to revert to the default tables.
+ *
+ * \param[in] _buf <tt>#th_huff_code[#TH_NHUFFMAN_TABLES][#TH_NDCT_TOKENS]</tt>
+ * \retval TH_EFAULT \a _enc_ctx is <tt>NULL</tt>.
+ * \retval TH_EINVAL Encoding has already begun or one or more of the given
+ *                     tables is not full or prefix-free, \a _buf is
+ *                     <tt>NULL</tt> and \a _buf_sz is not zero, or \a _buf is
+ *                     non-<tt>NULL</tt> and \a _buf_sz is not
+ *                     <tt>sizeof(#th_huff_code)*#TH_NHUFFMAN_TABLES*#TH_NDCT_TOKENS</tt>.
+ * \retval TH_EIMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_HUFFMAN_CODES (0)
+/**Sets the quantization parameters to use.
+ * The parameters are copied, not stored by reference, so they can be freed
+ *  after this call.
+ * <tt>NULL</tt> may be specified to revert to the default parameters.
+ *
+ * \param[in] _buf #th_quant_info
+ * \retval TH_EFAULT \a _enc_ctx is <tt>NULL</tt>.
+ * \retval TH_EINVAL Encoding has already begun, \a _buf is 
+ *                    <tt>NULL</tt> and \a _buf_sz is not zero,
+ *                    or \a _buf is non-<tt>NULL</tt> and
+ *                    \a _buf_sz is not <tt>sizeof(#th_quant_info)</tt>.
+ * \retval TH_EIMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_QUANT_PARAMS (2)
+/**Sets the maximum distance between key frames.
+ * This can be changed during an encode, but will be bounded by
+ *  <tt>1<<th_info#keyframe_granule_shift</tt>.
+ * If it is set before encoding begins, th_info#keyframe_granule_shift will
+ *  be enlarged appropriately.
+ *
+ * \param[in]  _buf <tt>ogg_uint32_t</tt>: The maximum distance between key
+ *                   frames.
+ * \param[out] _buf <tt>ogg_uint32_t</tt>: The actual maximum distance set.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(ogg_uint32_t)</tt>.
+ * \retval TH_EIMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_KEYFRAME_FREQUENCY_FORCE (4)
+/**Disables any encoder features that would prevent lossless transcoding back
+ *  to VP3.
+ * This primarily means disabling block-adaptive quantization and always coding
+ *  all four luma blocks in a macro block when 4MV is used.
+ * It also includes using the VP3 quantization tables and Huffman codes; if you
+ *  set them explicitly after calling this function, the resulting stream will
+ *  not be VP3-compatible.
+ * If you enable VP3-compatibility when encoding 4:2:2 or 4:4:4 source
+ *  material, or when using a picture region smaller than the full frame (e.g.
+ *  a non-multiple-of-16 width or height), then non-VP3 bitstream features will
+ *  still be disabled, but the stream will still not be VP3-compatible, as VP3
+ *  was not capable of encoding such formats.
+ * If you call this after encoding has already begun, then the quantization
+ *  tables and codebooks cannot be changed, but the frame-level features will
+ *  be enabled or disabled as requested.
+ *
+ * \param[in]  _buf <tt>int</tt>: a non-zero value to enable VP3 compatibility,
+ *                   or 0 to disable it (the default).
+ * \param[out] _buf <tt>int</tt>: 1 if all bitstream features required for
+ *                   VP3-compatibility could be set, and 0 otherwise.
+ *                  The latter will be returned if the pixel format is not
+ *                   4:2:0, the picture region is smaller than the full frame,
+ *                   or if encoding has begun, preventing the quantization
+ *                   tables and codebooks from being set.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval TH_EIMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_SET_VP3_COMPATIBLE (10)
+/**Gets the maximum speed level.
+ * Higher speed levels favor quicker encoding over better quality per bit.
+ * Depending on the encoding mode, and the internal algorithms used, quality
+ *  may actually improve, but in this case bitrate will also likely increase.
+ * In any case, overall rate/distortion performance will probably decrease.
+ * The maximum value, and the meaning of each value, may change depending on
+ *  the current encoding mode (VBR vs. constant quality, etc.).
+ *
+ * \param[out] _buf <tt>int</tt>: The maximum encoding speed level.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval TH_EIMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_GET_SPLEVEL_MAX (12)
+/**Sets the speed level.
+ * The current speed level may be retrieved using #TH_ENCCTL_GET_SPLEVEL.
+ *
+ * \param[in] _buf <tt>int</tt>: The new encoding speed level.
+ *                 0 is slowest, larger values use less CPU.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>, or the
+ *                    encoding speed level is out of bounds.
+ *                   The maximum encoding speed level may be
+ *                    implementation- and encoding mode-specific, and can be
+ *                    obtained via #TH_ENCCTL_GET_SPLEVEL_MAX.
+ * \retval TH_EIMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_SET_SPLEVEL (14)
+/**Gets the current speed level.
+ * The default speed level may vary according to encoder implementation, but if
+ *  this control code is not supported (it returns #TH_EIMPL), the default may
+ *  be assumed to be the slowest available speed (0).
+ * The maximum encoding speed level may be implementation- and encoding
+ *  mode-specific, and can be obtained via #TH_ENCCTL_GET_SPLEVEL_MAX.
+ *
+ * \param[out] _buf <tt>int</tt>: The current encoding speed level.
+ *                  0 is slowest, larger values use less CPU.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>.
+ * \retval TH_EIMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_GET_SPLEVEL (16)
+/**Sets the number of duplicates of the next frame to produce.
+ * Although libtheora can encode duplicate frames very cheaply, it costs some
+ *  amount of CPU to detect them, and a run of duplicates cannot span a
+ *  keyframe boundary.
+ * This control code tells the encoder to produce the specified number of extra
+ *  duplicates of the next frame.
+ * This allows the encoder to make smarter keyframe placement decisions and
+ *  rate control decisions, and reduces CPU usage as well, when compared to
+ *  just submitting the same frame for encoding multiple times.
+ * This setting only applies to the next frame submitted for encoding.
+ * You MUST call th_encode_packetout() repeatedly until it returns 0, or the
+ *  extra duplicate frames will be lost.
+ *
+ * \param[in] _buf <tt>int</tt>: The number of duplicates to produce.
+ *                 If this is negative or zero, no duplicates will be produced.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>, or the
+ *                    number of duplicates is greater than or equal to the
+ *                    maximum keyframe interval.
+ *                   In the latter case, NO duplicate frames will be produced.
+ *                   You must ensure that the maximum keyframe interval is set
+ *                    larger than the maximum number of duplicates you will
+ *                    ever wish to insert prior to encoding.
+ * \retval TH_EIMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_SET_DUP_COUNT (18)
+/**Modifies the default bitrate management behavior.
+ * Use to allow or disallow frame dropping, and to enable or disable capping
+ *  bit reservoir overflows and underflows.
+ * See \ref encctlcodes "the list of available flags".
+ * The flags are set by default to
+ *  <tt>#TH_RATECTL_DROP_FRAMES|#TH_RATECTL_CAP_OVERFLOW</tt>.
+ *
+ * \param[in] _buf <tt>int</tt>: Any combination of
+ *                  \ref ratectlflags "the available flags":
+ *                 - #TH_RATECTL_DROP_FRAMES: Enable frame dropping.
+ *                 - #TH_RATECTL_CAP_OVERFLOW: Don't bank excess bits for later
+ *                    use.
+ *                 - #TH_RATECTL_CAP_UNDERFLOW: Don't try to make up shortfalls
+ *                    later.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt> or rate control
+ *                    is not enabled.
+ * \retval TH_EIMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_SET_RATE_FLAGS (20)
+/**Sets the size of the bitrate management bit reservoir as a function
+ *  of number of frames.
+ * The reservoir size affects how quickly bitrate management reacts to
+ *  instantaneous changes in the video complexity.
+ * Larger reservoirs react more slowly, and provide better overall quality, but
+ *  require more buffering by a client, adding more latency to live streams.
+ * By default, libtheora sets the reservoir to the maximum distance between
+ *  keyframes, subject to a minimum and maximum limit.
+ * This call may be used to increase or decrease the reservoir, increasing or
+ *  decreasing the allowed temporary variance in bitrate.
+ * An implementation may impose some limits on the size of a reservoir it can
+ *  handle, in which case the actual reservoir size may not be exactly what was
+ *  requested.
+ * The actual value set will be returned.
+ *
+ * \param[in]  _buf <tt>int</tt>: Requested size of the reservoir measured in
+ *                   frames.
+ * \param[out] _buf <tt>int</tt>: The actual size of the reservoir set.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(int)</tt>, or rate control
+ *                    is not enabled.  The buffer has an implementation
+ *                    defined minimum and maximum size and the value in _buf
+ *                    will be adjusted to match the actual value set.
+ * \retval TH_EIMPL   Not supported by this implementation in the current
+ *                    encoding mode.*/
+#define TH_ENCCTL_SET_RATE_BUFFER (22)
+/**Enable pass 1 of two-pass encoding mode and retrieve the first pass metrics.
+ * Pass 1 mode must be enabled before the first frame is encoded, and a target
+ *  bitrate must have already been specified to the encoder.
+ * Although this does not have to be the exact rate that will be used in the
+ *  second pass, closer values may produce better results.
+ * The first call returns the size of the two-pass header data, along with some
+ *  placeholder content, and sets the encoder into pass 1 mode implicitly.
+ * This call sets the encoder to pass 1 mode implicitly.
+ * Then, a subsequent call must be made after each call to
+ *  th_encode_ycbcr_in() to retrieve the metrics for that frame.
+ * An additional, final call must be made to retrieve the summary data,
+ *  containing such information as the total number of frames, etc.
+ * This must be stored in place of the placeholder data that was returned
+ *  in the first call, before the frame metrics data.
+ * All of this data must be presented back to the encoder during pass 2 using
+ *  #TH_ENCCTL_2PASS_IN.
+ *
+ * \param[out] <tt>char *</tt>_buf: Returns a pointer to internal storage
+ *              containing the two pass metrics data.
+ *             This storage is only valid until the next call, or until the
+ *              encoder context is freed, and must be copied by the
+ *              application.
+ * \retval >=0       The number of bytes of metric data available in the
+ *                    returned buffer.
+ * \retval TH_EFAULT \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL \a _buf_sz is not <tt>sizeof(char *)</tt>, no target
+ *                    bitrate has been set, or the first call was made after
+ *                    the first frame was submitted for encoding.
+ * \retval TH_EIMPL   Not supported by this implementation.*/
+#define TH_ENCCTL_2PASS_OUT (24)
+/**Submits two-pass encoding metric data collected the first encoding pass to
+ *  the second pass.
+ * The first call must be made before the first frame is encoded, and a target
+ *  bitrate must have already been specified to the encoder.
+ * It sets the encoder to pass 2 mode implicitly; this cannot be disabled.
+ * The encoder may require reading data from some or all of the frames in
+ *  advance, depending on, e.g., the reservoir size used in the second pass.
+ * You must call this function repeatedly before each frame to provide data
+ *  until either a) it fails to consume all of the data presented or b) all of
+ *  the pass 1 data has been consumed.
+ * In the first case, you must save the remaining data to be presented after
+ *  the next frame.
+ * You can call this function with a NULL argument to get an upper bound on
+ *  the number of bytes that will be required before the next frame.
+ *
+ * When pass 2 is first enabled, the default bit reservoir is set to the entire
+ *  file; this gives maximum flexibility but can lead to very high peak rates.
+ * You can subsequently set it to another value with #TH_ENCCTL_SET_RATE_BUFFER
+ *  (e.g., to set it to the keyframe interval for non-live streaming), however,
+ *  you may then need to provide more data before the next frame.
+ *
+ * \param[in] _buf <tt>char[]</tt>: A buffer containing the data returned by
+ *                  #TH_ENCCTL_2PASS_OUT in pass 1.
+ *                 You may pass <tt>NULL</tt> for \a _buf to return an upper
+ *                  bound on the number of additional bytes needed before the
+ *                  next frame.
+ *                 The summary data returned at the end of pass 1 must be at
+ *                  the head of the buffer on the first call with a
+ *                  non-<tt>NULL</tt> \a _buf, and the placeholder data
+ *                  returned at the start of pass 1 should be omitted.
+ *                 After each call you should advance this buffer by the number
+ *                  of bytes consumed.
+ * \retval >0            The number of bytes of metric data required/consumed.
+ * \retval 0             No more data is required before the next frame.
+ * \retval TH_EFAULT     \a _enc_ctx is <tt>NULL</tt>.
+ * \retval TH_EINVAL     No target bitrate has been set, or the first call was
+ *                        made after the first frame was submitted for
+ *                        encoding.
+ * \retval TH_ENOTFORMAT The data did not appear to be pass 1 from a compatible
+ *                        implementation of this library.
+ * \retval TH_EBADHEADER The data was invalid; this may be returned when
+ *                        attempting to read an aborted pass 1 file that still
+ *                        has the placeholder data in place of the summary
+ *                        data.
+ * \retval TH_EIMPL       Not supported by this implementation.*/
+#define TH_ENCCTL_2PASS_IN (26)
+/**Sets the current encoding quality.
+ * This is only valid so long as no bitrate has been specified, either through
+ *  the #th_info struct used to initialize the encoder or through
+ *  #TH_ENCCTL_SET_BITRATE (this restriction may be relaxed in a future
+ *  version).
+ * If it is set before the headers are emitted, the target quality encoded in
+ *  them will be updated.
+ *
+ * \param[in] _buf <tt>int</tt>: The new target quality, in the range 0...63,
+ *                  inclusive.
+ * \retval 0             Success.
+ * \retval TH_EFAULT     \a _enc_ctx or \a _buf is <tt>NULL</tt>.
+ * \retval TH_EINVAL     A target bitrate has already been specified, or the
+ *                        quality index was not in the range 0...63.
+ * \retval TH_EIMPL       Not supported by this implementation.*/
+#define TH_ENCCTL_SET_QUALITY (28)
+/**Sets the current encoding bitrate.
+ * Once a bitrate is set, the encoder must use a rate-controlled mode for all
+ *  future frames (this restriction may be relaxed in a future version).
+ * If it is set before the headers are emitted, the target bitrate encoded in
+ *  them will be updated.
+ * Due to the buffer delay, the exact bitrate of each section of the encode is
+ *  not guaranteed.
+ * The encoder may have already used m