Merge some known-good changesets from m-i to m-c.
authorMs2ger <ms2ger@gmail.com>
Tue, 16 Aug 2011 12:09:24 +0200
changeset 75324 630e28e90986596a4855f8f67cd8072f2c1bdf6b
parent 75323 edd7aab15b8b902f77ef4a3910e9a1db5c512404 (current diff)
parent 75314 37dedb70a68adaf8d74fb2c2e58377ffb89e0449 (diff)
child 75364 35657230a209b1d8b709d7da1b2cc1f702332115
push id2
push userbsmedberg@mozilla.com
push dateFri, 19 Aug 2011 14:38:13 +0000
milestone8.0a1
Merge some known-good changesets from m-i to m-c.
--- a/build/autoconf/mozconfig-find
+++ b/build/autoconf/mozconfig-find
@@ -41,16 +41,37 @@
 #    command-line. The .mozconfig file is searched for in the 
 #    order:
 #       if $MOZCONFIG is set, use that.
 #       Otherwise, use $TOPSRCDIR/.mozconfig
 #       Otherwise, use $HOME/.mozconfig
 #
 topsrcdir=$1
 
+abspath() {
+  if uname -s | grep -q MINGW; then
+    # We have no way to figure out whether we're in gmake or pymake right
+    # now. gmake gives us Unix-style paths while pymake gives us Windows-style
+    # paths, so attempt to handle both.
+    regexes='^\([A-Za-z]:\|\\\\\|\/\) ^\/'
+  else
+    regexes='^\/'
+  fi
+
+  for regex in $regexes; do
+    if echo $1 | grep -q $regex; then
+      echo $1
+      exit 0
+    fi
+  done
+
+  # If we're at this point, we have a relative path
+  echo `pwd`/$1
+}
+
 for _config in "$MOZCONFIG" \
                "$MOZ_MYCONFIG"
 do
   if [ -n "$_config" ] && ! [ -f "$_config" ]; then
     echo "Specified MOZCONFIG \"$_config\" does not exist!"
     exit 1
   fi
 done
@@ -61,12 +82,12 @@ for _config in "$MOZCONFIG" \
                "$topsrcdir/mozconfig" \
                "$topsrcdir/mozconfig.sh" \
                "$topsrcdir/myconfig.sh" \
                "$HOME/.mozconfig" \
                "$HOME/.mozconfig.sh" \
                "$HOME/.mozmyconfig.sh"
 do
   if test -f "$_config"; then
-    echo "$_config";
+    echo `abspath $_config`
     exit 0
   fi
 done
--- a/build/win32/Makefile.in
+++ b/build/win32/Makefile.in
@@ -37,16 +37,18 @@
 
 DEPTH = ../..
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
+NO_PROFILE_GUIDED_OPTIMIZE = 1
+
 ifdef ENABLE_TESTS
 
 ifdef _MSC_VER
 ifneq ($(OS_TEST),x86_64)
 DIRS += vmwarerecordinghelper
 endif
 endif
 
--- a/caps/src/nsNullPrincipalURI.cpp
+++ b/caps/src/nsNullPrincipalURI.cpp
@@ -197,16 +197,30 @@ nsNullPrincipalURI::SetScheme(const nsAC
 
 NS_IMETHODIMP
 nsNullPrincipalURI::GetSpec(nsACString &_spec)
 {
   _spec = mScheme + NS_LITERAL_CSTRING(":") + mPath;
   return NS_OK;
 }
 
+// result may contain unescaped UTF-8 characters
+NS_IMETHODIMP
+nsNullPrincipalURI::GetSpecIgnoringRef(nsACString &result)
+{
+  return GetSpec(result);
+}
+
+NS_IMETHODIMP
+nsNullPrincipalURI::GetHasRef(PRBool *result)
+{
+  *result = PR_FALSE;
+  return NS_OK;
+}
+
 NS_IMETHODIMP
 nsNullPrincipalURI::SetSpec(const nsACString &aSpec)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsNullPrincipalURI::GetUsername(nsACString &_username)
--- a/content/canvas/src/WebGLContext.cpp
+++ b/content/canvas/src/WebGLContext.cpp
@@ -932,28 +932,35 @@ WebGLContext::MozGetUnderlyingParamStrin
 
     default:
         return NS_ERROR_INVALID_ARG;
     }
 
     return NS_OK;
 }
 
+bool WebGLContext::IsExtensionSupported(WebGLExtensionID ei)
+{
+    if (ei == WebGL_OES_texture_float) {
+        MakeContextCurrent();
+        return gl->IsExtensionSupported(gl->IsGLES2() ? GLContext::OES_texture_float
+                                                      : GLContext::ARB_texture_float);
+    }
+    return false;
+}
+
 NS_IMETHODIMP
 WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
 {
     *retval = nsnull;
 
     // handle simple extensions that don't need custom objects first
     WebGLExtensionID ei = WebGLExtensionID_Max;
     if (aName.EqualsLiteral("OES_texture_float")) {
-        MakeContextCurrent();
-
-        PRBool avail = gl->IsExtensionSupported(gl->IsGLES2() ? "GL_OES_texture_float" : "GL_ARB_texture_float");
-        if (avail)
+        if (IsExtensionSupported(WebGL_OES_texture_float))
             ei = WebGL_OES_texture_float;
     }
 
     // create a WebGLExtension object for extensions that don't
     // have any additional tokens or methods
     if (ei != WebGLExtensionID_Max) {
         if (!IsExtensionEnabled(ei)) {
             mEnabledExtensions[ei] = new WebGLExtension(this);
@@ -1240,17 +1247,18 @@ WebGLActiveInfo::GetName(nsAString & aNa
 NS_IMETHODIMP
 WebGLContext::GetSupportedExtensions(nsIVariant **retval)
 {
     nsCOMPtr<nsIWritableVariant> wrval = do_CreateInstance("@mozilla.org/variant;1");
     NS_ENSURE_TRUE(wrval, NS_ERROR_FAILURE);
 
     nsTArray<const char *> extList;
 
-    /* no extensions to add to extList */
+    if (IsExtensionSupported(WebGL_OES_texture_float))
+        extList.InsertElementAt(extList.Length(), "OES_texture_float");
 
     nsresult rv;
     if (extList.Length() > 0) {
         rv = wrval->SetAsArray(nsIDataType::VTYPE_CHAR_STR, nsnull,
                                extList.Length(), &extList[0]);
     } else {
         rv = wrval->SetAsEmptyArray();
     }
--- a/content/canvas/src/WebGLContext.h
+++ b/content/canvas/src/WebGLContext.h
@@ -467,16 +467,17 @@ protected:
         WebGL_OES_texture_float,
         WebGLExtensionID_Max
     };
     nsCOMPtr<nsIWebGLExtension> mEnabledExtensions[WebGLExtensionID_Max];
     PRBool IsExtensionEnabled(WebGLExtensionID ext) const {
         NS_ABORT_IF_FALSE(ext >= 0 && ext < WebGLExtensionID_Max, "bogus index!");
         return mEnabledExtensions[ext] != nsnull;
     }
+    bool IsExtensionSupported(WebGLExtensionID ei);
 
     PRBool InitAndValidateGL();
     PRBool ValidateBuffers(PRInt32* maxAllowedCount, const char *info);
     PRBool ValidateCapabilityEnum(WebGLenum cap, const char *info);
     PRBool ValidateBlendEquationEnum(WebGLenum cap, const char *info);
     PRBool ValidateBlendFuncDstEnum(WebGLenum mode, const char *info);
     PRBool ValidateBlendFuncSrcEnum(WebGLenum mode, const char *info);
     PRBool ValidateBlendFuncEnumsCompatibility(WebGLenum sfactor, WebGLenum dfactor, const char *info);
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -210,35 +210,34 @@
 
 #if NS_PRINT_PREVIEW
 #include "nsIDocumentViewerPrint.h"
 #include "nsIWebBrowserPrint.h"
 #endif
 
 #include "nsPluginError.h"
 #include "nsContentUtils.h"
+#include "nsContentErrors.h"
+#include "nsIChannelPolicy.h"
+#include "nsIContentSecurityPolicy.h"
+
+#include "nsXULAppAPI.h"
+
+#include "nsDOMNavigationTiming.h"
+#include "nsITimedChannel.h"
 
 static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
                      NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
 static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID);
 
 #if defined(DEBUG_bryner) || defined(DEBUG_chb)
 //#define DEBUG_DOCSHELL_FOCUS
 #define DEBUG_PAGE_CACHE
 #endif
 
-#include "nsContentErrors.h"
-#include "nsIChannelPolicy.h"
-#include "nsIContentSecurityPolicy.h"
-
-#include "nsXULAppAPI.h"
-
-#include "nsDOMNavigationTiming.h"
-#include "nsITimedChannel.h"
-
 using namespace mozilla;
 
 // Number of documents currently loading
 static PRInt32 gNumberOfDocumentsLoading = 0;
 
 // Global count of existing docshells.
 static PRInt32 gDocShellCount = 0;
 
@@ -917,17 +916,18 @@ NS_IMETHODIMP nsDocShell::GetInterface(c
     else if (aIID.Equals(NS_GET_IID(nsIURIContentListener))) {
         *aSink = mContentListener;
     }
     else if (aIID.Equals(NS_GET_IID(nsIScriptGlobalObject)) &&
              NS_SUCCEEDED(EnsureScriptEnvironment())) {
         *aSink = mScriptGlobal;
     }
     else if ((aIID.Equals(NS_GET_IID(nsPIDOMWindow)) ||
-              aIID.Equals(NS_GET_IID(nsIDOMWindow))) &&
+              aIID.Equals(NS_GET_IID(nsIDOMWindow)) ||
+              aIID.Equals(NS_GET_IID(nsIDOMWindowInternal))) &&
              NS_SUCCEEDED(EnsureScriptEnvironment())) {
         return mScriptGlobal->QueryInterface(aIID, aSink);
     }
     else if (aIID.Equals(NS_GET_IID(nsIDOMDocument)) &&
              NS_SUCCEEDED(EnsureContentViewer())) {
         mContentViewer->GetDOMDocument((nsIDOMDocument **) aSink);
         return *aSink ? NS_OK : NS_NOINTERFACE;
     }
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -257,16 +257,17 @@ static const char kStorageEnabled[] = "d
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using mozilla::TimeStamp;
 using mozilla::TimeDuration;
 
 nsIDOMStorageList *nsGlobalWindow::sGlobalStorageList  = nsnull;
 nsGlobalWindow::WindowByIdTable *nsGlobalWindow::sWindowsById = nsnull;
+bool nsGlobalWindow::sWarnedAboutWindowInternal = false;
 
 static nsIEntropyCollector *gEntropyCollector          = nsnull;
 static PRInt32              gRefCnt                    = 0;
 static PRInt32              gOpenPopupSpamCount        = 0;
 static PopupControlState    gPopupControlState         = openAbused;
 static PRInt32              gRunningTimeoutDepth       = 0;
 static PRPackedBool         gMouseDown                 = PR_FALSE;
 static PRPackedBool         gDragServiceDisabled       = PR_FALSE;
@@ -1343,16 +1344,27 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsGlobalW
 DOMCI_DATA(Window, nsGlobalWindow)
 
 // QueryInterface implementation for nsGlobalWindow
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsGlobalWindow)
   // Make sure this matches the cast in nsGlobalWindow::FromWrapper()
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsIDOMWindow)
   NS_INTERFACE_MAP_ENTRY(nsIDOMJSWindow)
+  if (aIID.Equals(NS_GET_IID(nsIDOMWindowInternal))) {
+    foundInterface = static_cast<nsIDOMWindowInternal*>(this);
+    if (!sWarnedAboutWindowInternal) {
+      sWarnedAboutWindowInternal = true;
+      nsContentUtils::ReportToConsole(nsContentUtils::eDOM_PROPERTIES,
+                                      "nsIDOMWindowInternalWarning",
+                                      nsnull, 0, nsnull, EmptyString(), 0, 0,
+                                      nsIScriptError::warningFlag,
+                                      "Extensions", mWindowID);
+    }
+  } else
   NS_INTERFACE_MAP_ENTRY(nsIScriptGlobalObject)
   NS_INTERFACE_MAP_ENTRY(nsIScriptObjectPrincipal)
   NS_INTERFACE_MAP_ENTRY(nsIDOMEventTarget)
   NS_INTERFACE_MAP_ENTRY(nsPIDOMWindow)
   NS_INTERFACE_MAP_ENTRY(nsIDOMStorageIndexedDB)
   NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
   NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
   NS_INTERFACE_MAP_ENTRY(nsIDOMWindowPerformance)
@@ -4921,18 +4933,17 @@ nsGlobalWindow::Focus()
     baseWin->GetVisibility(&isVisible);
   }
 
   if (!isVisible) {
     // A hidden tab is being focused, ignore this call.
     return NS_OK;
   }
 
-  nsIDOMWindow *caller =
-    static_cast<nsIDOMWindow*>(nsContentUtils::GetWindowFromCaller());
+  nsIDOMWindow *caller = nsContentUtils::GetWindowFromCaller();
   nsCOMPtr<nsIDOMWindow> opener;
   GetOpener(getter_AddRefs(opener));
 
   // Enforce dom.disable_window_flip (for non-chrome), but still allow the
   // window which opened us to raise us at times when popups are allowed
   // (bugs 355482 and 369306).
   PRBool canFocus = CanSetProperty("dom.disable_window_flip") ||
                     (opener == caller &&
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -962,16 +962,17 @@ protected:
   nsRefPtr<nsDOMMozURLProperty> mURLProperty;
 
   friend class nsDOMScriptableHelper;
   friend class nsDOMWindowUtils;
   friend class PostMessageEvent;
   static nsIDOMStorageList* sGlobalStorageList;
 
   static WindowByIdTable* sWindowsById;
+  static bool sWarnedAboutWindowInternal;
 };
 
 /*
  * nsGlobalChromeWindow inherits from nsGlobalWindow. It is the global
  * object created for a Chrome Window only.
  */
 class nsGlobalChromeWindow : public nsGlobalWindow,
                              public nsIDOMChromeWindow
--- a/dom/base/nsPIDOMWindow.h
+++ b/dom/base/nsPIDOMWindow.h
@@ -75,20 +75,20 @@ class nsIDocument;
 class nsIScriptTimeoutHandler;
 struct nsTimeout;
 class nsScriptObjectHolder;
 class nsXBLPrototypeHandler;
 class nsIArray;
 class nsPIWindowRoot;
 
 #define NS_PIDOMWINDOW_IID \
-{ 0x1bfacc26, 0xad77, 0x42bb, \
-  { 0xb9, 0xbb, 0xa0, 0x19, 0xc8, 0x27, 0x5c, 0x0e } }
+{ 0xeee816d2, 0x2f08, 0x4b34, \
+  { 0x97, 0x47, 0x5e, 0x5a, 0xcd, 0xc3, 0x56, 0xfa } }
 
-class nsPIDOMWindow : public nsIDOMWindow
+class nsPIDOMWindow : public nsIDOMWindowInternal
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_PIDOMWINDOW_IID)
 
   virtual nsPIDOMWindow* GetPrivateRoot() = 0;
 
   virtual void ActivateOrDeactivate(PRBool aActivate) = 0;
 
--- a/dom/indexedDB/nsIIDBCursor.idl
+++ b/dom/indexedDB/nsIIDBCursor.idl
@@ -37,20 +37,16 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 
 interface nsIIDBRequest;
 interface nsIVariant;
 
-%{C++
-#include "jspubtd.h"
-%}
-
 /**
  * IDBCursor interface.  See
  * http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBCursor for more
  * information.
  */
 [scriptable, uuid(adee4085-68cd-4568-9d74-e3d32b6dc5c5)]
 interface nsIIDBCursor : nsISupports
 {
--- a/dom/indexedDB/nsIIDBDatabase.idl
+++ b/dom/indexedDB/nsIIDBDatabase.idl
@@ -41,20 +41,16 @@
 
 interface nsIVariant;
 interface nsIIDBObjectStore;
 interface nsIIDBRequest;
 interface nsIIDBTransaction;
 interface nsIDOMDOMStringList;
 interface nsIDOMEventListener;
 
-%{C++
-#include "jspubtd.h"
-%}
-
 /**
  * IDBDatabase interface.  See
  * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBDatabase
  * for more information.
  */
 [scriptable, uuid(42b38d02-1a29-45f0-99ef-04fd5b441270)]
 interface nsIIDBDatabase : nsISupports
 {
--- a/dom/indexedDB/nsIIDBFactory.idl
+++ b/dom/indexedDB/nsIIDBFactory.idl
@@ -39,20 +39,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 
 interface nsIIDBKeyRange;
 interface nsIIDBRequest;
 interface nsIVariant;
 
-%{C++
-#include "jspubtd.h"
-%}
-
 /**
  * Interface that defines the indexedDB property on a window.  See
  * http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBFactory
  * for more information.
  */
 [scriptable, uuid(137d17a5-fac5-4788-87b5-bc3806d7cfaf)]
 interface nsIIDBFactory : nsISupports
 {
--- a/dom/indexedDB/nsIIDBObjectStore.idl
+++ b/dom/indexedDB/nsIIDBObjectStore.idl
@@ -41,20 +41,16 @@
 
 interface nsIIDBIndex;
 interface nsIIDBKeyRange;
 interface nsIIDBRequest;
 interface nsIIDBTransaction;
 interface nsIVariant;
 interface nsIDOMDOMStringList;
 
-%{C++
-#include "jspubtd.h"
-%}
-
 /**
  * nsIIDBObjectStore interface.  See
  * http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-nsIIDBObjectStore
  * for more information.
  */
 [scriptable, uuid(6a65dc92-66e3-407a-a370-590a6c54664a)]
 interface nsIIDBObjectStore : nsISupports
 {
--- a/dom/interfaces/base/nsIDOMWindow.idl
+++ b/dom/interfaces/base/nsIDOMWindow.idl
@@ -36,20 +36,16 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "domstubs.idl"
 
-%{ C++
-#include "jspubtd.h"
-%}
-
 interface nsIAnimationFrameListener;
 interface nsIControllers;
 interface nsIDOMBlob;
 interface nsIDOMLocation;
 interface nsIDOMMediaQueryList;
 interface nsIDOMOfflineResourceList;
 interface nsIDOMPerformance;
 interface nsIDOMStorage;
@@ -443,8 +439,15 @@ interface nsIDOMWindow : nsISupports
 [scriptable, uuid(2146c906-57f7-486c-a1b4-8cdb57ef577f)]
 interface nsIDOMWindowPerformance : nsISupports
 {
   /**
    * A namespace to hold performance related data and statistics.
    */
   readonly attribute nsIDOMPerformance performance;
 };
+
+/**
+ * Empty interface for compatibility with older versions.
+ * @deprecated Use nsIDOMWindow instead
+ */
+[scriptable, uuid(8614bdb7-5b07-4d00-a7ba-4d44697a343d)]
+interface nsIDOMWindowInternal : nsIDOMWindow {};
--- a/dom/interfaces/events/nsIDOMMessageEvent.idl
+++ b/dom/interfaces/events/nsIDOMMessageEvent.idl
@@ -33,20 +33,16 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMEvent.idl"
 
-%{ C++
-#include "jspubtd.h"
-%}
-
 /**
  * The nsIDOMMessageEvent interface is used for server-sent events and for
  * cross-domain messaging.
  *
  * For more information on this interface, please see
  * http://www.whatwg.org/specs/web-apps/current-work/#messageevent
  */
 [scriptable, uuid(dc8ec5c6-ebf2-4f95-be99-cd13e3c0d0c6)]
--- a/dom/interfaces/events/nsIDOMNotifyAudioAvailableEvent.idl
+++ b/dom/interfaces/events/nsIDOMNotifyAudioAvailableEvent.idl
@@ -35,20 +35,16 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMEvent.idl"
 #include "nsIVariant.idl"
 
-%{ C++
-#include "jspubtd.h"
-%}
-
 [scriptable, uuid(6250652d-7a6a-49a4-a2ee-9114e1e83427)]
 interface nsIDOMNotifyAudioAvailableEvent : nsIDOMEvent
 {
   [implicit_jscontext]
   readonly attribute jsval  frameBuffer;
 
   readonly attribute float  time;
 
--- a/dom/interfaces/html/nsIDOMHTMLDocument.idl
+++ b/dom/interfaces/html/nsIDOMHTMLDocument.idl
@@ -34,20 +34,16 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIDOMDocument.idl"
 
-%{C++
-#include "jspubtd.h"
-%}
-
 /**
  * The nsIDOMHTMLDocument interface is the interface to a [X]HTML
  * document object.
  *
  * @see <http://www.whatwg.org/html/>
  */
 interface nsISelection;
 
--- a/dom/interfaces/json/nsIJSON.idl
+++ b/dom/interfaces/json/nsIJSON.idl
@@ -37,20 +37,16 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "domstubs.idl"
 
 interface nsIInputStream;
 interface nsIOutputStream;
 interface nsIScriptGlobalObject;
 
-%{ C++
-#include "jspubtd.h"
-%}
-
 [ptr] native JSValPtr(jsval);
 [ptr] native JSContext(JSContext);
 
 /**
  * Encode and decode JSON text.
  */
 [scriptable, uuid(a4d68b4e-0c0b-4c7c-b540-ef2f9834171f)]
 interface nsIJSON : nsISupports
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -594,16 +594,29 @@ ContentParent::RecvGetIconForExtension(c
 
     bits->AppendElements(aIconSize * aIconSize * 4);
 
     AndroidBridge::Bridge()->GetIconForExtension(aFileExt, aIconSize, bits->Elements());
 #endif
     return true;
 }
 
+bool
+ContentParent::RecvGetShowPasswordSetting(PRBool* showPassword)
+{
+    // default behavior is to show the last password character
+    *showPassword = PR_TRUE;
+#ifdef ANDROID
+    NS_ASSERTION(AndroidBridge::Bridge() != nsnull, "AndroidBridge is not available");
+    if (AndroidBridge::Bridge() != nsnull)
+        *showPassword = AndroidBridge::Bridge()->GetShowPasswordSetting();
+#endif
+    return true;
+}
+
 NS_IMPL_THREADSAFE_ISUPPORTS4(ContentParent,
                               nsIObserver,
                               nsIThreadObserver,
                               nsIDOMGeoPositionCallback,
                               nsIDeviceMotionListener)
 
 NS_IMETHODIMP
 ContentParent::Observe(nsISupports* aSubject,
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -162,16 +162,17 @@ private:
 
     virtual bool RecvSetClipboardText(const nsString& text, const PRInt32& whichClipboard);
     virtual bool RecvGetClipboardText(const PRInt32& whichClipboard, nsString* text);
     virtual bool RecvEmptyClipboard();
     virtual bool RecvClipboardHasText(PRBool* hasText);
 
     virtual bool RecvGetSystemColors(const PRUint32& colorsCount, InfallibleTArray<PRUint32>* colors);
     virtual bool RecvGetIconForExtension(const nsCString& aFileExt, const PRUint32& aIconSize, InfallibleTArray<PRUint8>* bits);
+    virtual bool RecvGetShowPasswordSetting(PRBool* showPassword);
 
     virtual bool RecvStartVisitedQuery(const IPC::URI& uri);
 
     virtual bool RecvVisitURI(const IPC::URI& uri,
                               const IPC::URI& referrer,
                               const PRUint32& flags);
 
     virtual bool RecvSetURITitle(const IPC::URI& uri,
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -200,15 +200,18 @@ parent:
         returns (PRBool hasText);
 
     sync GetSystemColors(PRUint32 colorsCount)
         returns (PRUint32[] colors);
 
     sync GetIconForExtension(nsCString aFileExt, PRUint32 aIconSize)
         returns (PRUint8[] bits);
 
+    sync GetShowPasswordSetting()
+        returns (PRBool showPassword);
+
 both:
      AsyncMessage(nsString aMessage, nsString aJSON);
 
 };
 
 }
 }
--- a/dom/locales/en-US/chrome/dom/dom.properties
+++ b/dom/locales/en-US/chrome/dom/dom.properties
@@ -103,11 +103,11 @@ RemoveChildWarning=Use of attributes' re
 AppendChildWarning=Use of attributes' appendChild() is deprecated. Use value instead.
 CloneNodeWarning=Use of attributes' cloneNode() is deprecated.
 OwnerDocumentWarning=Use of attributes' ownerDocument attribute is deprecated.
 NormalizeWarning=Use of attributes' normalize() is deprecated.
 IsSupportedWarning=Use of attributes' isSupported() is deprecated.
 IsEqualNodeWarning=Use of attributes' isEqualNode() is deprecated.
 TextContentWarning=Use of attributes' textContent attribute is deprecated. Use value instead.
 EnablePrivilegeWarning=Use of enablePrivilege is deprecated.  Please use code that runs with the system principal (e.g. an extension) instead.
-
 nsIJSONDecodeDeprecatedWarning=nsIJSON.decode is deprecated.  Please use JSON.parse instead.
 nsIJSONEncodeDeprecatedWarning=nsIJSON.encode is deprecated.  Please use JSON.stringify instead.
+nsIDOMWindowInternalWarning=Use of nsIDOMWindowInternal is deprecated. Use nsIDOMWindow instead.
--- a/editor/composer/src/nsEditorSpellCheck.cpp
+++ b/editor/composer/src/nsEditorSpellCheck.cpp
@@ -59,32 +59,50 @@
 #include "nsReadableUtils.h"
 #include "nsITextServicesFilter.h"
 #include "nsUnicharUtils.h"
 #include "mozilla/Services.h"
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 
+class UpdateDictionnaryHolder {
+  private:
+    nsEditorSpellCheck* mSpellCheck;
+  public:
+    UpdateDictionnaryHolder(nsEditorSpellCheck* esc): mSpellCheck(esc) {
+      if (mSpellCheck) {
+        mSpellCheck->BeginUpdateDictionary();
+      }
+    }
+    ~UpdateDictionnaryHolder() {
+      if (mSpellCheck) {
+        mSpellCheck->EndUpdateDictionary();
+      }
+    }
+};
+
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsEditorSpellCheck)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsEditorSpellCheck)
 
 NS_INTERFACE_MAP_BEGIN(nsEditorSpellCheck)
   NS_INTERFACE_MAP_ENTRY(nsIEditorSpellCheck)
   NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIEditorSpellCheck)
   NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsEditorSpellCheck)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION_2(nsEditorSpellCheck,
                            mSpellChecker,
                            mTxtSrvFilter)
 
 nsEditorSpellCheck::nsEditorSpellCheck()
   : mSuggestedWordIndex(0)
   , mDictionaryIndex(0)
+  , mUpdateDictionaryRunning(PR_FALSE)
+  , mDictWasSetManually(PR_FALSE)
 {
 }
 
 nsEditorSpellCheck::~nsEditorSpellCheck()
 {
   // Make sure we blow the spellchecker away, just in
   // case it hasn't been destroyed already.
   mSpellChecker = nsnull;
@@ -355,72 +373,60 @@ nsEditorSpellCheck::GetDictionaryList(PR
   {
     tmpPtr[i] = ToNewUnicode(dictList[i]);
   }
 
   return rv;
 }
 
 NS_IMETHODIMP    
-nsEditorSpellCheck::GetCurrentDictionary(PRUnichar **aDictionary)
+nsEditorSpellCheck::GetCurrentDictionary(nsAString& aDictionary)
 {
   NS_ENSURE_TRUE(mSpellChecker, NS_ERROR_NOT_INITIALIZED);
 
-  NS_ENSURE_TRUE(aDictionary, NS_ERROR_NULL_POINTER);
-
-  *aDictionary = 0;
-
-  nsAutoString dictStr;
-  nsresult rv = mSpellChecker->GetCurrentDictionary(dictStr);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aDictionary = ToNewUnicode(dictStr);
-
-  return rv;
+  return mSpellChecker->GetCurrentDictionary(aDictionary);
 }
 
 NS_IMETHODIMP    
-nsEditorSpellCheck::SetCurrentDictionary(const PRUnichar *aDictionary)
+nsEditorSpellCheck::SetCurrentDictionary(const nsAString& aDictionary)
 {
   NS_ENSURE_TRUE(mSpellChecker, NS_ERROR_NOT_INITIALIZED);
 
-  NS_ENSURE_TRUE(aDictionary, NS_ERROR_NULL_POINTER);
-
-  return mSpellChecker->SetCurrentDictionary(nsDependentString(aDictionary));
+  if (!mUpdateDictionaryRunning) {
+    mDictWasSetManually = PR_TRUE;
+  }
+  return mSpellChecker->SetCurrentDictionary(aDictionary);
 }
 
 NS_IMETHODIMP    
 nsEditorSpellCheck::UninitSpellChecker()
 {
   NS_ENSURE_TRUE(mSpellChecker, NS_ERROR_NOT_INITIALIZED);
 
   // Cleanup - kill the spell checker
   DeleteSuggestedWordList();
   mDictionaryList.Clear();
   mDictionaryIndex = 0;
   mSpellChecker = 0;
   return NS_OK;
 }
 
-// Save the last used dictionary to the user's preferences.
+// Save the last set dictionary to the user's preferences.
 NS_IMETHODIMP
 nsEditorSpellCheck::SaveDefaultDictionary()
 {
-  PRUnichar *dictName = nsnull;
-  nsresult rv = GetCurrentDictionary(&dictName);
-
-  if (NS_SUCCEEDED(rv) && dictName && *dictName) {
-    rv = Preferences::SetString("spellchecker.dictionary", dictName);
+  if (!mDictWasSetManually) {
+    return NS_OK;
   }
 
-  if (dictName) {
-    nsMemory::Free(dictName);
-  }
+  nsAutoString dictName;
+  nsresult rv = GetCurrentDictionary(dictName);
+  NS_ENSURE_SUCCESS(rv, rv);
 
-  return rv;
+  return Preferences::SetString("spellchecker.dictionary", dictName);
 }
 
 
 /* void setFilter (in nsITextServicesFilter filter); */
 NS_IMETHODIMP 
 nsEditorSpellCheck::SetFilter(nsITextServicesFilter *filter)
 {
   mTxtSrvFilter = filter;
@@ -433,18 +439,24 @@ nsEditorSpellCheck::DeleteSuggestedWordL
   mSuggestedWordList.Clear();
   mSuggestedWordIndex = 0;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsEditorSpellCheck::UpdateCurrentDictionary(nsIEditor* aEditor)
 {
+  if (mDictWasSetManually) { // user has set dictionary manually; we better not change it.
+    return NS_OK;
+  }
+
   nsresult rv;
 
+  UpdateDictionnaryHolder holder(this);
+
   // Tell the spellchecker what dictionary to use:
   nsAutoString dictName;
 
   // First, try to get language with html5 algorithm
   nsAutoString editorLang;
 
   nsCOMPtr<nsIContent> rootContent;
 
@@ -487,65 +499,65 @@ nsEditorSpellCheck::UpdateCurrentDiction
     if (packageRegistry) {
       nsCAutoString utf8DictName;
       rv = packageRegistry->GetSelectedLocale(NS_LITERAL_CSTRING("global"),
                                               utf8DictName);
       AppendUTF8toUTF16(utf8DictName, dictName);
     }
   }
 
-  SetCurrentDictionary(NS_LITERAL_STRING("").get());
+  SetCurrentDictionary(EmptyString());
 
   if (NS_SUCCEEDED(rv) && !dictName.IsEmpty()) {
-    rv = SetCurrentDictionary(dictName.get());
+    rv = SetCurrentDictionary(dictName);
     if (NS_FAILED(rv)) {
       // required dictionary was not available. Try to get a dictionary
       // matching at least language part of dictName: If required dictionary is
       // "aa-bb", we try "aa", then we try any available dictionary aa-XX
       nsAutoString langCode;
       PRInt32 dashIdx = dictName.FindChar('-');
       if (dashIdx != -1) {
         langCode.Assign(Substring(dictName, 0, dashIdx));
         // try to use langCode
-        rv = SetCurrentDictionary(langCode.get());
+        rv = SetCurrentDictionary(langCode);
       } else {
         langCode.Assign(dictName);
       }
       if (NS_FAILED(rv)) {
         // loop over avaible dictionaries; if we find one with required
         // language, use it
         nsTArray<nsString> dictList;
         rv = mSpellChecker->GetDictionaryList(&dictList);
         NS_ENSURE_SUCCESS(rv, rv);
         nsDefaultStringComparator comparator;
         PRInt32 i, count = dictList.Length();
         for (i = 0; i < count; i++) {
           nsAutoString dictStr(dictList.ElementAt(i));
           if (nsStyleUtil::DashMatchCompare(dictStr, langCode, comparator) &&
-              NS_SUCCEEDED(SetCurrentDictionary(dictStr.get()))) {
+              NS_SUCCEEDED(SetCurrentDictionary(dictStr))) {
               break;
           }
         }
       }
     }
   }
 
   // If we have not set dictionary, and the editable element doesn't have a
   // lang attribute, we try to get a dictionary. First try, en-US. If it does
   // not work, pick the first one.
   if (editorLang.IsEmpty()) {
-    nsAutoString currentDictonary;
-    rv = mSpellChecker->GetCurrentDictionary(currentDictonary);
-    if (NS_FAILED(rv) || currentDictonary.IsEmpty()) {
-      rv = SetCurrentDictionary(NS_LITERAL_STRING("en-US").get());
+    nsAutoString currentDictionary;
+    rv = GetCurrentDictionary(currentDictionary);
+    if (NS_FAILED(rv) || currentDictionary.IsEmpty()) {
+      rv = SetCurrentDictionary(NS_LITERAL_STRING("en-US"));
       if (NS_FAILED(rv)) {
         nsTArray<nsString> dictList;
         rv = mSpellChecker->GetDictionaryList(&dictList);
         if (NS_SUCCEEDED(rv) && dictList.Length() > 0) {
-          SetCurrentDictionary(dictList[0].get());
+          SetCurrentDictionary(dictList[0]);
         }
       }
     }
   }
 
   // If an error was thrown while setting the dictionary, just
   // fail silently so that the spellchecker dialog is allowed to come
   // up. The user can manually reset the language to their choice on
--- a/editor/composer/src/nsEditorSpellCheck.h
+++ b/editor/composer/src/nsEditorSpellCheck.h
@@ -73,13 +73,20 @@ protected:
   // these are the words in the current personal dictionary,
   // GetPersonalDictionary must be called to load them.
   nsTArray<nsString>  mDictionaryList;
   PRInt32        mDictionaryIndex;
 
   nsresult       DeleteSuggestedWordList();
 
   nsCOMPtr<nsITextServicesFilter> mTxtSrvFilter;
+
+  PRPackedBool mUpdateDictionaryRunning;
+  PRPackedBool mDictWasSetManually;
+
+public:
+  void BeginUpdateDictionary() { mUpdateDictionaryRunning = PR_TRUE ;}
+  void EndUpdateDictionary() { mUpdateDictionaryRunning = PR_FALSE ;}
 };
 
 #endif // nsEditorSpellCheck_h___
 
 
--- a/editor/composer/test/Makefile.in
+++ b/editor/composer/test/Makefile.in
@@ -48,15 +48,16 @@ include $(topsrcdir)/config/rules.mk
 		test_bug348497.html \
 		test_bug384147.html \
 		test_bug389350.html \
 		test_bug519928.html \
 		$(NULL)
 
 _CHROME_TEST_FILES = \
 		test_bug434998.xul \
+		test_bug338427.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
 
 libs:: $(_CHROME_TEST_FILES)
 	$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/chrome/$(relativesrcdir)
new file mode 100644
--- /dev/null
+++ b/editor/composer/test/test_bug338427.html
@@ -0,0 +1,54 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=338427
+-->
+<head>
+  <title>Test for Bug 338427</title>
+  <script type="text/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=338427">Mozilla Bug 338427</a>
+<p id="display"></p>
+<div id="content">
+<textarea id="editor" lang="testing-XX"></textarea>
+
+</div>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+/** Test for Bug 338427 **/
+function init() {
+    var textarea = document.getElementById("editor");
+    var editor = textarea.QueryInterface(Components.interfaces.nsIDOMNSEditableElement).editor;
+    var spellchecker = editor.getInlineSpellChecker(true);
+    spellchecker.enableRealTimeSpell = true;
+
+    var list = {}, count = {};
+    spellchecker.spellChecker.GetDictionaryList(list, count);
+    if (count.value === 0) {
+        return; // no dictionary, no test possible
+    }
+    var lang = list.value[0];
+    spellchecker.spellChecker.SetCurrentDictionary(lang);
+
+    textarea.addEventListener("focus", function() {
+        var dictionary = "";
+        try {
+            dictionary = spellchecker.spellChecker.GetCurrentDictionary();
+        } catch(e) {}
+        is(dictionary, lang, "Unexpected spell check dictionary");
+        SimpleTest.finish();
+    }, false);
+    textarea.focus();
+}
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(init);
+
+</script>
+</pre>
+</body>
+</html>
+
--- a/editor/idl/nsIEditorSpellCheck.idl
+++ b/editor/idl/nsIEditorSpellCheck.idl
@@ -36,17 +36,17 @@
  *
  * ***** END LICENSE BLOCK ***** */
  
 #include "nsISupports.idl"
 
 interface nsIEditor;
 interface nsITextServicesFilter;
 
-[scriptable, uuid(803ff0dd-07f2-4438-b3a6-ab9c2fe4e1dd)]
+[scriptable, uuid(3da0ce96-7d3a-48d0-80b7-2d90dab09747)]
 interface nsIEditorSpellCheck : nsISupports
 {
 
  /**
    * Returns true if we can enable spellchecking. If there are no available
    * dictionaries, this will return false.
    */
   boolean       canSpellCheck();
@@ -138,22 +138,22 @@ interface nsIEditorSpellCheck : nsISuppo
    *
    * @see mozISpellCheckingEngine::GetDictionaryList
    */
   void          GetDictionaryList([array, size_is(count)] out wstring dictionaryList, out PRUint32 count);
 
   /**
    * @see nsISpellChecker::GetCurrentDictionary
    */
-  wstring       GetCurrentDictionary();
+  AString       GetCurrentDictionary();
 
   /**
    * @see nsISpellChecker::SetCurrentDictionary
    */
-  void          SetCurrentDictionary(in wstring dictionary);
+  void          SetCurrentDictionary(in AString dictionary);
 
   /**
    * Call to save the currently selected dictionary as the default. The
    * function UninitSpellChecker will also do this, but that function may not
    * be called in some situations. This function allows the caller to force the
    * default right now.
    */
   void          saveDefaultDictionary();
--- a/embedding/android/GeckoAppShell.java
+++ b/embedding/android/GeckoAppShell.java
@@ -57,16 +57,17 @@ import android.content.pm.*;
 import android.graphics.*;
 import android.widget.*;
 import android.hardware.*;
 import android.location.*;
 import android.telephony.*;
 import android.webkit.MimeTypeMap;
 import android.media.MediaScannerConnection;
 import android.media.MediaScannerConnection.MediaScannerConnectionClient;
+import android.provider.Settings;
 
 import android.util.*;
 import android.net.Uri;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 
 import android.graphics.drawable.*;
 import android.graphics.Bitmap;
@@ -1361,9 +1362,21 @@ public class GeckoAppShell
 
         if (resolveInfo == null)
             return null;
 
         ActivityInfo activityInfo = resolveInfo.activityInfo;
 
         return activityInfo.loadIcon(pm);
     }
+
+    public static boolean getShowPasswordSetting() {
+        try {
+            int showPassword =
+                Settings.System.getInt(GeckoApp.mAppContext.getContentResolver(),
+                                       Settings.System.TEXT_SHOW_PASSWORD);
+            return (showPassword > 0);
+        }
+        catch (Exception e) {
+            return false;
+        }
+    }
 }
--- a/embedding/components/windowwatcher/public/nsPIWindowWatcher.idl
+++ b/embedding/components/windowwatcher/public/nsPIWindowWatcher.idl
@@ -43,20 +43,16 @@
 #include "nsISupports.idl"
 
 interface nsIDOMWindow;
 interface nsISimpleEnumerator;
 interface nsIWebBrowserChrome;
 interface nsIDocShellTreeItem;
 interface nsIArray;
 
-%{C++
-#include "jspubtd.h"
-%}
-
 [uuid(8624594a-28d7-4bc3-8d12-b1c2b9eefd90)]
 
 interface nsPIWindowWatcher : nsISupports
 {
   /** A window has been created. Add it to our list.
       @param aWindow the window to add
       @param aChrome the corresponding chrome window. The DOM window
                      and chrome will be mapped together, and the corresponding
--- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp
+++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp
@@ -1440,18 +1440,18 @@ mozInlineSpellChecker::ResumeCheck(mozIn
   nsresult rv = wordUtil.Init(mEditor);
   if (NS_FAILED(rv))
     return NS_OK; // editor doesn't like us, don't assert
 
   nsCOMPtr<nsISelection> spellCheckSelection;
   rv = GetSpellCheckSelection(getter_AddRefs(spellCheckSelection));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  PRUnichar *currentDictionary = nsnull;
-  rv = mSpellCheck->GetCurrentDictionary(&currentDictionary);
+  nsAutoString currentDictionary;
+  rv = mSpellCheck->GetCurrentDictionary(currentDictionary);
   if (NS_FAILED(rv)) {
     // no active dictionary
     PRInt32 count;
     spellCheckSelection->GetRangeCount(&count);
     for (PRInt32 index = count - 1; index >= 0; index--) {
       nsCOMPtr<nsIDOMRange> checkRange;
       spellCheckSelection->GetRangeAt(index, getter_AddRefs(checkRange));
       if (checkRange) {
@@ -1755,36 +1755,27 @@ nsresult mozInlineSpellChecker::KeyPress
 }
 
 NS_IMETHODIMP mozInlineSpellChecker::UpdateCurrentDictionary()
 {
   if (!mSpellCheck) {
     return NS_OK;
   }
 
-  PRUnichar *previousDictionary = nsnull;
-  nsDependentString previousDictionaryStr;
-  if (NS_SUCCEEDED(mSpellCheck->GetCurrentDictionary(&previousDictionary))) {
-    previousDictionaryStr.Assign(previousDictionary);
+  nsAutoString previousDictionary;
+  if (NS_FAILED(mSpellCheck->GetCurrentDictionary(previousDictionary))) {
+    previousDictionary.Truncate();
   }
 
   nsCOMPtr<nsIEditor> editor (do_QueryReferent(mEditor));
   nsresult rv = mSpellCheck->UpdateCurrentDictionary(editor);
 
-  PRUnichar *currentDictionary = nsnull;
-  nsDependentString currentDictionaryStr;
-  if (NS_SUCCEEDED(mSpellCheck->GetCurrentDictionary(&currentDictionary))) {
-    currentDictionaryStr.Assign(currentDictionary);
+  nsAutoString currentDictionary;
+  if (NS_FAILED(mSpellCheck->GetCurrentDictionary(currentDictionary))) {
+    currentDictionary.Truncate();
   }
 
-  if (!previousDictionary || !currentDictionary || !previousDictionaryStr.Equals(currentDictionaryStr)) {
+  if (!previousDictionary.Equals(currentDictionary)) {
       rv = SpellCheckRange(nsnull);
   }
 
-  if (previousDictionary) {
-     nsMemory::Free(previousDictionary);
-  }
-  if (currentDictionary) {
-     nsMemory::Free(currentDictionary);
-  }
-
   return rv;
 }
--- a/gfx/angle/Makefile.in
+++ b/gfx/angle/Makefile.in
@@ -57,16 +57,17 @@ EXPORTS_angle = \
 LOCAL_INCLUDES += -I$(srcdir)/include -I$(srcdir)/src
 
 VPATH += $(srcdir)/src
 VPATH += $(srcdir)/src/compiler
 VPATH += $(srcdir)/src/compiler/preprocessor
 
 CPPSRCS = \
 	Compiler.cpp \
+        DetectRecursion.cpp \
         InfoSink.cpp \
         Initialize.cpp \
         InitializeDll.cpp \
         Intermediate.cpp \
         intermOut.cpp \
         IntermTraverse.cpp \
         MozAngleLink.cpp \
         parseConst.cpp \
--- a/gfx/angle/README.mozilla
+++ b/gfx/angle/README.mozilla
@@ -1,24 +1,26 @@
 This is the ANGLE project, from http://code.google.com/p/angleproject/.
 
-Current revision: r653
+Current revision: r686
 
 == Applied local patches ==
 
 In this order:
   angle-nspr-misc.patch - don't bother with ANGLE_OS detection with NSPR
   angle-renaming.patch - rename debug.h to compilerdebug.h to avoid conflict in our makefiles
   angle-intrinsic-msvc2005.patch - work around a MSVC 2005 compile error
   angle-amap-arev-fix.patch - plain bug fix, this is ANGLE r699
   angle-r702.patch - this is ANGLE r702
   angle-limit-identifiers-to-250-chars.patch - see bug 675625
   angle-r712.patch - this is ANGLE r712
   angle-win64.patch - Win64 support. This is ANGLE r697
   angle-r707.patch - this is ANGLE r707 for Win64 bug fix
+  angle-r719.patch - this is ANGLE r719
+  angle-r711.patch - this is ANGLE r711
 
 In addition to these patches, the Makefile.in files are ours, they're not present in upsteam ANGLE.
 
 == How to update this ANGLE copy ==
 
 1. Unapply patches
 2. Apply diff with new ANGLE version
 3. Reapply patches.
--- a/gfx/angle/src/compiler/Compiler.cpp
+++ b/gfx/angle/src/compiler/Compiler.cpp
@@ -1,14 +1,15 @@
 //
 // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
 
+#include "compiler/DetectRecursion.h"
 #include "compiler/Initialize.h"
 #include "compiler/ParseHelper.h"
 #include "compiler/ShHandle.h"
 #include "compiler/ValidateLimitations.h"
 #include "compiler/MapLongVariableNames.h"
 
 namespace {
 bool InitializeSymbolTable(
@@ -140,23 +141,26 @@ bool TCompiler::compile(const char* cons
     // Parse shader.
     bool success =
         (PaParseStrings(numStrings - firstSource, &shaderStrings[firstSource], NULL, &parseContext) == 0) &&
         (parseContext.treeRoot != NULL);
     if (success) {
         TIntermNode* root = parseContext.treeRoot;
         success = intermediate.postProcess(root);
 
+        if (success)
+            success = detectRecursion(root);
+
         if (success && (compileOptions & SH_VALIDATE_LOOP_INDEXING))
             success = validateLimitations(root);
 
         // Call mapLongVariableNames() before collectAttribsUniforms() so in
         // collectAttribsUniforms() we already have the mapped symbol names and
         // we could composite mapped and original variable names.
-        if (compileOptions & SH_MAP_LONG_VARIABLE_NAMES)
+        if (success && (compileOptions & SH_MAP_LONG_VARIABLE_NAMES))
             mapLongVariableNames(root);
 
         if (success && (compileOptions & SH_ATTRIBUTES_UNIFORMS))
             collectAttribsUniforms(root);
 
         if (success && (compileOptions & SH_INTERMEDIATE_TREE))
             intermediate.outputTree(root);
 
@@ -188,16 +192,35 @@ void TCompiler::clearResults()
     infoSink.info.erase();
     infoSink.obj.erase();
     infoSink.debug.erase();
 
     attribs.clear();
     uniforms.clear();
 }
 
+bool TCompiler::detectRecursion(TIntermNode* root)
+{
+    DetectRecursion detect;
+    root->traverse(&detect);
+    switch (detect.detectRecursion()) {
+        case DetectRecursion::kErrorNone:
+            return true;
+        case DetectRecursion::kErrorMissingMain:
+            infoSink.info.message(EPrefixError, "Missing main()");
+            return false;
+        case DetectRecursion::kErrorRecursion:
+            infoSink.info.message(EPrefixError, "Function recursion detected");
+            return false;
+        default:
+            UNREACHABLE();
+            return false;
+    }
+}
+
 bool TCompiler::validateLimitations(TIntermNode* root) {
     ValidateLimitations validate(shaderType, infoSink.info);
     root->traverse(&validate);
     return validate.numErrors() == 0;
 }
 
 void TCompiler::collectAttribsUniforms(TIntermNode* root)
 {
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/DetectRecursion.cpp
@@ -0,0 +1,158 @@
+//
+// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#include "compiler/DetectRecursion.h"
+
+DetectRecursion::FunctionNode::FunctionNode(const TString& fname)
+    : name(fname),
+      visit(PreVisit)
+{
+}
+
+const TString& DetectRecursion::FunctionNode::getName() const
+{
+    return name;
+}
+
+void DetectRecursion::FunctionNode::addCallee(
+    DetectRecursion::FunctionNode* callee)
+{
+    for (size_t i = 0; i < callees.size(); ++i) {
+        if (callees[i] == callee)
+            return;
+    }
+    callees.push_back(callee);
+}
+
+bool DetectRecursion::FunctionNode::detectRecursion()
+{
+    ASSERT(visit == PreVisit);
+    visit = InVisit;
+    for (size_t i = 0; i < callees.size(); ++i) {
+        switch (callees[i]->visit) {
+            case InVisit:
+                // cycle detected, i.e., recursion detected.
+                return true;
+            case PostVisit:
+                break;
+            case PreVisit: {
+                bool recursion = callees[i]->detectRecursion();
+                if (recursion)
+                    return true;
+                break;
+            }
+            default:
+                UNREACHABLE();
+                break;
+        }
+    }
+    visit = PostVisit;
+    return false;
+}
+
+DetectRecursion::DetectRecursion()
+    : currentFunction(NULL)
+{
+}
+
+DetectRecursion::~DetectRecursion()
+{
+    for (int i = 0; i < functions.size(); ++i)
+        delete functions[i];
+}
+
+void DetectRecursion::visitSymbol(TIntermSymbol*)
+{
+}
+
+void DetectRecursion::visitConstantUnion(TIntermConstantUnion*)
+{
+}
+
+bool DetectRecursion::visitBinary(Visit, TIntermBinary*)
+{
+    return true;
+}
+
+bool DetectRecursion::visitUnary(Visit, TIntermUnary*)
+{
+    return true;
+}
+
+bool DetectRecursion::visitSelection(Visit, TIntermSelection*)
+{
+    return true;
+}
+
+bool DetectRecursion::visitAggregate(Visit visit, TIntermAggregate* node)
+{
+    switch (node->getOp())
+    {
+        case EOpPrototype:
+            // Function declaration.
+            // Don't add FunctionNode here because node->getName() is the
+            // unmangled function name.
+            break;
+        case EOpFunction: {
+            // Function definition.
+            if (visit == PreVisit) {
+                currentFunction = findFunctionByName(node->getName());
+                if (currentFunction == NULL) {
+                    currentFunction = new FunctionNode(node->getName());
+                    functions.push_back(currentFunction);
+                }
+            }
+            break;
+        }
+        case EOpFunctionCall: {
+            // Function call.
+            if (visit == PreVisit) {
+                ASSERT(currentFunction != NULL);
+                FunctionNode* func = findFunctionByName(node->getName());
+                if (func == NULL) {
+                    func = new FunctionNode(node->getName());
+                    functions.push_back(func);
+                }
+                currentFunction->addCallee(func);
+            }
+            break;
+        }
+        default:
+            break;
+    }
+    return true;
+}
+
+bool DetectRecursion::visitLoop(Visit, TIntermLoop*)
+{
+    return true;
+}
+
+bool DetectRecursion::visitBranch(Visit, TIntermBranch*)
+{
+    return true;
+}
+
+DetectRecursion::ErrorCode DetectRecursion::detectRecursion()
+{
+    FunctionNode* main = findFunctionByName("main(");
+    if (main == NULL)
+        return kErrorMissingMain;
+    if (main->detectRecursion())
+        return kErrorRecursion;
+    return kErrorNone;
+}
+
+DetectRecursion::FunctionNode* DetectRecursion::findFunctionByName(
+    const TString& name)
+{
+    for (size_t i = 0; i < functions.size(); ++i) {
+        if (functions[i]->getName() == name)
+            return functions[i];
+    }
+    return NULL;
+}
+
new file mode 100644
--- /dev/null
+++ b/gfx/angle/src/compiler/DetectRecursion.h
@@ -0,0 +1,67 @@
+//
+// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+//
+
+#ifndef COMPILER_DETECT_RECURSION_H_
+#define COMPILER_DETECT_RECURSION_H_
+
+#include "GLSLANG/ShaderLang.h"
+
+#include "compiler/intermediate.h"
+#include "compiler/VariableInfo.h"
+
+// Traverses intermediate tree to detect function recursion.
+class DetectRecursion : public TIntermTraverser {
+public:
+    enum ErrorCode {
+        kErrorMissingMain,
+        kErrorRecursion,
+        kErrorNone
+    };
+
+    DetectRecursion();
+    ~DetectRecursion();
+
+    virtual void visitSymbol(TIntermSymbol*);
+    virtual void visitConstantUnion(TIntermConstantUnion*);
+    virtual bool visitBinary(Visit, TIntermBinary*);
+    virtual bool visitUnary(Visit, TIntermUnary*);
+    virtual bool visitSelection(Visit, TIntermSelection*);
+    virtual bool visitAggregate(Visit, TIntermAggregate*);
+    virtual bool visitLoop(Visit, TIntermLoop*);
+    virtual bool visitBranch(Visit, TIntermBranch*);
+
+    ErrorCode detectRecursion();
+
+private:
+    class FunctionNode {
+    public:
+        FunctionNode(const TString& fname);
+
+        const TString& getName() const;
+
+        // If a function is already in the callee list, this becomes a no-op.
+        void addCallee(FunctionNode* callee);
+
+        // Return true if recursive function calls are detected.
+        bool detectRecursion();
+
+    private:
+        // mangled function name is unique.
+        TString name;
+
+        // functions that are directly called by this function.
+        TVector<FunctionNode*> callees;
+
+        Visit visit;
+    };
+
+    FunctionNode* findFunctionByName(const TString& name);
+
+    TVector<FunctionNode*> functions;
+    FunctionNode* currentFunction;
+};
+
+#endif  // COMPILER_DETECT_RECURSION_H_
--- a/gfx/angle/src/compiler/ShHandle.h
+++ b/gfx/angle/src/compiler/ShHandle.h
@@ -61,16 +61,18 @@ public:
 
 protected:
     ShShaderType getShaderType() const { return shaderType; }
     ShShaderSpec getShaderSpec() const { return shaderSpec; }
     // Initialize symbol-table with built-in symbols.
     bool InitBuiltInSymbolTable(const ShBuiltInResources& resources);
     // Clears the results from the previous compilation.
     void clearResults();
+    // Return true if function recursion is detected.
+    bool detectRecursion(TIntermNode* root);
     // Returns true if the given shader does not exceed the minimum
     // functionality mandated in GLSL 1.0 spec Appendix A.
     bool validateLimitations(TIntermNode* root);
     // Collect info for all attribs and uniforms.
     void collectAttribsUniforms(TIntermNode* root);
     // Map long variable names into shorter ones.
     void mapLongVariableNames(TIntermNode* root);
     // Translate to object code.
--- a/gfx/angle/src/libEGL/Makefile.in
+++ b/gfx/angle/src/libEGL/Makefile.in
@@ -71,16 +71,17 @@ VPATH += $(srcdir)/.. \
   $(srcdir)/../compiler/preprocessor \
   $(srcdir)/../common \
   $(NULL)
 
 # Translator/compiler first
 
 CPPSRCS = \
   Compiler.cpp \
+  DetectRecursion.cpp \
   InfoSink.cpp \
   Initialize.cpp \
   InitializeDll.cpp \
   Intermediate.cpp \
   intermOut.cpp \
   IntermTraverse.cpp \
   MozAngleLink.cpp \
   parseConst.cpp \
--- a/gfx/angle/src/libGLESv2/Context.cpp
+++ b/gfx/angle/src/libGLESv2/Context.cpp
@@ -2104,26 +2104,26 @@ void Context::readPixels(GLint x, GLint 
     IDirect3DDevice9 *device = getDevice();
 
     D3DSURFACE_DESC desc;
     renderTarget->GetDesc(&desc);
 
     IDirect3DSurface9 *systemSurface;
     HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &systemSurface, NULL);
 
-    if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY)
+    if (FAILED(result))
     {
+        ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
         return error(GL_OUT_OF_MEMORY);
     }
 
-    ASSERT(SUCCEEDED(result));
-
     if (desc.MultiSampleType != D3DMULTISAMPLE_NONE)
     {
         UNIMPLEMENTED();   // FIXME: Requires resolve using StretchRect into non-multisampled render target
+        return error(GL_OUT_OF_MEMORY);
     }
 
     result = device->GetRenderTargetData(renderTarget, systemSurface);
 
     if (FAILED(result))
     {
         systemSurface->Release();
 
--- a/gfx/angle/src/libGLESv2/Makefile.in
+++ b/gfx/angle/src/libGLESv2/Makefile.in
@@ -71,16 +71,17 @@ VPATH += $(srcdir)/..
 VPATH += $(srcdir)/../compiler
 VPATH += $(srcdir)/../compiler/preprocessor
 VPATH += $(srcdir)/../common
 
 # Translator/compiler first
 
 CPPSRCS = \
 	Compiler.cpp \
+        DetectRecursion.cpp \
         InfoSink.cpp \
         Initialize.cpp \
         InitializeDll.cpp \
         Intermediate.cpp \
         intermOut.cpp \
         IntermTraverse.cpp \
         MozAngleLink.cpp \
         parseConst.cpp \
--- a/gfx/thebes/GLContext.cpp
+++ b/gfx/thebes/GLContext.cpp
@@ -429,16 +429,18 @@ static const char *sExtensionNames[] = {
     "GL_OES_depth_texture",
     "GL_OES_packed_depth_stencil",
     "GL_IMG_read_format",
     "GL_EXT_read_format_bgra",
     "GL_APPLE_client_storage",
     "GL_ARB_texture_non_power_of_two",
     "GL_ARB_pixel_buffer_object",
     "GL_ARB_ES2_compatibility",
+    "GL_OES_texture_float",
+    "GL_ARB_texture_float",
     NULL
 };
 
 void
 GLContext::InitExtensions()
 {
     MakeCurrent();
     const GLubyte *extensions = fGetString(LOCAL_GL_EXTENSIONS);
--- a/gfx/thebes/GLContext.h
+++ b/gfx/thebes/GLContext.h
@@ -954,16 +954,18 @@ public:
         OES_depth_texture,
         OES_packed_depth_stencil,
         IMG_read_format,
         EXT_read_format_bgra,
         APPLE_client_storage,
         ARB_texture_non_power_of_two,
         ARB_pixel_buffer_object,
         ARB_ES2_compatibility,
+        OES_texture_float,
+        ARB_texture_float,
         Extensions_Max
     };
 
     PRBool IsExtensionSupported(GLExtensions aKnownExtension) {
         return mAvailableExtensions[aKnownExtension];
     }
 
     // for unknown extensions
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -2605,35 +2605,16 @@ gfxFontGroup::FindFontForChar(PRUint32 a
 
     // 1. check fonts in the font group
     for (PRUint32 i = 0; i < FontListLength(); i++) {
         nsRefPtr<gfxFont> font = GetFontAt(i);
         if (font->HasCharacter(aCh)) {
             *aMatchType = gfxTextRange::kFontGroup;
             return font.forget();
         }
-        // check other faces of the family
-        // XXX optimization point: give the family a charmap that is the union
-        // of the char maps of all its faces, so we can quickly test whether
-        // it's worth doing this search
-        gfxFontFamily *family = font->GetFontEntry()->Family();
-        if (family) {
-            FontSearch matchData(aCh, font);
-            family->FindFontForChar(&matchData);
-            gfxFontEntry *fe = matchData.mBestMatch;
-            if (fe) {
-                PRBool needsBold =
-                    font->GetStyle()->weight >= 600 && !fe->IsBold();
-                selectedFont =
-                    fe->FindOrMakeFont(font->GetStyle(), needsBold);
-                if (selectedFont) {
-                    return selectedFont.forget();
-                }
-            }
-        }
     }
 
     // if character is in Private Use Area, don't do matching against pref or system fonts
     if ((aCh >= 0xE000  && aCh <= 0xF8FF) || (aCh >= 0xF0000 && aCh <= 0x10FFFD))
         return nsnull;
 
     // 2. search pref fonts
     if ((selectedFont = WhichPrefFontSupportsChar(aCh))) {
--- a/js/src/xpconnect/loader/mozJSComponentLoader.cpp
+++ b/js/src/xpconnect/loader/mozJSComponentLoader.cpp
@@ -1354,17 +1354,17 @@ mozJSComponentLoader::ImportInto(const n
             if (i == 0) {
                 logBuffer.AssignLiteral("Installing symbols [ ");
             }
             JSAutoByteString bytes(mContext, JSID_TO_STRING(symbolId));
             if (!!bytes)
                 logBuffer.Append(bytes.ptr());
             logBuffer.AppendLiteral(" ");
             if (i == symbolCount - 1) {
-                LOG(("%s] from %s\n", PromiseFlatCString(logBuffer).get(),
+                LOG(("%s] from %s\n", logBuffer.get(),
                                       PromiseFlatCString(aLocation).get()));
             }
 #endif
         }
     }
 
     // Cache this module for later
     if (newEntry) {
new file mode 100644
--- /dev/null
+++ b/mobile/chrome/content/MasterPasswordUI.js
@@ -0,0 +1,125 @@
+var MasterPasswordUI = {
+  _dialog: null,
+  _tokenName: "",
+
+  get _secModuleDB() {
+    delete this._secModuleDB;
+    return this._secModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService(Ci.nsIPKCS11ModuleDB);
+  },
+
+  get _pk11DB() {
+    delete this._pk11DB;
+    return this._pk11DB = Cc["@mozilla.org/security/pk11tokendb;1"].getService(Ci.nsIPK11TokenDB);
+  },
+
+  _setPassword: function _setPassword(password) {
+    try {
+      let status;
+      let slot = this._secModuleDB.findSlotByName(this._tokenName);
+      if (slot)
+        status = slot.status;
+      else
+        return false;
+
+      let token = this._pk11DB.findTokenByName(this._tokenName);
+
+      if (status == Ci.nsIPKCS11Slot.SLOT_UNINITIALIZED) {
+        token.initPassword(password);
+      } else if (status == Ci.nsIPKCS11Slot.SLOT_READY) {
+        token.changePassword("", password);
+      }
+      return true;
+    } catch(e) {
+      dump("--- MasterPasswordUI._setPassword exception: " + e + "\n");
+      return false;
+    }
+  },
+
+  _removePassword: function _removePassword(password) {
+    try {
+      let token = this._pk11DB.getInternalKeyToken();
+      if (token.checkPassword(password)) {
+        token.changePassword(password, "");
+        return true;
+      }
+    } catch(e) {
+      dump("--- MasterPasswordUI._removePassword exception: " + e + "\n");
+    }
+    return false;
+  },
+
+  show: function mp_show(aSet) {
+    let dialogId = aSet ? "masterpassword-change" : "masterpassword-remove";
+    if (document.getElementById(dialogId))
+      return;
+
+    let dialog = aSet ? "chrome://browser/content/masterPassword.xul"
+                        : "chrome://browser/content/removeMasterPassword.xul";
+    this._dialog = importDialog(window, dialog, null);
+    BrowserUI.pushPopup(this, this._dialog);
+
+    if (aSet) {
+      this.checkPassword();
+      document.getElementById("masterpassword-newpassword1").focus();
+    } else {
+      document.getElementById("masterpassword-oldpassword").focus();
+    }
+  },
+
+  hide: function mp_hide(aValue) {
+    this.updatePreference();
+    this._dialog.close();
+    this._dialog = null;
+    BrowserUI.popPopup(this);
+  },
+
+  setPassword: function mp_setPassword() {
+    if (!this.checkPassword())
+      return;
+
+    let newPasswordValue = document.getElementById("masterpassword-newpassword1").value;
+    if (this._setPassword(newPasswordValue)) {
+      this.hide();
+    }
+  },
+
+  removePassword: function mp_removePassword() {
+    let oldPassword = document.getElementById("masterpassword-oldpassword").value;
+    if (this._removePassword(oldPassword)) {
+      this.hide();
+    }
+  },
+
+  checkPassword: function mp_checkPassword() {
+    let newPasswordValue1 = document.getElementById("masterpassword-newpassword1").value;
+    let newPasswordValue2 = document.getElementById("masterpassword-newpassword2").value;
+
+    let buttonOk = this._dialog.getElementsByAttribute("class", "prompt-buttons")[0].firstChild;
+    let isPasswordValid = this._secModuleDB.isFIPSEnabled ? (newPasswordValue1 != "" && newPasswordValue1 == newPasswordValue2)
+                                                          : (newPasswordValue1 == newPasswordValue2);
+    buttonOk.setAttribute("disabled", !isPasswordValid);
+
+    return isPasswordValid;
+  },
+
+  checkOldPassword: function mp_checkOldPassword() {
+    let oldPassword = document.getElementById("masterpassword-oldpassword");
+
+    let buttonOk = this._dialog.getElementsByAttribute("class", "prompt-buttons")[0].firstChild;
+    let isPasswordValid = this._pk11DB.getInternalKeyToken().checkPassword(oldPassword.value);
+    buttonOk.setAttribute("disabled", !isPasswordValid);
+  },
+
+  hasMasterPassword: function mp_hasMasterPassword() {
+    let slot = this._secModuleDB.findSlotByName(this._tokenName);
+    if (slot) {
+      let status = slot.status;
+      return status != Ci.nsIPKCS11Slot.SLOT_UNINITIALIZED && status != Ci.nsIPKCS11Slot.SLOT_READY;
+    }
+    return false;
+  },
+
+  updatePreference: function mp_updatePreference() {
+    document.getElementById("prefs-master-password").value = this.hasMasterPassword();
+  }
+};
--- a/mobile/chrome/content/browser-scripts.js
+++ b/mobile/chrome/content/browser-scripts.js
@@ -104,16 +104,17 @@ XPCOMUtils.defineLazyGetter(this, "Commo
   ["OfflineApps", "chrome://browser/content/OfflineApps.js"],
   ["IndexedDB", "chrome://browser/content/IndexedDB.js"],
   ["PreferencesView", "chrome://browser/content/preferences.js"],
   ["Sanitizer", "chrome://browser/content/sanitize.js"],
   ["SelectHelperUI", "chrome://browser/content/SelectHelperUI.js"],
   ["ContentPopupHelper", "chrome://browser/content/ContentPopupHelper.js"],
   ["SharingUI", "chrome://browser/content/SharingUI.js"],
   ["TabsPopup", "chrome://browser/content/TabsPopup.js"],
+  ["MasterPasswordUI", "chrome://browser/content/MasterPasswordUI.js"],
 #ifdef MOZ_SERVICES_SYNC
   ["WeaveGlue", "chrome://browser/content/sync.js"],
 #endif
   ["SSLExceptions", "chrome://browser/content/exceptions.js"]
 ].forEach(function (aScript) {
   let [name, script] = aScript;
   XPCOMUtils.defineLazyGetter(window, name, function() {
     let sandbox = {};
--- a/mobile/chrome/content/browser.xul
+++ b/mobile/chrome/content/browser.xul
@@ -476,16 +476,17 @@
                       <button label="&sync.disconnect;" oncommand="WeaveGlue.disconnect();" />
                     </setting>
                   </settings>
 #endif
                   <settings id="prefs-privacy" label="&privacy.title;">
                     <setting pref="network.cookie.cookieBehavior" title="&allowCookies.title;" type="boolint" on="0" off="2"/>
                     <setting pref="signon.rememberSignons" title="&rememberPasswords.title;" type="bool"/>
                     <setting pref="privacy.donottrackheader.enabled" title="&doNotTrack.title;" type="bool"/>
+                    <setting id="prefs-master-password" title="&masterPassword.title;" type="bool" oncommand="MasterPasswordUI.show(this.value);"/>
                     <setting title="&clearPrivateData2.title;" type="control">
                       <button id="prefs-clear-data" label="&clearPrivateData.button;" command="cmd_sanitize"/>
                     </setting>
                   </settings>
                   <settings id="prefs-content" label="&content.title;">
                     <setting pref="browser.ui.zoom.reflow" title="&reflowZoom.title;" type="bool"/>
                     <setting pref="permissions.default.image" title="&showImages.title;" type="boolint" on="1" off="2"/>
                     <setting pref="javascript.enabled" type="bool" title="&enableJavaScript.title;"/>
new file mode 100644
--- /dev/null
+++ b/mobile/chrome/content/masterPassword.xul
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE dialog [
+<!ENTITY % dialog SYSTEM "chrome://browser/locale/prompt.dtd">
+<!ENTITY % changempDTD SYSTEM "chrome://mozapps/locale/preferences/changemp.dtd" >
+%dialog;
+%changempDTD;
+]>
+
+<dialog id="masterpassword-change" title="&setPassword.title;"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <keyset>
+    <key keycode="VK_RETURN" command="cmd_ok"/>
+    <key keycode="VK_ESCAPE" command="cmd_cancel"/>
+  </keyset>
+
+  <commandset>
+    <command id="cmd_ok" oncommand="MasterPasswordUI.setPassword();"/>
+    <command id="cmd_cancel" oncommand="MasterPasswordUI.hide();"/>
+  </commandset>
+
+  <vbox class="prompt-header" flex="1">
+    <description id="masterpassword-title" class="prompt-title" crop="center" flex="1">&setPassword.title;</description>
+    <separator id="prompt-confirm-separator" class="prompt-line"/>
+  </vbox>
+
+  <scrollbox orient="vertical" class="prompt-message" flex="1">
+    <label control="masterpassword-newpassword1" value="&setPassword.newPassword.label;"/>
+    <textbox id="masterpassword-newpassword1" type="password" oninput="MasterPasswordUI.checkPassword();" flex="1"/>
+    <label control="masterpassword-newpassword2" value="&setPassword.reenterPassword.label;"/>
+    <textbox id="masterpassword-newpassword2" type="password" oninput="MasterPasswordUI.checkPassword();" flex="1"/>
+    <separator/>
+  </scrollbox>
+
+  <hbox class="prompt-buttons">
+    <button class="prompt-button" label="&ok.label;" command="cmd_ok"/>
+    <button class="prompt-button" label="&cancel.label;" command="cmd_cancel"/>
+  </hbox>
+</dialog>
--- a/mobile/chrome/content/preferences.js
+++ b/mobile/chrome/content/preferences.js
@@ -96,16 +96,18 @@ var PreferencesView = {
     if (this._languages)
       return;
 
     this._msg = document.getElementById("prefs-messages");
     this._languages = document.getElementById("prefs-languages");
     this._loadLocales();
 
     this._loadHomePage();
+
+    MasterPasswordUI.updatePreference();
   },
 
   _loadLocales: function _loadLocales() {
     // Query available and selected locales
     let chrome = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIXULChromeRegistry);
     chrome.QueryInterface(Ci.nsIToolkitChromeRegistry);
 
     let selectedLocale = chrome.getSelectedLocale("browser");
new file mode 100644
--- /dev/null
+++ b/mobile/chrome/content/removeMasterPassword.xul
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+
+<!DOCTYPE dialog [
+<!ENTITY % dialog SYSTEM "chrome://browser/locale/prompt.dtd">
+<!ENTITY % removempDTD SYSTEM "chrome://mozapps/locale/preferences/removemp.dtd" >
+%dialog;
+%removempDTD;
+]>
+
+<dialog id="masterpassword-remove" title="&removePassword.title;"
+        xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+  <keyset>
+    <key keycode="VK_RETURN" command="cmd_ok"/>
+    <key keycode="VK_ESCAPE" command="cmd_cancel"/>
+  </keyset>
+
+  <commandset>
+    <command id="cmd_ok" oncommand="MasterPasswordUI.removePassword();"/>
+    <command id="cmd_cancel" oncommand="MasterPasswordUI.hide();"/>
+  </commandset>
+
+  <vbox class="prompt-header" flex="1">
+    <description id="masterpassword-title" class="prompt-title" crop="center" flex="1">&removePassword.title;</description>
+    <separator id="prompt-confirm-separator" class="prompt-line"/>
+  </vbox>
+
+  <scrollbox orient="vertical" class="prompt-message" flex="1">
+    <label control="masterpassword-oldpassword" value="&setPassword.oldPassword.label;"/>
+    <textbox id="masterpassword-oldpassword" type="password" oninput="MasterPasswordUI.checkOldPassword();" flex="1"/>
+    <separator/>
+  </scrollbox>
+
+  <hbox class="prompt-buttons">
+    <button class="prompt-button" label="&ok.label;" disabled="true" command="cmd_ok"/>
+    <button class="prompt-button" label="&cancel.label;" command="cmd_cancel"/>
+  </hbox>
+</dialog>
--- a/mobile/chrome/jar.mn
+++ b/mobile/chrome/jar.mn
@@ -26,16 +26,17 @@ chrome.jar:
   content/ContentPopupHelper.js        (content/ContentPopupHelper.js)
 * content/ContextCommands.js           (content/ContextCommands.js)
   content/IndexedDB.js                 (content/IndexedDB.js)
   content/MenuListHelperUI.js          (content/MenuListHelperUI.js)
   content/OfflineApps.js               (content/OfflineApps.js)
   content/SelectHelperUI.js            (content/SelectHelperUI.js)
   content/SharingUI.js                 (content/SharingUI.js)
   content/TabsPopup.js                 (content/TabsPopup.js)
+  content/MasterPasswordUI.js          (content/MasterPasswordUI.js)
 * content/content.js                   (content/content.js)
   content/commandUtil.js               (content/commandUtil.js)
 * content/bindings.xml                 (content/bindings.xml)
   content/tabs.xml                     (content/tabs.xml)
   content/bindings/checkbox.xml        (content/bindings/checkbox.xml)
   content/bindings/browser.xml         (content/bindings/browser.xml)
   content/bindings/browser.js          (content/bindings/browser.js)
   content/notification.xml             (content/notification.xml)
@@ -60,16 +61,18 @@ chrome.jar:
   content/prompt/alert.xul             (content/prompt/alert.xul)
   content/prompt/confirm.xul           (content/prompt/confirm.xul)
   content/prompt/prompt.xul            (content/prompt/prompt.xul)
   content/prompt/promptPassword.xul    (content/prompt/promptPassword.xul)
   content/prompt/select.xul            (content/prompt/select.xul)
   content/prompt/prompt.js             (content/prompt/prompt.js)
   content/share.xul                    (content/share.xul)
   content/webapps.xul                  (content/webapps.xul)
+  content/masterPassword.xul           (content/masterPassword.xul)
+  content/removeMasterPassword.xul     (content/removeMasterPassword.xul)
   content/AnimatedZoom.js              (content/AnimatedZoom.js)
 #ifdef MOZ_SERVICES_SYNC
   content/sync.js                      (content/sync.js)
 #endif
   content/LoginManagerChild.js         (content/LoginManagerChild.js)
   content/fullscreen-video.js          (content/fullscreen-video.js)
   content/fullscreen-video.xhtml       (content/fullscreen-video.xhtml)
   content/netError.xhtml               (content/netError.xhtml)
--- a/mobile/locales/en-US/chrome/preferences.dtd
+++ b/mobile/locales/en-US/chrome/preferences.dtd
@@ -3,16 +3,17 @@
 <!ENTITY about.button                              "Go to Page">
 <!ENTITY content.title                             "Content">
 <!ENTITY reflowZoom.title                          "Reformat text on zoom">
 <!ENTITY showImages.title                          "Show images">
 <!ENTITY enableJavaScript.title                    "Enable JavaScript">
 <!ENTITY privacy.title                             "Privacy &amp; Security">
 <!ENTITY allowCookies.title                        "Allow cookies">
 <!ENTITY doNotTrack.title                          "Tell sites not to track me">
+<!ENTITY masterPassword.title                      "Use master password">
 <!ENTITY clearPrivateData2.title                   "Clear private data">
 <!ENTITY clearPrivateData.button                   "Clear">
 <!ENTITY rememberPasswords.title                   "Remember passwords">
 <!ENTITY language.title                            "Language">
 <!ENTITY language.auto                             "Auto-detect">
 <!ENTITY defaultBrowser.title                      "Default Browser">
 <!ENTITY defaultBrowser.description                "Make &brandShortName; your default browser">
 <!ENTITY homepage.title                            "Start page">
--- a/modules/libjar/nsIJARURI.idl
+++ b/modules/libjar/nsIJARURI.idl
@@ -42,17 +42,17 @@
  * JAR URLs have the following syntax
  *
  * jar:<jar-file-uri>!/<jar-entry>
  *
  * EXAMPLE: jar:http://www.big.com/blue.jar!/ocean.html
  *
  * The nsIURL methods operate on the <jar-entry> part of the spec.
  */
-[scriptable, uuid(c95d481a-c0ec-43cc-8320-43842b1df597)]
+[scriptable, uuid(0d31634e-2fc9-4597-9d53-11fb3f05516a)]
 interface nsIJARURI : nsIURL {
 
     /**
      * Returns the root URI (the one for the actual JAR file) for this JAR
      * (e.g., http://www.big.com/blue.jar).
      */
     readonly attribute nsIURI JARFile;
 
--- a/modules/libjar/nsJARURI.cpp
+++ b/modules/libjar/nsJARURI.cpp
@@ -243,16 +243,30 @@ NS_IMETHODIMP
 nsJARURI::GetSpec(nsACString &aSpec)
 {
     nsCAutoString entrySpec;
     mJAREntry->GetSpec(entrySpec);
     return FormatSpec(entrySpec, aSpec);
 }
 
 NS_IMETHODIMP
+nsJARURI::GetSpecIgnoringRef(nsACString &aSpec)
+{
+    nsCAutoString entrySpec;
+    mJAREntry->GetSpecIgnoringRef(entrySpec);
+    return FormatSpec(entrySpec, aSpec);
+}
+
+NS_IMETHODIMP
+nsJARURI::GetHasRef(PRBool *result)
+{
+    return mJAREntry->GetHasRef(result);
+}
+
+NS_IMETHODIMP
 nsJARURI::SetSpec(const nsACString& aSpec)
 {
     return SetSpecWithBase(aSpec, nsnull);
 }
 
 nsresult
 nsJARURI::SetSpecWithBase(const nsACString &aSpec, nsIURI* aBaseURL)
 {
--- a/modules/libpr0n/decoders/icon/nsIIconURI.idl
+++ b/modules/libpr0n/decoders/icon/nsIIconURI.idl
@@ -68,17 +68,17 @@
    *   Values:      [normal | disabled]
    *   Description: The state of the icon.
    *
    *   Parameter:   contentType
    *   Values:      <mime-type>
    *   Description: The mime type we want an icon for. This is ignored by stock images.
    */
 
-[scriptable, uuid(b6a47fa0-2f1e-4084-ae5f-bdebab4d1cc3)]
+[scriptable, uuid(da53adda-cbe3-41bc-a57d-fdd7a0ff448b)]
 interface nsIMozIconURI : nsIURI 
 {
   /**
    * iconFile
    *
    * the file URL contained within this moz-icon url, or null.
    */
   attribute nsIURL iconURL;
--- a/modules/libpr0n/decoders/icon/nsIconURI.cpp
+++ b/modules/libpr0n/decoders/icon/nsIconURI.cpp
@@ -140,16 +140,29 @@ nsMozIconURI::GetSpec(nsACString &aSpec)
   {
     aSpec += "&contentType=";
     aSpec += mContentType.get();
   }
   
   return NS_OK;
 }
 
+NS_IMETHODIMP
+nsMozIconURI::GetSpecIgnoringRef(nsACString &result)
+{
+  return GetSpec(result);
+}
+
+NS_IMETHODIMP
+nsMozIconURI::GetHasRef(PRBool *result)
+{
+  *result = PR_FALSE;
+  return NS_OK;
+}
+
 // takes a string like ?size=32&contentType=text/html and returns a new string 
 // containing just the attribute value. i.e you could pass in this string with
 // an attribute name of 'size=', this will return 32
 // Assumption: attribute pairs in the string are separated by '&'.
 void extractAttributeValue(const char * searchString, const char * attributeName, nsCString& result)
 {
   //NS_ENSURE_ARG_POINTER(extractAttributeValue);
 
--- a/netwerk/base/public/nsIFileURL.idl
+++ b/netwerk/base/public/nsIFileURL.idl
@@ -40,17 +40,17 @@
 
 interface nsIFile;
 
 /**
  * nsIFileURL provides access to the underlying nsIFile object corresponding to
  * an URL.  The URL scheme need not be file:, since other local protocols may
  * map URLs to files (e.g., resource:).
  */
-[scriptable, uuid(44c14c16-07b4-48fb-b44b-0c8986697a17)]
+[scriptable, uuid(93a4f94e-1dae-4056-ac4e-08e13691ee8e)]
 interface nsIFileURL : nsIURL
 {
     /**
      * Get/Set nsIFile corresponding to this URL.
      *
      *  - Getter returns a reference to an immutable object.  Callers must clone
      *    before attempting to modify the returned nsIFile object.  NOTE: this
      *    constraint might not be enforced at runtime, so beware!!
--- a/netwerk/base/public/nsIURI.idl
+++ b/netwerk/base/public/nsIURI.idl
@@ -96,17 +96,17 @@
  * nsIIOService.newURI.
  *
  * NOTE: nsBinaryInputStream::ReadObject contains a hackaround to intercept the
  * old (pre-gecko6) nsIURI IID and swap in the current IID instead, in order
  * for sessionstore to work after an upgrade.  If this IID is revved further,
  * we will need to add additional checks there for all intermediate IIDs, until
  * nsPrincipal is fixed to serialize its URIs as nsISupports (bug 662693).
  */
-[scriptable, uuid(12120b20-0929-40e9-88cf-6e08766e8b23)]
+[scriptable, uuid(395fe045-7d18-4adb-a3fd-af98c8a1af11)]
 interface nsIURI : nsISupports
 {
     /************************************************************************
      * The URI is broken down into the following principal components:
      */
 
     /**
      * Returns a string representation of the URI. Setting the spec causes
@@ -267,9 +267,18 @@ interface nsIURI : nsISupports
      */
     boolean equalsExceptRef(in nsIURI other);
 
     /**
      * Clones the current URI, clearing the 'ref' attribute in the clone.
      */
     nsIURI cloneIgnoringRef();
 
+    /**
+     * returns a string for the current URI with the ref element cleared.
+     */
+   readonly attribute AUTF8String specIgnoringRef;
+
+    /**
+     * Returns if there is a reference portion (the part after the "#") of the URI.
+     */
+   readonly attribute boolean hasRef;
 };
--- a/netwerk/base/public/nsIURL.idl
+++ b/netwerk/base/public/nsIURL.idl
@@ -49,17 +49,17 @@
  *            \          \                       /
  *             \          -----------------------
  *              \                   |          /
  *               \               fileName     /
  *                ----------------------------
  *                            |
  *                        filePath
  */
-[scriptable, uuid(eab18ad5-e3be-4eb3-9c78-7d4e750200d6)]
+[scriptable, uuid(067d697a-c725-4293-9656-e658a75e6bcf)]
 interface nsIURL : nsIURI
 {
     /*************************************************************************
      * The URL path is broken down into the following principal components:
      */
 
     /**
      * Returns a path including the directory and file portions of a
--- a/netwerk/base/src/nsSimpleURI.cpp
+++ b/netwerk/base/src/nsSimpleURI.cpp
@@ -196,16 +196,31 @@ nsSimpleURI::GetSpec(nsACString &result)
     if (mIsRefValid) {
         result += NS_LITERAL_CSTRING("#") + mRef;
     } else {
         NS_ABORT_IF_FALSE(mRef.IsEmpty(), "mIsRefValid/mRef invariant broken");
     }
     return NS_OK;
 }
 
+// result may contain unescaped UTF-8 characters
+NS_IMETHODIMP
+nsSimpleURI::GetSpecIgnoringRef(nsACString &result)
+{
+    result = mScheme + NS_LITERAL_CSTRING(":") + mPath;
+    return NS_OK;
+}
+
+NS_IMETHODIMP
+nsSimpleURI::GetHasRef(PRBool *result)
+{
+    *result = mIsRefValid;
+    return NS_OK;
+}
+
 NS_IMETHODIMP
 nsSimpleURI::SetSpec(const nsACString &aSpec)
 {
     NS_ENSURE_STATE(mMutable);
     
     const nsAFlatCString& flat = PromiseFlatCString(aSpec);
     const char* specPtr = flat.get();
 
--- a/netwerk/base/src/nsStandardURL.cpp
+++ b/netwerk/base/src/nsStandardURL.cpp
@@ -996,16 +996,31 @@ NS_IMETHODIMP
 nsStandardURL::GetSpec(nsACString &result)
 {
     result = mSpec;
     return NS_OK;
 }
 
 // result may contain unescaped UTF-8 characters
 NS_IMETHODIMP
+nsStandardURL::GetSpecIgnoringRef(nsACString &result)
+{
+    // URI without ref is 0 to one char before ref
+    if (mRef.mLen >= 0) {
+        URLSegment noRef(0, mRef.mPos - 1);
+
+        result = Segment(noRef);
+    } else {
+        result = mSpec;
+    }
+    return NS_OK;
+}
+
+// result may contain unescaped UTF-8 characters
+NS_IMETHODIMP
 nsStandardURL::GetPrePath(nsACString &result)
 {
     result = Prepath();
     return NS_OK;
 }
 
 // result is strictly US-ASCII
 NS_IMETHODIMP
@@ -2139,16 +2154,23 @@ nsStandardURL::GetQuery(nsACString &resu
 // result may contain unescaped UTF-8 characters
 NS_IMETHODIMP
 nsStandardURL::GetRef(nsACString &result)
 {
     result = Ref();
     return NS_OK;
 }
 
+NS_IMETHODIMP
+nsStandardURL::GetHasRef(PRBool *result)
+{
+    *result = (mRef.mLen >= 0);
+    return NS_OK;
+}
+
 // result may contain unescaped UTF-8 characters
 NS_IMETHODIMP
 nsStandardURL::GetDirectory(nsACString &result)
 {
     result = Directory();
     return NS_OK;
 }
 
--- a/netwerk/test/unit/test_URIs.js
+++ b/netwerk/test/unit/test_URIs.js
@@ -301,23 +301,27 @@ var gTests = [
     ref:     "",// fix
     nsIURL:  true, nsINestedURI: false },
   { spec:    "http://a/b/c/d;p?q",
     relativeURI: "g?y",
     scheme:  "http",
     prePath: "http://a",
     path:    "/b/c/g?y",
     ref:     "",// fix
+    specIgnoringRef: "http://a/b/c/g?y",
+    hasRef:  false,
     nsIURL:  true, nsINestedURI: false },
   { spec:    "http://a/b/c/d;p?q",
     relativeURI: "#s",
     scheme:  "http",
     prePath: "http://a",
     path:    "/b/c/d;p?q#s",
     ref:     "s",// fix
+    specIgnoringRef: "http://a/b/c/d;p?q",
+    hasRef:  true,
     nsIURL:  true, nsINestedURI: false },
   { spec:    "http://a/b/c/d;p?q",
     relativeURI: "g#s",
     scheme:  "http",
     prePath: "http://a",
     path:    "/b/c/g#s",
     ref:     "s",
     nsIURL:  true, nsINestedURI: false },
@@ -683,16 +687,21 @@ function do_test_uri_basic(aTest) {
   do_check_property(aTest, URI, "scheme");
   do_check_property(aTest, URI, "prePath");
   do_check_property(aTest, URI, "path");
   do_check_property(aTest, URI, "ref");
   do_check_property(aTest, URI, "port");
   do_check_property(aTest, URI, "username");
   do_check_property(aTest, URI, "password");
   do_check_property(aTest, URI, "host");
+  do_check_property(aTest, URI, "specIgnoringRef");
+  if ("hasRef" in aTest) {
+    do_info("testing hasref: " + aTest.hasRef + " vs " + URI.hasRef);
+    do_check_eq(aTest.hasRef, URI.hasRef);
+  }
 }
 
 // Test that a given URI parses correctly when we add a given ref to the end
 function do_test_uri_with_hash_suffix(aTest, aSuffix) {
   do_info("making sure caller is using suffix that starts with '#'");
   do_check_eq(aSuffix[0], "#");
 
   var origURI = NetUtil.newURI(aTest.spec);
@@ -723,16 +732,18 @@ function do_test_uri_with_hash_suffix(aT
           " doesn't equal self with '" + aSuffix + "' appended");
 
   do_check_false(origURI.equals(testURI));
 
   do_info("testing " + aTest.spec +
           " is equalExceptRef to self with '" + aSuffix + "' appended");
   do_check_uri_eqExceptRef(origURI, testURI);
 
+  do_check_eq(testURI.hasRef, true);
+
   if (!origURI.ref) {
     // These tests fail if origURI has a ref
     do_info("testing cloneIgnoringRef on " + testURI.spec +
             " is equal to no-ref version but not equal to ref version");
     var cloneNoRef = testURI.cloneIgnoringRef();
     do_check_uri_eq(cloneNoRef, origURI);
     do_check_false(cloneNoRef.equals(testURI));
   }
--- a/testing/jetpack/jetpack-location.txt
+++ b/testing/jetpack/jetpack-location.txt
@@ -1,1 +1,1 @@
-http://hg.mozilla.org/projects/addon-sdk/archive/cfcf0515ae75.tar.bz2
+http://hg.mozilla.org/projects/addon-sdk/archive/9f45975c909d.tar.bz2
--- a/toolkit/content/aboutSupport.js
+++ b/toolkit/content/aboutSupport.js
@@ -242,16 +242,25 @@ function populateGraphicsSection() {
     pushInfoRow(trGraphics, "adapterVendorID", hexValueToString(gfxInfo.adapterVendorID));
     pushInfoRow(trGraphics, "adapterDeviceID", hexValueToString(gfxInfo.adapterDeviceID));
     pushInfoRow(trGraphics, "adapterRAM", gfxInfo.adapterRAM);
     pushInfoRow(trGraphics, "adapterDrivers", gfxInfo.adapterDriver);
     pushInfoRow(trGraphics, "driverVersion", gfxInfo.adapterDriverVersion);
     pushInfoRow(trGraphics, "driverDate", gfxInfo.adapterDriverDate);
 
 #ifdef XP_WIN
+    pushInfoRow(trGraphics, "adapterDescription2", gfxInfo.adapterDescription2);
+    pushInfoRow(trGraphics, "adapterVendorID2", hexValueToString(gfxInfo.adapterVendorID2));
+    pushInfoRow(trGraphics, "adapterDeviceID2", hexValueToString(gfxInfo.adapterDeviceID2));
+    pushInfoRow(trGraphics, "adapterRAM2", gfxInfo.adapterRAM2);
+    pushInfoRow(trGraphics, "adapterDrivers2", gfxInfo.adapterDriver2);
+    pushInfoRow(trGraphics, "driverVersion2", gfxInfo.adapterDriverVersion2);
+    pushInfoRow(trGraphics, "driverDate2", gfxInfo.adapterDriverDate2);
+    pushInfoRow(trGraphics, "isGPU2Active", gfxInfo.isGPU2Active);
+
     var version = Cc["@mozilla.org/system-info;1"]
                   .getService(Ci.nsIPropertyBag2)
                   .getProperty("version");
     var isWindowsVistaOrHigher = (parseFloat(version) >= 6.0);
     if (isWindowsVistaOrHigher) {
       var d2dEnabled = "false";
       try {
         d2dEnabled = gfxInfo.D2DEnabled;
--- a/toolkit/locales/en-US/chrome/global/aboutSupport.properties
+++ b/toolkit/locales/en-US/chrome/global/aboutSupport.properties
@@ -26,9 +26,17 @@ clearTypeParameters = ClearType Paramete
 clearTypeParametersNotFound = ClearType parameters not found
 adapterDescription = Adapter Description
 adapterVendorID = Vendor ID
 adapterDeviceID = Device ID
 adapterDrivers = Adapter Drivers
 adapterRAM = Adapter RAM
 driverVersion = Driver Version
 driverDate = Driver Date
+adapterDescription2 = Adapter Description (GPU #2) 
+adapterVendorID2 = Vendor ID (GPU #2) 
+adapterDeviceID2 = Device ID (GPU #2)
+adapterDrivers2 = Adapter Drivers (GPU #2)
+adapterRAM2 = Adapter RAM (GPU #2)
+driverVersion2 = Driver Version (GPU #2)
+driverDate2 = Driver Date (GPU #2)
+isGPU2Active = GPU #2 Active
 webglRenderer = WebGL Renderer
--- a/widget/public/nsIGfxInfo.idl
+++ b/widget/public/nsIGfxInfo.idl
@@ -46,37 +46,48 @@ interface nsIGfxInfo : nsISupports
   /*
    * These are win32-specific
    */
   readonly attribute boolean D2DEnabled;
   readonly attribute boolean DWriteEnabled;
   readonly attribute boolean AzureEnabled;
   readonly attribute DOMString DWriteVersion;
   readonly attribute DOMString cleartypeParameters;
-  
+
+  // XXX: Switch to a list of devices, rather than explicitly numbering them. 
+
   /**
    * The name of the display adapter.
    */
   readonly attribute DOMString adapterDescription;
+  readonly attribute DOMString adapterDescription2;
 
   readonly attribute DOMString adapterDriver;
+  readonly attribute DOMString adapterDriver2;
   
   /* These types are inspired by DXGI_ADAPTER_DESC */
   readonly attribute unsigned long adapterVendorID;
+  readonly attribute unsigned long adapterVendorID2;
   
   readonly attribute unsigned long adapterDeviceID;
-  
+  readonly attribute unsigned long adapterDeviceID2;
+
   /**
    * The amount of RAM in MB in the display adapter.
    */
   readonly attribute DOMString adapterRAM;
+  readonly attribute DOMString adapterRAM2;
   
   readonly attribute DOMString adapterDriverVersion;
+  readonly attribute DOMString adapterDriverVersion2;
   
   readonly attribute DOMString adapterDriverDate;
+  readonly attribute DOMString adapterDriverDate2;
+
+  readonly attribute boolean isGPU2Active;
 
   void getFailures(
                [optional] out unsigned long failureCount,
                [retval, array, size_is(failureCount)] out string failures);
 
   [noscript, notxpcom] void logFailure(in ACString failure);
   /*
    * A set of constants for features that we can ask this GfxInfo object
--- a/widget/src/android/AndroidBridge.cpp
+++ b/widget/src/android/AndroidBridge.cpp
@@ -143,16 +143,17 @@ AndroidBridge::Init(JNIEnv *jEnv,
     jIsNetworkLinkUp = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "isNetworkLinkUp", "()Z");
     jIsNetworkLinkKnown = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "isNetworkLinkKnown", "()Z");
     jGetNetworkLinkType = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getNetworkLinkType", "()I");
     jSetSelectedLocale = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "setSelectedLocale", "(Ljava/lang/String;)V");
     jScanMedia = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "scanMedia", "(Ljava/lang/String;Ljava/lang/String;)V");
     jGetSystemColors = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getSystemColors", "()[I");
     jGetIconForExtension = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getIconForExtension", "(Ljava/lang/String;I)[B");
     jCreateShortcut = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "createShortcut", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V");
+    jGetShowPasswordSetting = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "getShowPasswordSetting", "()Z");
 
     jEGLContextClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("javax/microedition/khronos/egl/EGLContext"));
     jEGL10Class = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("javax/microedition/khronos/egl/EGL10"));
     jEGLSurfaceImplClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("com/google/android/gles_jni/EGLSurfaceImpl"));
     jEGLContextImplClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("com/google/android/gles_jni/EGLContextImpl"));
     jEGLConfigImplClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("com/google/android/gles_jni/EGLConfigImpl"));
     jEGLDisplayImplClass = (jclass) jEnv->NewGlobalRef(jEnv->FindClass("com/google/android/gles_jni/EGLDisplayImpl"));
 
@@ -750,16 +751,23 @@ AndroidBridge::GetIconForExtension(const
     PRUint32 bufSize = aIconSize * aIconSize * 4;
     NS_ASSERTION(len == bufSize, "AndroidBridge::GetIconForExtension: Pixels array is incomplete!");
     if (len == bufSize)
         memcpy(aBuf, elements, bufSize);
 
     mJNIEnv->ReleaseByteArrayElements(arr, elements, 0);
 }
 
+bool
+AndroidBridge::GetShowPasswordSetting()
+{
+    ALOG_BRIDGE("AndroidBridge::GetShowPasswordSetting");
+    return mJNIEnv->CallStaticBooleanMethod(mGeckoAppShellClass, jGetShowPasswordSetting);
+}
+
 void
 AndroidBridge::SetSurfaceView(jobject obj)
 {
     mSurfaceView.Init(obj);
 }
 
 void
 AndroidBridge::ShowInputMethodPicker()
@@ -993,9 +1001,8 @@ AndroidBridge::LockBitmap(jobject bitmap
 
 void
 AndroidBridge::UnlockBitmap(jobject bitmap)
 {
     int err;
     if ((err = AndroidBitmap_unlockPixels(JNI(), bitmap)) != 0)
         ALOG_BRIDGE("AndroidBitmap_unlockPixels failed! (error %d)", err);
 }
-
--- a/widget/src/android/AndroidBridge.h
+++ b/widget/src/android/AndroidBridge.h
@@ -207,16 +207,18 @@ public:
     int GetNetworkLinkType();
 
     void SetSelectedLocale(const nsAString&);
 
     void GetSystemColors(AndroidSystemColors *aColors);
 
     void GetIconForExtension(const nsACString& aFileExt, PRUint32 aIconSize, PRUint8 * const aBuf);
 
+    bool GetShowPasswordSetting();
+
     struct AutoLocalJNIFrame {
         AutoLocalJNIFrame(int nEntries = 128) : mEntries(nEntries) {
             // Make sure there is enough space to store a local ref to the
             // exception.  I am not completely sure this is needed, but does
             // not hurt.
             AndroidBridge::Bridge()->JNI()->PushLocalFrame(mEntries + 1);
         }
         // Note! Calling Purge makes all previous local refs created in
@@ -317,16 +319,17 @@ protected:
     jmethodID jIsNetworkLinkUp;
     jmethodID jIsNetworkLinkKnown;
     jmethodID jGetNetworkLinkType;
     jmethodID jSetSelectedLocale;
     jmethodID jScanMedia;
     jmethodID jGetSystemColors;
     jmethodID jGetIconForExtension;
     jmethodID jCreateShortcut;
+    jmethodID jGetShowPasswordSetting;
 
     // stuff we need for CallEglCreateWindowSurface
     jclass jEGLSurfaceImplClass;
     jclass jEGLContextImplClass;
     jclass jEGLConfigImplClass;
     jclass jEGLDisplayImplClass;
     jclass jEGLContextClass;
     jclass jEGL10Class;
--- a/widget/src/android/GfxInfo.cpp
+++ b/widget/src/android/GfxInfo.cpp
@@ -106,64 +106,120 @@ GfxInfo::GetAdapterDescription(nsAString
       aAdapterDescription.Append(NS_LITERAL_STRING(" "));
       if (mozilla::AndroidBridge::Bridge()->GetStaticStringField("android/os/Build", "HARDWARE", str))
         aAdapterDescription.Append(str);
   }
 
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDescription2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute DOMString adapterRAM; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM)
 {
   aAdapterRAM.AssignLiteral("");
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterRAM2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute DOMString adapterDriver; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver)
 {
   aAdapterDriver.AssignLiteral("");
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDriver2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute DOMString adapterDriverVersion; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion)
 {
   aAdapterDriverVersion.AssignLiteral("");
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDriverVersion2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute DOMString adapterDriverDate; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate)
 {
   aAdapterDriverDate.AssignLiteral("");
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDriverDate2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute unsigned long adapterVendorID; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterVendorID(PRUint32 *aAdapterVendorID)
 {
   *aAdapterVendorID = 0;
   return NS_OK;
 }
 
+/* readonly attribute unsigned long adapterVendorID2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterVendorID2(PRUint32 *aAdapterVendorID)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute unsigned long adapterDeviceID; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDeviceID(PRUint32 *aAdapterDeviceID)
 {
   *aAdapterDeviceID = 0;
   return NS_OK;
 }
 
+/* readonly attribute unsigned long adapterDeviceID2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDeviceID2(PRUint32 *aAdapterDeviceID)
+{
+  return NS_ERROR_FAILURE;
+}
+
+/* readonly attribute boolean isGPU2Active; */
+NS_IMETHODIMP
+GfxInfo::GetIsGPU2Active(PRBool* aIsGPU2Active)
+{
+  return NS_ERROR_FAILURE;
+}
+
 void
 GfxInfo::AddCrashReportAnnotations()
 {
 #if 0
 #if defined(MOZ_CRASHREPORTER)
   nsCAutoString deviceIDString, vendorIDString;
   PRUint32 deviceID, vendorID;
 
--- a/widget/src/android/GfxInfo.h
+++ b/widget/src/android/GfxInfo.h
@@ -59,16 +59,24 @@ public:
   NS_SCRIPTABLE NS_IMETHOD GetCleartypeParameters(nsAString & aCleartypeParams);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDescription(nsAString & aAdapterDescription);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDriver(nsAString & aAdapterDriver);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterVendorID(PRUint32 *aAdapterVendorID);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDeviceID(PRUint32 *aAdapterDeviceID);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterRAM(nsAString & aAdapterRAM);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverVersion(nsAString & aAdapterDriverVersion);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverDate(nsAString & aAdapterDriverDate);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDescription2(nsAString & aAdapterDescription);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDriver2(nsAString & aAdapterDriver);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterVendorID2(PRUint32 *aAdapterVendorID);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDeviceID2(PRUint32 *aAdapterDeviceID);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterRAM2(nsAString & aAdapterRAM);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverDate2(nsAString & aAdapterDriverDate);
+  NS_SCRIPTABLE NS_IMETHOD GetIsGPU2Active(PRBool *aIsGPU2Active);
   using GfxInfoBase::GetFeatureStatus;
   using GfxInfoBase::GetFeatureSuggestedDriverVersion;
   using GfxInfoBase::GetWebGLParameter;
 
   virtual nsresult Init();
 
 protected:
 
--- a/widget/src/android/nsLookAndFeel.cpp
+++ b/widget/src/android/nsLookAndFeel.cpp
@@ -40,19 +40,22 @@
 #include "mozilla/dom/ContentChild.h"
 #include "nsStyleConsts.h"
 #include "nsXULAppAPI.h"
 #include "nsLookAndFeel.h"
 
 using namespace mozilla;
 using mozilla::dom::ContentChild;
 
-PRBool nsLookAndFeel::mInitialized = PR_FALSE;
+PRBool nsLookAndFeel::mInitializedSystemColors = PR_FALSE;
 AndroidSystemColors nsLookAndFeel::mSystemColors;
 
+PRBool nsLookAndFeel::mInitializedShowPassword = PR_FALSE;
+PRBool nsLookAndFeel::mShowPassword = PR_TRUE;
+
 nsLookAndFeel::nsLookAndFeel()
     : nsXPLookAndFeel()
 {
 }
 
 nsLookAndFeel::~nsLookAndFeel()
 {
 }
@@ -63,25 +66,25 @@ nsLookAndFeel::~nsLookAndFeel()
 #define DARK_GRAY_COLOR        NS_RGB(0x40,0x40,0x40)
 #define GRAY_COLOR             NS_RGB(0x80,0x80,0x80)
 #define LIGHT_GRAY_COLOR       NS_RGB(0xa0,0xa0,0xa0)
 #define RED_COLOR              NS_RGB(0xff,0x00,0x00)
 
 nsresult
 nsLookAndFeel::GetSystemColors()
 {
-    if (mInitialized)
+    if (mInitializedSystemColors)
         return NS_OK;
 
     if (!AndroidBridge::Bridge())
         return NS_ERROR_FAILURE;
 
     AndroidBridge::Bridge()->GetSystemColors(&mSystemColors);
 
-    mInitialized = PR_TRUE;
+    mInitializedSystemColors = PR_TRUE;
 
     return NS_OK;
 }
 
 nsresult
 nsLookAndFeel::CallRemoteGetSystemColors()
 {
     // An array has to be used to get data from remote process
@@ -97,27 +100,27 @@ nsLookAndFeel::CallRemoteGetSystemColors
 
     if (colors.Length() < colorsCount)
         colorsCount = colors.Length();
 
     // Array elements correspond to the members of mSystemColors structure,
     // so just copy the memory block
     memcpy(&mSystemColors, colors.Elements(), sizeof(nscolor) * colorsCount);
 
-    mInitialized = PR_TRUE;
+    mInitializedSystemColors = PR_TRUE;
 
     return NS_OK;
 }
 
 nsresult
 nsLookAndFeel::NativeGetColor(const nsColorID aID, nscolor &aColor)
 {
     nsresult rv = NS_OK;
 
-    if (!mInitialized) {
+    if (!mInitializedSystemColors) {
         if (XRE_GetProcessType() == GeckoProcessType_Default)
             rv = GetSystemColors();
         else
             rv = CallRemoteGetSystemColors();
         NS_ENSURE_SUCCESS(rv, rv);
     }
 
     // XXX we'll want to use context.obtainStyledAttributes on the java side to
@@ -455,8 +458,25 @@ nsLookAndFeel::GetMetric(const nsMetricF
 
         default:
             aMetric = -1.0;
             rv = NS_ERROR_FAILURE;
             break;
     }
     return rv;
 }
+
+/*virtual*/
+PRBool nsLookAndFeel::GetEchoPassword()
+{
+    if (!mInitializedShowPassword) {
+        if (XRE_GetProcessType() == GeckoProcessType_Default) {
+            if (AndroidBridge::Bridge())
+                mShowPassword = AndroidBridge::Bridge()->GetShowPasswordSetting();
+            else
+                NS_ASSERTION(AndroidBridge::Bridge() != nsnull, "AndroidBridge is not available!");
+        } else {
+            ContentChild::GetSingleton()->SendGetShowPasswordSetting(&mShowPassword);
+        }
+        mInitializedShowPassword = PR_TRUE;
+    }
+    return mShowPassword;
+}
--- a/widget/src/android/nsLookAndFeel.h
+++ b/widget/src/android/nsLookAndFeel.h
@@ -46,18 +46,21 @@ class nsLookAndFeel: public nsXPLookAndF
 {
 public:
     nsLookAndFeel();
     virtual ~nsLookAndFeel();
 
     nsresult NativeGetColor(const nsColorID aID, nscolor &aColor);
     NS_IMETHOD GetMetric(const nsMetricID aID, PRInt32 & aMetric);
     NS_IMETHOD GetMetric(const nsMetricFloatID aID, float & aMetric);
+    virtual PRBool GetEchoPassword();
 
 protected:
-    static PRBool mInitialized;
+    static PRBool mInitializedSystemColors;
     static mozilla::AndroidSystemColors mSystemColors;
+    static PRBool mInitializedShowPassword;
+    static PRBool mShowPassword;
 
     nsresult GetSystemColors();
     nsresult CallRemoteGetSystemColors();
 };
 
 #endif
--- a/widget/src/cocoa/GfxInfo.h
+++ b/widget/src/cocoa/GfxInfo.h
@@ -59,16 +59,24 @@ public:
   NS_SCRIPTABLE NS_IMETHOD GetCleartypeParameters(nsAString & aCleartypeParams);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDescription(nsAString & aAdapterDescription);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDriver(nsAString & aAdapterDriver);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterVendorID(PRUint32 *aAdapterVendorID);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDeviceID(PRUint32 *aAdapterDeviceID);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterRAM(nsAString & aAdapterRAM);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverVersion(nsAString & aAdapterDriverVersion);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverDate(nsAString & aAdapterDriverDate);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDescription2(nsAString & aAdapterDescription);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDriver2(nsAString & aAdapterDriver);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterVendorID2(PRUint32 *aAdapterVendorID);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDeviceID2(PRUint32 *aAdapterDeviceID);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterRAM2(nsAString & aAdapterRAM);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverDate2(nsAString & aAdapterDriverDate);
+  NS_SCRIPTABLE NS_IMETHOD GetIsGPU2Active(PRBool *aIsGPU2Active);
   using GfxInfoBase::GetFeatureStatus;
   using GfxInfoBase::GetFeatureSuggestedDriverVersion;
   using GfxInfoBase::GetWebGLParameter;
 
   virtual nsresult Init();
 
 protected:
 
--- a/widget/src/cocoa/GfxInfo.mm
+++ b/widget/src/cocoa/GfxInfo.mm
@@ -129,64 +129,120 @@ GfxInfo::GetCleartypeParameters(nsAStrin
 /* readonly attribute DOMString adapterDescription; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription)
 {
   aAdapterDescription = mRendererIDsString;
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDescription2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute DOMString adapterRAM; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM)
 {
   aAdapterRAM = mAdapterRAMString;
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterRAM2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute DOMString adapterDriver; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver)
 {
   aAdapterDriver.AssignLiteral("");
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDriver2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute DOMString adapterDriverVersion; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion)
 {
   aAdapterDriverVersion.AssignLiteral("");
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDriverVersion2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute DOMString adapterDriverDate; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate)
 {
   aAdapterDriverDate.AssignLiteral("");
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDriverDate2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute unsigned long adapterVendorID; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterVendorID(PRUint32 *aAdapterVendorID)
 {
   *aAdapterVendorID = 0;
   return NS_OK;
 }
 
+/* readonly attribute unsigned long adapterVendorID2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterVendorID2(PRUint32 *aAdapterVendorID)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute unsigned long adapterDeviceID; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDeviceID(PRUint32 *aAdapterDeviceID)
 {
   *aAdapterDeviceID = 0;
   return NS_OK;
 }
 
+/* readonly attribute unsigned long adapterDeviceID2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDeviceID2(PRUint32 *aAdapterDeviceID)
+{
+  return NS_ERROR_FAILURE;
+}
+
+/* readonly attribute boolean isGPU2Active; */
+NS_IMETHODIMP
+GfxInfo::GetIsGPU2Active(PRBool* aIsGPU2Active)
+{
+  return NS_ERROR_FAILURE;
+}
+
 void
 GfxInfo::AddCrashReportAnnotations()
 {
 #if defined(MOZ_CRASHREPORTER)
   CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AdapterRendererIDs"),
                                      NS_LossyConvertUTF16toASCII(mRendererIDsString));
 
   /* Add an App Note for now so that we get the data immediately. These
--- a/widget/src/windows/GfxInfo.cpp
+++ b/widget/src/windows/GfxInfo.cpp
@@ -72,17 +72,21 @@ static const PRUint32 vendorAMD = 0x1022
 static const PRUint32 vendorATI = 0x1002;
 
 #define V(a,b,c,d) GFX_DRIVER_VERSION(a,b,c,d)
 
 
 GfxInfo::GfxInfo()
   : mAdapterVendorID(0),
     mAdapterDeviceID(0),
-    mWindowsVersion(0)
+    mAdapterVendorID2(0),
+    mAdapterDeviceID2(0),
+    mWindowsVersion(0),
+    mHasDualGPU(PR_FALSE),
+    mIsGPU2Active(PR_FALSE)
 {
 }
 
 /* GetD2DEnabled and GetDwriteEnabled shouldn't be called until after gfxPlatform initialization
  * has occurred because they depend on it for information. (See bug 591561) */
 nsresult
 GfxInfo::GetD2DEnabled(PRBool *aEnabled)
 {
@@ -194,18 +198,16 @@ GfxInfo::GetCleartypeParameters(nsAStrin
 
   if (foundData) {
     aCleartypeParams.Assign(outStr);
     return NS_OK;
   }
   return NS_ERROR_FAILURE;
 }
 
-/* XXX: GfxInfo doesn't handle multiple GPUs. We should try to do that. Bug #591057 */
-
 static nsresult GetKeyValue(const WCHAR* keyLocation, const WCHAR* keyName, nsAString& destString, int type)
 {
   HKEY key;
   DWORD dwcbData;
   DWORD dValue;
   DWORD resultType;
   LONG result;
   nsresult retval = NS_OK;
@@ -404,47 +406,107 @@ GfxInfo::Init()
               dwcbData = sizeof(value);
               result = RegQueryValueExW(key, L"DriverVersion", NULL, NULL, (LPBYTE)value, &dwcbData);
               if (result == ERROR_SUCCESS)
                 mDriverVersion = value;
               dwcbData = sizeof(value);
               result = RegQueryValueExW(key, L"DriverDate", NULL, NULL, (LPBYTE)value, &dwcbData);
               if (result == ERROR_SUCCESS)
                 mDriverDate = value;
-              RegCloseKey(key);
+              RegCloseKey(key); 
+
+              // Check for second adapter:
+              //
+              // A second adapter will have the same driver key as the first adapter except for 
+              // the last character, where '1' will be swapped for '0' or vice-versa.
+              // We know driverKey.Length() > 0 since driverKeyPre is a prefix of driverKey.
+              if (driverKey[driverKey.Length()-1] == '0') {
+                driverKey.SetCharAt('1', driverKey.Length()-1);
+              } else {
+                driverKey.SetCharAt('0', driverKey.Length()-1);
+              }
+              result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, driverKey.BeginReading(), 0, KEY_QUERY_VALUE, &key);
+              if (result == ERROR_SUCCESS) {
+                mHasDualGPU = PR_TRUE;
+                mDeviceKey2 = driverKey;
+                dwcbData = sizeof(value);
+                result = RegQueryValueExW(key, L"DriverVersion", NULL, NULL, (LPBYTE)value, &dwcbData);
+                if (result == ERROR_SUCCESS)
+                  mDriverVersion2 = value;
+                dwcbData = sizeof(value);
+                result = RegQueryValueExW(key, L"DriverDate", NULL, NULL, (LPBYTE)value, &dwcbData);
+                if (result == ERROR_SUCCESS)
+                  mDriverDate2 = value;
+                dwcbData = sizeof(value);
+                result = RegQueryValueExW(key, L"Device Description", NULL, NULL, (LPBYTE)value, &dwcbData);
+                if (result == ERROR_SUCCESS)
+                  mDeviceString2 = value;
+                dwcbData = sizeof(value);
+                result = RegQueryValueExW(key, L"MatchingDeviceId", NULL, NULL, (LPBYTE)value, &dwcbData);
+                if (result == ERROR_SUCCESS)
+                  mDeviceID2 = value;
+                RegCloseKey(key);
+              }  
               break;
             }
           }
         }
 
         setupDestroyDeviceInfoList(devinfo);
       }
     }
 
     FreeLibrary(setupapi);
   }
 
+  nsAutoString vendor(mDeviceID);
+  ToUpperCase(vendor);
+  PRInt32 start = vendor.Find(NS_LITERAL_CSTRING("VEN_"));
+  if (start != -1) {
+    vendor.Cut(0, start + strlen("VEN_"));
+    vendor.Truncate(4);
+  }
+  nsresult err;
+  mAdapterVendorID = vendor.ToInteger(&err, 16);
+  
+  vendor = mDeviceID2;
+  ToUpperCase(vendor);
+  start = vendor.Find(NS_LITERAL_CSTRING("VEN_"));
+  if (start != -1) {
+    vendor.Cut(0, start + strlen("VEN_"));
+    vendor.Truncate(4);
+  }
+  mAdapterVendorID2 = vendor.ToInteger(&err, 16);
+
+  nsAutoString device(mDeviceID);
+  ToUpperCase(device);
+  start = device.Find(NS_LITERAL_CSTRING("&DEV_"));
+  if (start != -1) {
+    device.Cut(0, start + strlen("&DEV_"));
+    device.Truncate(4);
+  }
+  mAdapterDeviceID = device.ToInteger(&err, 16);
+  
+  device = mDeviceID2;
+  ToUpperCase(device);
+  start = device.Find(NS_LITERAL_CSTRING("&DEV_"));
+  if (start != -1) {
+    device.Cut(0, start + strlen("&DEV_"));
+    device.Truncate(4);
+  }
+  mAdapterDeviceID2 = device.ToInteger(&err, 16);
+  
   const char *spoofedDriverVersionString = PR_GetEnv("MOZ_GFX_SPOOF_DRIVER_VERSION");
   if (spoofedDriverVersionString) {
     mDriverVersion.AssignASCII(spoofedDriverVersionString);
   }
 
   const char *spoofedVendor = PR_GetEnv("MOZ_GFX_SPOOF_VENDOR_ID");
   if (spoofedVendor) {
      PR_sscanf(spoofedVendor, "%x", &mAdapterVendorID);
-  } else {
-    nsAutoString vendor(mDeviceID);
-    ToUpperCase(vendor);
-    PRInt32 start = vendor.Find(NS_LITERAL_CSTRING("VEN_"));
-    if (start != -1) {
-      vendor.Cut(0, start + strlen("VEN_"));
-      vendor.Truncate(4);
-    }
-    nsresult err;
-    mAdapterVendorID = vendor.ToInteger(&err, 16);
   }
 
   mHasDriverVersionMismatch = PR_FALSE;
   if (mAdapterVendorID == vendorIntel) {
     // we've had big crashers (bugs 590373 and 595364) apparently correlated
     // with bad Intel driver installations where the DriverVersion reported
     // by the registry was not the version of the DLL.
     PRBool is64bitApp = sizeof(void*) == 8;
@@ -463,26 +525,16 @@ GfxInfo::Init()
     // so this test implicitly handles the case where GetDLLVersion failed
     if (dllNumericVersion != driverNumericVersion)
       mHasDriverVersionMismatch = PR_TRUE;
   }
 
   const char *spoofedDevice = PR_GetEnv("MOZ_GFX_SPOOF_DEVICE_ID");
   if (spoofedDevice) {
     PR_sscanf(spoofedDevice, "%x", &mAdapterDeviceID);
-  } else {
-    nsAutoString device(mDeviceID);
-    ToUpperCase(device);
-    PRInt32 start = device.Find(NS_LITERAL_CSTRING("&DEV_"));
-    if (start != -1) {
-      device.Cut(0, start + strlen("&DEV_"));
-      device.Truncate(4);
-    }
-    nsresult err;
-    mAdapterDeviceID = device.ToInteger(&err, 16);
   }
 
   const char *spoofedWindowsVersion = PR_GetEnv("MOZ_GFX_SPOOF_WINDOWS_VERSION");
   if (spoofedWindowsVersion) {
     PR_sscanf(spoofedWindowsVersion, "%x", &mWindowsVersion);
   } else {
     mWindowsVersion = gfxWindowsPlatform::WindowsOSVersion();
   }
@@ -495,66 +547,132 @@ GfxInfo::Init()
 /* readonly attribute DOMString adapterDescription; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription)
 {
   aAdapterDescription = mDeviceString;
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDescription2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription)
+{
+  aAdapterDescription = mDeviceString2;
+  return NS_OK;
+}
+
 /* readonly attribute DOMString adapterRAM; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM)
 {
   if (NS_FAILED(GetKeyValue(mDeviceKey.BeginReading(), L"HardwareInformation.MemorySize", aAdapterRAM, REG_DWORD)))
     aAdapterRAM = L"Unknown";
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterRAM2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM)
+{
+  if (NS_FAILED(GetKeyValue(mDeviceKey2.BeginReading(), L"HardwareInformation.MemorySize", aAdapterRAM, REG_DWORD)))
+    aAdapterRAM = L"Unknown";
+  return NS_OK;
+}
+
 /* readonly attribute DOMString adapterDriver; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver)
 {
   if (NS_FAILED(GetKeyValue(mDeviceKey.BeginReading(), L"InstalledDisplayDrivers", aAdapterDriver, REG_MULTI_SZ)))
     aAdapterDriver = L"Unknown";
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDriver2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver)
+{
+  if (NS_FAILED(GetKeyValue(mDeviceKey2.BeginReading(), L"InstalledDisplayDrivers", aAdapterDriver, REG_MULTI_SZ)))
+    aAdapterDriver = L"Unknown";
+  return NS_OK;
+}
+
 /* readonly attribute DOMString adapterDriverVersion; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion)
 {
   aAdapterDriverVersion = mDriverVersion;
   return NS_OK;
 }
 
 /* readonly attribute DOMString adapterDriverDate; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate)
 {
   aAdapterDriverDate = mDriverDate;
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDriverVersion2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion)
+{
+  aAdapterDriverVersion = mDriverVersion2;
+  return NS_OK;
+}
+
+/* readonly attribute DOMString adapterDriverDate2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate)
+{
+  aAdapterDriverDate = mDriverDate2;
+  return NS_OK;
+}
+
 /* readonly attribute unsigned long adapterVendorID; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterVendorID(PRUint32 *aAdapterVendorID)
 {
   *aAdapterVendorID = mAdapterVendorID;
   return NS_OK;
 }
 
+/* readonly attribute unsigned long adapterVendorID2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterVendorID2(PRUint32 *aAdapterVendorID)
+{
+  *aAdapterVendorID = mAdapterVendorID2;
+  return NS_OK;
+}
+
 /* readonly attribute unsigned long adapterDeviceID; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDeviceID(PRUint32 *aAdapterDeviceID)
 {
   *aAdapterDeviceID = mAdapterDeviceID;
   return NS_OK;
 }
 
+/* readonly attribute unsigned long adapterDeviceID2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDeviceID2(PRUint32 *aAdapterDeviceID)
+{
+  *aAdapterDeviceID = mAdapterDeviceID2;
+  return NS_OK;
+}
+
+/* readonly attribute boolean isGPU2Active; */
+NS_IMETHODIMP
+GfxInfo::GetIsGPU2Active(PRBool* aIsGPU2Active)
+{
+  *aIsGPU2Active = mIsGPU2Active;
+  return NS_OK;
+}
+
 #if defined(MOZ_CRASHREPORTER)
 /* Cisco's VPN software can cause corruption of the floating point state.
  * Make a note of this in our crash reports so that some weird crashes
  * make more sense */
 static void
 CheckForCiscoVPN() {
   LONG result;
   HKEY key;
@@ -602,16 +720,29 @@ GfxInfo::AddCrashReportAnnotations()
       /* if we didn't find a valid vendorID lets append the mDeviceID string to try to find out why */
       note.Append(", ");
       note.AppendWithConversion(mDeviceID);
       note.Append(", ");
       note.AppendWithConversion(mDeviceKeyDebug);
   }
   note.Append("\n");
 
+  if (mHasDualGPU) {
+    PRUint32 deviceID2, vendorID2;
+    nsAutoString adapterDriverVersionString2;
+
+    note.Append("Has dual GPUs. GPU #2: ");
+    GetAdapterDeviceID2(&deviceID2);
+    GetAdapterVendorID2(&vendorID2);
+    GetAdapterDriverVersion2(adapterDriverVersionString2);
+    note.AppendPrintf("AdapterVendorID2: %04x, ", vendorID2);
+    note.AppendPrintf("AdapterDeviceID2: %04x, ", deviceID2);
+    note.AppendPrintf("AdapterDriverVersion2: ");
+    note.Append(NS_LossyConvertUTF16toASCII(adapterDriverVersionString2));
+  }
   CrashReporter::AppendAppNotesToCrashReport(note);
 
 #endif
 }
 
 #define V(a,b,c,d) GFX_DRIVER_VERSION(a,b,c,d)
 
 static const PRUint32 deviceFamilyIntelGMA500[] = {
--- a/widget/src/windows/GfxInfo.h
+++ b/widget/src/windows/GfxInfo.h
@@ -63,16 +63,24 @@ public:
   NS_SCRIPTABLE NS_IMETHOD GetCleartypeParameters(nsAString & aCleartypeParams);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDescription(nsAString & aAdapterDescription);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDriver(nsAString & aAdapterDriver);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterVendorID(PRUint32 *aAdapterVendorID);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDeviceID(PRUint32 *aAdapterDeviceID);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterRAM(nsAString & aAdapterRAM);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverVersion(nsAString & aAdapterDriverVersion);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverDate(nsAString & aAdapterDriverDate);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDescription2(nsAString & aAdapterDescription);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDriver2(nsAString & aAdapterDriver);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterVendorID2(PRUint32 *aAdapterVendorID);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDeviceID2(PRUint32 *aAdapterDeviceID);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterRAM2(nsAString & aAdapterRAM);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverDate2(nsAString & aAdapterDriverDate);
+  NS_SCRIPTABLE NS_IMETHOD GetIsGPU2Active(PRBool *aIsGPU2Active);
   using GfxInfoBase::GetFeatureStatus;
   using GfxInfoBase::GetFeatureSuggestedDriverVersion;
   using GfxInfoBase::GetWebGLParameter;
 
 #ifdef DEBUG
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_NSIGFXINFODEBUG
 #endif
@@ -89,16 +97,25 @@ private:
   nsString mDeviceString;
   nsString mDeviceID;
   nsString mDriverVersion;
   nsString mDriverDate;
   nsString mDeviceKey;
   nsString mDeviceKeyDebug;
   PRUint32 mAdapterVendorID;
   PRUint32 mAdapterDeviceID;
+  nsString mDeviceString2;
+  nsString mDriverVersion2;
+  nsString mDeviceID2;
+  nsString mDriverDate2;
+  nsString mDeviceKey2;
+  PRUint32 mAdapterVendorID2;
+  PRUint32 mAdapterDeviceID2;
   PRUint32 mWindowsVersion;
+  PRBool mHasDualGPU;
+  PRBool mIsGPU2Active;
   PRBool mHasDriverVersionMismatch;
 };
 
 } // namespace widget
 } // namespace mozilla
 
 #endif /* __mozilla_widget_GfxInfo_h__ */
--- a/widget/src/xpwidgets/GfxInfoX11.cpp
+++ b/widget/src/xpwidgets/GfxInfoX11.cpp
@@ -338,60 +338,116 @@ GfxInfo::GetCleartypeParameters(nsAStrin
 NS_IMETHODIMP
 GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription)
 {
   GetData();
   AppendASCIItoUTF16(mAdapterDescription, aAdapterDescription);
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDescription2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute DOMString adapterRAM; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM)
 {
   aAdapterRAM.AssignLiteral("");
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterRAM2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute DOMString adapterDriver; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver)
 {
   aAdapterDriver.AssignLiteral("");
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDriver2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute DOMString adapterDriverVersion; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion)
 {
   GetData();
   CopyASCIItoUTF16(mVersion, aAdapterDriverVersion);
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDriverVersion2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute DOMString adapterDriverDate; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate)
 {
   aAdapterDriverDate.AssignLiteral("");
   return NS_OK;
 }
 
+/* readonly attribute DOMString adapterDriverDate2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute unsigned long adapterVendorID; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterVendorID(PRUint32 *aAdapterVendorID)
 {
   *aAdapterVendorID = 0;
   return NS_OK;
 }
 
+/* readonly attribute unsigned long adapterVendorID2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterVendorID2(PRUint32 *aAdapterVendorID)
+{
+  return NS_ERROR_FAILURE;
+}
+
 /* readonly attribute unsigned long adapterDeviceID; */
 NS_IMETHODIMP
 GfxInfo::GetAdapterDeviceID(PRUint32 *aAdapterDeviceID)
 {
   *aAdapterDeviceID = 0;
   return NS_OK;
 }
 
+/* readonly attribute unsigned long adapterDeviceID2; */
+NS_IMETHODIMP
+GfxInfo::GetAdapterDeviceID2(PRUint32 *aAdapterDeviceID)
+{
+  return NS_ERROR_FAILURE;
+}
+
+/* readonly attribute boolean isGPU2Active; */
+NS_IMETHODIMP
+GfxInfo::GetIsGPU2Active(PRBool* aIsGPU2Active)
+{
+  return NS_ERROR_FAILURE;
+}
+
 
 } // end namespace widget
 } // end namespace mozilla
--- a/widget/src/xpwidgets/GfxInfoX11.h
+++ b/widget/src/xpwidgets/GfxInfoX11.h
@@ -58,16 +58,24 @@ public:
   NS_SCRIPTABLE NS_IMETHOD GetCleartypeParameters(nsAString & aCleartypeParams);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDescription(nsAString & aAdapterDescription);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDriver(nsAString & aAdapterDriver);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterVendorID(PRUint32 *aAdapterVendorID);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDeviceID(PRUint32 *aAdapterDeviceID);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterRAM(nsAString & aAdapterRAM);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverVersion(nsAString & aAdapterDriverVersion);
   NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverDate(nsAString & aAdapterDriverDate);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDescription2(nsAString & aAdapterDescription);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDriver2(nsAString & aAdapterDriver);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterVendorID2(PRUint32 *aAdapterVendorID);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDeviceID2(PRUint32 *aAdapterDeviceID);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterRAM2(nsAString & aAdapterRAM);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion);
+  NS_SCRIPTABLE NS_IMETHOD GetAdapterDriverDate2(nsAString & aAdapterDriverDate);
+  NS_SCRIPTABLE NS_IMETHOD GetIsGPU2Active(PRBool *aIsGPU2Active);
   using GfxInfoBase::GetFeatureStatus;
   using GfxInfoBase::GetFeatureSuggestedDriverVersion;
   using GfxInfoBase::GetWebGLParameter;
 
   virtual nsresult Init();
 
 protected:
 
--- a/xpcom/ds/nsIVariant.idl
+++ b/xpcom/ds/nsIVariant.idl
@@ -72,20 +72,16 @@ interface nsIDataType : nsISupports
     const PRUint16 VTYPE_WSTRING_SIZE_IS     = 22; // TD_PWSTRING_SIZE_IS  = 22,
     const PRUint16 VTYPE_UTF8STRING          = 23; // TD_UTF8STRING        = 23,
     const PRUint16 VTYPE_CSTRING             = 24; // TD_CSTRING           = 24,
     const PRUint16 VTYPE_ASTRING             = 25; // TD_ASTRING           = 25,
     const PRUint16 VTYPE_EMPTY_ARRAY         = 254;
     const PRUint16 VTYPE_EMPTY               = 255;
 };
 
-%{ C++
-#include "jspubtd.h"
-%}
-
 /**
  * XPConnect has magic to transparently convert between nsIVariant and JS types.
  * We mark the interface [scriptable] so that JS can use methods
  * that refer to this interface. But we mark all the methods and attributes
  * [noscript] since any nsIVariant object will be automatically converted to a
  * JS type anyway.
  */
 
--- a/xpcom/idl-parser/xpidl.py
+++ b/xpcom/idl-parser/xpidl.py
@@ -854,16 +854,18 @@ class Method(object):
                                     self.name,
                                     ", ".join([p.toIDL()
                                                for p in self.params]),
                                     raises)
 
     def needsJSTypes(self):
         if self.implicit_jscontext:
             return True
+        if self.type == "jsval":
+            return True
         for p in self.params:
             t = p.realtype
             if isinstance(t, Native) and t.specialtype == "jsval":
                 return True
         return False
 
     def count(self):
         return 1
new file mode 100644
--- /dev/null
+++ b/xpcom/tests/unit/head_xpcom.js
@@ -0,0 +1,25 @@
+var isWindows = ("@mozilla.org/windows-registry-key;1" in Components.classes);
+
+function get_test_program(prog)
+{
+  var progPath = do_get_cwd();
+  progPath.append(prog);
+  if (isWindows)
+    progPath.leafName = progPath.leafName + ".exe";
+  return progPath;
+}
+
+function set_process_running_environment()
+{
+  var envSvc = Components.classes["@mozilla.org/process/environment;1"].
+    getService(Components.interfaces.nsIEnvironment);
+  var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].
+    getService(Components.interfaces.nsIProperties);
+  var greDir = dirSvc.get("GreD", Components.interfaces.nsIFile);
+
+  envSvc.set("DYLD_LIBRARY_PATH", greDir.path);
+  // For Linux
+  envSvc.set("LD_LIBRARY_PATH", greDir.path);
+  //XXX: handle windows
+}
+
--- a/xpcom/tests/unit/test_nsIProcess.js
+++ b/xpcom/tests/unit/test_nsIProcess.js
@@ -37,42 +37,16 @@
 const TEST_ARGS = ["mozilla", "firefox", "thunderbird", "seamonkey", "foo",
                    "bar", "argument with spaces", "\"argument with quotes\""];
 
 const TEST_UNICODE_ARGS = ["M\u00F8z\u00EEll\u00E5",
                            "\u041C\u043E\u0437\u0438\u043B\u043B\u0430",
                            "\u09AE\u09CB\u099C\u09BF\u09B2\u09BE",
                            "\uD808\uDE2C\uD808\uDF63\uD808\uDDB7"];
 
-var isWindows = ("@mozilla.org/windows-registry-key;1" in Components.classes);
-
-function get_test_program(prog)
-{
-  var progPath = do_get_cwd();
-  progPath.append(prog);
-  if (isWindows)
-    progPath.leafName = progPath.leafName + ".exe";
-  return progPath;
-}
-
-function set_environment()
-{
-  var envSvc = Components.classes["@mozilla.org/process/environment;1"].
-    getService(Components.interfaces.nsIEnvironment);
-  var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].
-    getService(Components.interfaces.nsIProperties);
-  var greDir = dirSvc.get("GreD", Components.interfaces.nsIFile);
-
-  envSvc.set("DYLD_LIBRARY_PATH", greDir.path);
-  // For Linux
-  envSvc.set("LD_LIBRARY_PATH", greDir.path);
-  //XXX: handle windows
-}
-
-
 // test if a process can be started, polled for its running status
 // and then killed
 function test_kill()
 {
   var file = get_test_program("TestBlockingProcess");
  
   var process = Components.classes["@mozilla.org/process/util;1"]
                           .createInstance(Components.interfaces.nsIProcess);
@@ -226,46 +200,18 @@ function test_notify_killed()
       do_check_eq(topic, "process-finished");
       do_test_finished();
     }
   });
 
   process.kill();
 }
 
-// test if killing a process that is already finished doesn't crash
-function test_kill_2()
-{
-  var file = get_test_program("TestQuickReturn");
-  var thread = Components.classes["@mozilla.org/thread-manager;1"]
-                         .getService().currentThread;
-
-  for (var i = 0; i < 1000; i++) {
-    var process = Components.classes["@mozilla.org/process/util;1"]
-                          .createInstance(Components.interfaces.nsIProcess);
-    process.init(file);
-
-    process.run(false, [], 0);
-
-    try {
-      process.kill();
-    }
-    catch (e) { }
-
-    // We need to ensure that we process any events on the main thread -
-    // this allow threads to clean up properly and avoid out of memory
-    // errors during the test.
-    while (thread.hasPendingEvents())
-      thread.processNextEvent(false);
-  }
-}
-
 function run_test() {
-  set_environment();
+  set_process_running_environment();
   test_kill();
   test_quick();
   test_arguments();
   test_unicode_arguments();
   test_unicode_app();
   do_test_pending();
   test_notify_blocking();
-  test_kill_2();
 }
new file mode 100644
--- /dev/null
+++ b/xpcom/tests/unit/test_nsIProcess_stress.js
@@ -0,0 +1,27 @@
+function run_test() {
+  set_process_running_environment();
+
+  var file = get_test_program("TestQuickReturn");
+  var thread = Components.classes["@mozilla.org/thread-manager;1"]
+                         .getService().currentThread;
+
+  for (var i = 0; i < 1000; i++) {
+    var process = Components.classes["@mozilla.org/process/util;1"]
+                          .createInstance(Components.interfaces.nsIProcess);
+    process.init(file);
+
+    process.run(false, [], 0);
+
+    try {
+      process.kill();
+    }
+    catch (e) { }
+
+    // We need to ensure that we process any events on the main thread -
+    // this allow threads to clean up properly and avoid out of memory
+    // errors during the test.
+    while (thread.hasPendingEvents())
+      thread.processNextEvent(false);
+  }
+
+}
\ No newline at end of file
--- a/xpcom/tests/unit/xpcshell.ini
+++ b/xpcom/tests/unit/xpcshell.ini
@@ -1,10 +1,10 @@
 [DEFAULT]
-head = 
+head = head_xpcom.js
 tail = 
 
 [test_bug121341.js]
 [test_bug332389.js]
 [test_bug333505.js]
 [test_bug364285-1.js]
 [test_bug374754.js]
 [test_bug476919.js]
@@ -16,15 +16,17 @@ tail =
 [test_hidden_files.js]
 [test_home.js]
 [test_iniProcessor.js]
 [test_ioutil.js]
 [test_localfile.js]
 [test_mac_bundle.js]
 [test_nsIMutableArray.js]
 [test_nsIProcess.js]
+[test_nsIProcess_stress.js]
+skip-if = os == "win" # See bug: 676412
 [test_pipe.js]
 [test_storagestream.js]
 [test_streams.js]
 [test_stringstream.js]
 [test_symlinks.js]
 [test_systemInfo.js]
 [test_versioncomparator.js]
--- a/xpfe/appshell/src/nsXULWindow.cpp
+++ b/xpfe/appshell/src/nsXULWindow.cpp
@@ -84,17 +84,16 @@
 #include "nsAppShellCID.h"
 #include "nsReadableUtils.h"
 #include "nsStyleConsts.h"
 #include "nsPresContext.h"
 #include "nsContentUtils.h"
 #include "nsWebShellWindow.h" // get rid of this one, too...
 
 #include "prenv.h"
-
 #include "mozilla/Preferences.h"
 
 using namespace mozilla;
 
 #define SIZEMODE_NORMAL     NS_LITERAL_STRING("normal")
 #define SIZEMODE_MAXIMIZED  NS_LITERAL_STRING("maximized")
 #define SIZEMODE_MINIMIZED  NS_LITERAL_STRING("minimized")
 #define SIZEMODE_FULLSCREEN NS_LITERAL_STRING("fullscreen")
@@ -196,17 +195,25 @@ NS_IMETHODIMP nsXULWindow::GetInterface(
   }   
   if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
     rv = EnsureAuthPrompter();
     if (NS_FAILED(rv)) return rv;
     return mAuthPrompter->QueryInterface(aIID, aSink);
   }
   if (aIID.Equals(NS_GET_IID(nsIDOMWindow))) {
     return GetWindowDOMWindow(reinterpret_cast<nsIDOMWindow**>(aSink));
-  }   
+  }
+  if (aIID.Equals(NS_GET_IID(nsIDOMWindowInternal))) {
+    nsIDOMWindow* domWindow = nsnull;
+    rv = GetWindowDOMWindow(&domWindow);
+    nsIDOMWindowInternal* domWindowInternal =
+      static_cast<nsIDOMWindowInternal*>(domWindow);
+    *aSink = domWindowInternal;
+    return rv;
+  }
   if (aIID.Equals(NS_GET_IID(nsIWebBrowserChrome)) && 
     NS_SUCCEEDED(EnsureContentTreeOwner()) &&
     NS_SUCCEEDED(mContentTreeOwner->QueryInterface(aIID, aSink)))
     return NS_OK;
 
   if (aIID.Equals(NS_GET_IID(nsIEmbeddingSiteWindow)) && 
     NS_SUCCEEDED(EnsureContentTreeOwner()) &&
     NS_SUCCEEDED(mContentTreeOwner->QueryInterface(aIID, aSink)))