Merge mozilla-central into electrolysis.
authorBenjamin Smedberg <benjamin@smedbergs.us>
Mon, 14 Dec 2009 08:01:18 -0500
changeset 36176 33bdf9d466ec5d9d30b71ca53c8fdfeacd96d1da
parent 36175 4778341de66c04612e42500507411902431227b3 (current diff)
parent 35726 27937722da69ad0e8fd140a00671413068226a5b (diff)
child 36177 6c19a6a23583a523ef1ced884555f53c005f539f
push idunknown
push userunknown
push dateunknown
milestone1.9.3a1pre
Merge mozilla-central into electrolysis.
browser/installer/package-manifest.in
config/build-list.pl
configure.in
gfx/cairo/endian.patch
js/src/xpconnect/src/xpcjsruntime.cpp
js/src/xpconnect/src/xpcprivate.h
modules/plugin/base/src/nsNPAPIPluginInstance.cpp
modules/plugin/test/testplugin/nptest_windows.cpp
toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler_test.cc
toolkit/crashreporter/google-breakpad/src/client/linux/handler/linux_thread.cc
toolkit/crashreporter/google-breakpad/src/client/linux/handler/linux_thread.h
toolkit/crashreporter/google-breakpad/src/client/linux/handler/linux_thread_test.cc
toolkit/crashreporter/google-breakpad/src/client/linux/handler/minidump_generator.cc
toolkit/crashreporter/google-breakpad/src/client/linux/handler/minidump_generator.h
toolkit/crashreporter/google-breakpad/src/client/linux/handler/minidump_test.cc
toolkit/toolkit-makefiles.sh
toolkit/xre/Makefile.in
widget/src/gtk2/nsWindow.cpp
widget/src/windows/Makefile.in
widget/src/windows/nsWindow.cpp
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -280,17 +280,17 @@ nsIntRect nsHyperTextAccessible::GetBoun
     // are returning.
     nsIntRect frameScreenRect = frame->GetScreenRectExternal();
 
     // Get the length of the substring in this frame that we want the bounds for
     PRInt32 startFrameTextOffset, endFrameTextOffset;
     frame->GetOffsets(startFrameTextOffset, endFrameTextOffset);
     PRInt32 frameTotalTextLength = endFrameTextOffset - startFrameTextOffset;
     PRInt32 seekLength = endContentOffset - startContentOffset;
-    PRInt32 frameSubStringLength = PR_MIN(frameTotalTextLength - startContentOffsetInFrame, seekLength);
+    PRInt32 frameSubStringLength = NS_MIN(frameTotalTextLength - startContentOffsetInFrame, seekLength);
 
     // Add the point where the string starts to the frameScreenRect
     nsPoint frameTextStartPoint;
     rv = frame->GetPointFromOffset(startContentOffset, &frameTextStartPoint);
     NS_ENSURE_SUCCESS(rv, nsIntRect());
     frameScreenRect.x += context->AppUnitsToDevPixels(frameTextStartPoint.x);
 
     // Use the point for the end offset to calculate the width
--- a/browser/base/content/browser-menubar.inc
+++ b/browser/base/content/browser-menubar.inc
@@ -489,23 +489,23 @@
                           key="showAllHistoryKb"
 #endif
                           command="Browser:ShowAllHistory"/>
                 <menuseparator id="startHistorySeparator"/>
                 <menuseparator id="endHistorySeparator" builder="end"/>
                 <menu id="historyUndoMenu"
                       label="&historyUndoMenu.label;"
                       disabled="true">
-                  <menupopup id="historyUndoPopup"
+                  <menupopup id="historyUndoPopup" placespopup="true"
                              onpopupshowing="HistoryMenu.populateUndoSubmenu();"/>
                 </menu>
                 <menu id="historyUndoWindowMenu"
                       label="&historyUndoWindowMenu.label;"
                       disabled="true">
-                  <menupopup id="historyUndoWindowPopup"
+                  <menupopup id="historyUndoWindowPopup" placespopup="true"
                              onpopupshowing="HistoryMenu.populateUndoWindowSubmenu();"/>
                 </menu>
               </menupopup>
             </menu>
 
   <menu id="bookmarksMenu"
         label="&bookmarksMenu.label;"
         accesskey="&bookmarksMenu.accesskey;"
--- a/browser/base/content/browser-places.js
+++ b/browser/base/content/browser-places.js
@@ -632,16 +632,24 @@ var HistoryMenu = {
         // don't initiate a connection just to fetch a favicon (see bug 467828)
         if (/^https?:/.test(iconURL))
           iconURL = "moz-anno:favicon:" + iconURL;
         m.setAttribute("image", iconURL);
       }
       m.setAttribute("class", "menuitem-iconic bookmark-item");
       m.setAttribute("value", i);
       m.setAttribute("oncommand", "undoCloseTab(" + i + ");");
+
+      // Set the targetURI attribute so it will be shown in tooltip and statusbar.
+      // SessionStore uses one-based indexes, so we need to normalize them.
+      let tabData = undoItems[i].state;
+      let activeIndex = (tabData.index || tabData.entries.length) - 1;
+      if (activeIndex >= 0 && tabData.entries[activeIndex])
+        m.setAttribute("targetURI", tabData.entries[activeIndex].url);
+
       m.addEventListener("click", this._undoCloseMiddleClick, false);
       if (i == 0)
         m.setAttribute("key", "key_undoCloseTab");
       undoPopup.appendChild(m);
     }
 
     // "Restore All Tabs"
     var strings = gNavigatorBundle;
@@ -705,16 +713,23 @@ var HistoryMenu = {
         let iconURL = selectedTab.attributes.image;
         // don't initiate a connection just to fetch a favicon (see bug 467828)
         if (/^https?:/.test(iconURL))
           iconURL = "moz-anno:favicon:" + iconURL;
         m.setAttribute("image", iconURL);
       }
       m.setAttribute("class", "menuitem-iconic bookmark-item");
       m.setAttribute("oncommand", "undoCloseWindow(" + i + ");");
+
+      // Set the targetURI attribute so it will be shown in tooltip and statusbar.
+      // SessionStore uses one-based indexes, so we need to normalize them.
+      let activeIndex = (selectedTab.index || selectedTab.entries.length) - 1;
+      if (activeIndex >= 0 && selectedTab.entries[activeIndex])
+        m.setAttribute("targetURI", selectedTab.entries[activeIndex].url);
+
       if (i == 0)
         m.setAttribute("key", "key_undoCloseWindow");
       undoPopup.appendChild(m);
     }
 
     // "Open All in Windows"
     undoPopup.appendChild(document.createElement("menuseparator"));
     let m = undoPopup.appendChild(document.createElement("menuitem"));
--- a/browser/base/content/browser-tabPreviews.js
+++ b/browser/base/content/browser-tabPreviews.js
@@ -259,23 +259,17 @@ var ctrlTab = {
     this.showAllButton.label =
       PluralForm.get(this.tabCount, showAllLabel).replace("#1", this.tabCount);
   },
 
   updatePreview: function ctrlTab_updatePreview(aPreview, aTab) {
     if (aPreview == this.showAllButton)
       return;
 
-    if ((aPreview._tab || null) != aTab) {
-      if (aPreview._tab)
-        aPreview._tab.removeEventListener("DOMAttrModified", this, false);
-      aPreview._tab = aTab;
-      if (aTab)
-        aTab.addEventListener("DOMAttrModified", this, false);
-    }
+    aPreview._tab = aTab;
 
     if (aPreview.firstChild)
       aPreview.removeChild(aPreview.firstChild);
     if (aTab) {
       let canvasWidth = this.canvasWidth;
       let canvasHeight = this.canvasHeight;
       aPreview.appendChild(tabPreviews.get(aTab));
       aPreview.setAttribute("label", aTab.label);
@@ -500,18 +494,18 @@ var ctrlTab = {
       setTimeout(function (selected) {
         selected.focus();
       }, 0, this.selected);
     }
   },
 
   handleEvent: function ctrlTab_handleEvent(event) {
     switch (event.type) {
-      case "DOMAttrModified":
-        // tab attribute modified (e.g. label, crop, busy, image)
+      case "TabAttrModified":
+        // tab attribute modified (e.g. label, crop, busy, image, selected)
         for (let i = this.previews.length - 1; i >= 0; i--) {
           if (this.previews[i]._tab && this.previews[i]._tab == event.target) {
             this.updatePreview(this.previews[i], event.target);
             break;
           }
         }
         break;
       case "TabSelect":
@@ -536,16 +530,17 @@ var ctrlTab = {
     }
   },
 
   _init: function ctrlTab__init(enable) {
     var toggleEventListener = enable ? "addEventListener" : "removeEventListener";
 
     var tabContainer = gBrowser.tabContainer;
     tabContainer[toggleEventListener]("TabOpen", this, false);
+    tabContainer[toggleEventListener]("TabAttrModified", this, false);
     tabContainer[toggleEventListener]("TabSelect", this, false);
     tabContainer[toggleEventListener]("TabClose", this, false);
 
     document[toggleEventListener]("keypress", this, false);
     gBrowser.mTabBox.handleCtrlTab = !enable;
 
     // If we're not running, hide the "Show All Tabs" menu item,
     // as Shift+Ctrl+Tab will be handled by the tab bar.
@@ -585,25 +580,27 @@ var allTabs = {
       return;
     this._initiated = true;
 	
     Array.forEach(gBrowser.mTabs, function (tab) {
       this._addPreview(tab);
     }, this);
 
     gBrowser.tabContainer.addEventListener("TabOpen", this, false);
+    gBrowser.tabContainer.addEventListener("TabAttrModified", this, false);
     gBrowser.tabContainer.addEventListener("TabMove", this, false);
     gBrowser.tabContainer.addEventListener("TabClose", this, false);
   },
 
   uninit: function allTabs_uninit() {
     if (!this._initiated)
       return;
 
     gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
+    gBrowser.tabContainer.removeEventListener("TabAttrModified", this, false);
     gBrowser.tabContainer.removeEventListener("TabMove", this, false);
     gBrowser.tabContainer.removeEventListener("TabClose", this, false);
 
     while (this.container.hasChildNodes())
       this.container.removeChild(this.container.firstChild);
 
     this._initiated = false;
   },
@@ -656,23 +653,21 @@ var allTabs = {
           tabstring = decodeURI(tabstring);
         } catch (e) {}
         tabstring = tab.label + " " + tab.label.toLocaleLowerCase() + " " + tabstring;
         for (let i = 0; i < filter.length; i++)
           matches += tabstring.indexOf(filter[i]) > -1;
       }
       if (matches < filter.length) {
         preview.hidden = true;
-        tab.removeEventListener("DOMAttrModified", this, false);
       }
       else {
         this._visible++;
         this._updatePreview(preview);
         preview.hidden = false;
-        tab.addEventListener("DOMAttrModified", this, false);
       }
     }, this);
 
     this._reflow();
   },
 
   open: function allTabs_open() {
     this.init();
@@ -700,36 +695,34 @@ var allTabs = {
     this.filterField.setAttribute("emptytext", this.filterField.tooltipText);
 
     this.panel.addEventListener("keypress", this, false);
     this.panel.addEventListener("keypress", this, true);
     this._browserCommandSet.addEventListener("command", this, false);
   },
 
   suspendGUI: function allTabs_suspendGUI() {
-    Array.forEach(this.container.childNodes, function (preview) {
-      preview._tab.removeEventListener("DOMAttrModified", this, false);
-    }, this);
-
     this.filterField.removeAttribute("emptytext");
     this.filterField.value = "";
     this._currentFilter = null;
 
     this._updateTabCloseButton();
 
     this.panel.removeEventListener("keypress", this, false);
     this.panel.removeEventListener("keypress", this, true);
     this._browserCommandSet.removeEventListener("command", this, false);
   },
 
   handleEvent: function allTabs_handleEvent(event) {
     switch (event.type) {
-      case "DOMAttrModified":
+      case "TabAttrModified":
         // tab attribute modified (e.g. label, crop, busy, image)
-        this._updatePreview(this._getPreview(event.target));
+        let preview = this._getPreview(event.target);
+        if (!preview.hidden)
+          this._updatePreview(preview);
         break;
       case "TabOpen":
         if (this.isOpen)
           this.close();
         this._addPreview(event.target);
         break;
       case "TabMove":
         if (event.target.nextSibling)
@@ -827,17 +820,16 @@ var allTabs = {
     var preview = document.createElement("button");
     preview.className = "allTabs-preview";
     preview._tab = aTab;
     return this.container.appendChild(preview);
   },
 
   _removePreview: function allTabs_removePreview(aPreview) {
     var updateUI = (this.isOpen && !aPreview.hidden);
-    aPreview._tab.removeEventListener("DOMAttrModified", this, false);
     aPreview._tab = null;
     this.container.removeChild(aPreview);
     if (updateUI) {
       this._visible--;
       this._reflow();
       this.filterField.focus();
     }
   },
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -1294,24 +1294,22 @@ function delayedStartup(isLoadingBlank, 
     Components.utils.reportError("Failed to init content pref service:\n" + ex);
   }
 
   let NP = {};
   Cu.import("resource:///modules/NetworkPrioritizer.jsm", NP);
   NP.trackBrowserWindow(window);
 
   // initialize the session-restore service (in case it's not already running)
-  if (document.documentElement.getAttribute("windowtype") == "navigator:browser") {
-    try {
-      var ss = Cc["@mozilla.org/browser/sessionstore;1"].
-               getService(Ci.nsISessionStore);
-      ss.init(window);
-    } catch(ex) {
-      dump("nsSessionStore could not be initialized: " + ex + "\n");
-    }
+  try {
+    Cc["@mozilla.org/browser/sessionstore;1"]
+      .getService(Ci.nsISessionStore)
+      .init(window);
+  } catch (ex) {
+    dump("nsSessionStore could not be initialized: " + ex + "\n");
   }
 
   // bookmark-all-tabs command
   gBookmarkAllTabsHandler.init();
 
   // Attach a listener to watch for "command" events bubbling up from error
   // pages.  This lets us fix bugs like 401575 which require error page UI to
   // do privileged things, without letting error pages have any privilege
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -142,17 +142,17 @@ nsContextMenu.prototype = {
       isMailtoInternal = (!mailtoHandler.alwaysAskBeforeHandling &&
                           mailtoHandler.preferredAction == Ci.nsIHandlerInfo.useHelperApp &&
                           (mailtoHandler.preferredApplicationHandler instanceof Ci.nsIWebHandlerApp));
     }
 
     // Time to do some bad things and see if we've highlighted a URL that
     // isn't actually linked.
     var onPlainTextLink = false;
-    if (this.isTextSelected) {
+    if (this.isTextSelected && !this.onLink) {
       // Ok, we have some text, let's figure out if it looks like a URL.
       let selection =  document.commandDispatcher.focusedWindow
                                .getSelection();
       let linkText = selection.toString().trim();
       let uri;
       if (/^(?:https?|ftp):/i.test(linkText)) {
         try {
           uri = makeURI(linkText);
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -726,16 +726,17 @@
         <parameter name="aTab"/>
         <body>
           <![CDATA[
             var browser = this.getBrowserForTab(aTab);
             if (!aTab.hasAttribute("busy") && browser.mIconURL)
               aTab.setAttribute("image", browser.mIconURL);
             else
               aTab.removeAttribute("image");
+            this._tabAttrModified(aTab);
           ]]>
         </body>
       </method>
 
       <method name="shouldLoadFavIcon">
         <parameter name="aURI"/>
         <body>
           <![CDATA[
@@ -861,19 +862,21 @@
       <method name="updateCurrentBrowser">
         <parameter name="aForceUpdate"/>
         <body>
           <![CDATA[
             var newBrowser = this.getBrowserAtIndex(this.mTabContainer.selectedIndex);
             if (this.mCurrentBrowser == newBrowser && !aForceUpdate)
               return;
 
+            var oldTab = this.mCurrentTab;
+
             // Preview mode should not reset the owner
-            if (!this._previewMode && this.mCurrentTab != this.selectedTab)
-              this.mCurrentTab.owner = null;
+            if (!this._previewMode && oldTab != this.selectedTab)
+              oldTab.owner = null;
 
             this._lastRelatedTab = null;
 
             var oldBrowser = this.mCurrentBrowser;
             if (oldBrowser)
               oldBrowser.setAttribute("type", "content-targetable");
 
             var updatePageReport = false;
@@ -961,25 +964,39 @@
             // that might rely upon the other changes suppressed.
             // Focus is suppressed in the event that the main browser window is minimized - focusing a tab would restore the window
             if (!this._previewMode) {
               // We've selected the new tab, so go ahead and notify listeners.
               var event = document.createEvent("Events");
               event.initEvent("TabSelect", true, false);
               this.mCurrentTab.dispatchEvent(event);
 
+              this._tabAttrModified(oldTab);
+              this._tabAttrModified(this.mCurrentTab);
+
               // Change focus to the new browser unless the findbar is focused.
               if (gFindBar.hidden ||
                   gFindBar.getElement("findbar-textbox").getAttribute("focused") != "true")
                 newBrowser.focus();
             }
           ]]>
         </body>
       </method>
 
+      <method name="_tabAttrModified">
+        <parameter name="aTab"/>
+        <body><![CDATA[
+          // This event should be dispatched when any of these attributes change:
+          // label, crop, busy, image, selected
+          var event = document.createEvent("Events");
+          event.initEvent("TabAttrModified", true, false);
+          aTab.dispatchEvent(event);
+        ]]></body>
+      </method>
+
       <method name="onTabClick">
         <parameter name="event"/>
         <body>
           <![CDATA[
             if (event.button != 1 || event.target.localName != 'tab')
               return;
 
             if (this.mTabs.length > 1 ||
@@ -1010,16 +1027,17 @@
       </method>
 
       <method name="setTabTitleLoading">
         <parameter name="aTab"/>
         <body>
           <![CDATA[
             aTab.label = this.mStringBundle.getString("tabs.loading");
             aTab.setAttribute("crop", "end");
+            this._tabAttrModified(aTab);
           ]]>
         </body>
       </method>
 
       <method name="setTabTitle">
         <parameter name="aTab"/>
         <body>
           <![CDATA[
@@ -1050,16 +1068,17 @@
                 crop = "center";
 
               } else // Still no title?  Fall back to our untitled string.
                 title = this.mStringBundle.getString("tabs.untitled");
             }
 
             aTab.label = title;
             aTab.setAttribute("crop", crop);
+            this._tabAttrModified(aTab);
           ]]>
         </body>
       </method>
 
       <method name="setStripVisibilityTo">
         <parameter name="aShow"/>
         <body>
         <![CDATA[
@@ -1719,16 +1738,17 @@
 
             // Workarounds for bug 458697
             // Icon might have been set on DOMLinkAdded, don't override that.
             if (!ourBrowser.mIconURL && aOtherTab.linkedBrowser.mIconURL)
               this.setIcon(aOurTab, aOtherTab.linkedBrowser.mIconURL);
             var isBusy = aOtherTab.hasAttribute("busy");
             if (isBusy) {
               aOurTab.setAttribute("busy", "true");
+              this._tabAttrModified(aOurTab);
               if (aOurTab == this.selectedTab)
                 this.mIsBusy = true;
             }
 
             // Swap the docshells
             ourBrowser.swapDocShells(aOtherTab.linkedBrowser);
 
             // Finish tearing down the tab that's going away.
@@ -3259,47 +3279,32 @@
     </handlers>
   </binding>
 
   <binding id="tabbrowser-alltabs-popup"
            extends="chrome://global/content/bindings/popup.xml#popup">
     <implementation implements="nsIDOMEventListener">
       <method name="_menuItemOnCommand">
         <parameter name="aEvent"/>
-
         <body><![CDATA[
           var tabcontainer = document.getBindingParent(this);
           tabcontainer.selectedItem = aEvent.target.tab;
         ]]></body>
       </method>
 
       <method name="_tabOnAttrModified">
         <parameter name="aEvent"/>
         <body><![CDATA[
-          var menuItem = aEvent.target.mCorrespondingMenuitem;
-          if (menuItem) {
-            var attrName = aEvent.attrName;
-            switch (attrName) {
-              case "label":
-              case "crop":
-              case "busy":
-              case "image":
-              case "selected":
-                if (aEvent.attrChange == aEvent.REMOVAL)
-                  menuItem.removeAttribute(attrName);
-                else
-                  menuItem.setAttribute(attrName, aEvent.newValue);
-            }
-          }
+          var tab = aEvent.target;
+          this._setMenuitemAttributes(tab.mCorrespondingMenuitem, tab);
         ]]></body>
       </method>
 
       <method name="_tabOnTabClose">
         <parameter name="aEvent"/>
-
         <body><![CDATA[
           var menuItem = aEvent.target.mCorrespondingMenuitem;
           if (menuItem)
             this.removeChild(menuItem);
         ]]></body>
       </method>
 
       <method name="handleEvent">
@@ -3307,17 +3312,17 @@
         <body><![CDATA[
           if (!aEvent.isTrusted)
             return;
 
           switch (aEvent.type) {
             case "command":
               this._menuItemOnCommand(aEvent);
               break;
-            case "DOMAttrModified":
+            case "TabAttrModified":
               this._tabOnAttrModified(aEvent);
               break;
             case "TabClose":
               this._tabOnTabClose(aEvent);
               break;
             case "TabOpen":
               this._createTabMenuItem(aEvent.originalTarget);
               break;
@@ -3340,83 +3345,94 @@
             var curTabBO = this.childNodes[i].tab.boxObject;
             if (curTabBO.screenX >= tabstripBO.screenX &&
                 curTabBO.screenX + curTabBO.width <= tabstripBO.screenX + tabstripBO.width)
               this.childNodes[i].setAttribute("tabIsVisible", "true"); 
             else
               this.childNodes[i].removeAttribute("tabIsVisible");
           }
         ]]></body>
-
       </method>
 
       <method name="_createTabMenuItem">
         <parameter name="aTab"/>
         <body><![CDATA[
           var menuItem = document.createElementNS(
             "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", 
             "menuitem");
 
           menuItem.setAttribute("class", "menuitem-iconic alltabs-item");
 
-          menuItem.setAttribute("label", aTab.label);
-          menuItem.setAttribute("crop", aTab.getAttribute("crop"));
-          menuItem.setAttribute("image", aTab.getAttribute("image"));
-
-          if (aTab.hasAttribute("busy"))
-            menuItem.setAttribute("busy", aTab.getAttribute("busy"));
-          if (aTab.selected)
-            menuItem.setAttribute("selected", "true");
+          this._setMenuitemAttributes(menuItem, aTab);
 
           // Keep some attributes of the menuitem in sync with its
           // corresponding tab (e.g. the tab label)
           aTab.mCorrespondingMenuitem = menuItem;
-          aTab.addEventListener("DOMAttrModified", this, false);
-          aTab.addEventListener("TabClose", this, false);
           menuItem.tab = aTab;
           menuItem.addEventListener("command", this, false);
 
           this.appendChild(menuItem);
           return menuItem;
         ]]></body>
       </method>
+
+      <method name="_setMenuitemAttributes">
+        <parameter name="aMenuitem"/>
+        <parameter name="aTab"/>
+        <body><![CDATA[
+          aMenuitem.setAttribute("label", aTab.label);
+          aMenuitem.setAttribute("crop", aTab.getAttribute("crop"));
+          aMenuitem.setAttribute("image", aTab.getAttribute("image"));
+
+          if (aTab.hasAttribute("busy"))
+            aMenuitem.setAttribute("busy", aTab.getAttribute("busy"));
+          else
+            aMenuitem.removeAttribute("busy");
+
+          if (aTab.selected)
+            aMenuitem.setAttribute("selected", "true");
+          else
+            aMenuitem.removeAttribute("selected");
+        ]]></body>
+      </method>
     </implementation>
 
     <handlers>
       <handler event="popupshowing">
-
       <![CDATA[
         // set up the menu popup
         var tabcontainer = document.getBindingParent(this);
         var tabs = tabcontainer.childNodes;
 
         // Listen for changes in the tab bar.
         tabcontainer.addEventListener("TabOpen", this, false);
+        tabcontainer.addEventListener("TabAttrModified", this, false);
+        tabcontainer.addEventListener("TabClose", this, false);
         tabcontainer.mTabstrip.addEventListener("scroll", this, false);
 
         for (var i = 0; i < tabs.length; i++) {
           this._createTabMenuItem(tabs[i]);
         }
         this._updateTabsVisibilityStatus();
       ]]></handler>
 
       <handler event="popuphidden">
       <![CDATA[
         // clear out the menu popup and remove the listeners
         while (this.hasChildNodes()) {
           var menuItem = this.lastChild;
           menuItem.removeEventListener("command", this, false);
-          menuItem.tab.removeEventListener("DOMAttrModified", this, false);
-          menuItem.tab.removeEventListener("TabClose", this, false);
           menuItem.tab.mCorrespondingMenuitem = null;
           this.removeChild(menuItem);
         }
         var tabcontainer = document.getBindingParent(this);
         tabcontainer.mTabstrip.removeEventListener("scroll", this, false);
         tabcontainer.removeEventListener("TabOpen", this, false);
+        tabcontainer.removeEventListener("TabAttrModified", this, false);
+        tabcontainer.removeEventListener("TabClose", this, false);
       ]]></handler>
 
       <handler event="DOMMenuItemActive">
       <![CDATA[
         var tab = event.target.tab;
         if (tab) {
           var statusText = tab.linkedBrowser.currentURI.spec;
           if (statusText == "about:blank") {
--- a/browser/base/content/test/browser_plainTextLinks.js
+++ b/browser/base/content/test/browser_plainTextLinks.js
@@ -1,51 +1,56 @@
 let doc, range, selection;
 function setSelection(el1, el2, index1, index2) {
   selection.removeAllRanges();
   range.setStart(el1, index1);
   range.setEnd(el2, index2);
   selection.addRange(range);
 }
 
-function initContextMenu() {
-  document.popupNode = doc.getElementsByTagName("DIV")[0];
+function initContextMenu(aNode) {
+  document.popupNode = aNode;
   let contentAreaContextMenu = document.getElementById("contentAreaContextMenu");
   let contextMenu = new nsContextMenu(contentAreaContextMenu, gBrowser);
   return contextMenu;
 }
 
-function testExpected(expected, msg) {
-  initContextMenu();
+function testExpected(expected, msg, aNode) {
+  let popupNode = aNode || doc.getElementsByTagName("DIV")[0];
+  initContextMenu(popupNode);
   let linkMenuItem = document.getElementById("context-openlinkincurrent");
   is(linkMenuItem.hidden, expected, msg);
 }
 
-function testLinkExpected(expected, msg) {
-  let contextMenu = initContextMenu();
+function testLinkExpected(expected, msg, aNode) {
+  let popupNode = aNode || doc.getElementsByTagName("DIV")[0];
+  let contextMenu = initContextMenu(popupNode);
   is(contextMenu.linkURL, expected, msg);
 }
 
 function runSelectionTests() {
   let mainDiv = doc.createElement("div");
   let div = doc.createElement("div");
   let div2 = doc.createElement("div");
   let span1 = doc.createElement("span");
   let span2 = doc.createElement("span");
   let span3 = doc.createElement("span");
+  let span4 = doc.createElement("span");
   let p1 = doc.createElement("p");
   let p2 = doc.createElement("p");
   span1.textContent = "http://index.";
   span2.textContent = "example.com example.com";
   span3.textContent = " - Test";
+  span4.innerHTML = "<a href='http://www.example.com'>http://www.example.com/example</a>";
   p1.textContent = "mailto:test.com ftp.example.com";
   p2.textContent = "example.com   -";
   div.appendChild(span1);
   div.appendChild(span2);
   div.appendChild(span3);
+  div.appendChild(span4);
   div.appendChild(p1);
   div.appendChild(p2);
   let p3 = doc.createElement("p");
   p3.textContent = "main.example.com";
   div2.appendChild(p3);
   mainDiv.appendChild(div);
   mainDiv.appendChild(div2);
   doc.body.appendChild(mainDiv);
@@ -70,16 +75,18 @@ function runSelectionTests() {
   testExpected(true, "Link options should not show for mailto: links");
   setSelection(p1.firstChild, p1.firstChild, 16, 31);
   testExpected(false, "Link options should show for ftp.example.com");
   testLinkExpected("ftp://ftp.example.com/", "ftp.example.com should be preceeded with ftp://");
   setSelection(p2.firstChild, p2.firstChild, 0, 14);
   testExpected(false, "Link options should show for www.example.com  ");
   selection.selectAllChildren(div2);
   testExpected(false, "Link options should show for triple-click selections");
+  selection.selectAllChildren(span4);
+  testLinkExpected("http://www.example.com/", "Linkified text should open the correct link", span4.firstChild);
   gBrowser.removeCurrentTab();
   finish();
 }
 
 function test() {
   waitForExplicitFinish();
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function() {
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -1196,18 +1196,26 @@ GeolocationPrompt.prototype = {
               callback: function(notification) {
                   var elements = notification.getElementsByClassName("rememberChoice");
                   if (elements.length && elements[0].checked)
                       setPagePermission(request.requestingURI, false);
                   request.cancel();
               },
           }];
       
-      var message = browserBundle.formatStringFromName("geolocation.siteWantsToKnow",
-                                                       [request.requestingURI.host], 1);      
+      var message;
+
+      // Different message/info if it is a local file
+      if (request.requestingURI.schemeIs("file")) {
+        message = browserBundle.formatStringFromName("geolocation.fileWantsToKnow",
+                                                     [request.requestingURI.path], 1);
+      } else {
+        message = browserBundle.formatStringFromName("geolocation.siteWantsToKnow",
+                                                     [request.requestingURI.host], 1);
+      }
 
       var newBar = notificationBox.appendNotification(message,
                                                       "geolocation",
                                                       "chrome://browser/skin/Geo.png",
                                                       notificationBox.PRIORITY_INFO_HIGH,
                                                       buttons);
 
       // For whatever reason, if we do this immediately
@@ -1215,17 +1223,24 @@ GeolocationPrompt.prototype = {
       // element does not show up in the notification
       // bar.
       function geolocation_hacks_to_notification () {
 
         // Never show a remember checkbox inside the private browsing mode
         var inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
                                 getService(Ci.nsIPrivateBrowsingService).
                                 privateBrowsingEnabled;
-        if (!inPrivateBrowsing) {
+
+        // don't show "Remember for this site" checkbox for file:
+        var host;
+        try {
+            host = request.requestingURI.host;
+        } catch (ex) {}
+
+        if (!inPrivateBrowsing && host) {
           var checkbox = newBar.ownerDocument.createElementNS(XULNS, "checkbox");
           checkbox.className = "rememberChoice";
           checkbox.setAttribute("label", browserBundle.GetStringFromName("geolocation.remember"));
           checkbox.setAttribute("accesskey", browserBundle.GetStringFromName("geolocation.remember.accesskey"));
           newBar.appendChild(checkbox);
         }
 
         var link = newBar.ownerDocument.createElementNS(XULNS, "label");
--- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
+++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js
@@ -33,16 +33,20 @@
 # 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 *****
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
+#ifndef XP_WIN
+#define BROKEN_WM_Z_ORDER
+#endif
+
 ////////////////////////////////////////////////////////////////////////////////
 //// Utilities
 
 /**
  * Returns true if the string passed in is part of the root domain of the
  * current string.  For example, if this is "www.mozilla.org", and we pass in
  * "mozilla.org", this will return true.  It would return false the other way
  * around.
@@ -323,39 +327,74 @@ PrivateBrowsingService.prototype = {
     let cancelLeave = Cc["@mozilla.org/supports-PRBool;1"].
                       createInstance(Ci.nsISupportsPRBool);
     cancelLeave.data = false;
     this._obs.notifyObservers(cancelLeave, "private-browsing-cancel-vote", "exit");
     return !cancelLeave.data;
   },
 
   _getBrowserWindow: function PBS__getBrowserWindow() {
-    return Cc["@mozilla.org/appshell/window-mediator;1"].
-           getService(Ci.nsIWindowMediator).
-           getMostRecentWindow("navigator:browser");
+    var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
+             getService(Ci.nsIWindowMediator);
+
+    var win = wm.getMostRecentWindow("navigator:browser");
+
+    // We don't just return |win| now because of bug 528706.
+
+    if (!win)
+      return null;
+    if (!win.closed)
+      return win;
+
+#ifdef BROKEN_WM_Z_ORDER
+    win = null;
+    var windowsEnum = wm.getEnumerator("navigator:browser");
+    // this is oldest to newest, so this gets a bit ugly
+    while (windowsEnum.hasMoreElements()) {
+      let nextWin = windowsEnum.getNext();
+      if (!nextWin.closed)
+        win = nextWin;
+    }
+    return win;
+#else
+    var windowsEnum = wm.getZOrderDOMWindowEnumerator("navigator:browser", true);
+    while (windowsEnum.hasMoreElements()) {
+      win = windowsEnum.getNext();
+      if (!win.closed)
+        return win;
+    }
+    return null;
+#endif
   },
 
   _ensureCanCloseWindows: function PBS__ensureCanCloseWindows() {
     // whether we should save and close the current session
     this._saveSession = true;
     try {
       if (this._prefs.getBoolPref("browser.privatebrowsing.keep_current_session")) {
         this._saveSession = false;
         return;
       }
     } catch (ex) {}
 
     let windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
                          getService(Ci.nsIWindowMediator);
-    let windowsEnum = windowMediator.getXULWindowEnumerator("navigator:browser");
+    let windowsEnum = windowMediator.getEnumerator("navigator:browser");
 
     while (windowsEnum.hasMoreElements()) {
-      let win = windowsEnum.getNext().QueryInterface(Ci.nsIXULWindow);
-      if (win.docShell.contentViewer.permitUnload(true))
-        this._windowsToClose.push(win);
+      let win = windowsEnum.getNext();
+      if (win.closed)
+        continue;
+      let xulWin = win.QueryInterface(Ci.nsIInterfaceRequestor).
+                   getInterface(Ci.nsIWebNavigation).
+                   QueryInterface(Ci.nsIDocShellTreeItem).
+                   treeOwner.QueryInterface(Ci.nsIInterfaceRequestor).
+                   getInterface(Ci.nsIXULWindow);
+      if (xulWin.docShell.contentViewer.permitUnload(true))
+        this._windowsToClose.push(xulWin);
       else
         throw Cr.NS_ERROR_ABORT;
     }
   },
 
   _closePageInfoWindows: function PBS__closePageInfoWindows() {
     let pageInfoEnum = Cc["@mozilla.org/appshell/window-mediator;1"].
                        getService(Ci.nsIWindowMediator).
--- a/browser/components/sessionstore/src/nsSessionStore.js
+++ b/browser/components/sessionstore/src/nsSessionStore.js
@@ -181,19 +181,16 @@ SessionStoreService.prototype = {
   _recentCrashes: 0,
 
   // whether we are in private browsing mode
   _inPrivateBrowsing: false,
 
   // whether we clearing history on shutdown
   _clearingOnShutdown: false,
 
-  // List of windows that are being closed during setBrowserState.
-  _closingWindows: [],
-
 #ifndef XP_MACOSX
   // whether the last window was closed and should be restored
   _restoreLastWindow: false,
 #endif
 
 /* ........ Global Event Handlers .............. */
 
   /**
@@ -335,27 +332,19 @@ SessionStoreService.prototype = {
     // for event listeners
     var _this = this;
 
     switch (aTopic) {
     case "domwindowopened": // catch new windows
       aSubject.addEventListener("load", function(aEvent) {
         aEvent.currentTarget.removeEventListener("load", arguments.callee, false);
         _this.onLoad(aEvent.currentTarget);
-        }, false);
+      }, false);
       break;
     case "domwindowclosed": // catch closed windows
-      if (this._closingWindows.length > 0) {
-        let index = this._closingWindows.indexOf(aSubject);
-        if (index != -1) {
-          this._closingWindows.splice(index, 1);
-          if (this._closingWindows.length == 0)
-            this._sendRestoreCompletedNotifications(true);
-        }
-      }
       this.onClose(aSubject);
       break;
     case "quit-application-requested":
       // get a current snapshot of all windows
       this._forEachBrowserWindow(function(aWindow) {
         this._collectWindowData(aWindow);
       });
       this._dirtyWindows = [];
@@ -896,47 +885,48 @@ SessionStoreService.prototype = {
 
 /* ........ nsISessionStore API .............. */
 
   getBrowserState: function sss_getBrowserState() {
     return this._toJSONString(this._getCurrentState());
   },
 
   setBrowserState: function sss_setBrowserState(aState) {
+    this._handleClosedWindows();
+
     try {
       var state = this._safeEval("(" + aState + ")");
     }
     catch (ex) { /* invalid state object - don't restore anything */ }
     if (!state || !state.windows)
       throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
 
     this._browserSetState = true;
 
     var window = this._getMostRecentBrowserWindow();
     if (!window) {
       this._restoreCount = 1;
       this._openWindowWithState(state);
       return;
     }
 
+    // close all other browser windows
+    this._forEachBrowserWindow(function(aWindow) {
+      if (aWindow != window) {
+        aWindow.close();
+        this.onClose(aWindow);
+      }
+    });
+
     // make sure closed window data isn't kept
     this._closedWindows = [];
 
     // determine how many windows are meant to be restored
     this._restoreCount = state.windows ? state.windows.length : 0;
 
-    var self = this;
-    // close all other browser windows
-    this._forEachBrowserWindow(function(aWindow) {
-      if (aWindow != window) {
-        self._closingWindows.push(aWindow);
-        aWindow.close();
-      }
-    });
-
     // restore to the given state
     this.restoreWindow(window, state, true);
   },
 
   getWindowState: function sss_getWindowState(aWindow) {
     if (!aWindow.__SSi && !aWindow.__SS_dyingCache)
       throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
     
@@ -1717,30 +1707,32 @@ SessionStoreService.prototype = {
 
   /**
    * serialize session data as Ini-formatted string
    * @param aUpdateAll
    *        Bool update all windows 
    * @returns string
    */
   _getCurrentState: function sss_getCurrentState(aUpdateAll) {
+    this._handleClosedWindows();
+
     var activeWindow = this._getMostRecentBrowserWindow();
     
     if (this._loadState == STATE_RUNNING) {
       // update the data for all windows with activities since the last save operation
       this._forEachBrowserWindow(function(aWindow) {
         if (!this._isWindowLoaded(aWindow)) // window data is still in _statesToRestore
           return;
         if (aUpdateAll || this._dirtyWindows[aWindow.__SSi] || aWindow == activeWindow) {
           this._collectWindowData(aWindow);
         }
         else { // always update the window features (whose change alone never triggers a save operation)
           this._updateWindowFeatures(aWindow);
         }
-      }, this);
+      });
       this._dirtyWindows = [];
     }
     
     // collect the data for all windows
     var total = [], windows = [];
     var nonPopupCount = 0;
     var ix;
     for (ix in this._windows) {
@@ -2666,16 +2658,34 @@ SessionStoreService.prototype = {
       if (!win.closed)
         return win;
     }
     return null;
 #endif
   },
 
   /**
+   * Calls onClose for windows that are determined to be closed but aren't
+   * destroyed yet, which would otherwise cause getBrowserState and
+   * setBrowserState to treat them as open windows.
+   */
+  _handleClosedWindows: function sss_handleClosedWindows() {
+    var windowMediator = Cc["@mozilla.org/appshell/window-mediator;1"].
+                         getService(Ci.nsIWindowMediator);
+    var windowsEnum = windowMediator.getEnumerator("navigator:browser");
+
+    while (windowsEnum.hasMoreElements()) {
+      var window = windowsEnum.getNext();
+      if (window.closed) {
+        this.onClose(window);
+      }
+    }
+  },
+
+  /**
    * open a new browser window for a given session state
    * called when restoring a multi-window session
    * @param aState
    *        Object containing session data
    */
   _openWindowWithState: function sss_openWindowWithState(aState) {
     var argString = Cc["@mozilla.org/supports-string;1"].
                     createInstance(Ci.nsISupportsString);
@@ -2876,27 +2886,26 @@ SessionStoreService.prototype = {
       // instead of evalInSandbox everywhere
       jsonString = jsonString.replace(/[\u2028\u2029]/g,
                                       function($0) "\\u" + $0.charCodeAt(0).toString(16));
     }
     
     return jsonString;
   },
 
-  _sendRestoreCompletedNotifications:
-  function sss_sendRestoreCompletedNotifications(aOnWindowClose) {
-    if (this._restoreCount && !aOnWindowClose)
+  _sendRestoreCompletedNotifications: function sss_sendRestoreCompletedNotifications() {
+    if (this._restoreCount) {
       this._restoreCount--;
-
-    if (this._restoreCount == 0 && this._closingWindows.length == 0) {
-      // This was the last window restored at startup, notify observers.
-      this._observerService.notifyObservers(null,
-        this._browserSetState ? NOTIFY_BROWSER_STATE_RESTORED : NOTIFY_WINDOWS_RESTORED,
-        "");
-      this._browserSetState = false;
+      if (this._restoreCount == 0) {
+        // This was the last window restored at startup, notify observers.
+        this._observerService.notifyObservers(null,
+          this._browserSetState ? NOTIFY_BROWSER_STATE_RESTORED : NOTIFY_WINDOWS_RESTORED,
+          "");
+        this._browserSetState = false;
+      }
     }
   },
 
   /**
    * @param aWindow
    *        Window reference
    * @returns whether this window's data is still cached in _statesToRestore
    *          because it's not fully loaded yet
--- a/browser/components/sessionstore/test/browser/Makefile.in
+++ b/browser/components/sessionstore/test/browser/Makefile.in
@@ -40,16 +40,18 @@ DEPTH		= ../../../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 relativesrcdir  = browser/components/sessionstore/test/browser 
 
 include $(DEPTH)/config/autoconf.mk
 include $(topsrcdir)/config/rules.mk
 
+# browser_526613.js is disabled because of frequent failures (bug 534489)
+
 _BROWSER_TEST_FILES = \
 	browser_248970_a.js \
 	browser_248970_b.js \
 	browser_248970_b_sample.html \
 	browser_339445.js \
 	browser_339445_sample.html \
 	browser_345898.js \
 	browser_346337.js \
@@ -103,13 +105,13 @@ include $(topsrcdir)/config/rules.mk
 	browser_485563.js \
 	browser_490040.js \
 	browser_491168.js \
 	browser_491577.js \
 	browser_493467.js \
 	browser_495495.js \
 	browser_514751.js \
 	browser_522545.js \
-	browser_526613.js \
+	browser_528776.js \
 	$(NULL)
 
 libs:: $(_BROWSER_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
--- a/browser/components/sessionstore/test/browser/browser_354894.js
+++ b/browser/components/sessionstore/test/browser/browser_354894.js
@@ -100,30 +100,37 @@
  * not enabled on that platform (platform shim; the application is kept running
  * although there are no windows left)
  * @note There is a difference when closing a browser window with
  * BrowserTryToCloseWindow() as opposed to close(). The former will make
  * nsSessionStore restore a window next time it gets a chance and will post
  * notifications. The latter won't.
  */
 
-function browserWindowsCount() {
+function browserWindowsCount(expected, msg) {
+  if (typeof expected == "number")
+    expected = [expected, expected];
   let count = 0;
   let e = Cc["@mozilla.org/appshell/window-mediator;1"]
             .getService(Ci.nsIWindowMediator)
             .getEnumerator("navigator:browser");
   while (e.hasMoreElements()) {
     if (!e.getNext().closed)
       ++count;
   }
-  return count;
+  is(count, expected[0], msg + " (nsIWindowMediator)");
+  let state = Cc["@mozilla.org/browser/sessionstore;1"]
+                .getService(Ci.nsISessionStore)
+                .getBrowserState();
+  info(state);
+  is(JSON.parse(state).windows.length, expected[1], msg + " (getBrowserState)");
 }
 
 function test() {
-  is(browserWindowsCount(), 1, "Only one browser window should be open initially");
+  browserWindowsCount(1, "Only one browser window should be open initially");
 
   waitForExplicitFinish();
 
   // Some urls that might be opened in tabs and/or popups
   // Do not use about:blank:
   // That one is reserved for special purposes in the tests
   const TEST_URLS = ["about:mozilla", "about:buildconfig"];
 
@@ -506,39 +513,40 @@ function test() {
     });
   }
 
   // Execution starts here
 
   setupTestsuite();
   if (navigator.platform.match(/Mac/)) {
     // Mac tests
-    testMacNotifications(
-      function() testNotificationCount(
-        function() {
-          cleanupTestsuite();
-          is(browserWindowsCount(), 1, "Only one browser window should be open eventually");
-          finish();
-        }
-      )
-    );
+    testMacNotifications(function () {
+      testNotificationCount(function () {
+        cleanupTestsuite();
+        browserWindowsCount(1, "Only one browser window should be open eventually");
+        finish();
+      });
+    });
   }
   else {
     // Non-Mac Tests
-    testOpenCloseNormal(
-      function() testOpenClosePrivateBrowsing(
-        function() testOpenCloseWindowAndPopup(
-          function() testOpenCloseOnlyPopup(
-            function() testOpenCloseRestoreFromPopup (
-              function() testNotificationCount(
-                function() {
-                  cleanupTestsuite();
-                  is(browserWindowsCount(), 1, "Only one browser window should be open eventually");
-                  finish();
-                }
-              )
-            )
-          )
-        )
-      )
-    );
+    testOpenCloseNormal(function () {
+      browserWindowsCount([0, 1], "browser windows after testOpenCloseNormal");
+      testOpenClosePrivateBrowsing(function () {
+        browserWindowsCount([0, 1], "browser windows after testOpenClosePrivateBrowsing");
+        testOpenCloseWindowAndPopup(function () {
+          browserWindowsCount([0, 1], "browser windows after testOpenCloseWindowAndPopup");
+          testOpenCloseOnlyPopup(function () {
+            browserWindowsCount([0, 1], "browser windows after testOpenCloseOnlyPopup");
+            testOpenCloseRestoreFromPopup (function () {
+              browserWindowsCount([0, 1], "browser windows after testOpenCloseRestoreFromPopup");
+              testNotificationCount(function () {
+                cleanupTestsuite();
+                browserWindowsCount(1, "browser windows after testNotificationCount");
+                finish();
+              });
+            });
+          });
+        });
+      });
+    });
   }
 }
--- a/browser/components/sessionstore/test/browser/browser_526613.js
+++ b/browser/components/sessionstore/test/browser/browser_526613.js
@@ -42,38 +42,32 @@ function test() {
   let ss = Cc["@mozilla.org/browser/sessionstore;1"].
            getService(Ci.nsISessionStore);
   let os = Cc["@mozilla.org/observer-service;1"].
            getService(Ci.nsIObserverService);
   let wm = Cc["@mozilla.org/appshell/window-mediator;1"].
            getService(Ci.nsIWindowMediator);
   waitForExplicitFinish();
 
-  function browserWindowsCount() {
+  function browserWindowsCount(expected) {
     let count = 0;
     let e = wm.getEnumerator("navigator:browser");
     while (e.hasMoreElements()) {
-      let win = e.getNext();
-      if (!win.closed) {
+      if (!e.getNext().closed)
         ++count;
-        if (win != window) {
-          try {
-            var tabs = win.gBrowser.mTabs.length;
-          } catch (e) {
-            info(e);
-          }
-          info("secondary window: " + [win.document.readyState, win.content.location, tabs]);
-        }
-      }
     }
-
-    return count;
+    is(count, expected,
+       "number of open browser windows according to nsIWindowMediator");
+    let state = ss.getBrowserState();
+    info(state);
+    is(JSON.parse(state).windows.length, expected,
+       "number of open browser windows according to getBrowserState");
   }
 
-  is(browserWindowsCount(), 1, "Only one browser window should be open initially");
+  browserWindowsCount(1);
 
   // backup old state
   let oldState = ss.getBrowserState();
   // create a new state for testing
   let testState = {
     windows: [
       { tabs: [{ entries: [{ url: "http://example.com/" }] }], selected: 1 },
       { tabs: [{ entries: [{ url: "about:robots"        }] }], selected: 1 },
@@ -84,33 +78,33 @@ function test() {
   };
 
   let observer = {
     pass: 1,
     observe: function(aSubject, aTopic, aData) {
       is(aTopic, "sessionstore-browser-state-restored",
          "The sessionstore-browser-state-restored notification was observed");
 
-      if (this.pass++ == 1) {  
-        is(browserWindowsCount(), 2, "Two windows should exist at this point");
+      if (this.pass++ == 1) {
+        browserWindowsCount(2);
 
         // let the first window be focused (see above)
         function pollMostRecentWindow() {
           if (wm.getMostRecentWindow("navigator:browser") == window) {
             ss.setBrowserState(oldState);
           } else {
             info("waiting for the current window to become active");
             setTimeout(pollMostRecentWindow, 0);
+            window.focus(); //XXX Why is this needed?
           }
         }
-        window.focus(); //XXX Why is this needed?
         pollMostRecentWindow();
       }
       else {
-        is(browserWindowsCount(), 1, "Only one window should exist after cleanup");
+        browserWindowsCount(1);
         ok(!window.closed, "Restoring the old state should have left this window open");
         os.removeObserver(this, "sessionstore-browser-state-restored");
         finish();
       }
     }
   };
   os.addObserver(observer, "sessionstore-browser-state-restored", false);
 
new file mode 100644
--- /dev/null
+++ b/browser/components/sessionstore/test/browser/browser_528776.js
@@ -0,0 +1,29 @@
+var ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
+var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator);
+
+function browserWindowsCount(expected) {
+  var count = 0;
+  var e = wm.getEnumerator("navigator:browser");
+  while (e.hasMoreElements()) {
+    if (!e.getNext().closed)
+      ++count;
+  }
+  is(count, expected,
+     "number of open browser windows according to nsIWindowMediator");
+  is(JSON.parse(ss.getBrowserState()).windows.length, expected,
+     "number of open browser windows according to getBrowserState");
+}
+
+function test() {
+  waitForExplicitFinish();
+
+  browserWindowsCount(1);
+
+  var win = openDialog(location, "", "chrome,all,dialog=no");
+  win.addEventListener("load", function () {
+    browserWindowsCount(2);
+    win.close();
+    browserWindowsCount(1);
+    finish();
+  }, false);
+}
--- a/browser/components/shell/src/nsWindowsShellService.cpp
+++ b/browser/components/shell/src/nsWindowsShellService.cpp
@@ -599,16 +599,17 @@ nsWindowsShellService::SetDesktopBackgro
                                             PRInt32 aPosition)
 {
   nsresult rv;
 
   nsCOMPtr<imgIContainer> container;
   nsCOMPtr<nsIDOMHTMLImageElement> imgElement(do_QueryInterface(aElement));
   if (!imgElement) {
     // XXX write background loading stuff!
+    return NS_ERROR_NOT_AVAILABLE;
   } 
   else {
     nsCOMPtr<nsIImageLoadingContent> imageContent =
       do_QueryInterface(aElement, &rv);
     if (!imageContent)
       return rv;
 
     // get the image container
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -279,16 +279,17 @@
 @BINPATH@/components/nsSearchService.js
 @BINPATH@/components/nsSearchSuggestions.js
 @BINPATH@/components/nsTryToClose.js
 @BINPATH@/components/nsLoginInfo.js
 @BINPATH@/components/nsLoginManager.js
 @BINPATH@/components/nsLoginManagerPrompter.js
 @BINPATH@/components/storage-Legacy.js
 @BINPATH@/components/storage-mozStorage.js
+@BINPATH@/components/crypto-SDR.js
 @BINPATH@/components/jsconsole-clhandler.js
 #ifdef MOZ_GTK2
 @BINPATH@/components/nsFilePicker.js
 #endif
 @BINPATH@/components/nsHelperAppDlg.js
 @BINPATH@/components/nsDownloadManagerUI.js
 @BINPATH@/components/nsProxyAutoConfig.js
 @BINPATH@/components/NetworkGeolocationProvider.js
--- a/browser/locales/en-US/chrome/browser/browser.properties
+++ b/browser/locales/en-US/chrome/browser/browser.properties
@@ -191,16 +191,17 @@ editBookmark.removeBookmarks.label=Remov
 
 # LOCALIZATION NOTE (geolocation.shareLocation geolocation.dontShareLocation): 
 #If you're having trouble with the word Share, please use Allow and Block in your language.
 geolocation.shareLocation=Share Location
 geolocation.shareLocation.accesskey=a
 geolocation.dontShareLocation=Don't Share
 geolocation.dontShareLocation.accesskey=o
 geolocation.siteWantsToKnow=%S wants to know your location.
+geolocation.fileWantsToKnow=The file %S wants to know your location.
 # LOCALIZATION NOTE (geolocation.learnMore): Use the unicode ellipsis char, \u2026,
 # or use "..." if \u2026 doesn't suit traditions in your locale.
 geolocation.learnMore=Learn Moreā€¦
 geolocation.remember=Remember for this site
 geolocation.remember.accesskey=R
 
 # Phishing/Malware Notification Bar.
 # LOCALIZATION NOTE (notAForgery, notAnAttack)
--- a/build/win32/Makefile.in
+++ b/build/win32/Makefile.in
@@ -68,18 +68,23 @@ ifeq (1500,$(_MSC_VER))
 REDIST_FILES = \
 	Microsoft.VC90.CRT.manifest \
 	msvcm90.dll \
 	msvcp90.dll \
 	msvcr90.dll \
 	$(NULL)
 endif
 
+ifeq (1600,$(_MSC_VER))
+REDIST_FILES = \
+	msvcp100.dll \
+	msvcr100.dll \
+	$(NULL)
+endif
+
 endif
 
 ifdef REDIST_FILES
 libs::
 	mkdir -p $(FINAL_TARGET)
-	for file in $(REDIST_FILES) ; do \
-	  install --preserve-timestamps "$(WIN32_REDIST_DIR)"/$$file $(FINAL_TARGET) ; \
-	done
+	install --preserve-timestamps $(foreach f,$(REDIST_FILES),"$(WIN32_REDIST_DIR)"/$(f)) $(FINAL_TARGET)
 endif
 
--- a/config/Makefile.in
+++ b/config/Makefile.in
@@ -158,16 +158,17 @@ clean clobber realclean clobber_all::
 endif
 
 PYUNITS := \
   unit-Expression.py \
   unit-Preprocessor.py \
   unit-nsinstall.py \
   unit-printprereleasesuffix.py \
   unit-JarMaker.py \
+  unit-buildlist.py \
   $(NULL)
 
 check:: check-python-modules check-jar-mn
 
 check-python-modules::
 	@$(EXIT_ON_ERROR) \
 	for test in $(PYUNITS); do \
 	  $(PYTHON) $(srcdir)/tests/$$test ; \
deleted file mode 100755
--- a/config/build-list.pl
+++ /dev/null
@@ -1,114 +0,0 @@
-#!env perl
-
-#
-# ***** BEGIN LICENSE BLOCK *****
-# Version: MPL 1.1/GPL 2.0/LGPL 2.1
-#
-# The contents of this file are subject to the Mozilla Public License Version
-# 1.1 (the "License"); you may not use this file except in compliance with
-# the License. You may obtain a copy of the License at
-# http://www.mozilla.org/MPL/
-#
-# Software distributed under the License is distributed on an "AS IS" basis,
-# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
-# for the specific language governing rights and limitations under the
-# License.
-#
-# The Original Code is mozilla.org code.
-#
-# The Initial Developer of the Original Code is
-# Netscape Communications Corporation.
-# Portions created by the Initial Developer are Copyright (C) 2001
-# the Initial Developer. All Rights Reserved.
-#
-# Contributor(s):
-#   Christopher Seawood <cls@seawood.org>
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either of 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 *****
-
-#
-# A generic script to add entries to a file 
-# if the entry does not already exist
-# 
-# Usage: $0 [-l] <filename> <entry> [<entry> <entry>]
-#
-#   -l do not attempt flock the file.
-
-use Fcntl qw(:DEFAULT :flock);
-use Getopt::Std;
-use mozLock;
-
-sub usage() {
-    print "$0 [-l] <filename> <entry>\n";
-    exit(1);
-}
-
-$nofilelocks = 0;
-
-getopts("l");
-
-$nofilelocks = 1 if defined($::opt_l);
-
-$file = shift;
-
-undef @entrylist;
-while (defined($entry = shift)) {
-    push @entrylist, $entry;
-}
-
-$lockfile = $file . ".lck";
-
-# touch the file if it doesn't exist
-if ( ! -e "$file") {
-    $now = time;
-    utime $now, $now, $file;
-}
-
-# This needs to be atomic
-mozLock($lockfile) unless $nofilelocks;
-
-# Read entire file into mem
-undef @inbuf;
-if ( -e "$file" ) {
-    open(IN, "$file") || die ("$file: $!\n");
-    binmode(IN);
-    while ($tmp = <IN>) {
-	chomp($tmp);
-	push @inbuf, $tmp;
-    }
-    close(IN);
-}
-
-undef @outbuf;
-# Add each entry to file if it's not already there
-foreach $entry (@entrylist) {
-    push @outbuf, $entry if (!grep(/^$entry$/, @inbuf));
-}
-
-$count = $#outbuf + 1;
-
-# Append new entry to file
-if ($count) {
-    open(OUT, ">>$file") || die ("$file: $!\n");
-    binmode(OUT);
-    foreach $entry (@outbuf) {
-	print OUT "$entry\n";
-    }
-    close(OUT);
-}
-
-mozUnlock($lockfile) unless $nofilelocks;
-
-exit(0);
new file mode 100644
--- /dev/null
+++ b/config/buildlist.py
@@ -0,0 +1,73 @@
+# ***** BEGIN LICENSE BLOCK *****
+# Version: MPL 1.1/GPL 2.0/LGPL 2.1
+#
+# The contents of this file are subject to the Mozilla Public License Version
+# 1.1 (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+# http://www.mozilla.org/MPL/
+#
+# Software distributed under the License is distributed on an "AS IS" basis,
+# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+# for the specific language governing rights and limitations under the
+# License.
+#
+# The Original Code is Mozilla build system.
+#
+# The Initial Developer of the Original Code is
+# Mozilla Foundation.
+# Portions created by the Initial Developer are Copyright (C) 2009
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#  Ted Mielczarek <ted.mielczarek@gmail.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 provisiwons 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 *****
+
+'''A generic script to add entries to a file 
+if the entry does not already exist.
+
+Usage: buildlist.py <filename> <entry> [<entry> ...]
+'''
+
+import sys
+import os
+from utils import lockFile
+
+def addEntriesToListFile(listFile, entries):
+  """Given a file |listFile| containing one entry per line,
+  add each entry in |entries| to the file, unless it is already
+  present."""
+  lock = lockFile(listFile + ".lck")
+  try:
+    if os.path.exists(listFile):
+      f = open(listFile)
+      existing = set([x.strip() for x in f.readlines()])
+      f.close()
+    else:
+      existing = set()
+    f = open(listFile, 'a')
+    for e in entries:
+      if e not in existing:
+        f.write("%s\n" % e)
+        existing.add(e)
+    f.close()
+  finally:
+    lock = None
+
+if __name__ == '__main__':
+  if len(sys.argv) < 3:
+    print >>sys.stderr, "Usage: buildlist.py <list file> <entry> [<entry> ...]"
+    sys.exit(1)
+  addEntriesToListFile(sys.argv[1], sys.argv[2:])
--- a/config/config.mk
+++ b/config/config.mk
@@ -250,17 +250,17 @@ OS_LDFLAGS += $(MOZ_MEMORY_LDFLAGS)
 endif
 
 # MOZ_DEBUG_SYMBOLS generates debug symbols in separate PDB files.
 # Used for generating an optimized build with debugging symbols.
 # Used in the Windows nightlies to generate symbols for crash reporting.
 ifdef MOZ_DEBUG_SYMBOLS
 OS_CXXFLAGS += -Zi -UDEBUG -DNDEBUG
 OS_CFLAGS += -Zi -UDEBUG -DNDEBUG
-OS_LDFLAGS += -DEBUG -OPT:REF -OPT:nowin98
+OS_LDFLAGS += -DEBUG -OPT:REF
 endif
 
 ifdef MOZ_QUANTIFY
 # -FIXED:NO is needed for Quantify to work, but it increases the size
 # of executables, so only use it if building for Quantify.
 WIN32_EXE_LDFLAGS += -FIXED:NO
 
 # We need -OPT:NOICF to prevent identical methods from being merged together.
--- a/config/rules.mk
+++ b/config/rules.mk
@@ -150,17 +150,17 @@ define _INSTALL_TESTS
 $(TEST_INSTALLER) $(wildcard $(srcdir)/$(dir)/*) $(testxpcobjdir)/$(MODULE)/$(dir)
 
 endef # do not remove the blank line!
 
 SOLO_FILE ?= $(error Specify a test filename in SOLO_FILE when using check-interactive or check-one)
 
 libs::
 	$(foreach dir,$(XPCSHELL_TESTS),$(_INSTALL_TESTS))
-	$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl \
+	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py \
           $(testxpcobjdir)/all-test-dirs.list \
           $(addprefix $(MODULE)/,$(XPCSHELL_TESTS))
 
 testxpcsrcdir = $(topsrcdir)/testing/xpcshell
 
 # Execute all tests in the $(XPCSHELL_TESTS) directories.
 # See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
 xpcshell-tests:
@@ -819,23 +819,23 @@ endif
 #
 # Rule to create list of libraries for final link
 #
 export::
 ifdef LIBRARY_NAME
 ifdef EXPORT_LIBRARY
 ifdef IS_COMPONENT
 ifdef BUILD_STATIC_LIBS
-	@$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_LINK_COMPS) $(STATIC_LIBRARY_NAME)
+	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_COMPS) $(STATIC_LIBRARY_NAME)
 ifdef MODULE_NAME
-	@$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_LINK_COMP_NAMES) $(MODULE_NAME)
+	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_COMP_NAMES) $(MODULE_NAME)
 endif
 endif # BUILD_STATIC_LIBS
 else  # !IS_COMPONENT
-	$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
+	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
 endif # IS_COMPONENT
 endif # EXPORT_LIBRARY
 endif # LIBRARY_NAME
 
 # Create dependencies on static (and shared EXTRA_DSO_LIBS) libraries
 LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(LIBS))
 HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(HOST_LIBS))
 DSO_LDOPTS_DEPS = $(EXTRA_DSO_LIBS) $(filter %.$(LIB_SUFFIX), $(EXTRA_DSO_LDOPTS))
@@ -885,17 +885,17 @@ else
 	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DIST)/lib
 endif
 endif # DIST_INSTALL
 endif # LIBRARY
 ifdef SHARED_LIBRARY
 ifdef IS_COMPONENT
 	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components
 	$(ELF_DYNSTR_GC) $(FINAL_TARGET)/components/$(SHARED_LIBRARY)
-	@$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_TARGET)/components/components.list $(SHARED_LIBRARY)
+	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.list $(SHARED_LIBRARY)
 ifdef BEOS_ADDON_WORKAROUND
 	( cd $(FINAL_TARGET)/components && $(CC) -nostart -o $(SHARED_LIBRARY).stub $(SHARED_LIBRARY) )
 endif
 else # ! IS_COMPONENT
 ifneq (,$(filter OS2 WINNT WINCE,$(OS_ARCH)))
 	$(INSTALL) $(IFLAGS2) $(IMPORT_LIBRARY) $(DIST)/lib
 else
 	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(DIST)/lib
@@ -1780,17 +1780,17 @@ GARBAGE_DIRS += $(JAVA_GEN_DIR)
 
 # generate .java files into _javagen/[package name dirs]
 _JAVA_GEN_DIR = $(JAVA_GEN_DIR)/$(JAVA_IFACES_PKG_NAME)
 $(_JAVA_GEN_DIR):
 	$(NSINSTALL) -D $@
 
 $(JAVA_GEN_DIR)/.%.java.pp: %.idl $(XPIDL_COMPILE) $(_JAVA_GEN_DIR)
 	$(REPORT_BUILD)
-	$(ELOG) $(XPIDL_COMPILE) -m java -w -I$(srcdir) -I$(IDL_DIR) -o $(_JAVA_GEN_DIR)/$* $(_VPATH_SRCS)
+	$(ELOG) $(XPIDL_COMPILE) -m java -w $(XPIDL_FLAGS) -I$(srcdir) -I$(IDL_DIR) -o $(_JAVA_GEN_DIR)/$* $(_VPATH_SRCS)
 	@touch $@
 
 # "Install" generated Java interfaces.  We segregate them based on the XPI_NAME.
 # If XPI_NAME is not set, install into the "default" directory.
 ifneq ($(XPI_NAME),)
 JAVA_INSTALL_DIR = $(JAVA_DIST_DIR)/$(XPI_NAME)
 else
 JAVA_INSTALL_DIR = $(JAVA_DIST_DIR)/default
@@ -1806,32 +1806,32 @@ endif # XPIDLSRCS
 endif # MOZ_JAVAXPCOM
 
 ################################################################################
 # Copy each element of EXTRA_COMPONENTS to $(FINAL_TARGET)/components
 ifdef EXTRA_COMPONENTS
 libs:: $(EXTRA_COMPONENTS)
 ifndef NO_DIST_INSTALL
 	$(INSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/components
-	@$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_TARGET)/components/components.list $(notdir $^)
+	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.list $(notdir $^)
 endif
 
 endif
 
 ifdef EXTRA_PP_COMPONENTS
 libs:: $(EXTRA_PP_COMPONENTS)
 ifndef NO_DIST_INSTALL
 	$(EXIT_ON_ERROR) \
 	$(NSINSTALL) -D $(FINAL_TARGET)/components; \
 	for i in $^; do \
 	  fname=`basename $$i`; \
 	  dest=$(FINAL_TARGET)/components/$${fname}; \
 	  $(RM) -f $$dest; \
 	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
-	  $(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_TARGET)/components/components.list $$fname; \
+	  $(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.list $$fname; \
 	done
 endif
 
 endif
 
 ################################################################################
 # Copy each element of EXTRA_JS_MODULES to $(FINAL_TARGET)/modules
 ifdef EXTRA_JS_MODULES
--- a/config/system-headers
+++ b/config/system-headers
@@ -71,16 +71,17 @@ Button.h
 byteswap.h
 #if MOZ_ENABLE_LIBXUL!=1
 #define WRAP_CAIRO_HEADERS
 #endif
 #if MOZ_TREE_CAIRO!=1
 #define WRAP_CAIRO_HEADERS
 #endif
 #ifdef WRAP_CAIRO_HEADERS
+pixman.h
 cairo.h
 cairo-atsui.h
 cairo-beos.h
 cairo-ft.h
 cairo-glitz.h
 cairo-os2.h
 cairo-pdf.h
 cairo-ps.h
new file mode 100644
--- /dev/null
+++ b/config/tests/unit-buildlist.py
@@ -0,0 +1,80 @@
+import unittest
+
+import os, sys, os.path, time
+from tempfile import mkdtemp
+from shutil import rmtree
+sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
+
+from buildlist import addEntriesToListFile
+
+class TestBuildList(unittest.TestCase):
+  """
+  Unit tests for buildlist.py
+  """
+  def setUp(self):
+    self.tmpdir = mkdtemp()
+
+  def tearDown(self):
+    rmtree(self.tmpdir)
+
+  # utility methods for tests
+  def touch(self, file, dir=None):
+    if dir is None:
+      dir = self.tmpdir
+    f = os.path.join(dir, file)
+    open(f, 'w').close()
+    return f
+
+  def assertFileContains(self, filename, l):
+    """Assert that the lines in the file |filename| are equal
+    to the contents of the list |l|, in order."""
+    l = l[:]
+    f = open(filename, 'r')
+    lines = [line.rstrip() for line in f.readlines()]
+    f.close()
+    for line in lines:
+      self.assert_(len(l) > 0, "ran out of expected lines! (expected '%s', got '%s')" % (l, lines))
+      self.assertEqual(line, l.pop(0))
+    self.assert_(len(l) == 0, "not enough lines in file! (expected '%s', got '%s'" % (l, lines))
+
+  def test_basic(self):
+    "Test that addEntriesToListFile works when file doesn't exist."
+    testfile = os.path.join(self.tmpdir, "test.list")
+    l = ["a", "b", "c"]
+    addEntriesToListFile(testfile, l)
+    self.assertFileContains(testfile, l)
+    # ensure that attempting to add the same entries again doesn't change it
+    addEntriesToListFile(testfile, l)
+    self.assertFileContains(testfile, l)
+
+  def test_append(self):
+    "Test adding new entries."
+    testfile = os.path.join(self.tmpdir, "test.list")
+    l = ["a", "b", "c"]
+    addEntriesToListFile(testfile, l)
+    self.assertFileContains(testfile, l)
+    l2 = ["x","y","z"]
+    addEntriesToListFile(testfile, l2)
+    l.extend(l2)
+    self.assertFileContains(testfile, l)
+
+  def test_append_some(self):
+    "Test adding new entries mixed with existing entries."
+    testfile = os.path.join(self.tmpdir, "test.list")
+    l = ["a", "b", "c"]
+    addEntriesToListFile(testfile, l)
+    self.assertFileContains(testfile, l)
+    addEntriesToListFile(testfile, ["a", "x", "c", "z"])
+    self.assertFileContains(testfile, ["a", "b", "c", "x", "z"])
+
+  def test_add_multiple(self):
+    """Test that attempting to add the same entry multiple times results in
+    only one entry being added."""
+    testfile = os.path.join(self.tmpdir, "test.list")
+    addEntriesToListFile(testfile, ["a","b","a","a","b"])
+    self.assertFileContains(testfile, ["a","b"])
+    addEntriesToListFile(testfile, ["c","a","c","b","c"])
+    self.assertFileContains(testfile, ["a","b","c"])
+
+if __name__ == '__main__':
+  unittest.main()
--- a/configure.in
+++ b/configure.in
@@ -571,16 +571,23 @@ case "$target" in
             AC_DEFINE(_CRT_NONSTDC_NO_DEPRECATE)
         elif test "$_CC_MAJOR_VERSION" = "15"; then
             _CC_SUITE=9
             CXXFLAGS="$CXXFLAGS -Zc:wchar_t-"
             LDFLAGS="$LDFLAGS -MANIFESTUAC:NO"
             _USE_DYNAMICBASE=1
             AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
             AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
+        elif test "$_CC_MAJOR_VERSION" = "16"; then
+            _CC_SUITE=10
+            CXXFLAGS="$CXXFLAGS -Zc:wchar_t-"
+            LDFLAGS="$LDFLAGS -MANIFESTUAC:NO"
+            _USE_DYNAMICBASE=1
+            AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
+            AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
         else
             AC_MSG_ERROR([This version of the MSVC compiler, $CC_VERSION , is unsupported.])
         fi
 
         _MOZ_RTTI_FLAGS_ON='-GR'
         _MOZ_RTTI_FLAGS_OFF='-GR-'
         _MOZ_EXCEPTIONS_FLAGS_ON='-EHsc'
         _MOZ_EXCEPTIONS_FLAGS_OFF=''
@@ -1182,17 +1189,19 @@ SINIX-N | SINIX-Y | SINIX-Z |ReliantUNIX
     ;;
 UnixWare)
     HOST_OS_ARCH=UNIXWARE
     ;;
 esac
 
 case "$OS_ARCH" in
 WINNT)
-    OS_TEST=`uname -p`
+    if test -z "$CROSS_COMPILE" ; then
+        OS_TEST=`uname -p`
+    fi
     ;;
 Windows_NT)
 #
 # If uname -s returns "Windows_NT", we assume that we are using
 # the uname.exe in MKS toolkit.
 #
 # The -r option of MKS uname only returns the major version number.
 # So we need to use its -v option to get the minor version number.
@@ -2136,17 +2145,17 @@ case "$target" in
         CXXFLAGS="$CXXFLAGS -mms-bitfields"
         DSO_LDOPTS='-shared'
         MKSHLIB='$(CXX) $(DSO_LDOPTS) -o $@'
         MKCSHLIB='$(CC) $(DSO_LDOPTS) -o $@'
         RC='$(WINDRES)'
         # Use temp file for windres (bug 213281)
         RCFLAGS='-O coff --use-temp-file'
         # mingw doesn't require kernel32, user32, and advapi32 explicitly
-        LIBS="$LIBS -lgdi32 -lwinmm -lwsock32"
+        LIBS="$LIBS -luuid -lgdi32 -lwinmm -lwsock32"
         MOZ_JS_LIBS='-L$(LIBXUL_DIST)/lib -lmozjs'
         MOZ_FIX_LINK_PATHS=
         DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/lib -lxpcom -lxpcom_core'
         XPCOM_FROZEN_LDOPTS='-L$(LIBXUL_DIST)/lib -lxpcom'
         DLL_PREFIX=
         IMPORT_LIB_SUFFIX=dll.a
     else
         TARGET_COMPILER_ABI=msvc
@@ -7640,17 +7649,17 @@ if test "$MOZ_TREE_CAIRO"; then
             MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS $XLDFLAGS -lXrender -lfreetype -lfontconfig"
         fi
     fi
 
     CAIRO_FEATURES_H=gfx/cairo/cairo/src/cairo-features.h
     mv -f $CAIRO_FEATURES_H "$CAIRO_FEATURES_H".orig 2> /dev/null
 
 else
-   PKG_CHECK_MODULES(CAIRO, cairo >= $CAIRO_VERSION freetype2 fontconfig)
+   PKG_CHECK_MODULES(CAIRO, cairo >= $CAIRO_VERSION pixman-1 freetype2 fontconfig)
    MOZ_CAIRO_CFLAGS=$CAIRO_CFLAGS
    MOZ_CAIRO_LIBS=$CAIRO_LIBS
    if test "$MOZ_X11"; then
         PKG_CHECK_MODULES(CAIRO_XRENDER, cairo-xlib-xrender >= $CAIRO_VERSION)
         MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS $XLDFLAGS $CAIRO_XRENDER_LIBS"
         MOZ_CAIRO_CFLAGS="$MOZ_CAIRO_CFLAGS $CAIRO_XRENDER_CFLAGS"
    fi
 fi
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -1773,26 +1773,31 @@ nsObjectLoadingContent::Instantiate(nsIO
   nsCOMPtr<nsIURI> baseURI;
   if (!aURI) {
     // We need some URI. If we have nothing else, use the base URI.
     // XXX(biesi): The code used to do this. Not sure why this is correct...
     GetObjectBaseURI(thisContent, getter_AddRefs(baseURI));
     aURI = baseURI;
   }
 
+  nsIFrame *nsiframe = do_QueryFrame(aFrame);
+  nsWeakFrame weakFrame(nsiframe);
+
   // We'll always have a type or a URI by the time we get here
   NS_ASSERTION(aURI || !typeToUse.IsEmpty(), "Need a URI or a type");
   LOG(("OBJLC [%p]: Calling [%p]->Instantiate(<%s>, %p)\n", this, aFrame,
        typeToUse.get(), aURI));
   nsresult rv = aFrame->Instantiate(typeToUse.get(), aURI);
 
   mInstantiating = oldInstantiatingValue;
 
   nsCOMPtr<nsIPluginInstance> pluginInstance;
-  aFrame->GetPluginInstance(*getter_AddRefs(pluginInstance));
+  if (weakFrame.IsAlive()) {
+    aFrame->GetPluginInstance(*getter_AddRefs(pluginInstance));
+  }
   if (pluginInstance) {
     nsCOMPtr<nsIPluginTag> pluginTag;
     nsCOMPtr<nsIPluginHost> host(do_GetService(MOZ_PLUGIN_HOST_CONTRACTID));
     host->GetPluginTagForInstance(pluginInstance, getter_AddRefs(pluginTag));
 
     nsCOMPtr<nsIBlocklistService> blocklist =
       do_GetService("@mozilla.org/extensions/blocklist;1");
     if (blocklist) {
--- a/content/html/content/src/nsHTMLInputElement.cpp
+++ b/content/html/content/src/nsHTMLInputElement.cpp
@@ -1743,16 +1743,32 @@ SelectTextFieldOnFocus()
 }
 
 nsresult
 nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
 {
   if (!aVisitor.mPresContext) {
     return NS_OK;
   }
+
+  // ignore the activate event fired by the "Browse..." button
+  // (file input controls fire their own) (bug 500885)
+  if (mType == NS_FORM_INPUT_FILE) {
+    nsCOMPtr<nsIContent> maybeButton =
+      do_QueryInterface(aVisitor.mEvent->originalTarget);
+    if (maybeButton &&
+      maybeButton->IsRootOfNativeAnonymousSubtree() &&
+      maybeButton->AttrValueIs(kNameSpaceID_None,
+                               nsGkAtoms::type,
+                               nsGkAtoms::button,
+                               eCaseMatters)) {
+        return NS_OK;
+    }
+  }
+
   nsresult rv = NS_OK;
   PRBool outerActivateEvent = !!(aVisitor.mItemFlags & NS_OUTER_ACTIVATE_EVENT);
   PRBool originalCheckedValue =
     !!(aVisitor.mItemFlags & NS_ORIGINAL_CHECKED_VALUE);
   PRBool noContentDispatch = !!(aVisitor.mItemFlags & NS_NO_CONTENT_DISPATCH);
   PRInt8 oldType = NS_CONTROL_TYPE(aVisitor.mItemFlags);
   // Ideally we would make the default action for click and space just dispatch
   // DOMActivate, and the default action for DOMActivate flip the checkbox/
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -131,16 +131,17 @@ include $(topsrcdir)/config/rules.mk
 		test_bug460568.html \
 		test_bug347174.html \
 		test_bug347174_write.html \
 		test_bug347174_xsl.html \
 		test_bug347174_xslp.html \
 		347174transformable.xml \
 		347174transform.xsl \
 		test_bug481335.xhtml \
+		test_bug500885.html \
 		test_bug514856.html \
 		bug514856_iframe.html \
 		test_bug519987.html \
 		test_bug523771.html \
 		form_submit_server.sjs \
 		test_bug529819.html \
 		test_bug529859.html \
 		$(NULL)
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_bug500885.html
@@ -0,0 +1,98 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=500885
+-->
+<head>
+  <title>Test for Bug 500885</title>
+  <script type="text/javascript" src="/MochiKit/packed.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.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=500885">Mozilla Bug 500885</a>
+<div>
+  <input id="file" type="file" />
+</div>
+<script type="text/javascript">
+
+netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+const Cm = Components.manager;
+
+Cc["@mozilla.org/moz/jssubscript-loader;1"]
+  .getService(Ci.mozIJSSubScriptLoader)
+  .loadSubScript("chrome://mochikit/content/browser/toolkit/content/tests/browser/common/mockObjects.js", this);
+
+Cu.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function MockFilePicker() { };
+MockFilePicker.prototype = {
+  QueryInterface: XPCOMUtils.generateQI([Ci.nsIFilePicker]),
+  init: function(aParent, aTitle, aMode) { },
+  appendFilters: function(aFilterMask) { },
+  appendFilter: function(aTitle, aFilter) { },
+  defaultString: "",
+  defaultExtension: "",
+  filterIndex: 0,
+  displayDirectory: null,
+  file: null,
+  get fileURL() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+  get files() {
+    throw Cr.NS_ERROR_NOT_IMPLEMENTED;
+  },
+  show: function MFP_show() {
+    return Ci.nsIFilePicker.returnOK;
+  }
+};
+
+var mockFilePickerRegisterer =
+  new MockObjectRegisterer("@mozilla.org/filepicker;1",MockFilePicker);
+
+
+function test() {
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+  var wu = window.QueryInterface(Ci.nsIInterfaceRequestor)
+                  .getInterface(Ci.nsIDOMWindowUtils);
+                  
+  mockFilePickerRegisterer.register();
+  try {
+    var domActivateEvents;
+    var fileInput = document.getElementById("file");
+    var rect = fileInput.getBoundingClientRect();
+
+    fileInput.addEventListener ("DOMActivate", function () {
+      domActivateEvents++;
+    }, false);
+
+    domActivateEvents = 0;
+    wu.sendMouseEvent("mousedown", rect.left + 5, rect.top + 5, 0, 1, 0);
+    wu.sendMouseEvent("mouseup", rect.left + 5, rect.top + 5, 0, 1, 0);
+    is(domActivateEvents, 1, "click on text field should only fire 1 DOMActivate event");
+
+    domActivateEvents = 0;
+    wu.sendMouseEvent("mousedown", rect.right - 5, rect.top + 5, 0, 1, 0);
+    wu.sendMouseEvent("mouseup", rect.right - 5, rect.top + 5, 0, 1, 0);
+    is(domActivateEvents, 1, "click on button should only fire 1 DOMActivate event");
+
+  } finally {
+    mockFilePickerRegisterer.unregister();
+  }
+  SimpleTest.finish();
+}
+
+window.onload = function() {
+  SimpleTest.waitForExplicitFinish();
+  setTimeout(test, 0);
+};
+
+</script>
+</body>
+
+</html>
--- a/content/svg/content/src/nsSVGScriptElement.cpp
+++ b/content/svg/content/src/nsSVGScriptElement.cpp
@@ -169,18 +169,17 @@ nsSVGScriptElement::GetType(nsAString & 
 {
   GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
 
   return NS_OK;
 }
 NS_IMETHODIMP
 nsSVGScriptElement::SetType(const nsAString & aType)
 {
-  NS_ERROR("write me!");
-  return NS_ERROR_NOT_IMPLEMENTED;
+  return SetAttr(kNameSpaceID_None, nsGkAtoms::type, aType, PR_TRUE); 
 }
 
 //----------------------------------------------------------------------
 // nsIDOMSVGURIReference methods
 
 /* readonly attribute nsIDOMSVGAnimatedString href; */
 NS_IMETHODIMP
 nsSVGScriptElement::GetHref(nsIDOMSVGAnimatedString * *aHref)
--- a/content/xml/document/src/nsXMLFragmentContentSink.cpp
+++ b/content/xml/document/src/nsXMLFragmentContentSink.cpp
@@ -604,17 +604,17 @@ NS_XHTMLParanoidFragmentSinkShutdown()
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsXHTMLParanoidFragmentSink,
                              nsXMLFragmentContentSink)
 
 nsresult
 nsXHTMLParanoidFragmentSink::AddAttributes(const PRUnichar** aAtts,
                                            nsIContent* aContent)
 {
-  nsresult rv;
+  nsresult rv = NS_OK;
 
   // use this to check for safe URIs in the few attributes that allow them
   nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
   nsCOMPtr<nsIURI> baseURI;
   PRUint32 flags = nsIScriptSecurityManager::DISALLOW_INHERIT_PRINCIPAL;
 
   // scrub URI attributes that point at dangerous content
   // We have to do this here, because this is where we have a base URI,
--- a/docshell/shistory/src/nsSHistory.cpp
+++ b/docshell/shistory/src/nsSHistory.cpp
@@ -831,18 +831,18 @@ nsSHistory::EvictWindowContentViewers(PR
     if (i < aFromIndex - gHistoryMaxViewers || 
         i > aFromIndex + gHistoryMaxViewers) {
       nsCOMPtr<nsISHEntry> entry;
       trans->GetSHEntry(getter_AddRefs(entry));
       nsCOMPtr<nsIContentViewer> viewer;
       nsCOMPtr<nsISHEntry> ownerEntry;
       entry->GetAnyContentViewer(getter_AddRefs(ownerEntry),
                                  getter_AddRefs(viewer));
-      NS_ASSERTION(!viewer,
-                   "ContentViewer exists outside gHistoryMaxViewer range");
+      NS_WARN_IF_FALSE(!viewer,
+                       "ContentViewer exists outside gHistoryMaxViewer range");
     }
 
     nsISHTransaction *temp = trans;
     temp->GetNext(getter_AddRefs(trans));
   }
 #endif
 
   EvictContentViewersInRange(startIndex, endIndex);
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -578,21 +578,18 @@ static nsDOMClassInfoData sClassInfoData
   // that are implemented by nsGlobalWindow can securely be exposed
   // to JS.
 
 
   NS_DEFINE_CLASSINFO_DATA(Window, nsWindowSH,
                            DEFAULT_SCRIPTABLE_FLAGS |
                            WINDOW_SCRIPTABLE_FLAGS)
 
-  // Don't allow modifications to Location.prototype
   NS_DEFINE_CLASSINFO_DATA(Location, nsLocationSH,
-                           (DOM_DEFAULT_SCRIPTABLE_FLAGS |
-                            nsIXPCScriptable::WANT_PRECREATE) &
-                           ~nsIXPCScriptable::ALLOW_PROP_MODS_TO_PROTOTYPE)
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
 
   NS_DEFINE_CLASSINFO_DATA(Navigator, nsNavigatorSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS |
                            nsIXPCScriptable::WANT_PRECREATE)
   NS_DEFINE_CLASSINFO_DATA(Plugin, nsPluginSH,
                            ARRAY_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(PluginArray, nsPluginArraySH,
                            ARRAY_SCRIPTABLE_FLAGS)
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -7725,22 +7725,28 @@ nsGlobalWindow::SetTimeoutOrInterval(nsI
 
   // If we don't have a document (we could have been unloaded since
   // the call to setTimeout was made), do nothing.
   if (!mDocument) {
     return NS_OK;
   }
 
   PRUint32 nestingLevel = sNestingLevel + 1;
-  if (interval < DOM_MIN_TIMEOUT_VALUE &&
-      (aIsInterval || nestingLevel >= DOM_CLAMP_TIMEOUT_NESTING_LEVEL)) {
-    // Don't allow timeouts less than DOM_MIN_TIMEOUT_VALUE from
-    // now...
-
-    interval = DOM_MIN_TIMEOUT_VALUE;
+  if (interval < DOM_MIN_TIMEOUT_VALUE) {
+    if (aIsInterval || nestingLevel >= DOM_CLAMP_TIMEOUT_NESTING_LEVEL) {
+      // Don't allow timeouts less than DOM_MIN_TIMEOUT_VALUE from
+      // now...
+
+      interval = DOM_MIN_TIMEOUT_VALUE;
+    }
+    else if (interval < 0) {
+      // Clamp negative intervals to 0.
+
+      interval = 0;
+    }
   }
 
   NS_ASSERTION(interval >= 0, "DOM_MIN_TIMEOUT_VALUE lies");
   PRUint32 realInterval = interval;
 
   // Make sure we don't proceed with a interval larger than our timer
   // code can handle.
   if (realInterval > PR_IntervalToMilliseconds(DOM_MAX_TIMEOUT_VALUE)) {
--- a/dom/tests/browser/browser_focus_steal_from_chrome.js
+++ b/dom/tests/browser/browser_focus_steal_from_chrome.js
@@ -1,16 +1,15 @@
 function test() {
   waitForExplicitFinish();
 
   let fm = Components.classes["@mozilla.org/focus-manager;1"]
                      .getService(Components.interfaces.nsIFocusManager);
 
-  let tabs = [ gBrowser.mCurrentTab, gBrowser.addTab() ];
-  gBrowser.selectedTab = tabs[0];
+  let tabs = [ gBrowser.selectedTab, gBrowser.addTab() ];
 
   let testingList = [
     { uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').focus(); }, 10);\"><input id='target'></body>",
       tagName: "INPUT", methodName: "focus" },
     { uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').select(); }, 10);\"><input id='target'></body>",
       tagName: "INPUT", methodName: "select" },
     { uri: "data:text/html,<body onload=\"setTimeout(function () { document.getElementById('target').focus(); }, 10);\"><a href='about:blank' id='target'>anchor</a></body>",
       tagName: "A", methodName: "focus" },
@@ -47,18 +46,17 @@ function test() {
   let testingIndex = -1;
   let canRetry;
   let callback;
   let loadedCount;
 
   function runNextTest() {
     if (++testingIndex >= testingList.length) {
       // cleaning-up...
-      let cleanTab = gBrowser.addTab();
-      gBrowser.selectedTab = cleanTab;
+      gBrowser.addTab();
       for (let i = 0; i < tabs.length; i++) {
         gBrowser.removeTab(tabs[i]);
       }
       finish();
       return;
     }
     callback = doTest1;
     loadTestPage();
@@ -161,9 +159,9 @@ function test() {
           "the " + testingList[testingIndex].tagName +
           " element is focused by the " + testingList[testingIndex].methodName +
           " (Test2: content can NOT steal focus)");
 
     runNextTest();
   }
 
   runNextTest();
-}
\ No newline at end of file
+}
--- a/dom/tests/mochitest/bugs/Makefile.in
+++ b/dom/tests/mochitest/bugs/Makefile.in
@@ -101,12 +101,15 @@ include $(topsrcdir)/config/rules.mk
 		test_bug495219.html \
 		test_bug504862.html \
 		file_bug504862.html \
 		test_bug260264.html \
 		test_bug260264_nested.html \
 		child_bug260264.html \
 		grandchild_bug260264.html \
 		utils_bug260264.js \
+		test_bug534362.html \
+		iframe_bug534362.html \
+		test_bug531542.html \
 		$(NULL)
 
 libs:: 	$(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/bugs/iframe_bug534362.html
@@ -0,0 +1,19 @@
+<html>
+<head>
+	<title>Iframe test for bug 534362</title>
+</head>
+<body">
+<script>
+function locationSetter(_href)
+{
+  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+  parent.setterCalled = true;
+};
+
+netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
+parent.setterCalled = false;
+location.__proto__.href setter = locationSetter;
+location.href = "javascript:";
+</script>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/bugs/test_bug531542.html
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=531542
+-->
+<head>
+  <title>Test for Bug 531542</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=531542">Mozilla Bug 531542</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 531542 **/
+
+var negativeTimeoutFired = false;
+function negativeTimeout()
+{
+  negativeTimeoutFired = true;
+}
+function testFinished()
+{
+  ok(negativeTimeoutFired, "Timeout with negative delay should fire.");
+  SimpleTest.finish();
+}
+
+SimpleTest.waitForExplicitFinish();
+setTimeout(negativeTimeout, -1);
+setTimeout(testFinished, 0);
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/tests/mochitest/bugs/test_bug534362.html
@@ -0,0 +1,44 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=534362
+-->
+<head>
+  <title>Test for Bug 534362</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=534362">Mozilla Bug 534362</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+  <iframe src="http://example.org/tests/dom/tests/mochitest/bugs/iframe_bug534362.html" name="testFrame" onload="changeLocation();"></iframe>
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 534362 **/
+
+function checkSetterCalled(called, shouldCall)
+{
+  is(called, shouldCall, "Setter " + (called ? "" : "not ") + "called.");
+  if (!shouldCall) {
+    SimpleTest.finish();
+  }
+}
+
+function changeLocation()
+{
+  checkSetterCalled(setterCalled, true);
+  setterCalled = false;
+  frames["testFrame"].location.href = "javascript:";
+  checkSetterCalled(setterCalled, false);
+}
+
+SimpleTest.waitForExplicitFinish();
+
+</script>
+</pre>
+</body>
+</html>
--- a/gfx/cairo/README
+++ b/gfx/cairo/README
@@ -61,13 +61,13 @@ quartz-const-globals.patch: make some Qu
 quartz-minimze-gradient-repeat.patch: reduce the number of gradient stop repetitions we use, to improve quality of Quartz's gradient rendering
 
 quartz-first-stop.patch: return the first stop for negative positions on the gradient line of a nonrepeating linear gradient
 
 ==== pixman patches ====
 
 pixman-neon.patch: add ARM NEON optimized compositing functions
 
-endian.patch: include cairo-platform.h for endian macros
+pixman-rename-and-endian.patch: include cairo-platform.h for renaming of external symbols and endian macros
 
 ==== disable printing patch ====
 
 disable-printing.patch:  allows us to use NS_PRINTING to disable printing.
deleted file mode 100644
--- a/gfx/cairo/endian.patch
+++ /dev/null
@@ -1,11 +0,0 @@
---- a/libpixman/src/pixman-private.h	Fri Oct 19 14:55:56 2007
-+++ b/libpixman/src/pixman-private.h	Fri Oct 19 14:56:45 2007
-@@ -5,6 +5,8 @@
- #ifndef PIXMAN_PRIVATE_H
- #define PIXMAN_PRIVATE_H
- 
-+#include "cairo-platform.h"
-+
- #include "pixman.h"
- #include <time.h>
- 
--- a/gfx/cairo/libpixman/src/Makefile.in
+++ b/gfx/cairo/libpixman/src/Makefile.in
@@ -157,16 +157,30 @@ endif
 EXPORTS		= pixman.h pixman-version.h
 
 LOCAL_INCLUDES	+= -I$(srcdir) -I$(srcdir)/../../cairo/src
 
 FORCE_STATIC_LIB = 1
 # This library is used by other shared libs in a static build
 FORCE_USE_PIC = 1
 
+include $(topsrcdir)/config/config.mk
+
+ifndef MOZ_ENABLE_LIBXUL
+ifdef GNU_CC
+# -fvisibility=hidden works fine but PIXMAN_EXPORT is not used in header
+# files, so pixman.h needs to be included before
+# "#pragma GCC visibility -push(hidden)".
+ifdef WRAP_SYSTEM_INCLUDES
+MY_VISIBILITY_FLAGS := -include pixman.h $(VISIBILITY_FLAGS)
+COMPILE_CFLAGS += $(MY_VISIBILITY_FLAGS)
+endif # WRAP_SYSTEM_INCLUDES
+endif # GNU_CC
+endif # !MOZ_ENABLE_LIBXUL
+
 include $(topsrcdir)/config/rules.mk
 
 CFLAGS += -DPACKAGE="mozpixman" -D_USE_MATH_DEFINES
 
 
 # special rule for pixman-mmx to get the right cflags
 pixman-mmx.$(OBJ_SUFFIX): pixman-mmx.c Makefile Makefile.in
 	$(REPORT_BUILD)
--- a/gfx/cairo/libpixman/src/pixman-private.h
+++ b/gfx/cairo/libpixman/src/pixman-private.h
@@ -1,17 +1,15 @@
 #ifndef PACKAGE
 #  error config.h must be included before pixman-private.h
 #endif
 
 #ifndef PIXMAN_PRIVATE_H
 #define PIXMAN_PRIVATE_H
 
-#include "cairo-platform.h"
-
 #include "pixman.h"
 #include <time.h>
 
 #ifndef FALSE
 #define FALSE 0
 #endif
 
 #ifndef TRUE
--- a/gfx/cairo/libpixman/src/pixman.h
+++ b/gfx/cairo/libpixman/src/pixman.h
@@ -64,16 +64,18 @@ SOFTWARE.
  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
 #ifndef PIXMAN_H__
 #define PIXMAN_H__
 
+#include "cairo-platform.h"
+
 #include <pixman-version.h>
 
 /*
  * Standard integers
  */
 #if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined (_sgi) || defined (__sun) || defined (sun) || defined (__digital__)
 #  include <inttypes.h>
 #elif defined (_MSC_VER)
new file mode 100644
--- /dev/null
+++ b/gfx/cairo/pixman-rename-and-endian.patch
@@ -0,0 +1,22 @@
+diff --git a/gfx/cairo/libpixman/src/pixman.h b/gfx/cairo/libpixman/src/pixman.h
+--- a/gfx/cairo/libpixman/src/pixman.h
++++ b/gfx/cairo/libpixman/src/pixman.h
+@@ -64,16 +64,18 @@ SOFTWARE.
+  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+  * PERFORMANCE OF THIS SOFTWARE.
+  */
+ 
+ #ifndef PIXMAN_H__
+ #define PIXMAN_H__
+ 
++#include "cairo-platform.h"
++
+ #include <pixman-version.h>
+ 
+ /*
+  * Standard integers
+  */
+ #if defined (_SVR4) || defined (SVR4) || defined (__OpenBSD__) || defined (_sgi) || defined (__sun) || defined (sun) || defined (__digital__)
+ #  include <inttypes.h>
+ #elif defined (_MSC_VER)
--- a/gfx/src/thebes/nsThebesFontMetrics.cpp
+++ b/gfx/src/thebes/nsThebesFontMetrics.cpp
@@ -438,17 +438,17 @@ static void
 GetTextRunBoundingMetrics(gfxTextRun *aTextRun, PRUint32 aStart, PRUint32 aLength,
                           nsThebesRenderingContext *aContext,
                           nsBoundingMetrics &aBoundingMetrics)
 {
     StubPropertyProvider provider;
     gfxTextRun::Metrics theMetrics =
         aTextRun->MeasureText(aStart, aLength, gfxFont::TIGHT_HINTED_OUTLINE_EXTENTS,
                               aContext->ThebesContext(), &provider);
-        // note that TIGHT_UNHINTED_OUTLINE_EXTENTS can be expensive (on Windows)
+        // note that TIGHT_HINTED_OUTLINE_EXTENTS can be expensive (on Windows)
         // but this is only used for MathML positioning so it's not critical
 
     aBoundingMetrics.leftBearing = NSToCoordFloor(theMetrics.mBoundingBox.X());
     aBoundingMetrics.rightBearing = NSToCoordCeil(theMetrics.mBoundingBox.XMost());
     aBoundingMetrics.width = NSToCoordRound(theMetrics.mAdvanceWidth);
     aBoundingMetrics.ascent = NSToCoordCeil(- theMetrics.mBoundingBox.Y());
     aBoundingMetrics.descent = NSToCoordCeil(theMetrics.mBoundingBox.YMost());
 }
--- a/gfx/thebes/public/gfxWindowsFonts.h
+++ b/gfx/thebes/public/gfxWindowsFonts.h
@@ -111,17 +111,17 @@ public:
 class FontEntry : public gfxFontEntry
 {
 public:
     FontEntry(const nsAString& aFaceName, gfxWindowsFontType aFontType,
               PRBool aItalic, PRUint16 aWeight, gfxUserFontData *aUserFontData) : 
         gfxFontEntry(aFaceName), mFontType(aFontType),
         mForceGDI(PR_FALSE), mUnknownCMAP(PR_FALSE),
         mUnicodeFont(PR_FALSE), mSymbolFont(PR_FALSE),
-        mCharset(0), mUnicodeRanges(0)
+        mCharset(), mUnicodeRanges()
     {
         mUserFontData = aUserFontData;
         mItalic = aItalic;
         mWeight = aWeight;
         if (IsType1())
             mForceGDI = PR_TRUE;
         mIsUserFont = aUserFontData != nsnull;
     }
--- a/gfx/thebes/src/gfxFont.cpp
+++ b/gfx/thebes/src/gfxFont.cpp
@@ -255,17 +255,17 @@ gfxFontFamily::FindFontForStyle(const gf
 
         // if we've reached one side without finding a font,
         // go the other direction until we find a match
         if (i == 1 || i == 9) {
             direction = -direction;
         }
     }
 
-    gfxFontEntry *matchFE;
+    gfxFontEntry *matchFE = nsnull;
     const PRInt8 absDistance = abs(weightDistance);
     direction = (weightDistance >= 0) ? 1 : -1;
     PRInt8 i, wghtSteps = 0;
 
     // account for synthetic bold in lighter case
     // if lighter is applied with an inherited bold weight,
     // and no actual bold faces exist, synthetic bold is used
     // so the matched weight above is actually one step down already
@@ -281,20 +281,16 @@ gfxFontFamily::FindFontForStyle(const gf
         if (wghtSteps > absDistance)
             break;
     }
 
     if (weightDistance > 0 && wghtSteps <= absDistance) {
         aNeedsBold = PR_TRUE;
     }
 
-    if (!matchFE) {
-        matchFE = weightList[matchBaseWeight];
-    }
-
     PR_LOG(gFontSelection, PR_LOG_DEBUG,
            ("(FindFontForStyle) name: %s, sty: %02x, wt: %d, sz: %.1f -> %s\n", 
             NS_ConvertUTF16toUTF8(mName).get(),
             aFontStyle.style, aFontStyle.weight, aFontStyle.size,
             NS_ConvertUTF16toUTF8(matchFE->Name()).get()));
     NS_ASSERTION(matchFE, "we should always be able to return something here");
     return matchFE;
 }
--- a/jpeg/jcmarker.c
+++ b/jpeg/jcmarker.c
@@ -428,32 +428,32 @@ emit_adobe_app14 (j_compress_ptr cinfo)
  * These routines allow writing an arbitrary marker with parameters.
  * The only intended use is to emit COM or APPn markers after calling
  * write_file_header and before calling write_frame_header.
  * Other uses are not guaranteed to produce desirable results.
  * Counting the parameter bytes properly is the caller's responsibility.
  */
 
 METHODDEF(void)
-write_marker_header (j_compress_ptr cinfo, int16 marker, unsigned int datalen)
+write_marker_header (j_compress_ptr cinfo, int marker, unsigned int datalen)
 /* Emit an arbitrary marker header */
 {
   if (datalen > (unsigned int) 65533)		/* safety check */
     ERREXIT(cinfo, JERR_BAD_LENGTH);
 
   emit_marker(cinfo, (JPEG_MARKER) marker);
 
   emit_2bytes(cinfo, (int16) (datalen + 2));	/* total length */
 }
 
 METHODDEF(void)
-write_marker_byte (j_compress_ptr cinfo, int16 val)
+write_marker_byte (j_compress_ptr cinfo, int val)
 /* Emit one byte of marker parameters following write_marker_header */
 {
-  emit_byte(cinfo, val);
+  emit_byte(cinfo, (int16) val);
 }
 
 
 /*
  * Write datastream header.
  * This consists of an SOI and optional APPn markers.
  * We recommend use of the JFIF marker, but not the Adobe marker,
  * when using YCbCr or grayscale data.  The JFIF marker should NOT
--- a/js/jsd/jsd.h
+++ b/js/jsd/jsd.h
@@ -343,16 +343,22 @@ jsd_DebuggerOnForUser(JSRuntime*        
                       void*              user);
 extern JSDContext*
 jsd_DebuggerOn(void);
 
 extern void
 jsd_DebuggerOff(JSDContext* jsdc);
 
 extern void
+jsd_DebuggerPause(JSDContext* jsdc, JSBool forceAllHooksOff);
+
+extern void
+jsd_DebuggerUnpause(JSDContext* jsdc);
+
+extern void
 jsd_SetUserCallbacks(JSRuntime* jsrt, JSD_UserCallbacks* callbacks, void* user);
 
 extern JSDContext*
 jsd_JSDContextForJSContext(JSContext* context);
 
 extern void*
 jsd_SetContextPrivate(JSDContext* jsdc, void *data);
 
--- a/js/jsd/jsd_high.c
+++ b/js/jsd/jsd_high.c
@@ -198,25 +198,29 @@ jsd_DebuggerOnForUser(JSRuntime*        
 {
     JSDContext* jsdc;
     JSContext* iter = NULL;
 
     jsdc = _newJSDContext(jsrt, callbacks, user);
     if( ! jsdc )
         return NULL;
 
-    /* set hooks here */
+    /*
+     * Set hooks here.  The new/destroy script hooks are on even when
+     * the debugger is paused.  The destroy hook so we'll clean up
+     * internal data structures when scripts are destroyed, and the
+     * newscript hook for backwards compatibility for now.  We'd like
+     * to stop doing that.
+     */
     JS_SetNewScriptHookProc(jsdc->jsrt, jsd_NewScriptHookProc, jsdc);
     JS_SetDestroyScriptHookProc(jsdc->jsrt, jsd_DestroyScriptHookProc, jsdc);
-    JS_SetDebuggerHandler(jsdc->jsrt, jsd_DebuggerHandler, jsdc);
-    JS_SetExecuteHook(jsdc->jsrt, jsd_TopLevelCallHook, jsdc);
-    JS_SetCallHook(jsdc->jsrt, jsd_FunctionCallHook, jsdc);
-    JS_SetObjectHook(jsdc->jsrt, jsd_ObjectHook, jsdc);
-    JS_SetThrowHook(jsdc->jsrt, jsd_ThrowHandler, jsdc);
-    JS_SetDebugErrorHook(jsdc->jsrt, jsd_DebugErrorHook, jsdc);
+    jsd_DebuggerUnpause(jsdc);
+    if (!(jsdc->flags & JSD_DISABLE_OBJECT_TRACE)) {
+        JS_SetObjectHook(jsdc->jsrt, jsd_ObjectHook, jsdc);
+    }
 #ifdef LIVEWIRE
     LWDBG_SetNewScriptHookProc(jsd_NewScriptHookProc, jsdc);
 #endif
     if( jsdc->userCallbacks.setContext )
         jsdc->userCallbacks.setContext(jsdc, jsdc->user);
     return jsdc;
 }
 
@@ -226,25 +230,23 @@ jsd_DebuggerOn(void)
     JS_ASSERT(_jsrt);
     JS_ASSERT(_validateUserCallbacks(&_callbacks));
     return jsd_DebuggerOnForUser(_jsrt, &_callbacks, _user);
 }
 
 void
 jsd_DebuggerOff(JSDContext* jsdc)
 {
+    jsd_DebuggerPause(jsdc, JS_TRUE);
     /* clear hooks here */
     JS_SetNewScriptHookProc(jsdc->jsrt, NULL, NULL);
     JS_SetDestroyScriptHookProc(jsdc->jsrt, NULL, NULL);
-    JS_SetDebuggerHandler(jsdc->jsrt, NULL, NULL);
-    JS_SetExecuteHook(jsdc->jsrt, NULL, NULL);
-    JS_SetCallHook(jsdc->jsrt, NULL, NULL);
+    /* Have to unset these too, since jsd_DebuggerPause only unsets
+       them conditionally */
     JS_SetObjectHook(jsdc->jsrt, NULL, NULL);
-    JS_SetThrowHook(jsdc->jsrt, NULL, NULL);
-    JS_SetDebugErrorHook(jsdc->jsrt, NULL, NULL);
 #ifdef LIVEWIRE
     LWDBG_SetNewScriptHookProc(NULL,NULL);
 #endif
 
     /* clean up */
     JSD_LockScriptSubsystem(jsdc);
     jsd_DestroyScriptManager(jsdc);
     JSD_UnlockScriptSubsystem(jsdc);
@@ -252,16 +254,40 @@ jsd_DebuggerOff(JSDContext* jsdc)
     
     _destroyJSDContext(jsdc);
 
     if( jsdc->userCallbacks.setContext )
         jsdc->userCallbacks.setContext(NULL, jsdc->user);
 }
 
 void
+jsd_DebuggerPause(JSDContext* jsdc, JSBool forceAllHooksOff)
+{
+    JS_SetDebuggerHandler(jsdc->jsrt, NULL, NULL);
+    if (forceAllHooksOff ||
+        (!(jsdc->flags & JSD_COLLECT_PROFILE_DATA) &&
+         (jsdc->flags & JSD_DISABLE_OBJECT_TRACE))) {
+        JS_SetExecuteHook(jsdc->jsrt, NULL, NULL);
+        JS_SetCallHook(jsdc->jsrt, NULL, NULL);
+    }
+    JS_SetThrowHook(jsdc->jsrt, NULL, NULL);
+    JS_SetDebugErrorHook(jsdc->jsrt, NULL, NULL);
+}
+
+void
+jsd_DebuggerUnpause(JSDContext* jsdc)
+{
+    JS_SetDebuggerHandler(jsdc->jsrt, jsd_DebuggerHandler, jsdc);
+    JS_SetExecuteHook(jsdc->jsrt, jsd_TopLevelCallHook, jsdc);
+    JS_SetCallHook(jsdc->jsrt, jsd_FunctionCallHook, jsdc);
+    JS_SetThrowHook(jsdc->jsrt, jsd_ThrowHandler, jsdc);
+    JS_SetDebugErrorHook(jsdc->jsrt, jsd_DebugErrorHook, jsdc);
+}
+
+void
 jsd_SetUserCallbacks(JSRuntime* jsrt, JSD_UserCallbacks* callbacks, void* user)
 {
     _jsrt = jsrt;
     _user = user;
 
 #ifdef JSD_HAS_DANGEROUS_THREAD
     _dangerousThread = JSD_CURRENT_THREAD();
 #endif
--- a/js/jsd/jsd_xpc.cpp
+++ b/js/jsd/jsd_xpc.cpp
@@ -240,20 +240,20 @@ jsds_RemoveEphemeral (LiveEphemeral **li
     
     PR_REMOVE_AND_INIT_LINK(&item->links);
 }
 
 /*******************************************************************************
  * utility functions for filters
  *******************************************************************************/
 void
-jsds_FreeFilter (FilterRecord *filter)
+jsds_FreeFilter (FilterRecord *rec)
 {
-    NS_IF_RELEASE (filter->filterObject);
-    delete filter;
+    NS_IF_RELEASE (rec->filterObject);
+    PR_Free (rec);
 }
 
 /* copies appropriate |filter| attributes into |rec|.
  * False return indicates failure, the contents of |rec| will not be changed.
  */
 PRBool
 jsds_SyncFilter (FilterRecord *rec, jsdIFilter *filter)
 {
@@ -2651,16 +2651,17 @@ jsdService::Pause(PRUint32 *_rval)
     if (++mPauseLevel == 1) {
         JSD_SetErrorReporter (mCx, NULL, NULL);
         JSD_ClearThrowHook (mCx);
         JSD_ClearInterruptHook (mCx);
         JSD_ClearDebuggerHook (mCx);
         JSD_ClearDebugBreakHook (mCx);
         JSD_ClearTopLevelHook (mCx);
         JSD_ClearFunctionHook (mCx);
+        JSD_DebuggerPause (mCx);
     }
 
     if (_rval)
         *_rval = mPauseLevel;
 
     return NS_OK;
 }
 
@@ -2672,16 +2673,17 @@ jsdService::UnPause(PRUint32 *_rval)
 
     if (mPauseLevel == 0)
         return NS_ERROR_NOT_AVAILABLE;
 
     /* check mOn before we muck with this stuff, it's possible the debugger
      * was turned off while we were paused.
      */
     if (--mPauseLevel == 0 && mOn) {
+        JSD_DebuggerUnpause (mCx);
         if (mErrorHook)
             JSD_SetErrorReporter (mCx, jsds_ErrorHookProc, NULL);
         if (mThrowHook)
             JSD_SetThrowHook (mCx, jsds_ExecutionHookProc, NULL);
         if (mInterruptHook)
             JSD_SetInterruptHook (mCx, jsds_ExecutionHookProc, NULL);
         if (mDebuggerHook)
             JSD_SetDebuggerHook (mCx, jsds_ExecutionHookProc, NULL);
--- a/js/jsd/jsdebug.c
+++ b/js/jsd/jsdebug.c
@@ -60,16 +60,29 @@ JSD_DebuggerOn(void)
 
 JSD_PUBLIC_API(void)
 JSD_DebuggerOff(JSDContext* jsdc)
 {
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     jsd_DebuggerOff(jsdc);
 }
 
+JSD_PUBLIC_API(void)
+JSD_DebuggerPause(JSDContext* jsdc)
+{
+    JSD_ASSERT_VALID_CONTEXT(jsdc);
+    jsd_DebuggerPause(jsdc, JS_FALSE);
+}
+
+JSD_PUBLIC_API(void)
+JSD_DebuggerUnpause(JSDContext* jsdc)
+{
+    JSD_ASSERT_VALID_CONTEXT(jsdc);
+    jsd_DebuggerUnpause(jsdc);
+}
 
 JSD_PUBLIC_API(uintN)
 JSD_GetMajorVersion(void)
 {
     return JSD_MAJOR_VERSION;
 }
 
 JSD_PUBLIC_API(uintN)
@@ -117,18 +130,36 @@ JSD_ClearAllProfileData(JSDContext *jsdc
 {
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     jsd_ClearAllProfileData(jsdc);    
 }
 
 JSD_PUBLIC_API(void)
 JSD_SetContextFlags(JSDContext *jsdc, uint32 flags)
 {
+    uint32 oldFlags = jsdc->flags;
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     jsdc->flags = flags;
+    if ((flags & JSD_COLLECT_PROFILE_DATA) ||
+        !(flags & JSD_DISABLE_OBJECT_TRACE)) {
+        // Need to reenable our call hooks now
+        JS_SetExecuteHook(jsdc->jsrt, jsd_TopLevelCallHook, jsdc);
+        JS_SetCallHook(jsdc->jsrt, jsd_FunctionCallHook, jsdc);
+    }
+    if ((oldFlags ^ flags) & JSD_DISABLE_OBJECT_TRACE) {
+        // Changing our JSD_DISABLE_OBJECT_TRACE flag
+        if (!(flags & JSD_DISABLE_OBJECT_TRACE)) {
+            // Need to reenable our object hooks now
+            if (jsd_InitObjectManager(jsdc))
+                JS_SetObjectHook(jsdc->jsrt, jsd_ObjectHook, jsdc);
+        } else {
+            jsd_DestroyObjectManager(jsdc);
+            JS_SetObjectHook(jsdc->jsrt, NULL, NULL);
+        }
+    }
 }
 
 JSD_PUBLIC_API(uint32)
 JSD_GetContextFlags(JSDContext *jsdc)
 {
     JSD_ASSERT_VALID_CONTEXT(jsdc);
     return jsdc->flags;
 }
--- a/js/jsd/jsdebug.h
+++ b/js/jsd/jsdebug.h
@@ -146,16 +146,28 @@ JSD_DebuggerOnForUser(JSRuntime*        
 
 /*
 * Shutdown JSD for this JSDContext
 */
 extern JSD_PUBLIC_API(void)
 JSD_DebuggerOff(JSDContext* jsdc);
 
 /*
+ * Pause JSD for this JSDContext
+ */
+extern JSD_PUBLIC_API(void)
+JSD_DebuggerPause(JSDContext* jsdc);
+
+/*
+ * Unpause JSD for this JSDContext
+ */
+extern JSD_PUBLIC_API(void)
+JSD_DebuggerUnpause(JSDContext* jsdc);
+
+/*
 * Get the Major Version (initial JSD release used major version = 1)
 */
 extern JSD_PUBLIC_API(uintN)
 JSD_GetMajorVersion(void);
 
 /*
 * Get the Minor Version (initial JSD release used minor version = 0)
 */
--- a/js/src/config/config.mk
+++ b/js/src/config/config.mk
@@ -250,17 +250,17 @@ OS_LDFLAGS += $(MOZ_MEMORY_LDFLAGS)
 endif
 
 # MOZ_DEBUG_SYMBOLS generates debug symbols in separate PDB files.
 # Used for generating an optimized build with debugging symbols.
 # Used in the Windows nightlies to generate symbols for crash reporting.
 ifdef MOZ_DEBUG_SYMBOLS
 OS_CXXFLAGS += -Zi -UDEBUG -DNDEBUG
 OS_CFLAGS += -Zi -UDEBUG -DNDEBUG
-OS_LDFLAGS += -DEBUG -OPT:REF -OPT:nowin98
+OS_LDFLAGS += -DEBUG -OPT:REF
 endif
 
 ifdef MOZ_QUANTIFY
 # -FIXED:NO is needed for Quantify to work, but it increases the size
 # of executables, so only use it if building for Quantify.
 WIN32_EXE_LDFLAGS += -FIXED:NO
 
 # We need -OPT:NOICF to prevent identical methods from being merged together.
--- a/js/src/config/rules.mk
+++ b/js/src/config/rules.mk
@@ -150,17 +150,17 @@ define _INSTALL_TESTS
 $(TEST_INSTALLER) $(wildcard $(srcdir)/$(dir)/*) $(testxpcobjdir)/$(MODULE)/$(dir)
 
 endef # do not remove the blank line!
 
 SOLO_FILE ?= $(error Specify a test filename in SOLO_FILE when using check-interactive or check-one)
 
 libs::
 	$(foreach dir,$(XPCSHELL_TESTS),$(_INSTALL_TESTS))
-	$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl \
+	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py \
           $(testxpcobjdir)/all-test-dirs.list \
           $(addprefix $(MODULE)/,$(XPCSHELL_TESTS))
 
 testxpcsrcdir = $(topsrcdir)/testing/xpcshell
 
 # Execute all tests in the $(XPCSHELL_TESTS) directories.
 # See also testsuite-targets.mk 'xpcshell-tests' target for global execution.
 xpcshell-tests:
@@ -819,23 +819,23 @@ endif
 #
 # Rule to create list of libraries for final link
 #
 export::
 ifdef LIBRARY_NAME
 ifdef EXPORT_LIBRARY
 ifdef IS_COMPONENT
 ifdef BUILD_STATIC_LIBS
-	@$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_LINK_COMPS) $(STATIC_LIBRARY_NAME)
+	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_COMPS) $(STATIC_LIBRARY_NAME)
 ifdef MODULE_NAME
-	@$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_LINK_COMP_NAMES) $(MODULE_NAME)
+	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_COMP_NAMES) $(MODULE_NAME)
 endif
 endif # BUILD_STATIC_LIBS
 else  # !IS_COMPONENT
-	$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
+	$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_LINK_LIBS) $(STATIC_LIBRARY_NAME)
 endif # IS_COMPONENT
 endif # EXPORT_LIBRARY
 endif # LIBRARY_NAME
 
 # Create dependencies on static (and shared EXTRA_DSO_LIBS) libraries
 LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(LIBS))
 HOST_LIBS_DEPS = $(filter %.$(LIB_SUFFIX), $(HOST_LIBS))
 DSO_LDOPTS_DEPS = $(EXTRA_DSO_LIBS) $(filter %.$(LIB_SUFFIX), $(EXTRA_DSO_LDOPTS))
@@ -885,17 +885,17 @@ else
 	$(INSTALL) $(IFLAGS1) $(LIBRARY) $(DIST)/lib
 endif
 endif # DIST_INSTALL
 endif # LIBRARY
 ifdef SHARED_LIBRARY
 ifdef IS_COMPONENT
 	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components
 	$(ELF_DYNSTR_GC) $(FINAL_TARGET)/components/$(SHARED_LIBRARY)
-	@$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_TARGET)/components/components.list $(SHARED_LIBRARY)
+	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.list $(SHARED_LIBRARY)
 ifdef BEOS_ADDON_WORKAROUND
 	( cd $(FINAL_TARGET)/components && $(CC) -nostart -o $(SHARED_LIBRARY).stub $(SHARED_LIBRARY) )
 endif
 else # ! IS_COMPONENT
 ifneq (,$(filter OS2 WINNT WINCE,$(OS_ARCH)))
 	$(INSTALL) $(IFLAGS2) $(IMPORT_LIBRARY) $(DIST)/lib
 else
 	$(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(DIST)/lib
@@ -1780,17 +1780,17 @@ GARBAGE_DIRS += $(JAVA_GEN_DIR)
 
 # generate .java files into _javagen/[package name dirs]
 _JAVA_GEN_DIR = $(JAVA_GEN_DIR)/$(JAVA_IFACES_PKG_NAME)
 $(_JAVA_GEN_DIR):
 	$(NSINSTALL) -D $@
 
 $(JAVA_GEN_DIR)/.%.java.pp: %.idl $(XPIDL_COMPILE) $(_JAVA_GEN_DIR)
 	$(REPORT_BUILD)
-	$(ELOG) $(XPIDL_COMPILE) -m java -w -I$(srcdir) -I$(IDL_DIR) -o $(_JAVA_GEN_DIR)/$* $(_VPATH_SRCS)
+	$(ELOG) $(XPIDL_COMPILE) -m java -w $(XPIDL_FLAGS) -I$(srcdir) -I$(IDL_DIR) -o $(_JAVA_GEN_DIR)/$* $(_VPATH_SRCS)
 	@touch $@
 
 # "Install" generated Java interfaces.  We segregate them based on the XPI_NAME.
 # If XPI_NAME is not set, install into the "default" directory.
 ifneq ($(XPI_NAME),)
 JAVA_INSTALL_DIR = $(JAVA_DIST_DIR)/$(XPI_NAME)
 else
 JAVA_INSTALL_DIR = $(JAVA_DIST_DIR)/default
@@ -1806,32 +1806,32 @@ endif # XPIDLSRCS
 endif # MOZ_JAVAXPCOM
 
 ################################################################################
 # Copy each element of EXTRA_COMPONENTS to $(FINAL_TARGET)/components
 ifdef EXTRA_COMPONENTS
 libs:: $(EXTRA_COMPONENTS)
 ifndef NO_DIST_INSTALL
 	$(INSTALL) $(IFLAGS1) $^ $(FINAL_TARGET)/components
-	@$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_TARGET)/components/components.list $(notdir $^)
+	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.list $(notdir $^)
 endif
 
 endif
 
 ifdef EXTRA_PP_COMPONENTS
 libs:: $(EXTRA_PP_COMPONENTS)
 ifndef NO_DIST_INSTALL
 	$(EXIT_ON_ERROR) \
 	$(NSINSTALL) -D $(FINAL_TARGET)/components; \
 	for i in $^; do \
 	  fname=`basename $$i`; \
 	  dest=$(FINAL_TARGET)/components/$${fname}; \
 	  $(RM) -f $$dest; \
 	  $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $$i > $$dest; \
-	  $(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(FINAL_TARGET)/components/components.list $$fname; \
+	  $(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.list $$fname; \
 	done
 endif
 
 endif
 
 ################################################################################
 # Copy each element of EXTRA_JS_MODULES to $(FINAL_TARGET)/modules
 ifdef EXTRA_JS_MODULES
--- a/js/src/config/system-headers
+++ b/js/src/config/system-headers
@@ -71,16 +71,17 @@ Button.h
 byteswap.h
 #if MOZ_ENABLE_LIBXUL!=1
 #define WRAP_CAIRO_HEADERS
 #endif
 #if MOZ_TREE_CAIRO!=1
 #define WRAP_CAIRO_HEADERS
 #endif
 #ifdef WRAP_CAIRO_HEADERS
+pixman.h
 cairo.h
 cairo-atsui.h
 cairo-beos.h
 cairo-ft.h
 cairo-glitz.h
 cairo-os2.h
 cairo-pdf.h
 cairo-ps.h
--- a/js/src/configure.in
+++ b/js/src/configure.in
@@ -485,16 +485,23 @@ case "$target" in
             AC_DEFINE(_CRT_NONSTDC_NO_DEPRECATE)
         elif test "$_CC_MAJOR_VERSION" = "15"; then
             _CC_SUITE=9
             CXXFLAGS="$CXXFLAGS -Zc:wchar_t-"
             LDFLAGS="$LDFLAGS -MANIFESTUAC:NO"
             _USE_DYNAMICBASE=1
             AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
             AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
+        elif test "$_CC_MAJOR_VERSION" = "16"; then
+            _CC_SUITE=10
+            CXXFLAGS="$CXXFLAGS -Zc:wchar_t-"
+            LDFLAGS="$LDFLAGS -MANIFESTUAC:NO"
+            _USE_DYNAMICBASE=1
+            AC_DEFINE(_CRT_SECURE_NO_WARNINGS)
+            AC_DEFINE(_CRT_NONSTDC_NO_WARNINGS)
         else
             AC_MSG_ERROR([This version of the MSVC compiler, $CC_VERSION , is unsupported.])
         fi
 
         _MOZ_RTTI_FLAGS_ON='-GR'
         _MOZ_RTTI_FLAGS_OFF='-GR-'
         _MOZ_EXCEPTIONS_FLAGS_ON='-EHsc'
         _MOZ_EXCEPTIONS_FLAGS_OFF=''
--- a/js/src/tests/js1_5/Regress/jstests.list
+++ b/js/src/tests/js1_5/Regress/jstests.list
@@ -109,17 +109,17 @@ script regress-290656.js
 script regress-294191.js
 script regress-294195-01.js
 script regress-294195-02.js
 script regress-294302.js
 script regress-295052.js
 script regress-295666.js
 script regress-299209.js
 script regress-299641.js
-skip-if(xulRuntime.XPCOMABI.match(/x86_64/)||xulRuntime.OS=="WINNT") script regress-303213.js # bug 524731
+skip-if(!xulRuntime.shell) script regress-303213.js # bug 524731
 script regress-306633.js
 script regress-306727.js
 script regress-306794.js
 script regress-308085.js
 script regress-308566.js
 script regress-309242.js
 script regress-310295.js
 script regress-310607.js
--- a/js/src/tests/js1_8_1/trace/jstests.list
+++ b/js/src/tests/js1_8_1/trace/jstests.list
@@ -1,14 +1,14 @@
 url-prefix ../../jsreftest.html?test=js1_8_1/trace/
 script math-trace-tests.js
 script regress-451673.js # slow
 script regress-451974-01.js
 random script regress-451974-02.js # bug 524734
-fails script regress-452498-01.js
+random script regress-452498-01.js
 script regress-458838.js
 script regress-462459-01.js
 script regress-462459-02.js
 script regress-462459-03.js
 script regress-462459-04.js
 script regress-462459-05.js
 script regress-462459-06.js
 script regress-462459-07.js
--- a/js/src/xpconnect/src/xpcjsruntime.cpp
+++ b/js/src/xpconnect/src/xpcjsruntime.cpp
@@ -439,17 +439,18 @@ void XPCJSRuntime::AddXPConnectRoots(JSC
 void XPCJSRuntime::UnrootContextGlobals()
 {
     mUnrootedGlobalCount = 0;
     JSContext *iter = nsnull, *acx;
     while((acx = JS_ContextIterator(GetJSRuntime(), &iter)))
     {
         NS_ASSERTION(!JS_HAS_OPTION(acx, JSOPTION_UNROOTED_GLOBAL),
                      "unrooted global should be set only during CC");
-        if(nsXPConnect::GetXPConnect()->GetRequestDepth(acx) == 0)
+        if(XPCPerThreadData::IsMainThreadContext(acx) &&
+           nsXPConnect::GetXPConnect()->GetRequestDepth(acx) == 0)
         {
             JS_ClearNewbornRoots(acx);
             if(acx->globalObject)
             {
                 JS_ToggleOptions(acx, JSOPTION_UNROOTED_GLOBAL);
                 ++mUnrootedGlobalCount;
             }
         }
--- a/js/src/xpconnect/src/xpcprivate.h
+++ b/js/src/xpconnect/src/xpcprivate.h
@@ -3436,16 +3436,21 @@ public:
         else if(sMainThreadData && sMainThreadData->mThread == PR_GetCurrentThread())
         {
             return sMainThreadData;
         }
 
         return GetDataImpl(cx);
     }
 
+    static inline JSBool IsMainThreadContext(JSContext *cx)
+    {
+        return cx->thread == sMainJSThread;
+    }
+
     static void CleanupAllThreads();
 
     ~XPCPerThreadData();
 
     nsresult GetException(nsIException** aException)
     {
         if(EnsureExceptionManager())
             return mExceptionManager->GetCurrentException(aException);
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -1461,17 +1461,19 @@ PRBool nsDisplayTransform::ComputeVisibi
 
   nsRegion untransformedVisibleBeforeMove;
   if (aVisibleRegionBeforeMove) {
     // mVisibleRect contains areas visible before and after the move, so it's
     // OK (although conservative) to just use the same regions here.
     untransformedVisibleBeforeMove = untransformedVisible;
   }
   mStoredList.ComputeVisibility(aBuilder, &untransformedVisible,
-                                &untransformedVisibleBeforeMove);
+                                aVisibleRegionBeforeMove
+                                  ? &untransformedVisibleBeforeMove
+                                  : nsnull);
   return PR_TRUE;
 }
 
 #ifdef DEBUG_HIT
 #include <time.h>
 #endif
 
 /* HitTest does some fun stuff with matrix transforms to obtain the answer. */
--- a/layout/base/nsStyleConsts.h
+++ b/layout/base/nsStyleConsts.h
@@ -753,17 +753,16 @@
 #define NS_STYLE_GRADIENT_SHAPE_ELLIPTICAL      1
 #define NS_STYLE_GRADIENT_SHAPE_CIRCULAR        2
 
 #define NS_STYLE_GRADIENT_SIZE_CLOSEST_SIDE     0
 #define NS_STYLE_GRADIENT_SIZE_CLOSEST_CORNER   1
 #define NS_STYLE_GRADIENT_SIZE_FARTHEST_SIDE    2
 #define NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER  3
 
-#ifdef MOZ_SVG
 // See nsStyleSVG
 
 // dominant-baseline
 #define NS_STYLE_DOMINANT_BASELINE_AUTO              0
 #define NS_STYLE_DOMINANT_BASELINE_USE_SCRIPT        1
 #define NS_STYLE_DOMINANT_BASELINE_NO_CHANGE         2
 #define NS_STYLE_DOMINANT_BASELINE_RESET_SIZE        3
 #define NS_STYLE_DOMINANT_BASELINE_IDEOGRAPHIC       4
@@ -812,18 +811,16 @@
 #define NS_STYLE_TEXT_RENDERING_OPTIMIZELEGIBILITY 2
 #define NS_STYLE_TEXT_RENDERING_GEOMETRICPRECISION 3
 
 // color-interpolation and color-interpolation-filters
 #define NS_STYLE_COLOR_INTERPOLATION_AUTO           0
 #define NS_STYLE_COLOR_INTERPOLATION_SRGB           1
 #define NS_STYLE_COLOR_INTERPOLATION_LINEARRGB      2
 
-#endif // MOZ_SVG
-
 /*****************************************************************************
  * Constants for media features.                                             *
  *****************************************************************************/
 
 // orientation
 #define NS_STYLE_ORIENTATION_PORTRAIT           0
 #define NS_STYLE_ORIENTATION_LANDSCAPE          1
 
--- a/layout/base/tests/scrolling_helper.html
+++ b/layout/base/tests/scrolling_helper.html
@@ -109,16 +109,30 @@ iframe {
 <iframe class="testcase" id="testClipIFRAME"
         src="data:text/html,<body class='testcase' style='margin:0; height:300px; background:-moz-linear-gradient(top, red, black);'>">
 </iframe>
 
 <iframe class="testcase" id="testClipIFRAME2" style="top:-50px"
         src="data:text/html,<body class='testcase' style='margin:0; height:300px; background:-moz-linear-gradient(top, red, black);'>">
 </iframe>
 
+<div id="testHiddenTable" class="testcase">
+  <table style="position:fixed; visibility:hidden; width:200px; height:200px; background:blue;">
+    <tr><td>Hidden stuff</td></tr>
+  </table>
+  <div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
+</div>
+
+<div id="testTableNoBackground" class="testcase">
+  <table style="position:fixed; width:200px; height:200px;">
+    <tr><td></td></tr>
+  </table>
+  <div style="height:300px; background:-moz-linear-gradient(top, red, black);"></div>
+</div>
+
 <script>
 var testcases = document.querySelectorAll("div.testcase");
 var tests = [];
 var iframes = document.querySelectorAll("iframe.testcase");
 
 var currentTest = -1;
 
 function ok(a, msg) {
@@ -276,16 +290,30 @@ function testClipIFRAME(blitRegion, pain
 
 function testClipIFRAME2(blitRegion, paintRegion) {
   ok(blitRegion.equalsRegion(new Region([[0,50,200,180]])),
      "Should blit everything that was already visible: " + blitRegion.toString());
 //  ok(paintRegion.equalsRegion(new Region([[0,180,200,200]])),
 //     "Should repaint area that was scrolled into view: " + paintRegion.toString());
 }
 
+function testHiddenTable(blitRegion, paintRegion) {
+  ok(blitRegion.equalsRegion(new Region([[0,0,200,180]])),
+     "Should blit everything that was already visible: " + blitRegion.toString());
+  ok(paintRegion.equalsRegion(new Region([[0,180,200,200]])),
+     "Should repaint area that was scrolled into view: " + paintRegion.toString());
+}
+
+function testTableNoBackground(blitRegion, paintRegion) {
+  ok(blitRegion.equalsRegion(new Region([[0,0,200,180]])),
+     "Should blit everything that was already visible: " + blitRegion.toString());
+  ok(paintRegion.equalsRegion(new Region([[0,180,200,200]])),
+     "Should repaint area that was scrolled into view: " + paintRegion.toString());
+}
+
 function clientRectToRect(cr)
 {
   return [cr.left, cr.top, cr.right, cr.bottom];
 }
 
 function regionForReason(requests, reason)
 {
   var rects = [];
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -975,17 +975,17 @@ static PRBool EthiopicToText(PRInt32 ord
 }
 
 
 /* static */ PRBool
 nsBulletFrame::AppendCounterText(PRInt32 aListStyleType,
                                  PRInt32 aOrdinal,
                                  nsString& result)
 {
-  PRBool success;
+  PRBool success = PR_TRUE;
   
   switch (aListStyleType) {
     case NS_STYLE_LIST_STYLE_NONE: // used by counters code only
       break;
 
     case NS_STYLE_LIST_STYLE_DISC: // used by counters code only
       // XXX We really need to do this the same way we do list bullets.
       result.Append(PRUnichar(0x2022));
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -923,17 +923,17 @@ nsIFrame::DisplayCaret(nsDisplayListBuil
   if (!IsVisibleForPainting(aBuilder))
     return NS_OK;
 
   return aLists.Content()->AppendNewToTop(
       new (aBuilder) nsDisplayCaret(this, aBuilder->GetCaret()));
 }
 
 PRBool
-nsFrame::HasBorder() const
+nsIFrame::HasBorder() const
 {
   // Border images contribute to the background of the content area
   // even if there's no border proper.
   return (GetUsedBorder() != nsMargin(0,0,0,0) ||
           GetStyleBorder()->IsBorderImageLoaded());
 }
 
 nsresult
@@ -3809,26 +3809,27 @@ SetRectProperty(nsIFrame* aFrame, nsIAto
 /**
  * @param aAnyOutlineOrEffects set to true if this frame has any
  * outline, SVG effects or box shadows that mean we need to invalidate
  * the whole overflow area if the frame's size changes.
  */
 static nsRect
 ComputeOutlineAndEffectsRect(nsIFrame* aFrame, PRBool* aAnyOutlineOrEffects,
                              const nsRect& aOverflowRect,
+                             const nsSize& aNewSize,
                              PRBool aStoreRectProperties) {
   nsRect r = aOverflowRect;
   *aAnyOutlineOrEffects = PR_FALSE;
 
   // box-shadow
   nsCSSShadowArray* boxShadows = aFrame->GetEffectiveBoxShadows();
   if (boxShadows) {
     nsRect shadows;
     for (PRUint32 i = 0; i < boxShadows->Length(); ++i) {
-      nsRect tmpRect = r;
+      nsRect tmpRect(nsPoint(0, 0), aNewSize);
       nsCSSShadowItem* shadow = boxShadows->ShadowAt(i);
 
       // inset shadows are never painted outside the frame
       if (shadow->mInset)
         continue;
       nscoord outsetRadius = shadow->mRadius + shadow->mSpread;
 
       tmpRect.MoveBy(nsPoint(shadow->mXOffset, shadow->mYOffset));
@@ -3982,17 +3983,18 @@ nsIFrame::CheckInvalidateSizeChange(cons
   // though root-invalidation is technically only needed in the case where
   // layer.RenderingMightDependOnFrameSize().  This allows us to simplify the
   // code somewhat and return immediately after invalidation in the earlier
   // cases.
 
   // Invalidate the entire old frame+outline if the frame has an outline
   PRBool anyOutlineOrEffects;
   nsRect r = ComputeOutlineAndEffectsRect(this, &anyOutlineOrEffects,
-                                          aOldOverflowRect, PR_FALSE);
+                                          aOldOverflowRect, aNewDesiredSize,
+                                          PR_FALSE);
   if (anyOutlineOrEffects) {
     r.UnionRect(aOldOverflowRect, r);
     InvalidateRectForFrameSizeChange(this, r);
     return;
   }
 
   // Invalidate the old frame border box if the frame has borders. Those
   // borders may be moving.
@@ -5553,17 +5555,17 @@ IsInlineFrame(nsIFrame *aFrame)
 
 nsRect
 nsIFrame::GetAdditionalOverflow(const nsRect& aOverflowArea,
                                 const nsSize& aNewSize,
                                 PRBool* aHasOutlineOrEffects)
 {
   nsRect overflowRect =
     ComputeOutlineAndEffectsRect(this, aHasOutlineOrEffects,
-                                 aOverflowArea, PR_TRUE);
+                                 aOverflowArea, aNewSize, PR_TRUE);
 
   // Absolute position clipping
   PRBool hasAbsPosClip;
   nsRect absPosClipRect;
   hasAbsPosClip = GetAbsPosClipRect(GetStyleDisplay(), &absPosClipRect, aNewSize);
   if (hasAbsPosClip) {
     overflowRect.IntersectRect(overflowRect, absPosClipRect);
   }
@@ -6304,16 +6306,22 @@ nsFrame::DoLayout(nsBoxLayoutState& aSta
       }
 
       // ensure our size is what we think is should be. Someone could have
       // reset the frame to be smaller or something dumb like that. 
       SetSize(nsSize(ourRect.width, ourRect.height));
     }
   }
 
+  // Should we do this if IsCollapsed() is true?
+  nsSize size(GetSize());
+  desiredSize.mOverflowArea.UnionRect(desiredSize.mOverflowArea,
+                                      nsRect(nsPoint(0, 0), size));
+  FinishAndStoreOverflow(&desiredSize.mOverflowArea, size);
+
   SyncLayout(aState);
 
   return rv;
 }
 
 nsresult
 nsFrame::BoxReflow(nsBoxLayoutState&        aState,
                    nsPresContext*           aPresContext,
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -536,21 +536,16 @@ public:
   CorrectStyleParentFrame(nsIFrame* aProspectiveParent, nsIAtom* aChildPseudo);
 
 protected:
   // Protected constructor and destructor
   nsFrame(nsStyleContext* aContext);
   virtual ~nsFrame();
 
   /**
-   * @return PR_FALSE if this frame definitely has no borders at all
-   */                 
-  PRBool HasBorder() const;
-
-  /**
    * To be called by |BuildDisplayLists| of this class or derived classes to add
    * a translucent overlay if this frame's content is selected.
    * @param aContentType an nsISelectionDisplay DISPLAY_ constant identifying
    * which kind of content this is for
    */
   nsresult DisplaySelectionOverlay(nsDisplayListBuilder* aBuilder,
       const nsDisplayListSet& aLists, PRUint16 aContentType = nsISelectionDisplay::DISPLAY_FRAMES);
 
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -877,16 +877,19 @@ nsHTMLScrollFrame::Reflow(nsPresContext*
   }
 
   aDesiredSize.width = state.mInsideBorderSize.width +
     state.mComputedBorder.LeftRight();
   aDesiredSize.height = state.mInsideBorderSize.height +
     state.mComputedBorder.TopBottom();
 
   aDesiredSize.mOverflowArea = nsRect(0, 0, aDesiredSize.width, aDesiredSize.height);
+
+  CheckInvalidateSizeChange(aDesiredSize);
+
   FinishAndStoreOverflow(&aDesiredSize);
 
   if (!InInitialReflow() && !mInner.mHadNonInitialReflow) {
     mInner.mHadNonInitialReflow = PR_TRUE;
     if (mInner.mIsRoot) {
       // For viewports, record whether we needed a vertical scrollbar
       // after the first non-initial reflow.
       mInner.SaveVScrollbarStateToGlobalHistory();
--- a/layout/generic/nsHTMLContainerFrame.h
+++ b/layout/generic/nsHTMLContainerFrame.h
@@ -37,32 +37,32 @@
 
 /* base class #2 for rendering objects that have child lists */
 
 #ifndef nsHTMLContainerFrame_h___
 #define nsHTMLContainerFrame_h___
 
 #include "nsContainerFrame.h"
 #include "gfxPoint.h"
+#include "nsIDeviceContext.h"
+
 class nsString;
 class nsAbsoluteFrame;
 class nsPlaceholderFrame;
 struct nsStyleDisplay;
 struct nsStylePosition;
 struct nsHTMLReflowMetrics;
 struct nsHTMLReflowState;
 class nsLineBox;
 
 // Some macros for container classes to do sanity checking on
 // width/height/x/y values computed during reflow.
 #ifdef DEBUG
-#define CRAZY_W 500000
-
-// 100000 lines, approximately. Assumes p2t is 15 and 15 pixels per line
-#define CRAZY_H 22500000
+#define CRAZY_W (1000000*nsIDeviceContext::AppUnitsPerCSSPixel())
+#define CRAZY_H CRAZY_W
 
 #define CRAZY_WIDTH(_x) (((_x) < -CRAZY_W) || ((_x) > CRAZY_W))
 #define CRAZY_HEIGHT(_y) (((_y) < -CRAZY_H) || ((_y) > CRAZY_H))
 #endif
 
 class nsDisplayTextDecoration;
 
 // Base class for html container frames that provides common
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -721,16 +721,21 @@ public:
   virtual void SetAdditionalStyleContext(PRInt32 aIndex,
                                          nsStyleContext* aStyleContext) = 0;
 
   // returns GetStyleBorder()->mBoxShadow unless this frame is using
   // -moz-appearance and is not chrome
   nsCSSShadowArray* GetEffectiveBoxShadows();
 
   /**
+   * @return PR_FALSE if this frame definitely has no borders at all
+   */                 
+  PRBool HasBorder() const;
+
+  /**
    * Accessor functions for geometric parent
    */
   nsIFrame* GetParent() const { return mParent; }
   NS_IMETHOD SetParent(const nsIFrame* aParent) { mParent = (nsIFrame*)aParent; return NS_OK; }
 
   /**
    * Bounding rect of the frame. The values are in app units, and the origin is
    * relative to the upper-left of the geometric parent. The size includes the
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -172,23 +172,21 @@ nsLineLayout::BeginLineReflow(nscoord aX
 {
   NS_ASSERTION(nsnull == mRootSpan, "bad linelayout user");
   NS_WARN_IF_FALSE(aWidth != NS_UNCONSTRAINEDSIZE,
                    "have unconstrained width; this should only result from "
                    "very large sizes, not attempts at intrinsic width "
                    "calculation");
 #ifdef DEBUG
   if ((aWidth != NS_UNCONSTRAINEDSIZE) && CRAZY_WIDTH(aWidth)) {
-    NS_NOTREACHED("bad width");
     nsFrame::ListTag(stdout, mBlockReflowState->frame);
     printf(": Init: bad caller: width WAS %d(0x%x)\n",
            aWidth, aWidth);
   }
   if ((aHeight != NS_UNCONSTRAINEDSIZE) && CRAZY_HEIGHT(aHeight)) {
-    NS_NOTREACHED("bad height");
     nsFrame::ListTag(stdout, mBlockReflowState->frame);
     printf(": Init: bad caller: height WAS %d(0x%x)\n",
            aHeight, aHeight);
   }
 #endif
 #ifdef NOISY_REFLOW
   nsFrame::ListTag(stdout, mBlockReflowState->frame);
   printf(": BeginLineReflow: %d,%d,%d,%d impacted=%s %s\n",
--- a/layout/reftests/bugs/376532-2-ref.html
+++ b/layout/reftests/bugs/376532-2-ref.html
@@ -1,14 +1,14 @@
 <!DOCTYPE html>
 <!-- Reftest for bug 376532: should show single missing glyph box for non-BMP
      characters (not surrogates)
      Test 2 is a non-equality test to catch the case where a single missing
      glyph box is shown with the high surrogate code point. The test page
-     contains U+0DDBAD and the reference page contains U+0DDB0D
+     contains U+0DDBAD (DB36 DF0D) and the reference page U+0DDB0D (DB36 DFAD)
 -->
 <html>
  <head>
   <meta http-equiv="content-type" content="text/html; charset=utf-8">
  </head>
   <style type="text/css">
 p {   
   font-size: 36pt;
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/438537-1-ref.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Testcase, bug 438537</title>
+  </head>
+  <body>
+    <div style="height:40px;border:solid 2px black;-moz-border-radius: 8px;overflow:hidden">
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/438537-1.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <title>Testcase, bug 438537</title>
+    <script>
+      window.addEventListener("MozReftestInvalidate",
+        function() {
+          var div = document.getElementById("div");
+          div.style.height = "40px";
+          document.documentElement.className = "";
+        }, false);
+    </script>
+  </head>
+  <body>
+    <div id="div" style="height:20px;border:solid 2px black;-moz-border-radius: 8px;overflow:hidden">
+    </div>
+  </body>
+</html>
--- a/layout/reftests/bugs/461512-1-ref.html
+++ b/layout/reftests/bugs/461512-1-ref.html
@@ -1,18 +1,68 @@
 <html>
   <head>
     <style type="text/css">
-      body { background-color: white; opacity: 0.5; }
-      p { border: 10px solid rgb(10%, 20%, 30%);
+      body { background-color: white; margin: 0; padding: 0; }
+      div.mask {
+        position: absolute;
+        width: 10px;
+        height: 10px;
+        background-color: white;
+      }
+      div.tr {
+        right: 10px;
+      }
+      div.tl {
+        left: 10px;
+      }
+      div.bl {
+        left: 10px;
+        margin-top: 20px;
+      }
+      div.br {
+        right: 10px;
+        margin-top: 20px;
+      }
+      p {
+        margin: 10px;
+        padding: 0;
+        border: 10px solid rgb(227, 207, 187);
+        height: 10px;
+      }
+      p.groove, p.ridge {
+        border-width: 5px;
+        height: 20px;
+      }
+      p.groove > span, p.ridge > span {
+        border: 5px solid;
+        margin: 0;
+        padding: 0;
+        display: block;
+        height: 10px;
+      }
+      p.inset, p.groove, p.ridge > span {
+        border-color: rgb(182, 171, 160) rgb(246, 240, 234) rgb(246, 240, 234) rgb(182, 171, 160);
+      }
+      p.outset, p.ridge, p.groove > span {
+        border-color: rgb(246, 240, 234) rgb(182, 171, 160) rgb(182, 171, 160) rgb(246, 240, 234);
+      }
     </style>
   </head>
   <body>
     <p style="border-style: solid;">&nbsp;</p>
     <p style="border-style: dashed;">&nbsp;</p>
     <!-- <p style="border-style: dotted;">&nbsp;</p> -->
     <p style="border-style: double;">&nbsp;</p>
-    <p style="border-style: ridge;">&nbsp;</p>
-    <p style="border-style: groove;">&nbsp;</p>
-    <p style="border-style: inset;">&nbsp;</p>
-    <p style="border-style: outset;">&nbsp;</p>
+    <div class="mask tr"></div>
+    <div class="mask bl"></div>
+    <p class="ridge"><span>&nbsp;</span></p>
+    <div class="mask tr"></div>
+    <div class="mask bl"></div>
+    <p class="groove"><span>&nbsp;</span></p>
+    <div class="mask tr"></div>
+    <div class="mask bl"></div>
+    <p class="inset">&nbsp;</p>
+    <div class="mask tr"></div>
+    <div class="mask bl"></div>
+    <p class="outset">&nbsp;</p>
   </body>
 </html>
--- a/layout/reftests/bugs/461512-1.html
+++ b/layout/reftests/bugs/461512-1.html
@@ -1,18 +1,59 @@
 <html>
   <head>
     <style type="text/css">
-      body { background-color: white; }
-      p { border: 10px solid rgba(10%, 20%, 30%, 0.5);
+      body { background-color: white; margin: 0; padding: 0; }
+      p {
+        margin: 10px;
+        padding: 0;
+        border: 10px solid rgba(200, 160, 120, 0.5);
+        height: 10px;
+      }
+
+      /**
+       * XXX we cannot test the corner by this testing because when the corner
+       *     is joined with anti-aliased, the edge isn't matching with the
+       *     reference.  The dotted line's anti-aliasing is same.
+       */
+
+      /* Cover the coners by the white div element */
+      div {
+        position: absolute;
+        width: 10px;
+        height: 10px;
+        background-color: white;
+      }
+      div.tr {
+        right: 10px;
+      }
+      div.tl {
+        left: 10px;
+      }
+      div.bl {
+        left: 10px;
+        margin-top: 20px;
+      }
+      div.br {
+        right: 10px;
+        margin-top: 20px;
+      }
     </style>
   </head>
   <body>
     <p style="border-style: solid;">&nbsp;</p>
     <p style="border-style: dashed;">&nbsp;</p>
     <!-- <p style="border-style: dotted;">&nbsp;</p> -->
     <p style="border-style: double;">&nbsp;</p>
+    <div class="tr"></div>
+    <div class="bl"></div>
     <p style="border-style: ridge;">&nbsp;</p>
+    <div class="tr"></div>
+    <div class="bl"></div>
     <p style="border-style: groove;">&nbsp;</p>
+    <div class="tr"></div>
+    <div class="bl"></div>
     <p style="border-style: inset;">&nbsp;</p>
+    <div class="tr"></div>
+    <div class="bl"></div>
     <p style="border-style: outset;">&nbsp;</p>
   </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/514917-1-ref.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<title>Testcase, bug 514917</title>
+<style type="text/css">
+
+body > div > div {
+  width: 100px;
+  height: 100px;
+  -moz-box-shadow: blue 50px 50px;
+}
+
+body > div > div > div {
+  width: 160px;
+  height: 160px;
+  border: medium solid;
+}
+
+</style>
+<body>
+<div><div><div></div></div></div>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/514917-1.html
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<title>Testcase, bug 514917</title>
+<style type="text/css">
+
+body > div {
+  overflow: auto; /* to detect too much overflow, which is the bug here */
+  width: 200px;
+  height: 200px;
+}
+
+body > div > div {
+  width: 100px;
+  height: 100px;
+  -moz-box-shadow: blue 50px 50px;
+}
+
+body > div > div > div {
+  width: 160px;
+  height: 160px;
+  border: medium solid;
+}
+
+</style>
+<body>
+<div><div><div></div></div></div>
+</body>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/526463-1-ref.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+  <head>
+    <title>Testcase, bug 526463</title>
+  </head>
+  <body>
+    <div style="-moz-border-radius: 50px;overflow:hidden;background:gold">
+      outer div
+      <div>inner div</div>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/526463-1.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html class="reftest-wait">
+  <head>
+    <title>Testcase, bug 526463</title>
+    <script>
+      window.addEventListener("MozReftestInvalidate",
+        function() {
+          var div = document.getElementById("div");
+          div.style.display = "";
+          document.documentElement.className = "";
+        }, false);
+    </script>
+  </head>
+  <body>
+    <div style="-moz-border-radius: 50px;overflow:hidden;background:gold">
+      outer div
+      <div id="div" style="display:none">inner div</div>
+    </div>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/531098-1-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE HTML>
+<style type="text/css">
+html, body { margin: 0; padding: 0; border: none; }
+</style>
+
+<div style="position: absolute; width: 200px; height: 400px; top: 100px; left: 100px; -moz-box-shadow: 0 0 20px blue">A</div>
+<div style="position: absolute; width: 100px; height: 400px; top: 100px; left: 400px; -moz-box-shadow: 0 0 20px blue">B</div>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/bugs/531098-1.html
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML>
+<style type="text/css">
+html, body { margin: 0; padding: 0; border: none; }
+</style>
+
+<div style="margin: 100px; height: 400px; width: 400px; display: -moz-box; -moz-box-orient: horizontal">
+
+  <div style="width: 200px; -moz-box-shadow: 0 0 20px blue">A</div>
+  <div style="width: 100px"></div>
+  <div style="-moz-box-flex: 1; -moz-box-shadow: 0 0 20px blue">B</div>
+
+</div>
--- a/layout/reftests/bugs/reftest.list
+++ b/layout/reftests/bugs/reftest.list
@@ -1054,16 +1054,17 @@ fails == 428810-3e-rtl-insets.html 42881
 == 430412-1.html 430412-1-ref.html
 == 430813-1.html 430813-1-ref.html
 == 430813-2.html 430813-2-ref.html
 == 430813-3.html 430813-3-ref.html
 == 431341-1.html 431341-1-ref.html
 == 431341-2.html 431341-2-ref.html
 == 431520-1.html 431520-1-ref.html
 == 431948-1.html 431948-1-ref.html
+== 438537-1.html 438537-1-ref.html
 == 440112.html 440112-ref.html
 == 433640-1.html 433640-1-ref.html
 == 433700.html 433700-ref.html
 == 436356-1.html 436356-1-ref.html
 == 436356-2.html 436356-2-ref.html
 == 438981-1.xhtml about:blank
 == 438987-1.html 438987-1-ref.html
 == 438987-2a.html 438987-2-ref.html
@@ -1143,17 +1144,17 @@ fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") ==
 == 458487-4b.html 458487-4-ref.html
 == 458487-4c.html 458487-4-ref.html
 == 458487-5a.html 458487-5-ref.html
 == 458487-5b.html 458487-5-ref.html
 == 459443-1.html 459443-1-ref.html
 == 459613-1.html 459613-1-ref.html
 == 460012-1.html 460012-1-ref.html
 == 461266-1.html 461266-1-ref.html
-fails == 461512-1.html 461512-1-ref.html # Bug 461512
+== 461512-1.html 461512-1-ref.html
 == 462844-1.html 462844-ref.html
 == 462844-2.html 462844-ref.html
 == 462844-3.html 462844-ref.html
 == 462844-4.html 462844-ref.html
 == 463204-1.html 463204-1-ref.html
 == 463217-1.xul 463217-1-ref.xul
 == 463952-1.html 463952-1-ref.html
 == 464811-1.html 464811-1-ref.html
@@ -1324,28 +1325,31 @@ fails-if(MOZ_WIDGET_TOOLKIT!="cocoa") ==
 == 512631-1.html 512631-1-ref.html
 == 513153-1a.html 513153-1-ref.html
 == 513153-1b.html 513153-1-ref.html
 == 513153-2a.html 513153-2-ref.html
 == 513153-2b.html 513153-2-ref.html
 == 513318-1.xul 513318-1-ref.xul
 != 513318-2.xul 513318-2-ref.xul
 != 513318-3.xul 513318-3-ref.xul
+== 514917-1.html 514917-1-ref.html
 == 520421-1.html 520421-1-ref.html
 == 520563-1.xhtml 520563-1-ref.xhtml
 == 521525-1.html 521525-1-ref.html
 == 521525-2.html 521525-2-ref.html
 == 521539-1.html 521539-1-ref.html
 == 521542-1.xhtml 521542-1-ref.xhtml
 == 521685-1.html 521685-1-ref.html
 == 523096-1.html 523096-1-ref.html
 == 523468-1.html 523468-1-ref.html
 == 524175-1.html 524175-1-ref.html
+== 526463-1.html 526463-1-ref.html
 == 527464-1.html 527464-ref.html
 == 528038-1a.html 528038-1-ref.html
 == 528038-1b.html 528038-1-ref.html
 == 528038-1c.html 528038-1-ref.html
 == 528038-1d.html 528038-1-ref.html
 == 528038-1e.html 528038-1-ref.html
 == 528038-1f.html 528038-1-ref.html
 == 528038-2.html 528038-2-ref.html
 == 530686-1.html 530686-1-ref.html
+== 531098-1.html 531098-1-ref.html
 == 531371-1.html 531371-1-ref.html
--- a/layout/reftests/font-face/src-list-local-full-quotes.html
+++ b/layout/reftests/font-face/src-list-local-full-quotes.html
@@ -10,28 +10,28 @@ body {
   margin: 50px;
   font-size: 24pt;
 }
 
 /* use full names */
 
 @font-face {
   font-family: test-regular;
-  src: local("Helvetica Neue"), local("Bitstream Vera Sans"), local("Bitstream Vera Sans Roman"), local("Arial");
+  src: local("Helvetica Neue"), local("Bitstream Vera Sans"), local("Bitstream Vera Sans Roman"), local("Free Sans"), local("Arial");
 }
 
 /* use Helvetica on the Mac, since Futura has no bold face on 10.4, 10.5 */
 @font-face {
   font-family: test-bold;
-  src: local("Helvetica Neue Bold"), local("Bitstream Vera Sans Bold"), local("Arial Bold");
+  src: local("Helvetica Neue Bold"), local("Bitstream Vera Sans Bold"), local("Free Sans Bold"), local("Arial Bold");
 }
 
 @font-face {
   font-family: test-italic;
-  src: local("Helvetica Neue Italic"), local("Bitstream Vera Sans Oblique"), local("Arial Italic");
+  src: local("Helvetica Neue Italic"), local("Bitstream Vera Sans Oblique"), local("Free Sans Oblique"), local("Arial Italic");
 }
 
 .regular { font-family: test-regular, serif; }
 .bold { font-family: test-bold, serif; }
 .italic { font-family: test-italic, serif; }
 
 </style>
   
--- a/layout/reftests/font-face/src-list-local-full-ref.html
+++ b/layout/reftests/font-face/src-list-local-full-ref.html
@@ -8,17 +8,17 @@
 
 body {
   margin: 50px;
   font-size: 24pt;
 }
 
 /* use full names */
 
-p { font-family: Helvetica Neue, Bitstream Vera Sans, Arial, serif; }
+p { font-family: Helvetica Neue, Bitstream Vera Sans, FreeSans, Arial, serif; }
 
 .regular {  }
 .bold { font-weight: bold; }
 .italic { font-style: italic; }
 
 </style>
   
 <script type="text/javascript">
@@ -30,9 +30,9 @@ p { font-family: Helvetica Neue, Bitstre
 
 <p class="regular">This should be a sans-serif face</p>
 
 <p class="bold">This should be a bold sans-serif face</p>
 
 <p class="italic">This should be an italic sans-serif face</p>
 
 </body>
-</html>
\ No newline at end of file
+</html>
--- a/layout/reftests/font-face/src-list-local-full.html
+++ b/layout/reftests/font-face/src-list-local-full.html
@@ -10,28 +10,28 @@ body {
   margin: 50px;
   font-size: 24pt;
 }
 
 /* use full names */
 
 @font-face {
   font-family: test-regular;
-  src: local(Helvetica Neue), local(Bitstream Vera Sans), local(Bitstream Vera Sans Roman), local(Arial);
+  src: local(Helvetica Neue), local(Bitstream Vera Sans), local(Bitstream Vera Sans Roman), local(Free Sans), local(Arial);
 }
 
 /* use Helvetica on the Mac, since Futura has no bold face on 10.4, 10.5 */
 @font-face {
   font-family: test-bold;
-  src: local(Helvetica Neue Bold), local(Bitstream Vera Sans Bold), local(Arial Bold);
+  src: local(Helvetica Neue Bold), local(Bitstream Vera Sans Bold), local(Free Sans Bold), local(Arial Bold);
 }
 
 @font-face {
   font-family: test-italic;
-  src: local(Helvetica Neue Italic), local(Bitstream Vera Sans Oblique), local(Arial Italic);
+  src: local(Helvetica Neue Italic), local(Bitstream Vera Sans Oblique), local(Free Sans Oblique), local(Arial Italic);
 }
 
 .regular { font-family: test-regular, serif; }
 .bold { font-family: test-bold, serif; }
 .italic { font-family: test-italic, serif; }
 
 </style>
   
--- a/layout/reftests/table-background/reftest.list
+++ b/layout/reftests/table-background/reftest.list
@@ -46,8 +46,12 @@ fails == border-collapse-opacity-table-c
 == border-collapse-opacity-table-row.html border-collapse-opacity-table-row-ref.html
 == border-collapse-opacity-table.html border-collapse-opacity-table-ref.html
 == border-separate-opacity-table-cell.html border-separate-opacity-table-cell-ref.html
 fails == border-separate-opacity-table-column-group.html border-separate-opacity-table-column-group-ref.html # bug 424274
 fails == border-separate-opacity-table-column.html border-separate-opacity-table-column-ref.html # bug 424274
 == border-separate-opacity-table-row-group.html border-separate-opacity-table-row-group-ref.html
 == border-separate-opacity-table-row.html border-separate-opacity-table-row-ref.html
 == border-separate-opacity-table.html border-separate-opacity-table-ref.html
+!= scrollable-rowgroup-collapse-background.html scrollable-rowgroup-collapse-notref.html
+!= scrollable-rowgroup-collapse-border.html scrollable-rowgroup-collapse-notref.html
+!= scrollable-rowgroup-separate-background.html scrollable-rowgroup-separate-notref.html
+!= scrollable-rowgroup-separate-border.html scrollable-rowgroup-separate-notref.html
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-background/scrollable-rowgroup-collapse-background.html
@@ -0,0 +1,6 @@
+<title>Testcase for assertion fix in bug 531461</title>
+<table style="border-collapse:collapse">
+  <tbody style="overflow:scroll; background:yellow">
+    <tr><td>Cell</td></tr>
+  </tbody>
+</table>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-background/scrollable-rowgroup-collapse-border.html
@@ -0,0 +1,6 @@
+<title>Testcase for assertion fix in bug 531461</title>
+<table style="border-collapse:collapse">
+  <tbody style="overflow:scroll; border: medium solid black">
+    <tr><td>Cell</td></tr>
+  </tbody>
+</table>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-background/scrollable-rowgroup-collapse-notref.html
@@ -0,0 +1,6 @@
+<title>Testcase for assertion fix in bug 531461</title>
+<table style="border-collapse:collapse">
+  <tbody style="overflow:scroll">
+    <tr><td>Cell</td></tr>
+  </tbody>
+</table>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-background/scrollable-rowgroup-separate-background.html
@@ -0,0 +1,6 @@
+<title>Testcase for assertion fix in bug 531461</title>
+<table>
+  <tbody style="overflow:scroll; background:yellow">
+    <tr><td>Cell</td></tr>
+  </tbody>
+</table>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-background/scrollable-rowgroup-separate-border.html
@@ -0,0 +1,6 @@
+<title>Testcase for assertion fix in bug 531461</title>
+<table>
+  <tbody style="overflow:scroll; border: medium solid black">
+    <tr><td>Cell</td></tr>
+  </tbody>
+</table>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/table-background/scrollable-rowgroup-separate-notref.html
@@ -0,0 +1,6 @@
+<title>Testcase for assertion fix in bug 531461</title>
+<table>
+  <tbody style="overflow:scroll">
+    <tr><td>Cell</td></tr>
+  </tbody>
+</table>
--- a/layout/style/nsCSSDataBlock.h
+++ b/layout/style/nsCSSDataBlock.h
@@ -211,19 +211,17 @@ public:
     nsCSSColor mColor;
     nsCSSContent mContent;
     nsCSSText mText;
     nsCSSUserInterface mUserInterface;
     nsCSSAural mAural;
     nsCSSPage mPage;
     nsCSSBreaks mBreaks;
     nsCSSXUL mXUL;
-#ifdef MOZ_SVG
     nsCSSSVG mSVG;
-#endif
     nsCSSColumn mColumn;
 
     /**
      * Transfer all of the state from the compressed block to this
      * expanded block.  The state of this expanded block must be clear
      * beforehand.
      *
      * The compressed block passed in IS RELEASED by this method and
--- a/layout/style/nsCSSDeclaration.cpp
+++ b/layout/style/nsCSSDeclaration.cpp
@@ -1093,29 +1093,27 @@ nsCSSDeclaration::GetValue(nsCSSProperty
         // The sublists are different lengths, so this can't be
         // represented as the shorthand.
         aValue.Truncate();
       }
 #undef NUM_TRANSITION_SUBPROPS
       break;
     }
 
-#ifdef MOZ_SVG
     case eCSSProperty_marker: {
       const nsCSSValue &endValue =
         *data->ValueStorageFor(eCSSProperty_marker_end);
       const nsCSSValue &midValue =
         *data->ValueStorageFor(eCSSProperty_marker_mid);
       const nsCSSValue &startValue =
         *data->ValueStorageFor(eCSSProperty_marker_start);
       if (endValue == midValue && midValue == startValue)
         AppendValueToString(eCSSProperty_marker_end, aValue);
       break;
     }
-#endif
     default:
       NS_NOTREACHED("no other shorthands");
       break;
   }
   return NS_OK;
 }
 
 PRBool
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -587,17 +587,16 @@ CSS_KEY(button-focus, buttonfocus)
 CSS_KEY(-moz-win-media-toolbox, _moz_win_media_toolbox)
 CSS_KEY(-moz-win-communications-toolbox, _moz_win_communications_toolbox)
 CSS_KEY(-moz-win-browsertabbar-toolbox, _moz_win_browsertabbar_toolbox)
 CSS_KEY(-moz-win-mediatext, _moz_win_mediatext)
 CSS_KEY(-moz-win-communicationstext, _moz_win_communicationstext)
 CSS_KEY(-moz-win-glass, _moz_win_glass)
 CSS_KEY(-moz-mac-unified-toolbar, _moz_mac_unified_toolbar)
 
-#ifdef MOZ_SVG
 CSS_KEY(alphabetic, alphabetic)
 CSS_KEY(bevel, bevel)
 CSS_KEY(butt, butt)
 CSS_KEY(central, central)
 CSS_KEY(crispedges, crispedges)
 //CSS_KEY(end, end)
 CSS_KEY(evenodd, evenodd)
 CSS_KEY(geometricprecision, geometricprecision)
@@ -615,9 +614,8 @@ CSS_KEY(optimizespeed, optimizespeed)
 CSS_KEY(reset-size, reset_size)
 //CSS_KEY(square, square)
 //CSS_KEY(start, start)
 CSS_KEY(srgb, srgb)
 CSS_KEY(text-after-edge, text_after_edge)
 CSS_KEY(text-before-edge, text_before_edge)
 CSS_KEY(use-script, use_script)
 CSS_KEY(-moz-crisp-edges, _moz_crisp_edges)
-#endif
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -2692,17 +2692,16 @@ CSS_PROP_FONT(
     mScriptMinSize,
     eCSSType_Value,
     nsnull,
     CSS_PROP_NO_OFFSET,
     eStyleAnimType_None)
 #endif
 #endif
 
-#ifdef MOZ_SVG
 // XXX treat SVG's CSS Properties as internal for now.
 // Do we want to create an nsIDOMSVGCSS2Properties interface?
 #ifndef CSS_PROP_LIST_EXCLUDE_INTERNAL
 CSS_PROP_SVGRESET(
     clip-path,
     clip_path,
     ClipPath,
     0,
@@ -3032,17 +3031,16 @@ CSS_PROP_SVG(
     0,
     SVG,
     mTextRendering,
     eCSSType_Value,
     kTextRenderingKTable,
     offsetof(nsStyleSVG, mTextRendering),
     eStyleAnimType_EnumU8)
 #endif /* !defined (CSS_PROP_LIST_EXCLUDE_INTERNAL) */
-#endif
 
 // Callers that want information on the properties that are in
 // the style structs but not in the nsCSS* structs should define
 // |CSS_PROP_INCLUDE_NOT_CSS|.  (Some of these are also in nsRuleData*,
 // and a distinction might be needed at some point.)
 // The first 3 parameters don't matter, but some compilers don't like
 // empty arguments to macros.
 #ifdef CSS_PROP_INCLUDE_NOT_CSS
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1299,17 +1299,16 @@ const PRInt32 nsCSSProps::kBoxOrientKTab
 const PRInt32 nsCSSProps::kBoxPackKTable[] = {
   eCSSKeyword_start,  NS_STYLE_BOX_PACK_START,
   eCSSKeyword_center,   NS_STYLE_BOX_PACK_CENTER,
   eCSSKeyword_end, NS_STYLE_BOX_PACK_END,
   eCSSKeyword_justify, NS_STYLE_BOX_PACK_JUSTIFY,
   eCSSKeyword_UNKNOWN,-1
 };
 
-#ifdef MOZ_SVG
 // keyword tables for SVG properties
 
 const PRInt32 nsCSSProps::kDominantBaselineKTable[] = {
   eCSSKeyword_auto, NS_STYLE_DOMINANT_BASELINE_AUTO,
   eCSSKeyword_use_script, NS_STYLE_DOMINANT_BASELINE_USE_SCRIPT,
   eCSSKeyword_no_change, NS_STYLE_DOMINANT_BASELINE_NO_CHANGE,
   eCSSKeyword_reset_size, NS_STYLE_DOMINANT_BASELINE_RESET_SIZE,
   eCSSKeyword_alphabetic, NS_STYLE_DOMINANT_BASELINE_ALPHABETIC,
@@ -1376,18 +1375,16 @@ const PRInt32 nsCSSProps::kTextRendering
 
 const PRInt32 nsCSSProps::kColorInterpolationKTable[] = {
   eCSSKeyword_auto, NS_STYLE_COLOR_INTERPOLATION_AUTO,
   eCSSKeyword_srgb, NS_STYLE_COLOR_INTERPOLATION_SRGB,
   eCSSKeyword_linearrgb, NS_STYLE_COLOR_INTERPOLATION_LINEARRGB,
   eCSSKeyword_UNKNOWN, -1
 };
 
-#endif
-
 PRBool
 nsCSSProps::FindKeyword(nsCSSKeyword aKeyword, const PRInt32 aTable[], PRInt32& aResult)
 {
   PRInt32 index = 0;
   while (eCSSKeyword_UNKNOWN != nsCSSKeyword(aTable[index])) {
     if (aKeyword == nsCSSKeyword(aTable[index])) {
       aResult = aTable[index+1];
       return PR_TRUE;
@@ -1950,23 +1947,21 @@ static const nsCSSProperty gPauseSubprop
 static const nsCSSProperty gMozTransitionSubpropTable[] = {
   eCSSProperty_transition_property,
   eCSSProperty_transition_duration,
   eCSSProperty_transition_timing_function,
   eCSSProperty_transition_delay,
   eCSSProperty_UNKNOWN
 };
 
-#ifdef MOZ_SVG
 static const nsCSSProperty gMarkerSubpropTable[] = {
   eCSSProperty_marker_start,
   eCSSProperty_marker_mid,
   eCSSProperty_marker_end,
   eCSSProperty_UNKNOWN
 };
-#endif
 
 const nsCSSProperty *const
 nsCSSProps::kSubpropertyTable[eCSSProperty_COUNT - eCSSProperty_COUNT_no_shorthands] = {
 #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_) g##method_##SubpropTable,
 #include "nsCSSPropList.h"
 #undef CSS_PROP_SHORTHAND
 };
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -243,27 +243,25 @@ public:
   static const PRInt32 kBorderColorKTable[];
   static const PRInt32 kBorderImageKTable[];
   static const PRInt32 kBorderStyleKTable[];
   static const PRInt32 kBorderWidthKTable[];
   static const PRInt32 kBoxAlignKTable[];
   static const PRInt32 kBoxDirectionKTable[];
   static const PRInt32 kBoxOrientKTable[];
   static const PRInt32 kBoxPackKTable[];
-#ifdef MOZ_SVG
   static const PRInt32 kDominantBaselineKTable[];
   static const PRInt32 kFillRuleKTable[];
   static const PRInt32 kImageRenderingKTable[];
   static const PRInt32 kShapeRenderingKTable[];
   static const PRInt32 kStrokeLinecapKTable[];
   static const PRInt32 kStrokeLinejoinKTable[];
   static const PRInt32 kTextAnchorKTable[];
   static const PRInt32 kTextRenderingKTable[];
   static const PRInt32 kColorInterpolationKTable[];
-#endif
   static const PRInt32 kBoxPropSourceKTable[];
   static const PRInt32 kBoxShadowTypeKTable[];
   static const PRInt32 kBoxSizingKTable[];
   static const PRInt32 kCaptionSideKTable[];
   static const PRInt32 kClearKTable[];
   static const PRInt32 kColorKTable[];
   static const PRInt32 kContentKTable[];
   static const PRInt32 kCursorKTable[];
--- a/layout/style/nsCSSStruct.cpp
+++ b/layout/style/nsCSSStruct.cpp
@@ -459,23 +459,20 @@ nsCSSColumn::nsCSSColumn(void)
   MOZ_COUNT_CTOR(nsCSSColumn);
 }
 
 nsCSSColumn::~nsCSSColumn(void)
 {
   MOZ_COUNT_DTOR(nsCSSColumn);
 }
 
-#ifdef MOZ_SVG
 // --- nsCSSSVG -----------------
 
 nsCSSSVG::nsCSSSVG(void) : mStrokeDasharray(nsnull)
 {
   MOZ_COUNT_CTOR(nsCSSSVG);
 }
 
 nsCSSSVG::~nsCSSSVG(void)
 {
   MOZ_COUNT_DTOR(nsCSSSVG);
   delete mStrokeDasharray;
 }
-
-#endif // MOZ_SVG
--- a/layout/style/nsCSSStruct.h
+++ b/layout/style/nsCSSStruct.h
@@ -667,17 +667,16 @@ private:
 };
 
 struct nsRuleDataColumn : public nsCSSColumn {
   nsRuleDataColumn() {}
 private:
   nsRuleDataColumn(const nsRuleDataColumn& aOther); // NOT IMPLEMENTED
 };
 
-#ifdef MOZ_SVG
 struct nsCSSSVG : public nsCSSStruct {
   nsCSSSVG(void);
   ~nsCSSSVG(void);
 
   nsCSSValue mClipPath;
   nsCSSValue mClipRule;
   nsCSSValue mColorInterpolation;
   nsCSSValue mColorInterpolationFilters;
@@ -711,11 +710,10 @@ private:
   nsCSSSVG(const nsCSSSVG& aOther); // NOT IMPLEMENTED
 };
 
 struct nsRuleDataSVG : public nsCSSSVG {
   nsRuleDataSVG() {}
 private:
   nsRuleDataSVG(const nsRuleDataSVG& aOther); // NOT IMPLEMENTED
 };
-#endif
 
 #endif /* nsCSSStruct_h___ */
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -3737,18 +3737,16 @@ nsComputedDOMStyle::GetFrameBoundsHeight
   // Check to see that we're transformed.
   if (!mInnerFrame->GetStyleDisplay()->HasTransform())
     return PR_FALSE;
 
   aHeight = nsDisplayTransform::GetFrameBoundsForTransform(mInnerFrame).height;
   return PR_TRUE;
 }
 
-#ifdef MOZ_SVG
-
 nsresult
 nsComputedDOMStyle::GetSVGPaintFor(PRBool aFill,
                                    nsIDOMCSSValue** aValue)
 {
   nsROCSSPrimitiveValue* val = GetROCSSPrimitiveValue();
   NS_ENSURE_TRUE(val, NS_ERROR_OUT_OF_MEMORY);
 
   const nsStyleSVG* svg = GetStyleSVG();
@@ -4203,18 +4201,16 @@ nsComputedDOMStyle::GetMask(nsIDOMCSSVal
   if (svg->mMask)
     val->SetURI(svg->mMask);
   else
     val->SetIdent(eCSSKeyword_none);
 
   return CallQueryInterface(val, aValue);
 }
 
-#endif // MOZ_SVG
-
 nsresult
 nsComputedDOMStyle::GetTransitionDelay(nsIDOMCSSValue** aValue)
 {
   const nsStyleDisplay* display = GetStyleDisplay();
 
   nsDOMCSSValueList *valueList = GetROCSSValueList(PR_TRUE);
   NS_ENSURE_TRUE(valueList, NS_ERROR_OUT_OF_MEMORY);
 
@@ -4532,20 +4528,17 @@ nsComputedDOMStyle::GetQueryableProperty
     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),
     COMPUTED_STYLE_MAP_ENTRY(transition_property,           TransitionProperty),
     COMPUTED_STYLE_MAP_ENTRY(transition_timing_function,    TransitionTimingFunction),
     COMPUTED_STYLE_MAP_ENTRY(_moz_window_shadow,            WindowShadow),
-    COMPUTED_STYLE_MAP_ENTRY(word_wrap,                     WordWrap)
-
-#ifdef MOZ_SVG
-    ,
+    COMPUTED_STYLE_MAP_ENTRY(word_wrap,                     WordWrap),
     COMPUTED_STYLE_MAP_ENTRY(clip_path,                     ClipPath),
     COMPUTED_STYLE_MAP_ENTRY(clip_rule,                     ClipRule),
     COMPUTED_STYLE_MAP_ENTRY(color_interpolation,           ColorInterpolation),
     COMPUTED_STYLE_MAP_ENTRY(color_interpolation_filters,   ColorInterpolationFilters),
     COMPUTED_STYLE_MAP_ENTRY(dominant_baseline,             DominantBaseline),
     COMPUTED_STYLE_MAP_ENTRY(fill,                          Fill),
     COMPUTED_STYLE_MAP_ENTRY(fill_opacity,                  FillOpacity),
     COMPUTED_STYLE_MAP_ENTRY(fill_rule,                     FillRule),
@@ -4566,17 +4559,16 @@ nsComputedDOMStyle::GetQueryableProperty
     COMPUTED_STYLE_MAP_ENTRY(stroke_dashoffset,             StrokeDashoffset),
     COMPUTED_STYLE_MAP_ENTRY(stroke_linecap,                StrokeLinecap),
     COMPUTED_STYLE_MAP_ENTRY(stroke_linejoin,               StrokeLinejoin),
     COMPUTED_STYLE_MAP_ENTRY(stroke_miterlimit,             StrokeMiterlimit),
     COMPUTED_STYLE_MAP_ENTRY(stroke_opacity,                StrokeOpacity),
     COMPUTED_STYLE_MAP_ENTRY(stroke_width,                  StrokeWidth),
     COMPUTED_STYLE_MAP_ENTRY(text_anchor,                   TextAnchor),
     COMPUTED_STYLE_MAP_ENTRY(text_rendering,                TextRendering)
-#endif
 
   };
 
   *aLength = NS_ARRAY_LENGTH(map);
 
   return map;
 }
 
--- a/layout/style/nsComputedDOMStyle.h
+++ b/layout/style/nsComputedDOMStyle.h
@@ -331,17 +331,16 @@ private:
   nsresult GetColumnRuleColor(nsIDOMCSSValue** aValue);
 
   /* CSS Transitions */
   nsresult GetTransitionProperty(nsIDOMCSSValue** aValue);
   nsresult GetTransitionDuration(nsIDOMCSSValue** aValue);
   nsresult GetTransitionDelay(nsIDOMCSSValue** aValue);
   nsresult GetTransitionTimingFunction(nsIDOMCSSValue** aValue);
 
-#ifdef MOZ_SVG
   /* SVG properties */
   nsresult GetSVGPaintFor(PRBool aFill, nsIDOMCSSValue** aValue);
 
   nsresult GetFill(nsIDOMCSSValue** aValue);
   nsresult GetStroke(nsIDOMCSSValue** aValue);
   nsresult GetMarkerEnd(nsIDOMCSSValue** aValue);
   nsresult GetMarkerMid(nsIDOMCSSValue** aValue);
   nsresult GetMarkerStart(nsIDOMCSSValue** aValue);
@@ -371,17 +370,16 @@ private:
 
   nsresult GetFloodColor(nsIDOMCSSValue** aValue);
   nsresult GetLightingColor(nsIDOMCSSValue** aValue);
   nsresult GetStopColor(nsIDOMCSSValue** aValue);
 
   nsresult GetClipPath(nsIDOMCSSValue** aValue);
   nsresult GetFilter(nsIDOMCSSValue** aValue);
   nsresult GetMask(nsIDOMCSSValue** aValue);
-#endif // MOZ_SVG
 
   nsROCSSPrimitiveValue* GetROCSSPrimitiveValue();
   nsDOMCSSValueList* GetROCSSValueList(PRBool aCommaDelimited);
   nsresult SetToRGBAColor(nsROCSSPrimitiveValue* aValue, nscolor aColor);
   nsresult SetValueToStyleImage(const nsStyleImage& aStyleImage,
                                 nsROCSSPrimitiveValue* aValue);
   
   /**
--- a/layout/style/nsRuleData.h
+++ b/layout/style/nsRuleData.h
@@ -67,31 +67,24 @@ struct nsRuleData
   nsRuleDataList* mListData;
   nsRuleDataPosition* mPositionData;
   nsRuleDataTable* mTableData;
   nsRuleDataColor* mColorData;
   nsRuleDataContent* mContentData;
   nsRuleDataText* mTextData;
   nsRuleDataUserInterface* mUserInterfaceData;
   nsRuleDataXUL* mXULData;
-
-#ifdef MOZ_SVG
   nsRuleDataSVG* mSVGData;
-#endif
 
   nsRuleDataColumn* mColumnData;
 
   nsRuleData(PRUint32 aSIDs, nsPresContext* aContext, nsStyleContext* aStyleContext) 
     :mSIDs(aSIDs), mPresContext(aContext), mStyleContext(aStyleContext), mPostResolveCallback(nsnull),
      mFontData(nsnull), mDisplayData(nsnull), mMarginData(nsnull), mListData(nsnull), 
      mPositionData(nsnull), mTableData(nsnull), mColorData(nsnull), mContentData(nsnull), mTextData(nsnull),
-     mUserInterfaceData(nsnull), mColumnData(nsnull)
+     mUserInterfaceData(nsnull), mXULData(nsnull), mSVGData(nsnull), mColumnData(nsnull)
   {
     mCanStoreInRuleTree = PR_TRUE;
-    mXULData = nsnull;
-#ifdef MOZ_SVG
-    mSVGData = nsnull;
-#endif
   }
   ~nsRuleData() {}
 };
 
 #endif
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -1324,29 +1324,27 @@ static const PropertyCheckData UIResetCh
 };
 
 static const PropertyCheckData XULCheckProperties[] = {
 #define CSS_PROP_XUL CHECK_DATA_FOR_PROPERTY
 #include "nsCSSPropList.h"
 #undef CSS_PROP_XUL
 };
 
-#ifdef MOZ_SVG
 static const PropertyCheckData SVGCheckProperties[] = {
 #define CSS_PROP_SVG CHECK_DATA_FOR_PROPERTY
 #include "nsCSSPropList.h"
 #undef CSS_PROP_SVG
 };
 
 static const PropertyCheckData SVGResetCheckProperties[] = {
 #define CSS_PROP_SVGRESET CHECK_DATA_FOR_PROPERTY
 #include "nsCSSPropList.h"
 #undef CSS_PROP_SVGRESET
 };
-#endif
 
 static const PropertyCheckData ColumnCheckProperties[] = {
 #define CSS_PROP_COLUMN CHECK_DATA_FOR_PROPERTY
 #include "nsCSSPropList.h"
 #undef CSS_PROP_COLUMN
 };
 
 #undef CSS_PROP_INCLUDE_NOT_CSS
@@ -1807,17 +1805,16 @@ nsRuleNode::GetColumnData(nsStyleContext
 {
   nsRuleDataColumn columnData; // Declare a struct with null CSS values.
   nsRuleData ruleData(NS_STYLE_INHERIT_BIT(Column), mPresContext, aContext);
   ruleData.mColumnData = &columnData;
 
   return WalkRuleTree(eStyleStruct_Column, aContext, &ruleData, &columnData);
 }
 
-#ifdef MOZ_SVG
 const void*
 nsRuleNode::GetSVGData(nsStyleContext* aContext)
 {
   nsRuleDataSVG svgData; // Declare a struct with null CSS values.
   nsRuleData ruleData(NS_STYLE_INHERIT_BIT(SVG), mPresContext, aContext);
   ruleData.mSVGData = &svgData;
 
   const void *res = WalkRuleTree(eStyleStruct_SVG, aContext, &ruleData, &svgData);
@@ -1829,17 +1826,16 @@ const void*
 nsRuleNode::GetSVGResetData(nsStyleContext* aContext)
 {
   nsRuleDataSVG svgData; // Declare a struct with null CSS values.
   nsRuleData ruleData(NS_STYLE_INHERIT_BIT(SVGReset), mPresContext, aContext);
   ruleData.mSVGData = &svgData;
 
   return WalkRuleTree(eStyleStruct_SVGReset, aContext, &ruleData, &svgData);
 }
-#endif
 
 // If we need to restrict which properties apply to the style context,
 // return the bit to check in nsCSSProp's flags table.  Otherwise,
 // return 0.
 inline PRUint32
 GetPseudoRestriction(nsStyleContext *aContext)
 {
   // This needs to match nsStyleSet::WalkRestrictionRule.
@@ -2245,17 +2241,16 @@ nsRuleNode::SetDefaultOnRoot(const nsSty
     {
       nsStyleColumn* column = new (mPresContext) nsStyleColumn(mPresContext);
       if (NS_LIKELY(column != nsnull)) {
         aContext->SetStyle(eStyleStruct_Column, column);
       }
       return column;
     }
 
-#ifdef MOZ_SVG
     case eStyleStruct_SVG:
     {
       nsStyleSVG* svg = new (mPresContext) nsStyleSVG();
       if (NS_LIKELY(svg != nsnull)) {
         aContext->SetStyle(eStyleStruct_SVG, svg);
       }
       return svg;
     }
@@ -2263,17 +2258,16 @@ nsRuleNode::SetDefaultOnRoot(const nsSty
     case eStyleStruct_SVGReset:
     {
       nsStyleSVGReset* svgReset = new (mPresContext) nsStyleSVGReset();
       if (NS_LIKELY(svgReset != nsnull)) {
         aContext->SetStyle(eStyleStruct_SVGReset, svgReset);
       }
       return svgReset;
     }
-#endif
     default:
       /*
        * unhandled case: nsStyleStructID_Length.
        * last item of nsStyleStructID, to know its length.
        */
       return nsnull;
   }
   return nsnull;
@@ -5710,17 +5704,16 @@ nsRuleNode::ComputeColumnData(void* aSta
   else if (SetColor(colorValue, 0, mPresContext, aContext,
                     column->mColumnRuleColor, canStoreInRuleTree)) {
     column->mColumnRuleColorIsForeground = PR_FALSE;
   }
 
   COMPUTE_END_RESET(Column, column)
 }
 
-#ifdef MOZ_SVG
 static void
 SetSVGPaint(const nsCSSValuePair& aValue, const nsStyleSVGPaint& parentPaint,
             nsPresContext* aPresContext, nsStyleContext *aContext,
             nsStyleSVGPaint& aResult, nsStyleSVGPaintType aInitialPaintType,
             PRBool& aCanStoreInRuleTree)
 {
   nscolor color;
 
@@ -6018,17 +6011,16 @@ nsRuleNode::ComputeSVGResetData(void* aS
     svgReset->mMask = nsnull;
   } else if (eCSSUnit_Inherit == SVGData.mMask.GetUnit()) {
     canStoreInRuleTree = PR_FALSE;
     svgReset->mMask = parentSVGReset->mMask;
   }
 
   COMPUTE_END_RESET(SVGReset, svgReset)
 }
-#endif
 
 inline const void*
 nsRuleNode::GetParentData(const nsStyleStructID aSID)
 {
   NS_PRECONDITION(mDependentBits & nsCachedStyleData::GetBitForSID(aSID),
                   "should be called when node depends on parent data");
   NS_ASSERTION(mStyleData.GetStyleData(aSID) == nsnull,
                "both struct and dependent bits present");
--- a/layout/style/nsRuleNode.h
+++ b/layout/style/nsRuleNode.h
@@ -625,31 +625,29 @@ protected:
 
   NS_HIDDEN_(const void*)
     ComputeColumnData(void* aStartStruct,
                       const nsRuleDataStruct& aData,
                       nsStyleContext* aContext, nsRuleNode* aHighestNode,
                       RuleDetail aRuleDetail,
                       const PRBool aCanStoreInRuleTree);
 
-#ifdef MOZ_SVG
   NS_HIDDEN_(const void*)
     ComputeSVGData(void* aStartStruct,
                    const nsRuleDataStruct& aData, 
                    nsStyleContext* aContext, nsRuleNode* aHighestNode,
                    RuleDetail aRuleDetail,
                    const PRBool aCanStoreInRuleTree);
 
   NS_HIDDEN_(const void*)
     ComputeSVGResetData(void* aStartStruct,
                         const nsRuleDataStruct& aData, 
                         nsStyleContext* aContext, nsRuleNode* aHighestNode,
                         RuleDetail aRuleDetail,
                         const PRBool aCanStoreInRuleTree);
-#endif
 
   // helpers for |ComputeFontData| that need access to |mNoneBits|:
   static NS_HIDDEN_(void) SetFontSize(nsPresContext* aPresContext,
                                       const nsRuleDataFont& aFontData,
                                       const nsStyleFont* aFont,
                                       const nsStyleFont* aParentFont,
                                       nscoord* aSize,
                                       const nsFont& aSystemFont,
@@ -710,20 +708,18 @@ protected:
   NS_HIDDEN_(const void*) GetQuotesData(nsStyleContext* aContext);
   NS_HIDDEN_(const void*) GetTextData(nsStyleContext* aContext);
   NS_HIDDEN_(const void*) GetTextResetData(nsStyleContext* aContext);
   NS_HIDDEN_(const void*) GetUserInterfaceData(nsStyleContext* aContext);
 
   NS_HIDDEN_(const void*) GetUIResetData(nsStyleContext* aContext);
   NS_HIDDEN_(const void*) GetXULData(nsStyleContext* aContext);
   NS_HIDDEN_(const void*) GetColumnData(nsStyleContext* aContext);
-#ifdef MOZ_SVG
   NS_HIDDEN_(const void*) GetSVGData(nsStyleContext* aContext);
   NS_HIDDEN_(const void*) GetSVGResetData(nsStyleContext* aContext);
-#endif
 
   NS_HIDDEN_(already_AddRefed<nsCSSShadowArray>)
                           GetShadowData(nsCSSValueList* aList,
                                         nsStyleContext* aContext,
                                         PRBool aIsBoxShadow,
                                         PRBool& inherited);
 
 private:
--- a/layout/style/nsStyleAnimation.cpp
+++ b/layout/style/nsStyleAnimation.cpp
@@ -854,16 +854,26 @@ PRBool
 nsStyleAnimation::UncomputeValue(nsCSSProperty aProperty,
                                  nsPresContext* aPresContext,
                                  const Value& aComputedValue,
                                  void* aSpecifiedValue)
 {
   NS_ABORT_IF_FALSE(aPresContext, "null pres context");
 
   switch (aComputedValue.GetUnit()) {
+    case eUnit_Normal:
+      NS_ABORT_IF_FALSE(nsCSSProps::kTypeTable[aProperty] == eCSSType_Value,
+                        "type mismatch");
+      static_cast<nsCSSValue*>(aSpecifiedValue)->SetNormalValue();
+      break;
+    case eUnit_Auto:
+      NS_ABORT_IF_FALSE(nsCSSProps::kTypeTable[aProperty] == eCSSType_Value,
+                        "type mismatch");
+      static_cast<nsCSSValue*>(aSpecifiedValue)->SetAutoValue();
+      break;
     case eUnit_None:
       if (nsCSSProps::kAnimTypeTable[aProperty] == eStyleAnimType_PaintServer) {
         NS_ABORT_IF_FALSE(nsCSSProps::kTypeTable[aProperty] ==
                             eCSSType_ValuePair, "type mismatch");
         static_cast<nsCSSValuePair*>(aSpecifiedValue)->
           SetBothValuesTo(nsCSSValue(eCSSUnit_None));
       } else {
         NS_ABORT_IF_FALSE(nsCSSProps::kTypeTable[aProperty] == eCSSType_Value,
--- a/layout/style/nsStyleContext.cpp
+++ b/layout/style/nsStyleContext.cpp
@@ -437,21 +437,19 @@ nsStyleContext::CalcStyleDifference(nsSt
   DO_STRUCT_DIFFERENCE(Table);
   DO_STRUCT_DIFFERENCE(UIReset);
   DO_STRUCT_DIFFERENCE(Text);
   DO_STRUCT_DIFFERENCE(List);
   // If the quotes implementation is ever going to change we might not need
   // a framechange here and a reflow should be sufficient.  See bug 35768.
   DO_STRUCT_DIFFERENCE(Quotes);
 
-#ifdef MOZ_SVG
   maxHint = nsChangeHint(NS_STYLE_HINT_REFLOW | nsChangeHint_UpdateEffects);
   DO_STRUCT_DIFFERENCE(SVGReset);
   DO_STRUCT_DIFFERENCE(SVG);
-#endif
 
   // At this point, we know that the worst kind of damage we could do is
   // a reflow.
   maxHint = NS_STYLE_HINT_REFLOW;
       
   // The following structs cause (as their maximal difference) a reflow
   // to occur.  REFLOW Structs: Font, Margin, Padding, Border, List,
   // Position, Text, TextReset
--- a/layout/style/nsStyleStruct.cpp
+++ b/layout/style/nsStyleStruct.cpp
@@ -777,17 +777,16 @@ nsChangeHint nsStyleColumn::CalcDifferen
 #ifdef DEBUG
 /* static */
 nsChangeHint nsStyleColumn::MaxDifference()
 {
   return NS_STYLE_HINT_FRAMECHANGE;
 }
 #endif
 
-#ifdef MOZ_SVG
 // --------------------
 // nsStyleSVG
 //
 nsStyleSVG::nsStyleSVG() 
 {
     MOZ_COUNT_CTOR(nsStyleSVG);
     mFill.mType              = eStyleSVGPaintType_Color;
     mFill.mPaint.mColor      = NS_RGB(0,0,0);
@@ -1055,18 +1054,16 @@ PRBool nsStyleSVGPaint::operator==(const
   if (mType == eStyleSVGPaintType_Server)
     return EqualURIs(mPaint.mPaintServer, aOther.mPaint.mPaintServer) &&
            mFallbackColor == aOther.mFallbackColor;
   if (mType == eStyleSVGPaintType_None)
     return PR_TRUE;
   return mPaint.mColor == aOther.mPaint.mColor;
 }
 
-#endif // MOZ_SVG
-
 
 // --------------------
 // nsStylePosition
 //
 nsStylePosition::nsStylePosition(void) 
 { 
   MOZ_COUNT_CTOR(nsStylePosition);
   // positioning values not inherited
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -1792,17 +1792,16 @@ struct nsStyleColumn {
     return (IsVisibleBorderStyle(mColumnRuleStyle) ? mColumnRuleWidth : 0);
   }
 
 protected:
   nscoord mColumnRuleWidth;  // [reset] coord
   nscoord mTwipsPerPixel;
 };
 
-#ifdef MOZ_SVG
 enum nsStyleSVGPaintType {
   eStyleSVGPaintType_None = 1,
   eStyleSVGPaintType_Color,
   eStyleSVGPaintType_Server
 };
 
 struct nsStyleSVGPaint
 {
@@ -1896,11 +1895,10 @@ struct nsStyleSVGReset {
   nscolor          mFloodColor;       // [reset]
   nscolor          mLightingColor;    // [reset]
 
   float            mStopOpacity;      // [reset]
   float            mFloodOpacity;     // [reset]
 
   PRUint8          mDominantBaseline; // [reset] see nsStyleConsts.h
 };
-#endif
 
 #endif /* nsStyleStruct_h___ */
--- a/layout/style/nsStyleStructList.h
+++ b/layout/style/nsStyleStructList.h
@@ -135,29 +135,24 @@ STYLE_STRUCT_RESET(Border, nsnull, (SSAR
   STYLE_STRUCT_TEST_CODE(    })
   STYLE_STRUCT_TEST_CODE(  } else {)
   STYLE_STRUCT_TEST_CODE(    if (STYLE_STRUCT_TEST == 18) {)
 STYLE_STRUCT_RESET(Outline, nsnull, (SSARG_PRESCONTEXT))
   STYLE_STRUCT_TEST_CODE(    } else {)
 STYLE_STRUCT_RESET(XUL, nsnull, ())
   STYLE_STRUCT_TEST_CODE(    })
   STYLE_STRUCT_TEST_CODE(  })
-#ifndef MOZ_SVG
-  STYLE_STRUCT_TEST_CODE(} else {)
-  STYLE_STRUCT_TEST_CODE(  NS_ASSERTION(STYLE_STRUCT_TEST == 20, "out of range");)
-#else
   STYLE_STRUCT_TEST_CODE(} else if (STYLE_STRUCT_TEST < 22) {)
   STYLE_STRUCT_TEST_CODE(  if (STYLE_STRUCT_TEST == 20) {)
 STYLE_STRUCT_INHERITED(SVG, nsnull, ())
   STYLE_STRUCT_TEST_CODE(  } else {)
 STYLE_STRUCT_RESET(SVGReset,nsnull, ())
   STYLE_STRUCT_TEST_CODE(  })
   STYLE_STRUCT_TEST_CODE(} else {)
   STYLE_STRUCT_TEST_CODE(  NS_ASSERTION(STYLE_STRUCT_TEST == 22, "out of range");)
-#endif
   STYLE_STRUCT_RESET(Column, nsnull, (SSARG_PRESCONTEXT))
 STYLE_STRUCT_TEST_CODE(})
       
 #ifdef UNDEF_STYLE_STRUCT_INHERITED
 #undef STYLE_STRUCT_INHERITED
 #undef UNDEF_STYLE_STRUCT_INHERITED
 #endif
 
--- a/layout/svg/base/src/nsSVGUtils.cpp
+++ b/layout/svg/base/src/nsSVGUtils.cpp
@@ -727,23 +727,29 @@ nsSVGUtils::ObjectSpace(const gfxRect &a
   case X:
     axis = aRect.Width();
     break;
   case Y:
     axis = aRect.Height();
     break;
   case XY:
     axis = float(ComputeNormalizedHypotenuse(aRect.Width(), aRect.Height()));
+    break;
+  default:
+    NS_NOTREACHED("unexpected ctx type");
+    axis = 0.0f;
+    break;
   }
 
   if (aLength->IsPercentage()) {
     fraction = aLength->GetAnimValInSpecifiedUnits() / 100;
-  } else
+  } else {
     fraction = aLength->GetAnimValue(static_cast<nsSVGSVGElement*>
                                                 (nsnull));
+  }
 
   return fraction * axis;
 }
 
 float
 nsSVGUtils::UserSpace(nsSVGElement *aSVGElement, const nsSVGLength2 *aLength)
 {
   return aLength->GetAnimValue(aSVGElement);
--- a/layout/tables/nsTableCellFrame.cpp
+++ b/layout/tables/nsTableCellFrame.cpp
@@ -443,18 +443,19 @@ nsTableCellFrame::BuildDisplayList(nsDis
   // take account of 'empty-cells'
   if (GetStyleVisibility()->IsVisible() &&
       (NS_STYLE_TABLE_EMPTY_CELLS_HIDE != emptyCellStyle)) {
     
 
     PRBool isRoot = aBuilder->IsAtRootOfPseudoStackingContext();
     if (!isRoot) {
       nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem();
-      NS_ASSERTION(currentItem, "No current table item???");
-      currentItem->UpdateForFrameBackground(this);
+      if (currentItem) {
+        currentItem->UpdateForFrameBackground(this);
+      }
     }
 
     // display outset box-shadows if we need to.
     PRBool hasBoxShadow = !!(GetStyleBorder()->mBoxShadow);
     if (hasBoxShadow) {
       nsDisplayItem* item = new (aBuilder) nsDisplayBoxShadowOuter(this);
       nsresult rv = aLists.BorderBackground()->AppendNewToTop(item);
       NS_ENSURE_SUCCESS(rv, rv);
@@ -497,16 +498,21 @@ nsTableCellFrame::BuildDisplayList(nsDis
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
   // the 'empty-cells' property has no effect on 'outline'
   nsresult rv = DisplayOutline(aBuilder, aLists);
   NS_ENSURE_SUCCESS(rv, rv);
 
+  // Push a null 'current table item' so that descendant tables can't
+  // accidentally mess with our table
+  nsAutoPushCurrentTableItem pushTableItem;
+  pushTableItem.Push(aBuilder, nsnull);
+
   nsIFrame* kid = mFrames.FirstChild();
   NS_ASSERTION(kid && !kid->GetNextSibling(), "Table cells should have just one child");
   // The child's background will go in our BorderBackground() list.
   // This isn't a problem since it won't have a real background except for
   // event handling. We do not call BuildDisplayListForNonBlockChildren
   // because that/ would put the child's background in the Content() list
   // which isn't right (e.g., would end up on top of our child floats for
   // event handling).
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -68,16 +68,17 @@
 #include "nsIScrollableFrame.h"
 #include "nsFrameManager.h"
 #include "nsCSSRendering.h"
 #include "nsLayoutErrors.h"
 #include "nsAutoPtr.h"
 #include "nsCSSFrameConstructor.h"
 #include "nsStyleSet.h"
 #include "nsDisplayList.h"
+#include "nsIScrollableFrame.h"
 
 /********************************************************************************
  ** nsTableReflowState                                                         **
  ********************************************************************************/
 
 struct nsTableReflowState {
 
   // the real reflow state
@@ -1261,60 +1262,107 @@ nsTableFrame::DisplayGenericTablePart(ns
   PRBool sortEventBackgrounds = aDisplayItem && aBuilder->IsForEventDelivery();
   nsDisplayListCollection separatedCollection;
   const nsDisplayListSet* lists = sortEventBackgrounds ? &separatedCollection : &aLists;
   
   nsAutoPushCurrentTableItem pushTableItem;
   if (aDisplayItem) {
     pushTableItem.Push(aBuilder, aDisplayItem);
   }
-  nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem();
-  NS_ASSERTION(currentItem, "No current table item!");
-  currentItem->UpdateForFrameBackground(aFrame);
-  
-  // Paint the outset box-shadows for the table frames
-  PRBool hasBoxShadow = aFrame->IsVisibleForPainting(aBuilder) &&
-                        aFrame->GetStyleBorder()->mBoxShadow;
-  if (hasBoxShadow) {
-    nsDisplayItem* item = new (aBuilder) nsDisplayBoxShadowOuter(aFrame);
-    nsresult rv = lists->BorderBackground()->AppendNewToTop(item);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  // Create dedicated background display items per-frame when we're
-  // handling events.
-  // XXX how to handle collapsed borders?
-  if (aBuilder->IsForEventDelivery() &&
-      aFrame->IsVisibleForPainting(aBuilder)) {
-    nsresult rv = lists->BorderBackground()->AppendNewToTop(new (aBuilder)
-        nsDisplayBackground(aFrame));
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  // Paint the inset box-shadows for the table frames
-  if (hasBoxShadow) {
-    nsDisplayItem* item = new (aBuilder) nsDisplayBoxShadowInner(aFrame);
-    nsresult rv = lists->BorderBackground()->AppendNewToTop(item);
-    NS_ENSURE_SUCCESS(rv, rv);
+
+  if (aFrame->IsVisibleForPainting(aBuilder)) {
+    nsDisplayTableItem* currentItem = aBuilder->GetCurrentTableItem();
+    // currentItem may be null, when none of the table parts have a
+    // background or border
+    if (currentItem) {
+      currentItem->UpdateForFrameBackground(aFrame);
+    }
+
+    // Paint the outset box-shadows for the table frames
+    PRBool hasBoxShadow = aFrame->GetStyleBorder()->mBoxShadow != nsnull;
+    if (hasBoxShadow) {
+      nsDisplayItem* item = new (aBuilder) nsDisplayBoxShadowOuter(aFrame);
+      nsresult rv = lists->BorderBackground()->AppendNewToTop(item);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+
+    // Create dedicated background display items per-frame when we're
+    // handling events.
+    // XXX how to handle collapsed borders?
+    if (aBuilder->IsForEventDelivery()) {
+      nsresult rv = lists->BorderBackground()->AppendNewToTop(new (aBuilder)
+          nsDisplayBackground(aFrame));
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+
+    // Paint the inset box-shadows for the table frames
+    if (hasBoxShadow) {
+      nsDisplayItem* item = new (aBuilder) nsDisplayBoxShadowInner(aFrame);
+      nsresult rv = lists->BorderBackground()->AppendNewToTop(item);
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
   }
 
   nsresult rv = aTraversal(aBuilder, aFrame, aDirtyRect, *lists);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (sortEventBackgrounds) {
     // Ensure that the table frame event background goes before the
     // table rowgroups event backgrounds, before the table row event backgrounds,
     // before everything else (cells and their blocks)
     separatedCollection.BorderBackground()->Sort(aBuilder, CompareByTablePartRank, nsnull);
     separatedCollection.MoveTo(aLists);
   }
   
   return aFrame->DisplayOutline(aBuilder, aLists);
 }
 
+#ifdef DEBUG
+static PRBool
+IsFrameAllowedInTable(nsIAtom* aType)
+{
+  return IS_TABLE_CELL(aType) ||
+         nsGkAtoms::tableRowFrame == aType ||
+         nsGkAtoms::tableRowGroupFrame == aType ||
+         nsGkAtoms::scrollFrame == aType ||
+         nsGkAtoms::tableFrame == aType ||
+         nsGkAtoms::tableColFrame == aType ||
+         nsGkAtoms::tableColGroupFrame == aType;
+}
+#endif
+
+static PRBool
+AnyTablePartHasBorderOrBackground(nsIFrame* aFrame)
+{
+  NS_ASSERTION(IsFrameAllowedInTable(aFrame->GetType()), "unexpected frame type");
+
+  nsIScrollableFrame *scrollFrame = do_QueryFrame(aFrame);
+  if (scrollFrame) {
+    return AnyTablePartHasBorderOrBackground(scrollFrame->GetScrolledFrame());
+  }
+
+  if (aFrame->GetStyleVisibility()->IsVisible() &&
+      (!aFrame->GetStyleBackground()->IsTransparent() ||
+       aFrame->GetStyleDisplay()->mAppearance ||
+       aFrame->HasBorder()))
+    return PR_TRUE;
+
+  nsTableCellFrame *cellFrame = do_QueryFrame(aFrame);
+  if (cellFrame)
+    return PR_FALSE;
+
+  nsFrameList children = aFrame->GetChildList(nsnull);
+  for (nsIFrame* f = children.FirstChild(); f; f = f->GetNextSibling()) {
+    if (AnyTablePartHasBorderOrBackground(f))
+      return PR_TRUE;
+  }
+
+  return PR_FALSE;
+}
+
 // table paint code is concerned primarily with borders and bg color
 // SEC: TODO: adjust the rect for captions 
 NS_IMETHODIMP
 nsTableFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                const nsRect&           aDirtyRect,
                                const nsDisplayListSet& aLists)
 {
   if (!IsVisibleInSelection(aBuilder))
@@ -1328,24 +1376,26 @@ nsTableFrame::BuildDisplayList(nsDisplay
     // in its own display item, so do that to take advantage of
     // opacity and visibility optimizations
     if (deflate.IsZero()) {
       nsresult rv = DisplayBackgroundUnconditional(aBuilder, aLists, PR_FALSE);
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
-  // This background is created regardless of whether this frame is
-  // visible or not. Visibility decisions are delegated to the
-  // table background painter. This handles borders and backgrounds
-  // for the table.
-  nsDisplayTableItem* item = new (aBuilder) nsDisplayTableBorderBackground(this);
-  nsresult rv = aLists.BorderBackground()->AppendNewToTop(item);
-  NS_ENSURE_SUCCESS(rv, rv);
-  
+  nsDisplayTableItem* item = nsnull;
+  // This background is created if any of the table parts are visible.
+  // Specific visibility decisions are delegated to the table background
+  // painter, which handles borders and backgrounds for the table.
+  if (AnyTablePartHasBorderOrBackground(this)) {
+    item = new (aBuilder) nsDisplayTableBorderBackground(this);
+    nsresult rv = aLists.BorderBackground()->AppendNewToTop(item);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+
   return DisplayGenericTablePart(aBuilder, this, aDirtyRect, aLists, item);
 }
 
 nsMargin
 nsTableFrame::GetDeflationForBackground(nsPresContext* aPresContext) const
 {
   if (eCompatibility_NavQuirks != aPresContext->CompatibilityMode() ||
       !IsBorderCollapse())
--- a/layout/tools/reftest/Makefile.in
+++ b/layout/tools/reftest/Makefile.in
@@ -84,17 +84,17 @@ endif
 $(_HARNESS_FILES): $(_DEST_DIR)
 
 # copy harness and the reftest extension bits to $(_DEST_DIR)
 copy-harness: $(_HARNESS_FILES)
 	$(INSTALL) $(_HARNESS_FILES) $(_DEST_DIR)
 	(cd $(DIST)/xpi-stage && tar $(TAR_CREATE_FLAGS) - reftest) | (cd $(_DEST_DIR) && tar -xf -)
 	$(INSTALL) $(DIST)/bin/components/httpd.js $(_DEST_DIR)/reftest/components
 # need to get httpd.js into components.list so it loads
-	@$(PERL) -I$(MOZILLA_DIR)/config $(MOZILLA_DIR)/config/build-list.pl $(_DEST_DIR)/reftest/components/components.list httpd.js
+	@$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(_DEST_DIR)/reftest/components/components.list httpd.js
 	$(INSTALL) $(DIST)/bin/components/test_necko.xpt $(_DEST_DIR)/reftest/components
 
 PKG_STAGE = $(DIST)/test-package-stage
 
 # stage harness and tests for packaging
 stage-package:
 	$(NSINSTALL) -D $(PKG_STAGE)/reftest && $(NSINSTALL) -D $(PKG_STAGE)/reftest/tests
 	@(cd $(DEPTH)/_tests/reftest/ && tar $(TAR_CREATE_FLAGS) - *) | (cd $(PKG_STAGE)/reftest && tar -xf -)
--- a/layout/tools/reftest/reftest.js
+++ b/layout/tools/reftest/reftest.js
@@ -584,16 +584,20 @@ function StartCurrentURI(aState)
         setTimeout(DocumentLoaded, 0);
     } else {
         gBrowser.loadURI(gCurrentURL);
     }
 }
 
 function DoneTests()
 {
+    // TEMPORARILY DISABLE REPORTING OF ASSERTION FAILURES.
+    gTestResults.AssertionUnexpected = 0;
+    gTestResults.AssertionUnexpectedFixed = 0;
+
     dump("REFTEST FINISHED: Slowest test took " + gSlowestTestTime +
          "ms (" + gSlowestTestURL + ")\n");
 
     dump("REFTEST INFO | Result summary:\n");
     var count = gTestResults.Pass + gTestResults.LoadOnly;
     dump("REFTEST INFO | Successful: " + count + " (" +
          gTestResults.Pass + " pass, " +
          gTestResults.LoadOnly + " load only)\n");
@@ -688,16 +692,23 @@ function OnDocumentLoad(event)
 
        ps.headerStrLeft = "";
        ps.headerStrCenter = "";
        ps.headerStrRight = "";
        ps.footerStrLeft = "";
        ps.footerStrCenter = "";
        ps.footerStrRight = "";
        gBrowser.docShell.contentViewer.setPageMode(true, ps);
+
+       // WORKAROUND FOR ASSERTIONS IN BUG 534478:  Calling setPageMode
+       // above causes 2 assertions.  So that we don't have to annotate
+       // the manifests for every reftest-print reftest, bump the
+       // assertion count by two right here.
+       gURLs[0].minAsserts += 2;
+       gURLs[0].maxAsserts += 2;
     }
 
     setupZoom(contentRootElement);
 
     if (shouldWait()) {
         // The testcase will let us know when the test snapshot should be made.
         // Register a mutation listener to know when the 'reftest-wait' class
         // gets removed.
@@ -1088,40 +1099,41 @@ function FinishTestItem()
     gBrowser.loadURI(BLANK_URL_FOR_CLEARING);
 }
 
 function DoAssertionCheck()
 {
     gClearingForAssertionCheck = false;
 
     if (gDebug.isDebugBuild) {
-        // TEMPORARILY DISABLING ASSERTION CHECKS FOR NOW.  TO RE-ENABLE,
-        // USE COMMENTED LINE TO REPLACE FOLLOWING ONE.
-        // var newAssertionCount = gDebug.assertionCount;
-        var newAssertionCount = 0;
+        var newAssertionCount = gDebug.assertionCount;
         var numAsserts = newAssertionCount - gAssertionCount;
         gAssertionCount = newAssertionCount;
 
         var minAsserts = gURLs[0].minAsserts;
         var maxAsserts = gURLs[0].maxAsserts;
 
         var expectedAssertions = "expected " + minAsserts;
         if (minAsserts != maxAsserts) {
             expectedAssertions += " to " + maxAsserts;
         }
         expectedAssertions += " assertions";
 
         if (numAsserts < minAsserts) {
             ++gTestResults.AssertionUnexpectedFixed;
-            dump("REFTEST TEST-UNEXPECTED-PASS | " + gURLs[0].prettyPath +
+            // TEMPORARILY DISABLING REPORTING ON TINDERBOX BY REVERSING
+            // THE WORD "UNEXPECTED".
+            dump("REFTEST TEST-DETCEPXENU-PASS | " + gURLs[0].prettyPath +
                  " | assertion count " + numAsserts + " is less than " +
                  expectedAssertions + "\n");
         } else if (numAsserts > maxAsserts) {
             ++gTestResults.AssertionUnexpected;
-            dump("REFTEST TEST-UNEXPECTED-FAIL | " + gURLs[0].prettyPath +
+            // TEMPORARILY DISABLING REPORTING ON TINDERBOX BY REVERSING
+            // THE WORD "UNEXPECTED".
+            dump("REFTEST TEST-DETCEPXENU-FAIL | " + gURLs[0].prettyPath +
                  " | assertion count " + numAsserts + " is more than " +
                  expectedAssertions + "\n");
         } else if (numAsserts != 0) {
             ++gTestResults.AssertionKnown;
             dump("REFTEST TEST-KNOWN-FAIL | " + gURLs[0].prettyPath +
                  " | assertion count " + numAsserts + " matches " +
                  expectedAssertions + "\n");
         }
new file mode 100644
--- /dev/null
+++ b/layout/xul/base/src/crashtests/189814-1.xul
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+
+<window
+  id="sliderprint" title="Print These Sliders"
+  xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+  style="background-color: white">
+
+  <label>
+  With the Classic theme, printing causes the browser to crash. adding style="-moz-appearance: none" to the
+  thumb prevents the crash. The crash doesn't happen at all with Modern.
+  </label>
+  <spacer height="10"/>
+    <hbox>
+
+        <slider style="height: 174px; width: 24px" orient="vertical">
+            <thumb/>
+        </slider>
+
+    </hbox>
+
+</window>
--- a/layout/xul/base/src/crashtests/crashtests.list
+++ b/layout/xul/base/src/crashtests/crashtests.list
@@ -1,13 +1,14 @@
 load 131008-1.xul
 load 137216-1.xul
 load 140218-1.xml
 load 151826-1.xul
 load 168724-1.xul
+load 189814-1.xul
 load 237787-1.xul
 load 289410-1.xul
 load 291702-1.xul
 load 291702-2.xul
 load 291702-3.xul
 load 294371-1.xul
 load 311457-1.html
 load 321056-1.xhtml
--- a/modules/libjar/nsJARInputStream.cpp
+++ b/modules/libjar/nsJARInputStream.cpp
@@ -229,17 +229,17 @@ nsJARInputStream::Read(char* aBuffer, PR
         // deflating - this is because zlib buffers the input
         if (mZs.avail_in == 0) {
             mFd = nsnull;
         }
         break;
 
       case MODE_COPY:
         if (mFd) {
-          PRUint32 count = PR_MIN(aCount, mOutSize - mZs.total_out);
+          PRUint32 count = NS_MIN(aCount, mOutSize - PRUint32(mZs.total_out));
           if (count) {
               memcpy(aBuffer, mZs.next_in + mZs.total_out, count);
               mZs.total_out += count;
           }
           *aBytesRead = count;
         }
         // be aggressive about releasing the file!
         // note that sometimes, we will release mFd before we've finished copying.
@@ -281,17 +281,17 @@ nsJARInputStream::ContinueInflate(char* 
     // No need to check the args, ::Read did that, but assert them at least
     NS_ASSERTION(aBuffer,"aBuffer parameter must not be null");
     NS_ASSERTION(aBytesRead,"aBytesRead parameter must not be null");
 
     // Keep old total_out count
     const PRUint32 oldTotalOut = mZs.total_out;
     
     // make sure we aren't reading too much
-    mZs.avail_out = PR_MIN(aCount, (mOutSize-oldTotalOut));
+    mZs.avail_out = NS_MIN(aCount, (mOutSize-oldTotalOut));
     mZs.next_out = (unsigned char*)aBuffer;
 
     // now inflate
     int zerr = inflate(&mZs, Z_SYNC_FLUSH);
     if ((zerr != Z_OK) && (zerr != Z_STREAM_END))
         return NS_ERROR_FILE_CORRUPTED;
 
     *aBytesRead = (mZs.total_out - oldTotalOut);
@@ -378,17 +378,17 @@ nsJARInputStream::ReadDirectory(char* aB
 
     *aBytesRead = numRead;
     return NS_OK;
 }
 
 PRUint32
 nsJARInputStream::CopyDataToBuffer(char* &aBuffer, PRUint32 &aCount)
 {
-    const PRUint32 writeLength = PR_MIN(aCount, mBuffer.Length() - mCurPos);
+    const PRUint32 writeLength = NS_MIN(aCount, mBuffer.Length() - mCurPos);
 
     if (writeLength > 0) {
         memcpy(aBuffer, mBuffer.get() + mCurPos, writeLength);
         mCurPos += writeLength;
         aCount  -= writeLength;
         aBuffer += writeLength;
     }
 
--- a/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp
+++ b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp
@@ -203,17 +203,17 @@ NS_IMETHODIMP nsJPEGDecoder::Close(PRUin
   /* If we already know we're in an error state, don't
      bother flagging another one here. */
   if (mState == JPEG_ERROR)
     return NS_OK;
 
   /* If we're doing a full decode and haven't notified of completion yet,
    * we must not have got everything we wanted. Send error notifications. */
   if (!(aFlags & CLOSE_FLAG_DONTNOTIFY) &&
-      !(mFlags && imgIDecoder::DECODER_FLAG_HEADERONLY) &&
+      !(mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) &&
       !mNotifiedDone)
     NotifyDone(/* aSuccess = */ PR_FALSE);
 
   /* Otherwise, no problems. */
   return NS_OK;
 }
 
 /* void flush (); */
--- a/modules/libpr0n/decoders/png/nsPNGDecoder.cpp
+++ b/modules/libpr0n/decoders/png/nsPNGDecoder.cpp
@@ -56,25 +56,29 @@
 
 #include "nspr.h"
 #include "png.h"
 
 #include "gfxPlatform.h"
 
 static void PNGAPI info_callback(png_structp png_ptr, png_infop info_ptr);
 static void PNGAPI row_callback(png_structp png_ptr, png_bytep new_row,
-                           png_uint_32 row_num, int pass);
-static void PNGAPI frame_info_callback(png_structp png_ptr, png_uint_32 frame_num);
+                                png_uint_32 row_num, int pass);
+static void PNGAPI frame_info_callback(png_structp png_ptr,
+                                       png_uint_32 frame_num);
 static void PNGAPI end_callback(png_structp png_ptr, png_infop info_ptr);
-static void PNGAPI error_callback(png_structp png_ptr, png_const_charp error_msg);
-static void PNGAPI warning_callback(png_structp png_ptr, png_const_charp warning_msg);
+static void PNGAPI error_callback(png_structp png_ptr,
+                                  png_const_charp error_msg);
+static void PNGAPI warning_callback(png_structp png_ptr,
+                                    png_const_charp warning_msg);
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo *gPNGLog = PR_NewLogModule("PNGDecoder");
-static PRLogModuleInfo *gPNGDecoderAccountingLog = PR_NewLogModule("PNGDecoderAccounting");
+static PRLogModuleInfo *gPNGDecoderAccountingLog =
+                        PR_NewLogModule("PNGDecoderAccounting");
 #endif
 
 /* limit image dimensions (bug #251381) */
 #define MOZ_PNG_MAX_DIMENSION 1000000L
 
 // For header-only decodes
 #define WIDTH_OFFSET 16
 #define HEIGHT_OFFSET (WIDTH_OFFSET + 4)
@@ -111,17 +115,17 @@ nsPNGDecoder::~nsPNGDecoder()
     if (mTransform)
       qcms_transform_release(mTransform);
   }
   if (mHeaderBuf)
     nsMemory::Free(mHeaderBuf);
 }
 
 // CreateFrame() is used for both simple and animated images
-void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset, 
+void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
                                PRInt32 width, PRInt32 height,
                                gfxASurface::gfxImageFormat format)
 {
   PRUint32 imageDataLength;
   nsresult rv = mImage->AppendFrame(x_offset, y_offset, width, height, format,
                                     &mImageData, &imageDataLength);
   if (NS_FAILED(rv))
     longjmp(mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY
@@ -136,61 +140,65 @@ void nsPNGDecoder::CreateFrame(png_uint_
 
   PRUint32 numFrames = 0;
   mImage->GetNumFrames(&numFrames);
 
   if (mObserver)
     mObserver->OnStartFrame(nsnull, numFrames - 1);
 
   PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG,
-         ("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created image frame with %dx%d pixels in container %p",
+         ("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created image"
+          " frame with %dx%d pixels in container %p",
           width, height,
           mImage.get ()));
 
   mFrameHasNoAlpha = PR_TRUE;
 }
 
 // set timeout and frame disposal method for the current frame
 void nsPNGDecoder::SetAnimFrameInfo()
 {
   png_uint_16 delay_num, delay_den;
   /* delay, in seconds is delay_num/delay_den */
   png_byte dispose_op;
   png_byte blend_op;
   PRInt32 timeout; /* in milliseconds */
-  
+
   delay_num = png_get_next_frame_delay_num(mPNG, mInfo);
   delay_den = png_get_next_frame_delay_den(mPNG, mInfo);
   dispose_op = png_get_next_frame_dispose_op(mPNG, mInfo);
   blend_op = png_get_next_frame_blend_op(mPNG, mInfo);
 
   if (delay_num == 0) {
     timeout = 0; // SetFrameTimeout() will set to a minimum
   } else {
     if (delay_den == 0)
       delay_den = 100; // so says the APNG spec
-    
+
     // Need to cast delay_num to float to have a proper division and
     // the result to int to avoid compiler warning
     timeout = static_cast<PRInt32>
-                         (static_cast<PRFloat64>(delay_num) * 1000 / delay_den);
+              (static_cast<PRFloat64>(delay_num) * 1000 / delay_den);
   }
 
   PRUint32 numFrames = 0;
   mImage->GetNumFrames(&numFrames);
 
   mImage->SetFrameTimeout(numFrames - 1, timeout);
-  
+
   if (dispose_op == PNG_DISPOSE_OP_PREVIOUS)
-      mImage->SetFrameDisposalMethod(numFrames - 1, imgIContainer::kDisposeRestorePrevious);
+      mImage->SetFrameDisposalMethod(numFrames - 1,
+                                     imgIContainer::kDisposeRestorePrevious);
   else if (dispose_op == PNG_DISPOSE_OP_BACKGROUND)
-      mImage->SetFrameDisposalMethod(numFrames - 1, imgIContainer::kDisposeClear);
+      mImage->SetFrameDisposalMethod(numFrames - 1,
+                                     imgIContainer::kDisposeClear);
   else
-      mImage->SetFrameDisposalMethod(numFrames - 1, imgIContainer::kDisposeKeep);
-  
+      mImage->SetFrameDisposalMethod(numFrames - 1,
+                                     imgIContainer::kDisposeKeep);
+
   if (blend_op == PNG_BLEND_OP_SOURCE)
       mImage->SetFrameBlendMethod(numFrames - 1, imgIContainer::kBlendSource);
   /*else // 'over' is the default
       mImage->SetFrameBlendMethod(numFrames - 1, imgIContainer::kBlendOver); */
 }
 
 // set timeout and frame disposal method for the current frame
 void nsPNGDecoder::EndImageFrame()
@@ -206,28 +214,29 @@ void nsPNGDecoder::EndImageFrame()
 
     if (NS_FAILED(mImage->FrameUpdated(numFrames - 1, mFrameRect))) {
       mError = PR_TRUE;
       // allow the call out to the observers.
     }
     PRUint32 curFrame;
     mImage->GetCurrentFrameIndex(&curFrame);
     if (mObserver)
-      mObserver->OnDataAvailable(nsnull, curFrame == numFrames - 1, &mFrameRect);
+      mObserver->OnDataAvailable(nsnull, curFrame == numFrames - 1,
+                                 &mFrameRect);
   }
 
   mImage->EndFrameDecode(numFrames - 1);
   if (mObserver)
     mObserver->OnStopFrame(nsnull, numFrames - 1);
 }
 
 
 /** imgIDecoder methods **/
 
-/* void init (in imgIContainer aImage, 
+/* void init (in imgIContainer aImage,
               imgIDecoderObserver aObserver,
               unsigned long aFlags); */
 NS_IMETHODIMP nsPNGDecoder::Init(imgIContainer *aImage,
                                  imgIDecoderObserver *aObserver,
                                  PRUint32 aFlags)
 {
 #if defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
   static png_byte color_chunks[]=
@@ -264,17 +273,17 @@ NS_IMETHODIMP nsPNGDecoder::Init(imgICon
     return NS_OK;
   }
 
   /* For full decodes, do png init stuff */
 
   /* Initialize the container's source image header. */
   /* Always decode to 24 bit pixdepth */
 
-  mPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING, 
+  mPNG = png_create_read_struct(PNG_LIBPNG_VER_STRING,
                                 NULL, error_callback, warning_callback);
   if (!mPNG) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   mInfo = png_create_info_struct(mPNG);
   if (!mInfo) {
     png_destroy_read_struct(&mPNG, NULL, NULL);
@@ -282,17 +291,17 @@ NS_IMETHODIMP nsPNGDecoder::Init(imgICon
   }
 
 #if defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
   /* Ignore unused chunks */
   if (gfxPlatform::GetCMSMode() == eCMSMode_Off) {
     png_set_keep_unknown_chunks(mPNG, 1, color_chunks, 2);
   }
   png_set_keep_unknown_chunks(mPNG, 1, unused_chunks,
-     (int)sizeof(unused_chunks)/5);   
+     (int)sizeof(unused_chunks)/5);
 #endif
 
   /* use this as libpng "progressive pointer" (retrieve in callbacks) */
   png_set_progressive_read_fn(mPNG, static_cast<png_voidp>(this),
                               info_callback, row_callback, end_callback);
 
 
   return NS_OK;
@@ -336,17 +345,18 @@ nsPNGDecoder::Write(const char *aBuffer,
   // If we only want width/height, we don't need to go through libpng
   if (mFlags & imgIDecoder::DECODER_FLAG_HEADERONLY) {
 
     // Are we done?
     if (mHeaderBytesRead == BYTES_NEEDED_FOR_DIMENSIONS)
       return NS_OK;
 
     // Read data into our header buffer
-    PRUint32 bytesToRead = PR_MIN(aCount, BYTES_NEEDED_FOR_DIMENSIONS - mHeaderBytesRead);
+    PRUint32 bytesToRead = PR_MIN(aCount, BYTES_NEEDED_FOR_DIMENSIONS -
+                                  mHeaderBytesRead);
     memcpy(mHeaderBuf + mHeaderBytesRead, aBuffer, bytesToRead);
     mHeaderBytesRead += bytesToRead;
 
     // If we're done now, verify the data and set up the container
     if (mHeaderBytesRead == BYTES_NEEDED_FOR_DIMENSIONS) {
 
       // Check that the signature bytes are right
       if (memcmp(mHeaderBuf, pngSignatureBytes, sizeof(pngSignatureBytes)))
@@ -409,17 +419,17 @@ nsPNGDecoder::NotifyDone(PRBool aSuccess
     mObserver->OnStopDecode(nsnull, aSuccess ? NS_OK : NS_ERROR_FAILURE,
                             nsnull);
   }
 
   // Mark that we've been called
   mNotifiedDone = PR_TRUE;
 }
 
-// Sets up gamma pre-correction in libpng before our callback gets called. 
+// Sets up gamma pre-correction in libpng before our callback gets called.
 // We need to do this if we don't end up with a CMS profile.
 static void
 PNGDoGammaCorrection(png_structp png_ptr, png_infop info_ptr)
 {
   double aGamma;
 
   if (png_get_gAMA(png_ptr, info_ptr, &aGamma)) {
     if ((aGamma <= 0.0) || (aGamma > 21474.83)) {
@@ -475,26 +485,28 @@ PNGGetColorProfile(png_structp png_ptr, 
   }
 
   // Check sRGB chunk
   if (!profile && png_get_valid(png_ptr, info_ptr, PNG_INFO_sRGB)) {
     profile = qcms_profile_sRGB();
 
     if (profile) {
       int fileIntent;
-      png_set_gray_to_rgb(png_ptr); 
+      png_set_gray_to_rgb(png_ptr);
       png_get_sRGB(png_ptr, info_ptr, &fileIntent);
-      PRUint32 map[] = { QCMS_INTENT_PERCEPTUAL, QCMS_INTENT_RELATIVE_COLORIMETRIC,
-                         QCMS_INTENT_SATURATION, QCMS_INTENT_ABSOLUTE_COLORIMETRIC };
+      PRUint32 map[] = { QCMS_INTENT_PERCEPTUAL,
+                         QCMS_INTENT_RELATIVE_COLORIMETRIC,
+                         QCMS_INTENT_SATURATION,
+                         QCMS_INTENT_ABSOLUTE_COLORIMETRIC };
       *intent = map[fileIntent];
     }
   }
 
   // Check gAMA/cHRM chunks
-  if (!profile && 
+  if (!profile &&
        png_get_valid(png_ptr, info_ptr, PNG_INFO_gAMA) &&
        png_get_valid(png_ptr, info_ptr, PNG_INFO_cHRM)) {
     qcms_CIE_xyYTRIPLE primaries;
     qcms_CIE_xyY whitePoint;
 
     png_get_cHRM(png_ptr, info_ptr,
                  &whitePoint.x, &whitePoint.y,
                  &primaries.red.x,   &primaries.red.y,
@@ -502,17 +514,18 @@ PNGGetColorProfile(png_structp png_ptr, 
                  &primaries.blue.x,  &primaries.blue.y);
     whitePoint.Y =
       primaries.red.Y = primaries.green.Y = primaries.blue.Y = 1.0;
 
     double gammaOfFile;
 
     png_get_gAMA(png_ptr, info_ptr, &gammaOfFile);
 
-    profile = qcms_profile_create_rgb_with_gamma(whitePoint, primaries, 1/gammaOfFile);
+    profile = qcms_profile_create_rgb_with_gamma(whitePoint, primaries,
+                                                 1.0/gammaOfFile);
 
     if (profile)
       png_set_gray_to_rgb(png_ptr);
   }
 
   if (profile) {
     PRUint32 profileSpace = qcms_profile_get_color_space(profile);
     if (profileSpace == icSigGrayData) {
@@ -538,23 +551,24 @@ info_callback(png_structp png_ptr, png_i
 /*  int number_passes;   NOT USED  */
   png_uint_32 width, height;
   int bit_depth, color_type, interlace_type, compression_type, filter_type;
   unsigned int channels;
 
   png_bytep trans = NULL;
   int num_trans = 0;
 
-  nsPNGDecoder *decoder = static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
+  nsPNGDecoder *decoder =
+               static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
   nsresult rv;
 
   /* always decode to 24-bit RGB or 32-bit RGBA  */
   png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
                &interlace_type, &compression_type, &filter_type);
-  
+
   /* Are we too big? */
   if (width > MOZ_PNG_MAX_DIMENSION || height > MOZ_PNG_MAX_DIMENSION)
     longjmp(decoder->mPNG->jmpbuf, 1);
 
   // Set the size and notify that the container is set up
   rv = decoder->mImage->SetSize(width, height);
   if (NS_FAILED(rv)) {
     longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_UNEXPECTED
@@ -589,17 +603,18 @@ info_callback(png_structp png_ptr, png_i
     else
        png_set_expand(png_ptr);
   }
 
   if (bit_depth == 16)
     png_set_strip_16(png_ptr);
 
   qcms_data_type inType;
-  PRUint32 intent, pIntent;
+  PRUint32 intent = -1;
+  PRUint32 pIntent;
   if (gfxPlatform::GetCMSMode() != eCMSMode_Off) {
     intent = gfxPlatform::GetRenderingIntent();
     decoder->mInProfile = PNGGetColorProfile(png_ptr, info_ptr,
                                              color_type, &inType, &pIntent);
     /* If we're not mandating an intent, use the one from the image. */
     if (intent == PRUint32(-1))
       intent = pIntent;
   }
@@ -607,20 +622,20 @@ info_callback(png_structp png_ptr, png_i
     qcms_data_type outType;
 
     if (color_type & PNG_COLOR_MASK_ALPHA || num_trans)
       outType = QCMS_DATA_RGBA_8;
     else
       outType = QCMS_DATA_RGB_8;
 
     decoder->mTransform = qcms_transform_create(decoder->mInProfile,
-                                             inType,
-                                             gfxPlatform::GetCMSOutputProfile(),
-                                             outType,
-                                             (qcms_intent)intent);
+                                           inType,
+                                           gfxPlatform::GetCMSOutputProfile(),
+                                           outType,
+                                           (qcms_intent)intent);
   } else {
     png_set_gray_to_rgb(png_ptr);
     PNGDoGammaCorrection(png_ptr, info_ptr);
 
     if (gfxPlatform::GetCMSMode() == eCMSMode_All) {
       if (color_type & PNG_COLOR_MASK_ALPHA || num_trans)
         decoder->mTransform = gfxPlatform::GetCMSRGBATransform();
       else
@@ -664,48 +679,49 @@ info_callback(png_structp png_ptr, png_i
 
   if (channels == 1 || channels == 3)
     decoder->format = gfxASurface::ImageFormatRGB24;
   else if (channels == 2 || channels == 4)
     decoder->format = gfxASurface::ImageFormatARGB32;
 
   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL))
     png_set_progressive_frame_fn(png_ptr, frame_info_callback, NULL);
-  
+
   if (png_get_first_frame_is_hidden(png_ptr, info_ptr)) {
     decoder->mFrameIsHidden = PR_TRUE;
   } else {
     decoder->CreateFrame(0, 0, width, height, decoder->format);
   }
-  
+
   if (decoder->mTransform &&
       (channels <= 2 || interlace_type == PNG_INTERLACE_ADAM7)) {
     PRUint32 bpp[] = { 0, 3, 4, 3, 4 };
     decoder->mCMSLine =
       (PRUint8 *)nsMemory::Alloc(bpp[channels] * width);
     if (!decoder->mCMSLine) {
       longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY
     }
   }
 
   if (interlace_type == PNG_INTERLACE_ADAM7) {
     if (height < PR_INT32_MAX / (width * channels))
-      decoder->interlacebuf = (PRUint8 *)nsMemory::Alloc(channels * width * height);
+      decoder->interlacebuf = (PRUint8 *)nsMemory::Alloc(channels *
+                                                         width * height);
     if (!decoder->interlacebuf) {
       longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY
     }
   }
-  
+
   /* Reject any ancillary chunk after IDAT with a bad CRC (bug #397593).
    * It would be better to show the default frame (if one has already been
    * successfully decoded) before bailing, but it's simpler to just bail
    * out with an error message.
    */
   png_set_crc_action(png_ptr, NULL, PNG_CRC_ERROR_QUIT);
-  
+
   return;
 }
 
 void
 row_callback(png_structp png_ptr, png_bytep new_row,
              png_uint_32 row_num, int pass)
 {
   /* libpng comments:
@@ -730,18 +746,19 @@ row_callback(png_structp png_ptr, png_by
    *
    * where old_row is what was displayed for previous rows.  Note
    * that the first pass (pass == 0 really) will completely cover
    * the old row, so the rows do not have to be initialized.  After
    * the first pass (and only for interlaced images), you will have
    * to pass the current row, and the function will combine the
    * old row and the new row.
    */
-  nsPNGDecoder *decoder = static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
-  
+  nsPNGDecoder *decoder =
+               static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
+
   // skip this frame
   if (decoder->mFrameIsHidden)
     return;
 
   if (new_row) {
     PRInt32 width = decoder->mFrameRect.width;
     PRUint32 iwidth = decoder->mFrameRect.width;
 
@@ -752,17 +769,18 @@ row_callback(png_structp png_ptr, png_by
     }
 
     PRUint32 bpr = width * sizeof(PRUint32);
     PRUint32 *cptr32 = (PRUint32*)(decoder->mImageData + (row_num*bpr));
     PRBool rowHasNoAlpha = PR_TRUE;
 
     if (decoder->mTransform) {
       if (decoder->mCMSLine) {
-        qcms_transform_data(decoder->mTransform, line, decoder->mCMSLine, iwidth);
+        qcms_transform_data(decoder->mTransform, line, decoder->mCMSLine,
+                            iwidth);
         /* copy alpha over */
         PRUint32 channels = decoder->mChannels;
         if (channels == 2 || channels == 4) {
           for (PRUint32 i = 0; i < iwidth; i++)
             decoder->mCMSLine[4 * i + 3] = line[channels * i + channels - 1];
         }
         line = decoder->mCMSLine;
       } else {
@@ -774,17 +792,17 @@ row_callback(png_structp png_ptr, png_by
       case gfxASurface::ImageFormatRGB24:
       {
         // counter for while() loops below
         PRUint32 idx = iwidth;
 
         // copy as bytes until source pointer is 32-bit-aligned
         for (; (NS_PTR_TO_UINT32(line) & 0x3) && idx; --idx) {
           *cptr32++ = GFX_PACKED_PIXEL(0xFF, line[0], line[1], line[2]);
-          line += 3; 
+          line += 3;
         }
 
         // copy pixels in blocks of 4
         while (idx >= 4) {
           GFX_BLOCK_RGB_TO_FRGB(line, cptr32);
           idx    -=  4;
           line   += 12;
           cptr32 +=  4;
@@ -824,41 +842,43 @@ row_callback(png_structp png_ptr, png_by
       nsIntRect r(0, row_num, width, 1);
       if (NS_FAILED(decoder->mImage->FrameUpdated(numFrames - 1, r))) {
         decoder->mError = PR_TRUE;  /* bail */
         return;
       }
       PRUint32 curFrame;
       decoder->mImage->GetCurrentFrameIndex(&curFrame);
       if (decoder->mObserver)
-        decoder->mObserver->OnDataAvailable(nsnull, curFrame == numFrames - 1, &r);
+        decoder->mObserver->OnDataAvailable(nsnull,
+                                            curFrame == numFrames - 1, &r);
     }
   }
 }
 
 // got the header of a new frame that's coming
 void
 frame_info_callback(png_structp png_ptr, png_uint_32 frame_num)
 {
   png_uint_32 x_offset, y_offset;
   PRInt32 width, height;
-  
-  nsPNGDecoder *decoder = static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
-  
+
+  nsPNGDecoder *decoder =
+               static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
+
   // old frame is done
   if (!decoder->mFrameIsHidden)
     decoder->EndImageFrame();
-  
+
   decoder->mFrameIsHidden = PR_FALSE;
-  
+
   x_offset = png_get_next_frame_x_offset(png_ptr, decoder->mInfo);
   y_offset = png_get_next_frame_y_offset(png_ptr, decoder->mInfo);
   width = png_get_next_frame_width(png_ptr, decoder->mInfo);
   height = png_get_next_frame_height(png_ptr, decoder->mInfo);
-  
+
   decoder->CreateFrame(x_offset, y_offset, width, height, decoder->format);
 }
 
 void
 end_callback(png_structp png_ptr, png_infop info_ptr)
 {
   /* libpng comments:
    *
@@ -867,21 +887,22 @@ end_callback(png_structp png_ptr, png_in
    * the IEND).  You will usually have the same info chunk as you
    * had in the header, although some data may have been added
    * to the comments and time fields.
    *
    * Most people won't do much here, perhaps setting a flag that
    * marks the image as finished.
    */
 
-  nsPNGDecoder *decoder = static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
+  nsPNGDecoder *decoder =
+               static_cast<nsPNGDecoder*>(png_get_progressive_ptr(png_ptr));
 
   // We shouldn't get here if we've hit an error
   NS_ABORT_IF_FALSE(!decoder->mError, "Finishing up PNG but hit error!");
-  
+
   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_acTL)) {
     PRInt32 num_plays = png_get_num_plays(png_ptr, info_ptr);
     decoder->mImage->SetLoopCount(num_plays - 1);
   }
 
   // Send final notifications
   decoder->NotifyDone(/* aSuccess = */ PR_TRUE);
 }
--- a/modules/libpr0n/decoders/png/nsPNGDecoder.h
+++ b/modules/libpr0n/decoders/png/nsPNGDecoder.h
@@ -65,21 +65,21 @@ class nsPNGDecoder : public imgIDecoder
 {
 public:
   NS_DECL_ISUPPORTS
   NS_DECL_IMGIDECODER
 
   nsPNGDecoder();
   virtual ~nsPNGDecoder();
 
-  void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset, 
-                   PRInt32 width, PRInt32 height, 
+  void CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset,
+                   PRInt32 width, PRInt32 height,
                    gfxASurface::gfxImageFormat format);
   void SetAnimFrameInfo();
-  
+
   void EndImageFrame();
   void NotifyDone(PRBool aSuccess);
 
 public:
   nsCOMPtr<imgIContainer> mImage;
   nsCOMPtr<imgIDecoderObserver> mObserver;
   PRUint32 mFlags;
 
--- a/modules/libpr0n/src/imgRequest.cpp
+++ b/modules/libpr0n/src/imgRequest.cpp
@@ -185,21 +185,25 @@ nsresult imgRequest::RemoveProxy(imgRequ
 
   /* Check mState below before we potentially call Cancel() below. Since
      Cancel() may result in OnStopRequest being called back before Cancel()
      returns, leaving mState in a different state then the one it was in at
      this point.
    */
 
   if (aNotify) {
+    // The "real" OnStopDecode - fix this with bug 505385.
+    if (!(mState & stateDecodeStopped)) {
+      proxy->OnStopContainer(mImage);
+    }
+
     // make sure that observer gets an OnStopDecode message sent to it
     if (!(mState & stateRequestStopped)) {
       proxy->OnStopDecode(aStatus, nsnull);
     }
-
   }
 
   // make sure that observer gets an OnStopRequest message sent to it
   if (!(mState & stateRequestStopped)) {
     proxy->OnStopRequest(nsnull, nsnull, NS_BINDING_ABORTED, PR_TRUE);
   }
 
   if (mImage && !HaveProxyWithObserver(nsnull)) {
@@ -290,18 +294,21 @@ nsresult imgRequest::NotifyProxyListener
   }
 
   if (mImage && !HaveProxyWithObserver(proxy) && proxy->HasObserver()) {
     LOG_MSG(gImgLog, "imgRequest::NotifyProxyListener", "resetting animation");
 
     mImage->ResetAnimation();
   }
 
+  // The "real" OnStopDecode - Fix this with bug 505385.
+  if (mState & stateDecodeStopped)
+    proxy->OnStopContainer(mImage);
+
   if (mState & stateRequestStopped) {
-    proxy->OnStopContainer(mImage);
     proxy->OnStopDecode(GetResultFromImageStatus(mImageStatus), nsnull);
     proxy->OnStopRequest(nsnull, nsnull,
                          GetResultFromImageStatus(mImageStatus),
                          mHadLastPart);
   }
 
   return NS_OK;
 }
@@ -646,16 +653,20 @@ NS_IMETHODIMP imgRequest::OnStopFrame(im
 }
 
 /* void onStopContainer (in imgIRequest request, in imgIContainer image); */
 NS_IMETHODIMP imgRequest::OnStopContainer(imgIRequest *request,
                                           imgIContainer *image)
 {
   LOG_SCOPE(gImgLog, "imgRequest::OnStopContainer");
 
+  // XXXbholley - This should be moved into OnStopDecode when we fix bug
+  // 505385.
+  mState |= stateDecodeStopped;
+
   nsTObserverArray<imgRequestProxy*>::ForwardIterator iter(mObservers);
   while (iter.HasMore()) {
     iter.GetNext()->OnStopContainer(image);
   }
 
   return NS_OK;
 }
 
@@ -695,17 +706,17 @@ NS_IMETHODIMP imgRequest::OnStopRequest(
   NS_NOTREACHED("imgRequest(imgIDecoderObserver)::OnStopRequest");
   return NS_OK;
 }
 
 /* void onDiscard (in imgIRequest request); */
 NS_IMETHODIMP imgRequest::OnDiscard(imgIRequest *aRequest)
 {
   // Clear the state bits we no longer deserve.
-  PRUint32 stateBitsToClear = stateDecodeStarted;
+  PRUint32 stateBitsToClear = stateDecodeStarted | stateDecodeStopped;
   mState &= ~stateBitsToClear;
 
   // Clear the status bits we no longer deserve.
   PRUint32 statusBitsToClear = imgIRequest::STATUS_FRAME_COMPLETE
                                | imgIRequest::STATUS_DECODE_COMPLETE;
   mImageStatus &= ~statusBitsToClear;
 
   // Update the cache entry size, since we just got rid of frame data
@@ -745,16 +756,17 @@ NS_IMETHODIMP imgRequest::OnStartRequest
     mImage->NewSourceData();
 
     // Clear any status and state bits indicating load/decode
     mImageStatus &= ~imgIRequest::STATUS_LOAD_PARTIAL;
     mImageStatus &= ~imgIRequest::STATUS_LOAD_COMPLETE;
     mImageStatus &= ~imgIRequest::STATUS_FRAME_COMPLETE;
     mState &= ~stateRequestStarted;
     mState &= ~stateDecodeStarted;
+    mState &= ~stateDecodeStopped;
     mState &= ~stateRequestStopped;
   }
 
   /*
    * If mRequest is null here, then we need to set it so that we'll be able to
    * cancel it if our Cancel() method is called.  Note that this can only
    * happen for multipart channels.  We could simply not null out mRequest for
    * non-last parts, if GetIsLastPart() were reliable, but it's not.  See
--- a/modules/libpr0n/src/imgRequest.h
+++ b/modules/libpr0n/src/imgRequest.h
@@ -66,16 +66,17 @@ class imgCacheValidator;
 
 class imgRequestProxy;
 class imgCacheEntry;
 
 enum {
   stateRequestStarted    = PR_BIT(0),
   stateHasSize           = PR_BIT(1),
   stateDecodeStarted     = PR_BIT(2),
+  stateDecodeStopped     = PR_BIT(3),
   stateRequestStopped    = PR_BIT(4)
 };
 
 class imgRequest : public imgIDecoderObserver,
                    public nsIStreamListener,
                    public nsSupportsWeakReference,
                    public nsIChannelEventSink,
                    public nsIInterfaceRequestor
--- a/modules/plugin/base/src/nsNPAPIPluginInstance.cpp
+++ b/modules/plugin/base/src/nsNPAPIPluginInstance.cpp
@@ -498,22 +498,23 @@ nsNPAPIPluginStreamListener::OnDataAvail
     // mStreamBuffer here in first ODA when length of data available
     // in input stream is known.  mStreamBuffer will be freed in DTOR.
     // we also have to remember the size of that buff to make safe
     // consecutive Read() calls form input stream into our buff.
 
     PRUint32 contentLength;
     pluginInfo->GetLength(&contentLength);
 
-    mStreamBufferSize = PR_MAX(length, contentLength);
+    mStreamBufferSize = NS_MAX(length, contentLength);
 
     // Limit the size of the initial buffer to MAX_PLUGIN_NECKO_BUFFER
     // (16k). This buffer will grow if needed, as in the case where
     // we're getting data faster than the plugin can process it.
-    mStreamBufferSize = PR_MIN(mStreamBufferSize, MAX_PLUGIN_NECKO_BUFFER);
+    mStreamBufferSize = NS_MIN(mStreamBufferSize,
+                               PRUint32(MAX_PLUGIN_NECKO_BUFFER));
 
     mStreamBuffer = (char*) PR_Malloc(mStreamBufferSize);
     if (!mStreamBuffer)
       return NS_ERROR_OUT_OF_MEMORY;
   }
   
   // prepare NPP_ calls params
   NPP npp;
@@ -558,17 +559,17 @@ nsNPAPIPluginStreamListener::OnDataAvail
         char *buf = (char*)PR_Realloc(mStreamBuffer, mStreamBufferSize);
         if (!buf)
           return NS_ERROR_OUT_OF_MEMORY;
 
         mStreamBuffer = buf;
       }
 
       PRUint32 bytesToRead =
-        PR_MIN(length, mStreamBufferSize - mStreamBufferByteCount);
+        NS_MIN(length, mStreamBufferSize - mStreamBufferByteCount);
 
       PRUint32 amountRead = 0;
       rv = input->Read(mStreamBuffer + mStreamBufferByteCount, bytesToRead,
                        &amountRead);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (amountRead == 0) {
         NS_NOTREACHED("input->Read() returns no data, it's almost impossible "
@@ -637,17 +638,17 @@ nsNPAPIPluginStreamListener::OnDataAvail
 
           // Break out of the inner loop, but keep going through the
           // outer loop in case there's more data to read from the
           // input stream.
 
           break;
         }
 
-        numtowrite = PR_MIN(numtowrite, mStreamBufferByteCount);
+        numtowrite = NS_MIN(numtowrite, mStreamBufferByteCount);
       } else {
         // if WriteReady is not supported by the plugin, just write
         // the whole buffer
         numtowrite = mStreamBufferByteCount;
       }
 
       NPPAutoPusher nppPusher(npp);
 
@@ -665,17 +666,17 @@ nsNPAPIPluginStreamListener::OnDataAvail
         // NPP_Write(), kill the stream.
         return NS_BINDING_ABORTED;
       }
 
       if (writeCount > 0) {
         NS_ASSERTION(writeCount <= mStreamBufferByteCount,
                      "Plugin read past the end of the available data!");
 
-        writeCount = PR_MIN(writeCount, mStreamBufferByteCount);
+        writeCount = NS_MIN(writeCount, mStreamBufferByteCount);
         mStreamBufferByteCount -= writeCount;
 
         streamPosition += writeCount;
 
         zeroBytesWriteCount = 0;
 
         if (mStreamBufferByteCount > 0) {
           // This alignment code is most likely bogus, but we'll leave
--- a/modules/plugin/test/testplugin/Makefile.in
+++ b/modules/plugin/test/testplugin/Makefile.in
@@ -72,16 +72,17 @@ ifeq ($(MOZ_WIDGET_TOOLKIT),qt)
 CPPSRCS += nptest_qt.cpp
 endif
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),windows)
 CPPSRCS  += nptest_windows.cpp
 RCFILE    = nptest.rc
 RESFILE   = nptest.res
 DEFFILE   = $(win_srcdir)/nptest.def
+OS_LIBS  += $(call EXPAND_LIBNAME,msimg32)
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
 CXXFLAGS        += $(MOZ_GTK2_CFLAGS)
 CFLAGS          += $(MOZ_GTK2_CFLAGS)
 EXTRA_DSO_LDOPTS += $(MOZ_GTK2_LIBS) $(XLDFLAGS) $(XLIBS) $(XEXT_LIBS)
--- a/modules/plugin/test/testplugin/nptest_windows.cpp
+++ b/modules/plugin/test/testplugin/nptest_windows.cpp
@@ -34,18 +34,16 @@
 
 #include "nptest_platform.h"
 
 #include <windows.h>
 #include <windowsx.h>
 
  using namespace std;
 
-#pragma comment(lib, "msimg32.lib")
-
 void SetSubclass(HWND hWnd, InstanceData* instanceData);
 void ClearSubclass(HWND hWnd);
 LRESULT CALLBACK PluginWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 
 struct _PlatformData {
   HWND childWindow;
 };
 
--- a/netwerk/protocol/http/src/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/src/nsHttpChannel.cpp
@@ -2829,16 +2829,19 @@ nsHttpChannel::SetupReplacementChannel(n
         httpChannel->SetReferrer(mReferrer);
     // convey the mAllowPipelining flag
     httpChannel->SetAllowPipelining(mAllowPipelining);
     // convey the new redirection limit
     httpChannel->SetRedirectionLimit(mRedirectionLimit - 1);
 
     nsCOMPtr<nsIHttpChannelInternal> httpInternal = do_QueryInterface(newChannel);
     if (httpInternal) {
+        // convey the mForceAllowThirdPartyCookie flag
+        httpInternal->SetForceAllowThirdPartyCookie(mForceAllowThirdPartyCookie);
+
         // update the DocumentURI indicator since we are being redirected.
         // if this was a top-level document channel, then the new channel
         // should have its mDocumentURI point to newURI; otherwise, we
         // just need to pass along our mDocumentURI to the new channel.
         if (newURI && (mURI == mDocumentURI))
             httpInternal->SetDocumentURI(newURI);
         else
             httpInternal->SetDocumentURI(mDocumentURI);
new file mode 100644
--- /dev/null
+++ b/netwerk/test/unit/test_bug528292.js
@@ -0,0 +1,67 @@
+do_load_httpd_js();
+
+const sentCookieVal     = "foo=bar";
+const responseBody      = "response body";
+const baseURL           = "http://localhost:4444";
+const preRedirectPath   = "/528292/pre-redirect";
+const preRedirectURL    = baseURL + preRedirectPath;
+const postRedirectPath  = "/528292/post-redirect";
+const postRedirectURL   = baseURL + postRedirectPath;
+var   httpServer        = null;
+var   receivedCookieVal = null;
+
+function preRedirectHandler(metadata, response)
+{
+  response.setStatusLine(metadata.httpVersion, 302, "Found");
+  response.setHeader("Location", postRedirectURL, false);
+  return;
+}
+
+function postRedirectHandler(metadata, response)
+{
+  receivedCookieVal = metadata.getHeader("Cookie");
+  response.setHeader("Content-Type", "text/plain");
+  response.bodyOutputStream.write(responseBody, responseBody.length);
+}
+
+function run_test()
+{
+  // Start the HTTP server.
+  httpServer = new nsHttpServer();
+  httpServer.registerPathHandler(preRedirectPath, preRedirectHandler);
+  httpServer.registerPathHandler(postRedirectPath, postRedirectHandler);
+  httpServer.start(4444);
+
+  // Disable third-party cookies in general.
+  Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch).
+    setIntPref("network.cookie.cookieBehavior", 1);
+
+  var ioService = Cc["@mozilla.org/network/io-service;1"].
+                  getService(Ci.nsIIOService);
+
+  // Set up a channel with forceAllowThirdPartyCookie set to true.  We'll use
+  // the channel both to set a cookie (since nsICookieService::setCookieString
+  // requires such a channel in order to successfully set a cookie) and then
+  // to load the pre-redirect URI.
+  var chan = ioService.newChannel(preRedirectURL, "", null).
+             QueryInterface(Ci.nsIHttpChannel).
+             QueryInterface(Ci.nsIHttpChannelInternal);
+  chan.forceAllowThirdPartyCookie = true;
+
+  // Set a cookie on one of the URIs.  It doesn't matter which one, since
+  // they're both from the same host, which is enough for the cookie service
+  // to send the cookie with both requests.
+  var postRedirectURI = ioService.newURI(postRedirectURL, "", null);
+  Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService).
+    setCookieString(postRedirectURI, null, sentCookieVal, chan);
+
+  // Load the pre-redirect URI.
+  chan.asyncOpen(new ChannelListener(finish_test, null), null);
+  do_test_pending();
+}
+
+function finish_test(event)
+{
+  do_check_eq(receivedCookieVal, sentCookieVal);
+  httpServer.stop(do_test_finished);
+}
--- a/parser/htmlparser/src/CNavDTD.cpp
+++ b/parser/htmlparser/src/CNavDTD.cpp
@@ -501,17 +501,17 @@ IsHiddenInput(CToken* aToken, nsITokeniz
                   "Must be start token");
   NS_PRECONDITION(eHTMLTags(aToken->GetTypeID()) == eHTMLTag_input,
                   "Must be <input> tag");
   
   PRInt32 ac = aToken->GetAttributeCount();
   NS_ASSERTION(ac <= aTokenizer->GetCount(),
                "Not enough tokens in the tokenizer");
   // But we don't really trust ourselves to get that right
-  ac = PR_MIN(ac, aTokenizer->GetCount());
+  ac = NS_MIN(ac, aTokenizer->GetCount());
   
   for (PRInt32 i = 0; i < ac; ++i) {
     NS_ASSERTION(eHTMLTokenTypes(aTokenizer->GetTokenAt(i)->GetTokenType()) ==
                    eToken_attribute, "Unexpected token type");
     // Again, we're not sure we actually manage to guarantee that
     if (eHTMLTokenTypes(aTokenizer->GetTokenAt(i)->GetTokenType()) !=
         eToken_attribute) {
       break;
--- a/parser/htmlparser/src/nsHTMLTags.cpp
+++ b/parser/htmlparser/src/nsHTMLTags.cpp
@@ -378,17 +378,17 @@ nsHTMLTags::AddRefTable(void)
         nsAutoString temp2; temp2.AssignWithConversion(sTagAtoms_info[i].mString);
         NS_ASSERTION(temp1.Equals(temp2), "Bad unicode tag name!");
       }
 
       // let's verify that NS_HTMLTAG_NAME_MAX_LENGTH is correct
       PRUint32 maxTagNameLength = 0;
       for (i = 0; i < NS_HTML_TAG_MAX; ++i) {
         PRUint32 len = nsCRT::strlen(sTagUnicodeTable[i]);
-        maxTagNameLength = PR_MAX(len, maxTagNameLength);        
+        maxTagNameLength = NS_MAX(len, maxTagNameLength);        
       }
       NS_ASSERTION(maxTagNameLength == NS_HTMLTAG_NAME_MAX_LENGTH,
                    "NS_HTMLTAG_NAME_MAX_LENGTH not set correctly!");
     }
 #endif
   }
 
   return NS_OK;
--- a/parser/htmlparser/src/nsParser.cpp
+++ b/parser/htmlparser/src/nsParser.cpp
@@ -498,17 +498,17 @@ nsSpeculativeScriptThread::StartParsing(
 
     nsScannerIterator start;
     context->mScanner->CurrentPosition(start);
 
     if (mNumConsumed > context->mNumConsumed) {
       // We consumed more the last time we tried speculatively parsing than we
       // did the last time we actually parsed.
       PRUint32 distance = Distance(start, end);
-      start.advance(PR_MIN(mNumConsumed - context->mNumConsumed, distance));
+      start.advance(NS_MIN(mNumConsumed - context->mNumConsumed, distance));
     }
 
     if (start == end) {
       // We're at the end of this context's buffer, nothing else to do.
       return NS_OK;
     }
 
     CopyUnicodeTo(start, end, toScan);
@@ -2716,17 +2716,17 @@ nsParser::DetectMetaTag(const char* aByt
   // documents we should be looking inside the XMLDecl.
   if (!mParserContext->mMimeType.EqualsLiteral(kHTMLTextContentType)) {
     return PR_FALSE;
   }
 
   // Fast and loose parsing to determine if we have a complete
   // META tag in this block, looking upto 2k into it.
   const nsASingleFragmentCString& str =
-      Substring(aBytes, aBytes + PR_MIN(aLen, 2048));
+      Substring(aBytes, aBytes + NS_MIN(aLen, 2048));
   // XXXldb Should be const_char_iterator when FindInReadable supports it.
   nsACString::const_iterator begin, end;
 
   str.BeginReading(begin);
   str.EndReading(end);
   nsACString::const_iterator currPos(begin);
   nsACString::const_iterator tokEnd;
   nsACString::const_iterator tagEnd(begin);
--- a/profile/dirserviceprovider/src/nsProfileLock.cpp
+++ b/profile/dirserviceprovider/src/nsProfileLock.cpp
@@ -154,17 +154,18 @@ void nsProfileLock::RemovePidLockFiles()
 static struct sigaction SIGHUP_oldact;
 static struct sigaction SIGINT_oldact;
 static struct sigaction SIGQUIT_oldact;
 static struct sigaction SIGILL_oldact;
 static struct sigaction SIGABRT_oldact;
 static struct sigaction SIGSEGV_oldact;
 static struct sigaction SIGTERM_oldact;
 
-void nsProfileLock::FatalSignalHandler(int signo)
+void nsProfileLock::FatalSignalHandler(int signo, siginfo_t *info,
+                                       void *context)
 {
     // Remove any locks still held.
     RemovePidLockFiles();
 
     // Chain to the old handler, which may exit.
     struct sigaction *oldact = nsnull;
 
     switch (signo) {
@@ -206,16 +207,20 @@ void nsProfileLock::FatalSignalHandler(i
             sigset_t unblock_sigs;
             sigemptyset(&unblock_sigs);
             sigaddset(&unblock_sigs, signo);
 
             sigprocmask(SIG_UNBLOCK, &unblock_sigs, NULL);
 
             raise(signo);
         }
+        else if (oldact->sa_sigaction &&
+                 (oldact->sa_flags & SA_SIGINFO) == SA_SIGINFO) {
+            oldact->sa_sigaction(signo, info, context);
+        }
         else if (oldact->sa_handler && oldact->sa_handler != SIG_IGN)
         {
             oldact->sa_handler(signo);
         }
     }
 
     // Backstop exit call, just in case.
     _exit(signo);
@@ -382,18 +387,18 @@ nsresult nsProfileLock::LockWithSymlink(
                 // Clean up on normal termination.
                 atexit(RemovePidLockFiles);
 
                 // Clean up on abnormal termination, using POSIX sigaction.
                 // Don't arm a handler if the signal is being ignored, e.g.,
                 // because mozilla is run via nohup.
                 if (!sDisableSignalHandling) {
                     struct sigaction act, oldact;
-                    act.sa_handler = FatalSignalHandler;
-                    act.sa_flags = 0;
+                    act.sa_sigaction = FatalSignalHandler;
+                    act.sa_flags = SA_SIGINFO;
                     sigfillset(&act.sa_mask);
 
 #define CATCH_SIGNAL(signame)                                           \
 PR_BEGIN_MACRO                                                          \
   if (sigaction(signame, NULL, &oldact) == 0 &&                         \
       oldact.sa_handler != SIG_IGN)                                     \
   {                                                                     \
       sigaction(signame, &act, &signame##_oldact);                      \
--- a/profile/dirserviceprovider/src/nsProfileLock.h
+++ b/profile/dirserviceprovider/src/nsProfileLock.h
@@ -50,16 +50,17 @@ class nsIProfileUnlocker;
 
 #if defined (XP_OS2)
 #define INCL_DOSERRORS
 #define INCL_DOSFILEMGR
 #include <os2.h>
 #endif
 
 #if defined (XP_UNIX)
+#include <signal.h>
 #include "prclist.h"
 #endif
 
 class nsProfileLock
 #if defined (XP_UNIX)
   : public PRCList
 #endif
 {
@@ -87,17 +88,18 @@ private:
     PRPackedBool            mHaveLock;
 
 #if defined (XP_WIN)
     HANDLE                  mLockFileHandle;
 #elif defined (XP_OS2)
     LHANDLE                 mLockFileHandle;
 #elif defined (XP_UNIX)
     static void             RemovePidLockFiles();
-    static void             FatalSignalHandler(int signo);
+    static void             FatalSignalHandler(int signo, siginfo_t *info,
+                                               void *context);
     static PRCList          mPidLockList;
 
     nsresult                LockWithFcntl(const nsACString& lockFilePath);
 
     /**
      * @param aHaveFcntlLock if true, we've already acquired an fcntl lock so this
      * lock is merely an "obsolete" lock to keep out old Firefoxes
      */
--- a/testing/xpcshell/Makefile.in
+++ b/testing/xpcshell/Makefile.in
@@ -65,16 +65,21 @@ EXTRA_BUILD_FILES := \
   $(NULL)
 
 # Components / typelibs that don't get packaged with
 # the build, but that we need for the test harness.
 TEST_HARNESS_COMPONENTS := \
   httpd.js \
   $(NULL)
 
+ifdef MOZ_CRASHREPORTER
+#XXX: should find a better way to do this
+TEST_HARNESS_COMPONENTS +=  crashreporter_test.xpt
+endif
+
 # Rules for staging the necessary harness bits for a test package
 PKG_STAGE = $(DIST)/test-package-stage
 
 stage-package:
 	$(NSINSTALL) -D $(PKG_STAGE)/xpcshell/tests
 	@(cd $(srcdir) && tar $(TAR_CREATE_FLAGS) - $(TEST_HARNESS_FILES)) | (cd $(PKG_STAGE)/xpcshell && tar -xf -)
 	@(cd $(topsrcdir)/build && tar $(TAR_CREATE_FLAGS) - $(EXTRA_BUILD_FILES)) | (cd $(PKG_STAGE)/xpcshell && tar -xf -)
 	@(cd $(DEPTH)/_tests/xpcshell/ && tar $(TAR_CREATE_FLAGS) - *) | (cd $(PKG_STAGE)/xpcshell/tests && tar -xf -)
--- a/toolkit/components/autocomplete/src/Makefile.in
+++ b/toolkit/components/autocomplete/src/Makefile.in
@@ -56,13 +56,9 @@ CPPSRCS = nsAutoCompleteController.cpp \
           nsAutoCompleteSimpleResult.cpp \
           $(NULL)
 
 EXTRA_DSO_LDOPTS += \
 	$(MOZ_UNICHARUTIL_LIBS) \
 	$(MOZ_COMPONENT_LIBS) \
 	$(NULL)
 
-ifdef MOZ_MORKREADER
-EXTRA_DSO_LDOPTS += $(DEPTH)/db/morkreader/$(LIB_PREFIX)morkreader_s.$(LIB_SUFFIX)
-endif
-
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/components/build/nsToolkitCompsCID.h
+++ b/toolkit/components/build/nsToolkitCompsCID.h
@@ -58,19 +58,16 @@
   "@mozilla.org/autocomplete/mdb-result;1"
 
 #define NS_DOWNLOADMANAGER_CONTRACTID \
   "@mozilla.org/download-manager;1"
 
 #define NS_FORMHISTORY_CONTRACTID \
   "@mozilla.org/satchel/form-history;1"
 
-#define NS_FORMHISTORYIMPORTER_CONTRACTID \
-  "@mozilla.org/satchel/form-history-importer;1"
-
 #define NS_FORMFILLCONTROLLER_CONTRACTID \
   "@mozilla.org/satchel/form-fill-controller;1"
 
 #define NS_FORMHISTORYAUTOCOMPLETE_CONTRACTID \
   "@mozilla.org/autocomplete/search;1?name=form-history"
 
 #define NS_GLOBALHISTORY_DATASOURCE_CONTRACTID \
   "@mozilla.org/rdf/datasource;1?name=history"
@@ -144,20 +141,16 @@
 // {895DB6C7-DBDF-40ea-9F64-B175033243DC}
 #define NS_FORMFILLCONTROLLER_CID \
 { 0x895db6c7, 0xdbdf, 0x40ea, { 0x9f, 0x64, 0xb1, 0x75, 0x3, 0x32, 0x43, 0xdc } }
 
 // {A2059C0E-5A58-4c55-AB7C-26F0557546EF}
 #define NS_FORMHISTORY_CID \
 { 0xa2059c0e, 0x5a58, 0x4c55, { 0xab, 0x7c, 0x26, 0xf0, 0x55, 0x75, 0x46, 0xef } }
 
-// {db340cc2-7f50-4ea3-8427-f529daf6dc87}
-#define NS_FORMHISTORYIMPORTER_CID \
-{ 0xdb340cc2, 0x7f50, 0x4ea3, { 0x84, 0x27, 0xf5, 0x29, 0xda, 0xf6, 0xdc, 0x87 } }
-
 // {59648a91-5a60-4122-8ff2-54b839c84aed}
 #define NS_GLOBALHISTORY_CID \
 { 0x59648a91, 0x5a60, 0x4122, { 0x8f, 0xf2, 0x54, 0xb8, 0x39, 0xc8, 0x4a, 0xed} }
 
 // {59648a91-5a60-4122-8ff2-54b839c84aed}
 #define NS_PARENTALCONTROLSSERVICE_CID \
 { 0x580530e5, 0x118c, 0x4bc7, { 0xab, 0x88, 0xbc, 0x2c, 0xd2, 0xb9, 0x72, 0x23 } }
 
--- a/toolkit/components/passwordmgr/public/Makefile.in
+++ b/toolkit/components/passwordmgr/public/Makefile.in
@@ -46,11 +46,12 @@ XPIDL_MODULE  = loginmgr
 
 XPIDLSRCS = \
 		nsILoginInfo.idl \
 		nsILoginMetaInfo.idl \
 		nsILoginManager.idl \
 		nsILoginManagerStorage.idl \
 		nsILoginManagerPrompter.idl \
 		nsILoginManagerIEMigrationHelper.idl \
+		nsILoginManagerCrypto.idl \
 		$(NULL)
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/toolkit/components/passwordmgr/public/nsILoginManagerCrypto.idl
@@ -0,0 +1,73 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Justin Dolske <dolske@mozilla.com> (original author)
+ *
+ * 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 ***** */
+
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(1ddbe67d-a216-4915-9e0a-3e1b95b7126c)]
+
+interface nsILoginManagerCrypto : nsISupports {
+
+    /**
+     * encrypt
+     *
+     * @param plainText
+     *        The string to be encrypted.
+     *
+     * Encrypts the specified string, returning the ciphertext value.
+     *
+     * NOTE: The current implemention of this inferface simply uses NSS/PSM's
+     * "Secret Decoder Ring" service. It is not recommended for general
+     * purpose encryption/decryption.
+     *
+     * Can throw if the user cancels entry of their master password.
+     */
+    AString encrypt(in AString plainText);
+
+    /**
+     * decrypt
+     *
+     * @param cipherText
+     *        The string to be decrypted.
+     *
+     * Decrypts the specified string, returning the plaintext value.
+     *
+     * Can throw if the user cancels entry of their master password, or if the
+     * cipherText value can not be successfully decrypted (eg, if it was
+     * encrypted with some other key).
+     */
+    AString decrypt(in AString cipherText);
+};
--- a/toolkit/components/passwordmgr/src/Makefile.in
+++ b/toolkit/components/passwordmgr/src/Makefile.in
@@ -44,12 +44,13 @@ include $(DEPTH)/config/autoconf.mk
 MODULE = loginmgr
 
 EXTRA_COMPONENTS = \
 			nsLoginManager.js \
 			nsLoginManagerPrompter.js \
 			nsLoginInfo.js \
 			storage-Legacy.js \
 			storage-mozStorage.js \
+			crypto-SDR.js \
 			$(NULL)
 
 
 include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/toolkit/components/passwordmgr/src/crypto-SDR.js
@@ -0,0 +1,205 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Justin Dolske <dolske@mozilla.com> (original author)
+ *
+ * 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 ***** */
+
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
+
+function LoginManagerCrypto_SDR() {
+    this.init();
+};
+
+LoginManagerCrypto_SDR.prototype = {
+
+    classDescription  : "LoginManagerCrypto_SDR",
+    contractID : "@mozilla.org/login-manager/crypto/SDR;1",
+    classID : Components.ID("{dc6c2976-0f73-4f1f-b9ff-3d72b4e28309}"),
+    QueryInterface : XPCOMUtils.generateQI([Ci.nsILoginManagerCrypto]),
+
+    __logService : null, // Console logging service, used for debugging.
+    get _logService() {
+        if (!this.__logService)
+            this.__logService = Cc["@mozilla.org/consoleservice;1"].
+                                getService(Ci.nsIConsoleService);
+        return this.__logService;
+    },
+
+    __decoderRing : null,  // nsSecretDecoderRing service
+    get _decoderRing() {
+        if (!this.__decoderRing)
+            this.__decoderRing = Cc["@mozilla.org/security/sdr;1"].
+                                 getService(Ci.nsISecretDecoderRing);
+        return this.__decoderRing;
+    },
+
+    __utfConverter : null, // UCS2 <--> UTF8 string conversion
+    get _utfConverter() {
+        if (!this.__utfConverter) {
+            this.__utfConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
+                                  createInstance(Ci.nsIScriptableUnicodeConverter);
+            this.__utfConverter.charset = "UTF-8";
+        }
+        return this.__utfConverter;
+    },
+
+    _utfConverterReset : function() {
+        this.__utfConverter = null;
+    },
+
+    __observerService : null,
+    get _observerService() {
+        if (!this.__observerService)
+            this.__observerService = Cc["@mozilla.org/observer-service;1"].
+                                     getService(Ci.nsIObserverService);
+        return this.__observerService;
+    },
+
+    _debug : false, // mirrors signon.debug
+
+
+    /*
+     * log
+     *
+     * Internal function for logging debug messages to the Error Console.
+     */
+    log : function (message) {
+        if (!this._debug)
+            return;
+        dump("PwMgr cryptoSDR: " + message + "\n");
+        this._logService.logStringMessage("PwMgr cryptoSDR: " + message);
+    },
+
+
+    init : function () {
+        // Connect to the correct preferences branch.
+        this._prefBranch = Cc["@mozilla.org/preferences-service;1"].
+                           getService(Ci.nsIPrefService);
+        this._prefBranch = this._prefBranch.getBranch("signon.");
+        this._prefBranch.QueryInterface(Ci.nsIPrefBranch2);
+
+        this._debug = this._prefBranch.getBoolPref("debug");
+
+        // Check to see if the internal PKCS#11 token has been initialized.
+        // If not, set a blank password.
+        let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].
+                      getService(Ci.nsIPK11TokenDB);
+
+        let token = tokenDB.getInternalKeyToken();
+        if (token.needsUserInit) {
+            this.log("Initializing key3.db with default blank password.");
+            token.initPassword("");
+        }
+    },
+
+
+    /*
+     * encrypt
+     *
+     * Encrypts the specified string, using the SecretDecoderRing.
+     *
+     * Returns the encrypted string, or throws an exception if there was a
+     * problem.
+     */
+    encrypt : function (plainText) {
+        let cipherText = null;
+
+        try {
+            let plainOctet = this._utfConverter.ConvertFromUnicode(plainText);
+            plainOctet += this._utfConverter.Finish();
+            cipherText = this._decoderRing.encryptString(plainOctet);
+        } catch (e) {
+            this.log("Failed to encrypt string. (" + e.name + ")");
+            // If the user clicks Cancel, we get NS_ERROR_FAILURE.
+            // (unlike decrypting, which gets NS_ERROR_NOT_AVAILABLE).
+            if (e.result == Cr.NS_ERROR_FAILURE)
+                throw Components.Exception("User canceled master password entry", Cr.NS_ERROR_ABORT);
+            else
+                throw Components.Exception("Couldn't encrypt string", Cr.NS_ERROR_FAILURE);
+        }
+        return cipherText;
+    },
+
+
+    /*
+     * decrypt
+     *
+     * Decrypts the specified string, using the SecretDecoderRing.
+     *
+     * Returns the decrypted string, or throws an exception if there was a
+     * problem.
+     */
+    decrypt : function (cipherText) {
+        let plainText = null;
+
+        try {
+            let plainOctet;
+            if (cipherText.charAt(0) == '~') {
+                // The old Wallet file format obscured entries by
+                // base64-encoding them. These entries are signaled by a
+                // leading '~' character.
+                plainOctet = atob(cipherText.substring(1));
+            } else {
+                plainOctet = this._decoderRing.decryptString(cipherText);
+            }
+            plainText = this._utfConverter.ConvertToUnicode(plainOctet);
+        } catch (e) {
+            this.log("Failed to decrypt string: " + cipherText +
+                " (" + e.name + ")");
+
+            // In the unlikely event the converter threw, reset it.
+            this._utfConverterReset();
+
+            // If the user clicks Cancel, we get NS_ERROR_NOT_AVAILABLE.
+            // If the cipherText is bad / wrong key, we get NS_ERROR_FAILURE
+            // Wrong passwords are handled by the decoderRing reprompting;
+            // we get no notification.
+            if (e.result == Cr.NS_ERROR_NOT_AVAILABLE)
+                throw Components.Exception("User canceled master password entry", Cr.NS_ERROR_ABORT);
+            else
+                throw Components.Exception("Couldn't decrypt string", Cr.NS_ERROR_FAILURE);
+        }
+
+        return plainText;
+    }
+}; // end of nsLoginManagerCrypto_SDR implementation
+
+let component = [LoginManagerCrypto_SDR];
+function NSGetModule(compMgr, fileSpec) {
+    return XPCOMUtils.generateModule(component);
+}
--- a/toolkit/components/passwordmgr/src/storage-mozStorage.js
+++ b/toolkit/components/passwordmgr/src/storage-mozStorage.js
@@ -35,16 +35,17 @@
  * 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 ***** */
 
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
+const Cr = Components.results;
 
 const DB_VERSION = 3; // The database schema version
 
 const ENCTYPE_BASE64 = 0;
 const ENCTYPE_SDR = 1;
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 
@@ -60,36 +61,22 @@ LoginManagerStorage_mozStorage.prototype
     __logService : null, // Console logging service, used for debugging.
     get _logService() {
         if (!this.__logService)
             this.__logService = Cc["@mozilla.org/consoleservice;1"].
                                 getService(Ci.nsIConsoleService);
         return this.__logService;
     },
 
-    __decoderRing : null,  // nsSecretDecoderRing service
-    get _decoderRing() {
-        if (!this.__decoderRing)
-            this.__decoderRing = Cc["@mozilla.org/security/sdr;1"].
-                                 getService(Ci.nsISecretDecoderRing);
-        return this.__decoderRing;
-    },
-
-    __utfConverter : null, // UCS2 <--> UTF8 string conversion
-    get _utfConverter() {
-        if (!this.__utfConverter) {
-            this.__utfConverter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
-                                  createInstance(Ci.nsIScriptableUnicodeConverter);
-            this.__utfConverter.charset = "UTF-8";
-        }
-        return this.__utfConverter;
-    },
-
-    _utfConverterReset : function() {
-        this.__utfConverter = null;
+    __crypto : null,  // nsILoginManagerCrypto service
+    get _crypto() {
+        if (!this.__crypto)
+            this.__crypto = Cc["@mozilla.org/login-manager/crypto/SDR;1"].
+                            getService(Ci.nsILoginManagerCrypto);
+        return this.__crypto;
     },
 
     __profileDir: null,  // nsIFile for the user's profile dir
     get _profileDir() {
         if (!this.__profileDir)
             this.__profileDir = Cc["@mozilla.org/file/directory_service;1"].
                                 getService(Ci.nsIProperties).
                                 get("ProfD", Ci.nsIFile);
@@ -214,27 +201,16 @@ LoginManagerStorage_mozStorage.prototype
         // Connect to the correct preferences branch.
         this._prefBranch = Cc["@mozilla.org/preferences-service;1"].
                            getService(Ci.nsIPrefService);
         this._prefBranch = this._prefBranch.getBranch("signon.");
         this._prefBranch.QueryInterface(Ci.nsIPrefBranch2);
 
         this._debug = this._prefBranch.getBoolPref("debug");
 
-        // Check to see if the internal PKCS#11 token has been initialized.
-        // If not, set a blank password.
-        let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].
-                      getService(Ci.nsIPK11TokenDB);
-
-        let token = tokenDB.getInternalKeyToken();
-        if (token.needsUserInit) {
-            this.log("Initializing key3.db with default blank password.");
-            token.initPassword("");
-        }
-
         let isFirstRun;
         try {
             // If initWithFile is calling us, _signonsFile may already be set.
             if (!this._signonsFile) {
                 // Initialize signons.sqlite
                 this._signonsFile = this._profileDir.clone();
                 this._signonsFile.append("signons.sqlite");
             }
@@ -271,29 +247,25 @@ LoginManagerStorage_mozStorage.prototype
 
 
     /*
      * _addLogin
      *
      * Private function wrapping core addLogin functionality.
      */
     _addLogin : function (login, isEncrypted) {
-        let userCanceled, encUsername, encPassword;
+        let encUsername, encPassword;
 
         // Throws if there are bogus values.
         this._checkLoginValues(login);
 
-        if (isEncrypted) {
+        if (isEncrypted)
             [encUsername, encPassword] = [login.username, login.password];
-        } else {
-            // Get the encrypted value of the username and password.
-            [encUsername, encPassword, userCanceled] = this._encryptLogin(login);
-            if (userCanceled)
-                throw "User canceled master password entry, login not added.";
-        }
+        else
+            [encUsername, encPassword] = this._encryptLogin(login);
 
         // Clone the login, so we don't modify the caller's object.
         let loginClone = login.clone();
 
         // Initialize the nsILoginMetaInfo fields, unless the caller gave us values
         loginClone.QueryInterface(Ci.nsILoginMetaInfo);
         if (loginClone.guid) {
             if (!this._isGuidUnique(loginClone.guid))
@@ -428,19 +400,17 @@ LoginManagerStorage_mozStorage.prototype
         } else {
             throw "newLoginData needs an expected interface!";
         }
 
         // Throws if there are bogus values.
         this._checkLoginValues(newLogin);
 
         // Get the encrypted value of the username and password.
-        let [encUsername, encPassword, userCanceled] = this._encryptLogin(newLogin);
-        if (userCanceled)
-            throw "User canceled master password entry, login not modified.";
+        let [encUsername, encPassword] = this._encryptLogin(newLogin);
 
         let query =
             "UPDATE moz_logins " +
             "SET hostname = :hostname, " +
                 "httpRealm = :httpRealm, " +
                 "formSubmitURL = :formSubmitURL, " +
                 "usernameField = :usernameField, " +
                 "passwordField = :passwordField, " +
@@ -479,24 +449,20 @@ LoginManagerStorage_mozStorage.prototype
 
 
     /*
      * getAllLogins
      *
      * Returns an array of nsILoginInfo.
      */
     getAllLogins : function (count) {
-        let userCanceled;
         let [logins, ids] = this._searchLogins({});
 
         // decrypt entries for caller.
-        [logins, userCanceled] = this._decryptLogins(logins);
-
-        if (userCanceled)
-            throw "User canceled Master Password entry";
+        logins = this._decryptLogins(logins);
 
         this.log("_getAllLogins: returning " + logins.length + " logins.");
         if (count)
             count.value = logins.length; // needed for XPCOM
         return logins;
     },
 
 
@@ -504,17 +470,17 @@ LoginManagerStorage_mozStorage.prototype
      * getAllEncryptedLogins
      *
      * Not implemented. This interface was added to extract logins from the
      * legacy storage module without decrypting them. Now that logins are in
      * mozStorage, if the encrypted data is really needed it can be easily
      * obtained with SQL and the mozStorage APIs.
      */
     getAllEncryptedLogins : function (count) {
-        throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
+        throw Cr.NS_ERROR_NOT_IMPLEMENTED;
     },
 
 
     /*
      * searchLogins
      *
      * Public wrapper around _searchLogins to convert the nsIPropertyBag to a
      * JavaScript object and decrypt the results.
@@ -527,22 +493,18 @@ LoginManagerStorage_mozStorage.prototype
         let propEnum = matchData.enumerator;
         while (propEnum.hasMoreElements()) {
             let prop = propEnum.getNext().QueryInterface(Ci.nsIProperty);
             realMatchData[prop.name] = prop.value;
         }
 
         let [logins, ids] = this._searchLogins(realMatchData);
 
-        let userCanceled;
         // Decrypt entries found for the caller.
-        [logins, userCanceled] = this._decryptLogins(logins);
-
-        if (userCanceled)
-        throw "User canceled Master Password entry";
+        logins = this._decryptLogins(logins);
 
         count.value = logins.length; // needed for XPCOM
         return logins;
     },
 
 
     /*
      * _searchLogins
@@ -711,36 +673,29 @@ LoginManagerStorage_mozStorage.prototype
     },
 
 
     /*
      * findLogins
      *
      */
     findLogins : function (count, hostname, formSubmitURL, httpRealm) {
-        let userCanceled;
         let loginData = {
             hostname: hostname,
             formSubmitURL: formSubmitURL,
             httpRealm: httpRealm
         };
         let matchData = { };
         for each (field in ["hostname", "formSubmitURL", "httpRealm"])
           if (loginData[field] != '')
               matchData[field] = loginData[field];
         let [logins, ids] = this._searchLogins(matchData);
 
         // Decrypt entries found for the caller.
-        [logins, userCanceled] = this._decryptLogins(logins);
-
-        // We want to throw in this case, so that the Login Manager
-        // knows to stop processing forms on the page so the user isn't
-        // prompted multiple times.
-        if (userCanceled)
-            throw "User canceled Master Password entry";
+        logins = this._decryptLogins(logins);
 
         this.log("_findLogins: returning " + logins.length + " logins");
         count.value = logins.length; // needed for XPCOM
         return logins;
     },
 
 
     /*
@@ -813,21 +768,17 @@ LoginManagerStorage_mozStorage.prototype
         let id = null;
         let foundLogin = null;
 
         // The specified login isn't encrypted, so we need to ensure
         // the logins we're comparing with are decrypted. We decrypt one entry
         // at a time, lest _decryptLogins return fewer entries and screw up
         // indices between the two.
         for (let i = 0; i < logins.length; i++) {
-            let [[decryptedLogin], userCanceled] =
-                        this._decryptLogins([logins[i]]);
-
-            if (userCanceled)
-                throw "User canceled master password entry.";
+            let [decryptedLogin] = this._decryptLogins([logins[i]]);
 
             if (!decryptedLogin || !decryptedLogin.equals(login))
                 continue;
 
             // We've found a match, set id and break
             foundLogin = decryptedLogin;
             id = ids[i];
             break;
@@ -1065,30 +1016,23 @@ LoginManagerStorage_mozStorage.prototype
     /*
      * _encryptLogin
      *
      * Returns the encrypted username and password for the specified login,
      * and a boolean indicating if the user canceled the master password entry
      * (in which case no encrypted values are returned).
      */
     _encryptLogin : function (login) {
-        let encUsername, encPassword, userCanceled;
-        [encUsername, userCanceled] = this._encrypt(login.username);
-        if (userCanceled)
-            return [null, null, true];
-
-        [encPassword, userCanceled] = this._encrypt(login.password);
-        // Probably can't hit this case, but for completeness...
-        if (userCanceled)
-            return [null, null, true];
+        let encUsername = this._crypto.encrypt(login.username);
+        let encPassword = this._crypto.encrypt(login.password);
 
         if (!this._base64checked)
             this._reencryptBase64Logins();
 
-        return [encUsername, encPassword, false];
+        return [encUsername, encPassword];
     },
 
 
     /*
      * _decryptLogins
      *
      * Decrypts username and password fields in the provided array of
      * logins.
@@ -1096,47 +1040,36 @@ LoginManagerStorage_mozStorage.prototype
      * The entries specified by the array will be decrypted, if possible.
      * An array of successfully decrypted logins will be returned. The return
      * value should be given to external callers (since still-encrypted
      * entries are useless), whereas internal callers generally don't want
      * to lose unencrypted entries (eg, because the user clicked Cancel
      * instead of entering their master password)
      */
     _decryptLogins : function (logins) {
-        let result = [], userCanceled = false;
+        let result = [];
 
         for each (let login in logins) {
-            let decryptedUsername, decryptedPassword;
-
-            [decryptedUsername, userCanceled] = this._decrypt(login.username);
-
-            if (userCanceled)
-                break;
-
-            [decryptedPassword, userCanceled] = this._decrypt(login.password);
-
-            // Probably can't hit this case, but for completeness...
-            if (userCanceled)
-                break;
-
-            // If decryption failed (corrupt entry?) skip it.
-            // Note that we allow password-only logins, so username can be "".
-            if (decryptedUsername == null || !decryptedPassword)
-                continue;
-
-            login.username = decryptedUsername;
-            login.password = decryptedPassword;
-
+            try {
+                login.username = this._crypto.decrypt(login.username);
+                login.password = this._crypto.decrypt(login.password);
+            } catch (e) {
+                // If decryption failed (corrupt entry?), just skip it.
+                // Rethrow other errors (like canceling entry of a master pw)
+                if (e.result == Cr.NS_ERROR_FAILURE)
+                    continue;
+                throw e;
+            }
             result.push(login);
         }
 
-        if (!this._base64checked && !userCanceled)
+        if (!this._base64checked)
             this._reencryptBase64Logins();
 
-        return [result, userCanceled];
+        return result;
     },
 
 
     /*
      * _reencryptBase64Logins
      *
      * Checks the signons DB for any logins using the old wallet-style base64
      * obscuring of the username/password, instead of proper encryption. We're
@@ -1151,26 +1084,27 @@ LoginManagerStorage_mozStorage.prototype
         this.log("Reencrypting Base64 logins");
         this._dbConnection.beginTransaction();
         try {
             let [logins, ids] = this._searchLogins({ encType: ENCTYPE_BASE64 });
 
             if (!logins.length)
                 return;
 
-            let userCancelled;
-            [logins, userCanceled] = this._decryptLogins(logins);
-            if (userCanceled)
+            try {
+                logins = this._decryptLogins(logins);
+            } catch (e) {
+                // User might have canceled master password entry, just ignore.
                 return;
+            }
 
             let encUsername, encPassword, stmt;
             for each (let login in logins) {
-                [encUsername, encPassword, userCanceled] = this._encryptLogin(login);
-                if (userCanceled)
-                    throw "User canceled master password entry, login not modified.";
+                [encUsername, encPassword] = this._encryptLogin(login);
+
                 let query =
                     "UPDATE moz_logins " +
                     "SET encryptedUsername = :encryptedUsername, " +
                         "encryptedPassword = :encryptedPassword, " +
                         "encType = :encType " +
                     "WHERE guid = :guid";
                 let params = {
                     encryptedUsername: encUsername,
@@ -1191,96 +1125,16 @@ LoginManagerStorage_mozStorage.prototype
         } catch (e) {
             this.log("_reencryptBase64Logins failed: " + e);
         } finally {
             this._dbConnection.commitTransaction();
         }
     },
 
 
-    /*
-     * _encrypt
-     *
-     * Encrypts the specified string, using the SecretDecoderRing.
-     *
-     * Returns [cipherText, userCanceled] where:
-     *  cipherText   -- the encrypted string, or null if it failed.
-     *  userCanceled -- if the encryption failed, this is true if the
-     *                  user selected Cancel when prompted to enter their
-     *                  Master Password. The caller should bail out, and not
-     *                  not request that more things be encrypted (which
-     *                  results in prompting the user for a Master Password
-     *                  over and over.)
-     */
-    _encrypt : function (plainText) {
-        let cipherText = null, userCanceled = false;
-
-        try {
-            let plainOctet = this._utfConverter.ConvertFromUnicode(plainText);
-            plainOctet += this._utfConverter.Finish();
-            cipherText = this._decoderRing.encryptString(plainOctet);
-        } catch (e) {
-            this.log("Failed to encrypt string. (" + e.name + ")");
-            // If the user clicks Cancel, we get NS_ERROR_FAILURE.
-            // (unlike decrypting, which gets NS_ERROR_NOT_AVAILABLE).
-            if (e.result == Components.results.NS_ERROR_FAILURE)
-                userCanceled = true;
-        }
-
-        return [cipherText, userCanceled];
-    },
-
-
-    /*
-     * _decrypt
-     *
-     * Decrypts the specified string, using the SecretDecoderRing.
-     *
-     * Returns [plainText, userCanceled] where:
-     *  plainText    -- the decrypted string, or null if it failed.
-     *  userCanceled -- if the decryption failed, this is true if the
-     *                  user selected Cancel when prompted to enter their
-     *                  Master Password. The caller should bail out, and not
-     *                  not request that more things be decrypted (which
-     *                  results in prompting the user for a Master Password
-     *                  over and over.)
-     */
-    _decrypt : function (cipherText) {
-        let plainText = null, userCanceled = false;
-
-        try {
-            let plainOctet;
-            if (cipherText.charAt(0) == '~') {
-                // The old Wallet file format obscured entries by
-                // base64-encoding them. These entries are signaled by a
-                // leading '~' character.
-                plainOctet = atob(cipherText.substring(1));
-            } else {
-                plainOctet = this._decoderRing.decryptString(cipherText);
-            }
-            plainText = this._utfConverter.ConvertToUnicode(plainOctet);
-        } catch (e) {
-            this.log("Failed to decrypt string: " + cipherText +
-                " (" + e.name + ")");
-
-            // In the unlikely event the converter threw, reset it.
-            this._utfConverterReset();
-
-            // If the user clicks Cancel, we get NS_ERROR_NOT_AVAILABLE.
-            // If the cipherText is bad / wrong key, we get NS_ERROR_FAILURE
-            // Wrong passwords are handled by the decoderRing reprompting;
-            // we get no notification.
-            if (e.result == Components.results.NS_ERROR_NOT_AVAILABLE)
-                userCanceled = true;
-        }
-
-        return [plainText, userCanceled];
-    },
-
-
     //**************************************************************************//
     // Database Creation & Access
 
     /*
      * _dbCreateStatement
      *
      * Creates a statement, wraps it, and then does parameter replacement
      * Returns the wrapped statement for execution.  Will use memoization
@@ -1318,17 +1172,17 @@ LoginManagerStorage_mozStorage.prototype
             // database has not been created yet.
             let version = this._dbConnection.schemaVersion;
             if (version == 0) {
                 this._dbCreate();
                 isFirstRun = true;
             } else if (version != DB_VERSION) {
                 this._dbMigrate(version);
             }
-        } catch (e if e.result == Components.results.NS_ERROR_FILE_CORRUPTED) {
+        } catch (e if e.result == Cr.NS_ERROR_FILE_CORRUPTED) {
             // Database is corrupted, so we backup the database, then throw
             // causing initialization to fail and a new db to be created next use
             this._dbCleanup(true);
             throw e;
         }
         return isFirstRun;
     },
 
@@ -1372,17 +1226,17 @@ LoginManagerStorage_mozStorage.prototype
             // User's DB is newer. Sanity check that our expected columns are
             // present, and if so mark the lower version and merrily continue
             // on. If the columns are borked, something is wrong so blow away
             // the DB and start from scratch. [Future incompatible upgrades
             // should swtich to a different table or file.]
 
             if (!this._dbAreExpectedColumnsPresent())
                 throw Components.Exception("DB is missing expected columns",
-                                           Components.results.NS_ERROR_FILE_CORRUPTED);
+                                           Cr.NS_ERROR_FILE_CORRUPTED);
 
             // Change the stored version to the current version. If the user
             // runs the newer code again, it will see the lower version number
             // and re-upgrade (to fixup any entries the old code added).
             this._dbConnection.schemaVersion = DB_VERSION;
             return;
         }
 
--- a/toolkit/components/places/src/nsFaviconService.cpp
+++ b/toolkit/components/places/src/nsFaviconService.cpp
@@ -1285,17 +1285,17 @@ FaviconLoadListener::OnStopRequest(nsIRe
     nsCOMPtr<nsISupports> cacheToken;
     rv = cachingChannel->GetCacheToken(getter_AddRefs(cacheToken));
     if (NS_SUCCEEDED(rv)) {
       nsCOMPtr<nsICacheEntryInfo> cacheEntry(do_QueryInterface(cacheToken));
       PRUint32 seconds;
       rv = cacheEntry->GetExpirationTime(&seconds);
       if (NS_SUCCEEDED(rv)) {
         // Set the expiration, but make sure we honor our cap.
-        expiration = PR_Now() + PR_MIN(seconds * PR_USEC_PER_SEC,
+        expiration = PR_Now() + NS_MIN((PRTime)seconds * PR_USEC_PER_SEC,
                                        MAX_FAVICON_EXPIRATION);
       }
     }
   }
   // If we did not obtain a time from the cache, or it was negative, use our cap
   if (expiration < 0)
     expiration = PR_Now() + MAX_FAVICON_EXPIRATION;
 
--- a/toolkit/components/places/src/nsNavHistory.cpp
+++ b/toolkit/components/places/src/nsNavHistory.cpp
@@ -181,17 +181,17 @@ using namespace mozilla::places;
 #define DEFAULT_JOURNAL_MODE "TRUNCATE"
 
 // These macros are used when splitting history by date.
 // These are the day containers and catch-all final container.
 #define ADDITIONAL_DATE_CONT_NUM 3
 // We use a guess of the number of months considering all of them 30 days
 // long, but we split only the last 6 months.
 #define DATE_CONT_NUM(_expireDays) \
-  (ADDITIONAL_DATE_CONT_NUM + PR_MIN(6, (_expireDays/30)))
+  (ADDITIONAL_DATE_CONT_NUM + NS_MIN(6, (_expireDays/30)))
 
 // fraction of free pages in the database to force a vacuum between
 // MAX_TIME_BEFORE_VACUUM and MIN_TIME_BEFORE_VACUUM.
 #define VACUUM_FREEPAGES_THRESHOLD 0.1
 // This is the maximum time (in microseconds) that can pass between 2 VACUUM
 // operations.
 #define MAX_TIME_BEFORE_VACUUM (PRInt64)60 * 24 * 60 * 60 * 1000 * 1000
 // This is the minimum time (in microseconds) that should pass between 2 VACUUM
--- a/toolkit/components/satchel/public/nsIFormHistory.idl
+++ b/toolkit/components/satchel/public/nsIFormHistory.idl
@@ -98,26 +98,8 @@ interface nsIFormHistory2 : nsISupports
    */
   void removeEntriesByTimeframe(in long long aBeginTime, in long long aEndTime);
 
   /**
    * Returns the underlying DB connection the form history module is using.
    */
   readonly attribute mozIStorageConnection DBConnection;
 };
-
-/**
- * nsIFormHistoryImporter is an interface for importing a Mork formhistory.dat
- * file into the new form history storage.
- */
-
-[scriptable, uuid(9e811188-6a5b-4d96-a92d-1bac66a41898)]
-interface nsIFormHistoryImporter : nsISupports
-{
-  /**
-   * Import the given Mork form history file.
-   *  @param file     The Mork form history file to import
-   *  @param history  A reference to the nsIFormHistory.  This is
-   *                  supplied since the importer is invoked during
-   *                  form history initialization.
-   */
-  void importFormHistory(in nsIFile file, in nsIFormHistory2 formHistory);
-};
--- a/toolkit/components/satchel/src/Makefile.in
+++ b/toolkit/components/satchel/src/Makefile.in
@@ -68,12 +68,8 @@ EXTRA_DSO_LIBS	= gkgfx
 include $(topsrcdir)/config/rules.mk
 
 EXTRA_DSO_LDOPTS += \
 	$(LIBS_DIR) \
 	$(EXTRA_DSO_LIBS) \
 	$(MOZ_UNICHARUTIL_LIBS) \
 	$(MOZ_COMPONENT_LIBS) \
 	$(NULL)
-
-ifdef MOZ_MORKREADER
-EXTRA_DSO_LDOPTS += $(DEPTH)/db/morkreader/$(LIB_PREFIX)morkreader_s.$(LIB_SUFFIX)
-endif
--- a/toolkit/components/satchel/src/nsFormFillController.cpp
+++ b/toolkit/components/satchel/src/nsFormFillController.cpp
@@ -1208,19 +1208,16 @@ nsFormFillController::IsEventTrusted(nsI
   PRBool isTrusted;
   rv = nsevent->GetIsTrusted(&isTrusted);
   NS_ENSURE_SUCCESS(rv, PR_FALSE);
   return isTrusted;
 }
 
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsFormHistory, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFormFillController)
-#ifdef MOZ_MORKREADER
-NS_GENERIC_FACTORY_CONSTRUCTOR(nsFormHistoryImporter)
-#endif
 
 static const nsModuleComponentInfo components[] =
 {
   { "HTML Form History",
     NS_FORMHISTORY_CID, 
     NS_FORMHISTORY_CONTRACTID,
     nsFormHistoryConstructor },
 
@@ -1228,19 +1225,12 @@ static const nsModuleComponentInfo compo
     NS_FORMFILLCONTROLLER_CID, 
     "@mozilla.org/satchel/form-fill-controller;1",
     nsFormFillControllerConstructor },
 
   { "HTML Form History AutoComplete",
     NS_FORMFILLCONTROLLER_CID, 
     NS_FORMHISTORYAUTOCOMPLETE_CONTRACTID,
     nsFormFillControllerConstructor },
-
-#ifdef MOZ_MORKREADER
-  { "Form History Importer",
-    NS_FORMHISTORYIMPORTER_CID,
-    NS_FORMHISTORYIMPORTER_CONTRACTID,
-    nsFormHistoryImporterConstructor },
-#endif
 };
 
 NS_IMPL_NSGETMODULE(satchel, components)
 
--- a/toolkit/components/satchel/src/nsStorageFormHistory.cpp
+++ b/toolkit/components/satchel/src/nsStorageFormHistory.cpp
@@ -119,32 +119,16 @@ nsFormHistory::Init()
     /* If the DB is corrupt, nuke it and try again with a new DB. */
     rv = dbCleanup();
     NS_ENSURE_SUCCESS(rv, rv);
     rv = OpenDatabase(&doImport);
     doImport = PR_FALSE;
   }
   NS_ENSURE_SUCCESS(rv, rv);
 
-#ifdef MOZ_MORKREADER
-  if (doImport) {
-    // Locate the old formhistory.dat file and import it.
-    nsCOMPtr<nsIFile> historyFile;
-    rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
-                                getter_AddRefs(historyFile));
-    if (NS_SUCCEEDED(rv)) {
-      historyFile->Append(NS_LITERAL_STRING("formhistory.dat"));
-
-      nsCOMPtr<nsIFormHistoryImporter> importer = new nsFormHistoryImporter();
-      NS_ENSURE_TRUE(importer, NS_ERROR_OUT_OF_MEMORY);
-      importer->ImportFormHistory(historyFile, this);
-    }
-  }
-#endif
-
   nsCOMPtr<nsIObserverService> service = do_GetService("@mozilla.org/observer-service;1");
   if (service) {
     service->AddObserver(this, NS_EARLYFORMSUBMIT_SUBJECT, PR_TRUE);
     service->AddObserver(this, "idle-daily", PR_TRUE);
     service->AddObserver(this, "formhistory-expire-now", PR_TRUE);
   }
 
   return NS_OK;
@@ -805,192 +789,8 @@ nsFormHistory::dbAreExpectedColumnsPrese
 {
   // If the statement succeeds, all the columns are there.
   nsCOMPtr<mozIStorageStatement> stmt;
   nsresult rv = mDBConn->CreateStatement(NS_LITERAL_CSTRING(
                   "SELECT fieldname, value, timesUsed, firstUsed, lastUsed "
                   "FROM moz_formhistory"), getter_AddRefs(stmt));
   return NS_SUCCEEDED(rv) ? PR_TRUE : PR_FALSE;
 }
-
-
-#ifdef MOZ_MORKREADER
-
-// Columns for form history rows
-enum {
-  kNameColumn,
-  kValueColumn,
-  kColumnCount // keep me last
-};
-
-static const char * const gColumnNames[] = {
-  "Name", "Value"
-};
-
-struct FormHistoryImportClosure
-{
-  FormHistoryImportClosure(nsMorkReader *aReader, nsIFormHistory2 *aFormHistory)
-    : reader(aReader), formHistory(aFormHistory), byteOrderColumn(-1),
-      swapBytes(PR_FALSE)
-  {
-    for (PRUint32 i = 0; i < kColumnCount; ++i) {
-      columnIndexes[i] = -1;
-    }
-  }
-
-  // Back pointers to the reader and history we're operating on
-  const nsMorkReader *reader;
-  nsIFormHistory2 *formHistory;
-
-  // Indexes of the columns that we care about
-  PRInt32 columnIndexes[kColumnCount];
-  PRInt32 byteOrderColumn;
-
-  // Whether we need to swap bytes (file format is other-endian)
-  PRPackedBool swapBytes;
-};
-
-// Reverses the high and low bytes in a PRUnichar buffer.
-// This is used if the file format has a different endianness from the
-// current architecture.
-static void SwapBytes(PRUnichar* aBuffer)
-{
-  for (PRUnichar *b = aBuffer; *b; b++)
-  {
-    PRUnichar c = *b;
-    *b = (0xff & (c >> 8)) | (c << 8);
-  }
-}
-
-// Enumerator callback to add an entry to the FormHistory
-/* static */ PLDHashOperator
-nsFormHistoryImporter::AddToFormHistoryCB(const nsCSubstring &aRowID,
-                                          const nsTArray<nsCString> *aValues,
-                                          void *aData)
-{
-  FormHistoryImportClosure *data = static_cast<FormHistoryImportClosure*>
-                                              (aData);
-  const nsMorkReader *reader = data->reader;
-  nsCString values[kColumnCount];
-  const PRUnichar* valueStrings[kColumnCount];
-  PRUint32 valueLengths[kColumnCount];
-  const PRInt32 *columnIndexes = data->columnIndexes;
-  PRInt32 i;
-
-  // Values are in UTF16.
-
-  for (i = 0; i < kColumnCount; ++i) {
-    if (columnIndexes[i] == -1) {
-      // We didn't find this column in the map
-      continue;
-    }
-
-    values[i] = (*aValues)[columnIndexes[i]];
-    reader->NormalizeValue(values[i]);
-
-    PRUint32 length;
-    const char *bytes;
-    if (values[i].IsEmpty()) {
-      bytes = "\0";
-      length = 0;
-    } else {
-      length = values[i].Length() / 2;
-
-      // add an extra null byte onto the end, so that the buffer ends
-      // with a complete unicode null character.
-      values[i].Append('\0');
-
-      // Swap the bytes in the unicode characters if necessary.
-      if (data->swapBytes) {
-        SwapBytes(reinterpret_cast<PRUnichar*>(values[i].BeginWriting()));
-      }
-      bytes = values[i].get();
-    }
-    valueStrings[i] = reinterpret_cast<const PRUnichar*>(bytes);
-    valueLengths[i] = length;
-  }
-
-  data->formHistory->AddEntry(nsDependentString(valueStrings[kNameColumn],
-                                                valueLengths[kNameColumn]),
-                              nsDependentString(valueStrings[kValueColumn],
-                                                valueLengths[kValueColumn]));
-  return PL_DHASH_NEXT;
-}
-
-NS_IMPL_ISUPPORTS1(nsFormHistoryImporter, nsIFormHistoryImporter)
-
-NS_IMETHODIMP
-nsFormHistoryImporter::ImportFormHistory(nsIFile *aFile,
-                                         nsIFormHistory2 *aFormHistory)
-{
-  // Check that the file exists before we try to open it
-  PRBool exists;
-  aFile->Exists(&exists);
-  if (!exists) {
-    return NS_OK;
-  }
-  
-  nsMorkReader reader;
-  nsresult rv = reader.Init();
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = reader.Read(aFile);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  // Gather up the column ids so we don't need to find them on each row
-  FormHistoryImportClosure data(&reader, aFormHistory);
-  const nsTArray<nsMorkReader::MorkColumn> columns = reader.GetColumns();
-  for (PRUint32 i = 0; i < columns.Length(); ++i) {
-    const nsCSubstring &name = columns[i].name;
-    for (PRUint32 j = 0; j < kColumnCount; ++j) {
-      if (name.Equals(gColumnNames[j])) {
-        data.columnIndexes[j] = i;
-        break;
-      }
-    }
-    if (name.EqualsLiteral("ByteOrder")) {
-      data.byteOrderColumn = i;
-    }
-  }
-
-  // Determine the byte order from the table's meta-row.
-  const nsTArray<nsCString> *metaRow = reader.GetMetaRow();
-  if (metaRow && data.byteOrderColumn != -1) {
-    const nsCString &byteOrder = (*metaRow)[data.byteOrderColumn];
-    // Note whether the file uses a non-native byte ordering.
-    // If it does, we'll have to swap bytes for PRUnichar values.
-    // "BBBB" and "llll" are the only recognized values, anything
-    // else is garbage and the file will be treated as native-endian
-    // (no swapping).
-    nsCAutoString byteOrderValue(byteOrder);
-    reader.NormalizeValue(byteOrderValue);
-#ifdef IS_LITTLE_ENDIAN
-    data.swapBytes = byteOrderValue.EqualsLiteral("BBBB");
-#else
-    data.swapBytes = byteOrderValue.EqualsLiteral("llll");
-#endif
-  }
-#if defined(XP_MACOSX) && defined(IS_LITTLE_ENDIAN)
-  // The meta row and its ByteOrder field was introduced in 1.8.0.2.
-  // If it's not present, treat the formhistory db as using native byte
-  // ordering (as was done prior to 1.8.0.2).
-  // Exception: the ByteOrder field was always present since the initial
-  // x86 Mac release, so if we're on one of those, and the file doesn't
-  // have a ByteOrder field, it most likely came from a ppc Mac and needs
-  // its bytes swapped.  nsFormHistory in 1.8.0.2 swapped the bytes, this
-  // importer should behave the same way.
-  else {
-    data.swapBytes = PR_TRUE;
-  }
-#endif
-
-  // Add the rows to form history
-  nsCOMPtr<nsIFormHistoryPrivate> fhPrivate = do_QueryInterface(aFormHistory);
-  NS_ENSURE_TRUE(fhPrivate, NS_ERROR_FAILURE);
-
-  mozIStorageConnection *conn = fhPrivate->GetStorageConnection();
-  NS_ENSURE_TRUE(conn, NS_ERROR_NOT_INITIALIZED);
-  mozStorageTransaction transaction(conn, PR_FALSE);
-
-  reader.EnumerateRows(AddToFormHistoryCB, &data);
-  return transaction.Commit();
-}
-#endif
--- a/toolkit/components/satchel/src/nsStorageFormHistory.h
+++ b/toolkit/components/satchel/src/nsStorageFormHistory.h
@@ -48,19 +48,16 @@
 #include "nsWeakReference.h"
 
 #include "mozIStorageService.h"
 #include "mozIStorageConnection.h"
 #include "mozIStorageStatement.h"
 
 #include "nsServiceManagerUtils.h"
 #include "nsToolkitCompsCID.h"
-#ifdef MOZ_MORKREADER
-#include "nsMorkReader.h"
-#endif
 
 class nsIAutoCompleteSimpleResult;
 class nsIAutoCompleteResult;
 class nsFormHistory;
 template <class E> class nsTArray;
 
 #define NS_IFORMHISTORYPRIVATE_IID \
 {0xc4a47315, 0xaeb5, 0x4039, {0x9f, 0x34, 0x45, 0x11, 0xb3, 0xa7, 0x58, 0xdd}}
@@ -126,25 +123,9 @@ public:
   nsCOMPtr<mozIStorageService> mStorageService;
   nsCOMPtr<mozIStorageStatement> mDBFindEntry;
   nsCOMPtr<mozIStorageStatement> mDBFindEntryByName;
   nsCOMPtr<mozIStorageStatement> mDBSelectEntries;
   nsCOMPtr<mozIStorageStatement> mDBInsertNameValue;
   nsCOMPtr<mozIStorageStatement> mDBUpdateEntry;
 };
 
-#ifdef MOZ_MORKREADER
-class nsFormHistoryImporter : public nsIFormHistoryImporter
-{
-public:
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIFORMHISTORYIMPORTER
-
-private:
-  // Enumerator callback to add a single row to the FormHistory.
-  static PLDHashOperator
-  AddToFormHistoryCB(const nsCSubstring &aRowID,
-                     const nsTArray<nsCString> *aValues,
-                     void *aData);
-};
-#endif
-
 #endif // __nsFormHistory__
--- a/toolkit/components/satchel/test/unit/head_satchel.js
+++ b/toolkit/components/satchel/test/unit/head_satchel.js
@@ -50,16 +50,8 @@ function getDBVersion(dbfile) {
     var ss = Cc["@mozilla.org/storage/service;1"].
              getService(Ci.mozIStorageService);
     var dbConnection = ss.openDatabase(dbfile);
     var version = dbConnection.schemaVersion;
     dbConnection.close();
 
     return version;
 }
-
-function cleanUpFormHist() {
-  var formhistFile = dirSvc.get("ProfD", Ci.nsIFile);
-  formhistFile.append("formhistory.dat");
-  if (formhistFile.exists())
-    formhistFile.remove(false);
-}
-cleanUpFormHist();
--- a/toolkit/components/satchel/test/unit/test_bug_329741.js
+++ b/toolkit/components/satchel/test/unit/test_bug_329741.js
@@ -30,25 +30,34 @@
  * 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 ***** */
 
-// Test to make sure we drop formhistory.dat when clearing form logins
+// Test to make sure we drop formhistory.dat when clearing form history
 
 
 
 function run_test()
 {
   var file = do_get_file("formhistory.dat");
-  var formhistFile = dirSvc.get("ProfD", Ci.nsIFile);
-  file.copyTo(formhistFile, "formhistory.dat");
+  var profileDir = dirSvc.get("ProfD", Ci.nsIFile);
+  var formhistFile = profileDir.clone();
   formhistFile.append("formhistory.dat");
+
+  // Cleanup from any previous test.
+  if (formhistFile.exists())
+      formhistFile.remove(false);
+  do_check_false(formhistFile.exists());
+
+  // Copy a formhistory.dat into place
+  file.copyTo(profileDir, "formhistory.dat");
   do_check_true(formhistFile.exists());
 
+  // Clear form history, test that file was deleted.
   var formHistory = Cc["@mozilla.org/satchel/form-history;1"].
                     getService(Ci.nsIFormHistory2);
   formHistory.removeAllEntries();
   do_check_false(formhistFile.exists());
 }
--- a/toolkit/crashreporter/Makefile.in
+++ b/toolkit/crashreporter/Makefile.in
@@ -73,16 +73,17 @@ endif
 ifeq ($(OS_ARCH),Linux)
 # there's no define for this normally
 DEFINES += -DXP_LINUX
 DIRS += \
   google-breakpad/src/common \
   google-breakpad/src/common/linux \
   google-breakpad/src/client \
   google-breakpad/src/client/linux/handler \
+  google-breakpad/src/client/linux/minidump_writer \
   google-breakpad/src/tools/linux/dump_syms \
   $(NULL)
 endif
 
 ifeq ($(OS_ARCH),SunOS)
 # there's no define for this normally
 DEFINES += -DXP_SOLARIS
 DIRS += \
@@ -105,12 +106,12 @@ EXPORTS = \
 
 CPPSRCS = \
 	nsExceptionHandler.cpp \
 	$(NULL)
 
 FORCE_STATIC_LIB = 1
 
 ifdef ENABLE_TESTS
-DIRS += test
+TOOL_DIRS = test
 endif
 
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/crashreporter/client/Makefile.in
+++ b/toolkit/crashreporter/client/Makefile.in
@@ -79,29 +79,27 @@ endif
 ifeq ($(OS_ARCH),Linux)
 CPPSRCS += crashreporter_linux.cpp crashreporter_unix.cpp
 LIBS += \
   $(DEPTH)/toolkit/crashreporter/google-breakpad/src/common/linux/$(LIB_PREFIX)breakpad_linux_common_s.$(LIB_SUFFIX) \
   $(NULL)
 LOCAL_INCLUDES += -I$(srcdir)
 OS_CXXFLAGS += $(MOZ_GTK2_CFLAGS) $(MOZ_GTHREAD_CFLAGS)
 OS_LIBS += $(MOZ_GTK2_LIBS) $(MOZ_GTHREAD_LIBS)
-CPPSRCS += http_upload.cc
 FORCE_USE_PIC=1
 endif
 
 ifeq ($(OS_ARCH),SunOS)
 CPPSRCS += crashreporter_linux.cpp crashreporter_unix.cpp
 LIBS += \
   $(DEPTH)/toolkit/crashreporter/google-breakpad/src/common/solaris/$(LIB_PREFIX)breakpad_solaris_common_s.$(LIB_SUFFIX) \
   $(NULL)
 LOCAL_INCLUDES += -I$(srcdir)
 OS_CXXFLAGS += $(MOZ_GTK2_CFLAGS) $(MOZ_GTHREAD_CFLAGS)
 OS_LIBS += $(MOZ_GTK2_LIBS) $(MOZ_GTHREAD_LIBS)
-CPPSRCS += http_upload.cc
 FORCE_USE_PIC=1
 endif
 
 include $(topsrcdir)/config/rules.mk
 
 ifeq ($(OS_ARCH),Darwin)
 libs::
 	$(NSINSTALL) -D $(DIST)/bin/crashreporter.app
@@ -109,14 +107,11 @@ libs::
 	sed -e "s/%APP_NAME%/$(MOZ_APP_DISPLAYNAME)/" $(srcdir)/macbuild/Contents/Resources/English.lproj/InfoPlist.strings.in | \
 	  iconv -f UTF-8 -t UTF-16 > $(DIST)/bin/crashreporter.app/Contents/Resources/English.lproj/InfoPlist.strings
 	$(NSINSTALL) -D $(DIST)/bin/crashreporter.app/Contents/MacOS
 	$(NSINSTALL) $(DIST)/bin/crashreporter $(DIST)/bin/crashreporter.app/Contents/MacOS
 	rm -f $(DIST)/bin/crashreporter
 endif
 
 ifeq (,$(filter-out Linux SunOS,$(OS_ARCH)))
-export:: $(srcdir)/../google-breakpad/src/common/linux/http_upload.cc
-	$(INSTALL) $^ .
-
 libs:: $(topsrcdir)/toolkit/themes/winstripe/global/throbber/Throbber-small.gif
 	$(INSTALL) $^ $(DIST)/bin
 endif
new file mode 100644
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/data/linux-gate-amd.sym
@@ -0,0 +1,3 @@
+MODULE Linux x86 B8CFDE93002D54DA1900A40AA1BD67690 linux-gate.so
+PUBLIC 400 0 __kernel_vsyscall
+STACK WIN 4 400 100 1 1 0 0 0 0 0 1
new file mode 100644
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/data/linux-gate-intel.sym
@@ -0,0 +1,3 @@
+MODULE Linux x86 4FBDA58B5A1DF5A379E3CF19A235EA090 linux-gate.so
+PUBLIC 400 0 __kernel_vsyscall
+STACK WIN 4 400 200 3 3 0 0 0 0 0 1
\ No newline at end of file
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/Makefile.in
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/Makefile.in
@@ -44,17 +44,15 @@ include $(DEPTH)/config/autoconf.mk
 MODULE		= handler
 LIBRARY_NAME	= exception_handler_s
 XPI_NAME 	= crashreporter
 
 LOCAL_INCLUDES 	= -I$(srcdir)/../../..
 
 CPPSRCS	= \
   exception_handler.cc \
-  minidump_generator.cc \
-  linux_thread.cc \
   $(NULL)
 
 # need static lib
 FORCE_STATIC_LIB = 1
 FORCE_USE_PIC = 1
 
 include $(topsrcdir)/config/rules.mk
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.cc
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.cc
@@ -1,13 +1,11 @@
-// Copyright (c) 2006, Google Inc.
+// Copyright (c) 2009, Google Inc.
 // All rights reserved.
 //
-// Author: Li Liu
-//
 // 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
@@ -24,273 +22,177 @@
 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
+// The ExceptionHandler object installs signal handlers for a number of
+// signals. We rely on the signal handler running on the thread which crashed
+// in order to identify it. This is true of the synchronous signals (SEGV etc),
+// but not true of ABRT. Thus, if you send ABRT to yourself in a program which
+// uses ExceptionHandler, you need to use tgkill to direct it to the current
+// thread.
+//
+// The signal flow looks like this:
+//
+//   SignalHandler (uses a global stack of ExceptionHandler objects to find
+//        |         one to handle the signal. If the first rejects it, try
+//        |         the second etc...)
+//        V
+//   HandleSignal ----------------------------| (clones a new process which
+//        |                                   |  shares an address space with
+//   (wait for cloned                         |  the crashed process. This
+//     process)                               |  allows us to ptrace the crashed
+//        |                                   |  process)
+//        V                                   V
+//   (set signal handler to             ThreadEntry (static function to bounce
+//    SIG_DFL and rethrow,                    |      back into the object)
+//    killing the crashed                     |
+//    process)                                V
+//                                          DoDump  (writes minidump)
+//                                            |
+//                                            V
+//                                         sys_exit
+//
+
+// This code is a little fragmented. Different functions of the ExceptionHandler
+// class run in a number of different contexts. Some of them run in a normal
+// context and are easy to code, others run in a compromised context and the
+// restrictions at the top of minidump_writer.cc apply: no libc and use the
+// alternative malloc. Each function should have comment above it detailing the
+// context which it runs in.
+
+#include "client/linux/handler/exception_handler.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/limits.h>
+#include <sched.h>
 #include <signal.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <string.h>
+#include <stdio.h>
+#include <sys/mman.h>
+#include <sys/signal.h>
+#include <sys/syscall.h>
+#include <sys/ucontext.h>
+#include <sys/user.h>
+#include <sys/wait.h>
 #include <unistd.h>
 
-#include <cassert>
-#include <cstdlib>
-#include <cstdio>
-#include <ctime>
-#include <linux/limits.h>
+#include "common/linux/linux_libc_support.h"
+#include "common/linux/linux_syscall_support.h"
+#include "common/linux/memory.h"
+#include "client/linux/minidump_writer//minidump_writer.h"
+#include "common/linux/guid_creator.h"
 
-#include "client/linux/handler/exception_handler.h"
-#include "common/linux/guid_creator.h"
-#include "google_breakpad/common/minidump_format.h"
+// A wrapper for the tgkill syscall: send a signal to a specific thread.
+static int tgkill(pid_t tgid, pid_t tid, int sig) {
+  syscall(__NR_tgkill, tgid, tid, sig);
+  return 0;
+}
 
 namespace google_breakpad {
 
-// Signals that we are interested.
-int SigTable[] = {
-#if defined(SIGSEGV)
-  SIGSEGV,
-#endif
-#ifdef SIGABRT
-  SIGABRT,
-#endif
-#ifdef SIGFPE
-  SIGFPE,
-#endif
-#ifdef SIGILL
-  SIGILL,
-#endif
-#ifdef SIGBUS
-  SIGBUS,
-#endif
+// The list of signals which we consider to be crashes. The default action for
+// all these signals must be Core (see man 7 signal) because we rethrow the
+// signal after handling it and expect that it'll be fatal.
+static const int kExceptionSignals[] = {
+  SIGSEGV, SIGABRT, SIGFPE, SIGILL, SIGBUS, -1
 };
 
-std::vector<ExceptionHandler*> *ExceptionHandler::handler_stack_ = NULL;
-int ExceptionHandler::handler_stack_index_ = 0;
+// We can stack multiple exception handlers. In that case, this is the global
+// which holds the stack.
+std::vector<ExceptionHandler*>* ExceptionHandler::handler_stack_ = NULL;
+unsigned ExceptionHandler::handler_stack_index_ = 0;
 pthread_mutex_t ExceptionHandler::handler_stack_mutex_ =
-PTHREAD_MUTEX_INITIALIZER;
+    PTHREAD_MUTEX_INITIALIZER;
 
-ExceptionHandler::ExceptionHandler(const string &dump_path,
+// Runs before crashing: normal context.
+ExceptionHandler::ExceptionHandler(const std::string &dump_path,
                                    FilterCallback filter,
                                    MinidumpCallback callback,
                                    void *callback_context,
                                    bool install_handler)
     : filter_(filter),
       callback_(callback),
       callback_context_(callback_context),
       dump_path_(),
-      installed_handler_(install_handler) {
+      handler_installed_(install_handler),
+      crash_handler_(NULL) {
   set_dump_path(dump_path);
 
-  act_.sa_handler = HandleException;
-  act_.sa_flags = SA_ONSTACK;
-  sigemptyset(&act_.sa_mask);
-  // now, make sure we're blocking all the signals we are handling
-  // when we're handling any of them
-  for ( size_t i = 0; i < sizeof(SigTable) / sizeof(SigTable[0]); ++i) {
-    sigaddset(&act_.sa_mask, SigTable[i]);
-  }
+  if (install_handler) {
+    InstallHandlers();
 
-  if (install_handler) {
-    SetupHandler();
     pthread_mutex_lock(&handler_stack_mutex_);
-    if (handler_stack_ == NULL)
-      handler_stack_ = new std::vector<ExceptionHandler *>;
-    handler_stack_->push_back(this);
+      if (handler_stack_ == NULL)
+        handler_stack_ = new std::vector<ExceptionHandler *>;
+      handler_stack_->push_back(this);
     pthread_mutex_unlock(&handler_stack_mutex_);
   }
 }
 
+// Runs before crashing: normal context.
 ExceptionHandler::~ExceptionHandler() {
-  TeardownAllHandler();
-  pthread_mutex_lock(&handler_stack_mutex_);
-  if (handler_stack_->back() == this) {
-    handler_stack_->pop_back();
-  } else {
-    fprintf(stderr, "warning: removing Breakpad handler out of order\n");
-    for (std::vector<ExceptionHandler *>::iterator iterator =
-         handler_stack_->begin();
-         iterator != handler_stack_->end();
-         ++iterator) {
-      if (*iterator == this) {
-        handler_stack_->erase(iterator);
-      }
-    }
-  }
-
-  if (handler_stack_->empty()) {
-    // When destroying the last ExceptionHandler that installed a handler,
-    // clean up the handler stack.
-    delete handler_stack_;
-    handler_stack_ = NULL;
-  }
-  pthread_mutex_unlock(&handler_stack_mutex_);
-}
-
-bool ExceptionHandler::WriteMinidump() {
-  bool success = InternalWriteMinidump(0, 0, NULL);
-  UpdateNextID();
-  return success;
-}
-
-// static
-bool ExceptionHandler::WriteMinidump(const string &dump_path,
-                   MinidumpCallback callback,
-                   void *callback_context) {
-  ExceptionHandler handler(dump_path, NULL, callback,
-                           callback_context, false);
-  return handler.InternalWriteMinidump(0, 0, NULL);
-}
-
-void ExceptionHandler::SetupHandler() {
-  // Signal on a different stack to avoid using the stack
-  // of the crashing thread.
-  struct sigaltstack sig_stack;
-  sig_stack.ss_sp = malloc(MINSIGSTKSZ);
-  if (sig_stack.ss_sp == NULL)
-    return;
-  sig_stack.ss_size = MINSIGSTKSZ;
-  sig_stack.ss_flags = 0;
-
-  if (sigaltstack(&sig_stack, NULL) < 0)
-    return;
-  for (size_t i = 0; i < sizeof(SigTable) / sizeof(SigTable[0]); ++i)
-    SetupHandler(SigTable[i]);
-}
-
-void ExceptionHandler::SetupHandler(int signo) {
-
-  // We're storing pointers to the old signal action
-  // structure, rather than copying the structure
-  // because we can't count on the sa_mask field to
-  // be scalar.
-  struct sigaction *old_act = &old_actions_[signo];
-
-  if (sigaction(signo, &act_, old_act) < 0)
-   return;
-}
-
-void ExceptionHandler::TeardownHandler(int signo) {
-  TeardownHandler(signo, NULL);
-}
-
-void ExceptionHandler::TeardownHandler(int signo, struct sigaction *final_handler) {
-  if (old_actions_[signo].sa_handler) {
-    struct sigaction *act = &old_actions_[signo];
-    sigaction(signo, act, final_handler);
-    memset(&old_actions_[signo], 0x0, sizeof(struct sigaction));
-  }
-}
-
-void ExceptionHandler::TeardownAllHandler() {
-  for (size_t i = 0; i < sizeof(SigTable) / sizeof(SigTable[0]); ++i) {
-    TeardownHandler(SigTable[i]);
-  }
+  UninstallHandlers();
 }
 
-// static
-void ExceptionHandler::HandleException(int signo) {
-  // In Linux, the context information about the signal is put on the stack of
-  // the signal handler frame as value parameter. For some reasons, the
-  // prototype of the handler doesn't declare this information as parameter, we
-  // will do it by hand. It is the second parameter above the signal number.
-  // However, if we are being called by another signal handler passing the
-  // signal up the chain, then we may not have this random extra parameter,
-  // so we may have to walk the stack to find it.  We do the actual work
-  // on another thread, where it's a little safer, but we want the ebp
-  // from this frame to find it.
-  uintptr_t current_ebp = 0;
-  asm volatile ("movl %%ebp, %0"
-                :"=m"(current_ebp));
+// Runs before crashing: normal context.
+bool ExceptionHandler::InstallHandlers() {
+  // We run the signal handlers on an alternative stack because we might have
+  // crashed because of a stack overflow.
+
+  // We use this value rather than SIGSTKSZ because we would end up overrunning
+  // such a small stack.
+  static const unsigned kSigStackSize = 8192;
 
-  pthread_mutex_lock(&handler_stack_mutex_);
-  ExceptionHandler *current_handler =
-    handler_stack_->at(handler_stack_->size() - ++handler_stack_index_);
-  pthread_mutex_unlock(&handler_stack_mutex_);
+  signal_stack = malloc(kSigStackSize);
+  stack_t stack;
+  memset(&stack, 0, sizeof(stack));
+  stack.ss_sp = signal_stack;
+  stack.ss_size = kSigStackSize;
 
-  // Restore original handler.
-  struct sigaction old_action;
-  current_handler->TeardownHandler(signo, &old_action);
+  if (sigaltstack(&stack, NULL) == -1)
+    return false;
+
+  struct sigaction sa;
+  memset(&sa, 0, sizeof(sa));
+  sigemptyset(&sa.sa_mask);
 
-  struct sigcontext *sig_ctx = NULL;
-  if (current_handler->InternalWriteMinidump(signo, current_ebp, &sig_ctx)) {
-    // Fully handled this exception, safe to exit.
-    exit(EXIT_FAILURE);
-  } else {
-    // Exception not fully handled, will call the next handler in stack to
-    // process it.
-    if (old_action.sa_handler != NULL && sig_ctx != NULL) {
+  // mask all exception signals when we're handling one of them.
+  for (unsigned i = 0; kExceptionSignals[i] != -1; ++i)
+    sigaddset(&sa.sa_mask, kExceptionSignals[i]);
+
+  sa.sa_sigaction = SignalHandler;
+  sa.sa_flags = SA_ONSTACK | SA_SIGINFO;
 
-      // Have our own typedef, because of the comment above w.r.t signal
-      // context on the stack
-      typedef void (*SignalHandler)(int signo, struct sigcontext);
-
-      SignalHandler old_handler =
-          reinterpret_cast<SignalHandler>(old_action.sa_handler);
+  for (unsigned i = 0; kExceptionSignals[i] != -1; ++i) {
+    struct sigaction* old = new struct sigaction;
+    if (sigaction(kExceptionSignals[i], &sa, old) == -1)
+      return false;
+    old_handlers_.push_back(std::make_pair(kExceptionSignals[i], old));
+  }
+  return true;
+}
 
-      sigset_t old_set;
-      // Use SIG_BLOCK here because we don't want to unblock a signal
-      // that the signal handler we're currently in needs to block
-      sigprocmask(SIG_BLOCK, &old_action.sa_mask, &old_set);
-      old_handler(signo, *sig_ctx);
-      sigprocmask(SIG_SETMASK, &old_set, NULL);
-    }
-
+// Runs before crashing: normal context.
+void ExceptionHandler::UninstallHandlers() {
+  for (unsigned i = 0; i < old_handlers_.size(); ++i) {
+    struct sigaction *action =
+        reinterpret_cast<struct sigaction*>(old_handlers_[i].second);
+    sigaction(old_handlers_[i].first, action, NULL);
+    delete action;
   }
 
-  pthread_mutex_lock(&handler_stack_mutex_);
-  current_handler->SetupHandler(signo);
-  --handler_stack_index_;
-  // All the handlers in stack have been invoked to handle the exception,
-  // normally the process should be terminated and should not reach here.
-  // In case we got here, ask the OS to handle it to avoid endless loop,
-  // normally the OS will generate a core and termiate the process. This
-  // may be desired to debug the program.
-  if (handler_stack_index_ == 0)
-    signal(signo, SIG_DFL);
-  pthread_mutex_unlock(&handler_stack_mutex_);
+  old_handlers_.clear();
 }
 
-bool ExceptionHandler::InternalWriteMinidump(int signo,
-                                             uintptr_t sighandler_ebp,
-                                             struct sigcontext **sig_ctx) {
-  if (filter_ && !filter_(callback_context_))
-    return false;
-
-  bool success = false;
-  // Block all the signals we want to process when writting minidump.
-  // We don't want it to be interrupted.
-  sigset_t sig_blocked, sig_old;
-  bool blocked = true;
-  sigfillset(&sig_blocked);
-  for (size_t i = 0; i < sizeof(SigTable) / sizeof(SigTable[0]); ++i)
-    sigdelset(&sig_blocked, SigTable[i]);
-  if (sigprocmask(SIG_BLOCK, &sig_blocked, &sig_old) != 0) {
-    blocked = false;
-    fprintf(stderr, "google_breakpad::ExceptionHandler::HandleException: "
-                    "failed to block signals.\n");
-  }
-
-  success = minidump_generator_.WriteMinidumpToFile(
-                     next_minidump_path_c_, signo, sighandler_ebp, sig_ctx);
-
-  // Unblock the signals.
-  if (blocked) {
-    sigprocmask(SIG_SETMASK, &sig_old, NULL);
-  }
-
-  if (callback_)
-    success = callback_(dump_path_c_, next_minidump_id_c_,
-                          callback_context_, success);
-  return success;
-}
-
+// Runs before crashing: normal context.
 void ExceptionHandler::UpdateNextID() {
   GUID guid;
   char guid_str[kGUIDStringLength + 1];
   if (CreateGUID(&guid) && GUIDToString(&guid, guid_str, sizeof(guid_str))) {
     next_minidump_id_ = guid_str;
     next_minidump_id_c_ = next_minidump_id_.c_str();
 
     char minidump_path[PATH_MAX];
@@ -298,9 +200,125 @@ void ExceptionHandler::UpdateNextID() {
              dump_path_c_,
              guid_str);
 
     next_minidump_path_ = minidump_path;
     next_minidump_path_c_ = next_minidump_path_.c_str();
   }
 }
 
+// This function runs in a compromised context: see the top of the file.
+// Runs on the crashing thread.
+// static
+void ExceptionHandler::SignalHandler(int sig, siginfo_t* info, void* uc) {
+  // All the exception signals are blocked at this point.
+
+  pthread_mutex_lock(&handler_stack_mutex_);
+
+  if (!handler_stack_->size()) {
+    pthread_mutex_unlock(&handler_stack_mutex_);
+    return;
+  }
+
+  for (int i = handler_stack_->size() - 1; i >= 0; --i) {
+    if ((*handler_stack_)[i]->HandleSignal(sig, info, uc)) {
+      // successfully handled: We are in an invalid state since an exception
+      // signal has been delivered. We don't call the exit handlers because
+      // they could end up corrupting on-disk state.
+      break;
+    }
+  }
+
+  pthread_mutex_unlock(&handler_stack_mutex_);
+
+  // Terminate ourselves with the same signal so that our parent knows that we
+  // crashed. The default action for all the signals which we catch is Core, so
+  // this is the end of us.
+  signal(sig, SIG_DFL);
+  tgkill(getpid(), sys_gettid(), sig);
+
+  // not reached.
+}
+
+struct ThreadArgument {
+  pid_t pid;  // the crashing process
+  ExceptionHandler* handler;
+  const void* context;  // a CrashContext structure
+  size_t context_size;
+};
+
+// This is the entry function for the cloned process. We are in a compromised
+// context here: see the top of the file.
+// static
+int ExceptionHandler::ThreadEntry(void *arg) {
+  const ThreadArgument *thread_arg = reinterpret_cast<ThreadArgument*>(arg);
+  return thread_arg->handler->DoDump(thread_arg->pid, thread_arg->context,
+                                     thread_arg->context_size) == false;
+}
+
+// This function runs in a compromised context: see the top of the file.
+// Runs on the crashing thread.
+bool ExceptionHandler::HandleSignal(int sig, siginfo_t* info, void* uc) {
+  if (filter_ && !filter_(callback_context_))
+    return false;
+
+  // Allow ourselves to be dumped.
+  sys_prctl(PR_SET_DUMPABLE, 1);
+
+  CrashContext context;
+  memcpy(&context.siginfo, info, sizeof(siginfo_t));
+  memcpy(&context.context, uc, sizeof(struct ucontext));
+  memcpy(&context.float_state, ((struct ucontext *)uc)->uc_mcontext.fpregs,
+         sizeof(context.float_state));
+  context.tid = sys_gettid();
+
+  if (crash_handler_ && crash_handler_(&context, sizeof(context),
+                                       callback_context_))
+    return true;
+
+  static const unsigned kChildStackSize = 8000;
+  PageAllocator allocator;
+  uint8_t* stack = (uint8_t*) allocator.Alloc(kChildStackSize);
+  if (!stack)
+    return false;
+  // clone() needs the top-most address. (scrub just to be safe)
+  stack += kChildStackSize;
+  my_memset(stack - 16, 0, 16);
+
+  ThreadArgument thread_arg;
+  thread_arg.handler = this;
+  thread_arg.pid = getpid();
+  thread_arg.context = &context;
+  thread_arg.context_size = sizeof(context);
+
+  const pid_t child = sys_clone(
+      ThreadEntry, stack, CLONE_FILES | CLONE_FS | CLONE_UNTRACED,
+      &thread_arg, NULL, NULL, NULL);
+  int r, status;
+  do {
+    r = sys_waitpid(child, &status, __WALL);
+  } while (r == -1 && errno == EINTR);
+
+  if (r == -1) {
+    static const char msg[] = "ExceptionHandler::HandleSignal: waitpid failed:";
+    sys_write(2, msg, sizeof(msg) - 1);
+    sys_write(2, strerror(errno), strlen(strerror(errno)));
+    sys_write(2, "\n", 1);
+  }
+
+  bool success = r != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0;
+
+  if (callback_)
+    success = callback_(dump_path_c_, next_minidump_id_c_,
+                        callback_context_, success);
+
+  return success;
+}
+
+// This function runs in a compromised context: see the top of the file.
+// Runs on the cloned process.
+bool ExceptionHandler::DoDump(pid_t crashing_process, const void* context,
+                              size_t context_size) {
+  return google_breakpad::WriteMinidump(
+      next_minidump_path_c_, crashing_process, context, context_size);
+}
+
 }  // namespace google_breakpad
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.h
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler.h
@@ -1,13 +1,11 @@
-// Copyright (c) 2006, Google Inc.
+// Copyright (c) 2009, Google Inc.
 // All rights reserved.
 //
-// Author: Li Liu
-//
 // 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
@@ -24,36 +22,26 @@
 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#ifndef CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H__
-#define CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H__
+#ifndef CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_
+#define CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_
 
-#include <pthread.h>
-
-#include <map>
+#include <vector>
 #include <string>
+
 #include <signal.h>
-#include <vector>
-
-#include "client/linux/handler/minidump_generator.h"
-
-// Context information when exception occured.
-struct sigcontex;
 
 namespace google_breakpad {
 
-using std::string;
-
-//
 // ExceptionHandler
 //
 // ExceptionHandler can write a minidump file when an exception occurs,
 // or when WriteMinidump() is called explicitly by your program.
 //
 // To have the exception handler write minidumps when an uncaught exception
 // (crash) occurs, you should create an instance early in the execution
 // of your program, and keep it around for the entire time you want to
@@ -68,17 +56,16 @@ using std::string;
 //
 // In either case, a callback function is called when a minidump is written,
 // which receives the unqiue id of the minidump.  The caller can use this
 // id to collect and write additional application state, and to launch an
 // external crash-reporting application.
 //
 // Caller should try to make the callbacks as crash-friendly as possible,
 // it should avoid use heap memory allocation as much as possible.
-//
 class ExceptionHandler {
  public:
   // A callback function to run before Breakpad performs any substantial
   // processing of an exception.  A FilterCallback is called before writing
   // a minidump.  context is the parameter supplied by the user as
   // callback_context when the handler was created.
   //
   // If a FilterCallback returns true, Breakpad will continue processing,
@@ -103,124 +90,109 @@ class ExceptionHandler {
   // should normally return the value of |succeeded|, or when they wish to
   // not report an exception of handled, false.  Callbacks will rarely want to
   // return true directly (unless |succeeded| is true).
   typedef bool (*MinidumpCallback)(const char *dump_path,
                                    const char *minidump_id,
                                    void *context,
                                    bool succeeded);
 
+  // In certain cases, a user may wish to handle the generation of the minidump
+  // themselves. In this case, they can install a handler callback which is
+  // called when a crash has occured. If this function returns true, no other
+  // processing of occurs and the process will shortly be crashed. If this
+  // returns false, the normal processing continues.
+  typedef bool (*HandlerCallback)(const void* crash_context,
+                                  size_t crash_context_size,
+                                  void* context);
+
   // Creates a new ExceptionHandler instance to handle writing minidumps.
   // Before writing a minidump, the optional filter callback will be called.
   // Its return value determines whether or not Breakpad should write a
   // minidump.  Minidump files will be written to dump_path, and the optional
   // callback is called after writing the dump file, as described above.
   // If install_handler is true, then a minidump will be written whenever
   // an unhandled exception occurs.  If it is false, minidumps will only
   // be written when WriteMinidump is called.
-  ExceptionHandler(const string &dump_path,
+  ExceptionHandler(const std::string &dump_path,
                    FilterCallback filter, MinidumpCallback callback,
                    void *callback_context,
                    bool install_handler);
   ~ExceptionHandler();
 
   // Get and set the minidump path.
-  string dump_path() const { return dump_path_; }
-  void set_dump_path(const string &dump_path) {
+  std::string dump_path() const { return dump_path_; }
+  void set_dump_path(const std::string &dump_path) {
     dump_path_ = dump_path;
     dump_path_c_ = dump_path_.c_str();
     UpdateNextID();
   }
 
+  void set_crash_handler(HandlerCallback callback) {
+    crash_handler_ = callback;
+  }
+
   // Writes a minidump immediately.  This can be used to capture the
   // execution state independently of a crash.  Returns true on success.
   bool WriteMinidump();
 
   // Convenience form of WriteMinidump which does not require an
   // ExceptionHandler instance.
-  static bool WriteMinidump(const string &dump_path,
+  static bool WriteMinidump(const std::string &dump_path,
                             MinidumpCallback callback,
                             void *callback_context);
 
- private:
-  // Setup crash handler.
-  void SetupHandler();
-  // Setup signal handler for a signal.
-  void SetupHandler(int signo);
-  // Teardown the handler for a signal.
-  void TeardownHandler(int signo);
-  // Teardown the handler for a signal.
-  void TeardownHandler(int signo, struct sigaction *old);
-  // Teardown all handlers.
-  void TeardownAllHandler();
-
-  // Signal handler.
-  static void HandleException(int signo);
-
-  // If called from a signal handler, sighandler_ebp is the ebp of
-  // that signal handler's frame, and sig_ctx is an out parameter
-  // that will be set to point at the sigcontext that was placed
-  // on the stack by the kernel.  You can pass zero and NULL
-  // for the second and third parameters if you are not calling
-  // this from a signal handler.
-  bool InternalWriteMinidump(int signo, uintptr_t sighandler_ebp,
-                             struct sigcontext **sig_ctx);
-
-  // Generates a new ID and stores it in next_minidump_id, and stores the
-  // path of the next minidump to be written in next_minidump_path_.
-  void UpdateNextID();
+  // This structure is passed to minidump_writer.h:WriteMinidump via an opaque
+  // blob. It shouldn't be needed in any user code.
+  struct CrashContext {
+    siginfo_t siginfo;
+    pid_t tid;  // the crashing thread.
+    struct ucontext context;
+    struct _libc_fpstate float_state;
+  };
 
  private:
-  FilterCallback filter_;
-  MinidumpCallback callback_;
-  void *callback_context_;
+  bool InstallHandlers();
+  void UninstallHandlers();
+  void PreresolveSymbols();
 
-  // The directory in which a minidump will be written, set by the dump_path
-  // argument to the constructor, or set_dump_path.
-  string dump_path_;
+  void UpdateNextID();
+  static void SignalHandler(int sig, siginfo_t* info, void* uc);
+  bool HandleSignal(int sig, siginfo_t* info, void* uc);
+  static int ThreadEntry(void* arg);
+  bool DoDump(pid_t crashing_process, const void* context,
+              size_t context_size);
 
-  // The basename of the next minidump to be written, without the extension
-  string next_minidump_id_;
+  const FilterCallback filter_;
+  const MinidumpCallback callback_;
+  void* const callback_context_;
 
-  // The full pathname of the next minidump to be written, including the file
-  // extension
-  string next_minidump_path_;
+  std::string dump_path_;
+  std::string next_minidump_path_;
+  std::string next_minidump_id_;
 
   // Pointers to C-string representations of the above. These are set
   // when the above are set so we can avoid calling c_str during
   // an exception.
-  const char *dump_path_c_;
-  const char *next_minidump_id_c_;
-  const char *next_minidump_path_c_;
+  const char* dump_path_c_;
+  const char* next_minidump_path_c_;
+  const char* next_minidump_id_c_;
 
-  // True if the ExceptionHandler installed an unhandled exception filter
-  // when created (with an install_handler parameter set to true).
-  bool installed_handler_;
+  const bool handler_installed_;
+  void* signal_stack;  // the handler stack.
+  HandlerCallback crash_handler_;
 
   // The global exception handler stack. This is need becuase there may exist
   // multiple ExceptionHandler instances in a process. Each will have itself
   // registered in this stack.
-  static std::vector<ExceptionHandler *> *handler_stack_;
+  static std::vector<ExceptionHandler*> *handler_stack_;
   // The index of the handler that should handle the next exception.
-  static int handler_stack_index_;
+  static unsigned handler_stack_index_;
   static pthread_mutex_t handler_stack_mutex_;
 
-  // The minidump generator.
-  MinidumpGenerator minidump_generator_;
-
-  // disallow copy ctor and operator=
-  explicit ExceptionHandler(const ExceptionHandler &);
-  void operator=(const ExceptionHandler &);
-
-  // The sigactions structure we use for each signal
-  struct sigaction act_;
-
-
-  // Keep the previous handlers for the signal.
-  // We're wasting a bit of memory here since we only change
-  // the handler for some signals but i want to avoid allocating
-  // memory in the signal handler
-  struct sigaction old_actions_[NSIG];
+  // A vector of the old signal handlers. The void* is a pointer to a newly
+  // allocated sigaction structure to avoid pulling in too many includes.
+  std::vector<std::pair<int, void *> > old_handlers_;
 };
 
 }  // namespace google_breakpad
 
-#endif  // CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H__
+#endif  // CLIENT_LINUX_HANDLER_EXCEPTION_HANDLER_H_
deleted file mode 100644
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler_test.cc
+++ /dev/null
@@ -1,124 +0,0 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-//
-// Author: Li Liu
-//
-// 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 Google Inc. 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 COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <pthread.h>
-#include <unistd.h>
-
-#include <cassert>
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-
-#include "client/linux/handler/exception_handler.h"
-#include "client/linux/handler/linux_thread.h"
-
-using namespace google_breakpad;
-
-// Thread use this to see if it should stop working.
-static bool should_exit = false;
-
-static int foo2(int arg) {
-  // Stack variable, used for debugging stack dumps.
-  /*DDDebug*/printf("%s:%d\n", __FUNCTION__, __LINE__);
-  int c = 0xcccccccc;
-  fprintf(stderr, "Thread trying to crash: %x\n", getpid());
-  c = *reinterpret_cast<int *>(0x5);
-  return c;
-}
-
-static int foo(int arg) {
-  // Stack variable, used for debugging stack dumps.
-  int b = 0xbbbbbbbb;
-  b = foo2(b);
-  return b;
-}
-
-static void *thread_crash(void *) {
-  // Stack variable, used for debugging stack dumps.
-  int a = 0xaaaaaaaa;
-  sleep(1);
-  a = foo(a);
-  printf("%x\n", a);
-  return NULL;
-}
-
-static void *thread_main(void *) {
-  while (!should_exit)
-    sleep(1);
-  return NULL;
-}
-
-static void CreateCrashThread() {
-  pthread_t h;
-  pthread_create(&h, NULL, thread_crash, NULL);
-  pthread_detach(h);
-}
-
-// Create working threads.
-static void CreateThread(int num) {
-  pthread_t h;
-  for (int i = 0; i < num; ++i) {
-    pthread_create(&h, NULL, thread_main, NULL);
-    pthread_detach(h);
-  }
-}
-
-// Callback when minidump written.
-static bool MinidumpCallback(const char *dump_path,
-                             const char *minidump_id,
-                             void *context,
-                             bool succeeded) {
-  int index = reinterpret_cast<int>(context);
-  printf("%d %s: %s is dumped\n", index, __FUNCTION__, minidump_id);
-  if (index == 0) {
-    should_exit = true;
-    return true;
-  }
-  // Don't process it.
-  return false;
-}
-
-int main(int argc, char *argv[]) {
-  int handler_index = 0;
-  ExceptionHandler handler_ignore(".", NULL, MinidumpCallback,
-                           (void*)handler_index, true);
-  ++handler_index;
-  ExceptionHandler handler_process(".", NULL, MinidumpCallback,
-                           (void*)handler_index, true);
-  CreateCrashThread();
-  CreateThread(10);
-
-  while (true)
-    sleep(1);
-  should_exit = true;
-
-  return 0;
-}
new file mode 100644
--- /dev/null
+++ b/toolkit/crashreporter/google-breakpad/src/client/linux/handler/exception_handler_unittest.cc
@@ -0,0 +1,256 @@
+// Copyright (c) 2009, Google Inc.
+// All rights reserved.
+//
+// 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 Google Inc. 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 COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <string>
+
+#include <stdint.h>
+#include <unistd.h>
+#include <signal.h>
+#include <sys/poll.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#include "client/linux/handler//exception_handler.h"
+#include "client/linux/minidump_writer/minidump_writer.h"
+#include "common/linux/linux_libc_support.h"
+#include "common/linux/linux_syscall_support.h"
+#include "breakpad_googletest_includes.h"
+
+// This provides a wrapper around system calls which may be
+// interrupted by a signal and return EINTR. See man 7 signal.
+#define HANDLE_EINTR(x) ({ \
+  typeof(x) __eintr_result__; \
+  do { \
+    __eintr_result__ = x; \
+  } while (__eintr_result__ == -1 && errno == EINTR); \
+  __eintr_result__;\
+})
+
+using namespace google_breakpad;
+
+static void sigchld_handler(int signo) { }
+
+class ExceptionHandlerTest : public ::testing::Test {
+ protected:
+  void SetUp() {
+    // We need to be able to wait for children, so SIGCHLD cannot be SIG_IGN.
+    struct sigaction sa;
+    memset(&sa, 0, sizeof(sa));
+    sa.sa_handler = sigchld_handler;
+    ASSERT_NE(sigaction(SIGCHLD, &sa, &old_action), -1);
+  }
+
+  void TearDown() {
+    sigaction(SIGCHLD, &old_action, NULL);
+  }
+
+  struct sigaction old_action;
+};
+
+TEST(ExceptionHandlerTest, Simple) {
+  ExceptionHandler handler("/tmp", NULL, NULL, NULL, true);
+}
+
+static bool DoneCallback(const char* dump_path,
+                         const char* minidump_id,
+                         void* context,
+                         bool succeeded) {
+  if (!succeeded)
+    return succeeded;
+
+  int fd = (intptr_t) context;
+  uint32_t len = my_strlen(minidump_id);
+  HANDLE_EINTR(sys_write(fd, &len, sizeof(len)));
+  HANDLE_EINTR(sys_write(fd, minidump_id, len));
+  sys_close(fd);
+
+  return true;
+}
+
+TEST(ExceptionHandlerTest, ChildCrash) {
+  int fds[2];
+  ASSERT_NE(pipe(fds), -1);
+
+  const pid_t child = fork();
+  if (child == 0) {
+    close(fds[0]);
+    ExceptionHandler handler("/tmp", NULL, DoneCallback, (void*) fds[1],
+                             true);
+    *reinterpret_cast<int*>(NULL) = 0;
+  }
+  close(fds[1]);
+
+  int status;
+  ASSERT_NE(HANDLE_EINTR(waitpid(child, &status, 0)), -1);
+  ASSERT_TRUE(WIFSIGNALED(status));
+  ASSERT_EQ(WTERMSIG(status), SIGSEGV);
+
+  struct pollfd pfd;
+  memset(&pfd, 0, sizeof(pfd));
+  pfd.fd = fds[0];
+  pfd.events = POLLIN | POLLERR;
+
+  const int r = HANDLE_EINTR(poll(&pfd, 1, 0));
+  ASSERT_EQ(r, 1);
+  ASSERT_TRUE(pfd.revents & POLLIN);
+
+  uint32_t len;
+  ASSERT_EQ(read(fds[0], &len, sizeof(len)), sizeof(len));
+  ASSERT_LT(len, 2048);
+  char* filename = reinterpret_cast<char*>(malloc(len + 1));
+  ASSERT_EQ(read(fds[0], filename, len), len);
+  filename[len] = 0;
+  close(fds[0]);
+
+  const std::string minidump_filename = std::string("/tmp/") + filename +
+                                        ".dmp";
+
+  struct stat st;
+  ASSERT_EQ(stat(minidump_filename.c_str(), &st), 0);
+  ASSERT_GT(st.st_size, 0u);
+  unlink(minidump_filename.c_str());
+}
+
+static const unsigned kControlMsgSize =
+    CMSG_SPACE(sizeof(int)) + CMSG_SPACE(sizeof(struct ucred));
+
+static bool
+CrashHandler(const void* crash_context, size_t crash_context_size,
+             void* context) {
+  const int fd = (intptr_t) context;
+  int fds[2];
+  pipe(fds);
+
+  struct kernel_msghdr msg = {0};
+  struct kernel_iovec iov;
+  iov.iov_base = const_cast<void*>(crash_context);
+  iov.iov_len = crash_context_size;
+
+  msg.msg_iov = &iov;
+  msg.msg_iovlen = 1;
+  char cmsg[kControlMsgSize];
+  memset(cmsg, 0, kControlMsgSize);
+  msg.msg_control = cmsg;
+  msg.msg_controllen = sizeof(cmsg);
+
+  struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg);
+  hdr->cmsg_level = SOL_SOCKET;
+  hdr->cmsg_type = SCM_RIGHTS;
+  hdr->cmsg_len = CMSG_LEN(sizeof(int));
+  *((int*) CMSG_DATA(hdr)) = fds[1];
+  hdr = CMSG_NXTHDR((struct msghdr*) &msg, hdr);
+  hdr->cmsg_level = SOL_SOCKET;
+  hdr->cmsg_type = SCM_CREDENTIALS;
+  hdr->cmsg_len = CMSG_LEN(sizeof(struct ucred));
+  struct ucred *cred = reinterpret_cast<struct ucred*>(CMSG_DATA(hdr));
+  cred->uid = getuid();
+  cred->gid = getgid();
+  cred->pid = getpid();
+
+  HANDLE_EINTR(sys_sendmsg(fd, &msg, 0));
+  sys_close(fds[1]);
+
+  char b;
+  HANDLE_EINTR(sys_read(fds[0], &b, 1));
+
+  return true;
+}
+
+TEST(ExceptionHandlerTest, ExternalDumper) {
+  int fds[2];
+  ASSERT_NE(socketpair(AF_UNIX, SOCK_DGRAM, 0, fds), -1);
+  static const int on = 1;
+  setsockopt(fds[0], SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
+  setsockopt(fds[1], SOL_SOCKET, SO_PASSCRED, &on, sizeof(on));
+
+  const pid_t child = fork();
+  if (child == 0) {
+    close(fds[0]);
+    ExceptionHandler handler("/tmp", NULL, NULL, (void*) fds[1], true);
+    handler.set_crash_handler(CrashHandler);
+    *reinterpret_cast<int*>(NULL) = 0;
+  }
+
+  close(fds[1]);
+  struct msghdr msg = {0};
+  struct iovec iov;
+  static const unsigned kCrashContextSize =
+      sizeof(ExceptionHandler::CrashContext);
+  char context[kCrashContextSize];
+  char control[kControlMsgSize];
+  iov.iov_base = context;
+  iov.iov_len = kCrashContextSize;
+  msg.msg_iov = &iov;
+  msg.msg_iovlen = 1;
+  msg.msg_control = control;
+  msg.msg_controllen = kControlMsgSize;
+
+  const ssize_t n = HANDLE_EINTR(recvmsg(fds[0], &msg, 0));
+  ASSERT_EQ(n, kCrashContextSize);
+  ASSERT_EQ(msg.msg_controllen, kControlMsgSize);
+  ASSERT_EQ(msg.msg_flags, 0);
+
+  pid_t crashing_pid = -1;
+  int signal_fd = -1;
+  for (struct cmsghdr *hdr = CMSG_FIRSTHDR(&msg); hdr;
+       hdr = CMSG_NXTHDR(&msg, hdr)) {
+    if (hdr->cmsg_level != SOL_SOCKET)
+      continue;
+    if (hdr->cmsg_type == SCM_RIGHTS) {
+      const unsigned len = hdr->cmsg_len -
+          (((uint8_t*)CMSG_DATA(hdr)) - (uint8_t*)hdr);
+      ASSERT_EQ(len, sizeof(int));
+      signal_fd = *((int *) CMSG_DATA(hdr));
+    } else if (hdr->cmsg_type == SCM_CREDENTIALS) {
+      const struct ucred *cred =
+          reinterpret_cast<struct ucred*>(CMSG_DATA(hdr));
+      crashing_pid = cred->pid;
+    }
+  }
+
+  ASSERT_NE(crashing_pid, -1);
+  ASSERT_NE(signal_fd, -1);
+
+  char templ[] = "/tmp/exception-handler-unittest-XXXXXX";
+  mktemp(templ);
+  ASSERT_TRUE(WriteMinidump(templ, crashing_pid, context,
+                            kCrashContextSize));
+  static const char b = 0;
+  HANDLE_EINTR(write(signal_fd, &b, 1));
+
+  int status;
+  ASSERT_NE(HANDLE_EINTR(waitpid(child, &status, 0)), -1);
+  ASSERT_TRUE(WIFSIGNALED(status));
+  ASSERT_EQ(WTERMSIG(status), SIGSEGV);
+
+  struct stat st;
+  ASSERT_EQ(stat(templ, &st), 0);
+  ASSERT_GT(st.st_size, 0u);
+  unlink(templ);
+}
deleted file mode 100644
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/linux_thread.cc
+++ /dev/null
@@ -1,411 +0,0 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-//
-// Author: Li Liu
-//
-// 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 Google Inc. 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 COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-#include <errno.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <sys/ptrace.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/wait.h>
-#include <string.h>
-
-#include <algorithm>
-#include <cassert>
-#include <cstdio>
-#include <cstdlib>
-#include <functional>
-
-#include "client/linux/handler/linux_thread.h"
-
-using namespace google_breakpad;
-
-// This unamed namespace contains helper function.
-namespace {
-
-// Context information for the callbacks when validating address by listing
-// modules.
-struct AddressValidatingContext {
-  uintptr_t address;
-  bool is_mapped;
-
-  AddressValidatingContext() : address(0UL), is_mapped(false) {
-  }
-};
-
-// Convert from string to int.
-bool LocalAtoi(char *s, int *r) {
-  assert(s != NULL);
-  assert(r != NULL);
-  char *endptr = NULL;
-  int ret = strtol(s, &endptr, 10);
-  if (endptr == s)
-    return false;
-  *r = ret;
-  return true;
-}
-
-// Fill the proc path of a thread given its id.
-void FillProcPath(int pid, char *path, int path_size) {
-  char pid_str[32];
-  snprintf(pid_str, sizeof(pid_str), "%d", pid);
-  snprintf(path, path_size, "/proc/%s/", pid_str);
-}
-
-// Read thread info from /proc/$pid/status.
-bool ReadThreadInfo(int pid, ThreadInfo *info) {
-  assert(info != NULL);
-  char status_path[80];
-  // Max size we want to read from status file.
-  static const int kStatusMaxSize = 1024;
-  char status_content[kStatusMaxSize];
-
-  FillProcPath(pid, status_path, sizeof(status_path));
-  strcat(status_path, "status");
-  int fd = open(status_path, O_RDONLY, 0);
-  if (fd < 0)
-    return false;
-
-  int num_read = read(fd, status_content, kStatusMaxSize - 1);
-  if (num_read < 0) {
-    close(fd);
-    return false;
-  }
-  close(fd);
-  status_content[num_read] = '\0';
-
-  char *tgid_start = strstr(status_content, "Tgid:");
-  if (tgid_start)
-    sscanf(tgid_start, "Tgid:\t%d\n", &(info->tgid));
-  else
-    // tgid not supported by kernel??
-    info->tgid = 0;
-
-  tgid_start = strstr(status_content, "Pid:");
-  if (tgid_start) {
-    sscanf(tgid_start, "Pid:\t%d\n" "PPid:\t%d\n", &(info->pid),
-           &(info->ppid));
-    return true;
-  }
-  return false;
-}
-
-// Callback invoked for each mapped module.
-// It use the module's adderss range to validate the address.
-bool IsAddressInModuleCallback(const ModuleInfo &module_info,
-                               void *context) {
-  AddressValidatingContext *addr =
-    reinterpret_cast<AddressValidatingContext *>(context);
-  addr->is_mapped = ((addr->address >= module_info.start_addr) &&
-                     (addr->address <= module_info.start_addr +
-                      module_info.size));
-  return !addr->is_mapped;
-}
-
-#if defined(__i386__) && !defined(NO_FRAME_POINTER)
-void *GetNextFrame(void **last_ebp) {
-  void *sp = *last_ebp;
-  if ((unsigned long)sp == (unsigned long)last_ebp)
-    return NULL;
-  if ((unsigned long)sp & (sizeof(void *) - 1))
-    return NULL;
-  if ((unsigned long)sp - (unsigned long)last_ebp > 100000)
-    return NULL;
-  return sp;
-}
-#else
-void *GetNextFrame(void **last_ebp) {
-  return reinterpret_cast<void*>(last_ebp);
-}
-#endif
-
-// Suspend a thread by attaching to it.
-bool SuspendThread(int pid, void *context) {
-  // This may fail if the thread has just died or debugged.
-  errno = 0;
-  if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) != 0 &&
-      errno != 0) {
-    return false;
-  }
-  while (waitpid(pid, NULL, __WALL) < 0) {
-    if (errno != EINTR) {
-      ptrace(PTRACE_DETACH, pid, NULL, NULL);
-      return false;
-    }
-  }
-  return true;
-}
-
-// Resume a thread by detaching from it.
-bool ResumeThread(int pid, void *context) {
-  return ptrace(PTRACE_DETACH, pid, NULL, NULL) >= 0;
-}
-
-// Callback to get the thread information.
-// Will be called for each thread found.
-bool ThreadInfoCallback(int pid, void *context) {
-  CallbackParam<ThreadCallback> *thread_callback =
-    reinterpret_cast<CallbackParam<ThreadCallback> *>(context);
-  ThreadInfo thread_info;
-  if (ReadThreadInfo(pid, &thread_info) && thread_callback) {
-    // Invoke callback from caller.
-    return (thread_callback->call_back)(thread_info, thread_callback->context);
-  }
-  return false;
-}
-
-}  // namespace
-
-namespace google_breakpad {
-
-LinuxThread::LinuxThread(int pid) : pid_(pid) , threads_suspened_(false) {
-}
-
-LinuxThread::~LinuxThread() {
-  if (threads_suspened_)
-    ResumeAllThreads();
-}
-
-int LinuxThread::SuspendAllThreads() {
-  CallbackParam<PidCallback> callback_param(SuspendThread, NULL);
-  int thread_count = 0;
-  if ((thread_count = IterateProcSelfTask(pid_, &callback_param)) > 0)
-    threads_suspened_ = true;
-  return thread_count;
-}
-
-void LinuxThread::ResumeAllThreads() const {
-  CallbackParam<PidCallback> callback_param(ResumeThread, NULL);
-  IterateProcSelfTask(pid_, &callback_param);
-}
-
-int LinuxThread::GetThreadCount() const {
-  return IterateProcSelfTask(pid_, NULL);
-}
-
-int LinuxThread::ListThreads(
-    CallbackParam<ThreadCallback> *thread_callback_param) const {
-  CallbackParam<PidCallback> callback_param(ThreadInfoCallback,
-                                            thread_callback_param);
-  return IterateProcSelfTask(pid_, &callback_param);
-}
-
-bool LinuxThread::GetRegisters(int pid, user_regs_struct *regs) const {
-  assert(regs);
-  return (regs != NULL &&
-          (ptrace(PTRACE_GETREGS, pid, NULL, regs) == 0) &&
-          errno == 0);
-}
-
-// Get the floating-point registers of a thread.
-// The caller must get the thread pid by ListThreads.
-bool LinuxThread::GetFPRegisters(int pid, user_fpregs_struct *regs) const {
-  assert(regs);
-  return (regs != NULL &&
-          (ptrace(PTRACE_GETREGS, pid, NULL, regs) ==0) &&
-          errno == 0);
-}
-
-bool LinuxThread::GetFPXRegisters(int pid, user_fpxregs_struct *regs) const {
-  assert(regs);
-  return (regs != NULL &&
-          (ptrace(PTRACE_GETFPREGS, pid, NULL, regs) != 0) &&
-          errno == 0);
-}
-
-bool LinuxThread::GetDebugRegisters(int pid, DebugRegs *regs) const {
-  assert(regs);
-
-#define GET_DR(name, num)\
-  name->dr##num = ptrace(PTRACE_PEEKUSER, pid,\
-                         offsetof(struct user, u_debugreg[num]), NULL)
-  GET_DR(regs, 0);
-  GET_DR(regs, 1);
-  GET_DR(regs, 2);
-  GET_DR(regs, 3);
-  GET_DR(regs, 4);
-  GET_DR(regs, 5);
-  GET_DR(regs, 6);
-  GET_DR(regs, 7);
-  return true;
-}
-
-int LinuxThread::GetThreadStackDump(uintptr_t current_ebp,
-                                    uintptr_t current_esp,
-                                    void *buf,
-                                    int buf_size) const {
-  assert(buf);
-  assert(buf_size > 0);
-
-  uintptr_t stack_bottom = GetThreadStackBottom(current_ebp);
-  int size = stack_bottom - current_esp;
-  size = buf_size > size ? size : buf_size;
-  if (size > 0)
-    memcpy(buf, reinterpret_cast<void*>(current_esp), size);
-  return size;
-}
-
-// Get the stack bottom of a thread by stack walking. It works
-// unless the stack has been corrupted or the frame pointer has been omited.
-// This is just a temporary solution before we get better ideas about how
-// this can be done.
-//
-// We will check each frame address by checking into module maps.
-// TODO(liuli): Improve it.
-uintptr_t LinuxThread::GetThreadStackBottom(uintptr_t current_ebp) const {
-  void **sp = reinterpret_cast<void **>(current_ebp);
-  void **previous_sp = sp;
-  while (sp && IsAddressMapped((uintptr_t)sp)) {
-    previous_sp = sp;
-    sp = reinterpret_cast<void **>(GetNextFrame(sp));
-  }
-  return (uintptr_t)previous_sp;
-}
-
-int LinuxThread::GetModuleCount() const {
-  return ListModules(NULL);
-}
-
-int LinuxThread::ListModules(
-    CallbackParam<ModuleCallback> *callback_param) const {
-  char line[512];
-  const char *maps_path = "/proc/self/maps";
-
-  int module_count = 0;
-  FILE *fp = fopen(maps_path, "r");
-  if (fp == NULL)
-    return -1;
-
-  uintptr_t start_addr;
-  uintptr_t end_addr;
-  while (fgets(line, sizeof(line), fp) != NULL) {
-    if (sscanf(line, "%x-%x", &start_addr, &end_addr) == 2) {
-      ModuleInfo module;
-      memset(&module, 0, sizeof(module));
-      module.start_addr = start_addr;
-      module.size = end_addr - start_addr;
-      char *name = NULL;
-      assert(module.size > 0);
-      // Only copy name if the name is a valid path name.
-      if ((name = strchr(line, '/')) != NULL) {
-        // Get rid of the last '\n' in line
-        char *last_return = strchr(line, '\n');
-        if (last_return != NULL)
-          *last_return = '\0';
-        // Keep a space for the ending 0.
-        strncpy(module.name, name, sizeof(module.name) - 1);
-        ++module_count;
-      }
-      if (callback_param &&
-          !(callback_param->call_back(module, callback_param->context)))
-        break;
-    }
-  }
-  fclose(fp);
-  return module_count;
-}
-
-// Parse /proc/$pid/tasks to list all the threads of the process identified by
-// pid.
-int LinuxThread::IterateProcSelfTask(int pid,
-                          CallbackParam<PidCallback> *callback_param) const {
-  char task_path[80];
-  FillProcPath(pid, task_path, sizeof(task_path));
-  strcat(task_path, "task");
-
-  DIR *dir = opendir(task_path);
-  if (dir == NULL)
-    return -1;
-
-  int pid_number = 0;
-  // Record the last pid we've found. This is used for duplicated thread
-  // removal. Duplicated thread information can be found in /proc/$pid/tasks.
-  int last_pid = -1;
-  struct dirent *entry = NULL;
-  while ((entry = readdir(dir)) != NULL) {
-    if (strcmp(entry->d_name, ".") &&
-        strcmp(entry->d_name, "..")) {
-      int tpid = 0;
-      if (LocalAtoi(entry->d_name, &tpid) &&
-          last_pid != tpid) {
-        last_pid = tpid;
-        ++pid_number;
-        // Invoke the callback.
-        if (callback_param &&
-            !(callback_param->call_back)(tpid, callback_param->context))
-          break;
-      }
-    }
-  }
-  closedir(dir);
-  return pid_number;
-}
-
-// Check if the address is a valid virtual address.
-// If the address is in any of the mapped modules, we take it as valid.
-// Otherwise it is invalid.
-bool LinuxThread::IsAddressMapped(uintptr_t address) const {
-  AddressValidatingContext addr;
-  addr.address = address;
-  CallbackParam<ModuleCallback> callback_param(IsAddressInModuleCallback,
-                                               &addr);
-  ListModules(&callback_param);
-  return addr.is_mapped;
-}
-
-bool LinuxThread::FindSigContext(uintptr_t sighandler_ebp,
-                                 struct sigcontext **sig_ctx) {
-  uintptr_t previous_ebp;
-  const int MAX_STACK_DEPTH = 10;
-  int depth_counter = 0;
-
-  do {
-    // We're looking for a |struct sigcontext| as the second parameter
-    // to a signal handler function call.  Luckily, the sigcontext
-    // has an ebp member which should match the ebp pointed to
-    // by the ebp of the signal handler frame.
-    previous_ebp = reinterpret_cast<uintptr_t>(GetNextFrame(
-                                  reinterpret_cast<void**>(sighandler_ebp)));
-    // The stack looks like this:
-    // | previous ebp | previous eip | first param | second param |,
-    // so we need to offset by 3 to get to the second parameter.
-    *sig_ctx = reinterpret_cast<struct sigcontext*>(sighandler_ebp +
-                                                    3 * sizeof(uintptr_t));
-    sighandler_ebp = previous_ebp;
-    depth_counter++;
-  } while(previous_ebp != (*sig_ctx)->ebp && sighandler_ebp != 0 &&
-          IsAddressMapped(sighandler_ebp) && depth_counter < MAX_STACK_DEPTH);
-
-  return previous_ebp == (*sig_ctx)->ebp && previous_ebp != 0;
-}
-
-}  // namespace google_breakpad
deleted file mode 100644
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/linux_thread.h
+++ /dev/null
@@ -1,204 +0,0 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-//
-// Author: Li Liu
-//
-// 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 Google Inc. 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 COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-#ifndef CLIENT_LINUX_HANDLER_LINUX_THREAD_H__
-#define CLIENT_LINUX_HANDLER_LINUX_THREAD_H__
-
-#include <stdint.h>
-#include <sys/user.h>
-
-namespace google_breakpad {
-
-// Max module path name length.
-#define kMaxModuleNameLength 256
-
-// Holding information about a thread in the process.
-struct ThreadInfo {
-  // Id of the thread group.
-  int tgid;
-  // Id of the thread.
-  int pid;
-  // Id of the parent process.
-  int ppid;
-};
-
-// Holding infomaton about a module in the process.
-struct ModuleInfo {
-  char name[kMaxModuleNameLength];
-  uintptr_t start_addr;
-  int size;
-};
-
-// Holding debug registers.
-struct DebugRegs {
-  int dr0;
-  int dr1;
-  int dr2;
-  int dr3;
-  int dr4;
-  int dr5;
-  int dr6;
-  int dr7;
-};
-
-// A callback to run when got a thread in the process.
-// Return true will go on to the next thread while return false will stop the
-// iteration.
-typedef bool (*ThreadCallback)(const ThreadInfo &thread_info, void *context);
-
-// A callback to run when a new module is found in the process.
-// Return true will go on to the next module while return false will stop the
-// iteration.
-typedef bool (*ModuleCallback)(const ModuleInfo &module_info, void *context);
-
-// Holding the callback information.
-template<class CallbackFunc>
-struct CallbackParam {
-  // Callback function address.
-  CallbackFunc call_back;
-  // Callback context;
-  void *context;
-
-  CallbackParam() : call_back(NULL), context(NULL) {
-  }
-
-  CallbackParam(CallbackFunc func, void *func_context) :
-    call_back(func), context(func_context) {
-  }
-};
-
-///////////////////////////////////////////////////////////////////////////////
-
-//
-// LinuxThread
-//
-// Provides handy support for operation on linux threads.
-// It uses ptrace to get thread registers. Since ptrace only works in a
-// different process other than the one being ptraced, user of this class
-// should create another process before using the class.
-//
-// The process should be created in the following way:
-//    int cloned_pid = clone(ProcessEntryFunction, stack_address,
-//                           CLONE_VM | CLONE_FILES | CLONE_FS | CLONE_UNTRACED,
-//                           (void*)&arguments);
-//    waitpid(cloned_pid, NULL, __WALL);
-//
-// If CLONE_VM is not used, GetThreadStackBottom, GetThreadStackDump
-// will not work since it just use memcpy to get the stack dump.
-//
-class LinuxThread {
- public:
-  // Create a LinuxThread instance to list all the threads in a process.
-  explicit LinuxThread(int pid);
-  ~LinuxThread();
-
-  // Stop all the threads in the process.
-  // Return the number of stopped threads in the process.
-  // Return -1 means failed to stop threads.
-  int SuspendAllThreads();
-
-  // Resume all the suspended threads.
-  void ResumeAllThreads() const;
-
-  // Get the count of threads in the process.
-  // Return -1 means error.
-  int GetThreadCount() const;
-
-  // List the threads of process.
-  // Whenever there is a thread found, the callback will be invoked to process
-  // the information.
-  // Return number of threads listed.
-  int ListThreads(CallbackParam<ThreadCallback> *thread_callback_param) const;
-
-  // Get the general purpose registers of a thread.
-  // The caller must get the thread pid by ListThreads.
-  bool GetRegisters(int pid, user_regs_struct *regs) const;
-
-  // Get the floating-point registers of a thread.
-  // The caller must get the thread pid by ListThreads.
-  bool GetFPRegisters(int pid, user_fpregs_struct *regs) const;
-
-  // Get all the extended floating-point registers. May not work on all
-  // machines.
-  // The caller must get the thread pid by ListThreads.
-  bool GetFPXRegisters(int pid, user_fpxregs_struct *regs) const;
-
-  // Get the debug registers.
-  // The caller must get the thread pid by ListThreads.
-  bool GetDebugRegisters(int pid, DebugRegs *regs) const;
-
-  // Get the stack memory dump.
-  int GetThreadStackDump(uintptr_t current_ebp,
-                         uintptr_t current_esp,
-                         void *buf,
-                         int buf_size) const;
-
-  // Get the module count of the current process.
-  int GetModuleCount() const;
-
-  // Get the mapped modules in the address space.
-  // Whenever a module is found, the callback will be invoked to process the
-  // information.
-  // Return how may modules are found.
-  int ListModules(CallbackParam<ModuleCallback> *callback_param) const;
-
-  // Get the bottom of the stack from ebp.
-  uintptr_t GetThreadStackBottom(uintptr_t current_ebp) const;
-
-  // Finds a sigcontext on the stack given the ebp of our signal handler.
-  bool FindSigContext(uintptr_t sighandler_ebp, struct sigcontext **sig_ctx);
-
- private:
-  // This callback will run when a new thread has been found.
-  typedef bool (*PidCallback)(int pid, void *context);
-
-  // Read thread information from /proc/$pid/task.
-  // Whenever a thread has been found, and callback will be invoked with
-  // the pid of the thread.
-  // Return number of threads found.
-  // Return -1 means the directory doesn't exist.
-  int IterateProcSelfTask(int pid,
-                          CallbackParam<PidCallback> *callback_param) const;
-
-  // Check if the address is a valid virtual address.
-  bool IsAddressMapped(uintptr_t address) const;
-
- private:
-  // The pid of the process we are listing threads.
-  int pid_;
-
-  // Mark if we have suspended the threads.
-  bool threads_suspened_;
-};
-
-}  // namespace google_breakpad
-
-#endif  // CLIENT_LINUX_HANDLER_LINUX_THREAD_H__
deleted file mode 100644
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/linux_thread_test.cc
+++ /dev/null
@@ -1,224 +0,0 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-//
-// Author: Li Liu
-//
-// 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 Google Inc. 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 COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <pthread.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/wait.h>
-
-#include <cstdio>
-#include <cstdlib>
-#include <cstring>
-
-#include "client/linux/handler/linux_thread.h"
-
-using namespace google_breakpad;
-
-// Thread use this to see if it should stop working.
-static bool should_exit = false;
-
-static void foo2(int *a) {
-  // Stack variable, used for debugging stack dumps.
-  int c = 0xcccccccc;
-  c = c;
-  while (!should_exit)
-    sleep(1);
-}
-
-static void foo() {
-  // Stack variable, used for debugging stack dumps.
-  int a = 0xaaaaaaaa;
-  foo2(&a);
-}
-
-static void *thread_main(void *) {
-  // Stack variable, used for debugging stack dumps.
-  int b = 0xbbbbbbbb;
-  b = b;
-  while (!should_exit) {
-    foo();
-  }
-  return NULL;
-}
-
-static void CreateThreads(int num) {
-  pthread_t handle;
-  for (int i = 0; i < num; i++) {
-    if (0 != pthread_create(&handle, NULL, thread_main, NULL))
-      fprintf(stderr, "Failed to create thread.\n");
-    else
-      pthread_detach(handle);
-  }
-}
-
-static bool ProcessOneModule(const struct ModuleInfo &module_info,
-                             void *context) {
-  printf("0x%x[%8d]         %s\n", module_info.start_addr, module_info.size,
-         module_info.name);
-  return true;
-}
-
-static bool ProcessOneThread(const struct ThreadInfo &thread_info,
-                             void *context) {
-  printf("\n\nPID: %d, TGID: %d, PPID: %d\n",
-         thread_info.pid,
-         thread_info.tgid,
-         thread_info.ppid);
-
-  struct user_regs_struct regs;
-  struct user_fpregs_struct fp_regs;
-  struct user_fpxregs_struct fpx_regs;
-  struct DebugRegs dbg_regs;
-
-  LinuxThread *threads = reinterpret_cast<LinuxThread *>(context);
-  memset(&regs, 0, sizeof(regs));
-  if (threads->GetRegisters(thread_info.pid, &regs)) {
-    printf("  gs                           = 0x%lx\n", regs.xgs);
-    printf("  fs                           = 0x%lx\n", regs.xfs);
-    printf("  es                           = 0x%lx\n", regs.xes);
-    printf("  ds                           = 0x%lx\n", regs.xds);
-    printf("  edi                          = 0x%lx\n", regs.edi);
-    printf("  esi                          = 0x%lx\n", regs.esi);
-    printf("  ebx                          = 0x%lx\n", regs.ebx);
-    printf("  edx                          = 0x%lx\n", regs.edx);
-    printf("  ecx                          = 0x%lx\n", regs.ecx);
-    printf("  eax                          = 0x%lx\n", regs.eax);
-    printf("  ebp                          = 0x%lx\n", regs.ebp);
-    printf("  eip                          = 0x%lx\n", regs.eip);
-    printf("  cs                           = 0x%lx\n", regs.xcs);
-    printf("  eflags                       = 0x%lx\n", regs.eflags);
-    printf("  esp                          = 0x%lx\n", regs.esp);
-    printf("  ss                           = 0x%lx\n", regs.xss);
-  } else {
-    fprintf(stderr, "ERROR: Failed to get general purpose registers\n");
-  }
-  memset(&fp_regs, 0, sizeof(fp_regs));
-  if (threads->GetFPRegisters(thread_info.pid, &fp_regs)) {
-    printf("\n Floating point registers:\n");
-    printf("  fctl                         = 0x%lx\n", fp_regs.cwd);
-    printf("  fstat                        = 0x%lx\n", fp_regs.swd);
-    printf("  ftag                         = 0x%lx\n", fp_regs.twd);
-    printf("  fioff                        = 0x%lx\n", fp_regs.fip);
-    printf("  fiseg                        = 0x%lx\n", fp_regs.fcs);
-    printf("  fooff                        = 0x%lx\n", fp_regs.foo);
-    printf("  foseg                        = 0x%lx\n", fp_regs.fos);
-    int st_space_size = sizeof(fp_regs.st_space) / sizeof(fp_regs.st_space[0]);
-    printf("  st_space[%2d]                 = 0x", st_space_size);
-    for (int i = 0; i < st_space_size; ++i)
-      printf("%02lx", fp_regs.st_space[i]);
-    printf("\n");
-  } else {
-    fprintf(stderr, "ERROR: Failed to get floating-point registers\n");
-  }
-  memset(&fpx_regs, 0, sizeof(fpx_regs));
-  if (threads->GetFPXRegisters(thread_info.pid, &fpx_regs)) {
-    printf("\n Extended floating point registers:\n");
-    printf("  fctl                         = 0x%x\n", fpx_regs.cwd);
-    printf("  fstat                        = 0x%x\n", fpx_regs.swd);
-    printf("  ftag                         = 0x%x\n", fpx_regs.twd);
-    printf("  fioff                        = 0x%lx\n", fpx_regs.fip);
-    printf("  fiseg                        = 0x%lx\n", fpx_regs.fcs);
-    printf("  fooff                        = 0x%lx\n", fpx_regs.foo);
-    printf("  foseg                        = 0x%lx\n", fpx_regs.fos);
-    printf("  fop                          = 0x%x\n", fpx_regs.fop);
-    printf("  mxcsr                        = 0x%lx\n", fpx_regs.mxcsr);
-    int space_size = sizeof(fpx_regs.st_space) / sizeof(fpx_regs.st_space[0]);
-    printf("  st_space[%2d]                 = 0x", space_size);
-    for (int i = 0; i < space_size; ++i)
-      printf("%02lx", fpx_regs.st_space[i]);
-    printf("\n");
-    space_size = sizeof(fpx_regs.xmm_space) / sizeof(fpx_regs.xmm_space[0]);
-    printf("  xmm_space[%2d]                = 0x", space_size);
-    for (int i = 0; i < space_size; ++i)
-      printf("%02lx", fpx_regs.xmm_space[i]);
-    printf("\n");
-  }
-  if (threads->GetDebugRegisters(thread_info.pid, &dbg_regs)) {
-    printf("\n Debug registers:\n");
-    printf("  dr0                          = 0x%x\n", dbg_regs.dr0);
-    printf("  dr1                          = 0x%x\n", dbg_regs.dr1);
-    printf("  dr2                          = 0x%x\n", dbg_regs.dr2);
-    printf("  dr3                          = 0x%x\n", dbg_regs.dr3);
-    printf("  dr4                          = 0x%x\n", dbg_regs.dr4);
-    printf("  dr5                          = 0x%x\n", dbg_regs.dr5);
-    printf("  dr6                          = 0x%x\n", dbg_regs.dr6);
-    printf("  dr7                          = 0x%x\n", dbg_regs.dr7);
-    printf("\n");
-  }
-  if (regs.esp != 0) {
-    // Print the stack content.
-    int size = 1024 * 2;
-    char *buf = new char[size];
-    size = threads->GetThreadStackDump(regs.ebp,
-                                       regs.esp,
-                                      (void*)buf, size);
-    printf(" Stack content:                 = 0x");
-    size /= sizeof(unsigned long);
-    unsigned long *p_buf = (unsigned long *)(buf);
-    for (int i = 0; i < size; i += 1)
-      printf("%.8lx ", p_buf[i]);
-    delete []buf;
-    printf("\n");
-  }
-  return true;
-}
-
-static int PrintAllThreads(void *argument) {
-  int pid = (int)argument;
-
-  LinuxThread threads(pid);
-  int total_thread = threads.SuspendAllThreads();
-  printf("There are %d threads in the process: %d\n", total_thread, pid);
-  int total_module = threads.GetModuleCount();
-  printf("There are %d modules in the process: %d\n", total_module, pid);
-  CallbackParam<ModuleCallback> module_callback(ProcessOneModule, &threads);
-  threads.ListModules(&module_callback);
-  CallbackParam<ThreadCallback> thread_callback(ProcessOneThread, &threads);
-  threads.ListThreads(&thread_callback);
-  return 0;
-}
-
-int main(int argc, char **argv) {
-  int pid = getpid();
-  printf("Main thread is %d\n", pid);
-  CreateThreads(1);
-  // Create stack for the process.
-  char *stack = new char[1024 * 100];
-  int cloned_pid = clone(PrintAllThreads, stack + 1024 * 100,
-                           CLONE_VM | CLONE_FILES | CLONE_FS | CLONE_UNTRACED,
-                           (void*)getpid());
-  waitpid(cloned_pid, NULL, __WALL);
-  should_exit = true;
-  printf("Test finished.\n");
-
-  delete []stack;
-  return 0;
-}
deleted file mode 100644
--- a/toolkit/crashreporter/google-breakpad/src/client/linux/handler/minidump_generator.cc
+++ /dev/null
@@ -1,816 +0,0 @@
-// Copyright (c) 2006, Google Inc.
-// All rights reserved.
-//
-// Author: Li Liu
-//
-// 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 Google Inc. 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 COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <fcntl.h>
-#include <pthread.h>
-#include <signal.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <sys/utsname.h>
-#include <sys/wait.h>
-
-#include <cstdlib>
-#include <cstdio>
-#include <ctime>
-#include <string.h>
-
-#include "common/linux/file_id.h"
-#include "client/linux/handler/linux_thread.h"
-#include "client/minidump_file_writer.h"
-#include "client/minidump_file_writer-inl.h"
-#include "google_breakpad/common/minidump_format.h"
-#include "client/linux/handler/minidump_generator.h"
-
-#ifndef CLONE_UNTRACED
-#define CLONE_UNTRACED 0x00800000
-#endif
-
-// This unnamed namespace contains helper functions.
-namespace {
-
-using namespace google_breakpad;
-
-// Argument for the writer function.
-struct WriterArgument {
-  MinidumpFileWriter *minidump_writer;
-
-  // Context for the callback.
-  void *version_context;
-
-  // Pid of the thread who called WriteMinidumpToFile
-  int requester_pid;
-
-  // The stack bottom of the thread which caused the dump.
-  // Mainly used to find the thread id of the crashed thread since signal
-  // handler may not be called in the thread who caused it.
-  uintptr_t crashed_stack_bottom;
-
-  // Pid of the crashing thread.
-  int crashed_pid;
-
-  // Signal number when crash happed. Can be 0 if this is a requested dump.
-  int signo;
-
-  // The ebp of the signal handler frame.  Can be zero if this
-  // is a requested dump.
-  uintptr_t sighandler_ebp;
-
-  // Signal context when crash happed. Can be NULL if this is a requested dump.
-  // This is actually an out parameter, but it will be filled in at the start
-  // of the writer thread.
-  struct sigcontext *sig_ctx;
-
-  // Used to get information about the threads.
-  LinuxThread *thread_lister;
-};
-
-// Holding context information for the callback of finding the crashing thread.
-struct FindCrashThreadContext {
-  const LinuxThread *thread_lister;
-  uintptr_t crashing_stack_bottom;
-  int crashing_thread_pid;
-
-  FindCrashThreadContext() :
-    thread_lister(NULL),
-    crashing_stack_bottom(0UL),
-    crashing_thread_pid(-1) {
-  }
-};
-
-// Callback for list threads.
-// It will compare the stack bottom of the provided thread with the stack
-// bottom of the crashed thread, it they are eqaul, this is thread is the one
-// who crashed.
-bool IsThreadCrashedCallback(const ThreadInfo &thread_info, void *context) {
-  FindCrashThreadContext *crashing_context =
-    static_cast<FindCrashThreadContext *>(context);
-  const LinuxThread *thread_lister = crashing_context->thread_lister;
-  struct user_regs_struct regs;
-  if (thread_lister->GetRegisters(thread_info.pid, &regs)) {
-    uintptr_t last_ebp = regs.ebp;
-    uintptr_t stack_bottom = thread_lister->GetThreadStackBottom(last_ebp);
-    if (stack_bottom > last_ebp &&
-        stack_bottom == crashing_context->crashing_stack_bottom) {
-      // Got it. Stop iteration.
-      crashing_context->crashing_thread_pid = thread_info.pid;
-      return false;
-    }
-  }
-  return true;
-}
-
-// Find the crashing thread id.
-// This is done based on stack bottom comparing.
-int FindCrashingThread(uintptr_t crashing_stack_bottom,
-                       int requester_pid,
-                       const LinuxThread *thread_lister) {
-  FindCrashThreadContext context;
-  context.thread_lister = thread_lister;
-  context.crashing_stack_bottom = crashing_stack_bottom;
-  CallbackParam<ThreadCallback> callback_param(IsThreadCrashedCallback,
-                                               &context);
-  thread_lister->ListThreads(&callback_param);
-  return context.crashing_thread_pid;
-}
-
-// Write the thread stack info minidump.
-bool WriteThreadStack(uintptr_t last_ebp,
-                      uintptr_t last_esp,
-                      const LinuxThread *thread_lister,
-                      UntypedMDRVA *memory,
-                      MDMemoryDescriptor *loc) {
-  // Maximum stack size for a thread.
-  uintptr_t stack_bottom = thread_lister->GetThreadStackBottom(last_ebp);
-  if (stack_bottom > last_esp) {
-    int size = stack_bottom - last_esp;
-    if (size > 0) {
-      if (!memory->Allocate(size))
-        return false;
-      memory->Copy(reinterpret_cast<void*>(last_esp), size);
-      loc->start_of_memory_range = 0 | last_esp;
-      loc->memory = memory->location();
-    }
-    return true;
-  }
-  return false;
-}
-
-// Write CPU context based on signal context.
-bool WriteContext(MDRawContextX86 *context, const struct sigcontext *sig_ctx,
-                  const DebugRegs *debug_regs) {
-  assert(sig_ctx != NULL);
-  context->context_flags = MD_CONTEXT_X86_FULL;
-  context->gs = sig_ctx->gs;
-  context->fs = sig_ctx->fs;
-  context->es = sig_ctx->es;
-  context->ds = sig_ctx->ds;
-  context->cs = sig_ctx->cs;
-  context->ss = sig_ctx->ss;
-  context->edi = sig_ctx->edi;
-  context->esi = sig_ctx->esi;
-  context->ebp = sig_ctx->ebp;
-  context->esp = sig_ctx->esp;
-  context->ebx = sig_ctx->ebx;
-  context->edx = sig_ctx->edx;
-  context->ecx = sig_ctx->ecx;
-  context->eax = sig_ctx->eax;
-  context->eip = sig_ctx->eip;
-  context->eflags = sig_ctx->eflags;
-  if (sig_ctx->fpstate != NULL) {
-    context->context_flags = MD_CONTEXT_X86_FULL |
-      MD_CONTEXT_X86_FLOATING_POINT;
-    context->float_save.control_word = sig_ctx->fpstate->cw;
-    context->float_save.status_word = sig_ctx->fpstate->sw;
-    context->float_save.tag_word = sig_ctx->fpstate->tag;
-    context->float_save.error_offset = sig_ctx->fpstate->ipoff;
-    context->float_save.error_selector = sig_ctx->fpstate->cssel;
-    context->float_save.data_offset = sig_ctx->fpstate->dataoff;
-    context->float_save.data_selector = sig_ctx->fpstate->