Merge last PGO-green changeset of mozilla-inbound to mozilla-central
authorEd Morley <emorley@mozilla.com>
Fri, 29 Jun 2012 08:41:44 +0100
changeset 97913 4a8e0d5fc954ac726af18044ae7e2b1d8a260782
parent 97857 081d8578beb131516f2d58290eb563bb96d46b72 (current diff)
parent 97912 0b5f8c30088c8279a7b49419c7bb31ee84a2c266 (diff)
child 97914 ff38bb1bce5add6c28f079f67353c432efac4f33
child 97936 8a2458ffa51dd08d8ee7d9885aaf0a6bd0b5a312
push id23007
push useremorley@mozilla.com
push dateFri, 29 Jun 2012 07:42:23 +0000
treeherdermozilla-central@4a8e0d5fc954 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone16.0a1
first release with
nightly linux32
4a8e0d5fc954 / 16.0a1 / 20120629030530 / files
nightly linux64
4a8e0d5fc954 / 16.0a1 / 20120629030530 / files
nightly mac
4a8e0d5fc954 / 16.0a1 / 20120629030530 / files
nightly win32
4a8e0d5fc954 / 16.0a1 / 20120629030530 / files
nightly win64
4a8e0d5fc954 / 16.0a1 / 20120629030530 / files
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
releases
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge last PGO-green changeset of mozilla-inbound to mozilla-central
modules/libpref/src/init/all.js
netwerk/protocol/websocket/WebSocketChannel.cpp
netwerk/protocol/websocket/WebSocketChannel.h
--- a/browser/base/content/openLocation.js
+++ b/browser/base/content/openLocation.js
@@ -2,24 +2,26 @@
 #
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 var browser;
 var dialog = {};
 var pref = null;
+let openLocationModule = {};
 try {
   pref = Components.classes["@mozilla.org/preferences-service;1"]
                    .getService(Components.interfaces.nsIPrefBranch);
 } catch (ex) {
   // not critical, remain silent
 }
 
-Components.utils.import("resource:///modules/openLocationLastURL.jsm");
+Components.utils.import("resource:///modules/openLocationLastURL.jsm", openLocationModule);
+let gOpenLocationLastURL = new openLocationModule.OpenLocationLastURL(window.opener);
 
 function onLoad()
 {
   dialog.input         = document.getElementById("dialog.input");
   dialog.open          = document.documentElement.getButton("accept");
   dialog.openWhereList = document.getElementById("openWhereList");
   dialog.openTopWindow = document.getElementById("currentWindow");
   dialog.bundle        = document.getElementById("openLocationBundle");
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -471,20 +471,23 @@ BrowserGlue.prototype = {
     //
     // aQuitType == "lastwindow" is overloaded. "lastwindow" is used to indicate
     // "the last window is closing but we're not quitting (a non-browser window is open)"
     // and also "we're quitting by closing the last window".
 
     var windowcount = 0;
     var pagecount = 0;
     var browserEnum = Services.wm.getEnumerator("navigator:browser");
+    let allWindowsPrivate = true;
     while (browserEnum.hasMoreElements()) {
       windowcount++;
 
       var browser = browserEnum.getNext();
+      if (("gPrivateBrowsingUI" in browser) && !browser.gPrivateBrowsingUI.privateWindow)
+        allWindowsPrivate = false;
       var tabbrowser = browser.document.getElementById("content");
       if (tabbrowser)
         pagecount += tabbrowser.browsers.length - tabbrowser._numPinnedTabs;
     }
 
     this._saveSession = false;
     if (pagecount < 2)
       return;
@@ -518,20 +521,18 @@ BrowserGlue.prototype = {
       // we should show the window closing warning instead. warnAboutClosing
       // tabs checks browser.tabs.warnOnClose and returns if it's ok to close
       // the window. It doesn't actually close the window.
       mostRecentBrowserWindow = Services.wm.getMostRecentWindow("navigator:browser");
       aCancelQuit.data = !mostRecentBrowserWindow.gBrowser.warnAboutClosingTabs(true);
       return;
     }
 
-    var inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
-                            getService(Ci.nsIPrivateBrowsingService).
-                            privateBrowsingEnabled;
-    if (inPrivateBrowsing)
+    // Never show a prompt inside private browsing mode
+    if (allWindowsPrivate)
       return;
 
     if (!showPrompt)
       return;
 
     var quitBundle = Services.strings.createBundle("chrome://browser/locale/quitDialog.properties");
     var brandBundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
 
@@ -1568,31 +1569,29 @@ ContentPermissionPrompt.prototype = {
       accessKey: browserBundle.GetStringFromName("geolocation.shareLocation.accesskey"),
       callback: function(notification) {
         request.allow();
       },
     };
 
     var message;
     var secondaryActions = [];
+    var requestingWindow = request.window.top;
+    var chromeWin = getChromeWindow(requestingWindow).wrappedJSObject;
 
     // Different message/options if it is a local file
     if (requestingURI.schemeIs("file")) {
       message = browserBundle.formatStringFromName("geolocation.shareWithFile",
                                                    [requestingURI.path], 1);
     } else {
       message = browserBundle.formatStringFromName("geolocation.shareWithSite",
                                                    [requestingURI.host], 1);
 
       // Don't offer to "always/never share" in PB mode
-      var inPrivateBrowsing = Cc["@mozilla.org/privatebrowsing;1"].
-                              getService(Ci.nsIPrivateBrowsingService).
-                              privateBrowsingEnabled;
-
-      if (!inPrivateBrowsing) {
+      if (("gPrivateBrowsingUI" in chromeWin) && !chromeWin.gPrivateBrowsingUI.privateWindow) {
         secondaryActions.push({
           label: browserBundle.GetStringFromName("geolocation.alwaysShareLocation"),
           accessKey: browserBundle.GetStringFromName("geolocation.alwaysShareLocation.accesskey"),
           callback: function () {
             Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.ALLOW_ACTION);
             request.allow();
           }
         });
@@ -1602,18 +1601,16 @@ ContentPermissionPrompt.prototype = {
           callback: function () {
             Services.perms.add(requestingURI, "geo", Ci.nsIPermissionManager.DENY_ACTION);
             request.cancel();
           }
         });
       }
     }
 
-    var requestingWindow = request.window.top;
-    var chromeWin = getChromeWindow(requestingWindow).wrappedJSObject;
     var browser = chromeWin.gBrowser.getBrowserForDocument(requestingWindow.document);
 
     chromeWin.PopupNotifications.show(browser, "geolocation", message, "geo-notification-icon",
                                       mainAction, secondaryActions);
   }
 };
 
 var components = [BrowserGlue, ContentPermissionPrompt];
--- a/browser/components/places/content/sidebarUtils.js
+++ b/browser/components/places/content/sidebarUtils.js
@@ -61,21 +61,21 @@ var SidebarUtils = {
       // selection as an indication of which link to load.
       tbo.view.selection.select(row.value);
       PlacesUIUtils.openNodeWithEvent(aTree.selectedNode, aEvent, aTree);
     }
   },
 
   handleTreeKeyPress: function SU_handleTreeKeyPress(aEvent) {
     // XXX Bug 627901: Post Fx4, this method should take a tree parameter.
-    let node = aEvent.target.selectedNode;
+    let tree = aEvent.target;
+    let node = tree.selectedNode;
     if (node) {
-      let view = PlacesUIUtils.getViewForNode(node);
       if (aEvent.keyCode == KeyEvent.DOM_VK_RETURN)
-        PlacesUIUtils.openNodeWithEvent(node, aEvent, view);
+        PlacesUIUtils.openNodeWithEvent(node, aEvent, tree);
     }
   },
 
   /**
    * The following function displays the URL of a node that is being
    * hovered over.
    */
   handleTreeMouseMove: function SU_handleTreeMouseMove(aEvent) {
--- a/browser/components/places/content/treeView.js
+++ b/browser/components/places/content/treeView.js
@@ -1,12 +1,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
+Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
+
+const PTV_interfaces = [Ci.nsITreeView,
+                        Ci.nsINavHistoryResultObserver,
+                        Ci.nsINavHistoryResultTreeViewer,
+                        Ci.nsISupportsWeakReference];
+
 function PlacesTreeView(aFlatList, aOnOpenFlatContainer, aController) {
   this._tree = null;
   this._result = null;
   this._selection = null;
   this._rootNode = null;
   this._rows = [];
   this._flatList = aFlatList;
   this._openContainerCallback = aOnOpenFlatContainer;
@@ -34,25 +41,27 @@ PlacesTreeView.prototype = {
   get _dateService() {
     if (!this.__dateService) {
       this.__dateService = Cc["@mozilla.org/intl/scriptabledateformat;1"].
                            getService(Ci.nsIScriptableDateFormat);
     }
     return this.__dateService;
   },
 
-  QueryInterface: function PTV_QueryInterface(aIID) {
-    if (aIID.equals(Ci.nsITreeView) ||
-        aIID.equals(Ci.nsINavHistoryResultObserver) ||
-        aIID.equals(Ci.nsINavHistoryResultTreeViewer) ||
-        aIID.equals(Ci.nsISupportsWeakReference) ||
-        aIID.equals(Ci.nsISupports))
-      return this;
-    throw Cr.NS_ERROR_NO_INTERFACE;
-  },
+  QueryInterface: XPCOMUtils.generateQI(PTV_interfaces),
+
+  // Bug 761494:
+  // ----------
+  // Some addons use methods from nsINavHistoryResultObserver and
+  // nsINavHistoryResultTreeViewer, without QIing to these intefaces first.
+  // That's not a problem when the view is retrieved through the
+  // <tree>.view getter (which returns the wrappedJSObject of this object),
+  // it raises an issue when the view retrieved through the treeBoxObject.view
+  // getter.  Thus, to avoid breaking addons, the interfaces are prefetched.
+  classInfo: XPCOMUtils.generateCI({ interfaces: PTV_interfaces }),
 
   /**
    * This is called once both the result and the tree are set.
    */
   _finishInit: function PTV__finishInit() {
     let selection = this.selection;
     if (selection)
       selection.selectEventsSuppressed = true;
--- a/browser/components/privatebrowsing/test/unit/test_openLocationLastURL.js
+++ b/browser/components/privatebrowsing/test/unit/test_openLocationLastURL.js
@@ -1,69 +1,78 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 // Test the correct behavior of the openLocationLastURL.jsm JS module.
 
 function run_test_on_service()
 {
-  Cu.import("resource:///modules/openLocationLastURL.jsm");
-
+  let openLocationModule = {};
+  // This variable fakes the window required for getting the PB flag
+  let window = { gPrivateBrowsingUI: { privateWindow: false } };
+  Cu.import("resource:///modules/openLocationLastURL.jsm", openLocationModule);
+  let gOpenLocationLastURL = new openLocationModule.OpenLocationLastURL(window);
+  
   function clearHistory() {
     // simulate clearing the private data
     Cc["@mozilla.org/observer-service;1"].
     getService(Ci.nsIObserverService).
     notifyObservers(null, "browser:purge-session-history", "");
   }
-
+  
   let pb = Cc[PRIVATEBROWSING_CONTRACT_ID].
            getService(Ci.nsIPrivateBrowsingService);
   let pref = Cc["@mozilla.org/preferences-service;1"].
              getService(Ci.nsIPrefBranch);
   gOpenLocationLastURL.reset();
 
   do_check_eq(typeof gOpenLocationLastURL, "object");
   do_check_eq(gOpenLocationLastURL.value, "");
 
+  function switchPrivateBrowsing(flag) {
+    pb.privateBrowsingEnabled = flag;
+    window.gPrivateBrowsingUI.privateWindow = flag;
+  }
+
   const url1 = "mozilla.org";
   const url2 = "mozilla.com";
 
   gOpenLocationLastURL.value = url1;
   do_check_eq(gOpenLocationLastURL.value, url1);
 
   gOpenLocationLastURL.value = "";
   do_check_eq(gOpenLocationLastURL.value, "");
 
   gOpenLocationLastURL.value = url2;
   do_check_eq(gOpenLocationLastURL.value, url2);
 
   clearHistory();
   do_check_eq(gOpenLocationLastURL.value, "");
   gOpenLocationLastURL.value = url2;
 
-  pb.privateBrowsingEnabled = true;
+  switchPrivateBrowsing(true);
   do_check_eq(gOpenLocationLastURL.value, "");
-
-  pb.privateBrowsingEnabled = false;
+  
+  switchPrivateBrowsing(false);
   do_check_eq(gOpenLocationLastURL.value, url2);
-  pb.privateBrowsingEnabled = true;
+  switchPrivateBrowsing(true);
 
   gOpenLocationLastURL.value = url1;
   do_check_eq(gOpenLocationLastURL.value, url1);
 
-  pb.privateBrowsingEnabled = false;
+  switchPrivateBrowsing(false);
   do_check_eq(gOpenLocationLastURL.value, url2);
 
-  pb.privateBrowsingEnabled = true;
+  switchPrivateBrowsing(true);
   gOpenLocationLastURL.value = url1;
   do_check_neq(gOpenLocationLastURL.value, "");
   clearHistory();
   do_check_eq(gOpenLocationLastURL.value, "");
 
-  pb.privateBrowsingEnabled = false;
+  switchPrivateBrowsing(false);
   do_check_eq(gOpenLocationLastURL.value, "");
 }
 
 // Support running tests on both the service itself and its wrapper
 function run_test() {
   run_test_on_all_services();
 }
--- a/browser/modules/openLocationLastURL.jsm
+++ b/browser/modules/openLocationLastURL.jsm
@@ -1,65 +1,78 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 const LAST_URL_PREF = "general.open_location.last_url";
 const nsISupportsString = Components.interfaces.nsISupportsString;
-
-var EXPORTED_SYMBOLS = [ "gOpenLocationLastURL" ];
+const Ci = Components.interfaces;
 
-let pbSvc = Components.classes["@mozilla.org/privatebrowsing;1"]
-                      .getService(Components.interfaces.nsIPrivateBrowsingService);
+var EXPORTED_SYMBOLS = [ "OpenLocationLastURL" ];
+
 let prefSvc = Components.classes["@mozilla.org/preferences-service;1"]
                         .getService(Components.interfaces.nsIPrefBranch);
+let gOpenLocationLastURLData = "";
 
 let observer = {
   QueryInterface: function (aIID) {
     if (aIID.equals(Components.interfaces.nsIObserver) ||
         aIID.equals(Components.interfaces.nsISupports) ||
         aIID.equals(Components.interfaces.nsISupportsWeakReference))
       return this;
     throw Components.results.NS_NOINTERFACE;
   },
   observe: function (aSubject, aTopic, aData) {
     switch (aTopic) {
-      case "private-browsing":
+      case "last-pb-context-exited":
         gOpenLocationLastURLData = "";
         break;
       case "browser:purge-session-history":
-        gOpenLocationLastURL.reset();
+        prefSvc.clearUserPref(LAST_URL_PREF);
+        gOpenLocationLastURLData = "";
         break;
     }
   }
 };
 
 let os = Components.classes["@mozilla.org/observer-service;1"]
                    .getService(Components.interfaces.nsIObserverService);
-os.addObserver(observer, "private-browsing", true);
+os.addObserver(observer, "last-pb-context-exited", true);
 os.addObserver(observer, "browser:purge-session-history", true);
 
-let gOpenLocationLastURLData = "";
-let gOpenLocationLastURL = {
+
+function OpenLocationLastURL(aWindow) {
+  this.window = aWindow;
+}
+
+OpenLocationLastURL.prototype = {
+  isPrivate: function OpenLocationLastURL_isPrivate() {
+    // Assume not in private browsing mode, unless the browser window is
+    // in private mode.
+    if (!this.window || !("gPrivateBrowsingUI" in this.window))
+      return false;
+  
+    return this.window.gPrivateBrowsingUI.privateWindow;
+  },
   get value() {
-    if (pbSvc.privateBrowsingEnabled)
+    if (this.isPrivate())
       return gOpenLocationLastURLData;
     else {
       try {
         return prefSvc.getComplexValue(LAST_URL_PREF, nsISupportsString).data;
       }
       catch (e) {
         return "";
       }
     }
   },
   set value(val) {
     if (typeof val != "string")
       val = "";
-    if (pbSvc.privateBrowsingEnabled)
+    if (this.isPrivate())
       gOpenLocationLastURLData = val;
     else {
       let str = Components.classes["@mozilla.org/supports-string;1"]
                           .createInstance(Components.interfaces.nsISupportsString);
       str.data = val;
       prefSvc.setComplexValue(LAST_URL_PREF, nsISupportsString, str);
     }
   },
--- a/build/mobile/robocop/FennecNativeActions.java.in
+++ b/build/mobile/robocop/FennecNativeActions.java.in
@@ -31,34 +31,36 @@ import org.json.*;
 import com.jayway.android.robotium.solo.Solo;
 
 import static @ANDROID_PACKAGE_NAME@.FennecNativeDriver.LogLevel;
 
 public class FennecNativeActions implements Actions {
     private Solo mSolo;
     private Instrumentation mInstr;
     private Activity mGeckoApp;
+    private Assert mAsserter;
 
     // Objects for reflexive access of fennec classes.
     private ClassLoader mClassLoader;
     private Class mGel;
     private Class mGe;
     private Class mGas;
     private Class mDrawListener;
     private Method mRegisterGEL;
     private Method mUnregisterGEL;
     private Method mSendGE;
     private Method mGetLayerClient;
     private Method mSetDrawListener;
     private static final String LOGTAG = "FennecNativeActions";
 
-    public FennecNativeActions(Activity activity, Solo robocop, Instrumentation instrumentation) {
+    public FennecNativeActions(Activity activity, Solo robocop, Instrumentation instrumentation, Assert asserter) {
         mSolo = robocop;
         mInstr = instrumentation;
         mGeckoApp = activity;
+        mAsserter = asserter;
         // Set up reflexive access of java classes and methods.
         try {
             mClassLoader = activity.getClassLoader();
             mGel = mClassLoader.loadClass("org.mozilla.gecko.GeckoEventListener");
             mGe = mClassLoader.loadClass("org.mozilla.gecko.GeckoEvent");
             mGas = mClassLoader.loadClass("org.mozilla.gecko.GeckoAppShell");
             Class [] parameters = new Class[2];
             parameters[0] = String.class;
@@ -112,30 +114,39 @@ public class FennecNativeActions impleme
             return null;
         }
     }
 
     class GeckoEventExpecter implements EventExpecter {
         private final String mGeckoEvent;
         private final Object[] mRegistrationParams;
         private boolean mEventReceived;
+        private static final int MAX_WAIT_MS = 90000;
 
         GeckoEventExpecter(String geckoEvent, Object[] registrationParams) {
             mGeckoEvent = geckoEvent;
             mRegistrationParams = registrationParams;
         }
 
         public synchronized void blockForEvent() {
+            long startTime = SystemClock.uptimeMillis();
+            long endTime = 0;
             while (! mEventReceived) {
                 try {
-                    this.wait();
+                    this.wait(MAX_WAIT_MS);
                 } catch (InterruptedException ie) {
                     FennecNativeDriver.log(LogLevel.ERROR, ie);
                     break;
                 }
+                endTime = SystemClock.uptimeMillis();
+                if (!mEventReceived && (endTime - startTime >= MAX_WAIT_MS)) {
+                    mAsserter.ok(false, "GeckoEventExpecter", 
+                        "blockForEvent timeout: "+mGeckoEvent);
+                    return;
+                }
             }
             FennecNativeDriver.log(FennecNativeDriver.LogLevel.DEBUG,
                 "unblocked on expecter for " + mGeckoEvent);
         }
 
         public synchronized boolean eventReceived() {
             return mEventReceived;
         }
@@ -217,37 +228,45 @@ public class FennecNativeActions impleme
             }
             return null;
         }
     }
 
     class PaintExpecter implements RepeatedEventExpecter {
         private Object mLayerClient;
         private boolean mPaintDone;
+        private static final int MAX_WAIT_MS = 90000;
 
         PaintExpecter() throws IllegalAccessException, InvocationTargetException {
             mLayerClient = mGetLayerClient.invoke(mGeckoApp);
             mSetDrawListener.invoke(mLayerClient, Proxy.newProxyInstance(mClassLoader, new Class[] { mDrawListener }, new DrawListenerProxy(this)));
         }
 
         void notifyOfEvent() {
             synchronized (this) {
                 mPaintDone = true;
                 this.notifyAll();
             }
         }
 
         public synchronized void blockForEvent() {
+            long startTime = SystemClock.uptimeMillis();
+            long endTime = 0;
             while (!mPaintDone) {
                 try {
-                    this.wait();
+                    this.wait(MAX_WAIT_MS);
                 } catch (InterruptedException ie) {
                     FennecNativeDriver.log(LogLevel.ERROR, ie);
                     break;
                 }
+                endTime = SystemClock.uptimeMillis();
+                if (!mPaintDone && (endTime - startTime >= MAX_WAIT_MS)) {
+                    mAsserter.ok(false, "PaintExpecter", "blockForEvent timeout");
+                    return;
+                }
             }
             try {
                 mSetDrawListener.invoke(mLayerClient, (Object)null);
             } catch (Exception e) {
                 FennecNativeDriver.log(LogLevel.ERROR, e);
             }
         }
 
@@ -255,34 +274,41 @@ public class FennecNativeActions impleme
             return mPaintDone;
         }
 
         public synchronized void blockUntilClear(long millis) {
             if (millis <= 0) {
                 throw new IllegalArgumentException("millis must be > 0");
             }
             // wait for at least one event
+            long startTime = SystemClock.uptimeMillis();
+            long endTime = 0;
             while (!mPaintDone) {
                 try {
-                    this.wait();
+                    this.wait(MAX_WAIT_MS);
                 } catch (InterruptedException ie) {
                     FennecNativeDriver.log(LogLevel.ERROR, ie);
                     break;
                 }
+                endTime = SystemClock.uptimeMillis();
+                if (!mPaintDone && (endTime - startTime >= MAX_WAIT_MS)) {
+                    mAsserter.ok(false, "PaintExpecter", "blockUtilClear timeout");
+                    return;
+                }
             }
             // now wait for a period of millis where we don't get an event
-            long startTime = SystemClock.uptimeMillis();
+            startTime = SystemClock.uptimeMillis();
             while (true) {
                 try {
                     this.wait(millis);
                 } catch (InterruptedException ie) {
                     FennecNativeDriver.log(LogLevel.ERROR, ie);
                     break;
                 }
-                long endTime = SystemClock.uptimeMillis();
+                endTime = SystemClock.uptimeMillis();
                 if (endTime - startTime >= millis) {
                     // success
                     break;
                 }
                 // we got a notify() before we could wait long enough, so we need to start over
                 startTime = endTime;
             }
             try {
--- a/caps/idl/nsIScriptSecurityManager.idl
+++ b/caps/idl/nsIScriptSecurityManager.idl
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "nsISupports.idl"
 #include "nsIPrincipal.idl"
 #include "nsIXPCSecurityManager.idl"
 interface nsIURI;
 interface nsIChannel;
 
-[scriptable, uuid(3708aa92-e2d9-4fd1-9e46-edfa3eb5ebf5)]
+[scriptable, uuid(cdb27711-492b-4973-938b-de81ac124658)]
 interface nsIScriptSecurityManager : nsIXPCSecurityManager
 {
     ///////////////// Security Checks //////////////////
     /**
      * Checks whether the running script is allowed to access aProperty.
      */
     [noscript] void checkPropertyAccess(in JSContextPtr aJSContext,
                                         in JSObjectPtr aJSObject,
@@ -255,37 +255,14 @@ interface nsIScriptSecurityManager : nsI
      * Same as getSubjectPrincipal(), only faster. cx must *never* be
      * passed null, and it must be the context on the top of the
      * context stack. Does *not* reference count the returned
      * principal.
      */
     [noscript,notxpcom] nsIPrincipal getCxSubjectPrincipal(in JSContextPtr cx);
     [noscript,notxpcom] nsIPrincipal getCxSubjectPrincipalAndFrame(in JSContextPtr cx,
                                                                    out JSStackFramePtr fp);
-
-    /**
-     * If no scripted code is running "above" (or called from) fp, then
-     * instead of looking at cx->globalObject, we will return |principal|.
-     * This function only affects |cx|. If someone pushes another context onto
-     * the context stack, then it supersedes this call.
-     * NOTE: If |fp| is non-null popContextPrincipal must be called before fp
-     * has finished executing.
-     *
-     * @param cx The context to clamp.
-     * @param fp The frame pointer to clamp at. May be 'null'.
-     * @param principal The principal to clamp to.
-     */
-    [noscript] void pushContextPrincipal(in JSContextPtr cx,
-                                         in JSStackFramePtr fp,
-                                         in nsIPrincipal principal);
-
-    /**
-     * Removes a clamp set by pushContextPrincipal from cx. This must be
-     * called in a stack-like fashion (e.g., given two contexts |a| and |b|,
-     * it is not legal to do: push(a) push(b) pop(a)).
-     */
-    [noscript] void popContextPrincipal(in JSContextPtr cx);
 };
 
 %{C++
 #define NS_SCRIPTSECURITYMANAGER_CONTRACTID "@mozilla.org/scriptsecuritymanager;1"
 #define NS_SCRIPTSECURITYMANAGER_CLASSNAME "scriptsecuritymanager"
 %}
--- a/caps/include/nsScriptSecurityManager.h
+++ b/caps/include/nsScriptSecurityManager.h
@@ -398,22 +398,21 @@ private:
     ObjectPrincipalFinder(JSObject *obj);
     
     // Decides, based on CSP, whether or not eval() and stuff can be executed.
     static JSBool
     ContentSecurityPolicyPermitsJSAction(JSContext *cx);
 
     // Returns null if a principal cannot be found; generally callers
     // should error out at that point.
-    static nsIPrincipal*
-    doGetObjectPrincipal(JSObject *obj
+    static nsIPrincipal* doGetObjectPrincipal(JSObject *obj);
 #ifdef DEBUG
-                         , bool aAllowShortCircuit = true
+    static nsIPrincipal*
+    old_doGetObjectPrincipal(JSObject *obj, bool aAllowShortCircuit = true);
 #endif
-                         );
 
     // Returns null if a principal cannot be found.  Note that rv can be NS_OK
     // when this happens -- this means that there was no JS running.
     nsIPrincipal*
     doGetSubjectPrincipal(nsresult* rv);
     
     nsresult
     CheckPropertyAccessImpl(PRUint32 aAction,
@@ -549,40 +548,28 @@ private:
     nsresult
     InitPrincipals(PRUint32 prefCount, const char** prefNames);
 
 #ifdef DEBUG_CAPS_HACKER
     void
     PrintPolicyDB();
 #endif
 
-    struct ContextPrincipal {
-        ContextPrincipal(ContextPrincipal *next, JSContext *cx,
-                         JSStackFrame *fp, nsIPrincipal *principal)
-            : mNext(next), mCx(cx), mFp(fp), mPrincipal(principal) {}
-
-        ContextPrincipal *mNext;
-        JSContext *mCx;
-        JSStackFrame *mFp;
-        nsCOMPtr<nsIPrincipal> mPrincipal;
-    };
-
     // JS strings we need to clean up on shutdown
     static jsid sEnabledID;
 
     inline void
     ScriptSecurityPrefChanged();
 
     nsObjectHashtable* mOriginToPolicyMap;
     DomainPolicy* mDefaultPolicy;
     nsObjectHashtable* mCapabilities;
 
     nsCOMPtr<nsIPrincipal> mSystemPrincipal;
     nsCOMPtr<nsIPrincipal> mSystemCertificate;
-    ContextPrincipal *mContextPrincipals;
     nsInterfaceHashtable<PrincipalKey, nsIPrincipal> mPrincipals;
     bool mPrefInitialized;
     bool mIsJavaScriptEnabled;
     bool mIsWritingPrefs;
     bool mPolicyPrefsChanged;
 
     static bool sStrictFileOriginPolicy;
 
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -158,54 +158,16 @@ GetPrincipalDomainOrigin(nsIPrincipal* a
 }
 
 static nsIScriptContext *
 GetScriptContext(JSContext *cx)
 {
     return GetScriptContextFromJSContext(cx);
 }
 
-// Callbacks for the JS engine to use to push/pop context principals.
-static JSBool
-PushPrincipalCallback(JSContext *cx, JSPrincipals *principals)
-{
-    // We should already be in the compartment of the given principal.
-    MOZ_ASSERT(principals ==
-               JS_GetCompartmentPrincipals((js::GetContextCompartment(cx))));
-
-    // Get the security manager.
-    nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
-    if (!ssm) {
-        return true;
-    }
-
-    // Push the principal.
-    JSStackFrame *fp = NULL;
-    nsresult rv = ssm->PushContextPrincipal(cx, JS_FrameIterator(cx, &fp),
-                                            nsJSPrincipals::get(principals));
-    if (NS_FAILED(rv)) {
-        JS_ReportOutOfMemory(cx);
-        return false;
-    }
-
-    return true;
-}
-
-static JSBool
-PopPrincipalCallback(JSContext *cx)
-{
-    nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
-    if (ssm) {
-        ssm->PopContextPrincipal(cx);
-    }
-
-    return true;
-}
-
-
 inline void SetPendingException(JSContext *cx, const char *aMsg)
 {
     JSAutoRequest ar(cx);
     JS_ReportError(cx, "%s", aMsg);
 }
 
 inline void SetPendingException(JSContext *cx, const PRUnichar *aMsg)
 {
@@ -400,44 +362,16 @@ nsScriptSecurityManager::GetCxSubjectPri
     nsresult rv = NS_ERROR_FAILURE;
     nsIPrincipal *principal = GetPrincipalAndFrame(cx, fp, &rv);
     if (NS_FAILED(rv))
         return nsnull;
 
     return principal;
 }
 
-NS_IMETHODIMP
-nsScriptSecurityManager::PushContextPrincipal(JSContext *cx,
-                                              JSStackFrame *fp,
-                                              nsIPrincipal *principal)
-{
-    NS_ASSERTION(principal, "Must pass a non-null principal");
-
-    ContextPrincipal *cp = new ContextPrincipal(mContextPrincipals, cx, fp,
-                                                principal);
-    if (!cp)
-        return NS_ERROR_OUT_OF_MEMORY;
-
-    mContextPrincipals = cp;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-nsScriptSecurityManager::PopContextPrincipal(JSContext *cx)
-{
-    NS_ASSERTION(mContextPrincipals->mCx == cx, "Mismatched push/pop");
-
-    ContextPrincipal *next = mContextPrincipals->mNext;
-    delete mContextPrincipals;
-    mContextPrincipals = next;
-
-    return NS_OK;
-}
-
 ////////////////////
 // Policy Storage //
 ////////////////////
 
 // Table of security levels
 static bool
 DeleteCapability(nsHashKey *aKey, void *aData, void* closure)
 {
@@ -2299,62 +2233,29 @@ nsScriptSecurityManager::GetPrincipalAnd
 {
     NS_PRECONDITION(rv, "Null out param");
     //-- If there's no principal on the stack, look at the global object
     //   and return the innermost frame for annotations.
     *rv = NS_OK;
 
     if (cx)
     {
-        JSStackFrame *target = nsnull;
-        nsIPrincipal *targetPrincipal = nsnull;
-        for (ContextPrincipal *cp = mContextPrincipals; cp; cp = cp->mNext)
-        {
-            if (cp->mCx == cx)
-            {
-                target = cp->mFp;
-                targetPrincipal = cp->mPrincipal;
-                break;
-            }
-        }
-
         // Get principals from innermost JavaScript frame.
         JSStackFrame *fp = nsnull; // tell JS_FrameIterator to start at innermost
         for (fp = JS_FrameIterator(cx, &fp); fp; fp = JS_FrameIterator(cx, &fp))
         {
-            if (fp == target)
-                break;
             nsIPrincipal* result = GetFramePrincipal(cx, fp, rv);
             if (result)
             {
                 NS_ASSERTION(NS_SUCCEEDED(*rv), "Weird return");
                 *frameResult = fp;
                 return result;
             }
         }
 
-        // If targetPrincipal is non-null, then it means that someone wants to
-        // clamp the principals on this context to this principal. Note that
-        // fp might not equal target here (fp might be null) because someone
-        // could have set aside the frame chain in the meantime.
-        if (targetPrincipal)
-        {
-            if (fp && fp == target)
-            {
-                *frameResult = fp;
-            }
-            else
-            {
-                JSStackFrame *inner = nsnull;
-                *frameResult = JS_FrameIterator(cx, &inner);
-            }
-
-            return targetPrincipal;
-        }
-
         nsIScriptContextPrincipal* scp =
             GetScriptContextPrincipalFromJSContext(cx);
         if (scp)
         {
             nsIScriptObjectPrincipal* globalData = scp->GetObjectPrincipal();
             if (!globalData)
             {
                 *rv = NS_ERROR_FAILURE;
@@ -2375,47 +2276,67 @@ nsScriptSecurityManager::GetPrincipalAnd
 
     return nsnull;
 }
 
 nsIPrincipal*
 nsScriptSecurityManager::GetSubjectPrincipal(JSContext *cx,
                                              nsresult* rv)
 {
-    NS_PRECONDITION(rv, "Null out param");
-    JSStackFrame *fp;
-    return GetPrincipalAndFrame(cx, &fp, rv);
+    *rv = NS_OK;
+    JSCompartment *compartment = js::GetContextCompartment(cx);
+
+    // The context should always be in a compartment, either one it has entered
+    // or the one associated with its global.
+    MOZ_ASSERT(!!compartment);
+
+    JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
+    return nsJSPrincipals::get(principals);
 }
 
 NS_IMETHODIMP
 nsScriptSecurityManager::GetObjectPrincipal(JSContext *aCx, JSObject *aObj,
                                             nsIPrincipal **result)
 {
     *result = doGetObjectPrincipal(aObj);
     if (!*result)
         return NS_ERROR_FAILURE;
     NS_ADDREF(*result);
     return NS_OK;
 }
 
 // static
 nsIPrincipal*
-nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj
+nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj)
+{
+    JSCompartment *compartment = js::GetObjectCompartment(aObj);
+    JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
+    nsIPrincipal *principal = nsJSPrincipals::get(principals);
+
+    // We leave the old code in for a little while to make sure that pulling
+    // object principals directly off the compartment always gives an equivalent
+    // result (from a security perspective).
 #ifdef DEBUG
-                                              , bool aAllowShortCircuit
+    nsIPrincipal *old = old_doGetObjectPrincipal(aObj);
+    MOZ_ASSERT(NS_SUCCEEDED(CheckSameOriginPrincipal(principal, old)));
 #endif
-                                              )
+
+    return principal;
+}
+
+#ifdef DEBUG
+// static
+nsIPrincipal*
+nsScriptSecurityManager::old_doGetObjectPrincipal(JSObject *aObj,
+                                                  bool aAllowShortCircuit)
 {
     NS_ASSERTION(aObj, "Bad call to doGetObjectPrincipal()!");
     nsIPrincipal* result = nsnull;
 
-#ifdef DEBUG
     JSObject* origObj = aObj;
-#endif
-    
     js::Class *jsClass = js::GetObjectClass(aObj);
 
     // A common case seen in this code is that we enter this function
     // with aObj being a Function object, whose parent is a Call
     // object. Neither of those have object principals, so we can skip
     // those objects here before we enter the below loop. That way we
     // avoid wasting time checking properties of their classes etc in
     // the loop.
@@ -2439,48 +2360,41 @@ nsScriptSecurityManager::doGetObjectPrin
     }
 
     do {
         // Note: jsClass is set before this loop, and also at the
         // *end* of this loop.
         
         if (IS_WRAPPER_CLASS(jsClass)) {
             result = sXPConnect->GetPrincipal(aObj,
-#ifdef DEBUG
-                                              aAllowShortCircuit
-#else
-                                              true
-#endif
-                                              );
+                                              aAllowShortCircuit);
             if (result) {
                 break;
             }
         } else {
             nsISupports *priv;
             if (!(~jsClass->flags & (JSCLASS_HAS_PRIVATE |
                                      JSCLASS_PRIVATE_IS_NSISUPPORTS))) {
                 priv = (nsISupports *) js::GetObjectPrivate(aObj);
             } else if (IsDOMClass(jsClass) &&
                        DOMJSClass::FromJSClass(jsClass)->mDOMObjectIsISupports) {
                 priv = UnwrapDOMObject<nsISupports>(aObj);
             } else {
                 priv = nsnull;
             }
 
-#ifdef DEBUG
             if (aAllowShortCircuit) {
                 nsCOMPtr<nsIXPConnectWrappedNative> xpcWrapper =
                     do_QueryInterface(priv);
 
                 NS_ASSERTION(!xpcWrapper ||
                              !strcmp(jsClass->name, "XPCNativeWrapper"),
                              "Uh, an nsIXPConnectWrappedNative with the "
                              "wrong JSClass or getObjectOps hooks!");
             }
-#endif
 
             nsCOMPtr<nsIScriptObjectPrincipal> objPrin =
                 do_QueryInterface(priv);
 
             if (objPrin) {
                 result = objPrin->GetPrincipal();
 
                 if (result) {
@@ -2492,63 +2406,47 @@ nsScriptSecurityManager::doGetObjectPrin
         aObj = js::GetObjectParentMaybeScope(aObj);
 
         if (!aObj)
             break;
 
         jsClass = js::GetObjectClass(aObj);
     } while (1);
 
-#ifdef DEBUG
     if (aAllowShortCircuit) {
-        nsIPrincipal *principal = doGetObjectPrincipal(origObj, false);
+        nsIPrincipal *principal = old_doGetObjectPrincipal(origObj, false);
 
         // Because of inner window reuse, we can have objects with one principal
         // living in a scope with a different (but same-origin) principal. So
         // just check same-origin here.
         NS_ASSERTION(NS_SUCCEEDED(CheckSameOriginPrincipal(result, principal)),
                      "Principal mismatch.  Not good");
     }
-#endif
 
     return result;
 }
+#endif /* DEBUG */
 
 ///////////////// Capabilities API /////////////////////
 NS_IMETHODIMP
 nsScriptSecurityManager::IsCapabilityEnabled(const char *capability,
                                              bool *result)
 {
     nsresult rv;
     JSStackFrame *fp = nsnull;
     JSContext *cx = GetCurrentJSContext();
     fp = cx ? JS_FrameIterator(cx, &fp) : nsnull;
 
-    JSStackFrame *target = nsnull;
-    nsIPrincipal *targetPrincipal = nsnull;
-    for (ContextPrincipal *cp = mContextPrincipals; cp; cp = cp->mNext)
-    {
-        if (cp->mCx == cx)
-        {
-            target = cp->mFp;
-            targetPrincipal = cp->mPrincipal;
-            break;
-        }
-    }
-
     if (!fp)
     {
-        // No script code on stack. If we had a principal pushed for this
-        // context and fp is null, then we use that principal. Otherwise, we
-        // don't have enough information and have to allow execution.
-
-        *result = (targetPrincipal && !target)
-                  ? (targetPrincipal == mSystemPrincipal)
-                  : true;
-
+        // No script code on stack. Allow access if and only if the subject
+        // principal is system.
+        nsresult ignored;
+        nsIPrincipal *subjectPrin = doGetSubjectPrincipal(&ignored);
+        *result = (!subjectPrin || subjectPrin == mSystemPrincipal);
         return NS_OK;
     }
 
     *result = false;
     nsIPrincipal* previousPrincipal = nsnull;
     do
     {
         nsIPrincipal* principal = GetFramePrincipal(cx, fp, &rv);
@@ -2581,17 +2479,17 @@ nsScriptSecurityManager::IsCapabilityEna
         if (NS_FAILED(rv)) return rv;
         if (*result)
             return NS_OK;
 
         // Capabilities do not extend to calls into C/C++ and then back into
         // the JS engine via JS_EvaluateScript or similar APIs.
         if (JS_IsGlobalFrame(cx, fp))
             break;
-    } while (fp != target && (fp = JS_FrameIterator(cx, &fp)) != nsnull);
+    } while ((fp = JS_FrameIterator(cx, &fp)) != nsnull);
 
     if (!previousPrincipal)
     {
         // No principals on the stack, all native code.  Allow
         // execution if the subject principal is the system principal.
 
         return SubjectPrincipalIsSystem(result);
     }
@@ -3065,17 +2963,16 @@ nsScriptSecurityManager::Observe(nsISupp
 
 /////////////////////////////////////////////
 // Constructor, Destructor, Initialization //
 /////////////////////////////////////////////
 nsScriptSecurityManager::nsScriptSecurityManager(void)
     : mOriginToPolicyMap(nsnull),
       mDefaultPolicy(nsnull),
       mCapabilities(nsnull),
-      mContextPrincipals(nsnull),
       mPrefInitialized(false),
       mIsJavaScriptEnabled(false),
       mIsWritingPrefs(false),
       mPolicyPrefsChanged(true)
 {
     MOZ_STATIC_ASSERT(sizeof(intptr_t) == sizeof(void*),
                       "intptr_t and void* have different lengths on this platform. "
                       "This may cause a security failure with the SecurityLevel union.");
@@ -3126,19 +3023,17 @@ nsresult nsScriptSecurityManager::Init()
 
     rv = runtimeService->GetRuntime(&sRuntime);
     NS_ENSURE_SUCCESS(rv, rv);
 
     static const JSSecurityCallbacks securityCallbacks = {
         CheckObjectAccess,
         nsJSPrincipals::Subsume,
         ObjectPrincipalFinder,
-        ContentSecurityPolicyPermitsJSAction,
-        PushPrincipalCallback,
-        PopPrincipalCallback
+        ContentSecurityPolicyPermitsJSAction
     };
 
     MOZ_ASSERT(!JS_GetSecurityCallbacks(sRuntime));
     JS_SetSecurityCallbacks(sRuntime, &securityCallbacks);
     JS_InitDestroyPrincipalsCallback(sRuntime, nsJSPrincipals::Destroy);
 
     JS_SetTrustedPrincipals(sRuntime, system);
 
@@ -3147,17 +3042,16 @@ nsresult nsScriptSecurityManager::Init()
 
 static nsRefPtr<nsScriptSecurityManager> gScriptSecMan;
 
 jsid nsScriptSecurityManager::sEnabledID   = JSID_VOID;
 
 nsScriptSecurityManager::~nsScriptSecurityManager(void)
 {
     Preferences::RemoveObservers(this, kObservedPrefs);
-    NS_ASSERTION(!mContextPrincipals, "Leaking mContextPrincipals");
     delete mOriginToPolicyMap;
     if(mDefaultPolicy)
         mDefaultPolicy->Drop();
     delete mCapabilities;
 }
 
 void
 nsScriptSecurityManager::Shutdown()
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -252,17 +252,17 @@ nsFrameMessageManager::SendAsyncMessage(
   }
   return SendAsyncMessageInternal(aMessageName, json);
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::Dump(const nsAString& aStr)
 {
 #ifdef ANDROID
-  __android_log_print(ANDROID_LOG_INFO, "Gecko", NS_ConvertUTF16toUTF8(aStr).get());
+  __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", NS_ConvertUTF16toUTF8(aStr).get());
 #endif
   fputs(NS_ConvertUTF16toUTF8(aStr).get(), stdout);
   fflush(stdout);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsFrameMessageManager::PrivateNoteIntentionalCrash()
--- a/content/events/src/nsEventListenerManager.cpp
+++ b/content/events/src/nsEventListenerManager.cpp
@@ -208,24 +208,30 @@ nsEventListenerManager::AddEventListener
 
   mNoListenerForEvent = NS_EVENT_TYPE_NULL;
   mNoListenerForEventAtom = nsnull;
 
   ls = mListeners.AppendElement();
   ls->mListener = aListener;
   ls->mEventType = aType;
   ls->mTypeAtom = aTypeAtom;
-  ls->mWrappedJS = false;
   ls->mFlags = aFlags;
   ls->mHandlerIsString = false;
 
-  nsCOMPtr<nsIXPConnectWrappedJS> wjs = do_QueryInterface(aListener);
-  if (wjs) {
-    ls->mWrappedJS = true;
+  // Detect the type of event listener.
+  nsCOMPtr<nsIXPConnectWrappedJS> wjs;
+  if (aFlags & NS_PRIV_EVENT_FLAG_SCRIPT) {
+    ls->mListenerType = eJSEventListener;
+  } else if ((wjs = do_QueryInterface(aListener))) {
+    ls->mListenerType = eWrappedJSListener;
+  } else {
+    ls->mListenerType = eNativeListener;
   }
+
+
   if (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) {
     mMayHaveSystemGroupListeners = true;
   }
   if (aFlags & NS_EVENT_FLAG_CAPTURE) {
     mMayHaveCapturingListeners = true;
   }
 
   if (aType == NS_AFTERPAINT) {
@@ -453,17 +459,18 @@ nsEventListenerManager::FindJSEventListe
 {
   // Run through the listeners for this type and see if a script
   // listener is registered
   nsListenerStruct *ls;
   PRUint32 count = mListeners.Length();
   for (PRUint32 i = 0; i < count; ++i) {
     ls = &mListeners.ElementAt(i);
     if (EVENT_TYPE_EQUALS(ls, aEventType, aTypeAtom) &&
-        ls->mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) {
+        (ls->mListenerType == eJSEventListener))
+    {
       return ls;
     }
   }
   return nsnull;
 }
 
 nsresult
 nsEventListenerManager::SetJSEventListener(nsIScriptContext *aContext,
@@ -791,17 +798,17 @@ nsEventListenerManager::HandleEventSubTy
                                            nsIDOMEventTarget* aCurrentTarget,
                                            PRUint32 aPhaseFlags,
                                            nsCxPusher* aPusher)
 {
   nsresult result = NS_OK;
 
   // If this is a script handler and we haven't yet
   // compiled the event handler itself
-  if ((aListenerStruct->mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) &&
+  if ((aListenerStruct->mListenerType == eJSEventListener) &&
       aListenerStruct->mHandlerIsString) {
     nsIJSEventListener *jslistener = aListenerStruct->GetJSListener();
     result = CompileEventHandlerInternal(aListenerStruct,
                                          jslistener->GetEventContext() !=
                                            aPusher->GetCurrentScriptContext(),
                                          nsnull);
   }
 
@@ -858,23 +865,38 @@ nsEventListenerManager::HandleEventInter
         }
         if (*aDOMEvent) {
           if (!aEvent->currentTarget) {
             aEvent->currentTarget = aCurrentTarget->GetTargetForDOMEvent();
             if (!aEvent->currentTarget) {
               break;
             }
           }
+
+          // Push the appropriate context. Note that we explicitly don't push a
+          // context in the case that the listener is non-scripted, in which case
+          // it's the native code's responsibility to push a context if it ever
+          // enters JS. Ideally we'd do things this way for all scripted callbacks,
+          // but that would involve a lot of changes and context pushing is going
+          // away soon anyhow.
+          //
+          // NB: Since we're looping here, the no-RePush() case needs to actually be
+          // a Pop(), otherwise we might end up with whatever was pushed in a
+          // previous iteration.
+          if (ls->mListenerType == eNativeListener) {
+            aPusher->Pop();
+          } else if (!aPusher->RePush(aCurrentTarget)) {
+            continue;
+          }
+
           nsRefPtr<nsIDOMEventListener> kungFuDeathGrip = ls->mListener;
-          if (aPusher->RePush(aCurrentTarget)) {
-            if (NS_FAILED(HandleEventSubType(ls, ls->mListener, *aDOMEvent,
-                                             aCurrentTarget, aFlags,
-                                             aPusher))) {
-              aEvent->flags |= NS_EVENT_FLAG_EXCEPTION_THROWN;
-            }
+          if (NS_FAILED(HandleEventSubType(ls, ls->mListener, *aDOMEvent,
+                                           aCurrentTarget, aFlags,
+                                           aPusher))) {
+            aEvent->flags |= NS_EVENT_FLAG_EXCEPTION_THROWN;
           }
         }
       }
     }
   }
 
   aEvent->currentTarget = nsnull;
 
@@ -987,17 +1009,17 @@ nsEventListenerManager::GetListenerInfo(
   PRUint32 count = mListeners.Length();
   for (PRUint32 i = 0; i < count; ++i) {
     const nsListenerStruct& ls = mListeners.ElementAt(i);
     bool capturing = !!(ls.mFlags & NS_EVENT_FLAG_CAPTURE);
     bool systemGroup = !!(ls.mFlags & NS_EVENT_FLAG_SYSTEM_EVENT);
     bool allowsUntrusted = !!(ls.mFlags & NS_PRIV_EVENT_UNTRUSTED_PERMITTED);
     // If this is a script handler and we haven't yet
     // compiled the event handler itself go ahead and compile it
-    if ((ls.mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) && ls.mHandlerIsString) {
+    if ((ls.mListenerType == eJSEventListener) && ls.mHandlerIsString) {
       CompileEventHandlerInternal(const_cast<nsListenerStruct*>(&ls),
                                   true, nsnull);
     }
     const nsDependentSubstring& eventType =
       Substring(nsDependentAtomString(ls.mTypeAtom), 2);
     nsRefPtr<nsEventListenerInfo> info =
       new nsEventListenerInfo(eventType, ls.mListener, capturing,
                               allowsUntrusted, systemGroup);
@@ -1102,13 +1124,13 @@ nsEventListenerManager::UnmarkGrayJSList
 {
   PRUint32 count = mListeners.Length();
   for (PRUint32 i = 0; i < count; ++i) {
     const nsListenerStruct& ls = mListeners.ElementAt(i);
     nsIJSEventListener* jsl = ls.GetJSListener();
     if (jsl) {
       xpc_UnmarkGrayObject(jsl->GetHandler());
       xpc_UnmarkGrayObject(jsl->GetEventScope());
-    } else if (ls.mWrappedJS) {
+    } else if (ls.mListenerType == eWrappedJSListener) {
       xpc_TryUnmarkWrappedGrayObject(ls.mListener);
     }
   }
 }
--- a/content/events/src/nsEventListenerManager.h
+++ b/content/events/src/nsEventListenerManager.h
@@ -26,33 +26,40 @@ class nsIWidget;
 struct nsPoint;
 struct EventTypeData;
 class nsEventTargetChainItem;
 class nsPIDOMWindow;
 class nsCxPusher;
 class nsIEventListenerInfo;
 class nsIDocument;
 
+typedef enum
+{
+    eNativeListener = 0,
+    eJSEventListener,
+    eWrappedJSListener
+} nsListenerType;
+
 struct nsListenerStruct
 {
   nsRefPtr<nsIDOMEventListener> mListener;
   PRUint32                      mEventType;
   nsCOMPtr<nsIAtom>             mTypeAtom;
   PRUint16                      mFlags;
+  PRUint8                       mListenerType;
   bool                          mHandlerIsString;
-  bool                          mWrappedJS;
 
   nsIJSEventListener* GetJSListener() const {
-    return (mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) ?
+    return (mListenerType == eJSEventListener) ?
       static_cast<nsIJSEventListener *>(mListener.get()) : nsnull;
   }
 
   ~nsListenerStruct()
   {
-    if ((mFlags & NS_PRIV_EVENT_FLAG_SCRIPT) && mListener) {
+    if ((mListenerType == eJSEventListener) && mListener) {
       static_cast<nsIJSEventListener*>(mListener.get())->Disconnect();
     }
   }
 };
 
 /*
  * Event listener manager
  */
--- a/content/xbl/src/nsXBLPrototypeHandler.cpp
+++ b/content/xbl/src/nsXBLPrototypeHandler.cpp
@@ -275,16 +275,22 @@ nsXBLPrototypeHandler::ExecuteHandler(ns
   nsISupports *scriptTarget;
 
   if (winRoot) {
     scriptTarget = boundGlobal;
   } else {
     scriptTarget = aTarget;
   }
 
+  // We're about to create a new nsJSEventListener, which means that we're
+  // responsible for pushing the context of the event target. See the similar
+  // comment in nsEventManagerListener.cpp.
+  nsCxPusher pusher;
+  NS_ENSURE_STATE(pusher.Push(aTarget));
+
   rv = EnsureEventHandler(boundGlobal, boundContext, onEventAtom, handler);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Bind it to the bound element
   JSObject* scope = boundGlobal->GetGlobalJSObject();
   nsScriptObjectHolder<JSObject> boundHandler(boundContext);
   rv = boundContext->BindCompiledEventHandler(scriptTarget, scope,
                                               handler.get(), boundHandler);
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -1194,56 +1194,55 @@ nsJSContext::EvaluateStringWithValue(con
     }
 
     return NS_OK;
   }
 
   xpc_UnmarkGrayObject(aScopeObject);
   nsAutoMicroTask mt;
 
-  // Safety first: get an object representing the script's principals, i.e.,
-  // the entities who signed this script, or the fully-qualified-domain-name
-  // or "codebase" from which it was loaded.
-  nsCOMPtr<nsIPrincipal> principal = aPrincipal;
-  nsresult rv;
-  if (!aPrincipal) {
-    nsIScriptGlobalObject *global = GetGlobalObject();
-    if (!global)
-      return NS_ERROR_FAILURE;
-    nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
-      do_QueryInterface(global, &rv);
-    if (NS_FAILED(rv))
-      return NS_ERROR_FAILURE;
-    principal = objPrincipal->GetPrincipal();
-    if (!principal)
-      return NS_ERROR_FAILURE;
-  }
+  // Ignore the principal that was passed in, and just assert that it matches
+  // the one we pull off the global.
+  nsCOMPtr<nsIPrincipal> principal;
+  nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal = do_QueryInterface(GetGlobalObject());
+  if (!objPrincipal)
+    return NS_ERROR_FAILURE;
+  principal = objPrincipal->GetPrincipal();
+  if (!principal)
+    return NS_ERROR_FAILURE;
+#ifdef DEBUG
+  bool equal = false;
+  principal->Equals(aPrincipal, &equal);
+  MOZ_ASSERT(equal);
+  nsIPrincipal *scopeObjectPrincipal =
+    nsJSPrincipals::get(JS_GetCompartmentPrincipals(js::GetObjectCompartment(aScopeObject)));
+  equal = false;
+  principal->Equals(scopeObjectPrincipal, &equal);
+  MOZ_ASSERT(equal);
+#endif
 
   bool ok = false;
 
-  rv = sSecurityManager->CanExecuteScripts(mContext, principal, &ok);
+  nsresult rv = sSecurityManager->CanExecuteScripts(mContext, principal, &ok);
   if (NS_FAILED(rv)) {
     return NS_ERROR_FAILURE;
   }
 
   // Push our JSContext on the current thread's context stack so JS called
   // from native code via XPConnect uses the right context.  Do this whether
   // or not the SecurityManager said "ok", in order to simplify control flow
   // below where we pop before returning.
   nsCOMPtr<nsIJSContextStack> stack =
            do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
   if (NS_FAILED(rv) || NS_FAILED(stack->Push(mContext))) {
     return NS_ERROR_FAILURE;
   }
 
   jsval val;
 
-  rv = sSecurityManager->PushContextPrincipal(mContext, nsnull, principal);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsJSContext::TerminationFuncHolder holder(this);
 
   // SecurityManager said "ok", but don't compile if aVersion is unknown.
   // Since the caller is responsible for parsing the version strings, we just
   // check it isn't JSVERSION_UNKNOWN.
   if (ok && ((JSVersion)aVersion) != JSVERSION_UNKNOWN) {
 
     XPCAutoRequest ar(mContext);
@@ -1289,18 +1288,16 @@ nsJSContext::EvaluateStringWithValue(con
     // tricky...
   }
   else {
     if (aIsUndefined) {
       *aIsUndefined = true;
     }
   }
 
-  sSecurityManager->PopContextPrincipal(mContext);
-
   // Pop here, after JS_ValueToString and any other possible evaluation.
   if (NS_FAILED(stack->Pop(nsnull)))
     rv = NS_ERROR_FAILURE;
 
   // ScriptEvaluated needs to come after we pop the stack
   ScriptEvaluated(true);
 
   return rv;
@@ -1396,29 +1393,35 @@ nsJSContext::EvaluateString(const nsAStr
   nsAutoMicroTask mt;
 
   if (!aScopeObject) {
     aScopeObject = JS_GetGlobalObject(mContext);
   }
 
   xpc_UnmarkGrayObject(aScopeObject);
 
-  // Safety first: get an object representing the script's principals, i.e.,
-  // the entities who signed this script, or the fully-qualified-domain-name
-  // or "codebase" from which it was loaded.
-  nsCOMPtr<nsIPrincipal> principal = aPrincipal;
-  if (!aPrincipal) {
-    nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal =
-      do_QueryInterface(GetGlobalObject());
-    if (!objPrincipal)
-      return NS_ERROR_FAILURE;
-    principal = objPrincipal->GetPrincipal();
-    if (!principal)
-      return NS_ERROR_FAILURE;
-  }
+  // Ignore the principal that was passed in, and just assert that it matches
+  // the one we pull off the global.
+  nsCOMPtr<nsIPrincipal> principal;
+  nsCOMPtr<nsIScriptObjectPrincipal> objPrincipal = do_QueryInterface(GetGlobalObject());
+  if (!objPrincipal)
+    return NS_ERROR_FAILURE;
+  principal = objPrincipal->GetPrincipal();
+  if (!principal)
+    return NS_ERROR_FAILURE;
+#ifdef DEBUG
+  bool equal = false;
+  principal->Equals(aPrincipal, &equal);
+  MOZ_ASSERT(equal);
+  nsIPrincipal *scopeObjectPrincipal =
+    nsJSPrincipals::get(JS_GetCompartmentPrincipals(js::GetObjectCompartment(aScopeObject)));
+  equal = false;
+  principal->Equals(scopeObjectPrincipal, &equal);
+  MOZ_ASSERT(equal);
+#endif
 
   bool ok = false;
 
   nsresult rv = sSecurityManager->CanExecuteScripts(mContext, principal, &ok);
   if (NS_FAILED(rv)) {
     return NS_ERROR_FAILURE;
   }
 
@@ -1433,19 +1436,16 @@ nsJSContext::EvaluateString(const nsAStr
   }
 
   // The result of evaluation, used only if there were no errors.  This need
   // not be a GC root currently, provided we run the GC only from the
   // operation callback or from ScriptEvaluated.
   jsval val = JSVAL_VOID;
   jsval* vp = aRetValue ? &val : NULL;
 
-  rv = sSecurityManager->PushContextPrincipal(mContext, nsnull, principal);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsJSContext::TerminationFuncHolder holder(this);
 
   ++mExecuteDepth;
 
   // SecurityManager said "ok", but don't compile if aVersion is unknown.
   // Since the caller is responsible for parsing the version strings, we just
   // check it isn't JSVERSION_UNKNOWN.
   if (ok && JSVersion(aVersion) != JSVERSION_UNKNOWN) {
@@ -1487,18 +1487,16 @@ nsJSContext::EvaluateString(const nsAStr
 
     if (aRetValue) {
       aRetValue->Truncate();
     }
   }
 
   --mExecuteDepth;
 
-  sSecurityManager->PopContextPrincipal(mContext);
-
   // Pop here, after JS_ValueToString and any other possible evaluation.
   if (NS_FAILED(stack->Pop(nsnull)))
     rv = NS_ERROR_FAILURE;
 
   // ScriptEvaluated needs to come after we pop the stack
   ScriptEvaluated(true);
 
   return rv;
@@ -1586,25 +1584,16 @@ nsJSContext::ExecuteScript(JSScript* aSc
   // called from JS calls back into JS via XPConnect.
   nsresult rv;
   nsCOMPtr<nsIJSContextStack> stack =
            do_GetService("@mozilla.org/js/xpc/ContextStack;1", &rv);
   if (NS_FAILED(rv) || NS_FAILED(stack->Push(mContext))) {
     return NS_ERROR_FAILURE;
   }
 
-  nsCOMPtr<nsIPrincipal> principal;
-  rv = sSecurityManager->GetObjectPrincipal(mContext,
-                                            JS_GetGlobalFromScript(aScriptObject),
-                                            getter_AddRefs(principal));
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  rv = sSecurityManager->PushContextPrincipal(mContext, nsnull, principal);
-  NS_ENSURE_SUCCESS(rv, rv);
-
   nsJSContext::TerminationFuncHolder holder(this);
   XPCAutoRequest ar(mContext);
   ++mExecuteDepth;
 
   // The result of evaluation, used only if there were no errors. This need
   // not be a GC root currently, provided we run the GC only from the
   // operation callback or from ScriptEvaluated.
   jsval val;
@@ -1621,18 +1610,16 @@ nsJSContext::ExecuteScript(JSScript* aSc
 
     if (aRetValue) {
       aRetValue->Truncate();
     }
   }
 
   --mExecuteDepth;
 
-  sSecurityManager->PopContextPrincipal(mContext);
-
   // Pop here, after JS_ValueToString and any other possible evaluation.
   if (NS_FAILED(stack->Pop(nsnull)))
     rv = NS_ERROR_FAILURE;
 
   // ScriptEvaluated needs to come after we pop the stack
   ScriptEvaluated(true);
 
   return rv;
@@ -1863,34 +1850,22 @@ nsJSContext::CallEventHandler(nsISupport
   nsJSContext::TerminationFuncHolder holder(this);
 
   if (NS_SUCCEEDED(rv)) {
     // Convert args to jsvals.
     PRUint32 argc = 0;
     jsval *argv = nsnull;
 
     JSObject *funobj = aHandler;
-    nsCOMPtr<nsIPrincipal> principal;
-    rv = sSecurityManager->GetObjectPrincipal(mContext, funobj,
-                                              getter_AddRefs(principal));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    JSStackFrame *currentfp = nsnull;
-    rv = sSecurityManager->PushContextPrincipal(mContext,
-                                                JS_FrameIterator(mContext, &currentfp),
-                                                principal);
-    NS_ENSURE_SUCCESS(rv, rv);
-
     jsval funval = OBJECT_TO_JSVAL(funobj);
     JSAutoEnterCompartment ac;
     js::ForceFrame ff(mContext, funobj);
     if (!ac.enter(mContext, funobj) || !ff.enter() ||
         !JS_WrapObject(mContext, &target)) {
       ReportPendingException();
-      sSecurityManager->PopContextPrincipal(mContext);
       return NS_ERROR_FAILURE;
     }
 
     Maybe<nsRootedJSValueArray> tempStorage;
 
     // Use |target| as the scope for wrapping the arguments, since aScope is
     // the safe scope in many cases, which isn't very useful.  Wrapping aTarget
     // was OK because those typically have PreCreate methods that give them the
@@ -1923,18 +1898,16 @@ nsJSContext::CallEventHandler(nsISupport
       rv = nsContentUtils::XPConnect()->JSToVariant(mContext, rval, arv);
     }
 
     // Tell XPConnect about any pending exceptions. This is needed
     // to avoid dropping JS exceptions in case we got here through
     // nested calls through XPConnect.
     if (NS_FAILED(rv))
       ReportPendingException();
-
-    sSecurityManager->PopContextPrincipal(mContext);
   }
 
   pusher.Pop();
 
   // ScriptEvaluated needs to come after we pop the stack
   ScriptEvaluated(true);
 
   return rv;
--- a/dom/indexedDB/ipc/IndexedDBParent.cpp
+++ b/dom/indexedDB/ipc/IndexedDBParent.cpp
@@ -372,17 +372,17 @@ IndexedDBDatabaseParent::HandleDatabaseE
 {
   MOZ_ASSERT(mDatabase);
   MOZ_ASSERT(!aType.EqualsLiteral(ERROR_EVT_STR),
              "Should never get error events in the parent process!");
 
   nsresult rv;
 
   if (aType.EqualsLiteral(VERSIONCHANGE_EVT_STR)) {
-    JSContext* cx = nsContentUtils::GetCurrentJSContext();
+    JSContext* cx = nsContentUtils::GetSafeJSContext();
     NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
 
     nsCOMPtr<nsIIDBVersionChangeEvent> changeEvent = do_QueryInterface(aEvent);
     NS_ENSURE_TRUE(changeEvent, NS_ERROR_FAILURE);
 
     PRUint64 oldVersion;
     rv = changeEvent->GetOldVersion(&oldVersion);
     NS_ENSURE_SUCCESS(rv, rv);
--- a/dom/src/json/nsJSON.cpp
+++ b/dom/src/json/nsJSON.cpp
@@ -172,42 +172,25 @@ NS_IMETHODIMP
 nsJSON::EncodeFromJSVal(JS::Value *value, JSContext *cx, nsAString &result)
 {
   result.Truncate();
 
   // Begin a new request
   JSAutoRequest ar(cx);
 
   JSAutoEnterCompartment ac;
-  nsIScriptSecurityManager *ssm = nsnull;
   if (value->isObject()) {
     JSObject *obj = &value->toObject();
     if (!ac.enter(cx, obj)) {
       return NS_ERROR_FAILURE;
     }
-
-    nsCOMPtr<nsIPrincipal> principal;
-    ssm = nsContentUtils::GetSecurityManager();
-    nsresult rv = ssm->GetObjectPrincipal(cx, obj, getter_AddRefs(principal));
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    JSStackFrame *fp = nsnull;
-    rv = ssm->PushContextPrincipal(cx, JS_FrameIterator(cx, &fp), principal);
-    NS_ENSURE_SUCCESS(rv, rv);
   }
 
   nsJSONWriter writer;
-  JSBool ok = JS_Stringify(cx, value, NULL, JSVAL_NULL,
-                           WriteCallback, &writer);
-
-  if (ssm) {
-    ssm->PopContextPrincipal(cx);
-  }
-
-  if (!ok) {
+  if (!JS_Stringify(cx, value, NULL, JSVAL_NULL, WriteCallback, &writer)) {
     return NS_ERROR_XPC_BAD_CONVERT_JS;
   }
 
   NS_ENSURE_TRUE(writer.DidWrite(), NS_ERROR_UNEXPECTED);
   writer.FlushBuffer();
   result.Assign(writer.mOutputString);
   return NS_OK;
 }
--- a/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html
+++ b/dom/tests/mochitest/whatwg/postMessage_chrome_helper.html
@@ -32,19 +32,17 @@
           msg += " wrong-message(" + evt.data + ")";
 
         respond(msg);
       }
     }
     
     function respond(msg)
     {
-      // ...so get privileges and test that this works with privileges
-      netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
-      window.parent.postMessage(msg, "*");
+      SpecialPowers.wrap(window).parent.postMessage(msg, "*");
     }
     
     window.addEventListener("message", receiveMessage, false);
   </script>
 </head>
 <body>
 <h1 id="domain">example.org</h1>
 </body>
--- a/dom/tests/mochitest/whatwg/test_postMessage_chrome.html
+++ b/dom/tests/mochitest/whatwg/test_postMessage_chrome.html
@@ -88,20 +88,16 @@ function chromePathIsSet(evt)
 
 /*************
  * RECEIVERS *
  *************/
 
 function receiveContent(evt)
 {
   is(evt.isTrusted, true, "should have sent a trusted event");
-  is(evt.origin, "http://example.org", "content response event has wrong URI");
-  is(evt.source, window.frames.contentDomain,
-     "wrong source for same-domain message!");
-
   finish();
 }
 
 
 /**************
  * TEST SETUP *
  **************/
 
--- a/dom/wifi/WifiWorker.js
+++ b/dom/wifi/WifiWorker.js
@@ -713,19 +713,21 @@ var WifiManager = (function() {
         if (kv.length === 2)
           fields[kv[0]] = kv[1];
       }
       if (!("state" in fields))
         return true;
       fields.state = supplicantStatesMap[fields.state];
 
       // The BSSID field is only valid in the ASSOCIATING and ASSOCIATED
-      // states.
-      if (fields.state === "ASSOCIATING" || fields.state == "ASSOCIATED")
+      // states, except when we "reauth", except this seems to depend on the
+      // driver, so simply check to make sure that we don't have a null BSSID.
+      if (fields.BSSID !== "00:00:00:00:00:00")
         manager.connectionInfo.bssid = fields.BSSID;
+
       notifyStateChange(fields);
       return true;
     }
     if (eventData.indexOf("CTRL-EVENT-DRIVER-STATE") === 0) {
       var handlerName = driverEventMap[eventData];
       if (handlerName)
         notify(handlerName);
       return true;
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -1228,17 +1228,17 @@ public:
       else {
         NS_WARNING("Failed to log script error!");
       }
     }
 
     if (!logged) {
       NS_ConvertUTF16toUTF8 msg(aMessage);
 #ifdef ANDROID
-      __android_log_print(ANDROID_LOG_INFO, "Gecko", msg.get());
+      __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", msg.get());
 #endif
       fputs(msg.get(), stderr);
       fflush(stderr);
     }
 
     return true;
   }
 };
--- a/dom/workers/WorkerScope.cpp
+++ b/dom/workers/WorkerScope.cpp
@@ -537,17 +537,17 @@ private:
       }
 
       JSAutoByteString buffer(aCx, str);
       if (!buffer) {
         return false;
       }
 
 #ifdef ANDROID
-      __android_log_print(ANDROID_LOG_INFO, "Gecko", buffer.ptr());
+      __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", buffer.ptr());
 #endif
       fputs(buffer.ptr(), stdout);
       fflush(stdout);
     }
 
     return true;
   }
 
--- a/dom/workers/XMLHttpRequest.cpp
+++ b/dom/workers/XMLHttpRequest.cpp
@@ -1142,19 +1142,19 @@ public:
     mBody.swap(aBody);
     mClonedObjects.SwapElements(aClonedObjects);
   }
 
   nsresult
   MainThreadRun()
   {
     nsCOMPtr<nsIVariant> variant;
-    RuntimeService::AutoSafeJSContext cx;
 
     if (mBody.data()) {
+      RuntimeService::AutoSafeJSContext cx;
       nsIXPConnect* xpc = nsContentUtils::XPConnect();
       NS_ASSERTION(xpc, "This should never be null!");
 
       nsresult rv = NS_OK;
 
       JSStructuredCloneCallbacks* callbacks =
         mWorkerPrivate->IsChromeWorker() ?
         ChromeWorkerStructuredCloneCallbacks(true) :
--- a/gfx/thebes/gfxGDIFontList.cpp
+++ b/gfx/thebes/gfxGDIFontList.cpp
@@ -744,34 +744,37 @@ gfxGDIFontList::LookupLocalFont(const gf
 
     // lookup in name lookup tables, return null if not found
     if (!(lookup = mPostscriptNames.GetWeak(aFullname)) &&
         !(lookup = mFullnames.GetWeak(aFullname))) 
     {
         return nsnull;
     }
 
-    // create a new font entry with the proxy entry style characteristics
-    PRUint16 w = (aProxyEntry->mWeight == 0 ? 400 : aProxyEntry->mWeight);
     bool isCFF = false; // jtdfix -- need to determine this
     
     // use the face name from the lookup font entry, which will be the localized
     // face name which GDI mapping tables use (e.g. with the system locale set to
     // Dutch, a fullname of 'Arial Bold' will find a font entry with the face name
     // 'Arial Vet' which can be used as a key in GDI font lookups).
-    gfxFontEntry *fe = GDIFontEntry::CreateFontEntry(lookup->Name(), 
+    GDIFontEntry *fe = GDIFontEntry::CreateFontEntry(lookup->Name(), 
         gfxWindowsFontType(isCFF ? GFX_FONT_TYPE_PS_OPENTYPE : GFX_FONT_TYPE_TRUETYPE) /*type*/, 
-        PRUint32(aProxyEntry->mItalic ? NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL), 
-        w, aProxyEntry->mStretch, nsnull);
+        lookup->mItalic ? NS_FONT_STYLE_ITALIC : NS_FONT_STYLE_NORMAL,
+        lookup->mWeight, aProxyEntry->mStretch, nsnull);
         
     if (!fe)
         return nsnull;
 
     fe->mIsUserFont = true;
     fe->mIsLocalUserFont = true;
+
+    // make the new font entry match the proxy entry style characteristics
+    fe->mWeight = (aProxyEntry->mWeight == 0 ? 400 : aProxyEntry->mWeight);
+    fe->mItalic = aProxyEntry->mItalic;
+
     return fe;
 }
 
 void gfxGDIFontList::InitializeFontEmbeddingProcs()
 {
     static HMODULE fontlib = LoadLibraryW(L"t2embed.dll");
     if (!fontlib)
         return;
--- a/ipc/testshell/XPCShellEnvironment.cpp
+++ b/ipc/testshell/XPCShellEnvironment.cpp
@@ -875,30 +875,16 @@ FullTrustSecMan::GetCxSubjectPrincipal(J
 NS_IMETHODIMP_(nsIPrincipal *)
 FullTrustSecMan::GetCxSubjectPrincipalAndFrame(JSContext *cx,
                                                JSStackFrame **fp)
 {
     *fp = nsnull;
     return mSystemPrincipal;
 }
 
-NS_IMETHODIMP
-FullTrustSecMan::PushContextPrincipal(JSContext *cx,
-                                      JSStackFrame *fp,
-                                      nsIPrincipal *principal)
-{
-    return NS_OK;
-}
-
-NS_IMETHODIMP
-FullTrustSecMan::PopContextPrincipal(JSContext *cx)
-{
-    return NS_OK;
-}
-
 NS_IMETHODIMP_(nsrefcnt)
 XPCShellDirProvider::AddRef()
 {
     return 2;
 }
 
 NS_IMETHODIMP_(nsrefcnt)
 XPCShellDirProvider::Release()
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1660,26 +1660,16 @@ typedef JSPrincipals *
 /*
  * Used to check if a CSP instance wants to disable eval() and friends.
  * See js_CheckCSPPermitsJSAction() in jsobj.
  */
 typedef JSBool
 (* JSCSPEvalChecker)(JSContext *cx);
 
 /*
- * Security callbacks for pushing and popping context principals. These are only
- * temporarily necessary and will hopefully be gone again in a matter of weeks.
- */
-typedef JSBool
-(* JSPushContextPrincipalOp)(JSContext *cx, JSPrincipals *principals);
-
-typedef JSBool
-(* JSPopContextPrincipalOp)(JSContext *cx);
-
-/*
  * Callback used to ask the embedding for the cross compartment wrapper handler
  * that implements the desired prolicy for this kind of object in the
  * destination compartment.
  */
 typedef JSObject *
 (* JSWrapObjectCallback)(JSContext *cx, JSObject *obj, JSObject *proto, JSObject *parent,
                          unsigned flags);
 
@@ -4338,18 +4328,16 @@ JS_HoldPrincipals(JSPrincipals *principa
 extern JS_PUBLIC_API(void)
 JS_DropPrincipals(JSRuntime *rt, JSPrincipals *principals);
 
 struct JSSecurityCallbacks {
     JSCheckAccessOp            checkObjectAccess;
     JSSubsumePrincipalsOp      subsumePrincipals;
     JSObjectPrincipalsFinder   findObjectPrincipals;
     JSCSPEvalChecker           contentSecurityPolicyAllows;
-    JSPushContextPrincipalOp   pushContextPrincipal;
-    JSPopContextPrincipalOp    popContextPrincipal;
 };
 
 extern JS_PUBLIC_API(void)
 JS_SetSecurityCallbacks(JSRuntime *rt, const JSSecurityCallbacks *callbacks);
 
 extern JS_PUBLIC_API(const JSSecurityCallbacks *)
 JS_GetSecurityCallbacks(JSRuntime *rt);
 
--- a/js/src/jsclone.cpp
+++ b/js/src/jsclone.cpp
@@ -467,47 +467,16 @@ JSStructuredCloneWriter::startObject(JSO
     if (!objs.append(ObjectValue(*obj)) || !counts.append(count))
         return false;
     checkStack();
 
     /* Write the header for obj. */
     return out.writePair(obj->isArray() ? SCTAG_ARRAY_OBJECT : SCTAG_OBJECT_OBJECT, 0);
 }
 
-class AutoEnterCompartmentAndPushPrincipal : public JSAutoEnterCompartment
-{
-  public:
-    bool enter(JSContext *cx, JSObject *target) {
-        // First, enter the compartment.
-        if (!JSAutoEnterCompartment::enter(cx, target))
-            return false;
-
-        // We only need to push a principal if we changed compartments.
-        if (state != STATE_OTHER_COMPARTMENT)
-            return true;
-
-        // Push.
-        const JSSecurityCallbacks *cb = cx->runtime->securityCallbacks;
-        if (cb->pushContextPrincipal)
-          return cb->pushContextPrincipal(cx, target->principals(cx));
-        return true;
-    }
-
-    ~AutoEnterCompartmentAndPushPrincipal() {
-        // Pop the principal if necessary.
-        if (state == STATE_OTHER_COMPARTMENT) {
-            AutoCompartment *ac = getAutoCompartment();
-            const JSSecurityCallbacks *cb = ac->context->runtime->securityCallbacks;
-            if (cb->popContextPrincipal)
-              cb->popContextPrincipal(ac->context);
-        }
-    }
-};
-
-
 bool
 JSStructuredCloneWriter::startWrite(const Value &v)
 {
     assertSameCompartment(context(), v);
 
     if (v.isString()) {
         return writeString(SCTAG_STRING, v.toString());
     } else if (v.isNumber()) {
@@ -524,17 +493,17 @@ JSStructuredCloneWriter::startWrite(cons
         // The object might be a security wrapper. See if we can clone what's
         // behind it. If we can, unwrap the object.
         obj = UnwrapObjectChecked(context(), obj);
         if (!obj)
             return false;
 
         // If we unwrapped above, we'll need to enter the underlying compartment.
         // Let the AutoEnterCompartment do the right thing for us.
-        AutoEnterCompartmentAndPushPrincipal ac;
+        JSAutoEnterCompartment ac;
         if (!ac.enter(context(), obj))
             return false;
 
         if (obj->isRegExp()) {
             RegExpObject &reobj = obj->asRegExp();
             return out.writePair(SCTAG_REGEXP_OBJECT, reobj.getFlags()) &&
                    writeString(SCTAG_STRING, reobj.getSource());
         } else if (obj->isDate()) {
@@ -569,17 +538,17 @@ JSStructuredCloneWriter::write(const Val
 {
     if (!startWrite(v))
         return false;
 
     while (!counts.empty()) {
         RootedObject obj(context(), &objs.back().toObject());
 
         // The objects in |obj| can live in other compartments.
-        AutoEnterCompartmentAndPushPrincipal ac;
+        JSAutoEnterCompartment ac;
         if (!ac.enter(context(), obj))
             return false;
 
         if (counts.back()) {
             counts.back()--;
             RootedId id(context(), ids.back());
             ids.popBack();
             checkStack();
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -908,27 +908,26 @@ inline InterpreterFrames::InterpreterFra
 
 inline InterpreterFrames::~InterpreterFrames()
 {
     context->runtime->interpreterFrames = older;
 }
 
 #if defined(DEBUG) && !defined(JS_THREADSAFE) && !defined(JSGC_ROOT_ANALYSIS)
 void
-js::AssertValidPropertyCacheHit(JSContext *cx,
-                                JSObject *start_, JSObject *found,
-                                PropertyCacheEntry *entry)
+js::AssertValidPropertyCacheHit(JSContext *cx, JSObject *start_,
+                                JSObject *found, PropertyCacheEntry *entry)
 {
     jsbytecode *pc;
-    cx->stack.currentScript(&pc);
+    JSScript *script = cx->stack.currentScript(&pc);
 
     uint64_t sample = cx->runtime->gcNumber;
     PropertyCacheEntry savedEntry = *entry;
 
-    RootedPropertyName name(cx, GetNameFromBytecode(cx, pc, JSOp(*pc)));
+    RootedPropertyName name(cx, GetNameFromBytecode(cx, script, pc, JSOp(*pc)));
     RootedObject start(cx, start_);
 
     JSObject *obj, *pobj;
     JSProperty *prop;
     JSBool ok;
 
     if (JOF_OPMODE(*pc) == JOF_NAME)
         ok = FindProperty(cx, name, start, &obj, &pobj, &prop);
@@ -2325,17 +2324,17 @@ BEGIN_CASE(JSOP_THIS)
 END_CASE(JSOP_THIS)
 
 BEGIN_CASE(JSOP_GETPROP)
 BEGIN_CASE(JSOP_GETXPROP)
 BEGIN_CASE(JSOP_LENGTH)
 BEGIN_CASE(JSOP_CALLPROP)
 {
     RootedValue rval(cx);
-    if (!GetPropertyOperation(cx, regs.pc, regs.sp[-1], rval.address()))
+    if (!GetPropertyOperation(cx, script, regs.pc, regs.sp[-1], rval.address()))
         goto error;
 
     TypeScript::Monitor(cx, script, regs.pc, rval.reference());
 
     regs.sp[-1] = rval;
     assertSameCompartment(cx, regs.sp[-1]);
 }
 END_CASE(JSOP_GETPROP)
@@ -2537,17 +2536,17 @@ END_CASE(JSOP_IMPLICITTHIS)
 
 BEGIN_CASE(JSOP_GETGNAME)
 BEGIN_CASE(JSOP_CALLGNAME)
 BEGIN_CASE(JSOP_NAME)
 BEGIN_CASE(JSOP_CALLNAME)
 {
     RootedValue &rval = rootValue0;
 
-    if (!NameOperation(cx, regs.pc, rval.address()))
+    if (!NameOperation(cx, script, regs.pc, rval.address()))
         goto error;
 
     PUSH_COPY(rval);
     TypeScript::Monitor(cx, script, regs.pc, rval);
 }
 END_CASE(JSOP_NAME)
 
 BEGIN_CASE(JSOP_UINT16)
--- a/js/src/jsinterpinlines.h
+++ b/js/src/jsinterpinlines.h
@@ -161,17 +161,18 @@ GetPropertyGenericMaybeCallXML(JSContext
     if (op == JSOP_CALLPROP && obj->isXML())
         return js_GetXMLMethod(cx, obj, id, vp);
 #endif
 
     return obj->getGeneric(cx, id, vp);
 }
 
 inline bool
-GetPropertyOperation(JSContext *cx, jsbytecode *pc, const Value &lval, Value *vp)
+GetPropertyOperation(JSContext *cx, JSScript *script, jsbytecode *pc,
+                     const Value &lval, Value *vp)
 {
     JS_ASSERT(vp != &lval);
 
     JSOp op = JSOp(*pc);
 
     if (op == JSOP_LENGTH) {
         /* Optimize length accesses on strings, arrays, and arguments. */
         if (lval.isString()) {
@@ -315,17 +316,17 @@ SetPropertyOperation(JSContext *cx, jsby
         if (!obj->setGeneric(cx, id, rref.address(), strict))
             return false;
     }
 
     return true;
 }
 
 inline bool
-NameOperation(JSContext *cx, jsbytecode *pc, Value *vp)
+NameOperation(JSContext *cx, JSScript *script, jsbytecode *pc, Value *vp)
 {
     RootedObject obj(cx, cx->stack.currentScriptedScopeChain());
 
     /*
      * Skip along the scope chain to the enclosing global object. This is
      * used for GNAME opcodes where the bytecode emitter has determined a
      * name access must be on the global. It also insulates us from bugs
      * in the emitter: type inference will assume that GNAME opcodes are
--- a/js/src/jsopcodeinlines.h
+++ b/js/src/jsopcodeinlines.h
@@ -6,27 +6,26 @@
 
 #include "jsautooplen.h"
 
 #include "frontend/BytecodeEmitter.h"
 
 namespace js {
 
 static inline PropertyName *
-GetNameFromBytecode(JSContext *cx, jsbytecode *pc, JSOp op)
+GetNameFromBytecode(JSContext *cx, JSScript *script, jsbytecode *pc, JSOp op)
 {
     if (op == JSOP_LENGTH)
         return cx->runtime->atomState.lengthAtom;
 
     // The method JIT's implementation of instanceof contains an internal lookup
     // of the prototype property.
     if (op == JSOP_INSTANCEOF)
         return cx->runtime->atomState.classPrototypeAtom;
 
-    JSScript *script = cx->stack.currentScriptWithDiagnostics();
     PropertyName *name;
     GET_NAME_FROM_BYTECODE(script, pc, 0, name);
     return name;
 }
 
 class BytecodeRange {
   public:
     BytecodeRange(JSScript *script)
--- a/js/src/jspropertycache.cpp
+++ b/js/src/jspropertycache.cpp
@@ -117,32 +117,30 @@ PropertyCache::fill(JSContext *cx, JSObj
     return entry;
 }
 
 PropertyName *
 PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject **pobjp,
                         PropertyCacheEntry *entry)
 {
     JSObject *obj, *pobj, *tmp;
-#ifdef DEBUG
     JSScript *script = cx->stack.currentScript();
-#endif
 
     JS_ASSERT(this == &JS_PROPERTY_CACHE(cx));
     JS_ASSERT(uint32_t(pc - script->code) < script->length);
 
     JSOp op = JSOp(*pc);
     const JSCodeSpec &cs = js_CodeSpec[op];
 
     obj = *objp;
 
     if (entry->kpc != pc) {
         PCMETER(kpcmisses++);
 
-        PropertyName *name = GetNameFromBytecode(cx, pc, op);
+        PropertyName *name = GetNameFromBytecode(cx, script, pc, op);
 #ifdef DEBUG_notme
         JSAutoByteString printable;
         fprintf(stderr,
                 "id miss for %s from %s:%u"
                 " (pc %u, kpc %u, kshape %p, shape %p)\n",
                 js_AtomToPrintableString(cx, name, &printable),
                 script->filename,
                 js_PCToLineNumber(cx, script, pc),
@@ -155,17 +153,17 @@ PropertyCache::fullTest(JSContext *cx, j
                                 JS_FALSE, stderr);
 #endif
 
         return name;
     }
 
     if (entry->kshape != obj->lastProperty()) {
         PCMETER(kshapemisses++);
-        return GetNameFromBytecode(cx, pc, op);
+        return GetNameFromBytecode(cx, script, pc, op);
     }
 
     /*
      * PropertyCache::test handles only the direct and immediate-prototype hit
      * cases. All others go here.
      */
     pobj = obj;
 
@@ -188,25 +186,25 @@ PropertyCache::fullTest(JSContext *cx, j
         if (!tmp || !tmp->isNative())
             break;
         pobj = tmp;
         protoIndex--;
     }
 
     if (pobj->lastProperty() == entry->pshape) {
 #ifdef DEBUG
-        PropertyName *name = GetNameFromBytecode(cx, pc, op);
+        PropertyName *name = GetNameFromBytecode(cx, script, pc, op);
         JS_ASSERT(pobj->nativeContains(cx, NameToId(name)));
 #endif
         *pobjp = pobj;
         return NULL;
     }
 
     PCMETER(vcapmisses++);
-    return GetNameFromBytecode(cx, pc, op);
+    return GetNameFromBytecode(cx, script, pc, op);
 }
 
 #ifdef DEBUG
 void
 PropertyCache::assertEmpty()
 {
     JS_ASSERT(empty);
     for (unsigned i = 0; i < SIZE; i++) {
--- a/js/src/methodjit/PolyIC.cpp
+++ b/js/src/methodjit/PolyIC.cpp
@@ -1919,17 +1919,17 @@ ic::GetProp(VMFrame &f, ic::PICInfo *pic
     if (!monitor.recompiled() && pic->shouldUpdate(f.cx)) {
         GetPropCompiler cc(f, script, obj, *pic, name, stub);
         if (!cc.update())
             THROW();
     }
 
     Value v;
     if (cached) {
-        if (!GetPropertyOperation(f.cx, f.pc(), f.regs.sp[-1], &v))
+        if (!GetPropertyOperation(f.cx, f.script(), f.pc(), f.regs.sp[-1], &v))
             THROW();
     } else {
         if (!obj->getProperty(f.cx, name, &v))
             THROW();
     }
 
     f.regs.sp[-1] = v;
 }
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -93,17 +93,17 @@ stubs::SetGlobalName(VMFrame &f, Propert
 
 template void JS_FASTCALL stubs::SetGlobalName<true>(VMFrame &f, PropertyName *name);
 template void JS_FASTCALL stubs::SetGlobalName<false>(VMFrame &f, PropertyName *name);
 
 void JS_FASTCALL
 stubs::Name(VMFrame &f)
 {
     Value rval;
-    if (!NameOperation(f.cx, f.pc(), &rval))
+    if (!NameOperation(f.cx, f.script(), f.pc(), &rval))
         THROW();
     f.regs.sp[0] = rval;
 }
 
 void JS_FASTCALL
 stubs::GetElem(VMFrame &f)
 {
     Value &lref = f.regs.sp[-2];
@@ -975,17 +975,17 @@ stubs::Lambda(VMFrame &f, JSFunction *fu
 
 void JS_FASTCALL
 stubs::GetProp(VMFrame &f, PropertyName *name)
 {
     JSContext *cx = f.cx;
     FrameRegs &regs = f.regs;
 
     Value rval;
-    if (!GetPropertyOperation(cx, f.pc(), f.regs.sp[-1], &rval))
+    if (!GetPropertyOperation(cx, f.script(), f.pc(), f.regs.sp[-1], &rval))
         THROW();
 
     regs.sp[-1] = rval;
 }
 
 void JS_FASTCALL
 stubs::GetPropNoCache(VMFrame &f, PropertyName *name)
 {
--- a/js/src/vm/Stack-inl.h
+++ b/js/src/vm/Stack-inl.h
@@ -552,55 +552,16 @@ ContextStack::currentScript(jsbytecode *
     if (script->compartment() != cx_->compartment)
         return NULL;
 
     if (ppc)
         *ppc = fp->pcQuadratic(*this);
     return script;
 }
 
-inline JSScript *
-ContextStack::currentScriptWithDiagnostics(jsbytecode **ppc) const
-{
-    if (ppc)
-        *ppc = NULL;
-
-    FrameRegs *regs = maybeRegs();
-    StackFrame *fp = regs ? regs->fp() : NULL;
-    while (fp && fp->isDummyFrame())
-        fp = fp->prev();
-    if (!fp)
-        *(int *) 0x10 = 0;
-
-#ifdef JS_METHODJIT
-    mjit::CallSite *inlined = regs->inlined();
-    if (inlined) {
-        mjit::JITChunk *chunk = fp->jit()->chunk(regs->pc);
-        JS_ASSERT(inlined->inlineIndex < chunk->nInlineFrames);
-        mjit::InlineFrame *frame = &chunk->inlineFrames()[inlined->inlineIndex];
-        JSScript *script = frame->fun->script();
-        if (script->compartment() != cx_->compartment)
-            *(int *) 0x20 = 0;
-        if (ppc)
-            *ppc = script->code + inlined->pcOffset;
-        return script;
-    }
-#endif
-
-    JSScript *script = fp->script();
-    if (script->compartment() != cx_->compartment)
-        *(int *) 0x30 = 0;
-
-    if (ppc)
-        *ppc = fp->pcQuadratic(*this);
-    if (!script)
-        *(int *) 0x40 = 0;
-    return script;
-}
-
 inline HandleObject
 ContextStack::currentScriptedScopeChain() const
 {
     return fp()->scopeChain();
 }
 
 } /* namespace js */
 #endif /* Stack_inl_h__ */
--- a/js/src/vm/Stack.h
+++ b/js/src/vm/Stack.h
@@ -1655,17 +1655,16 @@ class ContextStack
                          InitialFrameFlags initial, Value **stackLimit);
     void popInlineFrame(FrameRegs &regs);
 
     /* Pop a partially-pushed frame after hitting the limit before throwing. */
     void popFrameAfterOverflow();
 
     /* Get the topmost script and optional pc on the stack. */
     inline JSScript *currentScript(jsbytecode **pc = NULL) const;
-    inline JSScript *currentScriptWithDiagnostics(jsbytecode **pc = NULL) const;
 
     /* Get the scope chain for the topmost scripted call on the stack. */
     inline HandleObject currentScriptedScopeChain() const;
 
     /*
      * Called by the methodjit for an arity mismatch. Arity mismatch can be
      * hot, so getFixupFrame avoids doing call setup performed by jit code when
      * FixupArity returns.
--- a/js/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/xpconnect/loader/mozJSComponentLoader.cpp
@@ -171,17 +171,17 @@ Dump(JSContext *cx, unsigned argc, jsval
 
     size_t length;
     const jschar *chars = JS_GetStringCharsAndLength(cx, str, &length);
     if (!chars)
         return false;
 
     NS_ConvertUTF16toUTF8 utf8str(reinterpret_cast<const PRUnichar*>(chars));
 #ifdef ANDROID
-    __android_log_print(ANDROID_LOG_INFO, "Gecko", utf8str.get());
+    __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", utf8str.get());
 #endif
     fputs(utf8str.get(), stdout);
     fflush(stdout);
     return true;
 }
 
 static JSBool
 Debug(JSContext *cx, unsigned argc, jsval *vp)
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -418,17 +418,17 @@ Dump(JSContext *cx, unsigned argc, jsval
     if (!str)
         return false;
 
     JSAutoByteString bytes(cx, str);
     if (!bytes)
         return false;
 
 #ifdef ANDROID
-    __android_log_print(ANDROID_LOG_INFO, "Gecko", bytes.ptr());
+    __android_log_print(ANDROID_LOG_INFO, "Gecko", "%s", bytes.ptr());
 #endif
     fputs(bytes.ptr(), gOutFile);
     fflush(gOutFile);
     return true;
 }
 
 static JSBool
 Load(JSContext *cx, unsigned argc, jsval *vp)
@@ -1376,30 +1376,16 @@ FullTrustSecMan::CanExecuteScripts(JSCon
 /* [noscript] nsIPrincipal getSubjectPrincipal (); */
 NS_IMETHODIMP
 FullTrustSecMan::GetSubjectPrincipal(nsIPrincipal **_retval)
 {
     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     return *_retval ? NS_OK : NS_ERROR_FAILURE;
 }
 
-/* [noscript] void pushContextPrincipal (in JSContextPtr cx, in JSStackFramePtr fp, in nsIPrincipal principal); */
-NS_IMETHODIMP
-FullTrustSecMan::PushContextPrincipal(JSContext * cx, JSStackFrame * fp, nsIPrincipal *principal)
-{
-    return NS_OK;
-}
-
-/* [noscript] void popContextPrincipal (in JSContextPtr cx); */
-NS_IMETHODIMP
-FullTrustSecMan::PopContextPrincipal(JSContext * cx)
-{
-    return NS_OK;
-}
-
 /* [noscript] nsIPrincipal getSystemPrincipal (); */
 NS_IMETHODIMP
 FullTrustSecMan::GetSystemPrincipal(nsIPrincipal **_retval)
 {
     NS_IF_ADDREF(*_retval = mSystemPrincipal);
     return *_retval ? NS_OK : NS_ERROR_FAILURE;
 }
 
--- a/js/xpconnect/src/XPCWrappedJSClass.cpp
+++ b/js/xpconnect/src/XPCWrappedJSClass.cpp
@@ -1107,27 +1107,16 @@ nsXPCWrappedJSClass::CheckForException(X
         // see if JS code signaled failure result without throwing exception
         if (NS_FAILED(pending_result)) {
             return pending_result;
         }
     }
     return NS_ERROR_FAILURE;
 }
 
-class ContextPrincipalGuard
-{
-    nsIScriptSecurityManager *ssm;
-    XPCCallContext &ccx;
-  public:
-    ContextPrincipalGuard(XPCCallContext &ccx)
-      : ssm(nsnull), ccx(ccx) {}
-    void principalPushed(nsIScriptSecurityManager *ssm) { this->ssm = ssm; }
-    ~ContextPrincipalGuard() { if (ssm) ssm->PopContextPrincipal(ccx); }
-};
-
 NS_IMETHODIMP
 nsXPCWrappedJSClass::CallMethod(nsXPCWrappedJS* wrapper, uint16_t methodIndex,
                                 const XPTMethodDescriptor* info,
                                 nsXPTCMiniVariant* nativeParams)
 {
     jsval* sp = nsnull;
     jsval* argv = nsnull;
     uint8_t i;
@@ -1161,53 +1150,29 @@ nsXPCWrappedJSClass::CallMethod(nsXPCWra
     JSAutoEnterCompartment ac;
     if (!ac.enter(cx, obj))
         return NS_ERROR_FAILURE;
 
     ccx.SetScopeForNewJSObjects(obj);
 
     JS::AutoValueVector args(cx);
     AutoScriptEvaluate scriptEval(cx);
-    ContextPrincipalGuard principalGuard(ccx);
 
     // XXX ASSUMES that retval is last arg. The xpidl compiler ensures this.
     uint8_t paramCount = info->num_args;
     uint8_t argc = paramCount -
         (paramCount && XPT_PD_IS_RETVAL(info->params[paramCount-1].flags) ? 1 : 0);
 
     if (!scriptEval.StartEvaluating(obj, xpcWrappedJSErrorReporter))
         goto pre_call_clean_up;
 
     xpcc->SetPendingResult(pending_result);
     xpcc->SetException(nsnull);
     XPCJSRuntime::Get()->SetPendingException(nsnull);
 
-    // This scoping is necessary due to the gotos here. Ugh.
-    {
-        // TODO Remove me in favor of security wrappers.
-        nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
-        if (ssm) {
-            nsIPrincipal *objPrincipal =
-                xpc::AccessCheck::getPrincipal(js::GetObjectCompartment(obj));
-            if (objPrincipal) {
-                JSStackFrame* fp = nsnull;
-                nsresult rv =
-                    ssm->PushContextPrincipal(ccx, JS_FrameIterator(ccx, &fp),
-                                              objPrincipal);
-                if (NS_FAILED(rv)) {
-                    JS_ReportOutOfMemory(ccx);
-                    retval = NS_ERROR_OUT_OF_MEMORY;
-                    goto pre_call_clean_up;
-                }
-
-                principalGuard.principalPushed(ssm);
-            }
-        }
-    }
-
     // We use js_Invoke so that the gcthings we use as args will be rooted by
     // the engine as we do conversions and prepare to do the function call.
 
     // setup stack
 
     // if this isn't a function call then we don't need to push extra stuff
     if (!(XPT_MD_IS_SETTER(info->flags) || XPT_MD_IS_GETTER(info->flags))) {
         // We get fval before allocating the stack to avoid gc badness that can
--- a/js/xpconnect/wrappers/CrossOriginWrapper.cpp
+++ b/js/xpconnect/wrappers/CrossOriginWrapper.cpp
@@ -10,25 +10,17 @@
 #include "XPCWrapper.h"
 
 #include "CrossOriginWrapper.h"
 #include "AccessCheck.h"
 #include "WrapperFactory.h"
 
 namespace xpc {
 
-NoWaiverWrapper::NoWaiverWrapper(unsigned flags) : js::CrossCompartmentWrapper(flags)
-{
-}
-
-NoWaiverWrapper::~NoWaiverWrapper()
-{
-}
-
-CrossOriginWrapper::CrossOriginWrapper(unsigned flags) : NoWaiverWrapper(flags)
+CrossOriginWrapper::CrossOriginWrapper(unsigned flags) : js::CrossCompartmentWrapper(flags)
 {
 }
 
 CrossOriginWrapper::~CrossOriginWrapper()
 {
 }
 
 bool
@@ -65,41 +57,9 @@ CrossOriginWrapper::call(JSContext *cx, 
 bool
 CrossOriginWrapper::construct(JSContext *cx, JSObject *wrapper,
                               unsigned argc, js::Value *argv, js::Value *rval)
 {
     return CrossCompartmentWrapper::construct(cx, wrapper, argc, argv, rval) &&
            WrapperFactory::WaiveXrayAndWrap(cx, rval);
 }
 
-bool
-NoWaiverWrapper::enter(JSContext *cx, JSObject *wrapper, jsid id, Action act, bool *bp)
-{
-    *bp = true; // always allowed
-    nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
-    if (!ssm) {
-        return true;
-    }
-
-    // Note: By the time enter is called here, CrossCompartmentWrapper has
-    // already pushed the fake stack frame onto cx. Because of this, the frame
-    // that we're clamping is the one that we want (the one in our compartment).
-    JSStackFrame *fp = NULL;
-    nsIPrincipal *principal = GetCompartmentPrincipal(js::GetObjectCompartment(wrappedObject(wrapper)));
-    nsresult rv = ssm->PushContextPrincipal(cx, JS_FrameIterator(cx, &fp), principal);
-    if (NS_FAILED(rv)) {
-        NS_WARNING("Not allowing call because we're out of memory");
-        JS_ReportOutOfMemory(cx);
-        return false;
-    }
-    return true;
 }
-
-void
-NoWaiverWrapper::leave(JSContext *cx, JSObject *wrapper)
-{
-    nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager();
-    if (ssm) {
-        ssm->PopContextPrincipal(cx);
-    }
-}
-
-}
--- a/js/xpconnect/wrappers/CrossOriginWrapper.h
+++ b/js/xpconnect/wrappers/CrossOriginWrapper.h
@@ -10,28 +10,17 @@
 
 #include "mozilla/Attributes.h"
 
 #include "jsapi.h"
 #include "jswrapper.h"
 
 namespace xpc {
 
-class NoWaiverWrapper : public js::CrossCompartmentWrapper {
-  public:
-    NoWaiverWrapper(unsigned flags);
-    virtual ~NoWaiverWrapper();
-
-    virtual bool enter(JSContext *cx, JSObject *wrapper, jsid id, Action act, bool *bp) MOZ_OVERRIDE;
-    virtual void leave(JSContext *cx, JSObject *wrapper) MOZ_OVERRIDE;
-
-    static NoWaiverWrapper singleton;
-};
-
-class CrossOriginWrapper : public NoWaiverWrapper {
+class CrossOriginWrapper : public js::CrossCompartmentWrapper {
   public:
     CrossOriginWrapper(unsigned flags);
     virtual ~CrossOriginWrapper();
 
     virtual bool getPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id,
                                        bool set, js::PropertyDescriptor *desc) MOZ_OVERRIDE;
     virtual bool getOwnPropertyDescriptor(JSContext *cx, JSObject *wrapper, jsid id,
                                           bool set, js::PropertyDescriptor *desc) MOZ_OVERRIDE;
--- a/js/xpconnect/wrappers/WrapperFactory.cpp
+++ b/js/xpconnect/wrappers/WrapperFactory.cpp
@@ -26,23 +26,16 @@ namespace xpc {
 // .wrappedJSObject, we want it to cross the membrane into the
 // chrome compartment without automatically being wrapped into an
 // X-ray wrapper. We achieve this by wrapping it into a special
 // transparent wrapper in the origin (non-chrome) compartment. When
 // an object with that special wrapper applied crosses into chrome,
 // we know to not apply an X-ray wrapper.
 DirectWrapper WaiveXrayWrapperWrapper(WrapperFactory::WAIVE_XRAY_WRAPPER_FLAG);
 
-// Objects that haven't been explicitly waived, but have been exposed
-// to chrome don't want a CrossOriginWrapper, since that deeply-waives
-// but need the transparent behavior of a CrossOriginWrapper. The
-// NoWaiverWrapper is like a CrossOriginWrapper that can also hand out
-// XrayWrappers as return values.
-NoWaiverWrapper NoWaiverWrapper::singleton(0);
-
 // When objects for which we waived the X-ray wrapper cross into
 // chrome, we wrap them into a special cross-compartment wrapper
 // that transitively extends the waiver to all properties we get
 // off it.
 CrossOriginWrapper CrossOriginWrapper::singleton(0);
 
 static JSObject *
 GetCurrentOuter(JSContext *cx, JSObject *obj)
@@ -336,17 +329,17 @@ WrapperFactory::Rewrap(JSContext *cx, JS
                     wrapper = &XrayDOM::singleton;
                 } else if (type == XrayForDOMProxyObject) {
                     wrapper = &XrayProxy::singleton;
                 } else if (type == XrayForWrappedNative) {
                     typedef XrayWrapper<CrossCompartmentWrapper> Xray;
                     usingXray = true;
                     wrapper = &Xray::singleton;
                 } else {
-                    wrapper = &NoWaiverWrapper::singleton;
+                    wrapper = &CrossCompartmentWrapper::singleton;
                 }
             }
         }
     } else if (AccessCheck::isChrome(origin)) {
         JSFunction *fun = JS_GetObjectFunction(obj);
         if (fun) {
             if (JS_IsBuiltinEvalFunction(fun) || JS_IsBuiltinFunctionConstructor(fun)) {
                 JS_ReportError(cx, "Not allowed to access chrome eval or Function from content");
--- a/layout/base/nsDisplayItemTypes.h
+++ b/layout/base/nsDisplayItemTypes.h
@@ -51,17 +51,17 @@ enum Type {
   TYPE_PRINT_PLUGIN,
   TYPE_REMOTE,
   TYPE_REMOTE_SHADOW,
   TYPE_SCROLL_LAYER,
   TYPE_SCROLL_INFO_LAYER,
   TYPE_SELECTION_OVERLAY,
   TYPE_SOLID_COLOR,
   TYPE_SVG_EFFECTS,
-  TYPE_SVG_EVENT_RECEIVER,
+  TYPE_SVG_OUTER_SVG,
   TYPE_TABLE_CELL_BACKGROUND,
   TYPE_TABLE_CELL_SELECTION,
   TYPE_TABLE_ROW_BACKGROUND,
   TYPE_TABLE_ROW_GROUP_BACKGROUND,
   TYPE_TABLE_BORDER_BACKGROUND,
   TYPE_TEXT,
   TYPE_TEXT_DECORATION,
   TYPE_TEXT_OVERFLOW,
--- a/layout/reftests/font-face/local-1-ref.html
+++ b/layout/reftests/font-face/local-1-ref.html
@@ -2,17 +2,18 @@
 <html>
 <head>
 	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 	<meta http-equiv="Content-Style-Type" content="text/css">
 	<title>test src: local() reference</title>
 	<style type="text/css">
 	  body {
 	    font-family: Nimbus Sans L, Helvetica, Bitstream Vera Sans,
-                         Arial, Liberation Sans, SwissA, serif;
+                         Arial, Liberation Sans, SwissA,
+                         Droid Sans, Roboto, serif;
 	  }
 	</style>
 </head>
 <body>
   <p style="font-weight: normal;">
     The quick brown fox jumped over the lazy dog
   </p>
   <p style="font-weight: bold;">
--- a/layout/reftests/font-face/local-1.html
+++ b/layout/reftests/font-face/local-1.html
@@ -29,25 +29,27 @@
 	  obvious.
 
 	  -->
 	<style type="text/css">
 	  @font-face {
 	     font-family: "Local";
 	     src: local(Nimbus Sans L), local(NimbusSansL-Regu),
 	          local(Helvetica), local(Bitstream Vera Sans),
-	          local(Arial), local(Liberation Sans), local(SwissA);
+	          local(Arial), local(Liberation Sans), local(SwissA),
+	          local(Droid Sans), local(Roboto);
 	     font-weight: 100;
 	  }
 	  @font-face {
 	     font-family: "Local";
 	     src: local(Nimbus Sans L Bold), local(NimbusSansL-Bold),
 	          local(Helvetica Bold), local(Helvetica-Bold),
                   local(Bitstream Vera Sans  Bold),
-	          local(Arial Bold), local(Liberation Sans Bold), local(SwissA Bold);
+	          local(Arial Bold), local(Liberation Sans Bold), local(SwissA Bold),
+	          local(Droid Sans Bold), local(Roboto Bold);
 	     font-weight: normal;
 	  }
 	  body { font-family: Local, serif }
 	</style>
 </head>
 <body>
   <p style="font-weight: 100">
     The quick brown fox jumped over the lazy dog
new file mode 100644
--- /dev/null
+++ b/layout/reftests/font-face/local-styled-1-ref.html
@@ -0,0 +1,33 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style type="text/css">
+@font-face {
+  font-family: test;
+  src: local(Nimbus Sans L), local(NimbusSansL-Regu),
+       local(Helvetica), local(Bitstream Vera Sans),
+       local(Arial), local(Liberation Sans), local(SwissA),
+       local(Droid Sans), local(Roboto);
+}
+div {
+  font-family: test, serif;
+  margin: 10px;
+}
+</style>
+</head>
+<body>
+<div style="font-family:serif">
+This serif font should NOT be used below.
+</div>
+<hr>
+<div>
+These three lines should all use the same font face.
+</div>
+<div>
+This line should NOT be bold.
+</div>
+<div>
+This line should NOT be italic.
+</div>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/font-face/local-styled-1.html
@@ -0,0 +1,49 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style type="text/css">
+@font-face {
+  font-family: test;
+  src: local(Nimbus Sans L), local(NimbusSansL-Regu),
+       local(Helvetica), local(Bitstream Vera Sans),
+       local(Arial), local(Liberation Sans), local(SwissA),
+       local(Droid Sans), local(Roboto);
+}
+@font-face {
+  font-family: test;
+  font-style: italic;
+  src: local(Nimbus Sans L), local(NimbusSansL-Regu),
+       local(Helvetica), local(Bitstream Vera Sans),
+       local(Arial), local(Liberation Sans), local(SwissA),
+       local(Droid Sans), local(Roboto);
+}
+@font-face {
+  font-family: test;
+  font-weight: bold;
+  src: local(Nimbus Sans L), local(NimbusSansL-Regu),
+       local(Helvetica), local(Bitstream Vera Sans),
+       local(Arial), local(Liberation Sans), local(SwissA),
+       local(Droid Sans), local(Roboto);
+}
+div {
+  font-family: test, serif;
+  margin: 10px;
+}
+</style>
+</head>
+<body>
+<div style="font-family:serif">
+This serif font should NOT be used below.
+</div>
+<hr>
+<div>
+These three lines should all use the same font face.
+</div>
+<div>
+<b>This line should NOT be bold.</b>
+</div>
+<div>
+<i>This line should NOT be italic.</i>
+</div>
+</body>
+</html>
--- a/layout/reftests/font-face/reftest.list
+++ b/layout/reftests/font-face/reftest.list
@@ -89,17 +89,20 @@ HTTP(..) == ahem-metrics-1.html ahem-met
 HTTP(..) == ex-unit-1.html ex-unit-1-ref.html
 HTTP(..) == ex-unit-1-dynamic.html ex-unit-1-ref.html
 
 # bug 493976 - for some reason the Arabic tests below cause Tinderbox timeouts
 # Arabic support requires AAT fonts under Mac OS, OpenType otherwise
 # random-if(!cocoaWidget) HTTP(..) == src-format-arabic.html src-format-arabic-aat-ref.html
 # random-if(cocoaWidget) HTTP(..) == src-format-arabic.html src-format-arabic-ot-ref.html
 
+# bug 769194 - src:local() completely broken on android
 fails-if(Android) == local-1.html local-1-ref.html
+fails-if(Android) == local-styled-1.html local-styled-1-ref.html
+
 HTTP(..) == synthetic-weight-style.html synthetic-weight-style-ref.html
 HTTP(..) == synthetic-variations.html synthetic-variations-ref.html
 
 # Leak test
 HTTP(..) load 486974-1.html
 
 # compare fonts with and without bad head checksum
 HTTP(..) == load-badchecksum.html load-badchecksum-ref.html
--- a/layout/reftests/position-dynamic-changes/relative/reftest.list
+++ b/layout/reftests/position-dynamic-changes/relative/reftest.list
@@ -1,4 +1,4 @@
-fuzzy-if(d2d,85,20) == move-right-bottom.html move-right-bottom-ref.html # Bug 742176
+random-if(cocoaWidget) fuzzy-if(d2d,85,20) == move-right-bottom.html move-right-bottom-ref.html # Bug 742176
 random-if(cocoaWidget) fuzzy-if(d2d,85,20) == move-top-left.html move-top-left-ref.html # Bug 688545, bug 742176
-fuzzy-if(d2d,85,20) == move-right-bottom-table.html move-right-bottom-table-ref.html # Bug 742176
+random-if(cocoaWidget) fuzzy-if(d2d,85,20) == move-right-bottom-table.html move-right-bottom-table-ref.html # Bug 742176
 random-if(cocoaWidget) fuzzy-if(d2d,85,20) == move-top-left-table.html move-top-left-table-ref.html # Bug 688545, bug 742176
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/svg-integration/mask-transformed-html-01.xhtml
@@ -0,0 +1,42 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <title>Test SVG masking of transformed HTML elements</title>
+  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=769103 -->
+  <style type="text/css">
+
+* { margin: 0; border: 0; padding: 0;}
+
+div {
+  position: absolute;
+  left: 1px;
+  top: 1px;
+  width: 3px;
+  height: 3px;
+  -moz-transform: scale(100,100);
+  -moz-transform-origin: 0 0;
+}
+
+  </style>
+</head>
+<body bgcolor="lime">
+
+  <svg xmlns="http://www.w3.org/2000/svg" width="300" height="300"
+       style="display:block; position:absolute;">
+    <mask id="mask1" x="0" y="0" width="1" height="1" maskContentUnits="objectBoundingBox">
+      <circle cx="0.5" cy="0.5" r="0.48" fill="white"/>
+    </mask>
+    <mask id="mask2" x="0" y="0" width="1" height="1" maskContentUnits="objectBoundingBox">
+      <circle cx="0.5" cy="0.5" r="0.5" fill="white"/>
+    </mask>
+    <circle cx="150" cy="150" r="147" fill="red"/>
+  </svg>
+
+  <div style="background: red; mask: url(#mask1);"/>
+  <div style="background: lime; mask: url(#mask2);"/>
+
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/svg/svg-integration/mask-transformed-html-02.xhtml
@@ -0,0 +1,42 @@
+<!--
+     Any copyright is dedicated to the Public Domain.
+     http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+  <title>Test SVG masking of transformed HTML elements</title>
+  <!-- From https://bugzilla.mozilla.org/show_bug.cgi?id=769103 -->
+  <style type="text/css">
+
+* { margin: 0; border: 0; padding: 0;}
+
+div {
+  position: absolute;
+  left: 50px;
+  top: 50px;
+  width: 150px;
+  height: 150px;
+  -moz-transform: scale(2,2);
+  -moz-transform-origin: 0 0;
+}
+
+  </style>
+</head>
+<body bgcolor="lime">
+
+  <svg xmlns="http://www.w3.org/2000/svg" width="350" height="350"
+       style="display:block; position:absolute;">
+    <mask id="mask1" x="0" y="0" width="1" height="1" maskContentUnits="objectBoundingBox">
+      <circle cx="0.5" cy="0.5" r="0.48" fill="white"/>
+    </mask>
+    <mask id="mask2" x="0" y="0" width="1" height="1" maskContentUnits="objectBoundingBox">
+      <circle cx="0.5" cy="0.5" r="0.50" fill="white"/>
+    </mask>
+    <circle cx="200" cy="200" r="147" fill="red"/>
+  </svg>
+
+  <div style="background: red; mask: url(#mask1);"/>
+  <div style="background: lime; mask: url(#mask2);"/>
+
+</body>
+</html>
--- a/layout/reftests/svg/svg-integration/reftest.list
+++ b/layout/reftests/svg/svg-integration/reftest.list
@@ -20,8 +20,12 @@
 == filter-html-01.xhtml filter-html-01-ref.svg
 == filter-html-01-extref.xhtml filter-html-01-ref.svg
 == filter-html-zoomed-01.xhtml filter-html-01-ref.svg
 == mask-html-01.xhtml mask-html-01-ref.svg
 == mask-html-01-extref-01.xhtml mask-html-01-ref.svg
 == mask-html-01-extref-02.xhtml mask-html-01-ref.svg
 == mask-html-zoomed-01.xhtml mask-html-01-ref.svg
 == mask-html-xbl-bound-01.html mask-html-01-ref.svg
+== mask-transformed-html-01.xhtml ../pass.svg
+== mask-transformed-html-02.xhtml ../pass.svg
+
+
--- a/layout/svg/base/src/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/base/src/nsSVGIntegrationUtils.cpp
@@ -358,23 +358,23 @@ private:
   nsDisplayListBuilder* mBuilder;
   nsDisplayList* mInnerList;
   nsIFrame* mFrame;
   nsPoint mOffset;
 };
 
 void
 nsSVGIntegrationUtils::PaintFramesWithEffects(nsRenderingContext* aCtx,
-                                              nsIFrame* aEffectsFrame,
+                                              nsIFrame* aFrame,
                                               const nsRect& aDirtyRect,
                                               nsDisplayListBuilder* aBuilder,
                                               nsDisplayList* aInnerList)
 {
 #ifdef DEBUG
-  nsISVGChildFrame *svgChildFrame = do_QueryFrame(aEffectsFrame);
+  nsISVGChildFrame *svgChildFrame = do_QueryFrame(aFrame);
   NS_ASSERTION(!svgChildFrame, "Should never be called on an SVG frame");
 #endif
 
   /* SVG defines the following rendering model:
    *
    *  1. Render geometry
    *  2. Apply filter
    *  3. Apply clipping, masking, group opacity
@@ -382,25 +382,25 @@ nsSVGIntegrationUtils::PaintFramesWithEf
    * We follow this, but perform a couple of optimizations:
    *
    * + Use cairo's clipPath when representable natively (single object
    *   clip region).
    *
    * + Merge opacity and masking if both used together.
    */
 
-  float opacity = aEffectsFrame->GetStyleDisplay()->mOpacity;
+  float opacity = aFrame->GetStyleDisplay()->mOpacity;
   if (opacity == 0.0f) {
     return;
   }
 
   /* Properties are added lazily and may have been removed by a restyle,
      so make sure all applicable ones are set again. */
   nsIFrame* firstFrame =
-    nsLayoutUtils::GetFirstContinuationOrSpecialSibling(aEffectsFrame);
+    nsLayoutUtils::GetFirstContinuationOrSpecialSibling(aFrame);
   nsSVGEffects::EffectProperties effectProperties =
     nsSVGEffects::GetEffectProperties(firstFrame);
 
   bool isOK = true;
   nsSVGClipPathFrame *clipPathFrame = effectProperties.GetClipPathFrame(&isOK);
   nsSVGFilterFrame *filterFrame = effectProperties.GetFilterFrame(&isOK);
   nsSVGMaskFrame *maskFrame = effectProperties.GetMaskFrame(&isOK);
   if (!isOK) {
@@ -408,76 +408,76 @@ nsSVGIntegrationUtils::PaintFramesWithEf
   }
 
   bool isTrivialClip = clipPathFrame ? clipPathFrame->IsTrivial() : true;
 
   gfxContext* gfx = aCtx->ThebesContext();
   gfxContextMatrixAutoSaveRestore matrixAutoSaveRestore(gfx);
 
   PRInt32 appUnitsPerDevPixel = 
-    aEffectsFrame->PresContext()->AppUnitsPerDevPixel();
+    aFrame->PresContext()->AppUnitsPerDevPixel();
   nsPoint firstFrameOffset = GetOffsetToUserSpace(firstFrame);
   nsPoint offset = (aBuilder->ToReferenceFrame(firstFrame) - firstFrameOffset).
                      ToNearestPixels(appUnitsPerDevPixel).
                      ToAppUnits(appUnitsPerDevPixel);
   aCtx->Translate(offset);
 
-  gfxMatrix cssPxToDevPxMatrix = GetCSSPxToDevPxMatrix(aEffectsFrame);
+  gfxMatrix cssPxToDevPxMatrix = GetCSSPxToDevPxMatrix(aFrame);
 
   bool complexEffects = false;
   /* Check if we need to do additional operations on this child's
    * rendering, which necessitates rendering into another surface. */
   if (opacity != 1.0f || maskFrame || (clipPathFrame && !isTrivialClip)) {
     complexEffects = true;
     gfx->Save();
-    aCtx->IntersectClip(aEffectsFrame->GetVisualOverflowRect());
+    aCtx->IntersectClip(aFrame->GetVisualOverflowRect());
     gfx->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
   }
 
   /* If this frame has only a trivial clipPath, set up cairo's clipping now so
    * we can just do normal painting and get it clipped appropriately.
    */
   if (clipPathFrame && isTrivialClip) {
     gfx->Save();
-    clipPathFrame->ClipPaint(aCtx, aEffectsFrame, cssPxToDevPxMatrix);
+    clipPathFrame->ClipPaint(aCtx, aFrame, cssPxToDevPxMatrix);
   }
 
   /* Paint the child */
   if (filterFrame) {
-    RegularFramePaintCallback callback(aBuilder, aInnerList, aEffectsFrame,
+    RegularFramePaintCallback callback(aBuilder, aInnerList, aFrame,
                                        offset);
     nsRect dirtyRect = aDirtyRect - offset;
-    filterFrame->PaintFilteredFrame(aCtx, aEffectsFrame, &callback, &dirtyRect);
+    filterFrame->PaintFilteredFrame(aCtx, aFrame, &callback, &dirtyRect);
   } else {
     gfx->SetMatrix(matrixAutoSaveRestore.Matrix());
-    aInnerList->PaintForFrame(aBuilder, aCtx, aEffectsFrame,
+    aInnerList->PaintForFrame(aBuilder, aCtx, aFrame,
                               nsDisplayList::PAINT_DEFAULT);
     aCtx->Translate(offset);
   }
 
   if (clipPathFrame && isTrivialClip) {
     gfx->Restore();
   }
 
   /* No more effects, we're done. */
   if (!complexEffects) {
     return;
   }
 
   gfx->PopGroupToSource();
 
   nsRefPtr<gfxPattern> maskSurface =
-    maskFrame ? maskFrame->ComputeMaskAlpha(aCtx, aEffectsFrame,
+    maskFrame ? maskFrame->ComputeMaskAlpha(aCtx, aFrame,
                                             cssPxToDevPxMatrix, opacity) : nsnull;
 
   nsRefPtr<gfxPattern> clipMaskSurface;
   if (clipPathFrame && !isTrivialClip) {
     gfx->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
 
-    nsresult rv = clipPathFrame->ClipPaint(aCtx, aEffectsFrame, cssPxToDevPxMatrix);
+    nsresult rv = clipPathFrame->ClipPaint(aCtx, aFrame, cssPxToDevPxMatrix);
     clipMaskSurface = gfx->PopGroup();
 
     if (NS_SUCCEEDED(rv) && clipMaskSurface) {
       // Still more set after clipping, so clip to another surface
       if (maskSurface || opacity != 1.0f) {
         gfx->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
         gfx->Mask(clipMaskSurface);
         gfx->PopGroupToSource();
--- a/layout/svg/base/src/nsSVGIntegrationUtils.h
+++ b/layout/svg/base/src/nsSVGIntegrationUtils.h
@@ -124,22 +124,20 @@ public:
    * Returns true if the given point is not clipped out by effects.
    * @param aPt in appunits relative to aFrame
    */
   static bool
   HitTestFrameForEffects(nsIFrame* aFrame, const nsPoint& aPt);
 
   /**
    * Paint non-SVG frame with SVG effects.
-   * @param aOffset the offset in appunits where aFrame should be positioned
-   * in aCtx's coordinate system
    */
   static void
   PaintFramesWithEffects(nsRenderingContext* aCtx,
-                         nsIFrame* aEffectsFrame, const nsRect& aDirtyRect,
+                         nsIFrame* aFrame, const nsRect& aDirtyRect,
                          nsDisplayListBuilder* aBuilder,
                          nsDisplayList* aInnerList);
 
   /**
    * SVG frames expect to paint in SVG user units, which are equal to CSS px
    * units. This method provides a transform matrix to multiply onto a
    * gfxContext's current transform to convert the context's current units from
    * its usual dev pixels to SVG user units/CSS px to keep the SVG code happy.
--- a/layout/svg/base/src/nsSVGMaskFrame.cpp
+++ b/layout/svg/base/src/nsSVGMaskFrame.cpp
@@ -48,28 +48,24 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRende
     bbox = nsSVGUtils::GetBBox(aParent);
   }
 
   gfxRect maskArea = nsSVGUtils::GetRelativeRect(units,
     &mask->mLengthAttributes[nsSVGMaskElement::X], bbox, aParent);
 
   gfxContext *gfx = aContext->ThebesContext();
 
+  // Get the clip extents in device space:
   gfx->Save();
   nsSVGUtils::SetClipRect(gfx, aMatrix, maskArea);
+  gfx->IdentityMatrix();
   gfxRect clipExtents = gfx->GetClipExtents();
   clipExtents.RoundOut();
   gfx->Restore();
 
-#ifdef DEBUG_tor
-  fprintf(stderr, "clip extent: %f,%f %fx%f\n",
-          clipExtents.X(), clipExtents.Y(),
-          clipExtents.Width(), clipExtents.Height());
-#endif
-
   bool resultOverflows;
   gfxIntSize surfaceSize =
     nsSVGUtils::ConvertToSurfaceSize(gfxSize(clipExtents.Width(),
                                              clipExtents.Height()),
                                      &resultOverflows);
 
   // 0 disables mask, < 0 is an error
   if (surfaceSize.width <= 0 || surfaceSize.height <= 0)
@@ -77,20 +73,29 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRende
 
   if (resultOverflows)
     return nsnull;
 
   nsRefPtr<gfxImageSurface> image =
     new gfxImageSurface(surfaceSize, gfxASurface::ImageFormatARGB32);
   if (!image || image->CairoStatus())
     return nsnull;
-  image->SetDeviceOffset(-clipExtents.TopLeft());
+
+  // We would like to use gfxImageSurface::SetDeviceOffset() to position
+  // 'image'. However, we need to set the same matrix on the temporary context
+  // and pattern that we create below as is currently set on 'gfx'.
+  // Unfortunately, any device offset set by SetDeviceOffset() is affected by
+  // the transform passed to the SetMatrix() calls, so to avoid that we account
+  // for the device offset in the transform rather than use SetDeviceOffset().
+  gfxMatrix matrix =
+    gfx->CurrentMatrix() * gfxMatrix().Translate(-clipExtents.TopLeft());
 
   nsRenderingContext tmpCtx;
   tmpCtx.Init(this->PresContext()->DeviceContext(), image);
+  tmpCtx.ThebesContext()->SetMatrix(matrix);
 
   mMaskParent = aParent;
   if (mMaskParentMatrix) {
     *mMaskParentMatrix = aMatrix;
   } else {
     mMaskParentMatrix = new gfxMatrix(aMatrix);
   }
 
@@ -127,16 +132,17 @@ nsSVGMaskFrame::ComputeMaskAlpha(nsRende
                         pixel[GFX_ARGB32_OFFSET_G] * 0.7154 +
                         pixel[GFX_ARGB32_OFFSET_B] * 0.0721) *
                        (pixel[GFX_ARGB32_OFFSET_A] / 255.0) * aOpacity);
 
       memset(pixel, alpha, 4);
     }
 
   gfxPattern *retval = new gfxPattern(image);
+  retval->SetMatrix(matrix);
   NS_IF_ADDREF(retval);
   return retval;
 }
 
 /* virtual */ void
 nsSVGMaskFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
 {
   nsSVGEffects::InvalidateDirectRenderingObservers(this);
--- a/layout/svg/base/src/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/base/src/nsSVGOuterSVGFrame.cpp
@@ -435,39 +435,39 @@ nsSVGOuterSVGFrame::DidReflow(nsPresCont
   PresContext()->PresShell()->SynthesizeMouseMove(false);
 
   return rv;
 }
 
 //----------------------------------------------------------------------
 // container methods
 
-class nsDisplaySVG : public nsDisplayItem {
+class nsDisplayOuterSVG : public nsDisplayItem {
 public:
-  nsDisplaySVG(nsDisplayListBuilder* aBuilder,
-               nsSVGOuterSVGFrame* aFrame) :
+  nsDisplayOuterSVG(nsDisplayListBuilder* aBuilder,
+                    nsSVGOuterSVGFrame* aFrame) :
     nsDisplayItem(aBuilder, aFrame) {
-    MOZ_COUNT_CTOR(nsDisplaySVG);
+    MOZ_COUNT_CTOR(nsDisplayOuterSVG);
   }
 #ifdef NS_BUILD_REFCNT_LOGGING
-  virtual ~nsDisplaySVG() {
-    MOZ_COUNT_DTOR(nsDisplaySVG);
+  virtual ~nsDisplayOuterSVG() {
+    MOZ_COUNT_DTOR(nsDisplayOuterSVG);
   }
 #endif
 
   virtual void HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
                        HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames);
   virtual void Paint(nsDisplayListBuilder* aBuilder,
                      nsRenderingContext* aCtx);
-  NS_DISPLAY_DECL_NAME("SVGEventReceiver", TYPE_SVG_EVENT_RECEIVER)
+  NS_DISPLAY_DECL_NAME("SVGOuterSVG", TYPE_SVG_OUTER_SVG)
 };
 
 void
-nsDisplaySVG::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
-                      HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
+nsDisplayOuterSVG::HitTest(nsDisplayListBuilder* aBuilder, const nsRect& aRect,
+                           HitTestState* aState, nsTArray<nsIFrame*> *aOutFrames)
 {
   nsSVGOuterSVGFrame *outerSVGFrame = static_cast<nsSVGOuterSVGFrame*>(mFrame);
   nsRect rectAtOrigin = aRect - ToReferenceFrame();
   nsRect thisRect(nsPoint(0,0), outerSVGFrame->GetSize());
   if (!thisRect.Intersects(rectAtOrigin))
     return;
 
   nsPoint rectCenter(rectAtOrigin.x + rectAtOrigin.width / 2,
@@ -477,39 +477,43 @@ nsDisplaySVG::HitTest(nsDisplayListBuild
     outerSVGFrame, rectCenter + outerSVGFrame->GetPosition() -
                    outerSVGFrame->GetContentRect().TopLeft());
   if (frame) {
     aOutFrames->AppendElement(frame);
   }
 }
 
 void
-nsDisplaySVG::Paint(nsDisplayListBuilder* aBuilder,
-                    nsRenderingContext* aContext)
+nsDisplayOuterSVG::Paint(nsDisplayListBuilder* aBuilder,
+                         nsRenderingContext* aContext)
 {
-  nsSVGOuterSVGFrame *frame = static_cast<nsSVGOuterSVGFrame*>(mFrame);
-
-  if (frame->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)
-    return;
-
 #if defined(DEBUG) && defined(SVG_DEBUG_PAINT_TIMING)
   PRTime start = PR_Now();
 #endif
 
   aContext->PushState();
 
+  nsSVGOuterSVGFrame *frame = static_cast<nsSVGOuterSVGFrame*>(mFrame);
+
 #ifdef XP_MACOSX
   if (frame->BitmapFallbackEnabled()) {
     // nquartz fallback paths, which svg tends to trigger, need
     // a non-window context target
     aContext->ThebesContext()->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
   }
 #endif
 
-  frame->Paint(aBuilder, aContext, mVisibleRect, ToReferenceFrame());
+  nsRect viewportRect =
+    frame->GetContentRectRelativeToSelf() + ToReferenceFrame();
+  nsRect clipRect = mVisibleRect.Intersect(viewportRect);
+
+  aContext->IntersectClip(clipRect);
+  aContext->Translate(viewportRect.TopLeft());
+
+  frame->Paint(aBuilder, aContext, clipRect - viewportRect.TopLeft());
 
 #ifdef XP_MACOSX
   if (frame->BitmapFallbackEnabled()) {
     // show the surface we pushed earlier for fallbacks
     aContext->ThebesContext()->PopGroupToSource();
     aContext->ThebesContext()->Paint();
   }
 
@@ -614,55 +618,51 @@ nsSVGOuterSVGFrame::AttributeChanged(PRI
 //----------------------------------------------------------------------
 // painting
 
 NS_IMETHODIMP
 nsSVGOuterSVGFrame::BuildDisplayList(nsDisplayListBuilder*   aBuilder,
                                      const nsRect&           aDirtyRect,
                                      const nsDisplayListSet& aLists)
 {
+  if (GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD) {
+    return NS_OK;
+  }
+
   nsresult rv = DisplayBorderBackgroundOutline(aBuilder, aLists);
   NS_ENSURE_SUCCESS(rv, rv);
 
   nsDisplayList replacedContent;
 
   rv = replacedContent.AppendNewToTop(
-      new (aBuilder) nsDisplaySVG(aBuilder, this));
+      new (aBuilder) nsDisplayOuterSVG(aBuilder, this));
   NS_ENSURE_SUCCESS(rv, rv);
 
   WrapReplacedContentForBorderRadius(aBuilder, &replacedContent, aLists);
 
   return NS_OK;
 }
 
 void
 nsSVGOuterSVGFrame::Paint(const nsDisplayListBuilder* aBuilder,
                           nsRenderingContext* aContext,
-                          const nsRect& aDirtyRect, nsPoint aPt)
+                          const nsRect& aDirtyRect)
 {
-  nsRect viewportRect = GetContentRect();
-  nsPoint viewportOffset = aPt + viewportRect.TopLeft() - GetPosition();
-  viewportRect.MoveTo(viewportOffset);
-
-  nsRect clipRect;
-  clipRect.IntersectRect(aDirtyRect, viewportRect);
-  aContext->IntersectClip(clipRect);
-  aContext->Translate(viewportRect.TopLeft());
-  nsRect dirtyRect = clipRect - viewportOffset;
-
-  nsIntRect dirtyPxRect = dirtyRect.ToOutsidePixels(PresContext()->AppUnitsPerDevPixel());
-
   // Create an SVGAutoRenderState so we can call SetPaintingToWindow on
   // it, but don't change the render mode:
   SVGAutoRenderState state(aContext, SVGAutoRenderState::GetRenderMode(aContext));
 
   if (aBuilder->IsPaintingToWindow()) {
     state.SetPaintingToWindow(true);
   }
 
+  // Convert the (content area relative) dirty rect to dev pixels:
+  nsIntRect dirtyPxRect =
+    aDirtyRect.ToOutsidePixels(PresContext()->AppUnitsPerDevPixel());
+
   nsSVGUtils::PaintFrameWithEffects(aContext, &dirtyPxRect, this);
 }
 
 nsSplittableType
 nsSVGOuterSVGFrame::GetSplittableType() const
 {
   return NS_FRAME_NOT_SPLITTABLE;
 }
--- a/layout/svg/base/src/nsSVGOuterSVGFrame.h
+++ b/layout/svg/base/src/nsSVGOuterSVGFrame.h
@@ -62,17 +62,17 @@ public:
    * Get the "type" of the frame
    *
    * @see nsGkAtoms::svgOuterSVGFrame
    */
   virtual nsIAtom* GetType() const;
 
   void Paint(const nsDisplayListBuilder* aBuilder,
              nsRenderingContext* aContext,
-             const nsRect& aDirtyRect, nsPoint aPt);
+             const nsRect& aDirtyRect);
 
 #ifdef DEBUG
   NS_IMETHOD GetFrameName(nsAString& aResult) const
   {
     return MakeFrameName(NS_LITERAL_STRING("SVGOuterSVG"), aResult);
   }
 #endif
 
--- a/mobile/android/base/AwesomeBar.java
+++ b/mobile/android/base/AwesomeBar.java
@@ -215,16 +215,25 @@ public class AwesomeBar extends GeckoAct
                     openUserEnteredAndFinish(mText.getText().toString());
                     return true;
                 } else {
                     return false;
                 }
             }
         });
 
+        mText.setOnFocusChangeListener(new View.OnFocusChangeListener() {
+            public void onFocusChange(View v, boolean hasFocus) {
+                if (!hasFocus) {
+                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
+                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
+                }
+            }
+        });
+
         registerForContextMenu(mAwesomeTabs.findViewById(R.id.all_pages_list));
         registerForContextMenu(mAwesomeTabs.findViewById(R.id.bookmarks_list));
         registerForContextMenu(mAwesomeTabs.findViewById(R.id.history_list));
 
         GeckoAppShell.registerGeckoEventListener("SearchEngines:Data", this);
         GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("SearchEngines:Get", null));
     }
 
@@ -348,16 +357,21 @@ public class AwesomeBar extends GeckoAct
         resultIntent.putExtra(URL_KEY, url);
         resultIntent.putExtra(TARGET_KEY, mTarget);
         resultIntent.putExtra(SEARCH_KEY, engine);
         finishWithResult(resultIntent);
     }
 
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
+        // Galaxy Note sends key events for the stylus that are outside of the
+        // valid keyCode range (see bug 758427)
+        if (keyCode > KeyEvent.getMaxKeyCode())
+            return true;
+
         // This method is called only if the key event was not handled
         // by any of the views, which usually means the edit box lost focus
         if (keyCode == KeyEvent.KEYCODE_BACK ||
             keyCode == KeyEvent.KEYCODE_MENU ||
             keyCode == KeyEvent.KEYCODE_SEARCH ||
             keyCode == KeyEvent.KEYCODE_DPAD_UP ||
             keyCode == KeyEvent.KEYCODE_DPAD_DOWN ||
             keyCode == KeyEvent.KEYCODE_DPAD_LEFT ||
--- a/mobile/android/base/AwesomeBarTabs.java
+++ b/mobile/android/base/AwesomeBarTabs.java
@@ -63,16 +63,17 @@ public class AwesomeBarTabs extends TabH
     private static final String HISTORY_TAB = "history";
 
     private static enum HistorySection { TODAY, YESTERDAY, WEEK, OLDER };
 
     private Context mContext;
     private boolean mInflated;
     private LayoutInflater mInflater;
     private OnUrlOpenListener mUrlOpenListener;
+    private View.OnTouchListener mListTouchListener;
     private ContentResolver mContentResolver;
     private ContentObserver mContentObserver;
     private SearchEngine mSuggestEngine;
     private ArrayList<SearchEngine> mSearchEngines;
 
     private BookmarksQueryTask mBookmarksQueryTask;
     private HistoryQueryTask mHistoryQueryTask;
     
@@ -881,16 +882,24 @@ public class AwesomeBarTabs extends TabH
             return;
 
         mInflated = true;
 
         // This should be called before adding any tabs
         // to the TabHost.
         setup();
 
+        mListTouchListener = new View.OnTouchListener() {
+            public boolean onTouch(View view, MotionEvent event) {
+                if (event.getAction() == MotionEvent.ACTION_DOWN)
+                    hideSoftInput(view);
+                return false;
+            }
+        };
+
         addAllPagesTab();
         addBookmarksTab();
         addHistoryTab();
 
         setOnTabChangedListener(new TabHost.OnTabChangeListener() {
             public void onTabChanged(String tabId) {
                 boolean hideSoftInput = true;
 
@@ -969,39 +978,42 @@ public class AwesomeBarTabs extends TabH
 
         allPagesList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
             public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                 ((AwesomeBarItem) allPagesList.getItemAtPosition(position)).onClick();
             }
         });
 
         allPagesList.setAdapter(mAllPagesCursorAdapter);
+        allPagesList.setOnTouchListener(mListTouchListener);
     }
 
     private void addBookmarksTab() {
         Log.d(LOGTAG, "Creating Bookmarks tab");
 
         addAwesomeTab(BOOKMARKS_TAB,
                       R.string.awesomebar_bookmarks_title,
                       R.id.bookmarks_list);
 
         ListView bookmarksList = (ListView) findViewById(R.id.bookmarks_list);
+        bookmarksList.setOnTouchListener(mListTouchListener);
 
         // Only load bookmark list when tab is actually used.
         // See OnTabChangeListener above.
     }
 
     private void addHistoryTab() {
         Log.d(LOGTAG, "Creating History tab");
 
         addAwesomeTab(HISTORY_TAB,
                       R.string.awesomebar_history_title,
                       R.id.history_list);
 
         ListView historyList = (ListView) findViewById(R.id.history_list);
+        historyList.setOnTouchListener(mListTouchListener);
 
         // Only load history list when tab is actually used.
         // See OnTabChangeListener above.
     }
 
     private boolean hideSoftInput(View view) {
         InputMethodManager imm =
                 (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
@@ -1219,21 +1231,9 @@ public class AwesomeBarTabs extends TabH
                 mAllPagesCursorAdapter.notifyDataSetChanged();
             }
         });
     }
 
     public boolean isInReadingList() {
         return mInReadingList;
     }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        // we should only have to hide the soft keyboard once - when the user
-        // initially touches the screen
-        if (ev.getAction() == MotionEvent.ACTION_DOWN)
-            hideSoftInput(this);
-
-        // the android docs make no sense, but returning false will cause this and other
-        // motion events to be sent to the view the user tapped on
-        return false;
-    }
 }
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -2147,17 +2147,17 @@ abstract public class GeckoApp
      * compatable with our previous implementations
      */
     private String getURIFromIntent(Intent intent) {
         String uri = intent.getDataString();
         if (uri != null)
             return uri;
 
         final String action = intent.getAction();
-        if (action.startsWith(ACTION_WEBAPP_PREFIX) || ACTION_BOOKMARK.equals(action)) {
+        if ((action != null && action.startsWith(ACTION_WEBAPP_PREFIX)) || ACTION_BOOKMARK.equals(action)) {
             uri = intent.getStringExtra("args");
             if (uri != null && uri.startsWith("--url=")) {
                 uri.replace("--url=", "");
             }
         }
         return uri;
     }
 
--- a/mobile/android/base/GeckoInputConnection.java
+++ b/mobile/android/base/GeckoInputConnection.java
@@ -871,16 +871,19 @@ public class GeckoInputConnection
     }
 
     private boolean processKeyDown(int keyCode, KeyEvent event, boolean isPreIme) {
         if (DEBUG) {
             Log.d(LOGTAG, "IME: processKeyDown(keyCode=" + keyCode + ", event=" + event + ", "
                           + isPreIme + ")");
         }
 
+        if (keyCode > KeyEvent.getMaxKeyCode())
+            return false;
+
         clampSelection();
 
         switch (keyCode) {
             case KeyEvent.KEYCODE_MENU:
             case KeyEvent.KEYCODE_BACK:
             case KeyEvent.KEYCODE_VOLUME_UP:
             case KeyEvent.KEYCODE_VOLUME_DOWN:
             case KeyEvent.KEYCODE_SEARCH:
@@ -930,16 +933,19 @@ public class GeckoInputConnection
     }
 
     private boolean processKeyUp(int keyCode, KeyEvent event, boolean isPreIme) {
         if (DEBUG) {
             Log.d(LOGTAG, "IME: processKeyUp(keyCode=" + keyCode + ", event=" + event + ", "
                           + isPreIme + ")");
         }
 
+        if (keyCode > KeyEvent.getMaxKeyCode())
+            return false;
+
         switch (keyCode) {
             case KeyEvent.KEYCODE_BACK:
             case KeyEvent.KEYCODE_SEARCH:
             case KeyEvent.KEYCODE_MENU:
                 return false;
             default:
                 break;
         }
--- a/mobile/android/base/GeckoThread.java
+++ b/mobile/android/base/GeckoThread.java
@@ -68,19 +68,22 @@ public class GeckoThread extends Thread 
         Configuration config = res.getConfiguration();
         config.locale = locale;
         res.updateConfiguration(config, res.getDisplayMetrics());
 
         Log.w(LOGTAG, "zerdatime " + SystemClock.uptimeMillis() + " - runGecko");
 
         // find the right intent type
         final String action = mIntent.getAction();
-        String type = action.startsWith(GeckoApp.ACTION_WEBAPP_PREFIX) ? "-webapp" :
-                      GeckoApp.ACTION_BOOKMARK.equals(action) ? "-bookmark" :
-                      null;
+        String type = null;
+
+        if (action != null && action.startsWith(GeckoApp.ACTION_WEBAPP_PREFIX))
+            type = "-webapp";
+        else if (GeckoApp.ACTION_BOOKMARK.equals(action))
+            type = "-bookmark";
 
         String args = mIntent.getStringExtra("args");
 
         // if this isn't the default BrowserApp, send the apps default profile to gecko
         if (!(app instanceof BrowserApp)) {
             String profile = app.getDefaultProfileName();
             args = (args != null ? args : "") + "-P " + profile;
         }
--- a/mobile/android/base/tests/BaseTest.java.in
+++ b/mobile/android/base/tests/BaseTest.java.in
@@ -63,33 +63,33 @@ abstract class BaseTest extends Activity
         Intent i = new Intent(Intent.ACTION_MAIN);
         mProfile = (String)config.get("profile");
         i.putExtra("args", "-no-remote -profile " + mProfile);
 
         // Start the activity
         setActivityIntent(i);
         mActivity = getActivity();
 
-        // Set up Robotium.solo and Driver objects
-        mSolo = new Solo(getInstrumentation());
-        mDriver = new FennecNativeDriver(mActivity, mSolo);
-        mActions = new FennecNativeActions(mActivity, mSolo, getInstrumentation());
-
         mLogFile = (String)config.get("logfile");
         mBaseUrl = ((String)config.get("host")).replaceAll("(/$)", "");
         mRawBaseUrl = ((String)config.get("rawhost")).replaceAll("(/$)", "");
 
         // Initialize the asserter
         if (getTestType() == TEST_TALOS) {
             mAsserter = new FennecTalosAssert();
         } else {
             mAsserter = new FennecMochitestAssert();
         }
         mAsserter.setLogFile(mLogFile);
         mAsserter.setTestName(this.getClass().getName());
+
+        // Set up Robotium.solo and Driver objects
+        mSolo = new Solo(getInstrumentation());
+        mDriver = new FennecNativeDriver(mActivity, mSolo);
+        mActions = new FennecNativeActions(mActivity, mSolo, getInstrumentation(), mAsserter);
     }
 
     @Override
     protected void runTest() throws Throwable {
         try {
             super.runTest();
         } catch (Throwable t) {
             if (mAsserter != null) {
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -1379,16 +1379,17 @@ var NativeWindow = {
     }
   }
 };
 
 var SelectionHandler = {
   // Keeps track of data about the dimensions of the selection
   cache: null,
   _active: false,
+  _viewOffset: null,
 
   // The window that holds the selection (can be a sub-frame)
   get _view() {
     if (this._viewRef)
       return this._viewRef.get();
     return null;
   },
 
@@ -1422,27 +1423,41 @@ var SelectionHandler = {
   // Units in pixels
   HANDLE_WIDTH: 35,
   HANDLE_HEIGHT: 64,
   HANDLE_PADDING: 20,
   HANDLE_VERTICAL_OFFSET: 10,
 
   init: function sh_init() {
     Services.obs.addObserver(this, "Gesture:SingleTap", false);
+    Services.obs.addObserver(this, "Window:Resize", false);
   },
 
   uninit: function sh_uninit() {
     Services.obs.removeObserver(this, "Gesture:SingleTap", false);
+    Services.obs.removeObserver(this, "Window:Resize", false);
   },
 
   observe: function sh_observe(aSubject, aTopic, aData) {
-    let data = JSON.parse(aData);
-
-    if (this._active)
-      this.endSelection(data.x, data.y);
+    switch (aTopic) {
+      case "Gesture:SingleTap": {
+        if (!this._active)
+          return;
+
+        let data = JSON.parse(aData);
+        this.endSelection(data.x, data.y);
+        break;
+      }
+      case "Window:Resize": {
+        // Knowing when the page is done drawing is hard, so let's just cancel
+        // the selection when the window changes. We should fix this later.
+        this.endSelection();
+        break;
+      }
+    }
   },
 
   notifySelectionChanged: function sh_notifySelectionChanged(aDoc, aSel, aReason) {
     // If the selection was removed, call endSelection() to clean up
     if (aSel == "" && aReason == Ci.nsISelectionListener.NO_REASON)
       this.endSelection();
   },
 
@@ -1458,16 +1473,20 @@ var SelectionHandler = {
       // Clear out any existing selection
       this.endSelection();
     }
 
     // Get the element's view
     this._view = aElement.ownerDocument.defaultView;
     this._isRTL = (this._view.getComputedStyle(aElement, "").direction == "rtl");
 
+    let computedStyle = this._view.getComputedStyle(this._view.document.documentElement);
+    this._viewOffset = { top: parseInt(computedStyle.getPropertyValue("margin-top").replace("px", "")),
+                         left: parseInt(computedStyle.getPropertyValue("margin-left").replace("px", "")) };
+
     // Remove any previous selected or created ranges. Tapping anywhere on a
     // page will create an empty range.
     let selection = this._view.getSelection();
     selection.removeAllRanges();
 
     // Position the caret using a fake mouse click
     let cwu = BrowserApp.selectedBrowser.contentWindow.QueryInterface(Ci.nsIInterfaceRequestor).
                                                        getInterface(Ci.nsIDOMWindowUtils);
@@ -1572,21 +1591,21 @@ var SelectionHandler = {
     if (!element || element instanceof Ci.nsIDOMHTMLInputElement ||
                     element instanceof Ci.nsIDOMHTMLTextAreaElement ||
                     element.ownerDocument.defaultView != this._view)
       return;
     */
 
     // Update the handle position as it's dragged
     if (aIsStartHandle) {
-      this._start.style.left = aX + this._view.scrollX + "px";
-      this._start.style.top = aY + this._view.scrollY + "px";
+      this._start.style.left = aX + this._view.scrollX - this._viewOffset.left + "px";
+      this._start.style.top = aY + this._view.scrollY - this._viewOffset.top + "px";
     } else {
-      this._end.style.left = aX + this._view.scrollX + "px";
-      this._end.style.top = aY + this._view.scrollY + "px";
+      this._end.style.left = aX + this._view.scrollX - this._viewOffset.left + "px";
+      this._end.style.top = aY + this._view.scrollY - this._viewOffset.top + "px";
     }
 
     let cwu = this._view.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
 
     // The handles work the same on both LTR and RTL pages, but the underlying selection
     // works differently, so we need to reverse how we send mouse events on RTL pages.
     if (this._isRTL) {
       // Position the caret at the end handle using a fake mouse click
@@ -1691,16 +1710,17 @@ var SelectionHandler = {
         let clipboard = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
         clipboard.copyString(selectedText, element.ownerDocument);
         NativeWindow.toast.show(Strings.browser.GetStringFromName("selectionHelper.textCopied"), "short");
       }
     }
 
     this._isRTL = false;
     this._view = null;
+    this._viewOffset = null;
     this.cache = null;
 
     return selectedText;
   },
 
   _pointInSelection: function sh_pointInSelection(aX, aY) {
     let offset = { x: 0, y: 0 };
     let win = this._view;
@@ -1739,21 +1759,21 @@ var SelectionHandler = {
     this.cache.end = end;
 
     return selectionReversed;
   },
 
   // Adjust start/end positions to account for scroll, and account for the dimensions of the
   // handle elements to ensure the handles point exactly at the ends of the selection.
   positionHandles: function sh_positionHandles() {
-    this._start.style.left = (this.cache.start.x + this._view.scrollX - this.HANDLE_WIDTH - this.HANDLE_PADDING) + "px";
-    this._start.style.top = (this.cache.start.y + this._view.scrollY - this.HANDLE_VERTICAL_OFFSET) + "px";
-
-    this._end.style.left = (this.cache.end.x + this._view.scrollX - this.HANDLE_PADDING) + "px";
-    this._end.style.top = (this.cache.end.y + this._view.scrollY - this.HANDLE_VERTICAL_OFFSET) + "px";
+    this._start.style.left = (this.cache.start.x + this._view.scrollX - this._viewOffset.left - this.HANDLE_WIDTH - this.HANDLE_PADDING) + "px";
+    this._start.style.top = (this.cache.start.y + this._view.scrollY - this._viewOffset.top - this.HANDLE_VERTICAL_OFFSET) + "px";
+
+    this._end.style.left = (this.cache.end.x + this._view.scrollX - this._viewOffset.left - this.HANDLE_PADDING) + "px";
+    this._end.style.top = (this.cache.end.y + this._view.scrollY - this._viewOffset.top - this.HANDLE_VERTICAL_OFFSET) + "px";
   },
 
   showHandles: function sh_showHandles() {
     let doc = this._view.document;
     this._start = doc.getAnonymousElementByAttribute(doc.documentElement, "anonid", "selection-handle-start");
     this._end = doc.getAnonymousElementByAttribute(doc.documentElement, "anonid", "selection-handle-end");
 
     if (!this._start || !this._end) {
--- a/netwerk/protocol/http/nsHttpConnection.cpp
+++ b/netwerk/protocol/http/nsHttpConnection.cpp
@@ -44,16 +44,17 @@ nsHttpConnection::nsHttpConnection()
     , mConsiderReusedAfterInterval(0)
     , mConsiderReusedAfterEpoch(0)
     , mCurrentBytesRead(0)
     , mMaxBytesRead(0)
     , mTotalBytesRead(0)
     , mTotalBytesWritten(0)
     , mKeepAlive(true) // assume to keep-alive by default
     , mKeepAliveMask(true)
+    , mDontReuse(false)
     , mSupportsPipelining(false) // assume low-grade server
     , mIsReused(false)
     , mCompletedProxyConnect(false)
     , mLastTransactionExpectedNoContent(false)
     , mIdleMonitoring(false)
     , mProxyConnectInProgress(false)
     , mHttp1xTransactionCount(0)
     , mRemainingConnectionUses(0xffffffff)
@@ -511,38 +512,42 @@ nsHttpConnection::ProxyStartSSL()
     return ssl->ProxyStartSSL();
 }
 
 void
 nsHttpConnection::DontReuse()
 {
     mKeepAliveMask = false;
     mKeepAlive = false;
+    mDontReuse = true;
     mIdleTimeout = 0;
     if (mSpdySession)
         mSpdySession->DontReuse();
 }
 
 // Checked by the Connection Manager before scheduling a pipelined transaction
 bool
 nsHttpConnection::SupportsPipelining()
 {
     if (mTransaction &&
         mTransaction->PipelineDepth() >= mRemainingConnectionUses) {
         LOG(("nsHttpConnection::SupportsPipelining this=%p deny pipeline "
              "because current depth %d exceeds max remaining uses %d\n",
              this, mTransaction->PipelineDepth(), mRemainingConnectionUses));
         return false;
     }
-    return mSupportsPipelining && IsKeepAlive();
+    return mSupportsPipelining && IsKeepAlive() && !mDontReuse;
 }
 
 bool
 nsHttpConnection::CanReuse()
 {
+    if (mDontReuse)
+        return false;
+
     if ((mTransaction ? mTransaction->PipelineDepth() : 0) >=
         mRemainingConnectionUses) {
         return false;
     }
 
     bool canReuse;
     
     if (mSpdySession)
--- a/netwerk/protocol/http/nsHttpConnection.h
+++ b/netwerk/protocol/http/nsHttpConnection.h
@@ -212,16 +212,17 @@ private:
     PRInt64                         mTotalBytesWritten;  // does not include CONNECT tunnel
 
     nsRefPtr<nsIAsyncInputStream>   mInputOverflow;
 
     PRIntervalTime                  mRtt;
 
     bool                            mKeepAlive;
     bool                            mKeepAliveMask;
+    bool                            mDontReuse;
     bool                            mSupportsPipelining;
     bool                            mIsReused;
     bool                            mCompletedProxyConnect;
     bool                            mLastTransactionExpectedNoContent;
     bool                            mIdleMonitoring;
     bool                            mProxyConnectInProgress;
 
     // The number of <= HTTP/1.1 transactions performed on this connection. This
--- a/netwerk/socket/nsSOCKSIOLayer.cpp
+++ b/netwerk/socket/nsSOCKSIOLayer.cpp
@@ -10,35 +10,41 @@
 
 #include "nsIServiceManager.h"
 #include "nsIDNSService.h"
 #include "nsIDNSRecord.h"
 #include "nsISOCKSSocketInfo.h"
 #include "nsISocketProvider.h"
 #include "nsSOCKSIOLayer.h"
 #include "nsNetCID.h"
+#include "nsIDNSListener.h"
+#include "nsICancelable.h"
+#include "nsThreadUtils.h"
 
 static PRDescIdentity	nsSOCKSIOLayerIdentity;
 static PRIOMethods	nsSOCKSIOLayerMethods;
 static bool firstTime = true;
 
 #if defined(PR_LOGGING)
 static PRLogModuleInfo *gSOCKSLog;
 #define LOGDEBUG(args) PR_LOG(gSOCKSLog, PR_LOG_DEBUG, args)
 #define LOGERROR(args) PR_LOG(gSOCKSLog, PR_LOG_ERROR , args)
 
 #else
 #define LOGDEBUG(args)
 #define LOGERROR(args)
 #endif
 
 class nsSOCKSSocketInfo : public nsISOCKSSocketInfo
+                        , public nsIDNSListener
 {
     enum State {
         SOCKS_INITIAL,
+        SOCKS_DNS_IN_PROGRESS,
+        SOCKS_DNS_COMPLETE,
         SOCKS_CONNECTING_TO_PROXY,
         SOCKS4_WRITE_CONNECT_REQUEST,
         SOCKS4_READ_CONNECT_RESPONSE,
         SOCKS5_WRITE_AUTH_REQUEST,
         SOCKS5_READ_AUTH_RESPONSE,
         SOCKS5_WRITE_CONNECT_REQUEST,
         SOCKS5_READ_CONNECT_RESPONSE_TOP,
         SOCKS5_READ_CONNECT_RESPONSE_BOTTOM,
@@ -52,30 +58,32 @@ class nsSOCKSSocketInfo : public nsISOCK
     static const PRUint32 MAX_HOSTNAME_LEN = 255;
 
 public:
     nsSOCKSSocketInfo();
     virtual ~nsSOCKSSocketInfo() { HandshakeFinished(); }
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSISOCKSSOCKETINFO
+    NS_DECL_NSIDNSLISTENER
 
     void Init(PRInt32 version,
               const char *proxyHost,
               PRInt32 proxyPort,
               const char *destinationHost,
               PRUint32 flags);
 
     void SetConnectTimeout(PRIntervalTime to);
     PRStatus DoHandshake(PRFileDesc *fd, PRInt16 oflags = -1);
     PRInt16 GetPollFlags() const;
     bool IsConnected() const { return mState == SOCKS_CONNECTED; }
 
 private:
     void HandshakeFinished(PRErrorCode err = 0);
+    PRStatus StartDNS(PRFileDesc *fd);
     PRStatus ConnectToProxy(PRFileDesc *fd);
     PRStatus ContinueConnectingToProxy(PRFileDesc *fd, PRInt16 oflags);
     PRStatus WriteV4ConnectRequest();
     PRStatus ReadV4ConnectResponse();
     PRStatus WriteV5AuthRequest();
     PRStatus ReadV5AuthResponse();
     PRStatus WriteV5ConnectRequest();
     PRStatus ReadV5AddrTypeAndLength(PRUint8 *type, PRUint32 *len);
@@ -101,17 +109,20 @@ private:
 
 private:
     State     mState;
     PRUint8 * mData;
     PRUint8 * mDataIoPtr;
     PRUint32  mDataLength;
     PRUint32  mReadOffset;
     PRUint32  mAmountToRead;
-    nsCOMPtr<nsIDNSRecord> mDnsRec;
+    nsCOMPtr<nsIDNSRecord>  mDnsRec;
+    nsCOMPtr<nsICancelable> mLookup;
+    nsresult                mLookupStatus;
+    PRFileDesc             *mFD;
 
     nsCString mDestinationHost;
     nsCString mProxyHost;
     PRInt32   mProxyPort;
     PRInt32   mVersion;   // SOCKS version 4 or 5
     PRUint32  mFlags;
     PRNetAddr mInternalProxyAddr;
     PRNetAddr mExternalProxyAddr;
@@ -141,17 +152,17 @@ nsSOCKSSocketInfo::Init(PRInt32 version,
 {
     mVersion         = version;
     mProxyHost       = proxyHost;
     mProxyPort       = proxyPort;
     mDestinationHost = host;
     mFlags           = flags;
 }
 
-NS_IMPL_THREADSAFE_ISUPPORTS1(nsSOCKSSocketInfo, nsISOCKSSocketInfo)
+NS_IMPL_THREADSAFE_ISUPPORTS2(nsSOCKSSocketInfo, nsISOCKSSocketInfo, nsIDNSListener)
 
 NS_IMETHODIMP 
 nsSOCKSSocketInfo::GetExternalProxyAddr(PRNetAddr * *aExternalProxyAddr)
 {
     memcpy(*aExternalProxyAddr, &mExternalProxyAddr, sizeof(PRNetAddr));
     return NS_OK;
 }
 
@@ -209,39 +220,74 @@ nsSOCKSSocketInfo::HandshakeFinished(PRE
 
     // We don't need the buffer any longer, so free it.
     delete [] mData;
     mData = nsnull;
     mDataIoPtr = nsnull;
     mDataLength = 0;
     mReadOffset = 0;
     mAmountToRead = 0;
+    if (mLookup) {
+        mLookup->Cancel(NS_ERROR_FAILURE);
+        mLookup = nsnull;
+    }
+}
+
+PRStatus
+nsSOCKSSocketInfo::StartDNS(PRFileDesc *fd)
+{
+    NS_ABORT_IF_FALSE(!mDnsRec && mState == SOCKS_INITIAL,
+                      "Must be in initial state to make DNS Lookup");
+
+    nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID);
+    if (!dns)
+        return PR_FAILURE;
+
+    mFD  = fd;
+    nsresult rv = dns->AsyncResolve(mProxyHost, 0, this,
+                                    NS_GetCurrentThread(),
+                                    getter_AddRefs(mLookup));
+
+    if (NS_FAILED(rv)) {
+        LOGERROR(("socks: DNS lookup for SOCKS proxy %s failed",
+                  mProxyHost.get()));
+        return PR_FAILURE;
+    }
+    mState = SOCKS_DNS_IN_PROGRESS;
+    PR_SetError(PR_IN_PROGRESS_ERROR, 0);
+    return PR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsSOCKSSocketInfo::OnLookupComplete(nsICancelable *aRequest,
+                                    nsIDNSRecord *aRecord,
+                                    nsresult aStatus)
+{
+    NS_ABORT_IF_FALSE(aRequest == mLookup, "wrong DNS query");
+    mLookup = nsnull;
+    mLookupStatus = aStatus;
+    mDnsRec = aRecord;
+    mState = SOCKS_DNS_COMPLETE;
+    ConnectToProxy(mFD);
+    mFD = nsnull;
+    return NS_OK;
 }
 
 PRStatus
 nsSOCKSSocketInfo::ConnectToProxy(PRFileDesc *fd)
 {
     PRStatus status;
     nsresult rv;
 
-    NS_ABORT_IF_FALSE(mState == SOCKS_INITIAL,
-                      "Must be in initial state to make connection!");
+    NS_ABORT_IF_FALSE(mState == SOCKS_DNS_COMPLETE,
+                      "Must have DNS to make connection!");
 
-    // If we haven't performed the DNS lookup, do that now.
-    if (!mDnsRec) {
-        nsCOMPtr<nsIDNSService> dns = do_GetService(NS_DNSSERVICE_CONTRACTID);
-        if (!dns)
-            return PR_FAILURE;
-
-        rv = dns->Resolve(mProxyHost, 0, getter_AddRefs(mDnsRec));
-        if (NS_FAILED(rv)) {
-            LOGERROR(("socks: DNS lookup for SOCKS proxy %s failed",
-                     mProxyHost.get()));
-            return PR_FAILURE;
-        }
+    if (NS_FAILED(mLookupStatus)) {
+        PR_SetError(PR_BAD_ADDRESS_ERROR, 0);
+        return PR_FAILURE;
     }
 
     PRInt32 addresses = 0;
     do {
         if (addresses++)
             mDnsRec->ReportUnusable(mProxyPort);
         
         rv = mDnsRec->GetNextAddr(mProxyPort, &mInternalProxyAddr);
@@ -286,17 +332,17 @@ nsSOCKSSocketInfo::ContinueConnectingToP
 
     LOGDEBUG(("socks: continuing connection to proxy"));
 
     status = fd->lower->methods->connectcontinue(fd->lower, oflags);
     if (status != PR_SUCCESS) {
         PRErrorCode c = PR_GetError();
         if (c != PR_WOULD_BLOCK_ERROR && c != PR_IN_PROGRESS_ERROR) {
             // A connection failure occured, try another address
-            mState = SOCKS_INITIAL;
+            mState = SOCKS_DNS_COMPLETE;
             return ConnectToProxy(fd);
         }
 
         // We're still connecting
         return PR_FAILURE;
     }
 
     // Connected now, start SOCKS
@@ -629,16 +675,21 @@ nsSOCKSSocketInfo::SetConnectTimeout(PRI
 
 PRStatus
 nsSOCKSSocketInfo::DoHandshake(PRFileDesc *fd, PRInt16 oflags)
 {
     LOGDEBUG(("socks: DoHandshake(), state = %d", mState));
 
     switch (mState) {
         case SOCKS_INITIAL:
+            return StartDNS(fd);
+        case SOCKS_DNS_IN_PROGRESS:
+            PR_SetError(PR_IN_PROGRESS_ERROR, 0);
+            return PR_FAILURE;
+        case SOCKS_DNS_COMPLETE:
             return ConnectToProxy(fd);
         case SOCKS_CONNECTING_TO_PROXY:
             return ContinueConnectingToProxy(fd, oflags);
         case SOCKS4_WRITE_CONNECT_REQUEST:
             if (WriteToSocket(fd) != PR_SUCCESS)
                 return PR_FAILURE;
             WantRead(8);
             mState = SOCKS4_READ_CONNECT_RESPONSE;
@@ -691,16 +742,18 @@ nsSOCKSSocketInfo::DoHandshake(PRFileDes
 
     return PR_FAILURE;
 }
 
 PRInt16
 nsSOCKSSocketInfo::GetPollFlags() const
 {
     switch (mState) {
+        case SOCKS_DNS_IN_PROGRESS:
+        case SOCKS_DNS_COMPLETE:
         case SOCKS_CONNECTING_TO_PROXY:
             return PR_POLL_EXCEPT | PR_POLL_WRITE;
         case SOCKS4_WRITE_CONNECT_REQUEST:
         case SOCKS5_WRITE_AUTH_REQUEST:
         case SOCKS5_WRITE_CONNECT_REQUEST:
             return PR_POLL_WRITE;
         case SOCKS4_READ_CONNECT_RESPONSE:
         case SOCKS5_READ_AUTH_RESPONSE:
@@ -1134,12 +1187,12 @@ nsSOCKSIOLayerAddToSocket(PRInt32 family
     if (NS_FAILED(rv))
     {
         LOGERROR(("PR_PushIOLayer() failed. rv = %x.", rv));
         NS_RELEASE(infoObject);
         PR_DELETE(layer);
         return NS_ERROR_FAILURE;
     }
 
-    *info = infoObject;
+    *info = static_cast<nsISOCKSSocketInfo*>(infoObject);
     NS_ADDREF(*info);
     return NS_OK;
 }
--- a/toolkit/components/downloads/nsDownloadManager.cpp
+++ b/toolkit/components/downloads/nsDownloadManager.cpp
@@ -2874,18 +2874,23 @@ nsDownload::OpenWithApplication()
       nsDownloadManager::gDownloadManagerService->mInPrivateBrowsing) {
     // Use the ExternalHelperAppService to push the temporary file to the list
     // of files to be deleted on exit.
     nsCOMPtr<nsPIExternalAppLauncher> appLauncher(do_GetService
                     (NS_EXTERNALHELPERAPPSERVICE_CONTRACTID));
 
     // Even if we are unable to get this service we return the result
     // of LaunchWithFile() which makes more sense.
-    if (appLauncher)
-      (void)appLauncher->DeleteTemporaryFileOnExit(target);
+    if (appLauncher) {
+      if (nsDownloadManager::gDownloadManagerService->mInPrivateBrowsing) {
+        (void)appLauncher->DeleteTemporaryPrivateFileWhenPossible(target);
+      } else {
+        (void)appLauncher->DeleteTemporaryFileOnExit(target);
+      }
+    }
   }
 
   return retVal;
 }
 
 void
 nsDownload::SetStartTime(PRInt64 aStartTime)
 {
--- a/toolkit/components/telemetry/TelemetryPing.js
+++ b/toolkit/components/telemetry/TelemetryPing.js
@@ -60,16 +60,18 @@ const MEM_HISTOGRAMS = {
 
 // Seconds of idle time before pinging.
 // On idle-daily a gather-telemetry notification is fired, during it probes can
 // start asynchronous tasks to gather data.  On the next idle the data is sent.
 const IDLE_TIMEOUT_SECONDS = 5 * 60;
 
 var gLastMemoryPoll = null;
 
+let gWasDebuggerAttached = false;
+
 function getLocale() {
   return Cc["@mozilla.org/chrome/chrome-registry;1"].
          getService(Ci.nsIXULChromeRegistry).
          getSelectedLocale('global');
 }
 
 XPCOMUtils.defineLazyServiceGetter(this, "Telemetry",
                                    "@mozilla.org/base/telemetry;1",
@@ -116,16 +118,22 @@ function getSimpleMeasurements() {
     for (let p in appTimestamps) {
       if (!(p in ret) && appTimestamps[p])
         ret[p] = appTimestamps[p] - si.process;
     }
   }
 
   ret.startupInterrupted = new Number(Services.startup.interrupted);
 
+  // Update debuggerAttached flag
+  let debugService = Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2);
+  let isDebuggerAttached = debugService.isDebuggerAttached;
+  gWasDebuggerAttached = gWasDebuggerAttached || isDebuggerAttached;
+  ret.debuggerAttached = new Number(gWasDebuggerAttached);
+
   ret.js = Cc["@mozilla.org/js/xpc/XPConnect;1"]
            .getService(Ci.nsIJSEngineTelemetryStats)
            .telemetryValue;
 
   return ret;
 }
 
 /**
@@ -771,16 +779,19 @@ TelemetryPing.prototype = {
         this.detachObservers()
       } else {
         this.attachObservers()
       }
       break;
     case "sessionstore-windows-restored":
       Services.obs.removeObserver(this, "sessionstore-windows-restored");
       this._hasWindowRestoredObserver = false;
+      // Check whether debugger was attached during startup
+      let debugService = Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2);
+      gWasDebuggerAttached = debugService.isDebuggerAttached;
       // fall through
     case "test-gather-startup":
       this.gatherStartupInformation();
       break;
     case "idle-daily":
       // Enqueue to main-thread, otherwise components may be inited by the
       // idle-daily category and miss the gather-telemetry notification.
       Services.tm.mainThread.dispatch((function() {
--- a/toolkit/components/viewsource/content/viewSourceUtils.js
+++ b/toolkit/components/viewsource/content/viewSourceUtils.js
@@ -114,20 +114,38 @@ var gViewSourceUtils = {
           var webBrowserPersist = Components
                                   .classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"]
                                   .createInstance(this.mnsIWebBrowserPersist);
           // the default setting is to not decode. we need to decode.
           webBrowserPersist.persistFlags = this.mnsIWebBrowserPersist.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
           webBrowserPersist.progressListener = this.viewSourceProgressListener;
           webBrowserPersist.saveURI(uri, null, null, null, null, file);
 
-          // register the file to be deleted on app exit
-          Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]
-                    .getService(Components.interfaces.nsPIExternalAppLauncher)
-                    .deleteTemporaryFileOnExit(file);
+          let fromPrivateWindow = false;
+          if (aDocument) {
+            try {
+              fromPrivateWindow =
+                aDocument.defaultView
+                         .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                         .getInterface(Components.interfaces.nsIWebNavigation)
+                         .QueryInterface(Components.interfaces.nsILoadContext)
+                         .usePrivateBrowsing;
+            } catch (e) {
+            }
+          }
+
+          let helperService = Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]
+                                        .getService(Components.interfaces.nsPIExternalAppLauncher);
+          if (fromPrivateWindow) {
+            // register the file to be deleted when possible
+            helperService.deleteTemporaryPrivateFileWhenPossible(file);
+          } else {
+            // register the file to be deleted on app exit
+            helperService.deleteTemporaryFileOnExit(file);
+          }
         } else {
           // we'll use nsIWebPageDescriptor to get the source because it may
           // not have to refetch the file from the server
           // XXXbz this is so broken...  This code doesn't set up this docshell
           // at all correctly; if somehow the view-source stuff managed to
           // execute script we'd be in big trouble here, I suspect.
           var webShell = Components.classes["@mozilla.org/docshell;1"].createInstance();
           webShell.QueryInterface(Components.interfaces.nsIBaseWindow).create();
@@ -259,20 +277,32 @@ var gViewSourceUtils = {
 
           // write the source to the file
           coStream.writeString(webNavigation.document.body.textContent);
           
           // clean up
           coStream.close();
           foStream.close();
 
-          // register the file to be deleted on app exit
-          Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]
-                    .getService(Components.interfaces.nsPIExternalAppLauncher)
-                    .deleteTemporaryFileOnExit(this.file);
+          let fromPrivateWindow =
+            this.data.doc.defaultView
+                         .QueryInterface(Components.interfaces.nsIInterfaceRequestor)
+                         .getInterface(Components.interfaces.nsIWebNavigation)
+                         .QueryInterface(Components.interfaces.nsILoadContext)
+                         .usePrivateBrowsing;
+
+          let helperService = Components.classes["@mozilla.org/uriloader/external-helper-app-service;1"]
+                              .getService(Components.interfaces.nsPIExternalAppLauncher);
+          if (fromPrivateWindow) {
+            // register the file to be deleted when possible
+            helperService.deleteTemporaryPrivateFileWhenPossible(this.file);
+          } else {
+            // register the file to be deleted on app exit
+            helperService.deleteTemporaryFileOnExit(this.file);
+          }
         }
 
         var editorArgs = gViewSourceUtils.buildEditorArgs(this.file.path,
                                                           this.data.lineNumber);
         this.editor.runw(false, editorArgs, editorArgs.length);
 
         gViewSourceUtils.handleCallBack(this.callBack, true, this.data);
       } catch (ex) {
--- a/tools/profiler/TableTicker.cpp
+++ b/tools/profiler/TableTicker.cpp
@@ -293,16 +293,23 @@ public:
       switch (entry.mTagName) {
         case 's':
           sample = b.CreateObject();
           b.DefineProperty(sample, "name", tagStringData);
           frames = b.CreateArray();
           b.DefineProperty(sample, "frames", frames);
           b.ArrayPush(samples, sample);
           break;
+        case 'r':
+          {
+            if (sample) {
+              b.DefineProperty(sample, "responsiveness", entry.mTagFloat);
+            }
+          }
+          break;
         case 'c':
         case 'l':
           {
             if (sample) {
               JSObject *frame = b.CreateObject();
               if (entry.mTagName == 'l') {
                 // Bug 753041
                 // We need a double cast here to tell GCC that we don't want to sign
--- a/uriloader/exthandler/nsExternalHelperAppService.cpp
+++ b/uriloader/exthandler/nsExternalHelperAppService.cpp
@@ -95,24 +95,23 @@
 #include "nsCRT.h"
 
 #include "nsLocalHandlerApp.h"
 
 #include "nsIRandomGenerator.h"
 #include "plbase64.h"
 #include "prmem.h"
 
-#include "nsIPrivateBrowsingService.h"
-
 #include "ContentChild.h"
 #include "nsXULAppAPI.h"
 #include "nsPIDOMWindow.h"
 #include "nsIDocShellTreeOwner.h"
 #include "nsIDocShellTreeItem.h"
 #include "ExternalHelperAppChild.h"
+#include "nsILoadContext.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "AndroidBridge.h"
 #endif
 
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
@@ -499,44 +498,37 @@ NS_IMPL_ISUPPORTS6(
   nsExternalHelperAppService,
   nsIExternalHelperAppService,
   nsPIExternalAppLauncher,
   nsIExternalProtocolService,
   nsIMIMEService,
   nsIObserver,
   nsISupportsWeakReference)
 
-nsExternalHelperAppService::nsExternalHelperAppService() :
-  mInPrivateBrowsing(false)
+nsExternalHelperAppService::nsExternalHelperAppService()
 {
 }
 nsresult nsExternalHelperAppService::Init()
 {
-  nsCOMPtr<nsIPrivateBrowsingService> pbs =
-    do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
-  if (pbs) {
-    pbs->GetPrivateBrowsingEnabled(&mInPrivateBrowsing);
-  }
-
   // Add an observer for profile change
   nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
   if (!obs)
     return NS_ERROR_FAILURE;
 
 #ifdef PR_LOGGING
   if (!mLog) {
     mLog = PR_NewLogModule("HelperAppService");
     if (!mLog)
       return NS_ERROR_OUT_OF_MEMORY;
   }
 #endif
 
   nsresult rv = obs->AddObserver(this, "profile-before-change", true);
   NS_ENSURE_SUCCESS(rv, rv);
-  return obs->AddObserver(this, NS_PRIVATE_BROWSING_SWITCH_TOPIC, true);
+  return obs->AddObserver(this, "last-pb-context-exited", true);
 }
 
 nsExternalHelperAppService::~nsExternalHelperAppService()
 {
 }
 
 static PRInt64 GetContentLengthAsInt64(nsIRequest *request)
 {
@@ -918,32 +910,44 @@ NS_IMETHODIMP nsExternalHelperAppService
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////
 // Methods related to deleting temporary files on exit
 //////////////////////////////////////////////////////////////////////////////////////////////////////
 
-NS_IMETHODIMP nsExternalHelperAppService::DeleteTemporaryFileOnExit(nsIFile * aTemporaryFile)
+/* static */
+nsresult
+nsExternalHelperAppService::DeleteTemporaryFileHelper(nsIFile * aTemporaryFile,
+                                                      nsCOMArray<nsIFile> &aFileList)
 {
   bool isFile = false;
 
   // as a safety measure, make sure the nsIFile is really a file and not a directory object.
   aTemporaryFile->IsFile(&isFile);
   if (!isFile) return NS_OK;
 
-  if (mInPrivateBrowsing)
-    mTemporaryPrivateFilesList.AppendObject(aTemporaryFile);
-  else
-    mTemporaryFilesList.AppendObject(aTemporaryFile);
+  aFileList.AppendObject(aTemporaryFile);
 
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsExternalHelperAppService::DeleteTemporaryFileOnExit(nsIFile* aTemporaryFile)
+{
+  return DeleteTemporaryFileHelper(aTemporaryFile, mTemporaryFilesList);
+}
+
+NS_IMETHODIMP
+nsExternalHelperAppService::DeleteTemporaryPrivateFileWhenPossible(nsIFile* aTemporaryFile)
+{
+  return DeleteTemporaryFileHelper(aTemporaryFile, mTemporaryPrivateFilesList);
+}
+
 void nsExternalHelperAppService::FixFilePermissions(nsIFile* aFile)
 {
   // This space intentionally left blank
 }
 
 void nsExternalHelperAppService::ExpungeTemporaryFilesHelper(nsCOMArray<nsIFile> &fileList)
 {
   PRInt32 numEntries = fileList.Count();
@@ -1047,23 +1051,18 @@ nsExternalHelperAppService::SetProtocolH
 }
  
 // XPCOM profile change observer
 NS_IMETHODIMP
 nsExternalHelperAppService::Observe(nsISupports *aSubject, const char *aTopic, const PRUnichar *someData )
 {
   if (!strcmp(aTopic, "profile-before-change")) {
     ExpungeTemporaryFiles();
-  } else if (!strcmp(aTopic, NS_PRIVATE_BROWSING_SWITCH_TOPIC)) {
-    if (NS_LITERAL_STRING(NS_PRIVATE_BROWSING_ENTER).Equals(someData))
-      mInPrivateBrowsing = true;
-    else if (NS_LITERAL_STRING(NS_PRIVATE_BROWSING_LEAVE).Equals(someData)) {
-      mInPrivateBrowsing = false;
-      ExpungeTemporaryPrivateFiles();
-    }
+  } else if (!strcmp(aTopic, "last-pb-context-exited")) {
+    ExpungeTemporaryPrivateFiles();
   }
   return NS_OK;
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////
 // begin external app handler implementation 
 //////////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -2175,35 +2174,50 @@ nsresult nsExternalAppHandler::OpenWithA
     bool deleteTempFileOnExit =
       Preferences::GetBool("browser.helperApps.deleteTempFileOnExit",
 #if !defined(XP_MACOSX)
                            true);
 #else
                            false);
 #endif
 
+    // See whether the channel has been opened in private browsing mode
+    bool inPrivateBrowsing = false;
+    NS_ASSERTION(mRequest, "This should never be called with a null request");
+    nsCOMPtr<nsIChannel> channel = do_QueryInterface(mRequest);
+    if (channel) {
+      nsCOMPtr<nsILoadContext> ctx;
+      NS_QueryNotificationCallbacks(channel, ctx);
+      if (ctx) {
+        inPrivateBrowsing = ctx->UsePrivateBrowsing();
+      }
+    }
+
     // make the tmp file readonly so users won't edit it and lose the changes
     // only if we're going to delete the file
-    if (deleteTempFileOnExit || mExtProtSvc->InPrivateBrowsing())
+    if (deleteTempFileOnExit || inPrivateBrowsing)
       mFinalFileDestination->SetPermissions(0400);
 
     rv = mMimeInfo->LaunchWithFile(mFinalFileDestination);
     if (NS_FAILED(rv))
     {
       // Send error notification.
       nsAutoString path;
       mFinalFileDestination->GetPath(path);
       SendStatusChange(kLaunchError, rv, nsnull, path);
       Cancel(rv); // Cancel, and clean up temp file.
     }
     // Always schedule files to be deleted at the end of the private browsing
     // mode, regardless of the value of the pref.
-    else if (deleteTempFileOnExit || mExtProtSvc->InPrivateBrowsing()) {
+    else if (deleteTempFileOnExit) {
       mExtProtSvc->DeleteTemporaryFileOnExit(mFinalFileDestination);
     }
+    else if (inPrivateBrowsing) {
+      mExtProtSvc->DeleteTemporaryPrivateFileWhenPossible(mFinalFileDestination);
+    }
   }
 
   return rv;
 }
 
 // LaunchWithApplication should only be called by the helper app dialog which allows
 // the user to say launch with application or save to disk. It doesn't actually 
 // perform launch with application. That won't happen until we are done downloading
--- a/uriloader/exthandler/nsExternalHelperAppService.h
+++ b/uriloader/exthandler/nsExternalHelperAppService.h
@@ -106,22 +106,16 @@ public:
    *                        application path.
    */
   virtual nsresult GetFileTokenForPath(const PRUnichar * platformAppPath,
                                        nsIFile ** aFile);
 
   virtual NS_HIDDEN_(nsresult) OSProtocolHandlerExists(const char *aScheme,
                                                        bool *aExists) = 0;
 
-  /**
-   * Simple accessor to let nsExternalAppHandler know if we are currently
-   * inside the private browsing mode.
-   */
-  bool InPrivateBrowsing() const { return mInPrivateBrowsing; }
-
 protected:
   /**
    * Searches the "extra" array of MIMEInfo objects for an object
    * with a specific type. If found, it will modify the passed-in
    * MIMEInfo. Otherwise, it will return an error and the MIMEInfo
    * will be untouched.
    * @param aContentType The type to search for.
    * @param aMIMEInfo    [inout] The mime info, if found
@@ -168,16 +162,21 @@ protected:
   friend class nsExternalAppHandler;
   friend class nsExternalLoadRequest;
 
   /**
    * Helper function for ExpungeTemporaryFiles and ExpungeTemporaryPrivateFiles
    */
   static void ExpungeTemporaryFilesHelper(nsCOMArray<nsIFile> &fileList);
   /**
+   * Helper function for DeleteTemporaryFileOnExit and DeleteTemporaryPrivateFileWhenPossible
+   */
+  static nsresult DeleteTemporaryFileHelper(nsIFile* aTemporaryFile,
+                                            nsCOMArray<nsIFile> &aFileList);
+  /**
    * Functions related to the tempory file cleanup service provided by
    * nsExternalHelperAppService
    */
   void ExpungeTemporaryFiles();
   /**
    * Functions related to the tempory file cleanup service provided by
    * nsExternalHelperAppService (for the temporary files added during
    * the private browsing mode)
@@ -187,20 +186,16 @@ protected:
    * Array for the files that should be deleted
    */
   nsCOMArray<nsIFile> mTemporaryFilesList;
   /**
    * Array for the files that should be deleted (for the temporary files
    * added during the private browsing mode)
    */
   nsCOMArray<nsIFile> mTemporaryPrivateFilesList;
-  /**
-   * Whether we are in private browsing mode
-   */
-  bool mInPrivateBrowsing;
 };
 
 /**
  * An external app handler is just a small little class that presents itself as
  * a nsIStreamListener. It saves the incoming data into a temp file. The handler
  * is bound to an application when it is created. When it receives an
  * OnStopRequest it launches the application using the temp file it has
  * stored the data into.  We create a handler every time we have to process
--- a/uriloader/exthandler/nsIExternalHelperAppService.idl
+++ b/uriloader/exthandler/nsIExternalHelperAppService.idl
@@ -48,25 +48,30 @@ interface nsIExternalHelperAppService : 
                                     in ACString aEncodingType);
 
 };
 
 /**
  * This is a private interface shared between external app handlers and the platform specific
  * external helper app service
  */
-[scriptable, uuid(d0b5d7d3-9565-403d-9fb5-e5089c4567c6)]
+[scriptable, uuid(6613e2e7-feab-4e3a-bb1f-b03200d544ec)]
 interface nsPIExternalAppLauncher : nsISupports
 {
   /**
    * mscott --> eventually I should move this into a new service so other
    * consumers can add temporary files they want deleted on exit.
    * @param aTemporaryFile A temporary file we should delete on exit.
    */
   void deleteTemporaryFileOnExit(in nsIFile aTemporaryFile); 
+  /**
+   * Delete a temporary file created inside private browsing mode when
+   * the private browsing mode has ended.
+   */
+  void deleteTemporaryPrivateFileWhenPossible(in nsIFile aTemporaryFile);
 };
 
 /**
  * A helper app launcher is a small object created to handle the launching
  * of an external application.
  *
  * Note that cancelling the load via the nsICancelable interface will release
  * the reference to the launcher dialog.
--- a/widget/xpwidgets/nsIdleService.cpp
+++ b/widget/xpwidgets/nsIdleService.cpp
@@ -173,16 +173,20 @@ nsIdleServiceDaily::~nsIdleServiceDaily(
     mTimer = nsnull;
   }
 }
 
 // static
 void
 nsIdleServiceDaily::DailyCallback(nsITimer* aTimer, void* aClosure)
 {
+#ifdef ANDROID
+  __android_log_print(ANDROID_LOG_INFO, "IdleService", "DailyCallback running, registering Idle observer");
+#endif
+
   nsIdleServiceDaily* me = static_cast<nsIdleServiceDaily*>(aClosure);
 
   // The one thing we do every day is to start waiting for the user to "have
   // a significant idle time".
   (void)me->mIdleService->AddIdleObserver(me,
                                           DAILY_SIGNIFICANT_IDLE_SERVICE_SEC);
 }
 
--- a/xpcom/base/nsDebugImpl.cpp
+++ b/xpcom/base/nsDebugImpl.cpp
@@ -38,16 +38,23 @@
 #include <signal.h>
 #endif
 
 #if defined(XP_WIN)
 #include <tchar.h>
 #include "nsString.h"
 #endif
 
+#if defined(XP_MACOSX)
+#include <stdbool.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/sysctl.h>
+#endif
+
 #include "mozilla/mozalloc_abort.h"
 
 static void
 Abort(const char *aMsg);
 
 static void
 RealBreak();
 
@@ -131,16 +138,50 @@ nsDebugImpl::GetIsDebugBuild(bool* aResu
 
 NS_IMETHODIMP
 nsDebugImpl::GetAssertionCount(PRInt32* aResult)
 {
   *aResult = gAssertionCount;
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsDebugImpl::GetIsDebuggerAttached(bool* aResult)
+{
+  *aResult = false;
+
+#if defined(XP_WIN)
+  *aResult = ::IsDebuggerPresent();
+#elif defined(XP_MACOSX)
+  // Specify the info we're looking for
+  int mib[4];
+  mib[0] = CTL_KERN;
+  mib[1] = KERN_PROC;
+  mib[2] = KERN_PROC_PID;
+  mib[3] = getpid();
+  size_t mibSize = sizeof(mib) / sizeof(int);
+
+  struct kinfo_proc info;
+  size_t infoSize = sizeof(info);
+  memset(&info, 0, infoSize);
+
+  if (sysctl(mib, mibSize, &info, &infoSize, NULL, 0)) {
+    // if the call fails, default to false
+    *aResult = false;
+    return NS_OK;
+  }
+
+  if (info.kp_proc.p_flag & P_TRACED) {
+    *aResult = true;
+  }
+#endif
+
+  return NS_OK;
+}
+
 /* static */ void
 nsDebugImpl::SetMultiprocessMode(const char *aDesc)
 {
   sIsMultiprocess = true;
   sMultiprocessDescription = aDesc;
 }
 
 /**
--- a/xpcom/base/nsIDebug2.idl
+++ b/xpcom/base/nsIDebug2.idl
@@ -2,23 +2,29 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* interface to expose information about calls to NS_DebugBreak */
 
 #include "nsIDebug.idl"
 
-[scriptable, uuid(9c9307ed-480a-4f2a-8f29-21378c03bcbc)]
+[scriptable, uuid(6cb17fec-cdf7-4f7c-b267-37a0acaa9cf1)]
 interface nsIDebug2 : nsIDebug
 {
     /**
      * Whether XPCOM was compiled with DEBUG defined.  This often
      * correlates to whether other code (e.g., Firefox, XULRunner) was
      * compiled with DEBUG defined.
      */
     readonly attribute boolean isDebugBuild;
 
     /**
      * The number of assertions since process start.
      */
     readonly attribute long assertionCount;
+
+    /**
+     * Whether a debugger is currently attached.
+     * Supports Windows + Mac
+     */
+    readonly attribute bool isDebuggerAttached;
 };