Merge only plugin changes from e10s to mozilla-central.
authorBenjamin Smedberg <benjamin@smedbergs.us>
Wed, 16 Dec 2009 09:19:07 -0500
changeset 36284 4eef63c0c6c9b75a9ebf0b7c51e4ecc443fc295a
parent 36280 7f78246faad942dbb4157e994d3a1634f23dda5f (current diff)
parent 36283 e517feb23baac6f2d0caad8c0b1269c9fdcdf1e3 (diff)
child 36286 35df81a4848405567610a32a3ffeffb4fe7c3668
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone1.9.3a1pre
Merge only plugin changes from e10s to mozilla-central.
.hgtags
toolkit/xre/nsEmbedFunctions.cpp
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -920,20 +920,20 @@ refChildCB(AtkObject *aAtkObj, gint aChi
     if (!accChild)
         return nsnull;
 
     AtkObject* childAtkObj = nsAccessibleWrap::GetAtkObject(accChild);
 
     NS_ASSERTION(childAtkObj, "Fail to get AtkObj");
     if (!childAtkObj)
         return nsnull;
+    g_object_ref(childAtkObj);
     
     //this will addref parent
     atk_object_set_parent(childAtkObj, aAtkObj);
-    g_object_ref(childAtkObj);
     return childAtkObj;
 }
 
 gint
 getIndexInParentCB(AtkObject *aAtkObj)
 {
     // We don't use nsIAccessible::GetIndexInParent() because
     // for ATK we don't want to include text leaf nodes as children
--- a/accessible/src/base/nsARIAMap.cpp
+++ b/accessible/src/base/nsARIAMap.cpp
@@ -404,16 +404,27 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] 
     eNoValue,
     eSortAction,
     eNoLiveAttr,
     kNoReqStates,
     eARIASelectable,
     eARIAReadonly
   },
   {
+    "scrollbar",
+    nsIAccessibleRole::ROLE_SCROLLBAR,
+    kUseMapRole,
+    eHasValueMinMax,
+    eNoAction,
+    eNoLiveAttr,
+    kNoReqStates,
+    eARIAOrientation,
+    eARIAReadonly
+  },
+  {
     "separator",
     nsIAccessibleRole::ROLE_SEPARATOR,
     kUseMapRole,
     eNoValue,
     eNoAction,
     eNoLiveAttr,
     kNoReqStates
   },
@@ -623,16 +634,21 @@ nsStateMapEntry nsARIAMap::gWAIStateMap[
   nsStateMapEntry(&nsAccessibilityAtoms::aria_multiline, kBoolType, 0,
                   0, nsIAccessibleStates::EXT_STATE_MULTI_LINE,
                   0, nsIAccessibleStates::EXT_STATE_SINGLE_LINE, PR_TRUE),
 
   // eARIAMultiSelectable
   nsStateMapEntry(&nsAccessibilityAtoms::aria_multiselectable, kBoolType, 0,
                   nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE, 0),
 
+  // eARIAOrientation
+  nsStateMapEntry(&nsAccessibilityAtoms::aria_orientation, eUseFirstState,
+                  "vertical", 0, nsIAccessibleStates::EXT_STATE_VERTICAL,
+                  "horizontal", 0, nsIAccessibleStates::EXT_STATE_HORIZONTAL),
+
   // eARIAPressed
   nsStateMapEntry(&nsAccessibilityAtoms::aria_pressed, kMixedType,
                   nsIAccessibleStates::STATE_CHECKABLE,
                   nsIAccessibleStates::STATE_PRESSED, 0),
 
   // eARIAReadonly
   nsStateMapEntry(&nsAccessibilityAtoms::aria_readonly, kBoolType, 0,
                   nsIAccessibleStates::STATE_READONLY, 0),
@@ -688,16 +704,17 @@ nsAttributeCharacteristics nsARIAMap::gW
   {&nsAccessibilityAtoms::aria_grabbed,                            ATTR_VALTOKEN },
   {&nsAccessibilityAtoms::aria_haspopup,          ATTR_BYPASSOBJ | ATTR_VALTOKEN },
   {&nsAccessibilityAtoms::aria_invalid,           ATTR_BYPASSOBJ | ATTR_VALTOKEN },
   {&nsAccessibilityAtoms::aria_labelledby,        ATTR_BYPASSOBJ                 },
   {&nsAccessibilityAtoms::aria_live,                               ATTR_VALTOKEN },
   {&nsAccessibilityAtoms::aria_multiline,         ATTR_BYPASSOBJ | ATTR_VALTOKEN },
   {&nsAccessibilityAtoms::aria_multiselectable,   ATTR_BYPASSOBJ | ATTR_VALTOKEN },
   {&nsAccessibilityAtoms::aria_owns,              ATTR_BYPASSOBJ                 },
+  {&nsAccessibilityAtoms::aria_orientation,                        ATTR_VALTOKEN },
   {&nsAccessibilityAtoms::aria_pressed,           ATTR_BYPASSOBJ | ATTR_VALTOKEN },
   {&nsAccessibilityAtoms::aria_readonly,          ATTR_BYPASSOBJ | ATTR_VALTOKEN },
   {&nsAccessibilityAtoms::aria_relevant,          ATTR_BYPASSOBJ                 },
   {&nsAccessibilityAtoms::aria_required,          ATTR_BYPASSOBJ | ATTR_VALTOKEN },
   {&nsAccessibilityAtoms::aria_selected,          ATTR_BYPASSOBJ | ATTR_VALTOKEN },
   {&nsAccessibilityAtoms::aria_sort,                               ATTR_VALTOKEN },
   {&nsAccessibilityAtoms::aria_valuenow,          ATTR_BYPASSOBJ                 },
   {&nsAccessibilityAtoms::aria_valuemin,          ATTR_BYPASSOBJ                 },
@@ -744,16 +761,36 @@ nsStateMapEntry::nsStateMapEntry(nsIAtom
   attributeName(aAttrName), isToken(PR_FALSE), permanentState(0),
   value1(aValue1), state1(aState1), extraState1(aExtraState1),
   value2(aValue2), state2(aState2), extraState2(aExtraState2),
   value3(aValue3), state3(aState3), extraState3(aExtraState3),
   defaultState(0), defaultExtraState(0), definedIfAbsent(PR_FALSE)
 {
 }
 
+nsStateMapEntry::nsStateMapEntry(nsIAtom **aAttrName,
+                                 EDefaultStateRule aDefaultStateRule,
+                                 const char *aValue1,
+                                 PRUint32 aState1, PRUint32 aExtraState1,
+                                 const char *aValue2,
+                                 PRUint32 aState2, PRUint32 aExtraState2,
+                                 const char *aValue3,
+                                 PRUint32 aState3, PRUint32 aExtraState3) :
+  attributeName(aAttrName), isToken(PR_TRUE), permanentState(0),
+  value1(aValue1), state1(aState1), extraState1(aExtraState1),
+  value2(aValue2), state2(aState2), extraState2(aExtraState2),
+  value3(aValue3), state3(aState3), extraState3(aExtraState3),
+  defaultState(0), defaultExtraState(0), definedIfAbsent(PR_TRUE)
+{
+  if (aDefaultStateRule == eUseFirstState) {
+    defaultState = aState1;
+    defaultExtraState = aExtraState1;
+  }
+}
+
 PRBool
 nsStateMapEntry::MapToStates(nsIContent *aContent,
                              PRUint32 *aState, PRUint32 *aExtraState,
                              eStateMapEntryID aStateMapEntryID)
 {
   // Return true if we should continue.
   if (aStateMapEntryID == eARIANone)
     return PR_FALSE;
--- a/accessible/src/base/nsARIAMap.h
+++ b/accessible/src/base/nsARIAMap.h
@@ -152,16 +152,22 @@ struct nsAttributeCharacteristics
 #define kNoReqStates 0
 
 enum eStateValueType
 {
   kBoolType,
   kMixedType
 };
 
+enum EDefaultStateRule
+{
+  //eNoDefaultState,
+  eUseFirstState
+};
+
 /**
  * ID for state map entry, used in nsRoleMapEntry.
  */
 enum eStateMapEntryID
 {
   eARIANone,
   eARIAAutoComplete,
   eARIABusy,
@@ -169,16 +175,17 @@ enum eStateMapEntryID
   eARIACheckableMixed,
   eARIACheckedMixed,
   eARIADisabled,
   eARIAExpanded,
   eARIAHasPopup,
   eARIAInvalid,
   eARIAMultiline,
   eARIAMultiSelectable,
+  eARIAOrientation,
   eARIAPressed,
   eARIAReadonly,
   eARIAReadonlyOrEditable,
   eARIARequired,
   eARIASelectable
 };
 
 class nsStateMapEntry
@@ -203,16 +210,27 @@ public:
    */
   nsStateMapEntry(nsIAtom **aAttrName,
                   const char *aValue1, PRUint32 aState1, PRUint32 aExtraState1,
                   const char *aValue2, PRUint32 aState2, PRUint32 aExtraState2,
                   const char *aValue3 = 0, PRUint32 aState3 = 0,
                   PRUint32 aExtraState3 = 0);
 
   /**
+   * Used for ARIA attributes having enumerated values, and where a default
+   * attribute state should be assumed when not supplied by the author.
+   */
+  nsStateMapEntry(nsIAtom **aAttrName,
+                  EDefaultStateRule aDefaultStateRule,
+                  const char *aValue1, PRUint32 aState1, PRUint32 aExtraState1,
+                  const char *aValue2, PRUint32 aState2, PRUint32 aExtraState2,
+                  const char *aValue3 = 0, PRUint32 aState3 = 0,
+                  PRUint32 aExtraState3 = 0);
+
+  /**
    * Maps ARIA state map pointed by state map entry ID to accessible states.
    *
    * @param  aContent         [in] node of the accessible
    * @param  aState           [in/out] accessible states
    * @param  aExtraState      [in/out] accessible extra states
    * @param  aStateMapEntryID [in] state map entry ID
    * @return                   true if state map entry ID is valid
    */
--- a/accessible/src/base/nsAccessibilityAtomList.h
+++ b/accessible/src/base/nsAccessibilityAtomList.h
@@ -236,16 +236,17 @@ ACCESSIBILITY_ATOM(aria_grabbed, "aria-g
 ACCESSIBILITY_ATOM(aria_haspopup, "aria-haspopup")
 ACCESSIBILITY_ATOM(aria_invalid, "aria-invalid")
 ACCESSIBILITY_ATOM(aria_label, "aria-label")
 ACCESSIBILITY_ATOM(aria_labelledby, "aria-labelledby")
 ACCESSIBILITY_ATOM(aria_level, "aria-level")
 ACCESSIBILITY_ATOM(aria_live, "aria-live")
 ACCESSIBILITY_ATOM(aria_multiline, "aria-multiline")
 ACCESSIBILITY_ATOM(aria_multiselectable, "aria-multiselectable")
+ACCESSIBILITY_ATOM(aria_orientation, "aria-orientation")
 ACCESSIBILITY_ATOM(aria_owns, "aria-owns")
 ACCESSIBILITY_ATOM(aria_posinset, "aria-posinset")
 ACCESSIBILITY_ATOM(aria_pressed, "aria-pressed")
 ACCESSIBILITY_ATOM(aria_readonly, "aria-readonly")
 ACCESSIBILITY_ATOM(aria_relevant, "aria-relevant")
 ACCESSIBILITY_ATOM(aria_required, "aria-required")
 ACCESSIBILITY_ATOM(aria_selected, "aria-selected")
 ACCESSIBILITY_ATOM(aria_setsize, "aria-setsize")
--- a/accessible/src/base/nsRootAccessible.cpp
+++ b/accessible/src/base/nsRootAccessible.cpp
@@ -942,19 +942,22 @@ void nsRootAccessible::FireFocusCallback
 // nsAccessNode
 
 nsresult
 nsRootAccessible::Init()
 {
   nsRefPtr<nsApplicationAccessibleWrap> root = GetApplicationAccessible();
   NS_ENSURE_STATE(root);
 
-  root->AddRootAccessible(this);
+  nsresult rv = nsDocAccessibleWrap::Init();
 
-  return nsDocAccessibleWrap::Init();
+  if (NS_SUCCEEDED(rv))
+    root->AddRootAccessible(this);
+
+  return rv;
 }
 
 nsresult
 nsRootAccessible::Shutdown()
 {
   // Called manually or by nsAccessNode::LastRelease()
   if (!mWeakShell) {
     return NS_OK;  // Already shutdown
--- a/accessible/tests/mochitest/common.js
+++ b/accessible/tests/mochitest/common.js
@@ -74,16 +74,17 @@ const STATE_UNAVAILABLE = nsIAccessibleS
 
 const EXT_STATE_EDITABLE = nsIAccessibleStates.EXT_STATE_EDITABLE;
 const EXT_STATE_EXPANDABLE = nsIAccessibleStates.EXT_STATE_EXPANDABLE;
 const EXT_STATE_HORIZONTAL = nsIAccessibleStates.EXT_STATE_HORIZONTAL;
 const EXT_STATE_MULTI_LINE = nsIAccessibleStates.EXT_STATE_MULTI_LINE;
 const EXT_STATE_SINGLE_LINE = nsIAccessibleStates.EXT_STATE_SINGLE_LINE;
 const EXT_STATE_SUPPORTS_AUTOCOMPLETION = 
       nsIAccessibleStates.EXT_STATE_SUPPORTS_AUTOCOMPLETION;
+const EXT_STATE_VERTICAL = nsIAccessibleStates.EXT_STATE_VERTICAL;
 
 ////////////////////////////////////////////////////////////////////////////////
 // OS detect
 const MAC = (navigator.platform.indexOf("Mac") != -1)? true : false;
 const LINUX = (navigator.platform.indexOf("Linux") != -1)? true : false;
 const WIN = (navigator.platform.indexOf("Win") != -1)? true : false;
 
 ////////////////////////////////////////////////////////////////////////////////
--- a/accessible/tests/mochitest/role.js
+++ b/accessible/tests/mochitest/role.js
@@ -39,16 +39,17 @@ const ROLE_OUTLINEITEM = nsIAccessibleRo
 const ROLE_PARAGRAPH = nsIAccessibleRole.ROLE_PARAGRAPH;
 const ROLE_PARENT_MENUITEM = nsIAccessibleRole.ROLE_PARENT_MENUITEM;
 const ROLE_PASSWORD_TEXT = nsIAccessibleRole.ROLE_PASSWORD_TEXT;
 const ROLE_PROGRESSBAR = nsIAccessibleRole.ROLE_PROGRESSBAR;
 const ROLE_PUSHBUTTON = nsIAccessibleRole.ROLE_PUSHBUTTON;
 const ROLE_RADIOBUTTON = nsIAccessibleRole.ROLE_RADIOBUTTON;
 const ROLE_ROW = nsIAccessibleRole.ROLE_ROW;
 const ROLE_ROWHEADER = nsIAccessibleRole.ROLE_ROWHEADER;
+const ROLE_SCROLLBAR = nsIAccessibleRole.ROLE_SCROLLBAR;
 const ROLE_SECTION = nsIAccessibleRole.ROLE_SECTION;
 const ROLE_SEPARATOR = nsIAccessibleRole.ROLE_SEPARATOR;
 const ROLE_SLIDER = nsIAccessibleRole.ROLE_SLIDER;
 const ROLE_STATICTEXT = nsIAccessibleRole.ROLE_STATICTEXT;
 const ROLE_TABLE = nsIAccessibleRole.ROLE_TABLE;
 const ROLE_TEXT_CONTAINER = nsIAccessibleRole.ROLE_TEXT_CONTAINER;
 const ROLE_TEXT_LEAF = nsIAccessibleRole.ROLE_TEXT_LEAF;
 const ROLE_TOGGLE_BUTTON = nsIAccessibleRole.ROLE_TOGGLE_BUTTON;
--- a/accessible/tests/mochitest/test_aria_roles.html
+++ b/accessible/tests/mochitest/test_aria_roles.html
@@ -1,13 +1,14 @@
 <!DOCTYPE html>
 <html>
 <!--
 https://bugzilla.mozilla.org/show_bug.cgi?id=481114
 https://bugzilla.mozilla.org/show_bug.cgi?id=469688
+https://bugzilla.mozilla.org/show_bug.cgi?id=529289
 -->
 <head>
   <title>Test weak ARIA roles</title>
   <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
 
   <script type="application/javascript"
           src="chrome://mochikit/content/MochiKit/packed.js"></script>
   <script type="application/javascript"
@@ -58,27 +59,31 @@ https://bugzilla.mozilla.org/show_bug.cg
 
       // abstract roles
       var abstract_roles = ["composite", "landmark", "structure", "widget",
                             "window", "input", "range", "select", "section",
                             "sectionhead"];
       for (a in abstract_roles)
         testRole(abstract_roles[a], ROLE_SECTION);
 
+      // aria scrollbar
+      testRole("scrollbar", ROLE_SCROLLBAR);
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 </head>
 <body>
 
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=481114">Mozilla Bug 481114</a>
   <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469688">Mozilla Bug 469688</a>
+  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=529289">Mozilla Bug 529289</a>
+  </a>
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
   
   <!-- "live" roles -->
   <table role="log" id="log_table">
     <tr><td>Table based log</td></tr>
@@ -129,10 +134,12 @@ https://bugzilla.mozilla.org/show_bug.cg
   <!-- test abstract input roles -->
   <div role="input" id="input">input</div>
   <div role="range" id="range">range</div>
   <div role="select" id="select">select</div>
   <!-- test abstract structure roles -->
   <div role="section" id="section">section</div>
   <div role="sectionhead" id="sectionhead">sectionhead</div>
 
+  <!-- aria scrollbar -->
+  <div role="scrollbar" id="scrollbar">scrollbar</div>
 </body>
 </html>
--- a/accessible/tests/mochitest/test_events_valuechange.html
+++ b/accessible/tests/mochitest/test_events_valuechange.html
@@ -61,49 +61,60 @@
     }
 
     function doTests()
     {
       // Test initial values
       testValue("slider_vn", "5", 5, 0, 1000, 0);
       testValue("slider_vnvt", "plain", 0, 0, 5, 0);
       testValue("slider_vt", "hi", 0, 0, 3, 0);
+      testValue("scrollbar", "5", 5, 0, 1000, 0);
 
       // Test value change events
       gQueue = new eventQueue(nsIAccessibleEvent.EVENT_VALUE_CHANGE);
 
       gQueue.push(new changeValue("slider_vn", "6", undefined));
       gQueue.push(new changeValue("slider_vt", undefined, "hey!"));
       gQueue.push(new changeValue("slider_vnvt", "3", "sweet"));
+      gQueue.push(new changeValue("scrollbar", "6", undefined));
 
       gQueue.invoke(); // Will call SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTests);
   </script>
 </head>
 
 <body>
 
   <a target="_blank"
      href="https://bugzilla.mozilla.org/show_bug.cgi?id=478032"
      title=" Fire delayed value changed event for aria-valuetext changes">
     Mozilla Bug 478032
   </a>
+  <a target="_blank"
+    href="https://bugzilla.mozilla.org/show_bug.cgi?id=529289"
+    title="We dont expose new aria role 'scrollbar' and property aria-orientation">
+   Mozilla Bug 529289
+  </a>
 
   <p id="display"></p>
   <div id="content" style="display: none"></div>
   <pre id="test">
   </pre>
   <div id="eventdump"></div>
 
   <!-- ARIA sliders -->
   <div id="slider_vn" role="slider" aria-valuenow="5"
-    aria-valuemin="0" aria-valuemax="1000">slider</div>
+       aria-valuemin="0" aria-valuemax="1000">slider</div>
 
   <div id="slider_vt" role="slider" aria-valuetext="hi"
-    aria-valuemin="0" aria-valuemax="3">greeting slider</div>
+       aria-valuemin="0" aria-valuemax="3">greeting slider</div>
 
   <div id="slider_vnvt" role="slider" aria-valuenow="0" aria-valuetext="plain"
-    aria-valuemin="0" aria-valuemax="5">sweetness slider</div>
+       aria-valuemin="0" aria-valuemax="5">sweetness slider</div>
+
+  <!-- ARIA scrollbar -->
+  <div id="scrollbar" role="scrollbar" aria-valuenow="5"
+       aria-valuemin="0" aria-valuemax="1000">slider</div>
 </body>
 </html>
--- a/accessible/tests/mochitest/test_states.html
+++ b/accessible/tests/mochitest/test_states.html
@@ -88,16 +88,21 @@
       testStates("aria_link_anchor", STATE_SELECTABLE);
 
       // some weak landmarks
       testStates("aria_main_link", STATE_LINKED);
       testStates("aria_navigation_link", STATE_LINKED);
       testStates("aria_main_anchor", STATE_SELECTABLE);
       testStates("aria_navigation_anchor", STATE_SELECTABLE);
 
+      // scrollbar
+      testStates("aria_scrollbar", 0, EXT_STATE_VERTICAL);
+      testStates("aria_hscrollbar", 0, EXT_STATE_HORIZONTAL);
+      testStates("aria_vscrollbar", 0, EXT_STATE_VERTICAL);
+
       SimpleTest.finish();
     }
 
     SimpleTest.waitForExplicitFinish();
     addA11yLoadEvent(doTest);
   </script>
 
 </head>
@@ -178,10 +183,14 @@
   <a id="aria_main_link" role="main" href="foo">main</a>
   <a id="aria_navigation_link" role="navigation" href="foo">nav</a>
   
   <!-- landmarks: anchors -->
   <a id="aria_application_anchor" role="application" name="app_anchor">app</a>
   <a id="aria_main_anchor" role="main" name="main_anchor">main</a>
   <a id="aria_navigation_anchor" role="navigation" name="nav_anchor">nav</a>
 
+  <!-- scrollbar -->
+  <div id="aria_scrollbar" role="scrollbar">scrollbar</a>
+  <div id="aria_hscrollbar" role="scrollbar" aria-orientation="horizontal">horizontal scrollbar</a>
+  <div id="aria_vscrollbar" role="scrollbar" aria-orientation="vertical">vertical scrollbar</a>
 </body>
 </html>
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -306,18 +306,23 @@ pref("browser.search.updateinterval", 6)
 // Whether or not microsummary and generator updates are enabled
 pref("browser.microsummary.enabled", true);
 pref("browser.microsummary.updateGenerators", true);
 
 // enable search suggestions by default
 pref("browser.search.suggest.enabled", true);
 
 pref("browser.sessionhistory.max_entries", 50);
+#ifndef WINCE
 pref("browser.history_expire_days", 180);
 pref("browser.history_expire_days_min", 90);
+#else
+pref("browser.history_expire_days", 90);
+pref("browser.history_expire_days_min", 45);
+#endif
 pref("browser.history_expire_sites", 40000);
 
 // handle links targeting new windows
 // 0=default window, 1=current window/tab, 2=new window, 3=new tab in most recent window
 pref("browser.link.open_newwindow", 3);
 
 // 0: no restrictions - divert everything
 // 1: don't divert window.open at all
--- a/browser/base/content/browser.js
+++ b/browser/base/content/browser.js
@@ -2287,17 +2287,17 @@ function SetPageProxyState(aState)
   gProxyFavIcon.setAttribute("pageproxystate", aState);
 
   // the page proxy state is set to valid via OnLocationChange, which
   // gets called when we switch tabs.
   if (aState == "valid") {
     gLastValidURLStr = gURLBar.value;
     gURLBar.addEventListener("input", UpdatePageProxyState, false);
 
-    PageProxySetIcon(gBrowser.selectedBrowser.mIconURL);
+    PageProxySetIcon(gBrowser.getIcon());
   } else if (aState == "invalid") {
     gURLBar.removeEventListener("input", UpdatePageProxyState, false);
     PageProxyClearIcon();
   }
 }
 
 function PageProxySetIcon (aURL)
 {
@@ -3097,17 +3097,17 @@ const BrowserSearch = {
     var searchBar = this.searchBar;
     if (isElementVisible(searchBar)) {
       searchBar.select();
       searchBar.focus();
     } else {
       var ss = Cc["@mozilla.org/browser/search-service;1"].
                getService(Ci.nsIBrowserSearchService);
       var searchForm = ss.defaultEngine.searchForm;
-      loadURI(searchForm, null, null, false);
+      openUILinkIn(searchForm, "current");
     }
   },
 
   /**
    * Loads a search results page, given a set of search terms. Uses the current
    * engine if the search bar is visible, or the default engine otherwise.
    *
    * @param searchText
@@ -3908,19 +3908,19 @@ var XULBrowserWindow = {
     // check the current value so we don't trigger an attribute change
     // and cause needless (slow!) UI updates
     if (this.statusText != text) {
       this.statusTextField.label = text;
       this.statusText = text;
     }
   },
   
-  onLinkIconAvailable: function (aBrowser) {
+  onLinkIconAvailable: function (aBrowser, aIconURL) {
     if (gProxyFavIcon && gBrowser.userTypedValue === null)
-      PageProxySetIcon(aBrowser.mIconURL); // update the favicon in the URL bar
+      PageProxySetIcon(aIconURL); // update the favicon in the URL bar
   },
 
   onProgressChange: function (aWebProgress, aRequest,
                               aCurSelfProgress, aMaxSelfProgress,
                               aCurTotalProgress, aMaxTotalProgress) {
     // Check this._busyUI to be safe, because we don't want to update
     // the progress meter when restoring a page from bfcache.
     if (aMaxTotalProgress > 0 && this._busyUI) {
@@ -3975,17 +3975,17 @@ var XULBrowserWindow = {
         this.stopCommand.removeAttribute("disabled");
       }
     }
     else if (aStateFlags & nsIWebProgressListener.STATE_STOP) {
       if (aStateFlags & nsIWebProgressListener.STATE_IS_NETWORK) {
         if (aWebProgress.DOMWindow == content) {
           if (aRequest)
             this.endDocumentLoad(aRequest, aStatus);
-          if (!gBrowser.mTabbedMode && !gBrowser.selectedBrowser.mIconURL)
+          if (!gBrowser.mTabbedMode && !gBrowser.getIcon())
             gBrowser.useDefaultIcon(gBrowser.selectedTab);
         }
       }
 
       // This (thanks to the filter) is a network stop or the last
       // request stop outside of loading the document, stop throbbers
       // and progress bars and such
       if (aRequest) {
--- a/browser/base/content/tabbrowser.xml
+++ b/browser/base/content/tabbrowser.xml
@@ -695,38 +695,48 @@
 
             this.updateIcon(aTab);
 
             if (browser == this.mCurrentBrowser) {
               for (let i = 0; i < this.mProgressListeners.length; i++) {
                 let p = this.mProgressListeners[i];
                 if ('onLinkIconAvailable' in p)
                   try {
-                    p.onLinkIconAvailable(browser);
+                    p.onLinkIconAvailable(browser, browser.mIconURL);
                   } catch (e) {
                     // don't inhibit other listeners
                     Components.utils.reportError(e);
                   }
               }
             }
 
             for (let i = 0; i < this.mTabsProgressListeners.length; i++) {
               let p = this.mTabsProgressListeners[i];
               if ('onLinkIconAvailable' in p)
                 try {
-                  p.onLinkIconAvailable(browser);
+                  p.onLinkIconAvailable(browser, browser.mIconURL);
                 } catch (e) {
                   // don't inhibit other listeners
                   Components.utils.reportError(e);
                 }
             }
           ]]>
         </body>
       </method>
 
+      <method name="getIcon">
+        <parameter name="aTab"/>
+        <body>
+          <![CDATA[
+            let browser = aTab ? this.getBrowserForTab(aTab) : this.selectedBrowser;
+            return browser.mIconURL;
+          ]]>
+        </body>
+      </method>
+
       <method name="updateIcon">
         <parameter name="aTab"/>
         <body>
           <![CDATA[
             var browser = this.getBrowserForTab(aTab);
             if (!aTab.hasAttribute("busy") && browser.mIconURL)
               aTab.setAttribute("image", browser.mIconURL);
             else
--- a/browser/base/content/test/browser_bug477014.js
+++ b/browser/base/content/test/browser_bug477014.js
@@ -71,16 +71,16 @@ function test() {
           newWindow.removeEventListener("load", arguments.callee, false);
         }
         newWindow.addEventListener("load", onLoad, false);
       }, 0);
       return;
     }
 
     is(newWindow.gBrowser.selectedTab.hasAttribute("busy"), true);
-    is(newWindow.gBrowser.selectedTab.linkedBrowser.mIconURL,iconURLSpec);
+    is(newWindow.gBrowser.getIcon(), iconURLSpec);
     newWindow.close();
     finish();
   }
 
   gBrowser.addEventListener("pageshow", onPageShow, false);
   tabToDetach = gBrowser.addTab(testPage);
 }
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -311,16 +311,28 @@ BrowserGlue.prototype = {
 
     this._observerService
         .notifyObservers(null, "browser-ui-startup-complete", "");
   },
 
   // profile shutdown handler (contains profile cleanup routines)
   _onProfileShutdown: function() 
   {
+#ifdef WINCE
+    // If there's a pending update, clear cache to free up disk space.
+    try {
+      let um = Cc["@mozilla.org/updates/update-manager;1"].
+               getService(Ci.nsIUpdateManager);
+      if (um.activeUpdate && um.activeUpdate.state == "pending") {
+        let cacheService = Cc["@mozilla.org/network/cache-service;1"].
+                           getService(Ci.nsICacheService);
+        cacheService.evictEntries(Ci.nsICache.STORE_ANYWHERE);
+      }
+    } catch (e) { }
+#endif
     this._shutdownPlaces();
     this._idleService.removeIdleObserver(this, BOOKMARKS_BACKUP_IDLE_TIME);
     this._isIdleObserver = false;
     this._sanitizer.onShutdown();
   },
 
   // Browser startup complete. All initial windows have opened.
   _onBrowserStartup: function()
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_viewsource.js
+++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_viewsource.js
@@ -97,17 +97,16 @@ function test() {
       ww.registerNotification(observer);
 
       gBrowser.addTabsProgressListener({
         onLocationChange: function() {},
         onProgressChange: function() {},
         onSecurityChange: function() {},
         onStatusChange: function() {},
         onRefreshAttempted: function() {},
-        onLinkIconAvailable: function() {},
         onStateChange: function(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
           if (aStateFlags & (Ci.nsIWebProgressListener.STATE_STOP |
                              Ci.nsIWebProgressListener.STATE_IS_WINDOW)) {
             gBrowser.removeTabsProgressListener(this);
 
             step3();
           }
         }
--- a/browser/components/search/content/engineManager.js
+++ b/browser/components/search/content/engineManager.js
@@ -221,17 +221,17 @@ var gEngineManagerDialog = {
                                              disableButtons || lastSelected);
     document.getElementById("cmd_editkeyword").setAttribute("disabled",
                                                             noSelection);
   }
 };
 
 function onDragEngineStart(event) {
   var selectedIndex = gEngineView.selectedIndex;
-  if (selectedIndex > 0) {
+  if (selectedIndex >= 0) {
     event.dataTransfer.setData(ENGINE_FLAVOR, selectedIndex.toString());
     event.dataTransfer.effectAllowed = "move";
   }
 }
 
 // "Operation" objects
 function EngineMoveOp(aEngineClone, aNewIndex) {
   if (!aEngineClone)
--- a/browser/components/sessionstore/test/browser/browser_354894.js
+++ b/browser/components/sessionstore/test/browser/browser_354894.js
@@ -438,31 +438,63 @@ function test() {
    * @note: Non-Mac only
    */
   function testOpenCloseRestoreFromPopup(nextFn) {
     setupTestAndRun(function(newWin) {
       setupTestAndRun(function(newWin2) {
         newWin.BrowserTryToCloseWindow();
         newWin2.BrowserTryToCloseWindow();
 
+        browserWindowsCount([0, 1], "browser windows while running testOpenCloseRestoreFromPopup");
+
         newWin = undoCloseWindow(0);
+        newWin.addEventListener("load", function () {
+          info(["testOpenCloseRestoreFromPopup: newWin loaded", newWin.closed, newWin.document]);
+          var ds = newWin.delayedStartup;
+          newWin.delayedStartup = function () {
+            info(["testOpenCloseRestoreFromPopup: newWin delayedStartup", newWin.closed, newWin.document]);
+            ds.apply(newWin, arguments);
+          };
+        }, false);
+        newWin.addEventListener("unload", function () {
+          info("testOpenCloseRestoreFromPopup: newWin unloaded");
+/*
+          var data;
+          try {
+            data = Cc["@mozilla.org/browser/sessionstore;1"]
+                     .getService(Ci.nsISessionStore)
+                     .getWindowState(newWin);
+          } catch (e) { }
+          ok(!data, "getWindowState should not have data about newWin");
+*/
+        }, false);
 
         newWin2 = openDialog(location, "_blank", CHROME_FEATURES);
         newWin2.addEventListener("load", function() {
           newWin2.removeEventListener("load", arguments.callee, true);
           executeSoon(function() {
             is(newWin2.gBrowser.browsers.length, 1,
                "Did not restore, as undoCloseWindow() was last called");
             is(TEST_URLS.indexOf(newWin2.gBrowser.browsers[0].currentURI.spec), -1,
                "Did not restore, as undoCloseWindow() was last called (2)");
 
+            browserWindowsCount([2, 3], "browser windows while running testOpenCloseRestoreFromPopup");
+
+            info([newWin.closed, newWin.__SSi, newWin.__SS_restoreID, newWin.__SS_dyingCache]);
+
             // Cleanup
             newWin.close();
             newWin2.close();
 
+            info([newWin.closed, newWin.__SSi, newWin.__SS_restoreID, newWin.__SS_dyingCache]);
+
+            browserWindowsCount([0, 1], "browser windows while running testOpenCloseRestoreFromPopup");
+
+            info([newWin.closed, newWin.__SSi, newWin.__SS_restoreID, newWin.__SS_dyingCache]);
+
             // Next please
             executeSoon(nextFn);
           });
         }, true);
       });
     });
   }
 
@@ -531,17 +563,17 @@ function test() {
     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 () {
+            testOpenCloseRestoreFromPopup(function () {
               browserWindowsCount([0, 1], "browser windows after testOpenCloseRestoreFromPopup");
               testNotificationCount(function () {
                 cleanupTestsuite();
                 browserWindowsCount(1, "browser windows after testNotificationCount");
                 finish();
               });
             });
           });
--- a/browser/components/wintaskbar/WindowsJumpLists.jsm
+++ b/browser/components/wintaskbar/WindowsJumpLists.jsm
@@ -336,17 +336,17 @@ var WinTaskbarJumpList =
 
     // XXX where can we grab this from in the build? Do we need to?
     file.append("firefox.exe");
 
     var handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
                      createInstance(Ci.nsILocalHandlerApp);
     handlerApp.executable = file;
     // handlers default to the leaf name if a name is not specified
-    if (name.length != 0)
+    if (name && name.length != 0)
       handlerApp.name = name;
     handlerApp.detailedDescription = description;
     handlerApp.appendParameter(args);
 
     var item = Cc["@mozilla.org/windows-jumplistshortcut;1"].
                createInstance(Ci.nsIJumpListShortcut);
     item.app = handlerApp;
     item.iconIndex = icon;
--- a/browser/components/wintaskbar/WindowsPreviewPerTab.jsm
+++ b/browser/components/wintaskbar/WindowsPreviewPerTab.jsm
@@ -512,19 +512,19 @@ TabWindow.prototype = {
   onProgressChange: function () {
   },
   onSecurityChange: function () {
   },
   onStateChange: function () {
   },
   onStatusChange: function () {
   },
-  onLinkIconAvailable: function (aBrowser) {
+  onLinkIconAvailable: function (aBrowser, aIconURL) {
     let self = this;
-    getFaviconAsImage(aBrowser.mIconURL, function (img) {
+    getFaviconAsImage(aIconURL, function (img) {
       let index = self.tabbrowser.browsers.indexOf(aBrowser);
       // Only add it if we've found the index.  The tab could have closed!
       if (index != -1)
         self.previews[index].icon = img;
     });
   }
 }
 
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -85,17 +85,17 @@
 @BINPATH@/plugins/libnullplugin.so
 #elifdef XP_WIN32
 #ifndef WINCE
 @BINPATH@/plugins/npnul32.dll
 #endif
 #elifdef XP_OS2
 @BINPATH@/plugins/npnulos2.dll
 #endif
-@BINPATH@/@DLL_PREFIX@sqlite3@DLL_SUFFIX@
+@BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
 @BINPATH@/README.txt
 @BINPATH@/LICENSE
 @BINPATH@/blocklist.xml
 #ifdef XP_UNIX
 #ifndef XP_MACOSX
 @BINPATH@/mozilla-xremote-client
 @BINPATH@/run-mozilla.sh
 #endif
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -838,9 +838,10 @@ js3250.dll
 #endif
 #ifdef XP_WIN
 components/brwsrcmp.dll
 #endif
 #ifndef MOZ_UPDATER
 components/nsUpdateService.js
 components/nsUpdateServiceStub.js
 #endif
+@DLL_PREFIX@sqlite3@DLL_SUFFIX@
 old-homepage-default.properties
--- a/browser/themes/gnomestripe/browser/browser.css
+++ b/browser/themes/gnomestripe/browser/browser.css
@@ -551,16 +551,19 @@ toolbar[mode="full"] .toolbarbutton-menu
 }
 #stop-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-stop?size=toolbar&state=disabled");
 }
 
 #home-button {
   list-style-image: url("moz-icon://stock/gtk-home?size=toolbar");
 }
+#home-button[disabled="true"] {
+  list-style-image: url("moz-icon://stock/gtk-home?size=toolbar&state=disabled");
+}
 
 #downloads-button {
   -moz-image-region: rect(0px 24px 24px 0px);
 }
 
 #history-button {
   -moz-image-region: rect(0px 48px 24px 24px);
 }
@@ -673,16 +676,20 @@ toolbar[iconsize="small"] #reload-button
 toolbar[iconsize="small"] #reload-button[disabled="true"] {
   list-style-image: url("moz-icon://stock/gtk-refresh?size=menu&state=disabled");
 }
 
 toolbar[iconsize="small"] #home-button ,
 #home-button.bookmark-item {
   list-style-image: url("moz-icon://stock/gtk-home?size=menu");
 }
+toolbar[iconsize="small"] #home-button[disabled="true"],
+#home-button.bookmark-item[disabled="true"] {
+  list-style-image: url("moz-icon://stock/gtk-home?size=menu&state=disabled");
+}
 
 toolbar[iconsize="small"] #downloads-button {
   -moz-image-region: rect(0px 16px 16px 0px);
 }
 
 toolbar[iconsize="small"] #history-button {
   -moz-image-region: rect(0px 32px 16px 16px);
 }
--- a/browser/themes/pinstripe/browser/browser.css
+++ b/browser/themes/pinstripe/browser/browser.css
@@ -577,16 +577,19 @@ toolbar[iconsize="small"] #unified-back-
 }
 
 
 /* ----- DEFAULT HOME BUTTON ----- */	
 
 #home-button {
   -moz-image-region: rect(0px, 180px, 23px, 144px);
 }
+#home-button[disabled="true"] {
+  -moz-image-region: rect(23px, 180px, 46px, 144px) !important;
+}
 #home-button:hover:active {
   -moz-image-region: rect(46px, 180px, 69px, 144px);
 }
 
 #home-button.bookmark-item {
   list-style-image: url("chrome://browser/skin/home.png");
   -moz-image-region: rect(0px, 16px, 16px, 0px) !important;
 }
old mode 100644
new mode 100755
index 76199d9f3d88e26749cbefd7acb3814bf0d87be1..8094d8a1facd9540ad4f14b9ea1fcb794f63361c
GIT binary patch
literal 44506
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
old mode 100644
new mode 100755
index f3607750398621f20c586a144f8748d4e22063b1..9da3ea5abbdf8e354e652b8d4da8b89c06041b69
GIT binary patch
literal 16153
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
BRNw#r
old mode 100644
new mode 100755
index ef903824786d128fe3568240fe8a9bc7bc0e8fd0..c9b39175e8a0aaa57aa00751e82e2356582b756d
GIT binary patch
literal 22459
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
Shg~6n@MoZFbg5Pw7WqFqBMjI8
old mode 100644
new mode 100755
index 6535fa297d7515abfb74f34aa385f4141ecc2080..418d2e977f46ab1e8fda991b2b900baf0cdf6f07
GIT binary patch
literal 44453
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
--- a/browser/themes/winstripe/browser/browser.css
+++ b/browser/themes/winstripe/browser/browser.css
@@ -399,16 +399,19 @@ toolbar[iconsize="small"][mode="icons"] 
 /* home button */
 
 #home-button {
   -moz-image-region: rect(0px 120px 24px 96px);
 }
 #home-button:hover {
   -moz-image-region: rect(24px 120px 48px 96px);
 }
+#home-button[disabled="true"] {
+  -moz-image-region: rect(48px 120px 72px 96px);
+}
 
 /* download manager button */
 
 #downloads-button {
   -moz-image-region: rect(0px 144px 24px 120px);
 }
 #downloads-button:hover {
   -moz-image-region: rect(24px 144px 48px 120px);
@@ -594,16 +597,20 @@ toolbar[iconsize="small"] #reload-button
 toolbar[iconsize="small"] #home-button,
 #home-button.bookmark-item {
   -moz-image-region: rect(0px 80px 16px 64px);
 }
 toolbar[iconsize="small"] #home-button:hover,
 #home-button.bookmark-item:hover {
   -moz-image-region: rect(16px 80px 32px 64px);
 }
+toolbar[iconsize="small"] #home-button[disabled="true"],
+#home-button.bookmark-item[disabled="true"] {
+  -moz-image-region: rect(32px 80px 48px 64px);
+}
 
 /* download manager button */
 
 toolbar[iconsize="small"] #downloads-button {
   -moz-image-region: rect(0px 96px 16px 80px);
 }
 toolbar[iconsize="small"] #downloads-button:hover {
   -moz-image-region: rect(16px 96px 32px 80px);
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -521,25 +521,27 @@ else:
     return (f.readline(), False)
 
   def isPidAlive(pid):
     try:
       # kill(pid, 0) checks for a valid PID without actually sending a signal
       # The method throws OSError if the PID is invalid, which we catch below.
       os.kill(pid, 0)
 
-      # wait on it to see if it's a zombie
+      # Wait on it to see if it's a zombie. This can throw OSError.ECHILD if
+      # the process terminates before we get to this point.
       wpid, wstatus = os.waitpid(pid, os.WNOHANG)
       if wpid == 0:
         return True
 
       return False
     except OSError, err:
-      # Catch the one error we expect from os.kill, and re-raise any others
-      if err.errno == errno.ESRCH:
+      # Catch the errors we might expect from os.kill/os.waitpid, 
+      # and re-raise any others
+      if err.errno == errno.ESRCH or err.errno == errno.ECHILD:
         return False
       raise
 
   def killPid(pid):
     os.kill(pid, signal.SIGKILL)
 
 def triggerBreakpad(proc, utilityPath):
   """Attempt to kill this process in a way that triggers Breakpad crash
--- a/configure.in
+++ b/configure.in
@@ -4561,16 +4561,17 @@ BUILD_STATIC_LIBS=
 ENABLE_TESTS=1
 MOZ_ACTIVEX_SCRIPTING_SUPPORT=
 MOZ_BRANDING_DIRECTORY=
 MOZ_OFFICIAL_BRANDING=
 MOZ_DBGRINFO_MODULES=
 MOZ_FEEDS=1
 MOZ_IMG_DECODERS_DEFAULT="png gif jpeg bmp icon"
 MOZ_IMG_ENCODERS_DEFAULT="png jpeg"
+MOZ_IPC=1
 MOZ_JAVAXPCOM=
 MOZ_JSDEBUGGER=1
 MOZ_JSLOADER=1
 MOZ_MATHML=1
 MOZ_MORK=1
 MOZ_MORKREADER=
 MOZ_AUTH_EXTENSION=1
 MOZ_NO_ACTIVEX_SUPPORT=1
@@ -5289,23 +5290,21 @@ MOZ_ARG_DISABLE_BOOL(jsd,
 [  --disable-jsd           Disable JavaScript debug library],
     MOZ_JSDEBUGGER=,
     MOZ_JSDEBUGGER=1)
 
 
 dnl ========================================================
 dnl = Disable IPC support for tabs and plugins
 dnl ========================================================
-MOZ_IPC=1
-
 case "${target}" in
 *-apple-darwin*)
     MOZ_IPC=
     ;;
-*wince)
+*-wince*)
     MOZ_IPC=
     ;;
 esac
 
 MOZ_ARG_DISABLE_BOOL(ipc,
 [  --disable-ipc           Disable IPC supports for tabs and plugins],
     MOZ_IPC=,
     MOZ_IPC=1)
@@ -6178,17 +6177,17 @@ MOZ_NATIVE_SQLITE=
 MOZ_ARG_ENABLE_BOOL(system-sqlite,
 [  --enable-system-sqlite  Use system sqlite (located with pkgconfig)],
 MOZ_NATIVE_SQLITE=1,
 MOZ_NATIVE_SQLITE= )
 
 if test -z "$MOZ_NATIVE_SQLITE"
 then
     SQLITE_CFLAGS=
-    SQLITE_LIBS='$(call EXPAND_LIBNAME_PATH,sqlite3,$(DIST)/lib)'
+    SQLITE_LIBS='$(call EXPAND_LIBNAME_PATH,mozsqlite3,$(DIST)/lib)'
 else
     PKG_CHECK_MODULES(SQLITE, sqlite3 >= $SQLITE_VERSION)
 fi
 
 AC_SUBST(MOZ_NATIVE_SQLITE)
 
 dnl ========================================================
 dnl = Enable help viewer (off by default)
--- a/content/base/src/nsCrossSiteListenerProxy.cpp
+++ b/content/base/src/nsCrossSiteListenerProxy.cpp
@@ -240,17 +240,23 @@ nsCrossSiteListenerProxy::CheckRequestAp
   NS_ENSURE_TRUE(http, NS_ERROR_DOM_BAD_URI);
 
   // Redirects aren't success-codes. But necko already checked that it was a
   // valid redirect.
   if (!aIsRedirect) {
     PRBool succeeded;
     rv = http->GetRequestSucceeded(&succeeded);
     NS_ENSURE_SUCCESS(rv, rv);
-    NS_ENSURE_TRUE(succeeded, NS_ERROR_DOM_BAD_URI);
+    if (!succeeded) {
+      PRUint32 responseStatus;
+      rv = http->GetResponseStatus(&responseStatus);
+      NS_ENSURE_SUCCESS(rv, rv);
+      NS_ENSURE_TRUE(mAllowedHTTPErrors.Contains(responseStatus),
+                     NS_ERROR_DOM_BAD_URI);
+    }
   }
 
   // Check the Access-Control-Allow-Origin header
   nsCAutoString allowedOriginHeader;
   rv = http->GetResponseHeader(
     NS_LITERAL_CSTRING("Access-Control-Allow-Origin"), allowedOriginHeader);
   NS_ENSURE_SUCCESS(rv, rv);
 
--- a/content/base/src/nsCrossSiteListenerProxy.h
+++ b/content/base/src/nsCrossSiteListenerProxy.h
@@ -76,24 +76,30 @@ public:
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIINTERFACEREQUESTOR
   NS_DECL_NSICHANNELEVENTSINK
 
   // Must be called at startup.
   static void Startup();
 
+  void AllowHTTPResult(PRUint32 aResultCode)
+  {
+    mAllowedHTTPErrors.AppendElement(aResultCode);
+  }
+
 private:
   nsresult UpdateChannel(nsIChannel* aChannel);
   nsresult CheckRequestApproved(nsIRequest* aRequest, PRBool aIsRedirect);
 
   nsCOMPtr<nsIStreamListener> mOuterListener;
   nsCOMPtr<nsIPrincipal> mRequestingPrincipal;
   nsCOMPtr<nsIInterfaceRequestor> mOuterNotificationCallbacks;
   PRBool mWithCredentials;
   PRBool mRequestApproved;
   PRBool mHasBeenCrossSite;
   PRBool mIsPreflight;
   nsCString mPreflightMethod;
   nsTArray<nsCString> mPreflightHeaders;
+  nsTArray<PRUint32> mAllowedHTTPErrors;
 };
 
 #endif
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -626,23 +626,26 @@ nsresult nsHTMLMediaElement::LoadResourc
   // after it is finished with the element.
   nsRefPtr<MediaLoadListener> loadListener = new MediaLoadListener(this);
   if (!loadListener) return NS_ERROR_OUT_OF_MEMORY;
 
   mChannel->SetNotificationCallbacks(loadListener);
 
   nsCOMPtr<nsIStreamListener> listener;
   if (ShouldCheckAllowOrigin()) {
-    listener = new nsCrossSiteListenerProxy(loadListener,
-                                            NodePrincipal(),
-                                            mChannel,
-                                            PR_FALSE,
-                                            &rv);
-    NS_ENSURE_SUCCESS(rv,rv);
-    if (!listener) return NS_ERROR_OUT_OF_MEMORY;
+    nsCrossSiteListenerProxy* crossSiteListener =
+      new nsCrossSiteListenerProxy(loadListener,
+                                   NodePrincipal(),
+                                   mChannel,
+                                   PR_FALSE,
+                                   &rv);
+    listener = crossSiteListener;
+    NS_ENSURE_TRUE(crossSiteListener, NS_ERROR_OUT_OF_MEMORY);
+    NS_ENSURE_SUCCESS(rv, rv);
+    crossSiteListener->AllowHTTPResult(HTTP_REQUESTED_RANGE_NOT_SATISFIABLE_CODE);
   } else {
     rv = nsContentUtils::GetSecurityManager()->
            CheckLoadURIWithPrincipal(NodePrincipal(),
                                      aURI,
                                      nsIScriptSecurityManager::STANDARD);
     NS_ENSURE_SUCCESS(rv,rv);
     listener = loadListener;
   }
--- a/content/media/nsMediaStream.cpp
+++ b/content/media/nsMediaStream.cpp
@@ -54,17 +54,16 @@
 #include "nsHTMLMediaElement.h"
 #include "nsIDocument.h"
 #include "nsDOMError.h"
 #include "nsICachingChannel.h"
 #include "nsURILoader.h"
 
 #define HTTP_OK_CODE 200
 #define HTTP_PARTIAL_RESPONSE_CODE 206
-#define HTTP_REQUESTED_RANGE_NOT_SATISFIABLE_CODE 416
 
 using mozilla::TimeStamp;
 
 nsMediaChannelStream::nsMediaChannelStream(nsMediaDecoder* aDecoder,
     nsIChannel* aChannel, nsIURI* aURI)
   : nsMediaStream(aDecoder, aChannel, aURI),
     mOffset(0), mSuspendCount(0),
     mReopenOnError(PR_FALSE), mIgnoreClose(PR_FALSE),
@@ -420,23 +419,26 @@ nsresult nsMediaChannelStream::OpenChann
     nsCOMPtr<nsIStreamListener> listener = mListener.get();
 
     // Ensure that if we're loading cross domain, that the server is sending
     // an authorizing Access-Control header.
     nsHTMLMediaElement* element = mDecoder->GetMediaElement();
     NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
     if (element->ShouldCheckAllowOrigin()) {
       nsresult rv;
-      listener = new nsCrossSiteListenerProxy(mListener,
-                                              element->NodePrincipal(),
-                                              mChannel,
-                                              PR_FALSE,
-                                              &rv);
-      NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
+      nsCrossSiteListenerProxy* crossSiteListener =
+        new nsCrossSiteListenerProxy(mListener,
+                                     element->NodePrincipal(),
+                                     mChannel,
+                                     PR_FALSE,
+                                     &rv);
+      listener = crossSiteListener;
+      NS_ENSURE_TRUE(crossSiteListener, NS_ERROR_OUT_OF_MEMORY);
       NS_ENSURE_SUCCESS(rv, rv);
+      crossSiteListener->AllowHTTPResult(HTTP_REQUESTED_RANGE_NOT_SATISFIABLE_CODE);
     } else {
       nsresult rv = nsContentUtils::GetSecurityManager()->
         CheckLoadURIWithPrincipal(element->NodePrincipal(),
                                   mURI,
                                   nsIScriptSecurityManager::STANDARD);
       NS_ENSURE_SUCCESS(rv, rv);
     }
 
--- a/content/media/nsMediaStream.h
+++ b/content/media/nsMediaStream.h
@@ -48,16 +48,18 @@
 #include "prlock.h"
 #include "nsMediaCache.h"
 
 // For HTTP seeking, if number of bytes needing to be
 // seeked forward is less than this value then a read is
 // done rather than a byte range request.
 #define SEEK_VS_READ_THRESHOLD (32*1024)
 
+#define HTTP_REQUESTED_RANGE_NOT_SATISFIABLE_CODE 416
+
 class nsMediaDecoder;
 
 /**
  * This class is useful for estimating rates of data passing through
  * some channel. The idea is that activity on the channel "starts"
  * and "stops" over time. At certain times data passes through the
  * channel (usually while the channel is active; data passing through
  * an inactive channel is ignored). The GetRate() function computes
--- a/content/media/test/Makefile.in
+++ b/content/media/test/Makefile.in
@@ -174,16 +174,17 @@ endif
 		$(NULL)
 
 # These tests need to be converted to be backend-independent. This list
 # is deprecated, do not add to it.
 ifdef MOZ_OGG
 _TEST_FILES += \
 		dynamic_redirect.sjs \
 		file_access_controls.html \
+		test_access_control.html \
 		test_bug448534.html \
 		test_bug468190.html \
 		test_bug486646.html \
 		test_bug493187.html \
 		test_bug495145.html \
 		test_bug495319.html \
 		test_closing_connections.html \
 		test_contentDuration1.html \
@@ -222,17 +223,16 @@ ifdef MOZ_OGG
 # test_videoDocumentTitle.html
 # Bug 493692:
 # test_autobuffer2.html
 ifneq ($(OS_ARCH),WINNT)
 # These tests are disabled on windows until we
 # figure out the random failures. See bug 475369 and bug 526323
 _TEST_FILES += \
 		test_timeupdate3.html \
-		test_access_control.html \
 		$(NULL)
 endif
 endif
 
 ifdef MOZ_OGG
 _TEST_FILES += \
 		test_can_play_type_ogg.html \
 		$(NULL)
--- a/content/media/test/file_access_controls.html
+++ b/content/media/test/file_access_controls.html
@@ -10,90 +10,91 @@ var gTests = [
   {
     // Test 0
     url: "redirect.sjs?http://example.com/tests/content/media/test/320x240.ogv",
     result: "error",
     description: "Won't load when redirected to different domain",
   },{
     // Test 1
     url: "redirect.sjs?http://example.com/tests/content/media/test/320x240.allow-origin.ogv",
-    result: "loaded",
+    result: "loadeddata",
     description: "Can load when redirected to different domain with allow-origin",
   },{
     // Test 2
     url: "redirect.sjs?http://test1.example.org/tests/content/media/test/320x240.ogv",
     result: "error",
     description: "Won't load when redirected to subdomain",
   },{
     // Test 3
     url: "redirect.sjs?http://test1.example.org/tests/content/media/test/320x240.allow-origin.ogv",
-    result: "loaded",
+    result: "loadeddata",
     description: "Can load when redirected to subdomain with allow-origin",
   },{
     // Test 4
     url: "redirect.sjs?http://example.org/tests/content/media/test/320x240.ogv",
-    result: "loaded",
+    result: "loadeddata",
     description: "Can load when redirected to same domain",
   },{
     // Test 5
     url: "http://example.org/tests/content/media/test/320x240.ogv",
-    result: "loaded",
+    result: "loadeddata",
     description: "Can load from same domain"
   },{
     // Test 6
     url: "http://example.org:8000/tests/content/media/test/320x240.ogv",
     result: "error",
     description: "Won't load from differnet port on same domain"
   },{
     // Test 7
     url: "http://example.org:8000/tests/content/media/test/320x240.allow-origin.ogv",
-    result: "loaded",
+    result: "loadeddata",
     description: "Can load from different port on same domain with allow-origin",
   },{
     // Test 8
     url: "http://example.com/tests/content/media/test/320x240.ogv",
     result: "error",
     description: "Won't load cross domain",
   },{
     // Test 9
     url: "http://example.com/tests/content/media/test/320x240.allow-origin.ogv",
-    result: "loaded",
+    result: "loadeddata",
     description: "Can load cross domain with allow-origin",
   },{
     // Test 10
     url: "http://test1.example.org/tests/content/media/test/320x240.allow-origin.ogv",
-    result: "loaded",
+    result: "loadeddata",
     description: "Can load from subdomain with allow-origin",
   },{
     // Test 11
     url: "http://test1.example.org/tests/content/media/test/320x240.ogv",
     result: "error",
     description: "Won't load from subdomain",
   }
 ];
 
 var gTestNum = 0;
-var gExpectedResult = null;
-var gTestDescription = null;
 var gVideo = null;
 var gTestedRemoved = false;
 var gOldPref;
 
-function result(code) {
-  //dump((gTestNum - 1) + ": " + code + "\n");
+function eventHandler(event) {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-  opener.is(code, gExpectedResult, gTestDescription);
+  //dump((gTestNum - 1) + ": " + event.type + "\n");
+  var video = event.target;
+  opener.is(event.type, video.expectedResult, video.testDescription +
+    (gTestedRemoved ? " (element not in document)" : " (element in document)"));
+  // Make sure any extra events cause an error
+  video.expectedResult = "<none>";
   nextTest();
 }
 
 function createVideo() {
   var v = document.createElement('video');
-  v.addEventListener('loadeddata', function(){result('loaded');}, false);
-  v.addEventListener('error', function(){result('error');}, false);
-  v.id = 'video';
+  v.addEventListener('loadeddata', eventHandler, false);
+  v.addEventListener('error', eventHandler, false);
   return v;
 }
 
 function load() {
   netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   opener.is(window.location.href,
             "http://example.org/tests/content/media/test/file_access_controls.html",
             "We must be on a example.org:80");
@@ -107,39 +108,38 @@ function load() {
   opener.ok(branch!=null, "Get media pref branch");
   gOldPref = branch.getBoolPref("enforce_same_site_origin");
   branch.setBoolPref("enforce_same_site_origin", true);
   nextTest();
 }
 
 function nextTest() {
   //dump("nextTest() called, gTestNum="+gTestNum+" gTestedRemoved="+gTestedRemoved+"\n");
-  netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
   if (gTestNum == gTests.length) {
     //dump("gTestNum == gTests.length\n");
     if (!gTestedRemoved) {
       // Repeat all tests with element removed from doc, should get same result.
       gTestedRemoved = true;
       gTestNum = 0;
     } else {
       //dump("Exiting...\n");
       // We're done, exit the test.
       window.close();
       return;
     }
   }
-  gExpectedResult = gTests[gTestNum].result;
-  gTestDescription = gTests[gTestNum].description;
-  //dump("Starting test " + gTestNum + " at " + gTests[gTestNum].url + " expecting:" + gExpectedResult + "\n");
 
   if (gVideo && gVideo.parentNode)
     gVideo.parentNode.removeChild(gVideo);
   
   gVideo = createVideo();
+  gVideo.expectedResult = gTests[gTestNum].result;
+  gVideo.testDescription = gTests[gTestNum].description;
   gVideo.src = gTests[gTestNum].url;
+  //dump("Starting test " + gTestNum + " at " + gVideo.src + " expecting:" + gVideo.expectedResult + "\n");
   if (!gTestedRemoved) {
     document.body.appendChild(gVideo); 
     // Will cause load() to be invoked.
   } else {
     gVideo.load();
   }
   gTestNum++;
 }
--- a/content/xul/templates/src/nsXULTemplateBuilder.cpp
+++ b/content/xul/templates/src/nsXULTemplateBuilder.cpp
@@ -1865,19 +1865,21 @@ nsXULTemplateBuilder::CompileTemplate(ns
         if (ni->Equals(nsGkAtoms::rule, kNameSpaceID_XUL)) {
             nsCOMPtr<nsIContent> action;
             nsXULContentUtils::FindChildByTag(rulenode,
                                               kNameSpaceID_XUL,
                                               nsGkAtoms::action,
                                               getter_AddRefs(action));
 
             if (action){
-                nsCOMPtr<nsIAtom> memberVariable;
-                DetermineMemberVariable(action, getter_AddRefs(memberVariable));
-                if (! memberVariable) continue;
+                nsCOMPtr<nsIAtom> memberVariable = mMemberVariable;
+                if (!memberVariable) {
+                    memberVariable = DetermineMemberVariable(action);
+                    if (!memberVariable) continue;
+                }
 
                 if (hasQuery) {
                     nsCOMPtr<nsIAtom> tag;
                     DetermineRDFQueryRef(aQuerySet->mQueryNode,
                                          getter_AddRefs(tag));
                     if (tag)
                         aQuerySet->SetTag(tag);
 
@@ -1989,19 +1991,21 @@ nsXULTemplateBuilder::CompileTemplate(ns
             if (! hasQuery)
                 continue;
 
             nsCOMPtr<nsIAtom> tag;
             DetermineRDFQueryRef(aQuerySet->mQueryNode, getter_AddRefs(tag));
             if (tag)
                 aQuerySet->SetTag(tag);
 
-            nsCOMPtr<nsIAtom> memberVariable;
-            DetermineMemberVariable(rulenode, getter_AddRefs(memberVariable));
-            if (! memberVariable) continue;
+            nsCOMPtr<nsIAtom> memberVariable = mMemberVariable;
+            if (!memberVariable) {
+                memberVariable = DetermineMemberVariable(rulenode);
+                if (!memberVariable) continue;
+            }
 
             nsCOMPtr<nsIDOMNode> query(do_QueryInterface(aQuerySet->mQueryNode));
 
             rv = mQueryProcessor->CompileQuery(this, query,
                                                mRefVariable, memberVariable,
                                                getter_AddRefs(aQuerySet->mCompiledQuery));
 
             if (aQuerySet->mCompiledQuery) {
@@ -2072,63 +2076,36 @@ nsXULTemplateBuilder::CompileExtendedQue
         bindings = aRuleElement;
 
     rv = CompileBindings(rule, bindings);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
 }
 
-nsresult
-nsXULTemplateBuilder::DetermineMemberVariable(nsIContent* aActionElement,
-                                              nsIAtom** aMemberVariable)
+already_AddRefed<nsIAtom>
+nsXULTemplateBuilder::DetermineMemberVariable(nsIContent* aElement)
 {
-    // If the member variable hasn't already been specified, then
-    // grovel over <action> to find it. We'll use the first one
-    // that we find in a breadth-first search.
-
-    if (mMemberVariable) {
-        *aMemberVariable = mMemberVariable;
-        NS_IF_ADDREF(*aMemberVariable);
-    }
-    else {
-        *aMemberVariable = nsnull;
-
-        nsCOMArray<nsIContent> unvisited;
-
-        if (!unvisited.AppendObject(aActionElement))
-            return NS_ERROR_OUT_OF_MEMORY;
-
-        while (unvisited.Count()) {
-            nsIContent* next = unvisited[0];
-            unvisited.RemoveObjectAt(0);
-
-            nsAutoString uri;
-            next->GetAttr(kNameSpaceID_None, nsGkAtoms::uri, uri);
-
-            if (!uri.IsEmpty() && uri[0] == PRUnichar('?')) {
-                // Found it.
-                *aMemberVariable = NS_NewAtom(uri);
-                break;
-            }
-
-            // otherwise, append the children to the unvisited list: this
-            // results in a breadth-first search.
-            PRUint32 count = next->GetChildCount();
-
-            for (PRUint32 i = 0; i < count; ++i) {
-                nsIContent *child = next->GetChildAt(i);
-
-                if (!unvisited.AppendObject(child))
-                    return NS_ERROR_OUT_OF_MEMORY;
-            }
+    // recursively iterate over the children looking for an element
+    // with uri="?..."
+    for (nsINode::ChildIterator iter(aElement); !iter.IsDone(); iter.Next()) {
+        nsAutoString uri;
+        nsIContent *child = iter;
+        child->GetAttr(kNameSpaceID_None, nsGkAtoms::uri, uri);
+        if (!uri.IsEmpty() && uri[0] == PRUnichar('?')) {
+            return NS_NewAtom(uri);
+        }
+
+        nsCOMPtr<nsIAtom> result = DetermineMemberVariable(child);
+        if (result) {
+            return result.forget();
         }
     }
 
-    return NS_OK;
+    return nsnull;
 }
 
 void
 nsXULTemplateBuilder::DetermineRDFQueryRef(nsIContent* aQueryElement, nsIAtom** aTag)
 {
     // check for a tag
     nsCOMPtr<nsIContent> content;
     nsXULContentUtils::FindChildByTag(aQueryElement,
--- a/content/xul/templates/src/nsXULTemplateBuilder.h
+++ b/content/xul/templates/src/nsXULTemplateBuilder.h
@@ -207,18 +207,17 @@ public:
      * Determine the ref variable and tag from inside a RDF query.
      */
     void DetermineRDFQueryRef(nsIContent* aQueryElement, nsIAtom** tag);
 
     /**
      * Determine the member variable from inside an action body. It will be
      * the value of the uri attribute on a node.
      */
-    nsresult
-    DetermineMemberVariable(nsIContent* aActionElement, nsIAtom** aMemberVariable);
+    already_AddRefed<nsIAtom> DetermineMemberVariable(nsIContent* aElement);
 
     /**
      * Compile a simple query. A simple query is one that doesn't have a
      * <query> and should use a default query which would normally just return
      * a list of children of the reference point.
      *
      * @param aRuleElement the <rule>
      * @param aQuerySet the query set
--- a/db/sqlite3/src/Makefile.in
+++ b/db/sqlite3/src/Makefile.in
@@ -41,17 +41,17 @@
 DEPTH		= ../../..
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE           = sqlite3
-LIBRARY_NAME     = sqlite3
+LIBRARY_NAME     = mozsqlite3
 FORCE_SHARED_LIB = 1
 VISIBILITY_FLAGS =
 LIB_IS_C_ONLY    = 1
 
 ifeq (,$(filter-out WINNT WINCE,$(OS_ARCH)))
 ifndef GNU_CC
 DEFFILE = $(CURDIR)/sqlite-processed.def
 RCFILE  = sqlite.rc
--- a/db/sqlite3/src/sqlite.def
+++ b/db/sqlite3/src/sqlite.def
@@ -28,17 +28,17 @@
 ; 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 *****
 
-LIBRARY sqlite3.dll
+LIBRARY mozsqlite3.dll
 
 EXPORTS
         sqlite3_aggregate_context
         sqlite3_aggregate_count
         sqlite3_auto_extension
         sqlite3_bind_blob
         sqlite3_bind_double
         sqlite3_bind_int
--- a/docshell/resources/content/netError.xhtml
+++ b/docshell/resources/content/netError.xhtml
@@ -58,17 +58,17 @@
 <html xmlns="http://www.w3.org/1999/xhtml">
   <head>
     <title>&loadError.label;</title>
     <link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all" />
     <!-- If the location of the favicon is changed here, the FAVICON_ERRORPAGE_URL symbol in
          toolkit/components/places/src/nsFaviconService.h should be updated. -->
     <link rel="icon" type="image/png" id="favicon" href="chrome://global/skin/icons/warning-16.png"/>
 
-    <script type="application/x-javascript"><![CDATA[
+    <script type="application/javascript"><![CDATA[
       // Error url MUST be formatted like this:
       //   moz-neterror:page?e=error&u=url&d=desc
       //
       // or optionally, to specify an alternate CSS class to allow for
       // custom styling and favicon:
       //
       //   moz-neterror:page?e=error&u=url&s=classname&d=desc
 
@@ -371,12 +371,12 @@
 
     </div>
 
     <!--
     - Note: It is important to run the script this way, instead of using
     - an onload handler. This is because error pages are loaded as
     - LOAD_BACKGROUND, which means that onload handlers will not be executed.
     -->
-    <script type="application/x-javascript">initPage();</script>
+    <script type="application/javascript">initPage();</script>
 
   </body>
 </html>
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -414,16 +414,17 @@ public:
 
   NS_IMETHOD GetURL(const char *aURL, const char *aTarget, void *aPostData,
                     PRUint32 aPostDataLen, void *aHeadersData,
                     PRUint32 aHeadersDataLen, PRBool aIsFile = PR_FALSE);
   NS_IMETHOD ShowStatus(const PRUnichar *aStatusMsg);
   NPError ShowNativeContextMenu(NPMenu* menu, void* event);
   NPBool ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
                       double *destX, double *destY, NPCoordinateSpace destSpace);
+  void SendIdleEvent();
 
   NS_DECL_CYCLE_COLLECTION_CLASS(nsDummyJavaPluginOwner)
 
 private:
   nsCOMPtr<nsIPluginInstance> mInstance;
   nsCOMPtr<nsIDocument> mDocument;
 };
 
@@ -558,16 +559,21 @@ nsDummyJavaPluginOwner::GetNetscapeWindo
 }
 
 NS_IMETHODIMP
 nsDummyJavaPluginOwner::SetEventModel(PRInt32 eventModel)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
+void
+nsDummyJavaPluginOwner::SendIdleEvent()
+{
+}
+
 /**
  * An indirect observer object that means we don't have to implement nsIObserver
  * on nsGlobalWindow, where any script could see it.
  */
 class nsGlobalWindowObserver : public nsIObserver {
 public:
   nsGlobalWindowObserver(nsGlobalWindow* aWindow) : mWindow(aWindow) {}
   NS_DECL_ISUPPORTS
--- a/dom/plugins/NPEventWindows.h
+++ b/dom/plugins/NPEventWindows.h
@@ -46,17 +46,17 @@ namespace mozilla {
 namespace plugins {
 
 // We use an NPRemoteEvent struct so that we can store the extra data on
 // the stack so that we don't need to worry about managing the memory.
 struct NPRemoteEvent
 {
     NPEvent event;
     union {
-        NPRect rect;
+        RECT rect;
         WINDOWPOS windowpos;
     } lParamData;
 };
 
 }
 
 }
 
@@ -82,19 +82,19 @@ struct ParamTraits<mozilla::plugins::NPR
         switch (paramCopy.event.event) {
             case WM_WINDOWPOSCHANGED:
                 // The lParam paramter of WM_WINDOWPOSCHANGED holds a pointer to
                 // a WINDOWPOS structure that contains information about the
                 // window's new size and position
                 paramCopy.lParamData.windowpos = *(reinterpret_cast<WINDOWPOS*>(paramCopy.event.lParam));
                 break;
             case WM_PAINT:
-                // The lParam paramter of WM_PAINT holds a pointer to an NPRect
+                // The lParam paramter of WM_PAINT holds a pointer to an RECT
                 // structure specifying the bounding box of the update area.
-                paramCopy.lParamData.rect = *(reinterpret_cast<NPRect*>(paramCopy.event.lParam));
+                paramCopy.lParamData.rect = *(reinterpret_cast<RECT*>(paramCopy.event.lParam));
                 break;
 
             // the white list of events that we will ipc to the client
             case WM_CHAR:
             case WM_SYSCHAR:
 
             case WM_KEYUP:
             case WM_SYSKEYUP:
@@ -122,35 +122,39 @@ struct ParamTraits<mozilla::plugins::NPR
             case WM_LBUTTONDBLCLK:
             case WM_MBUTTONDBLCLK:
             case WM_RBUTTONDBLCLK:
 
             case WM_SETFOCUS:
             case WM_KILLFOCUS:
                 break;
 
-            // ignore any events we don't expect
             default:
+                // RegisterWindowMessage events should be passed.
+                if (paramCopy.event.event >= 0xC000 && paramCopy.event.event <= 0xFFFF)
+                    break;
+
+                // ignore any events we don't expect
                 return;
         }
 
         aMsg->WriteBytes(&paramCopy, sizeof(paramType));
     }
 
     static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
     {
         const char* bytes = 0;
 
         if (!aMsg->ReadBytes(aIter, &bytes, sizeof(paramType))) {
             return false;
         }
         memcpy(aResult, bytes, sizeof(paramType));
 
         if (aResult->event.event == WM_PAINT) {
-            // restore the lParam to point at the NPRect
+            // restore the lParam to point at the RECT
             aResult->event.lParam = reinterpret_cast<LPARAM>(&aResult->lParamData.rect);
         } else if (aResult->event.event == WM_WINDOWPOSCHANGED) {
             // restore the lParam to point at the WINDOWPOS
             aResult->event.lParam = reinterpret_cast<LPARAM>(&aResult->lParamData.windowpos);
         }
 
         return true;
     }
--- a/dom/plugins/PluginInstanceChild.cpp
+++ b/dom/plugins/PluginInstanceChild.cpp
@@ -54,16 +54,17 @@ using namespace mozilla::plugins;
 #include <gdk/gdk.h>
 #include "gtk2xtbin.h"
 
 #elif defined(OS_WIN)
 using mozilla::gfx::SharedDIB;
 
 #include <windows.h>
 
+#define NS_OOPP_DOUBLEPASS_MSGID TEXT("MozDoublePassMsg")
 #endif
 
 PluginInstanceChild::PluginInstanceChild(const NPPluginFuncs* aPluginIface) :
         mPluginIface(aPluginIface)
 #if defined(OS_WIN)
         , mPluginWindowHWND(0)
         , mPluginWndProc(0)
         , mPluginParentHWND(0)
@@ -73,16 +74,20 @@ PluginInstanceChild::PluginInstanceChild
         mData.ndata = (void*) this;
 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
         mWindow.ws_info = &mWsInfo;
         memset(&mWsInfo, 0, sizeof(mWsInfo));
 #  ifdef MOZ_WIDGET_GTK2
         mWsInfo.display = GDK_DISPLAY();
 #  endif
 #endif
+#if defined(OS_WIN)
+    memset(&mAlphaExtract, 0, sizeof(mAlphaExtract));
+    mAlphaExtract.doublePassEvent = ::RegisterWindowMessage(NS_OOPP_DOUBLEPASS_MSGID);
+#endif
     }
 
 PluginInstanceChild::~PluginInstanceChild()
 {
 #if defined(OS_WIN)
   DestroyPluginWindow();
 #endif
 }
@@ -337,19 +342,31 @@ PluginInstanceChild::AnswerNPP_HandleEve
         printf("  received drawable 0x%lx\n",
                event.event.xgraphicsexpose.drawable);
 #endif
 
     // Make a copy since we may modify values.
     NPEvent evcopy = event.event;
 
 #ifdef OS_WIN
-    // Setup the shared dib for painting and update evcopy.
-    if (NPWindowTypeDrawable == mWindow.type && WM_PAINT == evcopy.event)
-        SharedSurfaceBeforePaint(evcopy);
+    // Painting for win32. SharedSurfacePaint handles everything.
+    if (mWindow.type == NPWindowTypeDrawable) {
+       if (evcopy.event == WM_PAINT) {
+          *handled = SharedSurfacePaint(evcopy);
+          return true;
+       }
+       else if (evcopy.event == mAlphaExtract.doublePassEvent) {
+            // We'll render to mSharedSurfaceDib first, then render to a cached bitmap
+            // we store locally. The two passes are for alpha extraction, so the second
+            // pass must be to a flat white surface in order for things to work.
+            mAlphaExtract.doublePass = RENDER_BACK_ONE;
+            *handled = true;
+            return true;
+       }
+    }
 #endif
 
     *handled = mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy));
 
 #ifdef MOZ_X11
     if (GraphicsExpose == event.event.type) {
         // Make sure the X server completes the drawing before the parent
         // draws on top and destroys the Drawable.
@@ -670,16 +687,19 @@ PluginInstanceChild::SharedSurfaceSetWin
             return false;
         }
     }
     else {
         // Attach to the new shared surface parent handed us.
         if (NS_FAILED(mSharedSurfaceDib.Attach((SharedDIB::Handle)aWindow.surfaceHandle,
                                                aWindow.width, aWindow.height, 32)))
           return false;
+        // Free any alpha extraction resources if needed. This will be reset
+        // the next time it's used.
+        AlphaExtractCacheRelease();
     }
       
     // NPRemoteWindow's origin is the origin of our shared dib.
     mWindow.x      = 0;
     mWindow.y      = 0;
     mWindow.width  = aWindow.width;
     mWindow.height = aWindow.height;
     mWindow.type   = aWindow.type;
@@ -689,30 +709,147 @@ PluginInstanceChild::SharedSurfaceSetWin
 
     return true;
 }
 
 void
 PluginInstanceChild::SharedSurfaceRelease()
 {
     mSharedSurfaceDib.Close();
+    AlphaExtractCacheRelease();
+}
+
+/* double pass cache buffer - (rarely) used in cases where alpha extraction
+ * occurs for windowless plugins. */
+ 
+bool
+PluginInstanceChild::AlphaExtractCacheSetup()
+{
+    AlphaExtractCacheRelease();
+
+    mAlphaExtract.hdc = ::CreateCompatibleDC(NULL);
+
+    if (!mAlphaExtract.hdc)
+        return false;
+
+    BITMAPINFOHEADER bmih;
+    memset((void*)&bmih, 0, sizeof(BITMAPINFOHEADER));
+    bmih.biSize        = sizeof(BITMAPINFOHEADER);
+    bmih.biWidth       = mWindow.width;
+    bmih.biHeight      = mWindow.height;
+    bmih.biPlanes      = 1;
+    bmih.biBitCount    = 32;
+    bmih.biCompression = BI_RGB;
+
+    void* ppvBits = nsnull;
+    mAlphaExtract.bmp = ::CreateDIBSection(mAlphaExtract.hdc,
+                                           (BITMAPINFO*)&bmih,
+                                           DIB_RGB_COLORS,
+                                           (void**)&ppvBits,
+                                           NULL,
+                                           (unsigned long)sizeof(BITMAPINFOHEADER));
+    if (!mAlphaExtract.bmp)
+      return false;
+
+    DeleteObject(::SelectObject(mAlphaExtract.hdc, mAlphaExtract.bmp));
+    return true;
+}
+
+void
+PluginInstanceChild::AlphaExtractCacheRelease()
+{
+    if (mAlphaExtract.bmp)
+        ::DeleteObject(mAlphaExtract.bmp);
+
+    if (mAlphaExtract.hdc)
+        ::DeleteObject(mAlphaExtract.hdc);
+
+    mAlphaExtract.bmp = NULL;
+    mAlphaExtract.hdc = NULL;
 }
 
 void
-PluginInstanceChild::SharedSurfaceBeforePaint(NPEvent& evcopy)
+PluginInstanceChild::UpdatePaintClipRect(RECT* aRect)
 {
-    // Update the clip rect on our internal hdc
+    if (aRect) {
+        // Update the clip rect on our internal hdc
+        HRGN clip = ::CreateRectRgnIndirect(aRect);
+        ::SelectClipRgn(mSharedSurfaceDib.GetHDC(), clip);
+        ::DeleteObject(clip);
+    }
+}
+
+int16_t
+PluginInstanceChild::SharedSurfacePaint(NPEvent& evcopy)
+{
     RECT* pRect = reinterpret_cast<RECT*>(evcopy.lParam);
-    if (pRect) {
-      HRGN clip = ::CreateRectRgnIndirect(pRect);
-      ::SelectClipRgn(mSharedSurfaceDib.GetHDC(), clip);
-      ::DeleteObject(clip);
+
+    switch(mAlphaExtract.doublePass) {
+        case RENDER_NATIVE:
+            // pass the internal hdc to the plugin
+            UpdatePaintClipRect(pRect);
+            evcopy.wParam = WPARAM(mSharedSurfaceDib.GetHDC());
+            return mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy));
+        break;
+        case RENDER_BACK_ONE:
+              // Handle a double pass render used in alpha extraction for transparent
+              // plugins. (See nsObjectFrame and gfxWindowsNativeDrawing for details.)
+              // We render twice, once to the shared dib, and once to a cache which
+              // we copy back on a second paint. These paints can't be spread across
+              // multiple rpc messages as delays cause animation frame changes.
+              if (!mAlphaExtract.bmp && !AlphaExtractCacheSetup()) {
+                  mAlphaExtract.doublePass = RENDER_NATIVE;
+                  return false;
+              }
+
+              // See gfxWindowsNativeDrawing, color order doesn't have to match.
+              ::FillRect(mSharedSurfaceDib.GetHDC(), pRect, (HBRUSH)GetStockObject(WHITE_BRUSH));
+              UpdatePaintClipRect(pRect);
+              evcopy.wParam = WPARAM(mSharedSurfaceDib.GetHDC());
+              if (!mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy))) {
+                  mAlphaExtract.doublePass = RENDER_NATIVE;
+                  return false;
+              }
+
+              // Copy to cache. We render to shared dib so we don't have to call
+              // setwindow between calls (flash issue).  
+              ::BitBlt(mAlphaExtract.hdc,
+                       pRect->left,
+                       pRect->top,
+                       pRect->right - pRect->left,
+                       pRect->bottom - pRect->top,
+                       mSharedSurfaceDib.GetHDC(),
+                       pRect->left,
+                       pRect->top,
+                       SRCCOPY);
+
+              ::FillRect(mSharedSurfaceDib.GetHDC(), pRect, (HBRUSH)GetStockObject(BLACK_BRUSH));
+              if (!mPluginIface->event(&mData, reinterpret_cast<void*>(&evcopy))) {
+                  mAlphaExtract.doublePass = RENDER_NATIVE;
+                  return false;
+              }
+              mAlphaExtract.doublePass = RENDER_BACK_TWO;
+              return true;
+        break;
+        case RENDER_BACK_TWO:
+              // copy our cached surface back
+              ::BitBlt(mSharedSurfaceDib.GetHDC(),
+                       pRect->left,
+                       pRect->top,
+                       pRect->right - pRect->left,
+                       pRect->bottom - pRect->top,
+                       mAlphaExtract.hdc,
+                       pRect->left,
+                       pRect->top,
+                       SRCCOPY);
+              mAlphaExtract.doublePass = RENDER_NATIVE;
+              return true;
+        break;
     }
-    // pass the internal hdc to the plugin
-    evcopy.wParam = WPARAM(mSharedSurfaceDib.GetHDC());
+    return false;
 }
 
 #endif // OS_WIN
 
 PPluginScriptableObjectChild*
 PluginInstanceChild::AllocPPluginScriptableObject()
 {
     AssertPluginThread();
--- a/dom/plugins/PluginInstanceChild.h
+++ b/dom/plugins/PluginInstanceChild.h
@@ -193,20 +193,34 @@ private:
 #endif
 
     nsTArray<nsAutoPtr<PluginScriptableObjectChild> > mScriptableObjects;
 
 #if defined(OS_WIN)
 private:
     // Shared dib rendering management for windowless plugins.
     bool SharedSurfaceSetWindow(const NPRemoteWindow& aWindow, NPError* rv);
-    void SharedSurfaceBeforePaint(NPEvent& evcopy);
+    int16_t SharedSurfacePaint(NPEvent& evcopy);
     void SharedSurfaceRelease();
+    bool AlphaExtractCacheSetup();
+    void AlphaExtractCacheRelease();
+    void UpdatePaintClipRect(RECT* aRect);
 
 private:
+    enum {
+      RENDER_NATIVE,
+      RENDER_BACK_ONE,
+      RENDER_BACK_TWO 
+    };
     gfx::SharedDIBWin mSharedSurfaceDib;
+    struct {
+      PRUint32        doublePassEvent;
+      PRUint16        doublePass;
+      HDC             hdc;
+      HBITMAP         bmp;
+    } mAlphaExtract;
 #endif // defined(OS_WIN)
 };
 
 } // namespace plugins
 } // namespace mozilla
 
 #endif // ifndef dom_plugins_PluginInstanceChild_h
--- a/dom/plugins/PluginInstanceParent.cpp
+++ b/dom/plugins/PluginInstanceParent.cpp
@@ -43,37 +43,29 @@
 #include "PluginModuleParent.h"
 #include "PluginStreamParent.h"
 #include "StreamNotifyParent.h"
 
 #include "npfunctions.h"
 #include "nsAutoPtr.h"
 
 #if defined(OS_WIN)
-#define NS_OOPP_DOUBLEPASS_MSGID TEXT("MozDoublePassMsg")
+#include <windowsx.h>
 #endif
 
 using namespace mozilla::plugins;
 
 PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
                                            NPP npp,
                                            const NPNetscapeFuncs* npniface)
   : mParent(parent),
     mNPP(npp),
     mNPNIface(npniface),
     mWindowType(NPWindowTypeWindow)
 {
-#if defined(OS_WIN)
-    // Event sent from nsObjectFrame indicating double pass rendering for
-    // windowless plugins. RegisterWindowMessage makes it easy sync event
-    // values, and insures we never conflict with windowing events we allow
-    // for windowless plugins.
-    mDoublePassEvent = ::RegisterWindowMessage(NS_OOPP_DOUBLEPASS_MSGID);
-    mLocalCopyRender = false;
-#endif
 }
 
 PluginInstanceParent::~PluginInstanceParent()
 {
     if (mNPP)
         mNPP->pdata = NULL;
 }
 
@@ -459,30 +451,68 @@ PluginInstanceParent::NPP_GetValue(NPPVa
 int16_t
 PluginInstanceParent::NPP_HandleEvent(void* event)
 {
     _MOZ_LOG(__FUNCTION__);
 
     NPEvent* npevent = reinterpret_cast<NPEvent*>(event);
     NPRemoteEvent npremoteevent;
     npremoteevent.event = *npevent;
+    int16_t handled;
 
 #if defined(OS_WIN)
     RECT rect;
     if (mWindowType == NPWindowTypeDrawable) {
-        if (mDoublePassEvent && mDoublePassEvent == npevent->event) {
-            // Sent from nsObjectFrame to let us know a double pass render is in progress.
-            mLocalCopyRender = PR_TRUE;
-            return true;
-        } else if (WM_PAINT == npevent->event) {
-            // Don't forward on the second pass, otherwise, fall through.
-            if (!SharedSurfaceBeforePaint(rect, npremoteevent))
-                return true;
+        switch(npevent->event) {
+            case WM_PAINT:
+            {
+                RECT rect;
+                SharedSurfaceBeforePaint(rect, npremoteevent);
+                if (!CallNPP_HandleEvent(npremoteevent, &handled))
+                    return 0;
+                if (handled)
+                    SharedSurfaceAfterPaint(npevent);
+            }
+            break;
+            case WM_WINDOWPOSCHANGED:
+                SharedSurfaceSetOrigin(npremoteevent);
+                if (!CallNPP_HandleEvent(npremoteevent, &handled))
+                    return 0;
+            break;
+            case WM_MOUSEMOVE:
+            case WM_RBUTTONDOWN:
+            case WM_MBUTTONDOWN:
+            case WM_LBUTTONDOWN:
+            case WM_LBUTTONUP:
+            case WM_MBUTTONUP:
+            case WM_RBUTTONUP:
+            case WM_LBUTTONDBLCLK:
+            case WM_MBUTTONDBLCLK:
+            case WM_RBUTTONDBLCLK:
+            {
+                // Received mouse events have an origin at the position of the plugin rect
+                // in the page. However, when rendering to the shared dib, the rect origin
+                // changes to 0,0 via the WM_WINDOWPOSCHANGED event. In this case we need to
+                // translate these coords to the proper location.
+                nsPoint pt(GET_X_LPARAM(npremoteevent.event.lParam), GET_Y_LPARAM(npremoteevent.event.lParam));
+                pt.MoveBy(-mPluginPosOrigin.x, -mPluginPosOrigin.y);
+                npremoteevent.event.lParam = MAKELPARAM(pt.x, pt.y);
+                if (!CallNPP_HandleEvent(npremoteevent, &handled))
+                    return 0;
+            }
+            default:
+                if (!CallNPP_HandleEvent(npremoteevent, &handled))
+                    return 0;
+            break;
         }
     }
+    else {
+        if (!CallNPP_HandleEvent(npremoteevent, &handled))
+            return 0;
+    }
 #endif
 
 #if defined(MOZ_X11)
     if (GraphicsExpose == npevent->type) {
         printf("  schlepping drawable 0x%lx across the pipe\n",
                npevent->xgraphicsexpose.drawable);
         // Make sure the X server has created the Drawable and completes any
         // drawing before the plugin draws on top.
@@ -490,26 +520,19 @@ PluginInstanceParent::NPP_HandleEvent(vo
         // XSync() waits for the X server to complete.  Really this parent
         // process does not need to wait; the child is the process that needs
         // to wait.  A possibly-slightly-better alternative would be to send
         // an X event to the child that the child would wait for.
 #  ifdef MOZ_WIDGET_GTK2
         XSync(GDK_DISPLAY(), False);
 #  endif
     }
-#endif
 
-    int16_t handled;
-    if (!CallNPP_HandleEvent(npremoteevent, &handled)) {
-        return 0;               // no good way to handle errors here...
-    }
-
-#if defined(OS_WIN)
-    if (handled && mWindowType == NPWindowTypeDrawable && WM_PAINT == npevent->event)
-        SharedSurfaceAfterPaint(npevent);
+    if (!CallNPP_HandleEvent(npremoteevent, &handled))
+        return 0; // no good way to handle errors here...
 #endif
 
     return handled;
 }
 
 NPError
 PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream,
                                     NPBool seekable, uint16_t* stype)
@@ -675,16 +698,51 @@ PluginInstanceParent::AnswerNPN_PopPopup
     *aSuccess = mNPNIface->poppopupsenabledstate(mNPP);
     return true;
 }
 
 #if defined(OS_WIN)
 
 /* windowless drawing helpers */
 
+/*
+ * Origin info:
+ *
+ * windowless, offscreen:
+ *
+ * WM_WINDOWPOSCHANGED: origin is relative to container 
+ * setwindow: origin is 0,0
+ * WM_PAINT: origin is 0,0
+ *
+ * windowless, native:
+ *
+ * WM_WINDOWPOSCHANGED: origin is relative to container 
+ * setwindow: origin is relative to container
+ * WM_PAINT: origin is relative to container
+ *
+ * PluginInstanceParent:
+ *
+ * painting: mPluginPort (nsIntRect, saved in SetWindow)
+ * event translation: mPluginPosOrigin (nsIntPoint, saved in SetOrigin)
+ */
+
+void
+PluginInstanceParent::SharedSurfaceSetOrigin(NPRemoteEvent& npremoteevent)
+{
+    WINDOWPOS* winpos = (WINDOWPOS*)npremoteevent.event.lParam;
+
+    // save the origin, we'll use this to translate input coordinates
+    mPluginPosOrigin.x = winpos->x;
+    mPluginPosOrigin.y = winpos->y;
+
+    // Reset to the offscreen dib origin
+    winpos->x  = 0;
+    winpos->y  = 0;
+}
+
 void
 PluginInstanceParent::SharedSurfaceRelease()
 {
     mSharedSurfaceDib.Close();
 }
 
 bool
 PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
@@ -706,79 +764,63 @@ PluginInstanceParent::SharedSurfaceSetWi
     newPort.MoveTo(0,0);
 
     // check to see if we have the room in shared surface
     if (mSharedSurfaceDib.IsValid() && mSharedSize.Contains(newPort)) {
       // ok to paint
       aRemoteWindow.surfaceHandle = 0;
       return true;
     }
-    
+
     // allocate a new shared surface
     SharedSurfaceRelease();
     if (NS_FAILED(mSharedSurfaceDib.Create(reinterpret_cast<HDC>(aWindow->window),
                                            newPort.width, newPort.height, 32)))
       return false;
 
     // save the new shared surface size we just allocated
     mSharedSize = newPort;
-    
+
     base::SharedMemoryHandle handle;
     if (NS_FAILED(mSharedSurfaceDib.ShareToProcess(mParent->ChildProcessHandle(), &handle)))
       return false;
 
     aRemoteWindow.surfaceHandle = handle;
-    
+
     return true;
 }
 
-bool
+void
 PluginInstanceParent::SharedSurfaceBeforePaint(RECT& rect,
                                                NPRemoteEvent& npremoteevent)
 {
     RECT* dr = (RECT*)npremoteevent.event.lParam;
     HDC parentHdc = (HDC)npremoteevent.event.wParam;
 
-    // We render twice per frame for windowless plugins that sit in transparent
-    // frames. (See nsObjectFrame and gfxWindowsNativeDrawing for details.) IPC
-    // message delays in OOP plugin painting can result in two passes yeilding
-    // different animation frames. The second rendering doesn't need to go over
-    // the wire (we already have a copy of the frame in mSharedSurfaceDib) so we
-    // skip off requesting the second. This also gives us a nice perf boost.
-    if (mLocalCopyRender) {
-      mLocalCopyRender = false;
-      // Reuse the old render.
-      SharedSurfaceAfterPaint(&npremoteevent.event);
-      return false;
-    }
-
     nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
     dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y); // should always be smaller than dirtyRect
 
     ::BitBlt(mSharedSurfaceDib.GetHDC(),
              dirtyRect.x,
              dirtyRect.y,
              dirtyRect.width,
              dirtyRect.height,
              parentHdc,
              dr->left,
              dr->top,
              SRCCOPY);
 
     // setup the translated dirty rect we'll send to the child
     rect.left   = dirtyRect.x;
     rect.top    = dirtyRect.y;
-    rect.right  = dirtyRect.width;
-    rect.bottom = dirtyRect.height;
+    rect.right  = dirtyRect.x + dirtyRect.width;
+    rect.bottom = dirtyRect.y + dirtyRect.height;
 
     npremoteevent.event.wParam = WPARAM(0);
     npremoteevent.event.lParam = LPARAM(&rect);
-
-    // Send the event to the plugin
-    return true;
 }
 
 void
 PluginInstanceParent::SharedSurfaceAfterPaint(NPEvent* npevent)
 {
     RECT* dr = (RECT*)npevent->lParam;
     HDC parentHdc = (HDC)npevent->wParam;
 
--- a/dom/plugins/PluginInstanceParent.h
+++ b/dom/plugins/PluginInstanceParent.h
@@ -212,26 +212,26 @@ private:
     NPWindowType mWindowType;
 
     nsTArray<nsAutoPtr<PluginScriptableObjectParent> > mScriptableObjects;
 
 #if defined(OS_WIN)
 private:
     // Used in rendering windowless plugins in other processes.
     bool SharedSurfaceSetWindow(const NPWindow* aWindow, NPRemoteWindow& aRemoteWindow);
-    bool SharedSurfaceBeforePaint(RECT &rect, NPRemoteEvent& npremoteevent);
+    void SharedSurfaceBeforePaint(RECT &rect, NPRemoteEvent& npremoteevent);
     void SharedSurfaceAfterPaint(NPEvent* npevent);
+    void SharedSurfaceSetOrigin(NPRemoteEvent& npremoteevent);
     void SharedSurfaceRelease();
 
 private:
     gfx::SharedDIBWin  mSharedSurfaceDib;
     nsIntRect          mPluginPort;
     nsIntRect          mSharedSize;
-    PRUint32           mDoublePassEvent;
-    bool               mLocalCopyRender;
+    nsIntPoint         mPluginPosOrigin;
 #endif // defined(XP_WIN)
 };
 
 
 } // namespace plugins
 } // namespace mozilla
 
 #endif // ifndef dom_plugins_PluginInstanceParent_h
--- a/dom/plugins/PluginPRLibrary.h
+++ b/dom/plugins/PluginPRLibrary.h
@@ -91,23 +91,27 @@ public:
 
         mNP_Shutdown = (NP_ShutdownFunc)
             PR_FindFunctionSymbol(mLibrary, "NP_Shutdown");
         if (!mNP_Shutdown)
             return false;
 
         mNP_GetMIMEDescription = (NP_GetMIMEDescriptionFunc)
             PR_FindFunctionSymbol(mLibrary, "NP_GetMIMEDescription");
+#ifndef XP_MACOSX
         if (!mNP_GetMIMEDescription)
             return false;
+#endif
 
         mNP_GetValue = (NP_GetValueFunc)
             PR_FindFunctionSymbol(mLibrary, "NP_GetValue");
+#ifndef XP_MACOSX
         if (!mNP_GetValue)
             return false;
+#endif
 
 #if defined(XP_WIN) || defined(XP_MACOSX)
         mNP_GetEntryPoints = (NP_GetEntryPointsFunc)
             PR_FindFunctionSymbol(mLibrary, "NP_GetEntryPoints");
         if (!mNP_GetEntryPoints)
             return false;
 #endif
         return true;
--- a/dom/plugins/PluginProcessParent.cpp
+++ b/dom/plugins/PluginProcessParent.cpp
@@ -62,17 +62,21 @@ PluginProcessParent::PluginProcessParent
 PluginProcessParent::~PluginProcessParent()
 {
 }
 
 bool
 PluginProcessParent::Launch()
 {
     std::vector<std::string> args;
+#if defined(XP_WIN)
+    args.push_back("\""+ mPluginFilePath +"\"");
+#else
     args.push_back(mPluginFilePath);
+#endif
     return SyncLaunch(args);
 }
 
 void
 PluginProcessParent::Delete()
 {
   MessageLoop* currentLoop = MessageLoop::current();
   MessageLoop* ioLoop = 
--- a/dom/tests/browser/browser_focus_steal_from_chrome.js
+++ b/dom/tests/browser/browser_focus_steal_from_chrome.js
@@ -1,11 +1,15 @@
 function test() {
   waitForExplicitFinish();
 
+  let secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
+                         .getService(Components.interfaces
+                                               .nsIScriptSecurityManager);
+
   let fm = Components.classes["@mozilla.org/focus-manager;1"]
                      .getService(Components.interfaces.nsIFocusManager);
 
   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" },
@@ -131,16 +135,42 @@ function test() {
 
 
   function doTest2() {
     if (canRetry-- > 0 && !isPrepared()) {
       setTimeout(callback, 10); // retry
       return;
     }
 
+    // XXX puts some useful information for bug 534420
+    let activeWindow = fm.activeWindow;
+    let focusedWindow = fm.focusedWindow;
+    ok(activeWindow, "We're not active");
+    ok(focusedWindow, "There is no focused window");
+    is(activeWindow, window.top, "our window isn't active");
+    let searchbar = BrowserSearch.searchBar;
+    let focusedElement = fm.focusedElement;
+    if (searchbar) {
+      let principal = searchbar.nodePrincipal;
+      ok(principal, "principal is null");
+      info("search bar: tagName=" + searchbar.tagName + " id=" + searchbar.id);
+      ok(secMan.isSystemPrincipal(principal), "search bar isn't chrome");
+    } else {
+      info("search bar is NULL!!");
+    }
+    if (focusedElement) {
+      let principal = focusedElement.nodePrincipal;
+      ok(principal, "principal is null");
+      info("focusedElement: tagName=" + focusedElement.tagName +
+           " id=" + focusedElement.id);
+      ok(secMan.isSystemPrincipal(principal), "focusedElement isn't chrome");
+    } else {
+      info("focusedElement is NULL!!");
+    }
+
     // The contents shouldn't be able to steal the focus from chrome.
 
     // in foreground tab
     let e = tabs[0].linkedBrowser.contentDocument.activeElement;
     is(e.tagName, testingList[testingIndex].tagName,
        "the foreground tab's " + testingList[testingIndex].tagName +
        " element is not active by the " + testingList[testingIndex].methodName +
        " (Test2: content can NOT steal focus)");
--- a/extensions/auth/nsAuthSSPI.cpp
+++ b/extensions/auth/nsAuthSSPI.cpp
@@ -310,16 +310,21 @@ nsAuthSSPI::GetNextToken(const void *inT
 
     DWORD ctxAttr, ctxReq = 0;
     CtxtHandle *ctxIn;
     SecBufferDesc ibd, obd;
     SecBuffer ib, ob;
 
     LOG(("entering nsAuthSSPI::GetNextToken()\n"));
 
+    if (!mCtxt.dwLower && !mCtxt.dwUpper) {
+        LOG(("nsAuthSSPI::GetNextToken(), not initialized. exiting."));
+        return NS_ERROR_NOT_INITIALIZED;
+    }
+
     if (mServiceFlags & REQ_DELEGATE)
         ctxReq |= ISC_REQ_DELEGATE;
     if (mServiceFlags & REQ_MUTUAL_AUTH)
         ctxReq |= ISC_REQ_MUTUAL_AUTH;
 
     if (inToken) {
         ib.BufferType = SECBUFFER_TOKEN;
         ib.cbBuffer = inTokenLen;
new file mode 100644
--- /dev/null
+++ b/extensions/cookie/test/unit/test_eviction.js
@@ -0,0 +1,89 @@
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+
+function run_test()
+{
+  var cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
+  var cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
+  var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+  var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
+
+  // twiddle prefs to convenient values for this test
+  prefs.setIntPref("network.cookie.purgeAge", 1);
+  prefs.setIntPref("network.cookie.maxNumber", 1000);
+
+  // eviction is performed based on two limits: when the total number of cookies
+  // exceeds maxNumber + 10% (1100), and when cookies are older than purgeAge
+  // (1 second). purging is done when both conditions are satisfied, and only
+  // those cookies are purged.
+
+  // we test the following cases of eviction:
+  // 1) excess and age are satisfied, but only some of the excess are old enough
+  // to be purged.
+  do_check_eq(testEviction(cm, 1101, 2, 50, 1051), 1051);
+
+  // 2) excess and age are satisfied, and all of the excess are old enough
+  // to be purged.
+  do_check_eq(testEviction(cm, 1101, 2, 100, 1001), 1001);
+
+  // 3) excess and age are satisfied, and more than the excess are old enough
+  // to be purged.
+  do_check_eq(testEviction(cm, 1101, 2, 500, 1001), 1001);
+
+  // 4) excess but not age are satisfied.
+  do_check_eq(testEviction(cm, 2000, 0, 0, 2000), 2000);
+
+  // 5) age but not excess are satisfied.
+  do_check_eq(testEviction(cm, 1100, 2, 200, 1100), 1100);
+
+  cm.removeAll();
+
+  // reset prefs to defaults
+  prefs.setIntPref("network.cookie.purgeAge", 30 * 24 * 60 * 60);
+  prefs.setIntPref("network.cookie.maxNumber", 2000);
+}
+
+// test that cookies are evicted by order of lastAccessed time, if both the limit
+// on total cookies (maxNumber + 10%) and the purge age are exceeded
+function
+testEviction(aCM, aNumberTotal, aSleepDuration, aNumberOld, aNumberToExpect)
+{
+  aCM.removeAll();
+  var expiry = (Date.now() + 1e6) * 1000;
+
+  var i;
+  for (i = 0; i < aNumberTotal; ++i) {
+    var host = "eviction." + i + ".tests";
+    aCM.add(host, "", "test", "eviction", false, false, false, expiry);
+
+    if ((i == aNumberOld - 1) && aSleepDuration) {
+      // sleep a while, to make sure the first batch of cookies is older than
+      // the second (timer resolution varies on different platforms).
+      sleep(aSleepDuration * 1000);
+    }
+  }
+
+  var enumerator = aCM.enumerator;
+
+  i = 0;
+  while (enumerator.hasMoreElements()) {
+    var cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
+    ++i;
+
+    if (aNumberTotal != aNumberToExpect) {
+      // make sure the cookie is one of the batch we expect was purged.
+      var hostNumber = new Number(cookie.rawHost.split(".")[1]);
+      if (hostNumber < (aNumberOld - aNumberToExpect)) break;
+    }
+  }
+
+  return i;
+}
+
+// delay for a number of milliseconds
+function sleep(delay)
+{
+  var start = Date.now();
+  while (Date.now() < start + delay);
+}
+
--- a/extensions/layout-debug/src/Makefile.in
+++ b/extensions/layout-debug/src/Makefile.in
@@ -42,17 +42,18 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= layout_debug
 LIBRARY_NAME	= gkdebug
 EXPORT_LIBRARY	= 1
 IS_COMPONENT	= 1
 MODULE_NAME	= nsLayoutDebugModule
-LIBXUL_LIBRARY = 1
+LIBXUL_LIBRARY	= 1
+GRE_MODULE	= 1
 
 
 XPIDLSRCS	= \
 		nsILayoutRegressionTester.idl \
 		nsILayoutDebuggingTools.idl \
 		$(NULL)
 
 EXPORTS		= \
--- a/extensions/reporter/resources/content/reporter/reporterOverlay.js
+++ b/extensions/reporter/resources/content/reporter/reporterOverlay.js
@@ -63,17 +63,16 @@ var reporterListener = {
 
     broadcaster.setAttribute("disabled", !isEnabled);
   },
 
   onStateChange: function() {  },
   onProgressChange: function() {  },
   onStatusChange: function() {  },
   onSecurityChange: function() {  },
-  onLinkIconAvailable: function() {  },
   onProgressChange64: function() { },
   onRefreshAttempted: function() { return true; }
 }
 
 function onBrowserLoad() {
   if ("undefined" != typeof(gBrowser))
     gBrowser.addProgressListener(reporterListener);
 }
--- a/gfx/src/thebes/nsThebesDeviceContext.cpp
+++ b/gfx/src/thebes/nsThebesDeviceContext.cpp
@@ -641,29 +641,33 @@ nsThebesDeviceContext::SetDPI()
         switch (mPrintingSurface->GetType()) {
             case gfxASurface::SurfaceTypePDF:
             case gfxASurface::SurfaceTypePS:
             case gfxASurface::SurfaceTypeQuartz:
                 dpi = 72;
                 break;
 #ifdef XP_WIN
             case gfxASurface::SurfaceTypeWin32:
-            case gfxASurface::SurfaceTypeWin32Printing:
+            case gfxASurface::SurfaceTypeWin32Printing: {
                 PRInt32 OSVal = GetDeviceCaps(GetPrintHDC(), LOGPIXELSY);
                 dpi = 144;
                 mPrintingScale = float(OSVal) / dpi;
                 break;
+            }
 #endif
 #ifdef XP_OS2
             case gfxASurface::SurfaceTypeOS2:
                 LONG lDPI;
                 if (DevQueryCaps(GetPrintHDC(), CAPS_VERTICAL_FONT_RES, 1, &lDPI))
                     dpi = lDPI;
                 break;
 #endif
+            default:
+                NS_NOTREACHED("Unexpected printing surface type");
+                break;
         }
         dotsArePixels = PR_FALSE;
     } else {
         nsresult rv;
         // A value of -1 means use the minimum of 96 and the system DPI.
         // A value of 0 means use the system DPI. A positive value is used as the DPI.
         // This sets the physical size of a device pixel and thus controls the
         // interpretation of physical units such as "pt".
--- a/gfx/thebes/public/gfxPDFSurface.h
+++ b/gfx/thebes/public/gfxPDFSurface.h
@@ -58,17 +58,21 @@ public:
     virtual void Finish();
 
     void SetDPI(double x, double y);
     void GetDPI(double *xDPI, double *yDPI);
 
     // this is in points!
     const gfxSize& GetSize() const { return mSize; }
 
-    virtual PRInt32 GetDefaultContextFlags() const { return gfxContext::FLAG_DISABLE_SNAPPING; }
+    virtual PRInt32 GetDefaultContextFlags() const
+    {
+        return gfxContext::FLAG_SIMPLIFY_OPERATORS |
+               gfxContext::FLAG_DISABLE_SNAPPING;
+    }
 
 private:
     nsCOMPtr<nsIOutputStream> mStream;
     double mXDPI;
     double mYDPI;
     gfxSize mSize;
 };
 
--- a/gfx/thebes/public/gfxPSSurface.h
+++ b/gfx/thebes/public/gfxPSSurface.h
@@ -58,17 +58,21 @@ public:
     virtual void Finish();
 
     void SetDPI(double x, double y);
     void GetDPI(double *xDPI, double *yDPI);
 
     // this is in points!
     const gfxSize& GetSize() const { return mSize; }
 
-    virtual PRInt32 GetDefaultContextFlags() const { return gfxContext::FLAG_DISABLE_SNAPPING; }
+    virtual PRInt32 GetDefaultContextFlags() const
+    {
+        return gfxContext::FLAG_SIMPLIFY_OPERATORS |
+               gfxContext::FLAG_DISABLE_SNAPPING;
+    }
 
 private:
     nsCOMPtr<nsIOutputStream> mStream;
     double mXDPI;
     double mYDPI;
     gfxSize mSize;
 };
 
--- a/gfx/thebes/public/gfxWindowsNativeDrawing.h
+++ b/gfx/thebes/public/gfxWindowsNativeDrawing.h
@@ -106,16 +106,19 @@ public:
     void TransformToNativeRect(const gfxRect& r, RECT& rout);
 
     /* Marks the end of native drawing */
     void EndNativeDrawing();
 
     /* Returns PR_TRUE if the native drawing should be executed again */
     PRBool ShouldRenderAgain();
 
+    /* Returns PR_TRUE if double pass alpha extraction is taking place. */
+    PRBool IsDoublePass();
+
     /* Places the result to the context, if necessary */
     void PaintToContext();
 
 private:
 
     nsRefPtr<gfxContext> mContext;
     gfxRect mNativeRect;
     PRUint32 mNativeDrawFlags;
--- a/gfx/thebes/src/gfxMacPlatformFontList.h
+++ b/gfx/thebes/src/gfxMacPlatformFontList.h
@@ -65,29 +65,33 @@ public:
     friend class gfxMacPlatformFontList;
 
     MacOSFontEntry(const nsAString& aPostscriptName, PRInt32 aWeight,
                    gfxFontFamily *aFamily, PRBool aIsStandardFace = PR_FALSE);
 
     ATSFontRef GetFontRef();
     nsresult ReadCMAP();
 
+#ifndef __LP64__
     PRBool UseLiGothicAtsuiHack() { return mUseLiGothicAtsuiHack; }
+#endif
 
 protected:
     // for use with data fonts
     MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFontRef,
                    PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
                    gfxUserFontData *aUserFontData);
 
     virtual nsresult GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer);
 
     ATSFontRef mATSFontRef;
     PRPackedBool mATSFontRefInitialized;
+#ifndef __LP64__
     PRPackedBool mUseLiGothicAtsuiHack;
+#endif
 };
 
 class gfxMacPlatformFontList : public gfxPlatformFontList {
 public:
     static gfxMacPlatformFontList* PlatformFontList() {
         return (gfxMacPlatformFontList*)sPlatformFontList;
     }
 
--- a/gfx/thebes/src/gfxMacPlatformFontList.mm
+++ b/gfx/thebes/src/gfxMacPlatformFontList.mm
@@ -112,29 +112,33 @@ static PRLogModuleInfo *gFontInfoLog = P
 #pragma mark-
 
 MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
                                PRInt32 aWeight,
                                gfxFontFamily *aFamily,
                                PRBool aIsStandardFace)
     : gfxFontEntry(aPostscriptName, aFamily, aIsStandardFace),
       mATSFontRef(0),
-      mATSFontRefInitialized(PR_FALSE),
-      mUseLiGothicAtsuiHack(PR_FALSE)
+      mATSFontRefInitialized(PR_FALSE)
+#ifndef __LP64__
+      , mUseLiGothicAtsuiHack(PR_FALSE)
+#endif
 {
     mWeight = aWeight;
 }
 
 MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFontRef,
                                PRUint16 aWeight, PRUint16 aStretch, PRUint32 aItalicStyle,
                                gfxUserFontData *aUserFontData)
     : gfxFontEntry(aPostscriptName),
       mATSFontRef(aFontRef),
-      mATSFontRefInitialized(PR_TRUE),
-      mUseLiGothicAtsuiHack(PR_FALSE)
+      mATSFontRefInitialized(PR_TRUE)
+#ifndef __LP64__
+      , mUseLiGothicAtsuiHack(PR_FALSE)
+#endif
 {
     // xxx - stretch is basically ignored for now
 
     mUserFontData = aUserFontData;
     mWeight = aWeight;
     mStretch = aStretch;
     mFixedPitch = PR_FALSE; // xxx - do we need this for downloaded fonts?
     mItalic = (aItalicStyle & (FONT_STYLE_ITALIC | FONT_STYLE_OBLIQUE)) != 0;
@@ -260,32 +264,36 @@ MacOSFontEntry::ReadCMAP()
 
             if (omitRange) {
                 mCharacterMap.ClearRange(gScriptsThatRequireShaping[s].rangeStart,
                                          gScriptsThatRequireShaping[s].rangeEnd);
             }
         }
     }
 
+#ifndef __LP64__  /* ATSUI not available on 64-bit */
+
     if ((gfxPlatformMac::GetPlatform()->OSXVersion() &
          MAC_OS_X_MAJOR_VERSION_MASK) == MAC_OS_X_VERSION_10_6_HEX) {
         // even ruder hack - LiGothic font on 10.6 has a bad glyph for U+775B
         // that causes ATSUI failure, so we set a flag to tell our layout code
         // to hack around that character
         if (mName.EqualsLiteral("LiGothicMed")) {
             // check whether the problem char maps to the expected glyph;
             // if not, we'll assume this isn't the problem version of the font
             if (gfxFontUtils::MapCharToGlyph(cmap.Elements(), cmap.Length(),
                                              kLiGothicBadCharUnicode) ==
                 kLiGothicBadCharGlyph) {
                 mUseLiGothicAtsuiHack = PR_TRUE;
             }
         }
     }
 
+#endif /* not __LP64__ */
+
     PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit-cmap) psname: %s, size: %d\n",
                                         NS_ConvertUTF16toUTF8(mName).get(), mCharacterMap.GetSize()));
 
     return rv;
 }
 
 nsresult
 MacOSFontEntry::GetFontTable(PRUint32 aTableTag, nsTArray<PRUint8>& aBuffer)
--- a/gfx/thebes/src/gfxWindowsNativeDrawing.cpp
+++ b/gfx/thebes/src/gfxWindowsNativeDrawing.cpp
@@ -201,16 +201,32 @@ gfxWindowsNativeDrawing::BeginNativeDraw
         return mDC;
     } else {
         NS_ERROR("Bogus render state!");
         return nsnull;
     }
 }
 
 PRBool
+gfxWindowsNativeDrawing::IsDoublePass()
+{
+    // this is the same test we use in BeginNativeDrawing.
+    nsRefPtr<gfxASurface> surf = mContext->CurrentSurface(&mDeviceOffset.x, &mDeviceOffset.y);
+    if (!surf || surf->CairoStatus())
+        return false;
+    if ((surf->GetType() == gfxASurface::SurfaceTypeWin32 ||
+         surf->GetType() == gfxASurface::SurfaceTypeWin32Printing) &&
+        (surf->GetContentType() != gfxASurface::CONTENT_COLOR ||
+         (surf->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA &&
+          !(mNativeDrawFlags & CAN_DRAW_TO_COLOR_ALPHA))))
+        return PR_TRUE;
+    return PR_FALSE;
+}
+
+PRBool
 gfxWindowsNativeDrawing::ShouldRenderAgain()
 {
     switch (mRenderState) {
         case RENDER_STATE_NATIVE_DRAWING_DONE:
             return PR_FALSE;
 
         case RENDER_STATE_ALPHA_RECOVERY_BLACK_DONE:
             mRenderState = RENDER_STATE_ALPHA_RECOVERY_WHITE;
--- a/gfx/thebes/src/woff.c
+++ b/gfx/thebes/src/woff.c
@@ -35,17 +35,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "woff-private.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <zlib.h>
+#include "zlib.h"
 
 #ifdef WOFF_MOZILLA_CLIENT /* define this when building as part of Gecko */
 # include "prmem.h"
 # define malloc  PR_Malloc
 # define realloc PR_Realloc
 # define free    PR_Free
 #endif
 
--- a/ipc/ipdl/ipdl/ast.py
+++ b/ipc/ipdl/ipdl/ast.py
@@ -118,17 +118,17 @@ class Loc:
         self.lineno = lineno
     def __repr__(self):
         return '%r:%r'% (self.filename, self.lineno)
     def __str__(self):
         return '%s:%s'% (self.filename, self.lineno)
 
 Loc.NONE = Loc(filename='<??>', lineno=0)
 
-class _struct():
+class _struct:
     pass
 
 class Node:
     def __init__(self, loc=Loc.NONE):
         self.loc = loc
 
     def accept(self, visitor):
         visit = getattr(visitor, 'visit'+ self.__class__.__name__, None)
--- a/js/ctypes/ctypes.msg
+++ b/js/ctypes/ctypes.msg
@@ -38,15 +38,10 @@
 
 /*
  * This is the jsctypes error message file.
  *
  * For syntax details, see js/src/js.msg.
  */
 
 MSG_DEF(CTYPESMSG_PLACEHOLDER_0, 0, 0, JSEXN_NONE, NULL)
-MSG_DEF(CTYPESMSG_PLACEHOLDER_1, 1, 0, JSEXN_NONE, NULL)
-MSG_DEF(CTYPESMSG_PLACEHOLDER_2, 2, 0, JSEXN_NONE, NULL)
+MSG_DEF(CTYPESMSG_TYPE_ERROR,    1, 2, JSEXN_TYPEERR, "expected type {0}, got {1}")
 
-// This error has to be number 3 in order to be a TypeError,
-// due to a bug in the js engine.
-MSG_DEF(CTYPESMSG_TYPE_ERROR,    3, 2, JSEXN_TYPEERR, "expected type {0}, got {1}")
-
--- a/js/jsd/jsd.h
+++ b/js/jsd/jsd.h
@@ -1037,16 +1037,19 @@ jsd_TopLevelCallHook(JSContext *cx, JSSt
 
 extern JSBool
 jsd_InitObjectManager(JSDContext* jsdc);
 
 extern void
 jsd_DestroyObjectManager(JSDContext* jsdc);
 
 extern void
+jsd_DestroyObjects(JSDContext* jsdc);
+
+extern void
 jsd_ObjectHook(JSContext *cx, JSObject *obj, JSBool isNew, void *closure);
 
 extern void
 jsd_Constructing(JSDContext* jsdc, JSContext *cx, JSObject *obj,
                  JSStackFrame *fp);
 
 extern JSDObject*
 jsd_IterateObjects(JSDContext* jsdc, JSDObject** iterp);
--- a/js/jsd/jsd_obj.c
+++ b/js/jsd/jsd_obj.c
@@ -234,20 +234,28 @@ jsd_InitObjectManager(JSDContext* jsdc)
                                          JS_CompareValues, JS_CompareValues,
                                          NULL, NULL);
     return (JSBool) jsdc->objectsTable;
 }
 
 void
 jsd_DestroyObjectManager(JSDContext* jsdc)
 {
+    jsd_DestroyObjects(jsdc);
+    JSD_LOCK_OBJECTS(jsdc);
+    JS_HashTableDestroy(jsdc->objectsTable);
+    JSD_UNLOCK_OBJECTS(jsdc);
+}
+
+void
+jsd_DestroyObjects(JSDContext* jsdc)
+{
     JSD_LOCK_OBJECTS(jsdc);
     while( !JS_CLIST_IS_EMPTY(&jsdc->objectsList) )
         _destroyJSDObject(jsdc, (JSDObject*)JS_NEXT_LINK(&jsdc->objectsList));
-    JS_HashTableDestroy(jsdc->objectsTable);
     JSD_UNLOCK_OBJECTS(jsdc);
 }
 
 JSDObject*
 jsd_IterateObjects(JSDContext* jsdc, JSDObject** iterp)
 {
     JSDObject *jsdobj = *iterp;
 
--- a/js/jsd/jsdebug.c
+++ b/js/jsd/jsdebug.c
@@ -135,28 +135,27 @@ JSD_ClearAllProfileData(JSDContext *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
+        /* 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
+        /* 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);
+            /* Need to reenable our object hooks now */
+            JS_SetObjectHook(jsdc->jsrt, jsd_ObjectHook, jsdc);
         } else {
-            jsd_DestroyObjectManager(jsdc);
+            jsd_DestroyObjects(jsdc);
             JS_SetObjectHook(jsdc->jsrt, NULL, NULL);
         }
     }
 }
 
 JSD_PUBLIC_API(uint32)
 JSD_GetContextFlags(JSDContext *jsdc)
 {
--- a/js/src/jsapi.cpp
+++ b/js/src/jsapi.cpp
@@ -5822,17 +5822,18 @@ JS_ErrorFromException(JSContext *cx, jsv
     CHECK_REQUEST(cx);
     return js_ErrorFromException(cx, v);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ThrowReportedError(JSContext *cx, const char *message,
                       JSErrorReport *reportp)
 {
-    return JS_IsRunning(cx) && js_ErrorToException(cx, message, reportp);
+    return JS_IsRunning(cx) &&
+           js_ErrorToException(cx, message, reportp, NULL, NULL);
 }
 
 JS_PUBLIC_API(JSBool)
 JS_ThrowStopIteration(JSContext *cx)
 {
     return js_ThrowStopIteration(cx);
 }
 
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -1276,37 +1276,40 @@ MarkLocalRoots(JSTracer *trc, JSLocalRoo
         mark = JSVAL_TO_INT(lrc->roots[m]);
         if (m == 0)
             lrc = lrc->down;
     } while (n != 0);
     JS_ASSERT(!lrc);
 }
 
 static void
-ReportError(JSContext *cx, const char *message, JSErrorReport *reportp)
+ReportError(JSContext *cx, const char *message, JSErrorReport *reportp,
+            JSErrorCallback callback, void *userRef)
 {
     /*
      * Check the error report, and set a JavaScript-catchable exception
      * if the error is defined to have an associated exception.  If an
      * exception is thrown, then the JSREPORT_EXCEPTION flag will be set
      * on the error report, and exception-aware hosts should ignore it.
      */
     JS_ASSERT(reportp);
-    if (reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION)
+    if ((!callback || callback == js_GetErrorMessage) &&
+        reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION)
         reportp->flags |= JSREPORT_EXCEPTION;
 
     /*
      * Call the error reporter only if an exception wasn't raised.
      *
      * If an exception was raised, then we call the debugErrorHook
      * (if present) to give it a chance to see the error before it
      * propagates out of scope.  This is needed for compatability
      * with the old scheme.
      */
-    if (!JS_IsRunning(cx) || !js_ErrorToException(cx, message, reportp)) {
+    if (!JS_IsRunning(cx) ||
+        !js_ErrorToException(cx, message, reportp, callback, userRef)) {
         js_ReportErrorAgain(cx, message, reportp);
     } else if (cx->debugHooks->debugErrorHook && cx->errorReporter) {
         JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
         /* test local in case debugErrorHook changed on another thread */
         if (hook)
             hook(cx, message, reportp, cx->debugHooks->debugErrorHookData);
     }
 }
@@ -1452,17 +1455,17 @@ js_ReportErrorVA(JSContext *cx, uintN fl
     memset(&report, 0, sizeof (struct JSErrorReport));
     report.flags = flags;
     report.errorNumber = JSMSG_USER_DEFINED_ERROR;
     report.ucmessage = ucmessage = js_InflateString(cx, message, &messagelen);
     PopulateReportBlame(cx, &report);
 
     warning = JSREPORT_IS_WARNING(report.flags);
 
-    ReportError(cx, message, &report);
+    ReportError(cx, message, &report, NULL, NULL);
     js_free(message);
     cx->free(ucmessage);
     return warning;
 }
 
 /*
  * The arguments from ap need to be packaged up into an array and stored
  * into the report struct.
@@ -1646,17 +1649,17 @@ js_ReportErrorNumberVA(JSContext *cx, ui
     report.errorNumber = errorNumber;
     PopulateReportBlame(cx, &report);
 
     if (!js_ExpandErrorArguments(cx, callback, userRef, errorNumber,
                                  &message, &report, charArgs, ap)) {
         return JS_FALSE;
     }
 
-    ReportError(cx, message, &report);
+    ReportError(cx, message, &report, callback, userRef);
 
     if (message)
         cx->free(message);
     if (report.messageArgs) {
         /*
          * js_ExpandErrorArguments owns its messageArgs only if it had to
          * inflate the arguments (from regular |char *|s).
          */
--- a/js/src/jsexn.cpp
+++ b/js/src/jsexn.cpp
@@ -1099,17 +1099,18 @@ static struct exnname { char *name; char
 #define MSG_DEF(name, number, count, exception, format) \
     {#name, #exception},
 #include "js.msg"
 #undef MSG_DEF
 };
 #endif /* DEBUG */
 
 JSBool
-js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp)
+js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
+                    JSErrorCallback callback, void *userRef)
 {
     JSErrNum errorNumber;
     const JSErrorFormatString *errorString;
     JSExnType exn;
     jsval tv[4];
     JSTempValueRooter tvr;
     JSBool ok;
     JSObject *errProto, *errObject;
@@ -1119,17 +1120,20 @@ js_ErrorToException(JSContext *cx, const
      * Tell our caller to report immediately if this report is just a warning.
      */
     JS_ASSERT(reportp);
     if (JSREPORT_IS_WARNING(reportp->flags))
         return JS_FALSE;
 
     /* Find the exception index associated with this error. */
     errorNumber = (JSErrNum) reportp->errorNumber;
-    errorString = js_GetLocalizedErrorMessage(cx, NULL, NULL, errorNumber);
+    if (!callback || callback == js_GetErrorMessage)
+        errorString = js_GetLocalizedErrorMessage(cx, NULL, NULL, errorNumber);
+    else
+        errorString = callback(userRef, NULL, errorNumber);
     exn = errorString ? (JSExnType) errorString->exnType : JSEXN_NONE;
     JS_ASSERT(exn < JSEXN_LIMIT);
 
 #if defined( DEBUG_mccabe ) && defined ( PRINTNAMES )
     /* Print the error name and the associated exception name to stderr */
     fprintf(stderr, "%s\t%s\n",
             errortoexnname[errorNumber].name,
             errortoexnname[errorNumber].exception);
--- a/js/src/jsexn.h
+++ b/js/src/jsexn.h
@@ -58,17 +58,18 @@ js_InitExceptionClasses(JSContext *cx, J
  * Given a JSErrorReport, check to see if there is an exception associated with
  * the error number.  If there is, then create an appropriate exception object,
  * set it as the pending exception, and set the JSREPORT_EXCEPTION flag on the
  * error report.  Exception-aware host error reporters should probably ignore
  * error reports so flagged.  Returns JS_TRUE if an associated exception is
  * found and set, JS_FALSE otherwise.
  */
 extern JSBool
-js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp);
+js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
+                    JSErrorCallback callback, void *userRef);
 
 /*
  * Called if a JS API call to js_Execute or js_InternalCall fails; calls the
  * error reporter with the error report associated with any uncaught exception
  * that has been raised.  Returns true if there was an exception pending, and
  * the error reporter was actually called.
  *
  * The JSErrorReport * that the error reporter is called with is currently
--- a/js/src/jsscan.cpp
+++ b/js/src/jsscan.cpp
@@ -602,17 +602,17 @@ ReportCompileErrorNumberVA(JSContext *cx
     onError = cx->errorReporter;
 
     /*
      * Try to raise an exception only if there isn't one already set --
      * otherwise the exception will describe the last compile-time error,
      * which is likely spurious.
      */
     if (!(ts->flags & TSF_ERROR)) {
-        if (js_ErrorToException(cx, message, &report))
+        if (js_ErrorToException(cx, message, &report, NULL, NULL))
             onError = NULL;
     }
 
     /*
      * Suppress any compile-time errors that don't occur at the top level.
      * This may still fail, as interplevel may be zero in contexts where we
      * don't really want to call the error reporter, as when js is called
      * by other code which could catch the error.
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -3249,17 +3249,19 @@ Scatter(JSContext *cx, uintN argc, jsval
 
     for (i = 1; i < n; i++) {
         JSContext *newcx;
         WITH_LOCKED_CONTEXT_LIST(
             newcx = JS_NewContext(JS_GetRuntime(cx), 8192)
         );
         if (!newcx)
             goto fail;
+        JS_BeginRequest(newcx);
         JS_SetGlobalObject(newcx, JS_GetGlobalObject(cx));
+        JS_EndRequest(newcx);
         JS_ClearContextThread(newcx);
         sd.threads[i].cx = newcx;
     }
 
     for (i = 1; i < n; i++) {
         PRThread *t = PR_CreateThread(PR_USER_THREAD,
                                       RunScatterThread,
                                       &sd.threads[i],
--- a/js/src/tests/js1_5/Regress/jstests.list
+++ b/js/src/tests/js1_5/Regress/jstests.list
@@ -165,17 +165,17 @@ script regress-334807-05.js
 script regress-334807-06.js
 script regress-336100.js
 script regress-338307.js
 script regress-340369.js
 skip-if(xulRuntime.OS=="WINNT"&&isDebugBuild) script regress-341360.js # slow
 script regress-343713.js
 script regress-343966.js
 script regress-344711-n.js
-fails-if(!xulRuntime.shell&&xulRuntime.OS=="WINNT") script regress-344804.js # bug 524732
+script regress-344804.js # bug 524732
 script regress-344959.js
 script regress-346237.js
 script regress-346801.js
 random script regress-347306-01.js # BigO
 script regress-349482-01.js
 script regress-349482-02.js
 script regress-349592.js
 script regress-349648.js
--- a/js/src/tests/js1_5/Scope/jstests.list
+++ b/js/src/tests/js1_5/Scope/jstests.list
@@ -1,11 +1,11 @@
 url-prefix ../../jsreftest.html?test=js1_5/Scope/
 script regress-154693.js
-fails-if(!xulRuntime.shell&&xulRuntime.OS=="WINNT") script regress-181834.js # bug 524732
+script regress-181834.js # bug 524732
 script regress-184107.js
 script regress-185485.js
 script regress-191276.js
 script regress-192226.js
 script regress-202678-001.js
 script regress-202678-002.js
 script regress-208496-001.js
 script regress-208496-002.js
--- a/js/src/xpconnect/loader/XPCOMUtils.jsm
+++ b/js/src/xpconnect/loader/XPCOMUtils.jsm
@@ -110,26 +110,28 @@ const Cr = Components.results;
 
 var XPCOMUtils = {
   /**
    * Generate a QueryInterface implementation. The returned function must be
    * assigned to the 'QueryInterface' property of a JS object. When invoked on
    * that object, it checks if the given iid is listed in the |interfaces|
    * param, and if it is, returns |this| (the object it was called on).
    */
-  generateQI: function(interfaces) {
+  generateQI: function XPCU_generateQI(interfaces) {
     /* Note that Ci[Ci.x] == Ci.x for all x */
     return makeQI([Ci[i].name for each (i in interfaces) if (Ci[i])]);
   },
 
   /**
    * Generate the NSGetModule function (along with the module definition).
    * See the parameters to generateModule.
    */
-  generateNSGetModule: function(componentsArray, postRegister, preUnregister) {
+  generateNSGetModule: function XPCU_generateNSGetModule(componentsArray,
+                                                         postRegister,
+                                                         preUnregister) {
     return function NSGetModule(compMgr, fileSpec) {
       return XPCOMUtils.generateModule(componentsArray,
                                        postRegister,
                                        preUnregister);
     }
   },
 
   /**
@@ -139,17 +141,18 @@ var XPCOMUtils = {
    *                         at the top of this file for details.
    * @param postRegister  optional post-registration function with
    *                      signature 'postRegister(nsIComponentManager,
    *                                              nsIFile, componentsArray)'
    * @param preUnregister optional pre-unregistration function with
    *                      signature 'preUnregister(nsIComponentManager,
    *                                               nsIFile, componentsArray)'
    */
-  generateModule: function(componentsArray, postRegister, preUnregister) {
+  generateModule: function XPCU_generateModule(componentsArray, postRegister,
+                                               preUnregister) {
     let classes = [];
     for each (let component in componentsArray) {
       classes.push({
         cid:          component.prototype.classID,
         className:    component.prototype.classDescription,
         contractID:   component.prototype.contractID,
         factory:      this._getFactory(component),
         categories:   component.prototype._xpcom_categories
@@ -276,17 +279,17 @@ var XPCOMUtils = {
   get categoryManager() {
     return Components.classes["@mozilla.org/categorymanager;1"]
            .getService(Ci.nsICategoryManager);
   },
 
   /**
    * Returns an nsIFactory for |component|.
    */
-  _getFactory: function(component) {
+  _getFactory: function XPCOMUtils__getFactory(component) {
     var factory = component.prototype._xpcom_factory;
     if (!factory) {
       factory = {
         createInstance: function(outer, iid) {
           if (outer)
             throw Cr.NS_ERROR_NO_AGGREGATION;
           return (new component()).QueryInterface(iid);
         }
--- a/layout/generic/nsInlineFrame.cpp
+++ b/layout/generic/nsInlineFrame.cpp
@@ -1005,16 +1005,17 @@ nsFirstLineFrame::Reflow(nsPresContext* 
     ReParentChildListStyle(aPresContext, newFrames, this);
   }
 
   // Set our own reflow state (additional state above and beyond
   // aReflowState)
   InlineReflowState irs;
   irs.mPrevFrame = nsnull;
   irs.mLineContainer = lineContainer;
+  irs.mLineLayout = aReflowState.mLineLayout;
   irs.mNextInFlow = (nsInlineFrame*) GetNextInFlow();
 
   nsresult rv;
   PRBool wasEmpty = mFrames.IsEmpty();
   if (wasEmpty) {
     // Try to pull over one frame before starting so that we know
     // whether we have an anonymous block or not.
     PRBool complete;
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -219,19 +219,19 @@ enum { XKeyPress = KeyPress };
 #ifdef CreateEvent // Thank you MS.
 #undef CreateEvent
 #endif
 
 #ifdef PR_LOGGING 
 static PRLogModuleInfo *nsObjectFrameLM = PR_NewLogModule("nsObjectFrame");
 #endif /* PR_LOGGING */
 
-#define NORMAL_PLUGIN_DELAY 20
-// must avoid audio skipping/delays
-#define HIDDEN_PLUGIN_DELAY 125
+#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
+#define MAC_CARBON_PLUGINS
+#endif
 
 // special class for handeling DOM context menu events because for
 // some reason it starves other mouse events if implemented on the
 // same class
 class nsPluginDOMContextMenuListener : public nsIDOMContextMenuListener
 {
 public:
   nsPluginDOMContextMenuListener();
@@ -252,17 +252,16 @@ public:
   {
     return nsEventStatus_eConsumeNoDefault;
   }
 };
 
 
 class nsPluginInstanceOwner : public nsIPluginInstanceOwner,
                               public nsIPluginTagInfo,
-                              public nsITimerCallback,
                               public nsIDOMMouseListener,
                               public nsIDOMMouseMotionListener,
                               public nsIDOMKeyListener,
                               public nsIDOMFocusListener,
                               public nsIScrollPositionListener
 {
 public:
   nsPluginInstanceOwner();
@@ -320,21 +319,21 @@ public:
 #elif defined(MOZ_X11) || defined(MOZ_DFB)
   void Paint(gfxContext* aContext,
              const gfxRect& aFrameRect,
              const gfxRect& aDirtyRect);
 #elif defined(XP_OS2)
   void Paint(const nsRect& aDirtyRect, HPS aHPS);
 #endif
 
-  // nsITimerCallback interface
-  NS_DECL_NSITIMERCALLBACK
-  
+#ifdef MAC_CARBON_PLUGINS
   void CancelTimer();
-  void StartTimer(unsigned int aDelay);
+  void StartTimer(PRBool isVisible);
+#endif
+  void SendIdleEvent();
 
   // nsIScrollPositionListener interface
   NS_IMETHOD ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY);
   virtual void ViewPositionDidChange(nsIScrollableView* aScrollable,
                                      nsTArray<nsIWidget::Configuration>* aConfigurations) {}
   NS_IMETHOD ScrollPositionDidChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY);
 
   //locals
@@ -427,17 +426,16 @@ private:
 
   nsPluginNativeWindow       *mPluginWindow;
   nsCOMPtr<nsIPluginInstance> mInstance;
   nsObjectFrame              *mObjectFrame; // owns nsPluginInstanceOwner
   nsCOMPtr<nsIContent>        mContent;
   nsCString                   mDocumentBase;
   char                       *mTagText;
   nsCOMPtr<nsIWidget>         mWidget;
-  nsCOMPtr<nsITimer>          mPluginTimer;
   nsCOMPtr<nsIPluginHost>     mPluginHost;
 
 #ifdef XP_MACOSX
   NP_CGContext                mCGPluginPortCopy;
   NP_Port                     mQDPluginPortCopy;
   PRInt32                     mInCGPaintLevel;
 #endif
 
@@ -447,17 +445,16 @@ private:
   PRUint32                    mLastEventloopNestingLevel;
   PRPackedBool                mContentFocused;
   PRPackedBool                mWidgetVisible;    // used on Mac to store our widget's visible state
   PRPackedBool                mPluginPortChanged;
 
   // If true, destroy the widget on destruction. Used when plugin stop
   // is being delayed to a safer point in time.
   PRPackedBool                mDestroyWidget;
-  PRPackedBool                mTimerCanceled;
   PRUint16          mNumCachedAttrs;
   PRUint16          mNumCachedParams;
   char              **mCachedAttrParamNames;
   char              **mCachedAttrParamValues;
 
 #ifdef MOZ_COMPOSITED_PLUGINS
   nsIntPoint        mLastPoint;
 #endif
@@ -1363,17 +1360,17 @@ nsObjectFrame::PrintPlugin(nsIRenderingC
   PRBool windowless = PR_FALSE;
   pi->IsWindowless(&windowless);
   window.type = windowless ? NPWindowTypeDrawable : NPWindowTypeWindow;
 
   window.clipRect.bottom = 0; window.clipRect.top = 0;
   window.clipRect.left = 0; window.clipRect.right = 0;
   
 // platform specific printing code
-#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
+#ifdef MAC_CARBON_PLUGINS
   nsSize contentSize = GetContentRect().Size();
   window.x = 0;
   window.y = 0;
   window.width = presContext->AppUnitsToDevPixels(contentSize.width);
   window.height = presContext->AppUnitsToDevPixels(contentSize.height);
 
   gfxContext *ctx = aRenderingContext.ThebesContext();
   if (!ctx)
@@ -1670,19 +1667,36 @@ nsObjectFrame::PaintPlugin(nsIRenderingC
     NPWindow *window;
     mInstanceOwner->GetWindow(window);
 
     if (window->type == NPWindowTypeDrawable) {
       // check if we need to call SetWindow with updated parameters
       PRBool doupdatewindow = PR_FALSE;
       // the offset of the DC
       nsPoint origin;
-      
+
       gfxWindowsNativeDrawing nativeDraw(ctx, frameGfxRect);
-      PRBool doublePass = PR_FALSE;
+#ifdef MOZ_IPC
+      if (nativeDraw.IsDoublePass()) {
+        // OOP plugin specific: let the shim know before we paint if we are doing a
+        // double pass render. If this plugin isn't oop, the register window message
+        // will be ignored.
+        if (!mDoublePassEvent)
+          mDoublePassEvent = ::RegisterWindowMessage(NS_OOPP_DOUBLEPASS_MSGID);
+        if (mDoublePassEvent) {
+          NPEvent pluginEvent;
+          pluginEvent.event = mDoublePassEvent;
+          pluginEvent.wParam = 0;
+          pluginEvent.lParam = 0;
+          PRBool eventHandled = PR_FALSE;
+
+          inst->HandleEvent(&pluginEvent, &eventHandled);
+        }
+      }
+#endif
       do {
         HDC hdc = nativeDraw.BeginNativeDrawing();
         if (!hdc)
           return;
 
         RECT dest;
         nativeDraw.TransformToNativeRect(frameGfxRect, dest);
         RECT dirty;
@@ -1691,27 +1705,32 @@ nsObjectFrame::PaintPlugin(nsIRenderingC
         // XXX how can we be sure that window->window doesn't point to
         // a dead DC and hdc has been reallocated at the same address?
         if (reinterpret_cast<HDC>(window->window) != hdc ||
             window->x != dest.left || window->y != dest.top) {
           window->window = hdc;
           window->x = dest.left;
           window->y = dest.top;
 
-          // Windowless plugins on windows need a special event to update their location, see bug 135737
+          // Windowless plugins on windows need a special event to update their location,
+          // see bug 135737.
+          //
           // bug 271442: note, the rectangle we send is now purely the bounds of the plugin
-          // relative to the window it is contained in, which is useful for the plugin to correctly translate mouse coordinates
+          // relative to the window it is contained in, which is useful for the plugin to
+          // correctly translate mouse coordinates.
           //
           // this does not mesh with the comments for bug 135737 which imply that the rectangle
-          // must be clipped in some way to prevent the plugin attempting to paint over areas it shouldn't;
+          // must be clipped in some way to prevent the plugin attempting to paint over areas
+          // it shouldn't.
           //
-          // since the two uses of the rectangle are mutually exclusive in some cases,
-          // and since I don't see any incorrect painting (at least with Flash and ViewPoint - the originator of 135737),
-          // it seems that windowless plugins are not relying on information here for clipping their drawing,
-          // and we can safely use this message to tell the plugin exactly where it is in all cases.
+          // since the two uses of the rectangle are mutually exclusive in some cases, and
+          // since I don't see any incorrect painting (at least with Flash and ViewPoint -
+          // the originator of bug 135737), it seems that windowless plugins are not relying
+          // on information here for clipping their drawing, and we can safely use this message
+          // to tell the plugin exactly where it is in all cases.
 
           nsIntPoint origin = GetWindowOriginInPixels(PR_TRUE);
           nsIntRect winlessRect = nsIntRect(origin, nsIntSize(window->width, window->height));
           // XXX I don't think we can be certain that the location wrt to
           // the window only changes when the location wrt to the drawable
           // changes, but the hdc probably changes on every paint so
           // doupdatewindow is rarely false, and there is not likely to be
           // a problem.
@@ -1730,42 +1749,21 @@ nsObjectFrame::PaintPlugin(nsIRenderingC
             pluginEvent.event = WM_WINDOWPOSCHANGED;
             pluginEvent.wParam = 0;
             pluginEvent.lParam = (uint32)&winpos;
             PRBool eventHandled = PR_FALSE;
 
             inst->HandleEvent(&pluginEvent, &eventHandled);
           }
 
-          inst->SetWindow(window);        
+          inst->SetWindow(window);
         }
-
         mInstanceOwner->Paint(dirty, hdc);
         nativeDraw.EndNativeDrawing();
-        doublePass = nativeDraw.ShouldRenderAgain();
-#ifdef MOZ_IPC
-        if (doublePass) {
-          // OOP plugin specific: let the shim know we are in the middle of a double pass
-          // render. The second pass will reuse the previous rendering without going over
-          // the wire.
-          if (!mDoublePassEvent)
-            mDoublePassEvent = ::RegisterWindowMessage(NS_OOPP_DOUBLEPASS_MSGID);
-          if (mDoublePassEvent) {
-            NPEvent pluginEvent;
-            pluginEvent.event = mDoublePassEvent;
-            pluginEvent.wParam = 0;
-            pluginEvent.lParam = 0;
-            PRBool eventHandled = PR_FALSE;
-
-            inst->HandleEvent(&pluginEvent, &eventHandled);
-          }          
-        }
-#endif
-      } while (doublePass);
-
+      } while (nativeDraw.ShouldRenderAgain());
       nativeDraw.PaintToContext();
     } else if (!(ctx->GetFlags() & gfxContext::FLAG_DESTINED_FOR_SCREEN)) {
       // Get PrintWindow dynamically since it's not present on Win2K,
       // which we still support
       typedef BOOL (WINAPI * PrintWindowPtr)
           (HWND hwnd, HDC hdcBlt, UINT nFlags);
       PrintWindowPtr printProc = nsnull;
       HMODULE module = ::GetModuleHandleW(L"user32.dll");
@@ -1927,17 +1925,19 @@ nsObjectFrame::HandleEvent(nsPresContext
   if ((anEvent->message == NS_MOUSE_ENTER || anEvent->message == NS_MOUSE_SCROLL) &&
       mInstanceOwner->GetEventModel() == NPEventModelCocoa) {
     *anEventStatus = mInstanceOwner->ProcessEvent(*anEvent);
     return rv;
   }
 #endif
 
   if (anEvent->message == NS_DESTROY) {
+#ifdef MAC_CARBON_PLUGINS
     mInstanceOwner->CancelTimer();
+#endif
     return rv;
   }
 
   return nsObjectFrameSuper::HandleEvent(aPresContext, anEvent, anEventStatus);
 }
 
 nsresult
 nsObjectFrame::GetPluginInstance(nsIPluginInstance*& aPluginInstance)
@@ -2427,17 +2427,16 @@ nsPluginInstanceOwner::nsPluginInstanceO
   mContentFocused = PR_FALSE;
   mWidgetVisible = PR_TRUE;
   mPluginPortChanged = PR_FALSE;
   mNumCachedAttrs = 0;
   mNumCachedParams = 0;
   mCachedAttrParamNames = nsnull;
   mCachedAttrParamValues = nsnull;
   mDestroyWidget = PR_FALSE;
-  mTimerCanceled = PR_TRUE;
 
 #ifdef MOZ_COMPOSITED_PLUGINS
   mLastPoint = nsIntPoint(0,0);
 #endif
 
 #if defined(MOZ_PLATFORM_HILDON) && defined(MOZ_WIDGET_GTK2)
   mPluginSize = nsIntSize(0,0);
   mXlibSurfGC = None;
@@ -2458,18 +2457,19 @@ nsPluginInstanceOwner::nsPluginInstanceO
 
 nsPluginInstanceOwner::~nsPluginInstanceOwner()
 {
   PRInt32 cnt;
 
   PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
          ("nsPluginInstanceOwner %p deleted\n", this));
 
-  // shut off the timer.
+#ifdef MAC_CARBON_PLUGINS
   CancelTimer();
+#endif
 
   mObjectFrame = nsnull;
 
   for (cnt = 0; cnt < (mNumCachedAttrs + 1 + mNumCachedParams); cnt++) {
     if (mCachedAttrParamNames && mCachedAttrParamNames[cnt]) {
       NS_Free(mCachedAttrParamNames[cnt]);
       mCachedAttrParamNames[cnt] = nsnull;
     }
@@ -2516,17 +2516,16 @@ nsPluginInstanceOwner::~nsPluginInstance
  */
 
 NS_IMPL_ADDREF(nsPluginInstanceOwner)
 NS_IMPL_RELEASE(nsPluginInstanceOwner)
 
 NS_INTERFACE_MAP_BEGIN(nsPluginInstanceOwner)
   NS_INTERFACE_MAP_ENTRY(nsIPluginInstanceOwner)
   NS_INTERFACE_MAP_ENTRY(nsIPluginTagInfo)
-  NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMouseMotionListener)
   NS_INTERFACE_MAP_ENTRY(nsIDOMKeyListener)
   NS_INTERFACE_MAP_ENTRY(nsIDOMFocusListener)
   NS_INTERFACE_MAP_ENTRY(nsIScrollPositionListener)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMMouseListener)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPluginInstanceOwner)
 NS_INTERFACE_MAP_END
@@ -3566,17 +3565,17 @@ nsPluginInstanceOwner::GetEventloopNesti
     currentLevel++;
   }
 
   return currentLevel;
 }
 
 nsresult nsPluginInstanceOwner::ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY)
 {
-#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
+#ifdef MAC_CARBON_PLUGINS
   if (GetEventModel() != NPEventModelCarbon)
     return NS_OK;
 
   CancelTimer();
 
   if (mInstance) {
     nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
     if (pluginWidget && NS_SUCCEEDED(pluginWidget->StartDrawPlugin())) {
@@ -3593,17 +3592,17 @@ nsresult nsPluginInstanceOwner::ScrollPo
     }
   }
 #endif
   return NS_OK;
 }
 
 nsresult nsPluginInstanceOwner::ScrollPositionDidChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY)
 {
-#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
+#ifdef MAC_CARBON_PLUGINS
   if (GetEventModel() != NPEventModelCarbon)
     return NS_OK;
 
   if (mInstance) {
     nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
     if (pluginWidget && NS_SUCCEEDED(pluginWidget->StartDrawPlugin())) {
       EventRecord scrollEvent;
       InitializeEventRecord(&scrollEvent, nsnull);
@@ -3612,19 +3611,19 @@ nsresult nsPluginInstanceOwner::ScrollPo
       void* window = FixUpPluginWindow(ePluginPaintEnable);
       if (window) {
         PRBool eventHandled = PR_FALSE;
         mInstance->HandleEvent(&scrollEvent, &eventHandled);
       }
       pluginWidget->EndDrawPlugin();
     }
   }
+
+  StartTimer(PR_TRUE);
 #endif
-
-  StartTimer(NORMAL_PLUGIN_DELAY);
   return NS_OK;
 }
 
 /*=============== nsIFocusListener ======================*/
 nsresult nsPluginInstanceOwner::Focus(nsIDOMEvent * aFocusEvent)
 {
   mContentFocused = PR_TRUE;
   return DispatchFocusToPlugin(aFocusEvent);
@@ -3674,17 +3673,17 @@ nsresult nsPluginInstanceOwner::KeyDown(
 
 nsresult nsPluginInstanceOwner::KeyUp(nsIDOMEvent* aKeyEvent)
 {
   return DispatchKeyToPlugin(aKeyEvent);
 }
 
 nsresult nsPluginInstanceOwner::KeyPress(nsIDOMEvent* aKeyEvent)
 {
-#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
+#ifdef MAC_CARBON_PLUGINS
   // send KeyPress events only for Mac OS X Carbon event model
   if (GetEventModel() != NPEventModelCarbon)
     return aKeyEvent->PreventDefault();
 
   // KeyPress events are really synthesized keyDown events.
   // Here we check the native message of the event so that
   // we won't send the plugin two keyDown events.
   nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(aKeyEvent));
@@ -4629,18 +4628,20 @@ nsEventStatus nsPluginInstanceOwner::Pro
 #endif
 
   return rv;
 }
 
 nsresult
 nsPluginInstanceOwner::Destroy()
 {
+#ifdef MAC_CARBON_PLUGINS
   // stop the timer explicitly to reduce reference count.
   CancelTimer();
+#endif
 
   // unregister context menu listener
   if (mCXMenuListener) {
     mCXMenuListener->Destroy(mContent);
     mCXMenuListener = nsnull;
   }
 
   nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(mContent));
@@ -5356,24 +5357,19 @@ nsPluginInstanceOwner::Renderer::NativeD
     XFreeGC(GDK_DISPLAY(), gc);
   }
 #endif
 #endif
   return NS_OK;
 }
 #endif
 
-// Here's how we give idle time to plugins.
-
-NS_IMETHODIMP nsPluginInstanceOwner::Notify(nsITimer* timer)
+void nsPluginInstanceOwner::SendIdleEvent()
 {
-#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
-  if (GetEventModel() != NPEventModelCarbon)
-    return NS_OK;
-
+#ifdef MAC_CARBON_PLUGINS
   // validate the plugin clipping information by syncing the plugin window info to
   // reflect the current widget location. This makes sure that everything is updated
   // correctly in the event of scrolling in the window.
   if (mInstance) {
     nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
     if (pluginWidget && NS_SUCCEEDED(pluginWidget->StartDrawPlugin())) {
       void* window = FixUpPluginWindow(ePluginPaintEnable);
       if (window) {
@@ -5389,46 +5385,32 @@ NS_IMETHODIMP nsPluginInstanceOwner::Not
         PRBool eventHandled = PR_FALSE;
         mInstance->HandleEvent(&idleEvent, &eventHandled);
       }
 
       pluginWidget->EndDrawPlugin();
     }
   }
 #endif
-  return NS_OK;
 }
 
-void nsPluginInstanceOwner::StartTimer(unsigned int aDelay)
+#ifdef MAC_CARBON_PLUGINS
+void nsPluginInstanceOwner::StartTimer(PRBool isVisible)
 {
-#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
   if (GetEventModel() != NPEventModelCarbon)
     return;
 
-  if (!mTimerCanceled)
-    return;
-
-  // start a periodic timer to provide null events to the plugin instance.
-  if (!mPluginTimer) {
-    mPluginTimer = do_CreateInstance("@mozilla.org/timer;1");
-  }
-  if (mPluginTimer) {
-    mTimerCanceled = PR_FALSE;
-    mPluginTimer->InitWithCallback(this, aDelay, nsITimer::TYPE_REPEATING_SLACK);
-  }
-#endif
+  mPluginHost->AddIdleTimeTarget(this, isVisible);
 }
 
 void nsPluginInstanceOwner::CancelTimer()
 {
-  if (mPluginTimer) {
-    mPluginTimer->Cancel();
-  }
-  mTimerCanceled = PR_TRUE;
+  mPluginHost->RemoveIdleTimeTarget(this);
 }
+#endif
 
 nsresult nsPluginInstanceOwner::Init(nsPresContext* aPresContext,
                                      nsObjectFrame* aFrame,
                                      nsIContent*    aContent)
 {
   mLastEventloopNestingLevel = GetEventloopNestingLevel();
 
   PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
@@ -5591,18 +5573,20 @@ NS_IMETHODIMP nsPluginInstanceOwner::Cre
           mWidget->Resize(mPluginWindow->width, mPluginWindow->height,
                           PR_FALSE);
 
           // mPluginWindow->type is used in |GetPluginPort| so it must
           // be initialized first
           mPluginWindow->type = NPWindowTypeWindow;
           mPluginWindow->window = GetPluginPort();
 
+#ifdef MAC_CARBON_PLUGINS
           // start the idle timer.
-          StartTimer(NORMAL_PLUGIN_DELAY);
+          StartTimer(PR_TRUE);
+#endif
 
           // tell the plugin window about the widget
           mPluginWindow->SetPluginWidget(mWidget);
 
           // tell the widget about the current plugin instance owner.
           nsCOMPtr<nsIPluginWidget> pluginWidget = do_QueryInterface(mWidget);
           if (pluginWidget)
             pluginWidget->SetPluginInstanceOwner(this);
@@ -5633,17 +5617,17 @@ PRBool nsPluginInstanceOwner::UpdateVisi
   visibilityEvent.state = VisibilityUnobscured;
   mInstance->HandleEvent(&pluginEvent, &handled);
 
   mWidgetVisible = PR_TRUE;
   return PR_TRUE;
 }
 #endif
 
-  // Mac specific code to fix up the port location and clipping region
+// Mac specific code to fix up the port location and clipping region
 #ifdef XP_MACOSX
 
 void* nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
 {
   if (!mWidget || !mPluginWindow || !mInstance || !mObjectFrame)
     return nsnull;
 
   NPDrawingModel drawingModel = GetDrawingModel();
@@ -5729,25 +5713,27 @@ void* nsPluginInstanceOwner::FixUpPlugin
   // (RealPlayer needs this to draw correctly)
   if (mPluginWindow->clipRect.left    != oldClipRect.left   ||
       mPluginWindow->clipRect.top     != oldClipRect.top    ||
       mPluginWindow->clipRect.right   != oldClipRect.right  ||
       mPluginWindow->clipRect.bottom  != oldClipRect.bottom)
   {
     mInstance->SetWindow(mPluginWindow);
     mPluginPortChanged = PR_FALSE;
+#ifdef MAC_CARBON_PLUGINS
     // if the clipRect is of size 0, make the null timer fire less often
     CancelTimer();
     if (mPluginWindow->clipRect.left == mPluginWindow->clipRect.right ||
         mPluginWindow->clipRect.top == mPluginWindow->clipRect.bottom) {
-      StartTimer(HIDDEN_PLUGIN_DELAY);
+      StartTimer(PR_FALSE);
     }
     else {
-      StartTimer(NORMAL_PLUGIN_DELAY);
+      StartTimer(PR_TRUE);
     }
+#endif
   } else if (mPluginPortChanged) {
     mInstance->SetWindow(mPluginWindow);
     mPluginPortChanged = PR_FALSE;
   }
 
 #ifndef NP_NO_QUICKDRAW
   if (drawingModel == NPDrawingModelQuickDraw)
     return ::GetWindowFromPort(static_cast<NP_Port*>(pluginPort)->port);
--- a/layout/generic/test/file_bug514732_helper.html
+++ b/layout/generic/test/file_bug514732_helper.html
@@ -62,53 +62,57 @@ function getDocBodyDimensions(doc) {
 
 function makeResult() {
   return {
     success: false,
     event: null
   };
 }
 
-function waitInterrupt(result, gen, timewait) {
+function makeListener(result, eventGen) {
+  return function(ev) {
+    result.success = true;
+    result.event = ev;
+    setTimeout(function() { eventGen.next(); }, 0);
+  };
+}
+
+function waitInterrupt(result, gen) {
   result.event = null;
   result.success = false;
-  setTimeout(function() { if (!result.success) gen.next(); }, (timewait || 2000));
+  setTimeout(function() { if (!result.success) gen.next(); }, 3500);
 }
 
 function testPhoom(isCapturing, x, y, expectEvent) {
-  var result;
 
   var eventGen = (function() {
     var innerdoc = document.getElementById('testframe').contentDocument;
 
     for each (var doc in [document, innerdoc]) {
       var inner = (doc == innerdoc);
-      var w, h;
-      var listener = function(ev) {
-        result.success = true;
-        result.event = ev;
-        setTimeout(function() { eventGen.next(); }, 0);
-      };
+      var w, h, result, listener;
 
       /* --- EXPANSION --- */
 
+      result = makeResult();
+      listener = makeListener(result, eventGen);
+
       doc.addEventListener("MozScrolledAreaChanged", listener, isCapturing);
 
-      result = makeResult();
-      waitInterrupt(result, eventGen, 1200);
+      if (!expectEvent) waitInterrupt(result, eventGen);
       phoom(doc, x, y);
       yield;
 
       doc.removeEventListener("MozScrolledAreaChanged", listener, isCapturing);
 
       /* If we're expecting an event, better check that we got one.  If we are not expecting one,
          one can still arrive, but we don't complain if it did not.  In either case, any event
          that arrives will have its data checked below. */
       if (expectEvent) {
-        ok(result.success, "Received expected expansion event");
+        ok(result.success, "Received expected " + (inner ? "inner" : "") + " expansion event");
       }
 
       if (result.success) {
         is(result.event.x, 0, "Expansion event x is 0");
         is(result.event.y, 0, "Expansion event y is 0");
         if (inner) {
           /* In iframe-land, the values of |myiframe.contentDocument.documentElement.scrollWidth| and
              |.scrollHeight| appear to be not as expected (they stay very small).  This is fine, since
@@ -124,27 +128,29 @@ function testPhoom(isCapturing, x, y, ex
           [w, h] = getDocBodyDimensions(doc);
           is(Math.round(result.event.width),  w, "Expansion event width matches body width");
           is(Math.round(result.event.height), h, "Expansion event height matches body height");
         }
       }
 
       /* --- CONTRACTION --- */
 
+      result = makeResult();
+      listener = makeListener(result, eventGen);
+
       doc.addEventListener("MozScrolledAreaChanged", listener, isCapturing);
 
-      result = makeResult();
-      waitInterrupt(result, eventGen, 1200);
+      if (!expectEvent) waitInterrupt(result, eventGen);
       unphoom(doc);
       yield;
 
       doc.removeEventListener("MozScrolledAreaChanged", listener, isCapturing);
 
       if (expectEvent) {
-        ok(result.success, "Received expected contraction event");
+        ok(result.success, "Received expected " + (inner ? "inner" : "") + " contraction event");
       }
 
       if (result.success) {
         is(result.event.x, 0, "Contraction event x is 0");
         is(result.event.y, 0, "Contraction event y is 0");
         if (inner) {
           is(Math.round(result.event.width),  300, "Inner contraction event width matches body width");
           is(Math.round(result.event.height), 150, "Inner contraction event height matches body height");
--- a/layout/printing/nsPrintEngine.cpp
+++ b/layout/printing/nsPrintEngine.cpp
@@ -1873,18 +1873,20 @@ nsPrintEngine::ReflowPrintObject(nsPrint
 
   if (aPO->mParent && aPO->mParent->IsPrintable()) {
     if (aPO->mParent->mPresShell) {
       frame = aPO->mParent->mPresShell->FrameManager()->
         GetPrimaryFrameFor(aPO->mContent, -1);
     }
     // Without a frame, this document can't be displayed; therefore, there is no
     // point to reflowing it
-    if (!frame)
+    if (!frame) {
+      aPO->mDontPrint = PR_TRUE;
       return NS_OK;
+    }
 
     adjSize = frame->GetContentRect().Size();
     documentIsTopLevel = PR_FALSE;
     // presshell exists because parent is printable
   } else {
     nscoord pageWidth, pageHeight;
     mPrt->mPrintDC->GetDeviceSurfaceDimensions(pageWidth, pageHeight);
 #if defined(XP_UNIX) && !defined(XP_MACOSX)
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/height-dependence-1-ref.html
@@ -0,0 +1,43 @@
+<!doctype html>
+<html><head>
+<style>
+html {
+  background-image: -moz-linear-gradient(black, white 20%);
+  background-repeat: repeat-x;
+}
+body {
+  font-size: 1em;
+  padding: 2em;
+  margin: 50px auto;
+  width: 14em;
+  border: 1px solid black;
+  background-color: white;
+}
+</style>
+</head><body>
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/height-dependence-1.html
@@ -0,0 +1,49 @@
+<!doctype html>
+<html class="reftest-wait"><head>
+<style>
+html {
+  background-image: -moz-linear-gradient(black, white 20%);
+  background-repeat: repeat-x;
+}
+body {
+  font-size: 1em;
+  padding: 2em;
+  margin: 50px auto;
+  width: 28em;
+  border: 1px solid black;
+  background-color: white;
+}
+</style>
+<script>
+window.addEventListener("MozReftestInvalidate", function() {
+  document.body.style.width = "14em";
+  document.documentElement.removeAttribute("class");
+}, false);
+</script>
+</head><body>
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/height-dependence-2-ref.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html><head>
+<style>
+html {
+  background-image: -moz-linear-gradient(black, white 20%);
+  background-repeat: repeat-x;
+  -moz-background-size: 1px 400px;
+}
+body {
+  font-size: 1em;
+  padding: 2em;
+  margin: 50px auto;
+  width: 14em;
+  border: 1px solid black;
+  background-color: white;
+}
+</style>
+</head><body>
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/height-dependence-2.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<html class="reftest-wait"><head>
+<style>
+html {
+  background-image: -moz-linear-gradient(black, white 20%);
+  background-repeat: repeat-x;
+  -moz-background-size: 1px 400px;
+}
+body {
+  font-size: 1em;
+  padding: 2em;
+  margin: 50px auto;
+  width: 28em;
+  border: 1px solid black;
+  background-color: white;
+}
+</style>
+<script>
+window.addEventListener("MozReftestInvalidate", function() {
+  document.body.style.width = "14em";
+  document.documentElement.removeAttribute("class");
+}, false);
+</script>
+</head><body>
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/height-dependence-3-ref.html
@@ -0,0 +1,44 @@
+<!doctype html>
+<html><head>
+<style>
+html {
+  background-image: -moz-linear-gradient(black, white 20%);
+  background-repeat: repeat-x;
+  -moz-background-size: 1px 80%;
+}
+body {
+  font-size: 1em;
+  padding: 2em;
+  margin: 50px auto;
+  width: 14em;
+  border: 1px solid black;
+  background-color: white;
+}
+</style>
+</head><body>
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-gradients/height-dependence-3.html
@@ -0,0 +1,50 @@
+<!doctype html>
+<html class="reftest-wait"><head>
+<style>
+html {
+  background-image: -moz-linear-gradient(black, white 20%);
+  background-repeat: repeat-x;
+  -moz-background-size: 1px 80%;
+}
+body {
+  font-size: 1em;
+  padding: 2em;
+  margin: 50px auto;
+  width: 28em;
+  border: 1px solid black;
+  background-color: white;
+}
+</style>
+<script>
+window.addEventListener("MozReftestInvalidate", function() {
+  document.body.style.width = "14em";
+  document.documentElement.removeAttribute("class");
+}, false);
+</script>
+</head><body>
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+pad pad pad pad pad pad pad pad
+</body>
+</html>
--- a/layout/reftests/css-gradients/reftest.list
+++ b/layout/reftests/css-gradients/reftest.list
@@ -80,9 +80,11 @@ fails == aja-linear-2c.html aja-linear-2
 fails == aja-linear-2d.html aja-linear-2-ref.html # bug 526694
 == aja-linear-3a.html aja-linear-3-ref.html
 == aja-linear-3b.html aja-linear-3-ref.html
 == aja-linear-4a.html aja-linear-4-ref.html
 == aja-linear-4b.html aja-linear-4-ref.html
 == aja-linear-5a.html aja-linear-5-ref.html
 fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == aja-linear-6a.html aja-linear-6-ref.html # bug 526708
 fails == aja-linear-6b.html aja-linear-6-ref.html # bug 522607
-
+== height-dependence-1.html height-dependence-1-ref.html
+fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == height-dependence-2.html height-dependence-2-ref.html # bug 535007
+== height-dependence-3.html height-dependence-3-ref.html
--- a/layout/style/nsCSSDeclaration.cpp
+++ b/layout/style/nsCSSDeclaration.cpp
@@ -871,16 +871,22 @@ nsCSSDeclaration::GetValue(nsCSSProperty
         * data->ValuePairListStorageFor(eCSSProperty_background_position);
       const nsCSSValueList *clip =
         * data->ValueListStorageFor(eCSSProperty__moz_background_clip);
       const nsCSSValueList *origin =
         * data->ValueListStorageFor(eCSSProperty__moz_background_origin);
       const nsCSSValuePairList *size =
         * data->ValuePairListStorageFor(eCSSProperty__moz_background_size);
       for (;;) {
+        if (size->mXValue.GetUnit() != eCSSUnit_Auto ||
+            size->mYValue.GetUnit() != eCSSUnit_Auto) {
+          // Non-default background-size, so can't be serialized as shorthand.
+          aValue.Truncate();
+          return NS_OK;
+        }
         AppendCSSValueToString(eCSSProperty_background_image,
                                image->mValue, aValue);
         aValue.Append(PRUnichar(' '));
         AppendCSSValueToString(eCSSProperty_background_repeat,
                                repeat->mValue, aValue);
         aValue.Append(PRUnichar(' '));
         AppendCSSValueToString(eCSSProperty_background_attachment,
                                attachment->mValue, aValue);
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -408,20 +408,29 @@ struct nsStyleBackground {
       ePercentage,
 
       eAuto,
       eLength,
       eDimensionType_COUNT
     };
     PRUint8 mWidthType, mHeightType;
 
-    // True if the effective image size described by this depends on the size
-    // of the corresponding frame.
-    PRBool DependsOnFrameSize() const {
-      return mWidthType <= ePercentage || mHeightType <= ePercentage;
+    // True if the effective image size described by this depends on
+    // the size of the corresponding frame.  Gradients depend on the
+    // frame size when their dimensions are 'auto', images don't; both
+    // types depend on the frame size when their dimensions are
+    // 'contain', 'cover', or a percentage.
+    PRBool DependsOnFrameSize(nsStyleImageType aType) const {
+      if (aType == eStyleImageType_Image) {
+        return mWidthType <= ePercentage || mHeightType <= ePercentage;
+      } else {
+        NS_ABORT_IF_FALSE(aType == eStyleImageType_Gradient,
+                          "unrecognized image type");
+        return mWidthType <= eAuto || mHeightType <= eAuto;
+      }
     }
 
     // Initialize nothing
     Size() {}
 
     // Initialize to initial values
     void SetInitialValues();
 
@@ -443,22 +452,24 @@ struct nsStyleBackground {
     Size mSize;                         // [reset]
 
     // Initializes only mImage
     Layer();
     ~Layer();
 
     void SetInitialValues();
 
-    // True if the rendering of this layer might change when the size of the
-    // corresponding frame changes (if its position or size is a percentage of
-    // the frame's dimensions).
+    // True if the rendering of this layer might change when the size
+    // of the corresponding frame changes.  This is true for any
+    // non-solid-color background whose position or size depends on
+    // the frame size.
     PRBool RenderingMightDependOnFrameSize() const {
-      return !mImage.IsEmpty() &&
-             (mPosition.DependsOnFrameSize() || mSize.DependsOnFrameSize());
+      return (!mImage.IsEmpty() &&
+              (mPosition.DependsOnFrameSize() ||
+               mSize.DependsOnFrameSize(mImage.GetType())));
     }
 
     // An equality operator that compares the images using URL-equality
     // rather than pointer-equality.
     PRBool operator==(const Layer& aOther) const;
     PRBool operator!=(const Layer& aOther) const {
       return !(*this == aOther);
     }
--- a/layout/style/test/test_shorthand_property_getters.html
+++ b/layout/style/test/test_shorthand_property_getters.html
@@ -117,39 +117,45 @@ e.setAttribute("style", "background: red
 is(e.style.background, "", "should not have background shorthand (clip:padding)");
 e.setAttribute("style", "background: red; -moz-background-origin: content");
 is(e.style.background, "", "should not have background shorthand (origin:content)");
 // -moz-background-clip:content not yet supported
 //e.setAttribute("style", "background: red; -moz-background-clip: content");
 //is(e.style.background, "", "should not have background shorthand (clip:content)");
 //e.setAttribute("style", "background: red; -moz-background-clip: content; -moz-background-origin: content;");
 //isnot(e.style.background, "", "should have background shorthand (clip:content;origin:content)");
+e.setAttribute("style", "background: red; -moz-background-size: 100% 100%");
+is(e.style.background, "", "should not have background shorthand (size:100% 100%)");
+e.setAttribute("style", "background: red; -moz-background-size: 100% auto");
+is(e.style.background, "", "should not have background shorthand (size:100% auto)");
+e.setAttribute("style", "background: red; -moz-background-size: auto 100%");
+is(e.style.background, "", "should not have background shorthand (size:auto 100%)");
 e.setAttribute("style", "background: red; -moz-background-inline-policy: each-box");
 isnot(e.style.background, "", "should have background shorthand (-moz-background-inline-policy not relevant)");
 
 // Check that we only serialize background when the lists (of layers) for
 // the subproperties are the same length.
 // XXX Should change background-clip to border,padding,border and
-// background-origin to border,padding,padding once serialization does
-// clip/origin.
-e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
+// background-origin to border,padding,padding and background-size to
+// cover,auto,contain once serialization does clip/origin/size.
+e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
 isnot(e.style.background, "", "should have background shorthand (all lists length 3)");
-e.setAttribute("style", "-moz-background-clip: border, border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
+e.setAttribute("style", "-moz-background-clip: border, border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
 is(e.style.background, "", "should not have background shorthand (background-clip too long)");
-e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: border, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
+e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
 is(e.style.background, "", "should not have background shorthand (background-origin too short)");
-e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png), none; background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
+e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png), none; background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
 is(e.style.background, "", "should not have background shorthand (background-image too long)");
-e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
+e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
 is(e.style.background, "", "should not have background shorthand (background-attachment too short)");
-e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px, bottom; background-repeat: repeat-x, repeat, no-repeat");
+e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px, bottom; background-repeat: repeat-x, repeat, no-repeat");
 is(e.style.background, "", "should not have background shorthand (background-position too long)");
-e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat");
+e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat");
 is(e.style.background, "", "should not have background shorthand (background-repeat too short)");
-e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain, cover; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
+e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
 is(e.style.background, "", "should not have background shorthand (-moz-background-size too long)");
 
 // Check that we only serialize transition when the lists are the same length.
 e.setAttribute("style", "-moz-transition-property: color, width; -moz-transition-duration: 1s, 200ms; -moz-transition-timing-function: ease-in, linear; -moz-transition-delay: 0s, 1s");
 isnot(e.style.MozTransition, "", "should have -moz-transition shorthand (lists same length)");
 e.setAttribute("style", "-moz-transition-property: color, width, left; -moz-transition-duration: 1s, 200ms; -moz-transition-timing-function: ease-in, linear; -moz-transition-delay: 0s, 1s");
 is(e.style.MozTransition, "", "should not have -moz-transition shorthand (lists different lengths)");
 e.setAttribute("style", "-moz-transition-property: all; -moz-transition-duration: 1s, 200ms; -moz-transition-timing-function: ease-in, linear; -moz-transition-delay: 0s, 1s");
--- a/layout/tools/reftest/reftest.js
+++ b/layout/tools/reftest/reftest.js
@@ -697,18 +697,21 @@ function OnDocumentLoad(event)
        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;
+       // And on Mac, it causes *three* assertions.
+       var xr = CC[NS_XREAPPINFO_CONTRACTID].getService(CI.nsIXULRuntime);
+       var count = (xr.widgetToolkit == "cocoa") ? 3 : 2;
+       gURLs[0].minAsserts += count;
+       gURLs[0].maxAsserts += count;
     }
 
     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.
--- a/layout/xul/base/src/nsScrollBoxFrame.cpp
+++ b/layout/xul/base/src/nsScrollBoxFrame.cpp
@@ -72,17 +72,22 @@ public:
                            nsGUIEvent*     aEvent,
                            nsEventStatus*  aEventStatus);
 
 protected:
   nsAutoRepeatBoxFrame(nsIPresShell* aPresShell, nsStyleContext* aContext):
     nsButtonBoxFrame(aPresShell, aContext) {}
   
   void StartRepeat() {
-    nsRepeatService::GetInstance()->Start(Notify, this, 0);
+    if (IsActivatedOnHover()) {
+      // No initial delay on hover.
+      nsRepeatService::GetInstance()->Start(Notify, this, 0);
+    } else {
+      nsRepeatService::GetInstance()->Start(Notify, this);
+    }
   }
   void StopRepeat() {
     nsRepeatService::GetInstance()->Stop(Notify, this);
   }
   void Notify();
   static void Notify(void* aData) {
     static_cast<nsAutoRepeatBoxFrame*>(aData)->Notify();
   }
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -54,35 +54,46 @@ pref("general.useragent.locale", "chrome
 pref("general.config.obscure_value", 13); // for MCD .cfg files
 
 pref("general.warnOnAboutConfig", true);
 
 // maximum number of dated backups to keep at any time
 pref("browser.bookmarks.max_backups",       5);
 
 pref("browser.cache.disk.enable",           true);
+#ifndef WINCE
 pref("browser.cache.disk.capacity",         51200);
+#else
+pref("browser.cache.disk.capacity",         20000);
+#endif
 pref("browser.cache.memory.enable",         true);
 //pref("browser.cache.memory.capacity",     -1);
 // -1 = determine dynamically, 0 = none, n = memory capacity in kilobytes
 pref("browser.cache.disk_cache_ssl",        false);
 // 0 = once-per-session, 1 = each-time, 2 = never, 3 = when-appropriate/automatically
 pref("browser.cache.check_doc_frequency",   3);
 
 pref("browser.cache.offline.enable",           true);
+#ifndef WINCE
 // offline cache capacity in kilobytes
 pref("browser.cache.offline.capacity",         512000);
 
 // offline apps should be limited to this much data in global storage
 // (in kilobytes)
 pref("offline-apps.quota.max",        204800);
 
 // the user should be warned if offline app disk usage exceeds this amount
 // (in kilobytes)
 pref("offline-apps.quota.warn",        51200);
+#else
+// Limited disk space on WinCE, tighten limits.
+pref("browser.cache.offline.capacity", 15000);
+pref("offline-apps.quota.max",          7000);
+pref("offline-apps.quota.warn",         4000);
+#endif
 
 // Fastback caching - if this pref is negative, then we calculate the number
 // of content viewers to cache based on the amount of available memory.
 pref("browser.sessionhistory.max_total_viewers", -1);
 
 pref("ui.use_native_colors", true);
 pref("ui.use_native_popup_windows", false);
 pref("browser.display.use_document_fonts",  1);  // 0 = never, 1 = quick, 2 = always
--- a/modules/libpref/src/nsPrefBranch.cpp
+++ b/modules/libpref/src/nsPrefBranch.cpp
@@ -62,16 +62,17 @@ struct EnumerateData {
   const char  *parent;
   nsVoidArray *pref_list;
 };
 
 struct PrefCallbackData {
   nsPrefBranch     *pBranch;
   nsIObserver      *pObserver;
   nsIWeakReference *pWeakRef;
+  char pDomain[1];
 };
 
 
 // Prototypes
 static PLDHashOperator
   pref_enumChild(PLDHashTable *table, PLDHashEntryHdr *heh,
                  PRUint32 i, void *arg);
 static nsresult
@@ -586,17 +587,17 @@ NS_IMETHODIMP nsPrefBranch::AddObserver(
   NS_ENSURE_ARG_POINTER(aObserver);
 
   if (!mObservers) {
     mObservers = new nsAutoVoidArray();
     if (nsnull == mObservers)
       return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  pCallback = (PrefCallbackData *)nsMemory::Alloc(sizeof(PrefCallbackData));
+  pCallback = (PrefCallbackData *)NS_Alloc(sizeof(PrefCallbackData) + strlen(aDomain));
   if (nsnull == pCallback)
     return NS_ERROR_OUT_OF_MEMORY;
 
   pCallback->pBranch = this;
   pCallback->pObserver = aObserver;
 
   // hold a weak reference to the observer if so requested
   if (aHoldWeak) {
@@ -608,18 +609,18 @@ NS_IMETHODIMP nsPrefBranch::AddObserver(
     }
     nsCOMPtr<nsIWeakReference> tmp = do_GetWeakReference(weakRefFactory);
     NS_ADDREF(pCallback->pWeakRef = tmp);
   } else {
     pCallback->pWeakRef = nsnull;
     NS_ADDREF(pCallback->pObserver);
   }
 
+  strcpy(pCallback->pDomain, aDomain);
   mObservers->AppendElement(pCallback);
-  mObserverDomains.AppendElement(nsCString(aDomain));
 
   // We must pass a fully qualified preference name to the callback
   pref = getPrefName(aDomain); // aDomain == nsnull only possible failure, trapped above
   PREF_RegisterCallback(pref, NotifyObserver, pCallback);
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aObserver)
@@ -639,38 +640,34 @@ NS_IMETHODIMP nsPrefBranch::RemoveObserv
     
   // need to find the index of observer, so we can remove it from the domain list too
   count = mObservers->Count();
   if (count == 0)
     return NS_OK;
 
   for (i = 0; i < count; i++) {
     pCallback = (PrefCallbackData *)mObservers->ElementAt(i);
-    if (pCallback) {
-      if (pCallback->pObserver == aObserver) {
-        domain = mObserverDomains[i];
-        if (domain.Equals(aDomain)) {
-          // We must pass a fully qualified preference name to remove the callback
-          pref = getPrefName(aDomain); // aDomain == nsnull only possible failure, trapped above
-          rv = PREF_UnregisterCallback(pref, NotifyObserver, pCallback);
-          if (NS_SUCCEEDED(rv)) {
-            // Remove this observer from our array so that nobody else can remove
-            // what we're trying to remove ourselves right now.
-            mObservers->RemoveElementAt(i);
-            mObserverDomains.RemoveElementAt(i);
-            if (pCallback->pWeakRef) {
-              NS_RELEASE(pCallback->pWeakRef);
-            } else {
-              NS_RELEASE(pCallback->pObserver);
-            }
-            nsMemory::Free(pCallback);
-          }
-          return rv;
+    if (pCallback &&
+        pCallback->pObserver == aObserver &&
+        !strcmp(pCallback->pDomain, aDomain)) {
+      // We must pass a fully qualified preference name to remove the callback
+      pref = getPrefName(aDomain); // aDomain == nsnull only possible failure, trapped above
+      rv = PREF_UnregisterCallback(pref, NotifyObserver, pCallback);
+      if (NS_SUCCEEDED(rv)) {
+        // Remove this observer from our array so that nobody else can remove
+        // what we're trying to remove ourselves right now.
+        mObservers->RemoveElementAt(i);
+        if (pCallback->pWeakRef) {
+          NS_RELEASE(pCallback->pWeakRef);
+        } else {
+          NS_RELEASE(pCallback->pObserver);
         }
+        NS_Free(pCallback);
       }
+      return rv;
     }
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP nsPrefBranch::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData)
 {
@@ -690,17 +687,17 @@ static nsresult NotifyObserver(const cha
   PRUint32 len = pData->pBranch->GetRootLength();
   nsCAutoString suffix(newpref + len);  
 
   nsCOMPtr<nsIObserver> observer;
   if (pData->pWeakRef) {
     observer = do_QueryReferent(pData->pWeakRef);
     if (!observer) {
       // this weak referenced observer went away, remove them from the list
-      pData->pBranch->RemoveObserver(newpref, pData->pObserver);
+      pData->pBranch->RemoveObserver(pData->pDomain, pData->pObserver);
       return NS_OK;
     }
   } else {
     observer = pData->pObserver;
   }
 
   observer->Observe(static_cast<nsIPrefBranch *>(pData->pBranch),
                     NS_PREFBRANCH_PREFCHANGE_TOPIC_ID,
@@ -720,34 +717,30 @@ void nsPrefBranch::freeObserverList(void
 
     count = mObservers->Count();
     if (count > 0) {
       PRInt32 i;
       nsCAutoString domain;
       for (i = 0; i < count; ++i) {
         pCallback = (PrefCallbackData *)mObservers->ElementAt(i);
         if (pCallback) {
-          domain = mObserverDomains[i];
           // We must pass a fully qualified preference name to remove the callback
-          pref = getPrefName(domain.get()); // can't fail because domain must be valid
+          pref = getPrefName(pCallback->pDomain);
           // Remove this observer from our array so that nobody else can remove
           // what we're trying to remove right now.
           mObservers->ReplaceElementAt(nsnull, i);
           PREF_UnregisterCallback(pref, NotifyObserver, pCallback);
           if (pCallback->pWeakRef) {
             NS_RELEASE(pCallback->pWeakRef);
           } else {
             NS_RELEASE(pCallback->pObserver);
           }
           nsMemory::Free(pCallback);
         }
       }
-
-      // now empty the observer domains array in bulk
-      mObserverDomains.Clear();
     }
     delete mObservers;
     mObservers = 0;
   }
 }
  
 nsresult nsPrefBranch::GetDefaultFromPropertiesFile(const char *aPrefName, PRUnichar **return_buf)
 {
--- a/modules/libpref/src/nsPrefBranch.h
+++ b/modules/libpref/src/nsPrefBranch.h
@@ -78,17 +78,16 @@ protected:
   const char *getPrefName(const char *aPrefName);
   nsresult   getValidatedPrefName(const char *aPrefName, const char **_retval);
   void       freeObserverList(void);
 
 private:
   PRInt32               mPrefRootLength;
   nsAutoVoidArray       *mObservers;
   nsCString             mPrefRoot;
-  nsTArray<nsCString>   mObserverDomains;
   PRBool                mIsDefault;
 
 };
 
 
 class nsPrefLocalizedString : public nsIPrefLocalizedString,
                               public nsISupportsString
 {
--- a/modules/plugin/base/public/nsIPluginHost.idl
+++ b/modules/plugin/base/public/nsIPluginHost.idl
@@ -59,17 +59,17 @@ interface nsIURI;
 interface nsIDOMPlugin;
 interface nsIChannel;
 interface nsIPluginStreamListener;
 
 [ptr] native PRLibraryPtr(PRLibrary);
 [ref] native nsIStreamListenerRef(nsIStreamListener *);
 [ptr] native nsPluginNativeWindowPtr(nsPluginNativeWindow);
 
-[scriptable, uuid(30C7C529-B05C-4950-B5B8-9AF673E46521)]
+[scriptable, uuid(AA13B116-2AFC-4F23-8395-913C0475D173)]
 interface nsIPluginHost : nsISupports
 {
   [noscript] void init();
 
   [noscript] void destroy();
 
   [noscript] void loadPlugins();
 
@@ -280,16 +280,21 @@ interface nsIPluginHost : nsISupports
   [noscript] void getPluginName(in nsIPluginInstance aInstance, [shared] out string aPluginName);
 
   /**
    * Get the plugin tag associated with a given plugin instance.
    * @param aInstance the plugin instance object
    * @return plugin tag object
    */
   [noscript] nsIPluginTag getPluginTagForInstance(in nsIPluginInstance aInstance);
+  
+%{C++
+  virtual void AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, PRBool isVisible) = 0;
+  virtual void RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame) = 0;
+%}
 };
 
 %{C++
 #ifdef MOZILLA_INTERNAL_API
 /**
  * Used for creating the correct input stream for plugins
  * We can either have raw data (with or without \r\n\r\n) or a path to a file (but it must be native!)
  * When making an nsIInputStream stream for the plugins POST data, be sure to take into 
--- a/modules/plugin/base/public/nsIPluginInstanceOwner.idl
+++ b/modules/plugin/base/public/nsIPluginInstanceOwner.idl
@@ -44,17 +44,17 @@ interface nsIDocument;
 
 %{C++
 #include "npapi.h"
 class nsPluginEvent;
 %}
 
 [ref] native nsIPluginInstanceRef(nsIPluginInstance*);
 
-[uuid(8080E717-7261-4707-B8B4-48250F47055F)]
+[uuid(D8776CDC-00DF-4395-A432-2E78EBCC12B6)]
 interface nsIPluginInstanceOwner : nsISupports
 {
   /**
    * Let the owner know what its instance is
    */
   void setInstance(in nsIPluginInstance aInstance);
 
   /**
@@ -132,9 +132,13 @@ interface nsIPluginInstanceOwner : nsISu
    */
 %{C++
   virtual NPError ShowNativeContextMenu(NPMenu* menu, void* event) = 0;
   virtual NPBool  ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
                                double *destX, double *destY, NPCoordinateSpace destSpace) = 0;
 %}
 
   void setEventModel(in PRInt32 eventModel);
+
+%{C++
+  virtual void SendIdleEvent() = 0;
+%}
 };
--- a/modules/plugin/base/src/Makefile.in
+++ b/modules/plugin/base/src/Makefile.in
@@ -52,16 +52,17 @@ GRE_MODULE	= 1
 LIBXUL_LIBRARY = 1
 
 CPPSRCS		= \
 		nsNPAPIPlugin.cpp \
 		nsNPAPIPluginInstance.cpp \
 		nsPluginHost.cpp \
 		nsPluginModule.cpp \
 		nsJSNPRuntime.cpp \
+		nsPluginTags.cpp \
 		$(NULL)
 
 ifeq ($(OS_ARCH), BeOS)
 	CPPSRCS += nsPluginsDirBeOS.cpp
 	CPPSRCS += nsPluginNativeWindow.cpp
 else
 ifneq (,$(filter WINNT WINCE,$(OS_ARCH)))
 	CPPSRCS += nsPluginsDirWin.cpp
--- a/modules/plugin/base/src/nsNPAPIPlugin.cpp
+++ b/modules/plugin/base/src/nsNPAPIPlugin.cpp
@@ -219,29 +219,29 @@ nsNPAPIPlugin::CheckClassInitialized(voi
 }
 
 NS_IMPL_ISUPPORTS1(nsNPAPIPlugin, nsIPlugin)
 
 nsNPAPIPlugin::nsNPAPIPlugin(NPPluginFuncs* callbacks, 
                              PluginLibrary* aLibrary)
 {
   memset((void*) &fCallbacks, 0, sizeof(fCallbacks));
+
+  fCallbacks.size = sizeof(fCallbacks);
   fLibrary = nsnull;
 
 #if defined(XP_WIN) || defined(XP_OS2)
   // On Windows (and Mac) we need to keep a direct reference to the
   // fCallbacks and NOT just copy the struct. See Bugzilla 85334
 
   NPError gepError;
   nsresult gepResult = aLibrary->NP_GetEntryPoints(&fCallbacks, &gepError);
   if (gepResult != NS_OK || gepError != NPERR_NO_ERROR)
     return;
 
-  fCallbacks.size = sizeof(fCallbacks);
-
   NS_ASSERTION(HIBYTE(fCallbacks.version) >= NP_VERSION_MAJOR,
                "callback version is less than NP version");
 
 #elif defined(XP_MACOSX)
   NPPluginFuncs np_callbacks;
   memset((void*) &np_callbacks, 0, sizeof(np_callbacks));
   np_callbacks.size = sizeof(np_callbacks);
 
@@ -256,17 +256,16 @@ nsNPAPIPlugin::nsNPAPIPlugin(NPPluginFun
   nsresult initResult = aLibrary->NP_Initialize(&(nsNPAPIPlugin::CALLBACKS), &initError);
   if (initResult != NS_OK || initError != NPERR_NO_ERROR)
     return;
   NPError gepError;
   nsresult gepResult = aLibrary->NP_GetEntryPoints(&np_callbacks, &gepError);
   if (gepResult != NS_OK || gepError != NPERR_NO_ERROR)
     return;
 
-  fCallbacks.size = sizeof(fCallbacks);
   fCallbacks.version = np_callbacks.version;
   fCallbacks.newp = (NPP_NewProcPtr)np_callbacks.newp;
   fCallbacks.destroy = (NPP_DestroyProcPtr)np_callbacks.destroy;
   fCallbacks.setwindow = (NPP_SetWindowProcPtr)np_callbacks.setwindow;
   fCallbacks.newstream = (NPP_NewStreamProcPtr)np_callbacks.newstream;
   fCallbacks.destroystream = (NPP_DestroyStreamProcPtr)np_callbacks.destroystream;
   fCallbacks.asfile = (NPP_StreamAsFileProcPtr)np_callbacks.asfile;
   fCallbacks.writeready = (NPP_WriteReadyProcPtr)np_callbacks.writeready;
--- a/modules/plugin/base/src/nsPluginHost.cpp
+++ b/modules/plugin/base/src/nsPluginHost.cpp
@@ -87,17 +87,16 @@
 #include "nsPrintfCString.h"
 #include "nsIBlocklistService.h"
 #include "nsVersionComparator.h"
 #include "nsIPrivateBrowsingService.h"
 
 #include "nsEnumeratorUtils.h"
 #include "nsXPCOM.h"
 #include "nsXPCOMCID.h"
-#include "nsICategoryManager.h"
 #include "nsISupportsPrimitives.h"
 
 // for the dialog
 #include "nsIStringBundle.h"
 #include "nsIWindowWatcher.h"
 #include "nsPIDOMWindow.h"
 
 #include "nsIScriptGlobalObject.h"
@@ -221,18 +220,16 @@ PRLogModuleInfo* nsPluginLogging::gPlugi
 #define PLUGIN_PROPERTIES_URL "chrome://global/locale/downloadProgress.properties"
 
 // #defines for plugin cache and prefs
 #define NS_PREF_MAX_NUM_CACHED_PLUGINS "browser.plugins.max_num_cached_plugins"
 #define DEFAULT_NUMBER_OF_STOPPED_PLUGINS 10
 
 #define MAGIC_REQUEST_CONTEXT 0x01020304
 
-nsresult PostPluginUnloadEvent(PRLibrary * aLibrary);
-
 static nsPluginInstanceTagList *gActivePluginList;
 
 #ifdef CALL_SAFETY_ON
 PRBool gSkipPluginSafeCalls = PR_FALSE;
 #endif
 
 nsIFile *nsPluginHost::sPluginTempDir;
 nsPluginHost *nsPluginHost::sInst;
@@ -304,629 +301,16 @@ NS_IMETHODIMP nsPluginDocReframeEvent::R
 
       }
     }
   }
 
   return mDocs->Clear();
 }
 
-nsPluginInstanceTag::nsPluginInstanceTag(nsPluginTag* aPluginTag,
-                               nsIPluginInstance* aInstance,
-                               const char * url,
-                               PRBool aDefaultPlugin)
-{
-  mNext = nsnull;
-  mPluginTag = aPluginTag;
-
-  mURL = PL_strdup(url);
-  mInstance = aInstance;
-  if (aInstance)
-    NS_ADDREF(aInstance);
-  mXPConnected = PR_FALSE;
-  mDefaultPlugin = aDefaultPlugin;
-  mStopped = PR_FALSE;
-  mllStopTime = LL_ZERO;
-}
-
-nsPluginInstanceTag::~nsPluginInstanceTag()
-{
-  mPluginTag = nsnull;
-  if (mInstance) {
-    nsCOMPtr<nsIPluginInstanceOwner> owner;
-    mInstance->GetOwner(getter_AddRefs(owner));
-    if (owner)
-      owner->SetInstance(nsnull);
-    mInstance->InvalidateOwner();
-
-    NS_RELEASE(mInstance);
-  }
-  PL_strfree(mURL);
-}
-
-void nsPluginInstanceTag::setStopped(PRBool stopped)
-{
-  mStopped = stopped;
-  if (mStopped) // plugin instance is told to stop
-    mllStopTime = PR_Now();
-  else
-    mllStopTime = LL_ZERO;
-}
-
-nsPluginInstanceTagList::nsPluginInstanceTagList()
-{
-  mFirst = nsnull;
-  mLast = nsnull;
-  mCount = 0;
-}
-
-nsPluginInstanceTagList::~nsPluginInstanceTagList()
-{
-  if (!mFirst)
-    return;
-  shutdown();
-}
-
-void nsPluginInstanceTagList::shutdown()
-{
-  if (!mFirst)
-    return;
-
-  for (nsPluginInstanceTag * plugin = mFirst; plugin != nsnull;) {
-    nsPluginInstanceTag * next = plugin->mNext;
-    remove(plugin);
-    plugin = next;
-  }
-  mFirst = nsnull;
-  mLast = nsnull;
-}
-
-PRInt32 nsPluginInstanceTagList::add(nsPluginInstanceTag * plugin)
-{
-  if (!mFirst) {
-    mFirst = plugin;
-    mLast = plugin;
-    mFirst->mNext = nsnull;
-  }
-  else {
-    mLast->mNext = plugin;
-    mLast = plugin;
-  }
-  mLast->mNext = nsnull;
-  mCount++;
-  return mCount;
-}
-
-PRBool nsPluginInstanceTagList::IsLastInstance(nsPluginInstanceTag * plugin)
-{
-  if (!plugin)
-    return PR_FALSE;
-
-  if (!plugin->mPluginTag)
-    return PR_FALSE;
-
-  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
-    if ((p->mPluginTag == plugin->mPluginTag) && (p != plugin))
-      return PR_FALSE;
-  }
-  return PR_TRUE;
-}
-
-PRBool nsPluginInstanceTagList::remove(nsPluginInstanceTag * plugin)
-{
-  if (!mFirst)
-    return PR_FALSE;
-
-  nsPluginInstanceTag * prev = nsnull;
-  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
-    if (p == plugin) {
-      PRBool lastInstance = IsLastInstance(p);
-
-      if (p == mFirst)
-        mFirst = p->mNext;
-      else
-        prev->mNext = p->mNext;
-
-      if (prev && !prev->mNext)
-        mLast = prev;
-
-      if (lastInstance) {
-        nsRefPtr<nsPluginTag> pluginTag = p->mPluginTag;
-
-        delete p;
-
-        if (pluginTag) {
-          nsresult rv;
-          nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
-          NS_ENSURE_SUCCESS(rv, rv);
-
-          PRBool unloadPluginsASAP = PR_FALSE;
-          rv = pref->GetBoolPref("plugins.unloadASAP", &unloadPluginsASAP);
-          if (NS_SUCCEEDED(rv) && unloadPluginsASAP)
-            pluginTag->TryUnloadPlugin();
-        } else {
-          NS_ASSERTION(pluginTag, "pluginTag was not set, plugin not shutdown");
-        }
-      } else {
-        delete p;
-      }
-
-      mCount--;
-      return PR_TRUE;
-    }
-    prev = p;
-  }
-  return PR_FALSE;
-}
-
-// This method terminates all running instances of plugins and collects their
-// documents to be returned through an array. This method is used
-// when we are shutting down or when a plugins.refresh(1) happens.
-// If aPluginTag is given, then only that plugin is terminated
-void nsPluginInstanceTagList::stopRunning(nsISupportsArray* aReloadDocs,
-                                     nsPluginTag* aPluginTag)
-{
-  if (!mFirst)
-    return;
-
-  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
-    if (!p->mStopped && p->mInstance &&
-       (!aPluginTag || aPluginTag == p->mPluginTag)) {
-      p->mInstance->SetWindow(nsnull);
-      p->mInstance->Stop();
-      p->setStopped(PR_TRUE);
-
-      // If we've been passed an array to return, lets collect all our documents,
-      // removing duplicates. These will be reframed (embedded) or reloaded (full-page) later
-      // to kickstart our instances.
-      if (aReloadDocs && p->mInstance) {
-        nsCOMPtr<nsIPluginInstanceOwner> owner;
-        p->mInstance->GetOwner(getter_AddRefs(owner));
-        if (owner) {
-          nsCOMPtr<nsIDocument> doc;
-          owner->GetDocument(getter_AddRefs(doc));
-          if (doc && aReloadDocs->IndexOf(doc) == -1)  // don't allow for duplicates
-            aReloadDocs->AppendElement(doc);
-        }
-      }
-    }
-  }
-}
-
-void nsPluginInstanceTagList::removeAllStopped()
-{
-  if (!mFirst)
-    return;
-
-  nsPluginInstanceTag * next = nsnull;
-
-  for (nsPluginInstanceTag * p = mFirst; p != nsnull;) {
-    next = p->mNext;
-
-    if (p->mStopped)
-      remove(p);
-
-    p = next;
-  }
-  return;
-}
-
-nsPluginInstanceTag * nsPluginInstanceTagList::find(nsIPluginInstance* instance)
-{
-  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
-    if (p->mInstance == instance)
-      return p;
-  }
-  return nsnull;
-}
-
-nsPluginInstanceTag * nsPluginInstanceTagList::find(const char * mimetype)
-{
-  PRBool defaultplugin = (PL_strcmp(mimetype, "*") == 0);
-
-  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
-    // give it some special treatment for the default plugin first
-    // because we cannot tell the default plugin by asking instance for a mime type
-    if (defaultplugin && p->mDefaultPlugin)
-      return p;
-
-    if (!p->mInstance)
-      continue;
-
-    const char* mt;
-    nsresult rv = p->mInstance->GetMIMEType(&mt);
-    if (NS_FAILED(rv))
-      continue;
-
-    if (PL_strcasecmp(mt, mimetype) == 0)
-      return p;
-  }
-  return nsnull;
-}
-
-nsPluginInstanceTag * nsPluginInstanceTagList::findStopped(const char * url)
-{
-  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
-    if (!PL_strcmp(url, p->mURL) && p->mStopped)
-       return p;
-  }
-  return nsnull;
-}
-
-PRUint32 nsPluginInstanceTagList::getStoppedCount()
-{
-  PRUint32 stoppedCount = 0;
-  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
-    if (p->mStopped)
-      stoppedCount++;
-  }
-  return stoppedCount;
-}
-
-nsPluginInstanceTag * nsPluginInstanceTagList::findOldestStopped()
-{
-  nsPluginInstanceTag * res = nsnull;
-  PRInt64 llTime = LL_MAXINT;
-  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
-    if (!p->mStopped)
-      continue;
-
-    if (LL_CMP(p->mllStopTime, <, llTime)) {
-      llTime = p->mllStopTime;
-      res = p;
-    }
-  }
-
-  return res;
-}
-
-inline char* new_str(const char* str)
-{
-  if (str == nsnull)
-    return nsnull;
-
-  char* result = new char[strlen(str) + 1];
-  if (result != nsnull)
-    return strcpy(result, str);
-  return result;
-}
-
-nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag)
-  : mPluginHost(nsnull),
-    mName(aPluginTag->mName),
-    mDescription(aPluginTag->mDescription),
-    mVariants(aPluginTag->mVariants),
-    mMimeTypeArray(nsnull),
-    mMimeDescriptionArray(aPluginTag->mMimeDescriptionArray),
-    mExtensionsArray(nsnull),
-    mLibrary(nsnull),
-    mCanUnloadLibrary(PR_TRUE),
-    mXPConnected(PR_FALSE),
-    mIsJavaPlugin(aPluginTag->mIsJavaPlugin),
-    mIsNPRuntimeEnabledJavaPlugin(aPluginTag->mIsNPRuntimeEnabledJavaPlugin),
-    mFileName(aPluginTag->mFileName),
-    mFullPath(aPluginTag->mFullPath),
-    mVersion(aPluginTag->mVersion),
-    mLastModifiedTime(0),
-    mFlags(NS_PLUGIN_FLAG_ENABLED)
-{
-  if (aPluginTag->mMimeTypeArray != nsnull) {
-    mMimeTypeArray = new char*[mVariants];
-    for (int i = 0; i < mVariants; i++)
-      mMimeTypeArray[i] = new_str(aPluginTag->mMimeTypeArray[i]);
-  }
-
-  if (aPluginTag->mExtensionsArray != nsnull) {
-    mExtensionsArray = new char*[mVariants];
-    for (int i = 0; i < mVariants; i++)
-      mExtensionsArray[i] = new_str(aPluginTag->mExtensionsArray[i]);
-  }
-}
-
-nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo)
-  : mPluginHost(nsnull),
-    mName(aPluginInfo->fName),
-    mDescription(aPluginInfo->fDescription),
-    mVariants(aPluginInfo->fVariantCount),
-    mMimeTypeArray(nsnull),
-    mExtensionsArray(nsnull),
-    mLibrary(nsnull),
-#ifdef XP_MACOSX
-    mCanUnloadLibrary(!aPluginInfo->fBundle),
-#else
-    mCanUnloadLibrary(PR_TRUE),
-#endif
-    mXPConnected(PR_FALSE),
-    mIsJavaPlugin(PR_FALSE),
-    mIsNPRuntimeEnabledJavaPlugin(PR_FALSE),
-    mFileName(aPluginInfo->fFileName),
-    mFullPath(aPluginInfo->fFullPath),
-    mVersion(aPluginInfo->fVersion),
-    mLastModifiedTime(0),
-    mFlags(NS_PLUGIN_FLAG_ENABLED)
-{
-  if (aPluginInfo->fMimeTypeArray != nsnull) {
-    mMimeTypeArray = new char*[mVariants];
-    for (int i = 0; i < mVariants; i++) {
-      if (mIsJavaPlugin && aPluginInfo->fMimeTypeArray[i] &&
-          strcmp(aPluginInfo->fMimeTypeArray[i],
-                 "application/x-java-vm-npruntime") == 0) {
-        mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
-
-        // Stop processing here, any mimetypes after the magic "I'm a
-        // NPRuntime enabled Java plugin" mimetype will be ignored.
-        mVariants = i;
-
-        break;
-      }
-
-      mMimeTypeArray[i] = new_str(aPluginInfo->fMimeTypeArray[i]);
-      if (nsPluginHost::IsJavaMIMEType(mMimeTypeArray[i]))
-        mIsJavaPlugin = PR_TRUE;
-    }
-  }
-
-  if (aPluginInfo->fMimeDescriptionArray != nsnull) {
-    for (int i = 0; i < mVariants; i++) {
-      // we should cut off the list of suffixes which the mime
-      // description string may have, see bug 53895
-      // it is usually in form "some description (*.sf1, *.sf2)"
-      // so we can search for the opening round bracket
-      char cur = '\0';
-      char pre = '\0';
-      char * p = PL_strrchr(aPluginInfo->fMimeDescriptionArray[i], '(');
-      if (p && (p != aPluginInfo->fMimeDescriptionArray[i])) {
-        if ((p - 1) && *(p - 1) == ' ') {
-          pre = *(p - 1);
-          *(p - 1) = '\0';
-        } else {
-          cur = *p;
-          *p = '\0';
-        }
-
-      }
-      mMimeDescriptionArray.AppendElement(
-        aPluginInfo->fMimeDescriptionArray[i]);
-      // restore the original string
-      if (cur != '\0')
-        *p = cur;
-      if (pre != '\0')
-        *(p - 1) = pre;
-    }
-  } else {
-    mMimeDescriptionArray.SetLength(mVariants);
-  }
-
-  if (aPluginInfo->fExtensionArray != nsnull) {
-    mExtensionsArray = new char*[mVariants];
-    for (int i = 0; i < mVariants; i++)
-      mExtensionsArray[i] = new_str(aPluginInfo->fExtensionArray[i]);
-  }
-
-  EnsureMembersAreUTF8();
-}
-
-nsPluginTag::nsPluginTag(const char* aName,
-                         const char* aDescription,
-                         const char* aFileName,
-                         const char* aFullPath,
-                         const char* aVersion,
-                         const char* const* aMimeTypes,
-                         const char* const* aMimeDescriptions,
-                         const char* const* aExtensions,
-                         PRInt32 aVariants,
-                         PRInt64 aLastModifiedTime,
-                         PRBool aCanUnload,
-                         PRBool aArgsAreUTF8)
-  : mPluginHost(nsnull),
-    mName(aName),
-    mDescription(aDescription),
-    mVariants(aVariants),
-    mMimeTypeArray(nsnull),
-    mExtensionsArray(nsnull),
-    mLibrary(nsnull),
-    mCanUnloadLibrary(aCanUnload),
-    mXPConnected(PR_FALSE),
-    mIsJavaPlugin(PR_FALSE),
-    mIsNPRuntimeEnabledJavaPlugin(PR_FALSE),
-    mFileName(aFileName),
-    mFullPath(aFullPath),
-    mVersion(aVersion),
-    mLastModifiedTime(aLastModifiedTime),
-    mFlags(0) // Caller will read in our flags from cache
-{
-  if (aVariants) {
-    mMimeTypeArray        = new char*[mVariants];
-    mExtensionsArray      = new char*[mVariants];
-
-    for (PRInt32 i = 0; i < aVariants; ++i) {
-      if (mIsJavaPlugin && aMimeTypes[i] &&
-          strcmp(aMimeTypes[i], "application/x-java-vm-npruntime") == 0) {
-        mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
-
-        // Stop processing here, any mimetypes after the magic "I'm a
-        // NPRuntime enabled Java plugin" mimetype will be ignored.
-        mVariants = i;
-
-        break;
-      }
-
-      mMimeTypeArray[i]        = new_str(aMimeTypes[i]);
-      mMimeDescriptionArray.AppendElement(aMimeDescriptions[i]);
-      mExtensionsArray[i]      = new_str(aExtensions[i]);
-      if (nsPluginHost::IsJavaMIMEType(mMimeTypeArray[i]))
-        mIsJavaPlugin = PR_TRUE;
-    }
-  }
-
-  if (!aArgsAreUTF8)
-    EnsureMembersAreUTF8();
-}
-
-nsPluginTag::~nsPluginTag()
-{
-  NS_ASSERTION(!mNext, "Risk of exhausting the stack space, bug 486349");
-
-  if (mMimeTypeArray) {
-    for (int i = 0; i < mVariants; i++)
-      delete[] mMimeTypeArray[i];
-
-    delete[] (mMimeTypeArray);
-    mMimeTypeArray = nsnull;
-  }
-
-  if (mExtensionsArray) {
-    for (int i = 0; i < mVariants; i++)
-      delete[] mExtensionsArray[i];
-
-    delete[] (mExtensionsArray);
-    mExtensionsArray = nsnull;
-  }
-}
-
-NS_IMPL_ISUPPORTS1(nsPluginTag, nsIPluginTag)
-
-static nsresult ConvertToUTF8(nsIUnicodeDecoder *aUnicodeDecoder,
-                              nsAFlatCString& aString)
-{
-  PRInt32 numberOfBytes = aString.Length();
-  PRInt32 outUnicodeLen;
-  nsAutoString buffer;
-  nsresult rv = aUnicodeDecoder->GetMaxLength(aString.get(), numberOfBytes,
-                                              &outUnicodeLen);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (!EnsureStringLength(buffer, outUnicodeLen))
-    return NS_ERROR_OUT_OF_MEMORY;
-  rv = aUnicodeDecoder->Convert(aString.get(), &numberOfBytes,
-                                buffer.BeginWriting(), &outUnicodeLen);
-  NS_ENSURE_SUCCESS(rv, rv);
-  buffer.SetLength(outUnicodeLen);
-  CopyUTF16toUTF8(buffer, aString);
-
-  return NS_OK;
-}
-
-nsresult nsPluginTag::EnsureMembersAreUTF8()
-{
-  nsresult rv;
-
-  nsCOMPtr<nsIPlatformCharset> pcs =
-    do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr<nsIUnicodeDecoder> decoder;
-  nsCOMPtr<nsICharsetConverterManager> ccm =
-    do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  nsCAutoString charset;
-  rv = pcs->GetCharset(kPlatformCharsetSel_FileName, charset);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (!charset.LowerCaseEqualsLiteral("utf-8")) {
-    rv = ccm->GetUnicodeDecoderRaw(charset.get(), getter_AddRefs(decoder));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    ConvertToUTF8(decoder, mFileName);
-    ConvertToUTF8(decoder, mFullPath);
-  }
-
-  // The description of the plug-in and the various MIME type descriptions
-  // should be encoded in the standard plain text file encoding for this system.
-  // XXX should we add kPlatformCharsetSel_PluginResource?
-  rv = pcs->GetCharset(kPlatformCharsetSel_PlainTextInFile, charset);
-  NS_ENSURE_SUCCESS(rv, rv);
-  if (!charset.LowerCaseEqualsLiteral("utf-8")) {
-    rv = ccm->GetUnicodeDecoderRaw(charset.get(), getter_AddRefs(decoder));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    ConvertToUTF8(decoder, mName);
-    ConvertToUTF8(decoder, mDescription);
-    for (PRUint32 i = 0; i < mMimeDescriptionArray.Length(); ++i) {
-      ConvertToUTF8(decoder, mMimeDescriptionArray[i]);
-    }
-  }
-  return NS_OK;
-}
-
-void nsPluginTag::SetHost(nsPluginHost * aHost)
-{
-  mPluginHost = aHost;
-}
-
-NS_IMETHODIMP
-nsPluginTag::GetDescription(nsACString& aDescription)
-{
-  aDescription = mDescription;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginTag::GetFilename(nsACString& aFileName)
-{
-  aFileName = mFileName;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginTag::GetVersion(nsACString& aVersion)
-{
-  aVersion = mVersion;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginTag::GetName(nsACString& aName)
-{
-  aName = mName;
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginTag::GetDisabled(PRBool* aDisabled)
-{
-  *aDisabled = !HasFlag(NS_PLUGIN_FLAG_ENABLED);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginTag::SetDisabled(PRBool aDisabled)
-{
-  if (HasFlag(NS_PLUGIN_FLAG_ENABLED) == !aDisabled)
-    return NS_OK;
-
-  if (aDisabled)
-    UnMark(NS_PLUGIN_FLAG_ENABLED);
-  else
-    Mark(NS_PLUGIN_FLAG_ENABLED);
-
-  mPluginHost->UpdatePluginInfo(this);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginTag::GetBlocklisted(PRBool* aBlocklisted)
-{
-  *aBlocklisted = HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
-  return NS_OK;
-}
-
-NS_IMETHODIMP
-nsPluginTag::SetBlocklisted(PRBool aBlocklisted)
-{
-  if (HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED) == aBlocklisted)
-    return NS_OK;
-
-  if (aBlocklisted)
-    Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
-  else
-    UnMark(NS_PLUGIN_FLAG_BLOCKLISTED);
-
-  mPluginHost->UpdatePluginInfo(nsnull);
-  return NS_OK;
-}
-
 // helper struct for asynchronous handling of plugin unloading
 class nsPluginUnloadEvent : public nsRunnable {
 public:
   nsPluginUnloadEvent(PRLibrary* aLibrary)
     : mLibrary(aLibrary)
   {}
  
   NS_DECL_NSIRUNNABLE
@@ -941,121 +325,28 @@ NS_IMETHODIMP nsPluginUnloadEvent::Run()
     NS_TRY_SAFE_CALL_VOID(PR_UnloadLibrary(mLibrary), nsnull, nsnull);
   } else {
     NS_WARNING("missing library from nsPluginUnloadEvent");
   }
   return NS_OK;
 }
 
 // unload plugin asynchronously if possible, otherwise just unload now
-nsresult PostPluginUnloadEvent(PRLibrary* aLibrary)
+nsresult nsPluginHost::PostPluginUnloadEvent(PRLibrary* aLibrary)
 {
   nsCOMPtr<nsIRunnable> ev = new nsPluginUnloadEvent(aLibrary);
   if (ev && NS_SUCCEEDED(NS_DispatchToCurrentThread(ev)))
     return NS_OK;
 
   // failure case
   NS_TRY_SAFE_CALL_VOID(PR_UnloadLibrary(aLibrary), nsnull, nsnull);
 
   return NS_ERROR_FAILURE;
 }
 
-void nsPluginTag::TryUnloadPlugin()
-{
-  if (mEntryPoint) {
-    mEntryPoint->Shutdown();
-    mEntryPoint = nsnull;
-  }
-
-  // before we unload check if we are allowed to, see bug #61388
-  if (mLibrary && mCanUnloadLibrary) {
-    // NPAPI plugins can be unloaded now if they don't use XPConnect
-    if (!mXPConnected) {
-      // unload the plugin asynchronously by posting a PLEvent
-      PostPluginUnloadEvent(mLibrary);
-    }
-    else {
-      // add library to the unused library list to handle it later
-      if (mPluginHost)
-        mPluginHost->AddUnusedLibrary(mLibrary);
-    }
-  }
-
-  // we should zero it anyway, it is going to be unloaded by
-  // CleanUnsedLibraries before we need to call the library
-  // again so the calling code should not be fooled and reload
-  // the library fresh
-  mLibrary = nsnull;
-
-  // Remove mime types added to the category manager
-  // only if we were made 'active' by setting the host
-  if (mPluginHost) {
-    RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
-  }
-}
-
-void nsPluginTag::Mark(PRUint32 mask)
-{
-  PRBool wasEnabled = IsEnabled();
-  mFlags |= mask;
-  // Update entries in the category manager if necessary.
-  if (mPluginHost && wasEnabled != IsEnabled()) {
-    if (wasEnabled)
-      RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
-    else
-      RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginRegister);
-  }
-}
-
-void nsPluginTag::UnMark(PRUint32 mask)
-{
-  PRBool wasEnabled = IsEnabled();
-  mFlags &= ~mask;
-  // Update entries in the category manager if necessary.
-  if (mPluginHost && wasEnabled != IsEnabled()) {
-    if (wasEnabled)
-      RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
-    else
-      RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginRegister);
-  }
-}
-
-PRBool nsPluginTag::HasFlag(PRUint32 flag)
-{
-  return (mFlags & flag) != 0;
-}
-
-PRUint32 nsPluginTag::Flags()
-{
-  return mFlags;
-}
-
-PRBool nsPluginTag::IsEnabled()
-{
-  return HasFlag(NS_PLUGIN_FLAG_ENABLED) && !HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
-}
-
-PRBool nsPluginTag::Equals(nsPluginTag *aPluginTag)
-{
-  NS_ENSURE_TRUE(aPluginTag, PR_FALSE);
-
-  if ((!mName.Equals(aPluginTag->mName)) ||
-      (!mDescription.Equals(aPluginTag->mDescription)) ||
-      (mVariants != aPluginTag->mVariants))
-    return PR_FALSE;
-
-  if (mVariants && mMimeTypeArray && aPluginTag->mMimeTypeArray) {
-    for (PRInt32 i = 0; i < mVariants; i++) {
-      if (PL_strcmp(mMimeTypeArray[i], aPluginTag->mMimeTypeArray[i]) != 0)
-        return PR_FALSE;
-    }
-  }
-  return PR_TRUE;
-}
-
 class nsPluginStreamListenerPeer;
 
 class nsPluginStreamInfo : public nsINPAPIPluginStreamInfo
 {
 public:
   nsPluginStreamInfo();
   virtual ~nsPluginStreamInfo();
 
@@ -2443,16 +1734,21 @@ nsPluginHost::nsPluginHost()
 
   PR_LOG(nsPluginLogging::gNPNLog, PLUGIN_LOG_ALWAYS,("NPN Logging Active!\n"));
   PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_ALWAYS,("General Plugin Logging Active! (nsPluginHost::ctor)\n"));
   PR_LOG(nsPluginLogging::gNPPLog, PLUGIN_LOG_ALWAYS,("NPP Logging Active!\n"));
 
   PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("nsPluginHost::ctor\n"));
   PR_LogFlush();
 #endif
+
+#ifdef MAC_CARBON_PLUGINS
+  mVisiblePluginTimer = do_CreateInstance("@mozilla.org/timer;1");
+  mHiddenPluginTimer = do_CreateInstance("@mozilla.org/timer;1");
+#endif
 }
 
 nsPluginHost::~nsPluginHost()
 {
   PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("nsPluginHost::dtor\n"));
 
   Destroy();
   sInst = nsnull;
@@ -2992,17 +2288,17 @@ NS_IMETHODIMP nsPluginHost::InstantiateP
 #endif
 
   // XXX do we need to look for stopped plugins, like InstantiateEmbeddedPlugin
   // does?
 
   return NewEmbeddedPluginStreamListener(uri, aOwner, nsnull, aListener);
 }
 
-// Called by nsPluginInstanceOwner (nsObjectFrame.cpp - embedded case)
+// Called by nsPluginInstanceOwner
 NS_IMETHODIMP nsPluginHost::InstantiateEmbeddedPlugin(const char *aMimeType,
                                                           nsIURI* aURL,
                                                           nsIPluginInstanceOwner *aOwner)
 {
   NS_ENSURE_ARG_POINTER(aOwner);
 
 #ifdef PLUGIN_LOGGING
   nsCAutoString urlSpec;
@@ -3335,90 +2631,16 @@ nsresult nsPluginHost::AddInstanceToActi
 
   if (!plugin)
     return NS_ERROR_OUT_OF_MEMORY;
 
   mPluginInstanceTagList.add(plugin);
   return NS_OK;
 }
 
-void
-nsPluginTag::RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
-                                         nsPluginTag::nsRegisterType aType)
-{
-  if (!mMimeTypeArray)
-    return;
-
-  PLUGIN_LOG(PLUGIN_LOG_NORMAL,
-  ("nsPluginTag::RegisterWithCategoryManager plugin=%s, removing = %s\n",
-  mFileName.get(), aType == ePluginUnregister ? "yes" : "no"));
-
-  nsCOMPtr<nsICategoryManager> catMan = do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
-  if (!catMan)
-    return;
-
-  const char *contractId = "@mozilla.org/content/plugin/document-loader-factory;1";
-
-  nsCOMPtr<nsIPrefBranch> psvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
-  if (!psvc)
-    return; // NS_ERROR_OUT_OF_MEMORY
-
-  // A preference controls whether or not the full page plugin is disabled for
-  // a particular type. The string must be in the form:
-  //   type1,type2,type3,type4
-  // Note: need an actual interface to control this and subsequent disabling 
-  // (and other plugin host settings) so applications can reliably disable 
-  // plugins - without relying on implementation details such as prefs/category
-  // manager entries.
-  nsXPIDLCString overrideTypes;
-  psvc->GetCharPref("plugin.disable_full_page_plugin_for_types", getter_Copies(overrideTypes));
-  nsCAutoString overrideTypesFormatted;
-  overrideTypesFormatted.Assign(',');
-  overrideTypesFormatted += overrideTypes;
-  overrideTypesFormatted.Append(',');
-
-  nsACString::const_iterator start, end;
-  for (int i = 0; i < mVariants; i++) {
-    if (aType == ePluginUnregister) {
-      nsXPIDLCString value;
-      if (NS_SUCCEEDED(catMan->GetCategoryEntry("Gecko-Content-Viewers",
-                                                mMimeTypeArray[i],
-                                                getter_Copies(value)))) {
-        // Only delete the entry if a plugin registered for it
-        if (strcmp(value, contractId) == 0) {
-          catMan->DeleteCategoryEntry("Gecko-Content-Viewers",
-                                      mMimeTypeArray[i],
-                                      PR_TRUE);
-        }
-      }
-    } else {
-      overrideTypesFormatted.BeginReading(start);
-      overrideTypesFormatted.EndReading(end);
-      
-      nsDependentCString mimeType(mMimeTypeArray[i]);
-      nsCAutoString commaSeparated; 
-      commaSeparated.Assign(',');
-      commaSeparated += mimeType;
-      commaSeparated.Append(',');
-      if (!FindInReadable(commaSeparated, start, end)) {
-        catMan->AddCategoryEntry("Gecko-Content-Viewers",
-                                 mMimeTypeArray[i],
-                                 contractId,
-                                 PR_FALSE, /* persist: broken by bug 193031 */
-                                 aOverrideInternalTypes, /* replace if we're told to */
-                                 nsnull);
-      }
-    }
-
-    PLUGIN_LOG(PLUGIN_LOG_NOISY,
-    ("nsPluginTag::RegisterWithCategoryManager mime=%s, plugin=%s\n",
-    mMimeTypeArray[i], mFileName.get()));
-  }
-}
-
 NS_IMETHODIMP nsPluginHost::SetUpPluginInstance(const char *aMimeType,
                                                 nsIURI *aURL,
                                                 nsIPluginInstanceOwner *aOwner)
 {
   nsresult rv = NS_OK;
 
   rv = TrySetUpPluginInstance(aMimeType, aURL, aOwner);
 
@@ -3531,19 +2753,24 @@ nsPluginHost::TrySetUpPluginInstance(con
   }
 
   if (NS_FAILED(result))
     return result;
 
   // it is adreffed here
   aOwner->SetInstance(instance);
 
-  result = instance->Initialize(aOwner, mimetype);  // this should not addref the instance or owner
-  if (NS_FAILED(result))                // except in some cases not Java, see bug 140931
-    return result;                      // our COM pointer will free the peer
+  // this should not addref the instance or owner
+  // except in some cases not Java, see bug 140931
+  // our COM pointer will free the peer
+  result = instance->Initialize(aOwner, mimetype);
+  if (NS_FAILED(result)) {
+    aOwner->SetInstance(nsnull);
+    return result;
+  }
 
   // instance and peer will be addreffed here
   result = AddInstanceToActiveList(plugin, instance, aURL, PR_FALSE);
 
 #ifdef PLUGIN_LOGGING
   nsCAutoString urlSpec2;
   if (aURL)
     aURL->GetSpec(urlSpec2);
@@ -3595,18 +2822,20 @@ nsPluginHost::SetUpDefaultPluginInstance
       res = ms->GetTypeFromURI(aURL, mt);
       if (NS_SUCCEEDED(res))
         mimetype = mt.get();
     }
   }
 
   // this should not addref the instance or owner
   result = instance->Initialize(aOwner, mimetype);
-  if (NS_FAILED(result))
+  if (NS_FAILED(result)) {
+    aOwner->SetInstance(nsnull);
     return result;
+  }
 
   // instance will be addreffed here
   result = AddInstanceToActiveList(plugin, instance, aURL, PR_TRUE);
 
   return result;
 }
 
 NS_IMETHODIMP
@@ -5876,16 +5105,86 @@ nsPluginHost::GetPluginTagForInstance(ns
 nsresult nsPluginHost::AddUnusedLibrary(PRLibrary * aLibrary)
 {
   if (!mUnusedLibraries.Contains(aLibrary)) // don't add duplicates
     mUnusedLibraries.AppendElement(aLibrary);
 
   return NS_OK;
 }
 
+#ifdef MAC_CARBON_PLUGINS
+// Flash requires a minimum of 8 events per second to avoid audio skipping.
+// Since WebKit uses a hidden plugin event rate of 4 events per second Flash
+// uses a Carbon timer for WebKit which fires at 8 events per second.
+#define HIDDEN_PLUGIN_DELAY 125
+#define VISIBLE_PLUGIN_DELAY 20
+#endif
+
+void nsPluginHost::AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, PRBool isVisible)
+{
+#ifdef MAC_CARBON_PLUGINS
+  nsTObserverArray<nsIPluginInstanceOwner*> *targetArray;
+  if (isVisible) {
+    targetArray = &mVisibleTimerTargets;
+  } else {
+    targetArray = &mHiddenTimerTargets;
+  }
+
+  if (targetArray->Contains(objectFrame)) {
+    return;
+  }
+
+  targetArray->AppendElement(objectFrame);
+  if (targetArray->Length() == 1) {
+    if (isVisible) {
+      mVisiblePluginTimer->InitWithCallback(this, VISIBLE_PLUGIN_DELAY, nsITimer::TYPE_REPEATING_SLACK);
+    } else {
+      mHiddenPluginTimer->InitWithCallback(this, HIDDEN_PLUGIN_DELAY, nsITimer::TYPE_REPEATING_SLACK);
+    }
+  }
+#endif
+}
+
+void nsPluginHost::RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame)
+{
+#ifdef MAC_CARBON_PLUGINS
+  PRBool visibleRemoved = mVisibleTimerTargets.RemoveElement(objectFrame);
+  if (visibleRemoved && mVisibleTimerTargets.IsEmpty()) {
+    mVisiblePluginTimer->Cancel();
+  }
+
+  PRBool hiddenRemoved = mHiddenTimerTargets.RemoveElement(objectFrame);
+  if (hiddenRemoved && mHiddenTimerTargets.IsEmpty()) {
+    mHiddenPluginTimer->Cancel();
+  }
+
+  NS_ASSERTION(!(hiddenRemoved && visibleRemoved), "Plugin instance received visible and hidden idle event notifications");
+#endif
+}
+
+NS_IMETHODIMP nsPluginHost::Notify(nsITimer* timer)
+{
+#ifdef MAC_CARBON_PLUGINS
+  if (timer == mVisiblePluginTimer) {
+    nsTObserverArray<nsIPluginInstanceOwner*>::ForwardIterator iter(mVisibleTimerTargets);
+    while (iter.HasMore()) {
+      iter.GetNext()->SendIdleEvent();
+    }
+    return NS_OK;
+  } else if (timer == mHiddenPluginTimer) {
+    nsTObserverArray<nsIPluginInstanceOwner*>::ForwardIterator iter(mHiddenTimerTargets);
+    while (iter.HasMore()) {
+      iter.GetNext()->SendIdleEvent();
+    }
+    return NS_OK;
+  }
+#endif
+  return NS_ERROR_FAILURE;
+}
+
 nsresult nsPluginStreamListenerPeer::ServeStreamAsFile(nsIRequest *request,
                                                        nsISupports* aContext)
 {
   if (!mInstance)
     return NS_ERROR_FAILURE;
 
   // mInstance->Stop calls mPStreamListener->CleanUpStream(), so stream will be properly clean up
   mInstance->Stop();
--- a/modules/plugin/base/src/nsPluginHost.h
+++ b/modules/plugin/base/src/nsPluginHost.h
@@ -53,156 +53,47 @@
 #include "nsAutoPtr.h"
 #include "nsWeakPtr.h"
 #include "nsIPrompt.h"
 #include "nsISupportsArray.h"
 #include "nsIPrefBranch.h"
 #include "nsWeakReference.h"
 #include "nsThreadUtils.h"
 #include "nsTArray.h"
+#include "nsTObserverArray.h"
+#include "nsITimer.h"
+#include "nsPluginTags.h"
 
 class nsNPAPIPlugin;
 class nsIComponentManager;
 class nsIFile;
 class nsIChannel;
-class nsPluginHost;
 
-// Remember that flags are written out to pluginreg.dat, be careful
-// changing their meaning.
-#define NS_PLUGIN_FLAG_ENABLED      0x0001    // is this plugin enabled?
-// no longer used                   0x0002    // reuse only if regenerating pluginreg.dat
-#define NS_PLUGIN_FLAG_FROMCACHE    0x0004    // this plugintag info was loaded from cache
-#define NS_PLUGIN_FLAG_UNWANTED     0x0008    // this is an unwanted plugin
-#define NS_PLUGIN_FLAG_BLOCKLISTED  0x0010    // this is a blocklisted plugin
-
-// A linked-list of plugin information that is used for instantiating plugins
-// and reflecting plugin information into JavaScript.
-class nsPluginTag : public nsIPluginTag
-{
-public:
-  enum nsRegisterType {
-    ePluginRegister,
-    ePluginUnregister
-  };
-
-  NS_DECL_ISUPPORTS
-  NS_DECL_NSIPLUGINTAG
-
-  nsPluginTag(nsPluginTag* aPluginTag);
-  nsPluginTag(nsPluginInfo* aPluginInfo);
-  nsPluginTag(const char* aName,
-              const char* aDescription,
-              const char* aFileName,
-              const char* aFullPath,
-              const char* aVersion,
-              const char* const* aMimeTypes,
-              const char* const* aMimeDescriptions,
-              const char* const* aExtensions,
-              PRInt32 aVariants,
-              PRInt64 aLastModifiedTime = 0,
-              PRBool aCanUnload = PR_TRUE,
-              PRBool aArgsAreUTF8 = PR_FALSE);
-  ~nsPluginTag();
-
-  void SetHost(nsPluginHost * aHost);
-  void TryUnloadPlugin();
-  void Mark(PRUint32 mask);
-  void UnMark(PRUint32 mask);
-  PRBool HasFlag(PRUint32 flag);
-  PRUint32 Flags();
-  PRBool Equals(nsPluginTag* aPluginTag);
-  PRBool IsEnabled();
-  void RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
-                                   nsRegisterType aType = ePluginRegister);
-
-  nsRefPtr<nsPluginTag> mNext;
-  nsPluginHost *mPluginHost;
-  nsCString     mName; // UTF-8
-  nsCString     mDescription; // UTF-8
-  PRInt32       mVariants;
-  char          **mMimeTypeArray;
-  nsTArray<nsCString> mMimeDescriptionArray; // UTF-8
-  char          **mExtensionsArray;
-  PRLibrary     *mLibrary;
-  nsCOMPtr<nsIPlugin> mEntryPoint;
-  PRPackedBool  mCanUnloadLibrary;
-  PRPackedBool  mXPConnected;
-  PRPackedBool  mIsJavaPlugin;
-  PRPackedBool  mIsNPRuntimeEnabledJavaPlugin;
-  nsCString     mFileName; // UTF-8
-  nsCString     mFullPath; // UTF-8
-  nsCString     mVersion;  // UTF-8
-  PRInt64       mLastModifiedTime;
-private:
-  PRUint32      mFlags;
-
-  nsresult EnsureMembersAreUTF8();
-};
-
-struct nsPluginInstanceTag
-{
-  nsPluginInstanceTag*   mNext;
-  char*                  mURL;
-  nsRefPtr<nsPluginTag>  mPluginTag;
-  nsIPluginInstance*     mInstance;
-  PRTime                 mllStopTime;
-  PRPackedBool           mStopped;
-  PRPackedBool           mDefaultPlugin;
-  PRPackedBool           mXPConnected;
-  // Array holding all opened stream listeners for this entry
-  nsCOMPtr <nsISupportsArray> mStreams; 
-
-  nsPluginInstanceTag(nsPluginTag* aPluginTag,
-                      nsIPluginInstance* aInstance, 
-                      const char * url,
-                      PRBool aDefaultPlugin);
-  ~nsPluginInstanceTag();
-
-  void setStopped(PRBool stopped);
-};
-
-class nsPluginInstanceTagList
-{
-public:
-  nsPluginInstanceTag *mFirst;
-  nsPluginInstanceTag *mLast;
-  PRInt32 mCount;
-
-  nsPluginInstanceTagList();
-  ~nsPluginInstanceTagList();
-
-  void shutdown();
-  PRBool add(nsPluginInstanceTag *plugin);
-  PRBool remove(nsPluginInstanceTag *plugin);
-  nsPluginInstanceTag *find(nsIPluginInstance *instance);
-  nsPluginInstanceTag *find(const char *mimetype);
-  nsPluginInstanceTag *findStopped(const char *url);
-  PRUint32 getStoppedCount();
-  nsPluginInstanceTag *findOldestStopped();
-  void removeAllStopped();
-  void stopRunning(nsISupportsArray *aReloadDocs, nsPluginTag *aPluginTag);
-  PRBool IsLastInstance(nsPluginInstanceTag *plugin);
-};
+#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
+#define MAC_CARBON_PLUGINS
+#endif
 
 class nsPluginHost : public nsIPluginHost,
                      public nsIObserver,
+                     public nsITimerCallback,
                      public nsSupportsWeakReference
 {
 public:
   nsPluginHost();
   virtual ~nsPluginHost();
 
   static nsPluginHost* GetInst();
   static const char *GetPluginName(nsIPluginInstance *aPluginInstance);
 
   NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIPLUGINHOST
   NS_DECL_NSIOBSERVER
+  NS_DECL_NSITIMERCALLBACK
 
   NS_IMETHOD
   GetURL(nsISupports* pluginInst, 
          const char* url, 
          const char* target = NULL,
          nsIPluginStreamListener* streamListener = NULL,
          const char* altHost = NULL,
          const char* referrer = NULL,
@@ -261,16 +152,21 @@ public:
   nsresult UpdatePluginInfo(nsPluginTag* aPluginTag);
 
   // checks whether aTag is a "java" plugin tag (a tag for a plugin
   // that does Java)
   static PRBool IsJavaMIMEType(const char *aType);
 
   static nsresult GetPrompt(nsIPluginInstanceOwner *aOwner, nsIPrompt **aPrompt);
 
+  static nsresult PostPluginUnloadEvent(PRLibrary* aLibrary);
+
+  void AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, PRBool isVisible);
+  void RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame);
+  
 private:
   nsresult
   TrySetUpPluginInstance(const char *aMimeType, nsIURI *aURL, nsIPluginInstanceOwner *aOwner);
 
   nsresult
   NewEmbeddedPluginStreamListener(nsIURI* aURL, nsIPluginInstanceOwner *aOwner,
                                   nsIPluginInstance* aInstance,
                                   nsIStreamListener** aListener);
@@ -368,16 +264,23 @@ private:
 
   nsWeakPtr mCurrentDocument; // weak reference, we use it to id document only
 
   static nsIFile *sPluginTempDir;
 
   // We need to hold a global ptr to ourselves because we register for
   // two different CIDs for some reason...
   static nsPluginHost* sInst;
+
+#ifdef MAC_CARBON_PLUGINS
+  nsCOMPtr<nsITimer> mVisiblePluginTimer;
+  nsTObserverArray<nsIPluginInstanceOwner*> mVisibleTimerTargets;
+  nsCOMPtr<nsITimer> mHiddenPluginTimer;
+  nsTObserverArray<nsIPluginInstanceOwner*> mHiddenTimerTargets;
+#endif
 };
 
 class NS_STACK_CLASS PluginDestructionGuard : protected PRCList
 {
 public:
   PluginDestructionGuard(nsIPluginInstance *aInstance)
     : mInstance(aInstance)
   {
new file mode 100644
--- /dev/null
+++ b/modules/plugin/base/src/nsPluginTags.cpp
@@ -0,0 +1,842 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Sean Echevarria <sean@beatnik.com>
+ *   HÃ¥kan Waara <hwaara@chello.se>
+ *   Josh Aas <josh@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include "nsPluginTags.h"
+
+#include "prlink.h"
+#include "plstr.h"
+#include "nsIPluginInstanceOwner.h"
+#include "nsIDocument.h"
+#include "nsServiceManagerUtils.h"
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
+#include "nsPluginsDir.h"
+#include "nsPluginHost.h"
+#include "nsIUnicodeDecoder.h"
+#include "nsIPlatformCharset.h"
+#include "nsICharsetConverterManager.h"
+#include "nsPluginLogging.h"
+#include "nsICategoryManager.h"
+
+inline char* new_str(const char* str)
+{
+  if (str == nsnull)
+    return nsnull;
+  
+  char* result = new char[strlen(str) + 1];
+  if (result != nsnull)
+    return strcpy(result, str);
+  return result;
+}
+
+/* nsPluginTag */
+
+nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag)
+: mPluginHost(nsnull),
+mName(aPluginTag->mName),
+mDescription(aPluginTag->mDescription),
+mVariants(aPluginTag->mVariants),
+mMimeTypeArray(nsnull),
+mMimeDescriptionArray(aPluginTag->mMimeDescriptionArray),
+mExtensionsArray(nsnull),
+mLibrary(nsnull),
+mCanUnloadLibrary(PR_TRUE),
+mXPConnected(PR_FALSE),
+mIsJavaPlugin(aPluginTag->mIsJavaPlugin),
+mIsNPRuntimeEnabledJavaPlugin(aPluginTag->mIsNPRuntimeEnabledJavaPlugin),
+mFileName(aPluginTag->mFileName),
+mFullPath(aPluginTag->mFullPath),
+mVersion(aPluginTag->mVersion),
+mLastModifiedTime(0),
+mFlags(NS_PLUGIN_FLAG_ENABLED)
+{
+  if (aPluginTag->mMimeTypeArray != nsnull) {
+    mMimeTypeArray = new char*[mVariants];
+    for (int i = 0; i < mVariants; i++)
+      mMimeTypeArray[i] = new_str(aPluginTag->mMimeTypeArray[i]);
+  }
+  
+  if (aPluginTag->mExtensionsArray != nsnull) {
+    mExtensionsArray = new char*[mVariants];
+    for (int i = 0; i < mVariants; i++)
+      mExtensionsArray[i] = new_str(aPluginTag->mExtensionsArray[i]);
+  }
+}
+
+nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo)
+: mPluginHost(nsnull),
+mName(aPluginInfo->fName),
+mDescription(aPluginInfo->fDescription),
+mVariants(aPluginInfo->fVariantCount),
+mMimeTypeArray(nsnull),
+mExtensionsArray(nsnull),
+mLibrary(nsnull),
+#ifdef XP_MACOSX
+mCanUnloadLibrary(!aPluginInfo->fBundle),
+#else
+mCanUnloadLibrary(PR_TRUE),
+#endif
+mXPConnected(PR_FALSE),
+mIsJavaPlugin(PR_FALSE),
+mIsNPRuntimeEnabledJavaPlugin(PR_FALSE),
+mFileName(aPluginInfo->fFileName),
+mFullPath(aPluginInfo->fFullPath),
+mVersion(aPluginInfo->fVersion),
+mLastModifiedTime(0),
+mFlags(NS_PLUGIN_FLAG_ENABLED)
+{
+  if (aPluginInfo->fMimeTypeArray != nsnull) {
+    mMimeTypeArray = new char*[mVariants];
+    for (int i = 0; i < mVariants; i++) {
+      if (mIsJavaPlugin && aPluginInfo->fMimeTypeArray[i] &&
+          strcmp(aPluginInfo->fMimeTypeArray[i],
+                 "application/x-java-vm-npruntime") == 0) {
+            mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
+            
+            // Stop processing here, any mimetypes after the magic "I'm a
+            // NPRuntime enabled Java plugin" mimetype will be ignored.
+            mVariants = i;
+            
+            break;
+          }
+      
+      mMimeTypeArray[i] = new_str(aPluginInfo->fMimeTypeArray[i]);
+      if (nsPluginHost::IsJavaMIMEType(mMimeTypeArray[i]))
+        mIsJavaPlugin = PR_TRUE;
+    }
+  }
+  
+  if (aPluginInfo->fMimeDescriptionArray != nsnull) {
+    for (int i = 0; i < mVariants; i++) {
+      // we should cut off the list of suffixes which the mime
+      // description string may have, see bug 53895
+      // it is usually in form "some description (*.sf1, *.sf2)"
+      // so we can search for the opening round bracket
+      char cur = '\0';
+      char pre = '\0';
+      char * p = PL_strrchr(aPluginInfo->fMimeDescriptionArray[i], '(');
+      if (p && (p != aPluginInfo->fMimeDescriptionArray[i])) {
+        if ((p - 1) && *(p - 1) == ' ') {
+          pre = *(p - 1);
+          *(p - 1) = '\0';
+        } else {
+          cur = *p;
+          *p = '\0';
+        }
+        
+      }
+      mMimeDescriptionArray.AppendElement(
+                                          aPluginInfo->fMimeDescriptionArray[i]);
+      // restore the original string
+      if (cur != '\0')
+        *p = cur;
+      if (pre != '\0')
+        *(p - 1) = pre;
+    }
+  } else {
+    mMimeDescriptionArray.SetLength(mVariants);
+  }
+  
+  if (aPluginInfo->fExtensionArray != nsnull) {
+    mExtensionsArray = new char*[mVariants];
+    for (int i = 0; i < mVariants; i++)
+      mExtensionsArray[i] = new_str(aPluginInfo->fExtensionArray[i]);
+  }
+  
+  EnsureMembersAreUTF8();
+}
+
+nsPluginTag::nsPluginTag(const char* aName,
+                         const char* aDescription,
+                         const char* aFileName,
+                         const char* aFullPath,
+                         const char* aVersion,
+                         const char* const* aMimeTypes,
+                         const char* const* aMimeDescriptions,
+                         const char* const* aExtensions,
+                         PRInt32 aVariants,
+                         PRInt64 aLastModifiedTime,
+                         PRBool aCanUnload,
+                         PRBool aArgsAreUTF8)
+: mPluginHost(nsnull),
+mName(aName),
+mDescription(aDescription),
+mVariants(aVariants),
+mMimeTypeArray(nsnull),
+mExtensionsArray(nsnull),
+mLibrary(nsnull),
+mCanUnloadLibrary(aCanUnload),
+mXPConnected(PR_FALSE),
+mIsJavaPlugin(PR_FALSE),
+mIsNPRuntimeEnabledJavaPlugin(PR_FALSE),
+mFileName(aFileName),
+mFullPath(aFullPath),
+mVersion(aVersion),
+mLastModifiedTime(aLastModifiedTime),
+mFlags(0) // Caller will read in our flags from cache
+{
+  if (aVariants) {
+    mMimeTypeArray        = new char*[mVariants];
+    mExtensionsArray      = new char*[mVariants];
+    
+    for (PRInt32 i = 0; i < aVariants; ++i) {
+      if (mIsJavaPlugin && aMimeTypes[i] &&
+          strcmp(aMimeTypes[i], "application/x-java-vm-npruntime") == 0) {
+        mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
+        
+        // Stop processing here, any mimetypes after the magic "I'm a
+        // NPRuntime enabled Java plugin" mimetype will be ignored.
+        mVariants = i;
+        
+        break;
+      }
+      
+      mMimeTypeArray[i]        = new_str(aMimeTypes[i]);
+      mMimeDescriptionArray.AppendElement(aMimeDescriptions[i]);
+      mExtensionsArray[i]      = new_str(aExtensions[i]);
+      if (nsPluginHost::IsJavaMIMEType(mMimeTypeArray[i]))
+        mIsJavaPlugin = PR_TRUE;
+    }
+  }
+  
+  if (!aArgsAreUTF8)
+    EnsureMembersAreUTF8();
+}
+
+nsPluginTag::~nsPluginTag()
+{
+  NS_ASSERTION(!mNext, "Risk of exhausting the stack space, bug 486349");
+  
+  if (mMimeTypeArray) {
+    for (int i = 0; i < mVariants; i++)
+      delete[] mMimeTypeArray[i];
+    
+    delete[] (mMimeTypeArray);
+    mMimeTypeArray = nsnull;
+  }
+  
+  if (mExtensionsArray) {
+    for (int i = 0; i < mVariants; i++)
+      delete[] mExtensionsArray[i];
+    
+    delete[] (mExtensionsArray);
+    mExtensionsArray = nsnull;
+  }
+}
+
+NS_IMPL_ISUPPORTS1(nsPluginTag, nsIPluginTag)
+
+static nsresult ConvertToUTF8(nsIUnicodeDecoder *aUnicodeDecoder,
+                              nsAFlatCString& aString)
+{
+  PRInt32 numberOfBytes = aString.Length();
+  PRInt32 outUnicodeLen;
+  nsAutoString buffer;
+  nsresult rv = aUnicodeDecoder->GetMaxLength(aString.get(), numberOfBytes,
+                                              &outUnicodeLen);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (!EnsureStringLength(buffer, outUnicodeLen))
+    return NS_ERROR_OUT_OF_MEMORY;
+  rv = aUnicodeDecoder->Convert(aString.get(), &numberOfBytes,
+                                buffer.BeginWriting(), &outUnicodeLen);
+  NS_ENSURE_SUCCESS(rv, rv);
+  buffer.SetLength(outUnicodeLen);
+  CopyUTF16toUTF8(buffer, aString);
+  
+  return NS_OK;
+}
+
+nsresult nsPluginTag::EnsureMembersAreUTF8()
+{
+  nsresult rv;
+  
+  nsCOMPtr<nsIPlatformCharset> pcs =
+  do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsIUnicodeDecoder> decoder;
+  nsCOMPtr<nsICharsetConverterManager> ccm =
+  do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+  
+  nsCAutoString charset;
+  rv = pcs->GetCharset(kPlatformCharsetSel_FileName, charset);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (!charset.LowerCaseEqualsLiteral("utf-8")) {
+    rv = ccm->GetUnicodeDecoderRaw(charset.get(), getter_AddRefs(decoder));
+    NS_ENSURE_SUCCESS(rv, rv);
+    
+    ConvertToUTF8(decoder, mFileName);
+    ConvertToUTF8(decoder, mFullPath);
+  }
+  
+  // The description of the plug-in and the various MIME type descriptions
+  // should be encoded in the standard plain text file encoding for this system.
+  // XXX should we add kPlatformCharsetSel_PluginResource?
+  rv = pcs->GetCharset(kPlatformCharsetSel_PlainTextInFile, charset);
+  NS_ENSURE_SUCCESS(rv, rv);
+  if (!charset.LowerCaseEqualsLiteral("utf-8")) {
+    rv = ccm->GetUnicodeDecoderRaw(charset.get(), getter_AddRefs(decoder));
+    NS_ENSURE_SUCCESS(rv, rv);
+    
+    ConvertToUTF8(decoder, mName);
+    ConvertToUTF8(decoder, mDescription);
+    for (PRUint32 i = 0; i < mMimeDescriptionArray.Length(); ++i) {
+      ConvertToUTF8(decoder, mMimeDescriptionArray[i]);
+    }
+  }
+  return NS_OK;
+}
+
+void nsPluginTag::SetHost(nsPluginHost * aHost)
+{
+  mPluginHost = aHost;
+}
+
+NS_IMETHODIMP
+nsPluginTag::GetDescription(nsACString& aDescription)
+{
+  aDescription = mDescription;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPluginTag::GetFilename(nsACString& aFileName)
+{
+  aFileName = mFileName;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPluginTag::GetVersion(nsACString& aVersion)
+{
+  aVersion = mVersion;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPluginTag::GetName(nsACString& aName)
+{
+  aName = mName;
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPluginTag::GetDisabled(PRBool* aDisabled)
+{
+  *aDisabled = !HasFlag(NS_PLUGIN_FLAG_ENABLED);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPluginTag::SetDisabled(PRBool aDisabled)
+{
+  if (HasFlag(NS_PLUGIN_FLAG_ENABLED) == !aDisabled)
+    return NS_OK;
+  
+  if (aDisabled)
+    UnMark(NS_PLUGIN_FLAG_ENABLED);
+  else
+    Mark(NS_PLUGIN_FLAG_ENABLED);
+  
+  mPluginHost->UpdatePluginInfo(this);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPluginTag::GetBlocklisted(PRBool* aBlocklisted)
+{
+  *aBlocklisted = HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPluginTag::SetBlocklisted(PRBool aBlocklisted)
+{
+  if (HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED) == aBlocklisted)
+    return NS_OK;
+  
+  if (aBlocklisted)
+    Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
+  else
+    UnMark(NS_PLUGIN_FLAG_BLOCKLISTED);
+  
+  mPluginHost->UpdatePluginInfo(nsnull);
+  return NS_OK;
+}
+
+void
+nsPluginTag::RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
+                                         nsPluginTag::nsRegisterType aType)
+{
+  if (!mMimeTypeArray)
+    return;
+  
+  PLUGIN_LOG(PLUGIN_LOG_NORMAL,
+             ("nsPluginTag::RegisterWithCategoryManager plugin=%s, removing = %s\n",
+              mFileName.get(), aType == ePluginUnregister ? "yes" : "no"));
+  
+  nsCOMPtr<nsICategoryManager> catMan = do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
+  if (!catMan)
+    return;
+  
+  const char *contractId = "@mozilla.org/content/plugin/document-loader-factory;1";
+  
+  nsCOMPtr<nsIPrefBranch> psvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
+  if (!psvc)
+    return; // NS_ERROR_OUT_OF_MEMORY
+  
+  // A preference controls whether or not the full page plugin is disabled for
+  // a particular type. The string must be in the form:
+  //   type1,type2,type3,type4
+  // Note: need an actual interface to control this and subsequent disabling 
+  // (and other plugin host settings) so applications can reliably disable 
+  // plugins - without relying on implementation details such as prefs/category
+  // manager entries.
+  nsXPIDLCString overrideTypes;
+  psvc->GetCharPref("plugin.disable_full_page_plugin_for_types", getter_Copies(overrideTypes));
+  nsCAutoString overrideTypesFormatted;
+  overrideTypesFormatted.Assign(',');
+  overrideTypesFormatted += overrideTypes;
+  overrideTypesFormatted.Append(',');
+  
+  nsACString::const_iterator start, end;
+  for (int i = 0; i < mVariants; i++) {
+    if (aType == ePluginUnregister) {
+      nsXPIDLCString value;
+      if (NS_SUCCEEDED(catMan->GetCategoryEntry("Gecko-Content-Viewers",
+                                                mMimeTypeArray[i],
+                                                getter_Copies(value)))) {
+        // Only delete the entry if a plugin registered for it
+        if (strcmp(value, contractId) == 0) {
+          catMan->DeleteCategoryEntry("Gecko-Content-Viewers",
+                                      mMimeTypeArray[i],
+                                      PR_TRUE);
+        }
+      }
+    } else {
+      overrideTypesFormatted.BeginReading(start);
+      overrideTypesFormatted.EndReading(end);
+      
+      nsDependentCString mimeType(mMimeTypeArray[i]);
+      nsCAutoString commaSeparated; 
+      commaSeparated.Assign(',');
+      commaSeparated += mimeType;
+      commaSeparated.Append(',');
+      if (!FindInReadable(commaSeparated, start, end)) {
+        catMan->AddCategoryEntry("Gecko-Content-Viewers",
+                                 mMimeTypeArray[i],
+                                 contractId,
+                                 PR_FALSE, /* persist: broken by bug 193031 */
+                                 aOverrideInternalTypes, /* replace if we're told to */
+                                 nsnull);
+      }
+    }
+    
+    PLUGIN_LOG(PLUGIN_LOG_NOISY,
+               ("nsPluginTag::RegisterWithCategoryManager mime=%s, plugin=%s\n",
+                mMimeTypeArray[i], mFileName.get()));
+  }
+}
+
+void nsPluginTag::Mark(PRUint32 mask)
+{
+  PRBool wasEnabled = IsEnabled();
+  mFlags |= mask;
+  // Update entries in the category manager if necessary.
+  if (mPluginHost && wasEnabled != IsEnabled()) {
+    if (wasEnabled)
+      RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
+    else
+      RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginRegister);
+  }
+}
+
+void nsPluginTag::UnMark(PRUint32 mask)
+{
+  PRBool wasEnabled = IsEnabled();
+  mFlags &= ~mask;
+  // Update entries in the category manager if necessary.
+  if (mPluginHost && wasEnabled != IsEnabled()) {
+    if (wasEnabled)
+      RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
+    else
+      RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginRegister);
+  }
+}
+
+PRBool nsPluginTag::HasFlag(PRUint32 flag)
+{
+  return (mFlags & flag) != 0;
+}
+
+PRUint32 nsPluginTag::Flags()
+{
+  return mFlags;
+}
+
+PRBool nsPluginTag::IsEnabled()
+{
+  return HasFlag(NS_PLUGIN_FLAG_ENABLED) && !HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
+}
+
+PRBool nsPluginTag::Equals(nsPluginTag *aPluginTag)
+{
+  NS_ENSURE_TRUE(aPluginTag, PR_FALSE);
+  
+  if ((!mName.Equals(aPluginTag->mName)) ||
+      (!mDescription.Equals(aPluginTag->mDescription)) ||
+      (mVariants != aPluginTag->mVariants))
+    return PR_FALSE;
+  
+  if (mVariants && mMimeTypeArray && aPluginTag->mMimeTypeArray) {
+    for (PRInt32 i = 0; i < mVariants; i++) {
+      if (PL_strcmp(mMimeTypeArray[i], aPluginTag->mMimeTypeArray[i]) != 0)
+        return PR_FALSE;
+    }
+  }
+  return PR_TRUE;
+}
+
+void nsPluginTag::TryUnloadPlugin()
+{
+  if (mEntryPoint) {
+    mEntryPoint->Shutdown();
+    mEntryPoint = nsnull;
+  }
+  
+  // before we unload check if we are allowed to, see bug #61388
+  if (mLibrary && mCanUnloadLibrary) {
+    // NPAPI plugins can be unloaded now if they don't use XPConnect
+    if (!mXPConnected) {
+      // unload the plugin asynchronously by posting a PLEvent
+      nsPluginHost::PostPluginUnloadEvent(mLibrary);
+    }
+    else {
+      // add library to the unused library list to handle it later
+      if (mPluginHost)
+        mPluginHost->AddUnusedLibrary(mLibrary);
+    }
+  }
+  
+  // we should zero it anyway, it is going to be unloaded by
+  // CleanUnsedLibraries before we need to call the library
+  // again so the calling code should not be fooled and reload
+  // the library fresh
+  mLibrary = nsnull;
+  
+  // Remove mime types added to the category manager
+  // only if we were made 'active' by setting the host
+  if (mPluginHost) {
+    RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
+  }
+}
+
+/* nsPluginInstanceTag */
+
+nsPluginInstanceTag::nsPluginInstanceTag(nsPluginTag* aPluginTag,
+                                         nsIPluginInstance* aInstance,
+                                         const char * url,
+                                         PRBool aDefaultPlugin)
+{
+  mNext = nsnull;
+  mPluginTag = aPluginTag;
+  
+  mURL = PL_strdup(url);
+  mInstance = aInstance;
+  if (aInstance)
+    NS_ADDREF(aInstance);
+  mXPConnected = PR_FALSE;
+  mDefaultPlugin = aDefaultPlugin;
+  mStopped = PR_FALSE;
+  mllStopTime = LL_ZERO;
+}
+
+nsPluginInstanceTag::~nsPluginInstanceTag()
+{
+  mPluginTag = nsnull;
+  if (mInstance) {
+    nsCOMPtr<nsIPluginInstanceOwner> owner;
+    mInstance->GetOwner(getter_AddRefs(owner));
+    if (owner)
+      owner->SetInstance(nsnull);
+    mInstance->InvalidateOwner();
+    
+    NS_RELEASE(mInstance);
+  }
+  PL_strfree(mURL);
+}
+
+void nsPluginInstanceTag::setStopped(PRBool stopped)
+{
+  mStopped = stopped;
+  if (mStopped) // plugin instance is told to stop
+    mllStopTime = PR_Now();
+  else
+    mllStopTime = LL_ZERO;
+}
+
+/* nsPluginInstanceTagList */
+
+nsPluginInstanceTagList::nsPluginInstanceTagList()
+{
+  mFirst = nsnull;
+  mLast = nsnull;
+  mCount = 0;
+}
+
+nsPluginInstanceTagList::~nsPluginInstanceTagList()
+{
+  if (!mFirst)
+    return;
+  shutdown();
+}
+
+void nsPluginInstanceTagList::shutdown()
+{
+  if (!mFirst)
+    return;
+  
+  for (nsPluginInstanceTag * plugin = mFirst; plugin != nsnull;) {
+    nsPluginInstanceTag * next = plugin->mNext;
+    remove(plugin);
+    plugin = next;
+  }
+  mFirst = nsnull;
+  mLast = nsnull;
+}
+
+PRInt32 nsPluginInstanceTagList::add(nsPluginInstanceTag * plugin)
+{
+  if (!mFirst) {
+    mFirst = plugin;
+    mLast = plugin;
+    mFirst->mNext = nsnull;
+  }
+  else {
+    mLast->mNext = plugin;
+    mLast = plugin;
+  }
+  mLast->mNext = nsnull;
+  mCount++;
+  return mCount;
+}
+
+PRBool nsPluginInstanceTagList::IsLastInstance(nsPluginInstanceTag * plugin)
+{
+  if (!plugin)
+    return PR_FALSE;
+  
+  if (!plugin->mPluginTag)
+    return PR_FALSE;
+  
+  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
+    if ((p->mPluginTag == plugin->mPluginTag) && (p != plugin))
+      return PR_FALSE;
+  }
+  return PR_TRUE;
+}
+
+PRBool nsPluginInstanceTagList::remove(nsPluginInstanceTag * plugin)
+{
+  if (!mFirst)
+    return PR_FALSE;
+  
+  nsPluginInstanceTag * prev = nsnull;
+  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
+    if (p == plugin) {
+      PRBool lastInstance = IsLastInstance(p);
+      
+      if (p == mFirst)
+        mFirst = p->mNext;
+      else
+        prev->mNext = p->mNext;
+      
+      if (prev && !prev->mNext)
+        mLast = prev;
+      
+      if (lastInstance) {
+        nsRefPtr<nsPluginTag> pluginTag = p->mPluginTag;
+        
+        delete p;
+        
+        if (pluginTag) {
+          nsresult rv;
+          nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
+          NS_ENSURE_SUCCESS(rv, rv);
+          
+          PRBool unloadPluginsASAP = PR_FALSE;
+          rv = pref->GetBoolPref("plugins.unloadASAP", &unloadPluginsASAP);
+          if (NS_SUCCEEDED(rv) && unloadPluginsASAP)
+            pluginTag->TryUnloadPlugin();
+        } else {
+          NS_ASSERTION(pluginTag, "pluginTag was not set, plugin not shutdown");
+        }
+      } else {
+        delete p;
+      }
+      
+      mCount--;
+      return PR_TRUE;
+    }
+    prev = p;
+  }
+  return PR_FALSE;
+}
+
+// This method terminates all running instances of plugins and collects their
+// documents to be returned through an array. This method is used
+// when we are shutting down or when a plugins.refresh(1) happens.
+// If aPluginTag is given, then only that plugin is terminated
+void nsPluginInstanceTagList::stopRunning(nsISupportsArray* aReloadDocs,
+                                          nsPluginTag* aPluginTag)
+{
+  if (!mFirst)
+    return;
+  
+  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
+    if (!p->mStopped && p->mInstance &&
+        (!aPluginTag || aPluginTag == p->mPluginTag)) {
+      p->mInstance->SetWindow(nsnull);
+      p->mInstance->Stop();
+      p->setStopped(PR_TRUE);
+      
+      // If we've been passed an array to return, lets collect all our documents,
+      // removing duplicates. These will be reframed (embedded) or reloaded (full-page) later
+      // to kickstart our instances.
+      if (aReloadDocs && p->mInstance) {
+        nsCOMPtr<nsIPluginInstanceOwner> owner;
+        p->mInstance->GetOwner(getter_AddRefs(owner));
+        if (owner) {
+          nsCOMPtr<nsIDocument> doc;
+          owner->GetDocument(getter_AddRefs(doc));
+          if (doc && aReloadDocs->IndexOf(doc) == -1)  // don't allow for duplicates
+            aReloadDocs->AppendElement(doc);
+        }
+      }
+    }
+  }
+}
+
+void nsPluginInstanceTagList::removeAllStopped()
+{
+  if (!mFirst)
+    return;
+  
+  nsPluginInstanceTag * next = nsnull;
+  
+  for (nsPluginInstanceTag * p = mFirst; p != nsnull;) {
+    next = p->mNext;
+    
+    if (p->mStopped)
+      remove(p);
+    
+    p = next;
+  }
+  return;
+}
+
+nsPluginInstanceTag * nsPluginInstanceTagList::find(nsIPluginInstance* instance)
+{
+  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
+    if (p->mInstance == instance)
+      return p;
+  }
+  return nsnull;
+}
+
+nsPluginInstanceTag * nsPluginInstanceTagList::find(const char * mimetype)
+{
+  PRBool defaultplugin = (PL_strcmp(mimetype, "*") == 0);
+  
+  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
+    // give it some special treatment for the default plugin first
+    // because we cannot tell the default plugin by asking instance for a mime type
+    if (defaultplugin && p->mDefaultPlugin)
+      return p;
+    
+    if (!p->mInstance)
+      continue;
+    
+    const char* mt;
+    nsresult rv = p->mInstance->GetMIMEType(&mt);
+    if (NS_FAILED(rv))
+      continue;
+    
+    if (PL_strcasecmp(mt, mimetype) == 0)
+      return p;
+  }
+  return nsnull;
+}
+
+nsPluginInstanceTag * nsPluginInstanceTagList::findStopped(const char * url)
+{
+  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
+    if (!PL_strcmp(url, p->mURL) && p->mStopped)
+      return p;
+  }
+  return nsnull;
+}
+
+PRUint32 nsPluginInstanceTagList::getStoppedCount()
+{
+  PRUint32 stoppedCount = 0;
+  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
+    if (p->mStopped)
+      stoppedCount++;
+  }
+  return stoppedCount;
+}
+
+nsPluginInstanceTag * nsPluginInstanceTagList::findOldestStopped()
+{
+  nsPluginInstanceTag * res = nsnull;
+  PRInt64 llTime = LL_MAXINT;
+  for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
+    if (!p->mStopped)
+      continue;
+    
+    if (LL_CMP(p->mllStopTime, <, llTime)) {
+      llTime = p->mllStopTime;
+      res = p;
+    }
+  }
+  
+  return res;
+}
new file mode 100644
--- /dev/null
+++ b/modules/plugin/base/src/nsPluginTags.h
@@ -0,0 +1,172 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *  Josh Aas <josh@mozilla.com>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef nsPluginTags_h_
+#define nsPluginTags_h_
+
+#include "nscore.h"
+#include "prtypes.h"
+#include "nsAutoPtr.h"
+#include "nsCOMPtr.h"
+#include "nsIPluginTag.h"
+#include "nsIPlugin.h"
+#include "nsIPluginInstance.h"
+#include "nsISupportsArray.h"
+
+class nsPluginHost;
+struct PRLibrary;
+struct nsPluginInfo;
+
+// Remember that flags are written out to pluginreg.dat, be careful
+// changing their meaning.
+#define NS_PLUGIN_FLAG_ENABLED      0x0001    // is this plugin enabled?
+// no longer used                   0x0002    // reuse only if regenerating pluginreg.dat
+#define NS_PLUGIN_FLAG_FROMCACHE    0x0004    // this plugintag info was loaded from cache
+#define NS_PLUGIN_FLAG_UNWANTED     0x0008    // this is an unwanted plugin
+#define NS_PLUGIN_FLAG_BLOCKLISTED  0x0010    // this is a blocklisted plugin
+
+// A linked-list of plugin information that is used for instantiating plugins
+// and reflecting plugin information into JavaScript.
+class nsPluginTag : public nsIPluginTag
+{
+public:
+  enum nsRegisterType {
+    ePluginRegister,
+    ePluginUnregister
+  };
+  
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIPLUGINTAG
+  
+  nsPluginTag(nsPluginTag* aPluginTag);
+  nsPluginTag(nsPluginInfo* aPluginInfo);
+  nsPluginTag(const char* aName,
+              const char* aDescription,
+              const char* aFileName,
+              const char* aFullPath,
+              const char* aVersion,
+              const char* const* aMimeTypes,
+              const char* const* aMimeDescriptions,
+              const char* const* aExtensions,
+              PRInt32 aVariants,
+              PRInt64 aLastModifiedTime = 0,
+              PRBool aCanUnload = PR_TRUE,
+              PRBool aArgsAreUTF8 = PR_FALSE);
+  ~nsPluginTag();
+  
+  void SetHost(nsPluginHost * aHost);
+  void TryUnloadPlugin();
+  void Mark(PRUint32 mask);
+  void UnMark(PRUint32 mask);
+  PRBool HasFlag(PRUint32 flag);
+  PRUint32 Flags();
+  PRBool Equals(nsPluginTag* aPluginTag);
+  PRBool IsEnabled();
+  void RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
+                                   nsRegisterType aType = ePluginRegister);
+  
+  nsRefPtr<nsPluginTag> mNext;
+  nsPluginHost *mPluginHost;
+  nsCString     mName; // UTF-8
+  nsCString     mDescription; // UTF-8
+  PRInt32       mVariants;
+  char          **mMimeTypeArray;
+  nsTArray<nsCString> mMimeDescriptionArray; // UTF-8
+  char          **mExtensionsArray;
+  PRLibrary     *mLibrary;
+  nsCOMPtr<nsIPlugin> mEntryPoint;
+  PRPackedBool  mCanUnloadLibrary;
+  PRPackedBool  mXPConnected;
+  PRPackedBool  mIsJavaPlugin;
+  PRPackedBool  mIsNPRuntimeEnabledJavaPlugin;
+  nsCString     mFileName; // UTF-8
+  nsCString     mFullPath; // UTF-8
+  nsCString     mVersion;  // UTF-8
+  PRInt64       mLastModifiedTime;
+private:
+  PRUint32      mFlags;
+  
+  nsresult EnsureMembersAreUTF8();
+};
+
+struct nsPluginInstanceTag
+{
+  nsPluginInstanceTag*   mNext;
+  char*                  mURL;
+  nsRefPtr<nsPluginTag>  mPluginTag;
+  nsIPluginInstance*     mInstance;
+  PRTime                 mllStopTime;
+  PRPackedBool           mStopped;
+  PRPackedBool           mDefaultPlugin;
+  PRPackedBool           mXPConnected;
+  // Array holding all opened stream listeners for this entry
+  nsCOMPtr <nsISupportsArray> mStreams; 
+  
+  nsPluginInstanceTag(nsPluginTag* aPluginTag,
+                      nsIPluginInstance* aInstance, 
+                      const char * url,
+                      PRBool aDefaultPlugin);
+  ~nsPluginInstanceTag();
+  
+  void setStopped(PRBool stopped);
+};
+
+class nsPluginInstanceTagList
+{
+public:
+  nsPluginInstanceTag *mFirst;
+  nsPluginInstanceTag *mLast;
+  PRInt32 mCount;
+  
+  nsPluginInstanceTagList();
+  ~nsPluginInstanceTagList();
+  
+  void shutdown();
+  PRBool add(nsPluginInstanceTag *plugin);
+  PRBool remove(nsPluginInstanceTag *plugin);
+  nsPluginInstanceTag *find(nsIPluginInstance *instance);
+  nsPluginInstanceTag *find(const char *mimetype);
+  nsPluginInstanceTag *findStopped(const char *url);
+  PRUint32 getStoppedCount();
+  nsPluginInstanceTag *findOldestStopped();
+  void removeAllStopped();
+  void stopRunning(nsISupportsArray *aReloadDocs, nsPluginTag *aPluginTag);
+  PRBool IsLastInstance(nsPluginInstanceTag *plugin);
+};
+
+#endif // nsPluginTags_h_
new file mode 100644
--- /dev/null
+++ b/modules/plugin/test/reftest/div-alpha-opacity.html
@@ -0,0 +1,27 @@
+<!doctype html>
+<html>
+<head>
+<style type="text/css">
+#one {
+  position:absolute;
+  left:0px; top:0px;
+  width:400px; height:400px;
+  background-color: rgb(160,160,160);
+  opacity:0.5;
+  z-index:1;
+}
+#two {
+  position:absolute;
+  top:100px; left:100px;
+  width:200px; height:200px;
+  z-index:0;
+  background-color: rgb(255,0,0);
+}
+</style>
+</head>
+<body>
+<div id="two"></div>
+<div id="one"></div>
+</body>
+</html>
+
new file mode 100644
--- /dev/null
+++ b/modules/plugin/test/reftest/plugin-alpha-opacity.html
@@ -0,0 +1,26 @@
+<!doctype html>
+<html>
+<head>
+<style type="text/css">
+#one {
+  position:absolute;
+  left:0px; top:0px;
+  width:400px; height:400px;
+  opacity:.5;
+  z-index:1;
+}
+#two {
+  position:absolute;
+  top:100px; left:100px;
+  width:200px; height:200px;
+  z-index:0;
+  background-color: rgb(255,0,0);
+}
+</style>
+</head>
+<body>
+<div id="two"></div>
+<embed id="one" type="application/x-test" width="400" height="400" drawmode="solid" color="FFa0a0a0"></embed>
+</body>
+</html>
+
--- a/modules/plugin/test/reftest/reftest.list
+++ b/modules/plugin/test/reftest/reftest.list
@@ -1,9 +1,10 @@
 # basic sanity checking
 random-if(!haveTestPlugin) != plugin-sanity.html about:blank
 fails-if(!haveTestPlugin) == plugin-sanity.html div-sanity.html
 fails-if(!haveTestPlugin) == plugin-alpha-zindex.html div-alpha-zindex.html
+fails-if(!haveTestPlugin) == plugin-alpha-opacity.html div-alpha-opacity.html
 fails-if(!haveTestPlugin) == windowless-clipping-1.html windowless-clipping-1-ref.html
 fails-if(!haveTestPlugin) == border-padding-1.html border-padding-1-ref.html
 fails-if(!haveTestPlugin) == border-padding-2.html border-padding-2-ref.html
 # Disabled for now to investigate Windows/Linux test failures
 # fails-if(!haveTestPlugin) == border-padding-3.html border-padding-3-ref.html
--- a/netwerk/base/src/NetUtil.jsm
+++ b/netwerk/base/src/NetUtil.jsm
@@ -123,33 +123,33 @@ const NetUtil = {
         }
 
         // start the copying
         copier.asyncCopy(observer, null);
         return copier;
     },
 
     /**
-     * Asynchronously opens a channel and fetches the response.  The provided
-     * callback will get an input stream containing the response, and the result
-     * code.
+     * Asynchronously opens a source and fetches the response.  A source can be
+     * an nsIURI, nsIFile, string spec, or nsIChannel.  The provided callback
+     * will get an input stream containing the response, and the result code.
      *
-     * @param aChannel
-     *        The nsIChannel to open.
+     * @param aSource
+     *        The nsIURI, nsIFile, string spec, or nsIChannel to open.
      * @param aCallback
      *        The callback function that will be notified upon completion.  It
      *        will get two arguments:
      *        1) An nsIInputStream containing the data from the channel, if any.
-     *        2) The status code from opening the channel.
+     *        2) The status code from opening the source.
      */
-    asyncFetch: function NetUtil_asyncOpen(aChannel, aCallback)
+    asyncFetch: function NetUtil_asyncOpen(aSource, aCallback)
     {
-        if (!aChannel || !aCallback) {
+        if (!aSource || !aCallback) {
             let exception = new Components.Exception(
-                "Must have a channel and a callback",
+                "Must have a source and a callback",
                 Cr.NS_ERROR_INVALID_ARG,
                 Components.stack.caller
             );
             throw exception;
         }
 
         // Create a pipe that will create our output stream that we can use once
         // we have gotten all the data.
@@ -163,43 +163,90 @@ const NetUtil = {
         listener.init(pipe.outputStream, {
             onStartRequest: function(aRequest, aContext) {},
             onStopRequest: function(aRequest, aContext, aStatusCode) {
                 pipe.outputStream.close();
                 aCallback(pipe.inputStream, aStatusCode);
             }
         });
 
-        aChannel.asyncOpen(listener, null);
+        let channel = aSource;
+        if (!(channel instanceof Ci.nsIChannel)) {
+            channel = this.newChannel(aSource);
+        }
+
+        channel.asyncOpen(listener, null);
     },
 
     /**
-     * Constructs a new URI for the given spec, character set, and base URI.
+     * Constructs a new URI for the given spec, character set, and base URI, or
+     * an nsIFile.
      *
-     * @param aSpec
-     *        The spec for the desired URI.
+     * @param aTarget
+     *        The string spec for the desired URI or an nsIFile.
      * @param aOriginCharset [optional]
-     *        The character set for the URI.
+     *        The character set for the URI.  Only used if aTarget is not an
+     *        nsIFile.
      * @param aBaseURI [optional]
-     *        The base URI for the spec.
+     *        The base URI for the spec.  Only used if aTarget is not an
+     *        nsIFile.
      *
      * @return an nsIURI object.
      */
-    newURI: function NetUtil_newURI(aSpec, aOriginCharset, aBaseURI)
+    newURI: function NetUtil_newURI(aTarget, aOriginCharset, aBaseURI)
     {
-        if (!aSpec) {
+        if (!aTarget) {
             let exception = new Components.Exception(
-                "Must have a non-null spec",
+                "Must have a non-null string spec or nsIFile object",
                 Cr.NS_ERROR_INVALID_ARG,
                 Components.stack.caller
             );
             throw exception;
         }
 
-        return this.ioService.newURI(aSpec, aOriginCharset, aBaseURI);
+        if (aTarget instanceof Ci.nsIFile) {
+            return this.ioService.newFileURI(aTarget);
+        }
+
+        return this.ioService.newURI(aTarget, aOriginCharset, aBaseURI);
+    },
+
+    /**
+     * Constructs a new channel for the given spec, character set, and base URI,
+     * or nsIURI, or nsIFile.
+     *
+     * @param aWhatToLoad
+     *        The string spec for the desired URI, an nsIURI, or an nsIFile.
+     * @param aOriginCharset [optional]
+     *        The character set for the URI.  Only used if aWhatToLoad is a
+     *        string.
+     * @param aBaseURI [optional]
+     *        The base URI for the spec.  Only used if aWhatToLoad is a string.
+     *
+     * @return an nsIChannel object.
+     */
+    newChannel: function NetUtil_newChannel(aWhatToLoad, aOriginCharset,
+                                            aBaseURI)
+    {
+        if (!aWhatToLoad) {
+            let exception = new Components.Exception(
+                "Must have a non-null string spec, nsIURI, or nsIFile object",
+                Cr.NS_ERROR_INVALID_ARG,
+                Components.stack.caller
+            );
+            throw exception;
+        }
+
+        let uri = aWhatToLoad;
+        if (!(aWhatToLoad instanceof Ci.nsIURI)) {
+            // We either have a string or an nsIFile that we'll need a URI for.
+            uri = this.newURI(aWhatToLoad, aOriginCharset, aBaseURI);
+        }
+
+        return this.ioService.newChannelFromURI(uri);
     },
 
     /**
      * Returns a reference to nsIIOService.
      *
      * @return a reference to nsIIOService.
      */
     get ioService()
--- a/netwerk/cookie/public/nsICookieService.idl
+++ b/netwerk/cookie/public/nsICookieService.idl
@@ -47,28 +47,33 @@ interface nsIChannel;
  * Provides methods for setting and getting cookies in the context of a
  * page load.  See nsICookieManager for methods to manipulate the cookie
  * database directly.  This separation of interface is mainly historical.
  *
  * This service broadcasts the following notifications when the cookie
  * list is changed, or a cookie is rejected:
  *
  * topic  : "cookie-changed"
- *          broadcast whenever the cookie list changes in some way. there
- *          are four possible data strings for this notification; one
- *          notification will be broadcast for each change, and will involve
- *          a single cookie.
- * subject: an nsICookie2 interface pointer representing the cookie object
- *          that changed.
+ *          broadcast whenever the cookie list changes in some way. see
+ *          explanation of data strings below.
+ * subject: see below.
  * data   : "deleted"
- *          a cookie was deleted. the subject is the deleted cookie.
+ *          a cookie was deleted. the subject is an nsICookie2 representing
+ *          the deleted cookie.
  *          "added"
- *          a cookie was added. the subject is the added cookie.
+ *          a cookie was added. the subject is an nsICookie2 representing
+ *          the added cookie.
  *          "changed"
- *          a cookie was changed. the subject is the new cookie.
+ *          a cookie was changed. the subject is an nsICookie2 representing
+ *          the new cookie. (note that host, path, and name are invariant
+ *          for a given cookie; other parameters may change.)
+ *          "batch-deleted"
+ *          a batch of cookies was deleted (for instance, as part of a purging
+ *          operation). the subject is an nsIArray of nsICookie2's representing
+ *          the deleted cookies.
  *          "cleared"
  *          the entire cookie list was cleared. the subject is null.
  *          "reload"
  *          the entire cookie list should be reloaded.  the subject is null.
  *
  * topic  : "cookie-rejected"
  *          broadcast whenever a cookie was rejected from being set as a
  *          result of user prefs.
@@ -80,19 +85,21 @@ interface nsIChannel;
 interface nsICookieService : nsISupports
 {
   /*
    * Get the complete cookie string associated with the URI.
    *
    * @param aURI
    *        the URI of the document for which cookies are being queried.
    * @param aChannel
-   *        the channel used to load the document.  this parameter may be null,
-   *        but it is strongly recommended that a non-null value be provided to
-   *        ensure that the cookie privacy preferences are honored.
+   *        the channel used to load the document.  this parameter should not
+   *        be null, otherwise the cookies will not be returned if third-party
+   *        cookies have been disabled by the user. (the channel is used
+   *        to determine the originating URI of the document; if it is not
+   *        provided, the cookies will be assumed third-party.)
    *
    * @return the resulting cookie string
    */
   string getCookieString(in nsIURI aURI, in nsIChannel aChannel);
 
   /*
    * Get the complete cookie string associated with the URI.
    *
@@ -100,37 +107,41 @@ interface nsICookieService : nsISupports
    * will be different based on httponly (see bug 178993)
    *
    * @param aURI
    *        the URI of the document for which cookies are being queried.
    * @param aFirstURI
    *        the URI that the user originally typed in or clicked on to initiate
    *        the load of the document referenced by aURI.
    * @param aChannel
-   *        the channel used to load the document.  this parameter may be null,
-   *        but it is strongly recommended that a non-null value be provided to
-   *        ensure that the cookie privacy preferences are honored.
+   *        the channel used to load the document.  this parameter should not
+   *        be null, otherwise the cookies will not be returned if third-party
+   *        cookies have been disabled by the user. (the channel is used
+   *        to determine the originating URI of the document; if it is not
+   *        provided, the cookies will be assumed third-party.)
    *
    * @return the resulting cookie string
    */
   string getCookieStringFromHttp(in nsIURI aURI, in nsIURI aFirstURI, in nsIChannel aChannel);
 
   /*
    * Set the cookie string associated with the URI.
    *
    * @param aURI
    *        the URI of the document for which cookies are being set.
    * @param aPrompt
    *        the prompt to use for all user-level cookie notifications.
    * @param aCookie
    *        the cookie string to set.
    * @param aChannel
-   *        the channel used to load the document.  this parameter may be null,
-   *        but it is strongly recommended that a non-null value be provided to
-   *        ensure that the cookie privacy preferences are honored.
+   *        the channel used to load the document.  this parameter should not
+   *        be null, otherwise the cookies will not be set if third-party
+   *        cookies have been disabled by the user. (the channel is used
+   *        to determine the originating URI of the document; if it is not
+   *        provided, the cookies will be assumed third-party.)
    *
    * XXX should be able to allow null aPrompt, since nsIPrompt can be queryied
    * from aChannel.
    */
   void setCookieString(in nsIURI aURI, in nsIPrompt aPrompt, in string aCookie, in nsIChannel aChannel);
 
   /*
    * Set the cookie string and expires associated with the URI.
@@ -146,14 +157,16 @@ interface nsICookieService : nsISupports
    * @param aPrompt
    *        the prompt to use for all user-level cookie notifications.
    * @param aCookie
    *        the cookie string to set.
    * @param aServerTime
    *        the expiry information of the cookie (the Date header from the HTTP
    *        response).
    * @param aChannel
-   *        the channel used to load the document.  this parameter may be null,
-   *        but it is strongly recommended that a non-null value be provided to
-   *        ensure that the cookie privacy preferences are honored.
+   *        the channel used to load the document.  this parameter should not
+   *        be null, otherwise the cookies will not be set if third-party
+   *        cookies have been disabled by the user. (the channel is used
+   *        to determine the originating URI of the document; if it is not
+   *        provided, the cookies will be assumed third-party.)
    */
   void setCookieStringFromHttp(in nsIURI aURI, in nsIURI aFirstURI, in nsIPrompt aPrompt, in string aCookie, in string aServerTime, in nsIChannel aChannel);
 };
--- a/netwerk/cookie/src/nsCookieService.cpp
+++ b/netwerk/cookie/src/nsCookieService.cpp
@@ -50,17 +50,19 @@
 #include "nsIURI.h"
 #include "nsIURL.h"
 #include "nsIChannel.h"
 #include "nsIFile.h"
 #include "nsIObserverService.h"
 #include "nsILineInputStream.h"
 #include "nsIEffectiveTLDService.h"
 
+#include "nsTArray.h"
 #include "nsCOMArray.h"
+#include "nsIMutableArray.h"
 #include "nsArrayEnumerator.h"
 #include "nsEnumeratorUtils.h"
 #include "nsAutoPtr.h"
 #include "nsReadableUtils.h"
 #include "nsCRT.h"
 #include "prtime.h"
 #include "prprf.h"
 #include "nsNetUtil.h"
@@ -80,22 +82,26 @@
 // This is a hack to hide HttpOnly cookies from older browsers
 //
 static const char kHttpOnlyPrefix[] = "#HttpOnly_";
 
 static const char kCookieFileName[] = "cookies.sqlite";
 #define COOKIES_SCHEMA_VERSION 2
 
 static const PRInt64 kCookieStaleThreshold = 60 * PR_USEC_PER_SEC; // 1 minute in microseconds
+static const PRInt64 kCookiePurgeAge = 30 * 24 * 60 * 60 * PR_USEC_PER_SEC; // 30 days in microseconds
 
 static const char kOldCookieFileName[] = "cookies.txt";
 
 #undef  LIMIT
 #define LIMIT(x, low, high, default) ((x) >= (low) && (x) <= (high) ? (x) : (default))
 
+#undef  ADD_TEN_PERCENT
+#define ADD_TEN_PERCENT(i) ((i) + (i)/10)
+
 // default limits for the cookie list. these can be tuned by the
 // network.cookie.maxNumber and network.cookie.maxPerHost prefs respectively.
 static const PRUint32 kMaxNumberOfCookies = 3000;
 static const PRUint32 kMaxCookiesPerHost  = 50;
 static const PRUint32 kMaxBytesPerCookie  = 4096;
 static const PRUint32 kMaxBytesPerPath    = 1024;
 
 // these constants represent a decision about a cookie based on user prefs.
@@ -111,16 +117,17 @@ static const PRUint32 STATUS_REJECTED_WI
 static const PRUint32 BEHAVIOR_ACCEPT        = 0;
 static const PRUint32 BEHAVIOR_REJECTFOREIGN = 1;
 static const PRUint32 BEHAVIOR_REJECT        = 2;
 
 // pref string constants
 static const char kPrefCookiesPermissions[] = "network.cookie.cookieBehavior";
 static const char kPrefMaxNumberOfCookies[] = "network.cookie.maxNumber";
 static const char kPrefMaxCookiesPerHost[]  = "network.cookie.maxPerHost";
+static const char kPrefCookiePurgeAge[]     = "network.cookie.purgeAge";
 
 // struct for temporarily storing cookie attributes during header parsing
 struct nsCookieAttributes
 {
   nsCAutoString name;
   nsCAutoString value;
   nsCAutoString host;
   nsCAutoString path;
@@ -201,17 +208,23 @@ struct nsEnumerationData
 #define SET_COOKIE PR_TRUE
 #define GET_COOKIE PR_FALSE
 
 #ifdef PR_LOGGING
 static PRLogModuleInfo *sCookieLog = PR_NewLogModule("cookie");
 
 #define COOKIE_LOGFAILURE(a, b, c, d)    LogFailure(a, b, c, d)
 #define COOKIE_LOGSUCCESS(a, b, c, d, e) LogSuccess(a, b, c, d, e)
-#define COOKIE_LOGEVICTED(a)             LogEvicted(a)
+
+#define COOKIE_LOGEVICTED(a)                   \
+  PR_BEGIN_MACRO                               \
+    if (PR_LOG_TEST(sCookieLog, PR_LOG_DEBUG)) \
+      LogEvicted(a);                           \
+  PR_END_MACRO
+
 #define COOKIE_LOGSTRING(lvl, fmt)   \
   PR_BEGIN_MACRO                     \
     PR_LOG(sCookieLog, lvl, fmt);    \
     PR_LOG(sCookieLog, lvl, ("\n")); \
   PR_END_MACRO
 
 static void
 LogFailure(PRBool aSetCookie, nsIURI *aHostURI, const char *aCookieString, const char *aReason)
@@ -294,21 +307,16 @@ LogSuccess(PRBool aSetCookie, nsIURI *aH
   LogCookie(aCookie);
 
   PR_LOG(sCookieLog, PR_LOG_DEBUG,("\n"));
 }
 
 static void
 LogEvicted(nsCookie *aCookie)
 {
-  // if logging isn't enabled, return now to save cycles
-  if (!PR_LOG_TEST(sCookieLog, PR_LOG_DEBUG)) {
-    return;
-  }
-
   PR_LOG(sCookieLog, PR_LOG_DEBUG,("===== COOKIE EVICTED =====\n"));
 
   LogCookie(aCookie);
 
   PR_LOG(sCookieLog, PR_LOG_DEBUG,("\n"));
 }
 
 // inline wrappers to make passing in nsAFlatCStrings easier
@@ -375,16 +383,17 @@ NS_IMPL_ISUPPORTS5(nsCookieService,
                    nsIObserver,
                    nsISupportsWeakReference)
 
 nsCookieService::nsCookieService()
  : mDBState(&mDefaultDBState)
  , mCookiesPermissions(BEHAVIOR_ACCEPT)
  , mMaxNumberOfCookies(kMaxNumberOfCookies)
  , mMaxCookiesPerHost(kMaxCookiesPerHost)
+ , mCookiePurgeAge(kCookiePurgeAge)
 {
 }
 
 nsresult
 nsCookieService::Init()
 {
   if (!mDBState->hostTable.Init()) {
     return NS_ERROR_OUT_OF_MEMORY;
@@ -395,16 +404,17 @@ nsCookieService::Init()
   NS_ENSURE_SUCCESS(rv, rv);
 
   // init our pref and observer
   nsCOMPtr<nsIPrefBranch2> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID);
   if (prefBranch) {
     prefBranch->AddObserver(kPrefCookiesPermissions, this, PR_TRUE);
     prefBranch->AddObserver(kPrefMaxNumberOfCookies, this, PR_TRUE);
     prefBranch->AddObserver(kPrefMaxCookiesPerHost,  this, PR_TRUE);
+    prefBranch->AddObserver(kPrefCookiePurgeAge,     this, PR_TRUE);
     PrefChanged(prefBranch);
   }
 
   // failure here is non-fatal (we can run fine without
   // persistent storage - e.g. if there's no profile)
   rv = InitDB();
   if (NS_FAILED(rv))
     COOKIE_LOGSTRING(PR_LOG_WARNING, ("Init(): InitDB() gave error %x", rv));
@@ -686,31 +696,33 @@ nsCookieService::Observe(nsISupports    
   } else if (!strcmp(aTopic, NS_PRIVATE_BROWSING_SWITCH_TOPIC)) {
     if (NS_LITERAL_STRING(NS_PRIVATE_BROWSING_ENTER).Equals(aData)) {
       if (!mPrivateDBState.hostTable.IsInitialized() &&
           !mPrivateDBState.hostTable.Init())
         return NS_ERROR_OUT_OF_MEMORY;
 
       NS_ASSERTION(mDBState == &mDefaultDBState, "already in private state");
       NS_ASSERTION(mPrivateDBState.cookieCount == 0, "private count not 0");
+      NS_ASSERTION(mPrivateDBState.cookieOldestTime == LL_MAXINT, "private time not reset");
       NS_ASSERTION(mPrivateDBState.hostTable.Count() == 0, "private table not empty");
       NS_ASSERTION(mPrivateDBState.dbConn == NULL, "private DB connection not null");
 
       // swap the private and default states
       mDBState = &mPrivateDBState;
 
       NotifyChanged(nsnull, NS_LITERAL_STRING("reload").get());
 
     } else if (NS_LITERAL_STRING(NS_PRIVATE_BROWSING_LEAVE).Equals(aData)) {
       // restore the default state, and clear the private one
       mDBState = &mDefaultDBState;
 
       NS_ASSERTION(!mPrivateDBState.dbConn, "private DB connection not null");
 
       mPrivateDBState.cookieCount = 0;
+      mPrivateDBState.cookieOldestTime = LL_MAXINT;
       if (mPrivateDBState.hostTable.IsInitialized())
         mPrivateDBState.hostTable.Clear();
 
       NotifyChanged(nsnull, NS_LITERAL_STRING("reload").get());
     }
   }
 
   return NS_OK;
@@ -807,28 +819,30 @@ nsCookieService::SetCookieStringInternal
 // notify observers that a cookie was rejected due to the users' prefs.
 void
 nsCookieService::NotifyRejected(nsIURI *aHostURI)
 {
   if (mObserverService)
     mObserverService->NotifyObservers(aHostURI, "cookie-rejected", nsnull);
 }
 
-// notify observers that the cookie list changed. there are four possible
+// notify observers that the cookie list changed. there are five possible
 // values for aData:
-// "deleted" means a cookie was deleted. aCookie is the deleted cookie.
-// "added"   means a cookie was added. aCookie is the added cookie.
-// "changed" means a cookie was altered. aCookie is the new cookie.
-// "cleared" means the entire cookie list was cleared. aCookie is null.
+// "deleted" means a cookie was deleted. aSubject is the deleted cookie.
+// "added"   means a cookie was added. aSubject is the added cookie.
+// "changed" means a cookie was altered. aSubject is the new cookie.
+// "cleared" means the entire cookie list was cleared. aSubject is null.
+// "batch-deleted" means multiple cookies were deleted. aSubject is the list of
+// cookies.
 void
-nsCookieService::NotifyChanged(nsICookie2      *aCookie,
+nsCookieService::NotifyChanged(nsISupports     *aSubject,
                                const PRUnichar *aData)
 {
   if (mObserverService)
-    mObserverService->NotifyObservers(aCookie, "cookie-changed", aData);
+    mObserverService->NotifyObservers(aSubject, "cookie-changed", aData);
 }
 
 /******************************************************************************
  * nsCookieService:
  * pref observer impl
  ******************************************************************************/
 
 void
@@ -838,16 +852,19 @@ nsCookieService::PrefChanged(nsIPrefBran
   if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefCookiesPermissions, &val)))
     mCookiesPermissions = (PRUint8) LIMIT(val, 0, 2, 0);
 
   if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefMaxNumberOfCookies, &val)))
     mMaxNumberOfCookies = (PRUint16) LIMIT(val, 1, 0xFFFF, kMaxNumberOfCookies);
 
   if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefMaxCookiesPerHost, &val)))
     mMaxCookiesPerHost = (PRUint16) LIMIT(val, 1, 0xFFFF, kMaxCookiesPerHost);
+
+  if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefCookiePurgeAge, &val)))
+    mCookiePurgeAge = LIMIT(val, 0, PR_INT32_MAX, PR_INT32_MAX) * PR_USEC_PER_SEC;
 }
 
 /******************************************************************************
  * nsICookieManager impl:
  * nsICookieManager
  ******************************************************************************/
 
 NS_IMETHODIMP
@@ -933,17 +950,17 @@ nsCookieService::Add(const nsACString &a
                      currentTimeInUsec,
                      aIsSession,
                      aIsSecure,
                      aIsHttpOnly);
   if (!cookie) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
-  AddInternal(cookie, currentTimeInUsec / PR_USEC_PER_SEC, nsnull, nsnull, PR_TRUE);
+  AddInternal(cookie, currentTimeInUsec, nsnull, nsnull, PR_TRUE);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCookieService::Remove(const nsACString &aHost,
                         const nsACString &aName,
                         const nsACString &aPath,
                         PRBool           aBlocked)
@@ -1177,52 +1194,55 @@ nsCookieService::ImportCookies(nsIFile *
     
     // trick: preserve the most-recently-used cookie ordering,
     // by successively decrementing the lastAccessed time
     lastAccessedCounter--;
 
     if (originalCookieCount == 0)
       AddCookieToList(newCookie);
     else
-      AddInternal(newCookie, currentTime, nsnull, nsnull, PR_TRUE);
+      AddInternal(newCookie, currentTimeInUsec, nsnull, nsnull, PR_TRUE);
   }
 
   COOKIE_LOGSTRING(PR_LOG_DEBUG, ("ImportCookies(): %ld cookies imported", mDBState->cookieCount));
 
   return NS_OK;
 }
 
 /******************************************************************************
  * nsCookieService impl:
  * private GetCookie/SetCookie helpers
  ******************************************************************************/
 
 // helper function for GetCookieList
 static inline PRBool ispathdelimiter(char c) { return c == '/' || c == '?' || c == '#' || c == ';'; }
 
 // Comparator class for sorting cookies before sending to a server.
-class CompareCookiesForSendingComparator
+class CompareCookiesForSending
 {
-  public:
-  PRBool Equals(const nsCookie* aCookie1, const nsCookie* aCookie2) const {
-    return PR_FALSE; // CreationID is unique, so two id's can never be equal.
+public:
+  PRBool Equals(const nsCookie* aCookie1, const nsCookie* aCookie2) const
+  {
+    // CreationID is unique, so two id's can never be equal.
+    return PR_FALSE;
   }
-  PRBool LessThan(const nsCookie* aCookie1, const nsCookie* aCookie2) const {
+
+  PRBool LessThan(const nsCookie* aCookie1, const nsCookie* aCookie2) const
+  {
     // compare by cookie path length in accordance with RFC2109
-    int rv = aCookie2->Path().Length() - aCookie1->Path().Length();
-    if (rv == 0) {
-      // when path lengths match, older cookies should be listed first.  this is
-      // required for backwards compatibility since some websites erroneously
-      // depend on receiving cookies in the order in which they were sent to the
-      // browser!  see bug 236772.
-      // note: CreationID is unique, so two id's can never be equal.
-      // we may have overflow problems returning the result directly, so we need branches
-      rv = (aCookie1->CreationID() > aCookie2->CreationID() ? 1 : -1);
-    }
-    return rv < 0;
+    PRInt32 result = aCookie2->Path().Length() - aCookie1->Path().Length();
+    if (result != 0)
+      return result < 0;
+
+    // when path lengths match, older cookies should be listed first.  this is
+    // required for backwards compatibility since some websites erroneously
+    // depend on receiving cookies in the order in which they were sent to the
+    // browser!  see bug 236772.
+    // note: CreationID is unique, so two id's can never be equal.
+    return aCookie1->CreationID() < aCookie2->CreationID();
   }
 };
 
 void
 nsCookieService::GetCookieInternal(nsIURI      *aHostURI,
                                    nsIChannel  *aChannel,
                                    PRBool       aHttpBound,
                                    char       **aCookie)
@@ -1353,17 +1373,17 @@ nsCookieService::GetCookieInternal(nsIUR
       if (currentTimeInUsec - cookie->LastAccessed() > kCookieStaleThreshold)
         UpdateCookieInList(cookie, currentTimeInUsec);
     }
   }
 
   // return cookies in order of path length; longest to shortest.
   // this is required per RFC2109.  if cookies match in length,
   // then sort by creation time (see bug 236772).
-  foundCookieList.Sort(CompareCookiesForSendingComparator());
+  foundCookieList.Sort(CompareCookiesForSending());
 
   nsCAutoString cookieData;
   for (PRInt32 i = 0; i < count; ++i) {
     cookie = foundCookieList.ElementAt(i);
 
     // check if we have anything to write
     if (!cookie->Name().IsEmpty() || !cookie->Value().IsEmpty()) {
       // if we've already added a cookie to the return list, append a "; " so
@@ -1476,103 +1496,102 @@ nsCookieService::SetCookieInternal(nsIUR
 
     // update isSession and expiry attributes, in case they changed
     cookie->SetIsSession(cookieAttributes.isSession);
     cookie->SetExpiry(cookieAttributes.expiryTime);
   }
 
   // add the cookie to the list. AddInternal() takes care of logging.
   // we get the current time again here, since it may have changed during prompting
-  AddInternal(cookie, PR_Now() / PR_USEC_PER_SEC, aHostURI, savedCookieHeader.get(), aFromHttp);
+  AddInternal(cookie, PR_Now(), aHostURI, savedCookieHeader.get(), aFromHttp);
   return newCookie;
 }
 
 // this is a backend function for adding a cookie to the list, via SetCookie.
 // also used in the cookie manager, for profile migration from IE.
 // it either replaces an existing cookie; or adds the cookie to the hashtable,
 // and deletes a cookie (if maximum number of cookies has been
 // reached). also performs list maintenance by removing expired cookies.
 void
 nsCookieService::AddInternal(nsCookie   *aCookie,
-                             PRInt64     aCurrentTime,
+                             PRInt64     aCurrentTimeInUsec,
                              nsIURI     *aHostURI,
                              const char *aCookieHeader,
                              PRBool      aFromHttp)
 {
+  PRInt64 currentTime = aCurrentTimeInUsec / PR_USEC_PER_SEC;
+
   // if the new cookie is httponly, make sure we're not coming from script
   if (!aFromHttp && aCookie->IsHttpOnly()) {
     COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader, "cookie is httponly; coming from script");
     return;
   }
 
   // start a transaction on the storage db, to optimize deletions/insertions.
   // transaction will automically commit on completion. if we already have a
   // transaction (e.g. from SetCookie*()), this will have no effect. 
   mozStorageTransaction transaction(mDBState->dbConn, PR_TRUE);
 
   nsListIter matchIter;
   PRBool foundCookie = FindCookie(aCookie->Host(), aCookie->Name(), aCookie->Path(),
-                                  matchIter, aCurrentTime);
+                                  matchIter, currentTime);
 
   nsRefPtr<nsCookie> oldCookie;
   if (foundCookie) {
     oldCookie = matchIter.current;
 
     // if the old cookie is httponly, make sure we're not coming from script
     if (!aFromHttp && oldCookie->IsHttpOnly()) {
       COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader, "previously stored cookie is httponly; coming from script");
       return;
     }
 
     RemoveCookieFromList(matchIter);
 
     // check if the cookie has expired
-    if (aCookie->Expiry() <= aCurrentTime) {
+    if (aCookie->Expiry() <= currentTime) {
       COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader, "previously stored cookie was deleted");
       NotifyChanged(oldCookie, NS_LITERAL_STRING("deleted").get());
       return;
     }
 
     // preserve creation time of cookie
     if (oldCookie)
       aCookie->SetCreationID(oldCookie->CreationID());
 
   } else {
     // check if cookie has already expired
-    if (aCookie->Expiry() <= aCurrentTime) {
+    if (aCookie->Expiry() <= currentTime) {
       COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader, "cookie has already expired");
       return;
     }
 
     // check if we have to delete an old cookie.
-    nsEnumerationData data(aCurrentTime, LL_MAXINT);
+    nsEnumerationData data(currentTime, LL_MAXINT);
     if (CountCookiesFromHostInternal(aCookie->RawHost(), data) >= mMaxCookiesPerHost) {
       // remove the oldest cookie from host
       oldCookie = data.iter.current;
+      COOKIE_LOGEVICTED(oldCookie);
       RemoveCookieFromList(data.iter);
 
-    } else if (mDBState->cookieCount >= mMaxNumberOfCookies) {
-      // try to make room, by removing expired cookies
-      RemoveExpiredCookies(aCurrentTime);
+      NotifyChanged(oldCookie, NS_LITERAL_STRING("deleted").get());
 
-      // check if we still have to get rid of something
-      if (mDBState->cookieCount >= mMaxNumberOfCookies) {
-        // find the position of the oldest cookie, and remove it
-        data.oldestTime = LL_MAXINT;
-        FindOldestCookie(data);
-        oldCookie = data.iter.current;
-        RemoveCookieFromList(data.iter);
+    } else if (mDBState->cookieCount >= ADD_TEN_PERCENT(mMaxNumberOfCookies)) {
+      PRInt64 maxAge = aCurrentTimeInUsec - mDBState->cookieOldestTime;
+      PRInt64 purgeAge = ADD_TEN_PERCENT(mCookiePurgeAge);
+      if (maxAge >= purgeAge) {
+        // we're over both size and age limits by 10%; time to purge the table!
+        // do this by:
+        // 1) removing expired cookies;
+        // 2) evicting the balance of old cookies, until we reach the size limit.
+        // note that the cookieOldestTime indicator can be pessimistic - if it's
+        // older than the actual oldest cookie, we'll just purge more eagerly.
+        PurgeCookies(aCurrentTimeInUsec);
       }
     }
-
-    // if we deleted an old cookie, notify consumers
-    if (oldCookie) {
-      COOKIE_LOGEVICTED(oldCookie);
-      NotifyChanged(oldCookie, NS_LITERAL_STRING("deleted").get());
-    }
   }
 
   // add the cookie to head of list
   AddCookieToList(aCookie);
   NotifyChanged(aCookie, foundCookie ? NS_LITERAL_STRING("changed").get()
                                      : NS_LITERAL_STRING("added").get());
 
   COOKIE_LOGSUCCESS(SET_COOKIE, aHostURI, aCookieHeader, aCookie, foundCookie != nsnull);
@@ -2119,45 +2138,169 @@ nsCookieService::GetExpiry(nsCookieAttri
 
 void
 nsCookieService::RemoveAllFromMemory()
 {
   // clearing the hashtable will call each nsCookieEntry's dtor,
   // which releases all their respective children.
   mDBState->hostTable.Clear();
   mDBState->cookieCount = 0;
+  mDBState->cookieOldestTime = LL_MAXINT;
 }
 
+// stores temporary data for enumerating over the hash entries,
+// since enumeration is done using callback functions
+struct nsPurgeData
+{
+  nsPurgeData(PRInt64 aCurrentTime,
+              PRInt64 aPurgeTime,
+              nsTArray<nsListIter> &aPurgeList,
+              nsIMutableArray *aRemovedList)
+   : currentTime(aCurrentTime)
+   , purgeTime(aPurgeTime)
+   , oldestTime(LL_MAXINT)
+   , purgeList(aPurgeList)
+   , removedList(aRemovedList) {}
+
+  // the current time, in seconds
+  PRInt64 currentTime;
+
+  // lastAccessed time older than which cookies are eligible for purge
+  PRInt64 purgeTime;
+
+  // lastAccessed time of the oldest cookie found during purge, to update our indicator
+  PRInt64 oldestTime;
+
+  // list of cookies over the age limit, for purging
+  nsTArray<nsListIter> &purgeList;
+
+  // list of all cookies we've removed, for notification
+  nsIMutableArray *removedList;
+};
+
+// comparator class for lastaccessed times of cookies.
+class CompareCookiesByAge {
+public:
+  PRBool Equals(const nsListIter &a, const nsListIter &b) const
+  {
+    // CreationID is unique, so two id's can never be equal.
+    return PR_FALSE;
+  }
+
+  PRBool LessThan(const nsListIter &a, const nsListIter &b) const
+  {
+    // compare by LastAccessed time, and tiebreak by CreationID.
+    PRInt64 result = a.current->LastAccessed() - b.current->LastAccessed();
+    if (result != 0)
+      return result < 0;
+
+    return a.current->CreationID() < b.current->CreationID();
+  }
+};
+
 PLDHashOperator
-removeExpiredCallback(nsCookieEntry *aEntry,
-                      void          *aArg)
+purgeCookiesCallback(nsCookieEntry *aEntry,
+                     void          *aArg)
 {
-  const PRInt64 &currentTime = *static_cast<PRInt64*>(aArg);
+  nsPurgeData &data = *static_cast<nsPurgeData*>(aArg);
   for (nsListIter iter(aEntry, nsnull, aEntry->Head()); iter.current; ) {
-    if (iter.current->Expiry() <= currentTime)
+    // check if the cookie has expired
+    if (iter.current->Expiry() <= data.currentTime) {
+      nsCookie *cookie = iter.current;
+      data.removedList->AppendElement(cookie, PR_FALSE);
+      COOKIE_LOGEVICTED(cookie);
+
       // remove from list. this takes care of updating the iterator for us
       nsCookieService::gCookieService->RemoveCookieFromList(iter);
-    else
+
+    } else {
+      // check if the cookie is over the age limit
+      if (iter.current->LastAccessed() <= data.purgeTime) {
+        data.purgeList.AppendElement(iter);
+
+      } else if (iter.current->LastAccessed() < data.oldestTime) {
+        // reset our indicator
+        data.oldestTime = iter.current->LastAccessed();
+      }
+
       ++iter;
+    }
   }
   return PL_DHASH_NEXT;
 }
 
-// removes any expired cookies from memory
+// purges expired and old cookies in a batch operation.
 void
-nsCookieService::RemoveExpiredCookies(PRInt64 aCurrentTime)
+nsCookieService::PurgeCookies(PRInt64 aCurrentTimeInUsec)
 {
   NS_ASSERTION(mDBState->hostTable.Count() > 0, "table is empty");
 #ifdef PR_LOGGING
   PRUint32 initialCookieCount = mDBState->cookieCount;
-#endif
-  mDBState->hostTable.EnumerateEntries(removeExpiredCallback, &aCurrentTime);
   COOKIE_LOGSTRING(PR_LOG_DEBUG,
-    ("RemoveExpiredCookies(): %ld purged; %ld remain",
-     initialCookieCount - mDBState->cookieCount, mDBState->cookieCount));
+    ("PurgeCookies(): beginning purge with %ld cookies and %lld age",
+     mDBState->cookieCount, aCurrentTimeInUsec - mDBState->cookieOldestTime));
+#endif
+
+  nsAutoTArray<nsListIter, kMaxNumberOfCookies> purgeList;
+
+  nsCOMPtr<nsIMutableArray> removedList = do_CreateInstance(NS_ARRAY_CONTRACTID);
+  if (!removedList)
+    return;
+
+  nsPurgeData data(aCurrentTimeInUsec / PR_USEC_PER_SEC,
+    aCurrentTimeInUsec - mCookiePurgeAge, purgeList, removedList);
+  mDBState->hostTable.EnumerateEntries(purgeCookiesCallback, &data);
+
+#ifdef PR_LOGGING
+  PRUint32 postExpiryCookieCount = mDBState->cookieCount;
+#endif
+
+  // now we have a list of iterators for cookies over the age limit.
+  // sort them by age, and then we'll see how many to remove...
+  purgeList.Sort(CompareCookiesByAge());
+
+  // only remove old cookies until we reach the max cookie limit, no more.
+  PRUint32 excess = mDBState->cookieCount - mMaxNumberOfCookies;
+  if (purgeList.Length() > excess) {
+    // we're not purging everything in the list, so update our indicator
+    data.oldestTime = purgeList[excess].current->LastAccessed();
+
+    purgeList.SetLength(excess);
+  }
+
+  // traverse the list and remove cookies. the iterators we've stored
+  // in the list aren't stable under list mutation, so we need to do a
+  // fresh linked list traversal from the hash entryclass for each cookie.
+  for (PRUint32 i = 0; i < purgeList.Length(); ++i) {
+    nsListIter iter(purgeList[i].entry, nsnull, purgeList[i].entry->Head());
+    for (; iter.current; ++iter) {
+      if (iter.current == purgeList[i].current) {
+        // remove from list. this takes care of updating the iterator for us
+        nsCookie *cookie = iter.current;
+        removedList->AppendElement(cookie, PR_FALSE);
+        COOKIE_LOGEVICTED(cookie);
+
+        RemoveCookieFromList(iter);
+        break;
+      }
+    }
+  }
+
+  // take all the cookies in the removed list, and notify about them in one batch
+  NotifyChanged(removedList, NS_LITERAL_STRING("batch-deleted").get());
+
+  // reset the oldest time indicator
+  mDBState->cookieOldestTime = data.oldestTime;
+
+  COOKIE_LOGSTRING(PR_LOG_DEBUG,
+    ("PurgeCookies(): %ld expired; %ld purged; %ld remain; %lld oldest age",
+     initialCookieCount - postExpiryCookieCount,
+     mDBState->cookieCount - postExpiryCookieCount,
+     mDBState->cookieCount,
+     aCurrentTimeInUsec - mDBState->cookieOldestTime));
 }
 
 // find whether a given cookie has been previously set. this is provided by the
 // nsICookieManager2 interface.
 NS_IMETHODIMP
 nsCookieService::CookieExists(nsICookie2 *aCookie,
                               PRBool     *aFoundCookie)
 {
@@ -2374,16 +2517,20 @@ nsCookieService::AddCookieToList(nsCooki
   }
 
   NS_ADDREF(aCookie);
 
   aCookie->Next() = entry->Head();
   entry->Head() = aCookie;
   ++mDBState->cookieCount;
 
+  // keep track of the oldest cookie, for when it comes time to purge
+  if (aCookie->LastAccessed() < mDBState->cookieOldestTime)
+    mDBState->cookieOldestTime = aCookie->LastAccessed();
+
   // if it's a non-session cookie and hasn't just been read from the db, write it out.
   if (aWriteToDB && !aCookie->IsSession() && mDBState->dbConn) {
     // use our cached sqlite "insert" statement
     mozStorageStatementScoper scoper(mDBState->stmtInsert);
 
     nsresult rv = bindCookieParameters(mDBState->stmtInsert, aCookie);
     if (NS_SUCCEEDED(rv)) {
       PRBool hasResult;
@@ -2421,29 +2568,8 @@ nsCookieService::UpdateCookieInList(nsCo
 
     if (NS_FAILED(rv)) {
       NS_WARNING("db update failed!");
       COOKIE_LOGSTRING(PR_LOG_WARNING, ("UpdateCookieInList(): updating db gave error %x", rv));
     }
   }
 }
 
-static PLDHashOperator
-findOldestCallback(nsCookieEntry *aEntry,
-                   void          *aArg)
-{
-  nsEnumerationData *data = static_cast<nsEnumerationData*>(aArg);
-  for (nsListIter iter(aEntry, nsnull, aEntry->Head()); iter.current; ++iter) {
-    // check if we've found the oldest cookie so far
-    if (data->oldestTime > iter.current->LastAccessed()) {
-      data->oldestTime = iter.current->LastAccessed();
-      data->iter = iter;
-    }
-  }
-  return PL_DHASH_NEXT;
-}
-
-void
-nsCookieService::FindOldestCookie(nsEnumerationData &aData)
-{
-  NS_ASSERTION(mDBState->hostTable.Count() > 0, "table is empty");
-  mDBState->hostTable.EnumerateEntries(findOldestCallback, &aData);
-}
--- a/netwerk/cookie/src/nsCookieService.h
+++ b/netwerk/cookie/src/nsCookieService.h
@@ -139,20 +139,21 @@ class nsCookieEntry : public PLDHashEntr
   private:
     nsCookie *mHead;
 };
 
 // encapsulates in-memory and on-disk DB states, so we can
 // conveniently switch state when entering or exiting private browsing.
 struct DBState
 {
-  DBState() : cookieCount(0) { }
+  DBState() : cookieCount(0), cookieOldestTime(LL_MAXINT) { }
 
   nsTHashtable<nsCookieEntry>     hostTable;
   PRUint32                        cookieCount;
+  PRInt64                         cookieOldestTime;
   nsCOMPtr<mozIStorageConnection> dbConn;
   nsCOMPtr<mozIStorageStatement>  stmtInsert;
   nsCOMPtr<mozIStorageStatement>  stmtDelete;
   nsCOMPtr<mozIStorageStatement>  stmtUpdate;
 };
 
 /******************************************************************************
  * nsCookieService:
@@ -182,34 +183,33 @@ class nsCookieService : public nsICookie
     nsresult                      InitDB();
     nsresult                      TryInitDB(PRBool aDeleteExistingDB);
     nsresult                      CreateTable();
     void                          CloseDB();
     nsresult                      Read();
     void                          GetCookieInternal(nsIURI *aHostURI, nsIChannel *aChannel, PRBool aHttpBound, char **aCookie);
     nsresult                      SetCookieStringInternal(nsIURI *aHostURI, nsIPrompt *aPrompt, const char *aCookieHeader, const char *aServerTime, nsIChannel *aChannel, PRBool aFromHttp);
     PRBool                        SetCookieInternal(nsIURI *aHostURI, nsIChannel *aChannel, nsDependentCString &aCookieHeader, PRInt64 aServerTime, PRBool aFromHttp);
-    void                          AddInternal(nsCookie *aCookie, PRInt64 aCurrentTime, nsIURI *aHostURI, const char *aCookieHeader, PRBool aFromHttp);
+    void                          AddInternal(nsCookie *aCookie, PRInt64 aCurrentTimeInUsec, nsIURI *aHostURI, const char *aCookieHeader, PRBool aFromHttp);
     void                          RemoveCookieFromList(nsListIter &aIter);
     PRBool                        AddCookieToList(nsCookie *aCookie, PRBool aWriteToDB = PR_TRUE);
     void                          UpdateCookieInList(nsCookie *aCookie, PRInt64 aLastAccessed);
     static PRBool                 GetTokenValue(nsASingleFragmentCString::const_char_iterator &aIter, nsASingleFragmentCString::const_char_iterator &aEndIter, nsDependentCSubstring &aTokenString, nsDependentCSubstring &aTokenValue, PRBool &aEqualsFound);
     static PRBool                 ParseAttributes(nsDependentCString &aCookieHeader, nsCookieAttributes &aCookie);
     PRBool                        IsForeign(nsIURI *aHostURI, nsIURI *aFirstURI);
     PRUint32                      CheckPrefs(nsIURI *aHostURI, nsIChannel *aChannel, const char *aCookieHeader);
     PRBool                        CheckDomain(nsCookieAttributes &aCookie, nsIURI *aHostURI);
     static PRBool                 CheckPath(nsCookieAttributes &aCookie, nsIURI *aHostURI);
     static PRBool                 GetExpiry(nsCookieAttributes &aCookie, PRInt64 aServerTime, PRInt64 aCurrentTime);
     void                          RemoveAllFromMemory();
-    void                          RemoveExpiredCookies(PRInt64 aCurrentTime);
+    void                          PurgeCookies(PRInt64 aCurrentTimeInUsec);
     PRBool                        FindCookie(const nsAFlatCString &aHost, const nsAFlatCString &aName, const nsAFlatCString &aPath, nsListIter &aIter, PRInt64 aCurrentTime);
-    void                          FindOldestCookie(nsEnumerationData &aData);
     PRUint32                      CountCookiesFromHostInternal(const nsACString &aHost, nsEnumerationData &aData);
     void                          NotifyRejected(nsIURI *aHostURI);
-    void                          NotifyChanged(nsICookie2 *aCookie, const PRUnichar *aData);
+    void                          NotifyChanged(nsISupports *aSubject, const PRUnichar *aData);
 
   protected:
     // cached members.
     nsCOMPtr<nsIObserverService>     mObserverService;
     nsCOMPtr<nsICookiePermission>    mPermissionService;
     nsCOMPtr<nsIEffectiveTLDService> mTLDService;
 
     // we have two separate DB states: one for normal browsing and one for
@@ -220,18 +220,19 @@ class nsCookieService : public nsICookie
     DBState                      *mDBState;
     DBState                       mDefaultDBState;
     DBState                       mPrivateDBState;
 
     // cached prefs
     PRUint8                       mCookiesPermissions;   // BEHAVIOR_{ACCEPT, REJECTFOREIGN, REJECT}
     PRUint16                      mMaxNumberOfCookies;
     PRUint16                      mMaxCookiesPerHost;
+    PRInt64                       mCookiePurgeAge;
 
     // private static member, used to cache a ptr to nsCookieService,
     // so we can make nsCookieService a singleton xpcom object.
     static nsCookieService        *gCookieService;
 
     // this callback needs access to member functions
-    friend PLDHashOperator removeExpiredCallback(nsCookieEntry *aEntry, void *aArg);
+    friend PLDHashOperator purgeCookiesCallback(nsCookieEntry *aEntry, void *aArg);
 };
 
 #endif // nsCookieService_h__
--- a/netwerk/test/TestCookie.cpp
+++ b/netwerk/test/TestCookie.cpp
@@ -754,51 +754,17 @@ main(PRInt32 argc, char *argv[])
           expected += name;
           if (i < 59)
             expected += NS_LITERAL_CSTRING("; ");
         }
       }
       GetACookie(cookieService, "http://creation.ordering.tests/", nsnull, getter_Copies(cookie));
       rv[0] = CheckResult(cookie.get(), MUST_EQUAL, expected.get());
 
-      // test that cookies are evicted by order of lastAccessed time, if the limit on total cookies
-      // (3000) is reached
-      nsCAutoString host;
-      for (PRInt32 i = 0; i < 3010; ++i) {
-        host = NS_LITERAL_CSTRING("http://eviction.");
-        host.AppendInt(i);
-        host += NS_LITERAL_CSTRING(".tests/");
-        SetACookie(cookieService, host.get(), nsnull, "test=eviction", nsnull);
-
-        if (i == 9) {
-          // sleep a couple of seconds, to make sure the first 10 cookies are older than
-          // subsequent ones (timer resolution varies on different platforms).
-          PR_Sleep(2 * PR_TicksPerSecond());
-        }
-      }
-      rv[1] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator)));
-      i = 0;
-      rv[2] = PR_FALSE; // init to failure in case we break from the while loop
-      while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) {
-        nsCOMPtr<nsISupports> cookie;
-        if (NS_FAILED(enumerator->GetNext(getter_AddRefs(cookie)))) break;
-        ++i;
-        
-        // keep tabs on the third cookie, so we can check it later
-        nsCOMPtr<nsICookie2> cookie2(do_QueryInterface(cookie));
-        if (!cookie2) break;
-        nsCAutoString domain;
-        cookie2->GetRawHost(domain);
-        PRInt32 hostNumber;
-        PRInt32 numInts = PR_sscanf(domain.get(), "eviction.%ld.tests", &hostNumber);
-        if (numInts != 1 || hostNumber < 10) break;
-      }
-      rv[2] = i == 3000;
-
-      allTestsPassed = PrintResult(rv, 3) && allTestsPassed;
+      allTestsPassed = PrintResult(rv, 1) && allTestsPassed;
 
 
       // XXX the following are placeholders: add these tests please!
       // *** "noncompliant cookie" tests
       // *** IP address tests
       // *** speed tests
 
 
--- a/netwerk/test/httpserver/httpd.js
+++ b/netwerk/test/httpserver/httpd.js
@@ -108,17 +108,16 @@ const HTTP_407 = new HttpError(407, "Pro
 const HTTP_408 = new HttpError(408, "Request Timeout");
 const HTTP_409 = new HttpError(409, "Conflict");
 const HTTP_410 = new HttpError(410, "Gone");
 const HTTP_411 = new HttpError(411, "Length Required");
 const HTTP_412 = new HttpError(412, "Precondition Failed");
 const HTTP_413 = new HttpError(413, "Request Entity Too Large");
 const HTTP_414 = new HttpError(414, "Request-URI Too Long");
 const HTTP_415 = new HttpError(415, "Unsupported Media Type");
-const HTTP_416 = new HttpError(416, "Requested Range Not Satisfiable");
 const HTTP_417 = new HttpError(417, "Expectation Failed");
 
 const HTTP_500 = new HttpError(500, "Internal Server Error");
 const HTTP_501 = new HttpError(501, "Not Implemented");
 const HTTP_502 = new HttpError(502, "Bad Gateway");
 const HTTP_503 = new HttpError(503, "Service Unavailable");
 const HTTP_504 = new HttpError(504, "Gateway Timeout");
 const HTTP_505 = new HttpError(505, "HTTP Version Not Supported");
@@ -2222,16 +2221,18 @@ ServerHandler.prototype =
       {
         if (!(e instanceof HttpError))
           throw e;
 
         errorCode = e.code;
         dumpn("*** errorCode == " + errorCode);
 
         response = new Response(connection);
+        if (e.customErrorHandling)
+          e.customErrorHandling(response);
         this._handleError(errorCode, request, response);
         return;
       }
       catch (e2)
       {
         dumpn("*** error handling " + errorCode + " error: " +
               "e2 == " + e2 + ", shutting down server");
 
@@ -2441,18 +2442,24 @@ ServerHandler.prototype =
         start = Math.max(0, file.fileSize - end);
         end   = file.fileSize - 1;
       }
 
       // start and end are inclusive
       if (end === undefined || end >= file.fileSize)
         end = file.fileSize - 1;
 
-      if (start !== undefined && start >= file.fileSize)
+      if (start !== undefined && start >= file.fileSize) {
+        var HTTP_416 = new HttpError(416, "Requested Range Not Satisfiable");
+        HTTP_416.customErrorHandling = function(errorResponse)
+        {
+          maybeAddHeaders(file, metadata, errorResponse);
+        };
         throw HTTP_416;
+      }
 
       if (end < start)
       {
         response.setStatusLine(metadata.httpVersion, 200, "OK");
         start = 0;
         end = file.fileSize - 1;
       }
       else
new file mode 100644
--- /dev/null
+++ b/netwerk/test/httpserver/test/data/ranges/headers.txt
@@ -0,0 +1,1 @@
+Hello Kitty
new file mode 100644
--- /dev/null
+++ b/netwerk/test/httpserver/test/data/ranges/headers.txt^headers^
@@ -0,0 +1,1 @@
+X-SJS-Header: customized
--- a/netwerk/test/httpserver/test/test_byte_range.js
+++ b/netwerk/test/httpserver/test/test_byte_range.js
@@ -60,16 +60,18 @@ var tests =
    new Test(PREFIX + "/range.txt",
             init_byterange9, start_byterange9, stop_byterange9),
    new Test(PREFIX + "/range.txt",
             init_byterange10, start_byterange10),
    new Test(PREFIX + "/range.txt",
             init_byterange11, start_byterange11, stop_byterange11),
    new Test(PREFIX + "/empty.txt",
             null, start_byterange12, stop_byterange12),
+   new Test(PREFIX + "/headers.txt",
+            init_byterange13, start_byterange13, null),
    new Test(PREFIX + "/range.txt",
             null, start_normal, stop_normal)
    ];
 
 function run_test()
 {
   var srv = createServer();
   var dir = do_get_file("data/ranges/");
@@ -284,8 +286,19 @@ function start_byterange12(ch, cx)
   do_check_eq(ch.responseStatus, 200);
   do_check_eq(ch.getResponseHeader("Content-Length"), "0");
 }
 
 function stop_byterange12(ch, cx, status, data)
 {
   do_check_eq(data.length, 0);
 }
+
+function init_byterange13(ch)
+{
+  ch.setRequestHeader("Range", "bytes=9999999-", false);
+}
+
+function start_byterange13(ch, cx)
+{
+  do_check_eq(ch.responseStatus, 416);
+  do_check_eq(ch.getResponseHeader("X-SJS-Header"), "customized");
+}
--- a/netwerk/test/unit/test_NetUtil.js
+++ b/netwerk/test/unit/test_NetUtil.js
@@ -158,25 +158,45 @@ function test_newURI_no_spec_throws()
 
   run_next_test();
 }
 
 function test_newURI()
 {
   let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
 
-  // Check that we get the same URI back from the IO service and the utility method.
+  // Check that we get the same URI back from the IO service and the utility
+  // method.
   const TEST_URI = "http://mozilla.org";
   let iosURI = ios.newURI(TEST_URI, null, null);
   let NetUtilURI = NetUtil.newURI(TEST_URI);
   do_check_true(iosURI.equals(NetUtilURI));
 
   run_next_test();
 }
 
+function test_newURI_takes_nsIFile()
+{
+  let ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
+
+  // Create a test file that we can pass into NetUtil.newURI
+  let file = Cc["@mozilla.org/file/directory_service;1"].
+             getService(Ci.nsIProperties).
+             get("TmpD", Ci.nsIFile);
+  file.append("NetUtil-test-file.tmp");
+
+  // Check that we get the same URI back from the IO service and the utility
+  // method.
+  let iosURI = ios.newFileURI(file);
+  let NetUtilURI = NetUtil.newURI(file);
+  do_check_true(iosURI.equals(NetUtilURI));
+
+  run_next_test();
+}
+
 function test_ioService()
 {
   do_check_true(NetUtil.ioService instanceof Ci.nsIIOService);
   run_next_test();
 }
 
 function test_asyncFetch_no_channel()
 {
@@ -199,17 +219,17 @@ function test_asyncFetch_no_callback()
   }
   catch (e) {
     do_check_eq(e.result, Cr.NS_ERROR_INVALID_ARG);
   }
 
   run_next_test();
 }
 
-function test_asyncFetch()
+function test_asyncFetch_with_nsIChannel()
 {
   const TEST_DATA = "this is a test string";
 
   // Start the http server, and register our handler.
   let server = new nsHttpServer();
   server.registerPathHandler("/test", function(aRequest, aResponse) {
     aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
     aResponse.setHeader("Content-Type", "text/plain", false);
@@ -233,16 +253,120 @@ function test_asyncFetch()
     is.init(aInputStream);
     let result = is.read(TEST_DATA.length);
     do_check_eq(TEST_DATA, result);
 
     server.stop(run_next_test);
   });
 }
 
+function test_asyncFetch_with_nsIURI()
+{
+  const TEST_DATA = "this is a test string";
+
+  // Start the http server, and register our handler.
+  let server = new nsHttpServer();
+  server.registerPathHandler("/test", function(aRequest, aResponse) {
+    aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
+    aResponse.setHeader("Content-Type", "text/plain", false);
+    aResponse.write(TEST_DATA);
+  });
+  server.start(4444);
+
+  // Create our URI.
+  let uri = NetUtil.newURI("http://localhost:4444/test");
+
+  // Open our URI asynchronously.
+  NetUtil.asyncFetch(uri, function(aInputStream, aResult) {
+    // Check that we had success.
+    do_check_true(Components.isSuccessCode(aResult));
+
+    // Check that we got the right data.
+    do_check_eq(aInputStream.available(), TEST_DATA.length);
+    let is = Cc["@mozilla.org/scriptableinputstream;1"].
+             createInstance(Ci.nsIScriptableInputStream);
+    is.init(aInputStream);
+    let result = is.read(TEST_DATA.length);
+    do_check_eq(TEST_DATA, result);
+
+    server.stop(run_next_test);
+  });
+}
+
+function test_asyncFetch_with_string()
+{
+  const TEST_DATA = "this is a test string";
+
+  // Start the http server, and register our handler.
+  let server = new nsHttpServer();
+  server.registerPathHandler("/test", function(aRequest, aResponse) {
+    aResponse.setStatusLine(aRequest.httpVersion, 200, "OK");
+    aResponse.setHeader("Content-Type", "text/plain", false);
+    aResponse.write(TEST_DATA);
+  });
+  server.start(4444);
+