Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Wed, 11 Jan 2012 14:11:45 -0800
changeset 105552 91c7d8b9c9e96bed8c5f867ccd98fed385638c48
parent 105551 6e4acb5ff1b82b0fdf4b3849380124f587b4669c (current diff)
parent 84272 7c7d2a8db7ffd00d817249c1cfd3939465418894 (diff)
child 105553 a12010ca115a11b5b6701cbc16dcf7910637941e
push id23447
push userdanderson@mozilla.com
push dateTue, 11 Sep 2012 17:34:27 +0000
treeherdermozilla-central@fdfaef738a00 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone12.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge from mozilla-central.
accessible/src/atk/nsAccessibleWrap.cpp
accessible/src/atk/nsApplicationAccessibleWrap.cpp
accessible/src/base/nsAccessibilityService.h
accessible/src/base/nsAccessible.cpp
accessible/src/base/nsAccessible.h
accessible/src/base/nsCoreUtils.cpp
accessible/src/base/nsDocAccessible.cpp
accessible/src/html/nsHTMLImageAccessible.h
accessible/src/html/nsHyperTextAccessible.cpp
accessible/src/html/nsHyperTextAccessible.h
accessible/src/msaa/nsAccessibleWrap.cpp
accessible/tests/mochitest/events/test_caretmove.xul
accessible/tests/mochitest/states/Makefile.in
b2g/installer/package-manifest.in
browser/app/profile/firefox.js
browser/components/migration/src/nsProfileMigrator.cpp
browser/components/shell/src/nsGNOMEShellService.cpp
browser/devtools/webconsole/HUDService.jsm
browser/devtools/webconsole/test/browser_webconsole_bug_595934_message_categories.js
browser/devtools/webconsole/test/browser_webconsole_bug_653531_highlighter_console_helper.js
config/autoconf.mk.in
config/system-headers
configure.in
content/base/public/nsContentUtils.h
content/base/public/nsDOMFile.h
content/base/public/nsIContentIterator.h
content/base/public/nsIRange.h
content/base/public/nsIRangeUtils.h
content/base/src/Makefile.in
content/base/src/nsContentIterator.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsCopySupport.cpp
content/base/src/nsCrossSiteListenerProxy.cpp
content/base/src/nsCrossSiteListenerProxy.h
content/base/src/nsDocumentEncoder.cpp
content/base/src/nsFrameMessageManager.cpp
content/base/src/nsGenericElement.cpp
content/base/src/nsGkAtomList.h
content/base/src/nsRange.cpp
content/base/src/nsRange.h
content/base/src/nsTextNode.cpp
content/base/src/nsTreeSanitizer.cpp
content/base/src/nsXMLHttpRequest.cpp
content/base/test/test_XHR.html
content/canvas/src/CustomQS_Canvas2D.h
content/canvas/src/CustomQS_WebGL.h
content/canvas/src/nsCanvasRenderingContext2DAzure.cpp
content/events/src/nsContentEventHandler.cpp
content/events/src/nsContentEventHandler.h
content/events/src/nsIMEStateManager.cpp
content/html/content/src/nsGenericHTMLElement.cpp
content/html/content/src/nsGenericHTMLElement.h
content/html/content/src/nsHTMLAudioElement.cpp
content/html/content/src/nsHTMLCanvasElement.cpp
content/html/content/src/nsHTMLMediaElement.cpp
content/html/document/src/nsHTMLDocument.cpp
content/media/VideoUtils.cpp
content/media/VideoUtils.h
content/media/nsBuiltinDecoder.cpp
content/media/nsBuiltinDecoderReader.cpp
content/media/nsBuiltinDecoderStateMachine.cpp
content/media/ogg/nsOggCodecState.cpp
content/media/ogg/nsOggCodecState.h
content/media/wave/nsWaveReader.cpp
dom/base/nsDOMClassInfo.cpp
dom/base/nsGlobalWindow.cpp
dom/base/nsJSEnvironment.cpp
dom/base/nsJSEnvironment.h
dom/interfaces/range/nsIDOMNSRange.idl
dom/plugins/base/nsJSNPRuntime.cpp
dom/plugins/base/nsNPAPIPlugin.cpp
dom/plugins/base/nsPluginInstanceOwner.cpp
dom/plugins/ipc/PluginInstanceChild.cpp
dom/plugins/ipc/PluginInstanceParent.cpp
dom/plugins/ipc/PluginMessageUtils.h
dom/src/storage/nsDOMStoragePersistentDB.cpp
dom/src/storage/nsDOMStoragePersistentDB.h
dom/workers/WorkerPrivate.cpp
editor/libeditor/base/IMETextTxn.cpp
editor/libeditor/base/nsEditor.cpp
editor/libeditor/base/nsEditorEventListener.cpp
editor/libeditor/base/nsSelectionState.cpp
editor/libeditor/base/nsSelectionState.h
editor/libeditor/html/nsHTMLDataTransfer.cpp
editor/libeditor/html/nsHTMLEditRules.cpp
editor/libeditor/html/nsHTMLEditRules.h
editor/libeditor/html/nsHTMLEditor.cpp
editor/libeditor/html/nsHTMLEditor.h
editor/libeditor/html/nsHTMLEditorEventListener.cpp
editor/libeditor/html/nsWSRunObject.cpp
editor/libeditor/text/nsPlaintextDataTransfer.cpp
editor/libeditor/text/nsTextEditRules.cpp
editor/libeditor/text/nsTextEditUtils.cpp
editor/libeditor/text/nsTextEditUtils.h
editor/txmgr/tests/TestTXMgr.cpp
editor/txtsvc/src/nsFilteredContentIterator.cpp
editor/txtsvc/src/nsFilteredContentIterator.h
editor/txtsvc/src/nsTextServicesDocument.cpp
embedding/components/find/src/nsFind.cpp
extensions/spellcheck/src/mozInlineSpellChecker.cpp
extensions/spellcheck/src/mozInlineSpellChecker.h
extensions/spellcheck/src/mozInlineSpellWordUtil.cpp
extensions/spellcheck/src/mozInlineSpellWordUtil.h
gfx/layers/ipc/ShadowLayerUtilsX11.cpp
gfx/thebes/gfxFont.cpp
gfx/thebes/gfxFont.h
gfx/thebes/gfxPangoFonts.cpp
gfx/thebes/gfxPlatform.cpp
gfx/thebes/gfxPlatformGtk.cpp
gfx/thebes/gfxPlatformGtk.h
gfx/thebes/nsCoreAnimationSupport.mm
image/src/RasterImage.cpp
image/src/RasterImage.h
js/jsd/jsd_xpc.cpp
js/jsd/jsd_xpc.h
js/src/Makefile.in
js/src/MemoryMetrics.cpp
js/src/config/system-headers
js/src/ion/CodeGenerator.cpp
js/src/ion/IonCode.h
js/src/jsapi.cpp
js/src/jsapi.h
js/src/jsatom.h
js/src/jscntxt.cpp
js/src/jscntxt.h
js/src/jscompartment.cpp
js/src/jsdbgapi.cpp
js/src/jsdbgapi.h
js/src/jsfriendapi.cpp
js/src/jsfriendapi.h
js/src/jsfun.h
js/src/jsgc.cpp
js/src/jsgc.h
js/src/jsinfer.cpp
js/src/jsinfer.h
js/src/jsiter.cpp
js/src/jsobj.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/jsopcode.cpp
js/src/jsscope.cpp
js/src/jsscript.cpp
js/src/jstypedarray.cpp
js/src/jstypedarray.h
js/src/shell/js.cpp
js/xpconnect/src/XPCCallContext.cpp
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/src/XPCConvert.cpp
js/xpconnect/src/XPCJSRuntime.cpp
js/xpconnect/src/XPCMaps.cpp
js/xpconnect/src/XPCQuickStubs.cpp
js/xpconnect/src/XPCThreadContext.cpp
js/xpconnect/src/XPCVariant.cpp
js/xpconnect/src/XPCWrappedJSClass.cpp
js/xpconnect/src/XPCWrappedNativeJSOps.cpp
js/xpconnect/src/nsXPConnect.cpp
js/xpconnect/src/qsgen.py
js/xpconnect/src/xpcprivate.h
js/xpconnect/src/xpcpublic.h
js/xpconnect/wrappers/AccessCheck.cpp
js/xpconnect/wrappers/FilteringWrapper.cpp
js/xpconnect/wrappers/WrapperFactory.cpp
js/xpconnect/wrappers/XrayWrapper.cpp
layout/base/FrameLayerBuilder.cpp
layout/base/FrameLayerBuilder.h
layout/base/nsPresContext.cpp
layout/base/nsPresContext.h
layout/base/nsPresShell.cpp
layout/base/nsPresShell.h
layout/build/nsLayoutModule.cpp
layout/forms/nsTextControlFrame.cpp
layout/generic/nsFrameSelection.h
layout/generic/nsSelection.cpp
layout/inspector/src/inDOMUtils.cpp
layout/printing/nsPrintEngine.cpp
layout/reftests/bugs/reftest.list
mobile/android/base/GeckoApp.java
mobile/android/base/GeckoAppShell.java
mobile/android/base/Makefile.in
mobile/xul/chrome/content/content.js
mobile/xul/installer/package-manifest.in
mozglue/android/APKOpen.cpp
mozglue/android/Makefile.in
netwerk/protocol/ftp/FTPChannelChild.cpp
netwerk/protocol/ftp/FTPChannelChild.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/nsHttp.h
netwerk/protocol/http/nsHttpChannel.cpp
other-licenses/android/Makefile.in
security/manager/ssl/src/nsNSSComponent.cpp
toolkit/components/telemetry/Telemetry.cpp
toolkit/components/telemetry/TelemetryHistograms.h
toolkit/components/typeaheadfind/nsTypeAheadFind.cpp
toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp
toolkit/components/url-classifier/nsUrlClassifierPrefixSet.h
toolkit/mozapps/installer/packager.mk
widget/android/AndroidJNI.cpp
widget/android/nsAppShell.cpp
widget/cocoa/nsCocoaFeatures.h
widget/cocoa/nsCocoaFeatures.mm
widget/gtk2/nsSound.cpp
widget/gtk2/nsWindow.cpp
widget/gtk2/nsWindow.h
widget/windows/JumpListItem.cpp
widget/windows/nsFilePicker.cpp
widget/windows/nsToolkit.cpp
widget/windows/nsToolkit.h
xpcom/base/nsConsoleService.cpp
xpcom/base/nsConsoleService.h
xpcom/build/nsXPComInit.cpp
xpcom/components/nsCategoryManager.cpp
xpcom/components/nsCategoryManager.h
xpcom/glue/nsTHashtable.h
xpcom/proxy/Makefile.in
xpcom/proxy/public/Makefile.in
xpcom/proxy/public/nsIProxyObjectManager.idl
xpcom/proxy/public/nsProxiedService.h
xpcom/proxy/src/Makefile.in
xpcom/proxy/src/nsProxyEvent.cpp
xpcom/proxy/src/nsProxyEventClass.cpp
xpcom/proxy/src/nsProxyEventObject.cpp
xpcom/proxy/src/nsProxyEventPrivate.h
xpcom/proxy/src/nsProxyObjectManager.cpp
xpcom/proxy/tests/Makefile.in
xpcom/proxy/tests/nsITestProxy.idl
xpcom/proxy/tests/proxy-create-threadsafety.cpp
xpcom/proxy/tests/proxytests.cpp
xpcom/tests/TestProxies.cpp
xpcom/tests/TestThreadPoolListener.cpp
xpcom/threads/TimerThread.cpp
xpcom/threads/nsThreadPool.cpp
--- a/accessible/src/atk/Makefile.in
+++ b/accessible/src/atk/Makefile.in
@@ -87,15 +87,19 @@ EXPORTS = \
 # we want to force the creation of a static lib.
 FORCE_STATIC_LIB = 1
 
 include $(topsrcdir)/config/rules.mk
 
 CFLAGS		+= $(MOZ_GTK2_CFLAGS)
 CXXFLAGS	+= $(MOZ_GTK2_CFLAGS)
 
+ifdef MOZ_ENABLE_DBUS
+CXXFLAGS += $(MOZ_DBUS_CFLAGS)
+endif
+
 LOCAL_INCLUDES += \
   -I$(srcdir) \
   -I$(srcdir)/../base \
   -I$(srcdir)/../html \
   -I$(srcdir)/../xul \
   -I$(topsrcdir)/other-licenses/atk-1.0 \
   $(NULL)
--- a/accessible/src/atk/nsAccessibleWrap.cpp
+++ b/accessible/src/atk/nsAccessibleWrap.cpp
@@ -444,23 +444,18 @@ nsAccessibleWrap::CreateMaiInterfaces(vo
     //nsIAccessibleDocument
     nsCOMPtr<nsIAccessibleDocument> accessInterfaceDocument;
     QueryInterface(NS_GET_IID(nsIAccessibleDocument),
                               getter_AddRefs(accessInterfaceDocument));
     if (accessInterfaceDocument) {
         interfacesBits |= 1 << MAI_INTERFACE_DOCUMENT;
     }
 
-    //nsIAccessibleImage
-    nsCOMPtr<nsIAccessibleImage> accessInterfaceImage;
-    QueryInterface(NS_GET_IID(nsIAccessibleImage),
-                              getter_AddRefs(accessInterfaceImage));
-    if (accessInterfaceImage) {
+    if (IsImageAccessible())
         interfacesBits |= 1 << MAI_INTERFACE_IMAGE;
-    }
 
   // HyperLinkAccessible
   if (IsLink())
     interfacesBits |= 1 << MAI_INTERFACE_HYPERLINK_IMPL;
 
     if (!nsAccUtils::MustPrune(this)) {  // These interfaces require children
       //nsIAccessibleHypertext
       if (IsHyperText()) {
--- a/accessible/src/atk/nsApplicationAccessibleWrap.cpp
+++ b/accessible/src/atk/nsApplicationAccessibleWrap.cpp
@@ -47,29 +47,30 @@
 #include "nsIGConfService.h"
 #include "nsIServiceManager.h"
 #include "nsAutoPtr.h"
 #include "nsAccessibilityService.h"
 #include "AtkSocketAccessible.h"
 
 #include <gtk/gtk.h>
 #include <atk/atk.h>
+#ifdef MOZ_ENABLE_DBUS
+#include <dbus/dbus.h>
+#endif
 
 using namespace mozilla;
+using namespace mozilla::a11y;
 
 typedef GType (* AtkGetTypeType) (void);
 GType g_atk_hyperlink_impl_type = G_TYPE_INVALID;
 static bool sATKChecked = false;
 static PRLibrary *sATKLib = nsnull;
 static const char sATKLibName[] = "libatk-1.0.so.0";
 static const char sATKHyperlinkImplGetTypeSymbol[] =
-    "atk_hyperlink_impl_get_type";
-static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
-static const char sGconfAccessibilityKey[] =
-    "/desktop/gnome/interface/accessibility";
+  "atk_hyperlink_impl_get_type";
 
 /* gail function pointer */
 static guint (* gail_add_global_event_listener) (GSignalEmissionHook listener,
                                                  const gchar *event_type);
 static void (* gail_remove_global_event_listener) (guint remove_listener);
 static void (* gail_remove_key_event_listener) (guint remove_listener);
 static AtkObject * (*gail_get_root) (void);
 
@@ -609,37 +610,17 @@ toplevel_event_watcher(GSignalInvocation
   }
 
   return TRUE;
 }
 
 bool
 nsApplicationAccessibleWrap::Init()
 {
-    // XXX following code is copied from widget/gtk2/nsWindow.cpp
-    // we should put it to somewhere that can be used from both modules
-    // see bug 390761
-
-    // check if accessibility enabled/disabled by environment variable
-    bool isGnomeATEnabled = false;
-    const char *envValue = PR_GetEnv(sAccEnv);
-    if (envValue) {
-        isGnomeATEnabled = !!atoi(envValue);
-    } else {
-        //check gconf-2 setting
-      nsresult rv;
-      nsCOMPtr<nsIGConfService> gconf =
-        do_GetService(NS_GCONFSERVICE_CONTRACTID, &rv);
-      if (NS_SUCCEEDED(rv) && gconf) {
-          gconf->GetBool(NS_LITERAL_CSTRING(sGconfAccessibilityKey),
-                         &isGnomeATEnabled);
-      }
-    }
-
-    if (isGnomeATEnabled) {
+    if (ShouldA11yBeEnabled()) {
         // load and initialize gail library
         nsresult rv = LoadGtkModule(sGail);
         if (NS_SUCCEEDED(rv)) {
             (*sGail.init)();
         }
         else {
             MAI_LOG_DEBUG(("Fail to load lib: %s\n", sGail.libName));
         }
@@ -878,8 +859,135 @@ LoadGtkModule(GnomeAccessibilityModule& 
                        aModule.init ? aModule.shutdownName : aModule.initName,
                        aModule.libName));
         PR_UnloadLibrary(aModule.lib);
         aModule.lib = NULL;
         return NS_ERROR_FAILURE;
     }
     return NS_OK;
 }
+
+namespace mozilla {
+namespace a11y {
+
+  static const char sAccEnv [] = "GNOME_ACCESSIBILITY";
+#ifdef MOZ_ENABLE_DBUS
+static DBusPendingCall *sPendingCall = nsnull;
+#endif
+
+void
+PreInit()
+{
+#ifdef MOZ_ENABLE_DBUS
+  static bool sChecked = FALSE;
+  if (sChecked)
+    return;
+
+  sChecked = TRUE;
+
+  // dbus is only checked if GNOME_ACCESSIBILITY is unset
+  // also make sure that a session bus address is available to prevent dbus from
+  // starting a new one.  Dbus confuses the test harness when it creates a new
+  // process (see bug 693343)
+  if (PR_GetEnv(sAccEnv) || !PR_GetEnv("DBUS_SESSION_BUS_ADDRESS"))
+    return;
+
+  DBusConnection* bus = dbus_bus_get(DBUS_BUS_SESSION, nsnull);
+  if (!bus)
+    return;
+
+  dbus_connection_set_exit_on_disconnect(bus, FALSE);
+
+  DBusMessage *message;
+  message = dbus_message_new_method_call("org.a11y.Bus", "/org/a11y/bus",
+                                         "org.freedesktop.DBus.Properties",
+                                         "Get");
+  if (!message)
+    goto dbus_done;
+
+  static const char* iface = "org.a11y.Status";
+  static const char* member = "IsEnabled";
+  dbus_message_append_args(message, DBUS_TYPE_STRING, &iface,
+                           DBUS_TYPE_STRING, &member, DBUS_TYPE_INVALID);
+  dbus_connection_send_with_reply(bus, message, &sPendingCall, 1000);
+  dbus_message_unref(message);
+
+dbus_done:
+  dbus_connection_unref(bus);
+#endif
+}
+
+bool
+ShouldA11yBeEnabled()
+{
+  static bool sChecked = false, sShouldEnable = false;
+  if (sChecked)
+    return sShouldEnable;
+
+  sChecked = true;
+
+  // check if accessibility enabled/disabled by environment variable
+  const char* envValue = PR_GetEnv(sAccEnv);
+  if (envValue)
+    return sShouldEnable = !!atoi(envValue);
+
+#ifdef MOZ_ENABLE_DBUS
+  PreInit();
+  bool dbusSuccess = false;
+  DBusMessage *reply = nsnull;
+  if (!sPendingCall)
+    goto dbus_done;
+
+  dbus_pending_call_block(sPendingCall);
+  reply = dbus_pending_call_steal_reply(sPendingCall);
+  dbus_pending_call_unref(sPendingCall);
+  sPendingCall = nsnull;
+  if (!reply ||
+      dbus_message_get_type(reply) != DBUS_MESSAGE_TYPE_METHOD_RETURN ||
+      strcmp(dbus_message_get_signature (reply), DBUS_TYPE_VARIANT_AS_STRING))
+    goto dbus_done;
+
+  DBusMessageIter iter, iter_variant, iter_struct;
+  dbus_bool_t dResult;
+  dbus_message_iter_init(reply, &iter);
+  dbus_message_iter_recurse (&iter, &iter_variant);
+  switch (dbus_message_iter_get_arg_type(&iter_variant)) {
+    case DBUS_TYPE_STRUCT:
+      // at-spi2-core 2.2.0-2.2.1 had a bug where it returned a struct
+      dbus_message_iter_recurse(&iter_variant, &iter_struct);
+      if (dbus_message_iter_get_arg_type(&iter_struct) == DBUS_TYPE_BOOLEAN) {
+        dbus_message_iter_get_basic(&iter_struct, &dResult);
+        sShouldEnable = dResult;
+        dbusSuccess = true;
+      }
+
+      break;
+    case DBUS_TYPE_BOOLEAN:
+      dbus_message_iter_get_basic(&iter_variant, &dResult);
+      sShouldEnable = dResult;
+      dbusSuccess = true;
+      break;
+    default:
+      break;
+  }
+
+dbus_done:
+  if (reply)
+    dbus_message_unref(reply);
+
+  if (dbusSuccess)
+    return sShouldEnable;
+#endif
+
+  //check gconf-2 setting
+static const char sGconfAccessibilityKey[] =
+    "/desktop/gnome/interface/accessibility";
+  nsresult rv = NS_OK;
+  nsCOMPtr<nsIGConfService> gconf =
+    do_GetService(NS_GCONFSERVICE_CONTRACTID, &rv);
+  if (NS_SUCCEEDED(rv) && gconf)
+    gconf->GetBool(NS_LITERAL_CSTRING(sGconfAccessibilityKey), &sShouldEnable);
+
+  return sShouldEnable;
+}
+} // namespace a11y
+} // namespace mozilla
+
--- a/accessible/src/atk/nsMaiInterfaceImage.cpp
+++ b/accessible/src/atk/nsMaiInterfaceImage.cpp
@@ -32,18 +32,20 @@
  * use your version of this file under the terms of the MPL, indicate your
  * decision by deleting the provisions above and replace them with the notice
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
+#include "nsMaiInterfaceImage.h"
+
 #include "nsAccessibleWrap.h"
-#include "nsMaiInterfaceImage.h"
+#include "nsHTMLImageAccessible.h"
 
 extern "C" const gchar* getDescriptionCB(AtkObject* aAtkObj);
 
 void
 imageInterfaceInitCB(AtkImageIface *aIface)
 {
     g_return_if_fail(aIface != NULL);
 
@@ -53,46 +55,34 @@ imageInterfaceInitCB(AtkImageIface *aIfa
 
 }
 
 void
 getImagePositionCB(AtkImage *aImage, gint *aAccX, gint *aAccY,
                    AtkCoordType aCoordType)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aImage));
-    if (!accWrap) 
+    if (!accWrap || !accWrap->IsImageAccessible())
       return;
 
-    nsCOMPtr<nsIAccessibleImage> image;
-    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleImage),
-                            getter_AddRefs(image));
-    if (!image)
-      return;
-
+    nsHTMLImageAccessible* image = accWrap->AsImage();
     PRUint32 geckoCoordType = (aCoordType == ATK_XY_WINDOW) ?
       nsIAccessibleCoordinateType::COORDTYPE_WINDOW_RELATIVE :
       nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE;
-
     // Returned in screen coordinates
     image->GetImagePosition(geckoCoordType, aAccX, aAccY);
 }
 
 const gchar *
 getImageDescriptionCB(AtkImage *aImage)
 {
    return getDescriptionCB(ATK_OBJECT(aImage));
 }
 
 void
 getImageSizeCB(AtkImage *aImage, gint *aAccWidth, gint *aAccHeight)
 {
     nsAccessibleWrap *accWrap = GetAccessibleWrap(ATK_OBJECT(aImage));
-    if (!accWrap) 
+    if (!accWrap || !accWrap->IsImageAccessible())
       return;
 
-    nsCOMPtr<nsIAccessibleImage> image;
-    accWrap->QueryInterface(NS_GET_IID(nsIAccessibleImage),
-                            getter_AddRefs(image));
-    if (!image)
-      return;
-
-    image->GetImageSize(aAccWidth, aAccHeight);
+    accWrap->AsImage()->GetImageSize(aAccWidth, aAccHeight);
 }
--- a/accessible/src/base/nsAccessibilityService.h
+++ b/accessible/src/base/nsAccessibilityService.h
@@ -51,16 +51,31 @@
 namespace mozilla {
 namespace a11y {
 
 /**
  * Return focus manager.
  */
 FocusManager* FocusMgr();
 
+#ifdef MOZ_ACCESSIBILITY_ATK
+/**
+ * Perform initialization that should be done as soon as possible, in order
+ * to minimize startup time.
+ * XXX: this function and the next defined in nsApplicationAccessibleWrap.cpp
+ */
+void PreInit();
+
+/**
+ * Is platform accessibility enabled.
+ * Only used on linux with atk for now.
+ */
+bool ShouldA11yBeEnabled();
+#endif
+
 } // namespace a11y
 } // namespace mozilla
 
 class nsAccessibilityService : public nsAccDocManager,
                                public mozilla::a11y::FocusManager,
                                public nsIAccessibilityService,
                                public nsIObserver
 {
--- a/accessible/src/base/nsAccessible.cpp
+++ b/accessible/src/base/nsAccessible.cpp
@@ -585,85 +585,73 @@ nsresult nsAccessible::GetTranslatedStri
   if (!gStringBundle || 
     NS_FAILED(gStringBundle->GetStringFromName(PromiseFlatString(aKey).get(), getter_Copies(xsValue)))) 
     return NS_ERROR_FAILURE;
 
   aStringOut.Assign(xsValue);
   return NS_OK;
 }
 
-bool
-nsAccessible::IsVisible(bool* aIsOffscreen)
+PRUint64
+nsAccessible::VisibilityState()
 {
+  PRUint64 vstates = states::INVISIBLE | states::OFFSCREEN;
+
+  // We need to check the parent chain for visibility.
+  nsAccessible* accessible = this;
+  do {
+    // We don't want background tab page content to be aggressively invisible.
+    // Otherwise this foils screen reader virtual buffer caches.
+	  PRUint32 role = accessible->Role();
+    if (role == nsIAccessibleRole::ROLE_PROPERTYPAGE ||
+        role == nsIAccessibleRole::ROLE_PANE) {
+      break;
+    }
+
+    nsIFrame* frame = accessible->GetFrame();
+    if (!frame)
+      return vstates;
+
+    const nsIView* view = frame->GetView();
+    if (view && view->GetVisibility() == nsViewVisibility_kHide)
+      return vstates;
+    
+  } while (accessible = accessible->Parent());
+
+  nsIFrame* frame = GetFrame();
+  const nsCOMPtr<nsIPresShell> shell(GetPresShell());
+
   // We need to know if at least a kMinPixels around the object is visible,
-  // otherwise it will be marked states::OFFSCREEN. The states::INVISIBLE flag
-  // is for elements which are programmatically hidden.
-
-  *aIsOffscreen = true;
-  if (IsDefunct())
-    return false;
-
+  // otherwise it will be marked states::OFFSCREEN.
   const PRUint16 kMinPixels  = 12;
-   // Set up the variables we need, return false if we can't get at them all
-  nsCOMPtr<nsIPresShell> shell(GetPresShell());
-  if (!shell) 
-    return false;
-
-  nsIFrame *frame = GetFrame();
-  if (!frame) {
-    return false;
-  }
-
-  // If visibility:hidden or visibility:collapsed then mark with STATE_INVISIBLE
-  if (!frame->GetStyleVisibility()->IsVisible())
-  {
-      return false;
-  }
-
-  // We don't use the more accurate GetBoundsRect, because that is more expensive
-  // and the STATE_OFFSCREEN flag that this is used for only needs to be a rough
-  // indicator
-  nsSize frameSize = frame->GetSize();
-  nsRectVisibility rectVisibility =
+  const nsSize frameSize = frame->GetSize();
+  const nsRectVisibility rectVisibility =
     shell->GetRectVisibility(frame, nsRect(nsPoint(0,0), frameSize),
                              nsPresContext::CSSPixelsToAppUnits(kMinPixels));
 
-  if (frame->GetRect().IsEmpty()) {
-    bool isEmpty = true;
-
-    nsIAtom *frameType = frame->GetType();
-    if (frameType == nsGkAtoms::textFrame) {
-      // Zero area rects can occur in the first frame of a multi-frame text flow,
-      // in which case the rendered text is not empty and the frame should not be marked invisible
-      nsAutoString renderedText;
-      frame->GetRenderedText (&renderedText, nsnull, nsnull, 0, 1);
-      isEmpty = renderedText.IsEmpty();
-    }
-    else if (frameType == nsGkAtoms::inlineFrame) {
-      // Yuck. Unfortunately inline frames can contain larger frames inside of them,
-      // so we can't really believe this is a zero area rect without checking more deeply.
-      // GetBounds() will do that for us.
-      PRInt32 x, y, width, height;
-      GetBounds(&x, &y, &width, &height);
-      isEmpty = width == 0 || height == 0;
-    }
-
-    if (isEmpty && !(frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW)) {
-      // Consider zero area objects hidden unless they are absolutely positioned
-      // or floating and may have descendants that have a non-zero size
-      return false;
-    }
+  if (rectVisibility == nsRectVisibility_kVisible)
+    vstates &= ~states::OFFSCREEN;
+
+  // Zero area rects can occur in the first frame of a multi-frame text flow,
+  // in which case the rendered text is not empty and the frame should not be
+  // marked invisible.
+  // XXX Can we just remove this check? Why do we need to mark empty
+  // text invisible?
+  if (frame->GetType() == nsGkAtoms::textFrame &&
+      !(frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
+      frame->GetRect().IsEmpty()) {
+    nsAutoString renderedText;
+    frame->GetRenderedText(&renderedText, nsnull, nsnull, 0, 1);
+    if (renderedText.IsEmpty())
+      return vstates;
+
   }
 
-  // The frame intersects the viewport, but we need to check the parent view chain :(
-  bool isVisible = frame->IsVisibleConsideringAncestors(nsIFrame::VISIBILITY_CROSS_CHROME_CONTENT_BOUNDARY);
-  if (isVisible && rectVisibility == nsRectVisibility_kVisible) {
-    *aIsOffscreen = false;
-  }
-  return isVisible;
+  // Assume we are visible enough.
+  return vstates &= ~states::INVISIBLE;
 }
 
 PRUint64
 nsAccessible::NativeState()
 {
   PRUint64 state = 0;
 
   nsDocAccessible* document = GetDocAccessible();
@@ -696,25 +684,18 @@ nsAccessible::NativeState()
     nsIFrame* frame = GetFrame();
     if (frame && frame->IsFocusable())
       state |= states::FOCUSABLE;
 
     if (FocusMgr()->IsFocused(this))
       state |= states::FOCUSED;
   }
 
-  // Check if states::INVISIBLE and
-  // states::OFFSCREEN flags should be turned on for this object.
-  bool isOffscreen;
-  if (!IsVisible(&isOffscreen)) {
-    state |= states::INVISIBLE;
-  }
-  if (isOffscreen) {
-    state |= states::OFFSCREEN;
-  }
+  // Gather states::INVISIBLE and states::OFFSCREEN flags for this object.
+  state |= VisibilityState();
 
   nsIFrame *frame = GetFrame();
   if (frame && (frame->GetStateBits() & NS_FRAME_OUT_OF_FLOW))
     state |= states::FLOATING;
 
   // Check if a XUL element has the popup attribute (an attached popup menu).
   if (mContent->IsXUL())
     if (mContent->HasAttr(kNameSpaceID_None, nsGkAtoms::popup))
--- a/accessible/src/base/nsAccessible.h
+++ b/accessible/src/base/nsAccessible.h
@@ -55,16 +55,17 @@
 #include "nsRefPtrHashtable.h"
 
 class AccEvent;
 class AccGroupInfo;
 class EmbeddedObjCollector;
 class KeyBinding;
 class nsAccessible;
 class nsHyperTextAccessible;
+class nsHTMLImageAccessible;
 class nsHTMLLIAccessible;
 struct nsRoleMapEntry;
 class Relation;
 class nsTextAccessible;
 
 struct nsRect;
 class nsIContent;
 class nsIFrame;
@@ -423,16 +424,19 @@ public:
 
   inline bool IsHyperText() const { return mFlags & eHyperTextAccessible; }
   nsHyperTextAccessible* AsHyperText();
 
   inline bool IsHTMLFileInput() const { return mFlags & eHTMLFileInputAccessible; }
 
   inline bool IsHTMLListItem() const { return mFlags & eHTMLListItemAccessible; }
   nsHTMLLIAccessible* AsHTMLListItem();
+  
+  inline bool IsImageAccessible() const { return mFlags & eImageAccessible; }
+  nsHTMLImageAccessible* AsImage();
 
   inline bool IsListControl() const { return mFlags & eListControlAccessible; }
 
   inline bool IsMenuButton() const { return mFlags & eMenuButtonAccessible; }
 
   inline bool IsMenuPopup() const { return mFlags & eMenuPopupAccessible; }
 
   inline bool IsRoot() const { return mFlags & eRootAccessible; }
@@ -649,34 +653,36 @@ protected:
     eApplicationAccessible = 1 << 2,
     eAutoCompleteAccessible = 1 << 3,
     eAutoCompletePopupAccessible = 1 << 4,
     eComboboxAccessible = 1 << 5,
     eDocAccessible = 1 << 6,
     eHyperTextAccessible = 1 << 7,
     eHTMLFileInputAccessible = 1 << 8,
     eHTMLListItemAccessible = 1 << 9,
-    eListControlAccessible = 1 << 10,
-    eMenuButtonAccessible = 1 << 11,
-    eMenuPopupAccessible = 1 << 12,
-    eRootAccessible = 1 << 13,
-    eTextLeafAccessible = 1 << 14
+    eImageAccessible = 1 << 10,
+    eListControlAccessible = 1 << 11,
+    eMenuButtonAccessible = 1 << 12,
+    eMenuPopupAccessible = 1 << 13,
+    eRootAccessible = 1 << 14,
+    eTextLeafAccessible = 1 << 15
   };
 
   //////////////////////////////////////////////////////////////////////////////
   // Miscellaneous helpers
 
   /**
    * Return ARIA role (helper method).
    */
   PRUint32 ARIARoleInternal();
 
   virtual nsIFrame* GetBoundsFrame();
   virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
-  bool IsVisible(bool *aIsOffscreen); 
+
+  PRUint64 VisibilityState(); 
 
   //////////////////////////////////////////////////////////////////////////////
   // Name helpers
 
   /**
    * Compute the name of HTML node.
    */
   nsresult GetHTMLName(nsAString& aName);
--- a/accessible/src/base/nsCoreUtils.cpp
+++ b/accessible/src/base/nsCoreUtils.cpp
@@ -41,40 +41,37 @@
 #include "nsIAccessibleTypes.h"
 
 #include "nsAccessNode.h"
 
 #include "nsIDocument.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMHTMLDocument.h"
 #include "nsIDOMHTMLElement.h"
-#include "nsIDOMRange.h"
+#include "nsRange.h"
 #include "nsIDOMWindow.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDocShell.h"
 #include "nsIContentViewer.h"
 #include "nsEventListenerManager.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
 #include "nsIScrollableFrame.h"
 #include "nsEventStateManager.h"
 #include "nsISelectionPrivate.h"
 #include "nsISelectionController.h"
 #include "nsPIDOMWindow.h"
 #include "nsGUIEvent.h"
 #include "nsIView.h"
 #include "nsLayoutUtils.h"
 
-#include "nsContentCID.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "mozilla/dom/Element.h"
 
-static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsCoreUtils
 ////////////////////////////////////////////////////////////////////////////////
 
 bool
 nsCoreUtils::HasClickListener(nsIContent *aContent)
 {
   NS_ENSURE_TRUE(aContent, false);
@@ -312,19 +309,17 @@ nsCoreUtils::ScrollSubstringTo(nsIFrame 
                                nsIDOMNode *aEndNode, PRInt32 aEndIndex,
                                PRInt16 aVPercent, PRInt16 aHPercent)
 {
   if (!aFrame || !aStartNode || !aEndNode)
     return NS_ERROR_FAILURE;
 
   nsPresContext *presContext = aFrame->PresContext();
 
-  nsCOMPtr<nsIDOMRange> scrollToRange = do_CreateInstance(kRangeCID);
-  NS_ENSURE_TRUE(scrollToRange, NS_ERROR_FAILURE);
-
+  nsRefPtr<nsIDOMRange> scrollToRange = new nsRange();
   nsCOMPtr<nsISelectionController> selCon;
   aFrame->GetSelectionController(presContext, getter_AddRefs(selCon));
   NS_ENSURE_TRUE(selCon, NS_ERROR_FAILURE);
 
   scrollToRange->SetStart(aStartNode, aStartIndex);
   scrollToRange->SetEnd(aEndNode, aEndIndex);
 
   nsCOMPtr<nsISelection> selection;
--- a/accessible/src/base/nsDocAccessible.cpp
+++ b/accessible/src/base/nsDocAccessible.cpp
@@ -1273,23 +1273,28 @@ nsDocAccessible::HandleAccEvent(AccEvent
 
 ////////////////////////////////////////////////////////////////////////////////
 // Public members
 
 void*
 nsDocAccessible::GetNativeWindow() const
 {
   nsCOMPtr<nsIPresShell> shell(do_QueryReferent(mWeakShell));
+  if (!shell)
+    return nsnull;
+
   nsIViewManager* vm = shell->GetViewManager();
-  if (vm) {
-    nsCOMPtr<nsIWidget> widget;
-    vm->GetRootWidget(getter_AddRefs(widget));
-    if (widget)
-      return widget->GetNativeData(NS_NATIVE_WINDOW);
-  }
+  if (!vm)
+    return nsnull;
+
+  nsCOMPtr<nsIWidget> widget;
+  vm->GetRootWidget(getter_AddRefs(widget));
+  if (widget)
+    return widget->GetNativeData(NS_NATIVE_WINDOW);
+
   return nsnull;
 }
 
 nsAccessible*
 nsDocAccessible::GetAccessibleByUniqueIDInSubtree(void* aUniqueID)
 {
   nsAccessible* child = GetAccessibleByUniqueID(aUniqueID);
   if (child)
--- a/accessible/src/html/nsHTMLImageAccessible.h
+++ b/accessible/src/html/nsHTMLImageAccessible.h
@@ -87,10 +87,19 @@ private:
    *
    * @param aIndex  The 0-based index to be tested.
    *
    * @returns  true if index is valid for longdesc action.
    */
   bool IsValidLongDescIndex(PRUint8 aIndex);
 };
 
+////////////////////////////////////////////////////////////////////////////////
+// nsAccessible downcasting method
+inline nsHTMLImageAccessible*
+nsAccessible::AsImage()
+{
+  return IsImageAccessible() ?
+    static_cast<nsHTMLImageAccessible*>(this) : nsnull;
+}
+
 #endif
 
--- a/accessible/src/html/nsHyperTextAccessible.cpp
+++ b/accessible/src/html/nsHyperTextAccessible.cpp
@@ -40,40 +40,36 @@
 #include "nsHyperTextAccessible.h"
 
 #include "States.h"
 #include "nsAccessibilityService.h"
 #include "nsAccUtils.h"
 #include "nsTextAttrs.h"
 
 #include "nsIClipboard.h"
-#include "nsContentCID.h"
 #include "nsFocusManager.h"
 #include "nsIDOMCharacterData.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMRange.h"
-#include "nsIDOMNSRange.h"
 #include "nsIDOMXULDocument.h"
 #include "nsIEditingSession.h"
 #include "nsIEditor.h"
 #include "nsIFrame.h"
 #include "nsFrameSelection.h"
 #include "nsILineIterator.h"
 #include "nsIInterfaceRequestorUtils.h"
 #include "nsIPlaintextEditor.h"
 #include "nsIScrollableFrame.h"
 #include "nsISelectionPrivate.h"
 #include "nsIServiceManager.h"
 #include "nsTextFragment.h"
 #include "gfxSkipChars.h"
 
 using namespace mozilla::a11y;
 
-static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
-
 ////////////////////////////////////////////////////////////////////////////////
 // nsHyperTextAccessible
 ////////////////////////////////////////////////////////////////////////////////
 
 nsHyperTextAccessible::
   nsHyperTextAccessible(nsIContent *aNode, nsIWeakReference *aShell) :
   nsAccessibleWrap(aNode, aShell)
 {
@@ -1734,17 +1730,17 @@ already_AddRefed<nsFrameSelection>
 nsHyperTextAccessible::FrameSelection()
 {
   nsIFrame* frame = GetFrame();
   return frame ? frame->GetFrameSelection() : nsnull;
 }
 
 void
 nsHyperTextAccessible::GetSelectionDOMRanges(PRInt16 aType,
-                                             nsCOMArray<nsIDOMRange>* aRanges)
+                                             nsTArray<nsRange*>* aRanges)
 {
   nsRefPtr<nsFrameSelection> frameSelection = FrameSelection();
   if (!frameSelection)
     return;
 
   nsISelection* domSel = frameSelection->GetSelection(aType);
   if (!domSel)
     return;
@@ -1758,72 +1754,70 @@ nsHyperTextAccessible::GetSelectionDOMRa
     editor->GetRootElement(getter_AddRefs(editorRoot));
     startNode = do_QueryInterface(editorRoot);
   }
 
   if (!startNode)
     return;
 
   PRUint32 childCount = startNode->GetChildCount();
-  nsCOMPtr<nsIDOMNode> startDOMNode(do_QueryInterface(startNode));
   nsCOMPtr<nsISelectionPrivate> privSel(do_QueryInterface(domSel));
   nsresult rv = privSel->
-    GetRangesForIntervalCOMArray(startDOMNode, 0, startDOMNode, childCount,
-                                 true, aRanges);
+    GetRangesForIntervalArray(startNode, 0, startNode, childCount, true, aRanges);
   NS_ENSURE_SUCCESS(rv,);
 
   // Remove collapsed ranges
-  PRInt32 numRanges = aRanges->Count();
-  for (PRInt32 count = 0; count < numRanges; count ++) {
+  PRUint32 numRanges = aRanges->Length();
+  for (PRUint32 count = 0; count < numRanges; count ++) {
     bool isCollapsed = false;
     (*aRanges)[count]->GetCollapsed(&isCollapsed);
     if (isCollapsed) {
-      aRanges->RemoveObjectAt(count);
+      aRanges->RemoveElementAt(count);
       --numRanges;
       --count;
     }
   }
 }
 
 /*
  * Gets the number of selected regions.
  */
 NS_IMETHODIMP
 nsHyperTextAccessible::GetSelectionCount(PRInt32* aSelectionCount)
 {
   NS_ENSURE_ARG_POINTER(aSelectionCount);
   *aSelectionCount = 0;
 
-  nsCOMArray<nsIDOMRange> ranges;
+  nsTArray<nsRange*> ranges;
   GetSelectionDOMRanges(nsISelectionController::SELECTION_NORMAL, &ranges);
-  *aSelectionCount = ranges.Count();
+  *aSelectionCount = PRInt32(ranges.Length());
 
   return NS_OK;
 }
 
 /*
  * Gets the start and end offset of the specified selection.
  */
 NS_IMETHODIMP
 nsHyperTextAccessible::GetSelectionBounds(PRInt32 aSelectionNum,
                                           PRInt32* aStartOffset,
                                           PRInt32* aEndOffset)
 {
   NS_ENSURE_ARG_POINTER(aStartOffset);
   NS_ENSURE_ARG_POINTER(aEndOffset);
   *aStartOffset = *aEndOffset = 0;
 
-  nsCOMArray<nsIDOMRange> ranges;
+  nsTArray<nsRange*> ranges;
   GetSelectionDOMRanges(nsISelectionController::SELECTION_NORMAL, &ranges);
 
-  PRInt32 rangeCount = ranges.Count();
+  PRUint32 rangeCount = ranges.Length();
   if (aSelectionNum < 0 || aSelectionNum >= rangeCount)
     return NS_ERROR_INVALID_ARG;
 
-  nsCOMPtr<nsIDOMRange> range = ranges[aSelectionNum];
+  nsRange* range = ranges[aSelectionNum];
 
   // Get start point
   nsCOMPtr<nsIDOMNode> startDOMNode;
   range->GetStartContainer(getter_AddRefs(startDOMNode));
   nsCOMPtr<nsINode> startNode(do_QueryInterface(startDOMNode));
   PRInt32 startOffset = 0;
   range->GetStartOffset(&startOffset);
 
@@ -1875,18 +1869,17 @@ nsHyperTextAccessible::SetSelectionBound
 
   // Caret is a collapsed selection
   bool isOnlyCaret = (aStartOffset == aEndOffset);
 
   PRInt32 rangeCount = 0;
   domSel->GetRangeCount(&rangeCount);
   nsCOMPtr<nsIDOMRange> range;
   if (aSelectionNum == rangeCount) { // Add a range
-    range = do_CreateInstance(kRangeCID);
-    NS_ENSURE_TRUE(range, NS_ERROR_OUT_OF_MEMORY);
+    range = new nsRange();
   }
   else if (aSelectionNum < 0 || aSelectionNum > rangeCount) {
     return NS_ERROR_INVALID_ARG;
   }
   else {
     domSel->GetRangeAt(aSelectionNum, getter_AddRefs(range));
     NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
   }
@@ -2300,20 +2293,20 @@ nsHyperTextAccessible::GetDOMPointByFram
   }
 
   NS_IF_ADDREF(*aNode = node);
   return NS_OK;
 }
 
 // nsHyperTextAccessible
 nsresult
-nsHyperTextAccessible::DOMRangeBoundToHypertextOffset(nsIDOMRange *aRange,
-                                                      bool aIsStartBound,
-                                                      bool aIsStartHTOffset,
-                                                      PRInt32 *aHTOffset)
+nsHyperTextAccessible::RangeBoundToHypertextOffset(nsRange *aRange,
+                                                   bool aIsStartBound,
+                                                   bool aIsStartHTOffset,
+                                                   PRInt32 *aHTOffset)
 {
   nsCOMPtr<nsIDOMNode> DOMNode;
   PRInt32 nodeOffset = 0;
 
   nsresult rv;
   if (aIsStartBound) {
     rv = aRange->GetStartContainer(getter_AddRefs(DOMNode));
     NS_ENSURE_SUCCESS(rv, rv);
@@ -2341,30 +2334,28 @@ nsHyperTextAccessible::DOMRangeBoundToHy
 // nsHyperTextAccessible
 nsresult
 nsHyperTextAccessible::GetSpellTextAttribute(nsIDOMNode *aNode,
                                              PRInt32 aNodeOffset,
                                              PRInt32 *aHTStartOffset,
                                              PRInt32 *aHTEndOffset,
                                              nsIPersistentProperties *aAttributes)
 {
-  nsCOMArray<nsIDOMRange> ranges;
+  nsTArray<nsRange*> ranges;
   GetSelectionDOMRanges(nsISelectionController::SELECTION_SPELLCHECK, &ranges);
 
-  PRInt32 rangeCount = ranges.Count();
+  PRUint32 rangeCount = ranges.Length();
   if (!rangeCount)
     return NS_OK;
 
-  for (PRInt32 index = 0; index < rangeCount; index++) {
-    nsCOMPtr<nsIDOMRange> range = ranges[index];
-    nsCOMPtr<nsIDOMNSRange> nsrange(do_QueryInterface(range));
-    NS_ENSURE_STATE(nsrange);
+  for (PRUint32 index = 0; index < rangeCount; index++) {
+    nsRange* range = ranges[index];
 
     PRInt16 result;
-    nsresult rv = nsrange->ComparePoint(aNode, aNodeOffset, &result);
+    nsresult rv = range->ComparePoint(aNode, aNodeOffset, &result);
     NS_ENSURE_SUCCESS(rv, rv);
     // ComparePoint checks boundary points, but we need to check that
     // text at aNodeOffset is inside the range.
     // See also bug 460690.
     if (result == 0) {
       nsCOMPtr<nsIDOMNode> end;
       rv = range->GetEndContainer(getter_AddRefs(end));
       NS_ENSURE_SUCCESS(rv, rv);
@@ -2373,41 +2364,41 @@ nsHyperTextAccessible::GetSpellTextAttri
       NS_ENSURE_SUCCESS(rv, rv);
       if (aNode == end && aNodeOffset == endOffset) {
         result = 1;
       }
     }
 
     if (result == 1) { // range is before point
       PRInt32 startHTOffset = 0;
-      nsresult rv = DOMRangeBoundToHypertextOffset(range, false, true,
-                                                   &startHTOffset);
+      nsresult rv = RangeBoundToHypertextOffset(range, false, true,
+                                                &startHTOffset);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (startHTOffset > *aHTStartOffset)
         *aHTStartOffset = startHTOffset;
 
     } else if (result == -1) { // range is after point
       PRInt32 endHTOffset = 0;
-      nsresult rv = DOMRangeBoundToHypertextOffset(range, true, false,
-                                                   &endHTOffset);
+      nsresult rv = RangeBoundToHypertextOffset(range, true, false,
+                                                &endHTOffset);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (endHTOffset < *aHTEndOffset)
         *aHTEndOffset = endHTOffset;
 
     } else { // point is in range
       PRInt32 startHTOffset = 0;
-      nsresult rv = DOMRangeBoundToHypertextOffset(range, true, true,
-                                                   &startHTOffset);
+      nsresult rv = RangeBoundToHypertextOffset(range, true, true,
+                                                &startHTOffset);
       NS_ENSURE_SUCCESS(rv, rv);
 
       PRInt32 endHTOffset = 0;
-      rv = DOMRangeBoundToHypertextOffset(range, false, false,
-                                          &endHTOffset);
+      rv = RangeBoundToHypertextOffset(range, false, false,
+                                       &endHTOffset);
       NS_ENSURE_SUCCESS(rv, rv);
 
       if (startHTOffset > *aHTStartOffset)
         *aHTStartOffset = startHTOffset;
       if (endHTOffset < *aHTEndOffset)
         *aHTEndOffset = endHTOffset;
 
       if (aAttributes) {
--- a/accessible/src/html/nsHyperTextAccessible.h
+++ b/accessible/src/html/nsHyperTextAccessible.h
@@ -355,17 +355,17 @@ protected:
   /**
    * Return frame selection object for the accessible.
    */
   virtual already_AddRefed<nsFrameSelection> FrameSelection();
 
   /**
    * Return selection ranges within the accessible subtree.
    */
-  void GetSelectionDOMRanges(PRInt16 aType, nsCOMArray<nsIDOMRange>* aRanges);
+  void GetSelectionDOMRanges(PRInt16 aType, nsTArray<nsRange*>* aRanges);
 
   nsresult SetSelectionRange(PRInt32 aStartPos, PRInt32 aEndPos);
 
   /**
    * Provide the line number for the caret, relative to the
    * current DOM node.
    * @return 1-based index for the line number with the caret
    */
@@ -385,20 +385,20 @@ protected:
    *
    * @param aRange          [in] the given range
    * @param aIsStartBound   [in] specifies whether the required range bound is
    *                        start bound
    * @param aIsStartOffset  [in] the offset type, used when the range bound is
    *                        outside of hyper text
    * @param aHTOffset       [out] the result offset
    */
-  nsresult DOMRangeBoundToHypertextOffset(nsIDOMRange *aRange,
-                                          bool aIsStartBound,
-                                          bool aIsStartOffset,
-                                          PRInt32 *aHTOffset);
+  nsresult RangeBoundToHypertextOffset(nsRange *aRange,
+                                       bool aIsStartBound,
+                                       bool aIsStartOffset,
+                                       PRInt32 *aHTOffset);
 
   /**
    * Set 'misspelled' text attribute and return range offsets where the
    * attibute is stretched. If the text is not misspelled at the given offset
    * then we expose only range offsets where text is not misspelled. The method
    * is used by GetTextAttributes() method.
    *
    * @param aIncludeDefAttrs  [in] points whether text attributes having default
--- a/accessible/src/msaa/nsAccessibleWrap.cpp
+++ b/accessible/src/msaa/nsAccessibleWrap.cpp
@@ -86,32 +86,32 @@ EXTERN_C GUID CDECL CLSID_Accessible =
 { 0x61044601, 0xa811, 0x4e2b, { 0xbb, 0xba, 0x17, 0xbf, 0xab, 0xd3, 0x29, 0xd7 } };
 
 static const PRInt32 kIEnumVariantDisconnected = -1;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessibleWrap
 ////////////////////////////////////////////////////////////////////////////////
 
+ITypeInfo* nsAccessibleWrap::gTypeInfo = NULL;
+
 //-----------------------------------------------------
 // construction
 //-----------------------------------------------------
 nsAccessibleWrap::
   nsAccessibleWrap(nsIContent *aContent, nsIWeakReference *aShell) :
-  nsAccessible(aContent, aShell), mEnumVARIANTPosition(0), mTypeInfo(NULL)
+  nsAccessible(aContent, aShell), mEnumVARIANTPosition(0)
 {
 }
 
 //-----------------------------------------------------
 // destruction
 //-----------------------------------------------------
 nsAccessibleWrap::~nsAccessibleWrap()
 {
-  if (mTypeInfo)
-    mTypeInfo->Release();
 }
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsAccessibleWrap, nsAccessible);
 
 //-----------------------------------------------------
 // IUnknown interface methods - see iunknown.h for documentation
 //-----------------------------------------------------
 
@@ -1830,24 +1830,24 @@ void nsAccessibleWrap::UpdateSystemCaret
     ::SetCaretPos(caretRect.x - windowRect.left, caretRect.y - windowRect.top);
     ::DeleteObject(caretBitMap);
   }
 }
 
 ITypeInfo*
 nsAccessibleWrap::GetTI(LCID lcid)
 {
-  if (mTypeInfo)
-    return mTypeInfo;
+  if (gTypeInfo)
+    return gTypeInfo;
 
   ITypeLib *typeLib = NULL;
   HRESULT hr = LoadRegTypeLib(LIBID_Accessibility, 1, 0, lcid, &typeLib);
   if (FAILED(hr))
     return NULL;
 
-  hr = typeLib->GetTypeInfoOfGuid(IID_IAccessible, &mTypeInfo);
+  hr = typeLib->GetTypeInfoOfGuid(IID_IAccessible, &gTypeInfo);
   typeLib->Release();
 
   if (FAILED(hr))
     return NULL;
 
-  return mTypeInfo;
+  return gTypeInfo;
 }
--- a/accessible/src/msaa/nsAccessibleWrap.h
+++ b/accessible/src/msaa/nsAccessibleWrap.h
@@ -351,19 +351,19 @@ protected:
   // mEnumVARIANTPosition not the current accessible's position, but a "cursor" of 
   // where we are in the current list of children, with respect to
   // nsIEnumVariant::Reset(), Skip() and Next().
   PRInt32 mEnumVARIANTPosition;
 
   /**
    * Creates ITypeInfo for LIBID_Accessibility if it's needed and returns it.
    */
-  ITypeInfo *GetTI(LCID lcid);
+  static ITypeInfo* GetTI(LCID lcid);
 
-  ITypeInfo *mTypeInfo;
+  static ITypeInfo* gTypeInfo;
 
 
   enum navRelations {
     NAVRELATION_CONTROLLED_BY = 0x1000,
     NAVRELATION_CONTROLLER_FOR = 0x1001,
     NAVRELATION_LABEL_FOR = 0x1002,
     NAVRELATION_LABELLED_BY = 0x1003,
     NAVRELATION_MEMBER_OF = 0x1004,
--- a/accessible/tests/mochitest/events/test_caretmove.xul
+++ b/accessible/tests/mochitest/events/test_caretmove.xul
@@ -23,16 +23,23 @@
 
     //gA11yEventDumpID = "eventdump"; // debug stuff
     //gA11yEventDumpToConsole = true;
 
     var gQueue = null;
 
     function doTests()
     {
+
+      if (MAC) {
+        todo(false, "Make these tests pass on OSX (bug 650294)");
+        SimpleTest.finish();
+        return;
+      }
+
       gQueue = new eventQueue(EVENT_TEXT_CARET_MOVED);
 
       var id = "textbox";
       gQueue.push(new synthFocus(id, new caretMoveChecker(5, id)));
       gQueue.push(new synthSelectAll(id, new caretMoveChecker(5, id)));
       gQueue.push(new synthHomeKey(id, new caretMoveChecker(0, id)));
       gQueue.push(new synthRightKey(id, new caretMoveChecker(1, id)));
 
--- a/accessible/tests/mochitest/states/Makefile.in
+++ b/accessible/tests/mochitest/states/Makefile.in
@@ -58,16 +58,17 @@ include $(topsrcdir)/config/rules.mk
 		test_inputs.html \
 		test_inputs.xul \
 		test_link.html \
 		test_popup.xul \
 		test_selects.html \
 		test_stale.html \
 		test_textbox.xul \
 		test_tree.xul \
+		test_visibility.html \
 		z_frames.html \
 		z_frames_article.html \
 		z_frames_checkbox.html \
 		z_frames_textbox.html \
 		z_frames_update.html \
 		$(NULL)
 
 libs:: $(_TEST_FILES)
new file mode 100644
--- /dev/null
+++ b/accessible/tests/mochitest/states/test_visibility.html
@@ -0,0 +1,71 @@
+<html>
+<head>
+  <title>visibility state testing</title>
+
+  <link rel="stylesheet" type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css" />
+
+  <script type="application/javascript"
+          src="chrome://mochikit/content/MochiKit/packed.js"></script>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+
+  <script type="application/javascript"
+          src="../common.js"></script>
+  <script type="application/javascript"
+          src="../role.js"></script>
+  <script type="application/javascript"
+          src="../states.js"></script>
+
+  <script type="application/javascript">
+    function doTest()
+    {
+      testStates("div", 0, 0, STATE_INVISIBLE);
+      testStates("div_off", STATE_OFFSCREEN, 0, STATE_INVISIBLE);
+      testStates("div_abschild", 0, 0, STATE_INVISIBLE);
+
+      // Confirm destruction of accessibles.
+      document.getElementById("div").style.visibility = "hidden";
+      document.getElementById("div_off").style.visibility="hidden";
+      document.getElementById("div_abschild").style.visibility="hidden";
+      document.body.clientWidth; // flush layout
+      testAccessibleTree("outer_div", {children:[]});
+
+
+      SimpleTest.finish();
+    }
+
+    SimpleTest.waitForExplicitFinish();
+    addA11yLoadEvent(doTest);
+  </script>
+
+</head>
+
+<body>
+
+  <a target="_blank"
+     href="https://bugzilla.mozilla.org/show_bug.cgi?id=591363"
+     title="(in)visible state is not always correct?">
+    Mozilla Bug 591363
+  </a>
+  <p id="display"></p>
+  <div id="content" style="display: none"></div>
+  <pre id="test">
+  </pre>
+
+  <div id="outer_div">
+
+    <!-- trivial cases -->
+    <div id="div">div</div>
+    <div id="div_off" style="position: absolute; left:-999px; top:-999px">
+      offscreen!
+    </div>
+
+    <!-- edge case: no rect but has out of flow child -->
+    <div id="div_abschild">
+      <p style="position: absolute; left: 120px; top:120px;">absolute</p>
+    </div>
+
+  </div>
+</body>
+</html>
--- a/accessible/tests/mochitest/tree/test_combobox.xul
+++ b/accessible/tests/mochitest/tree/test_combobox.xul
@@ -38,17 +38,21 @@
                 role: ROLE_COMBOBOX_OPTION,
                 children: []
               }
             ]
           }
         ]
       };
 
-      testAccessibleTree("menulist", accTree);
+      if (!MAC) {
+        testAccessibleTree("menulist", accTree);
+      } else {
+        todo(false, "Make this test pass on OSX (bug 650366)");
+      }
 
       //////////////////////////////////////////////////////////////////////////
       // editable menulist
 
       accTree = {
         role: ROLE_COMBOBOX,
         children: [
           {
@@ -76,19 +80,20 @@
                 role: ROLE_COMBOBOX_OPTION,
                 children: []
               }
             ]
           }
         ]
       };
 
-      // XXX Bug 551957
       if (!MAC) {
         testAccessibleTree("menulist2", accTree);
+      } else {
+        todo(false, "Make this test pass on OSX (bug 551957)");
       }
 
       //////////////////////////////////////////////////////////////////////////
       // textbox@type=autocomplete #1 (history)
 
       accTree = {
         // textbox
         role: ROLE_AUTOCOMPLETE,
--- a/allmakefiles.sh
+++ b/allmakefiles.sh
@@ -85,16 +85,21 @@ if [ ! "$LIBXUL_SDK" ]; then
   fi
   if [ "$MOZ_WIDGET_TOOLKIT" = "android" ]; then
     add_makefiles "
       other-licenses/android/Makefile
       other-licenses/skia-npapi/Makefile
       mozglue/android/Makefile
     "
   fi
+  if [ "$MOZ_LINKER" ]; then
+    add_makefiles "
+      mozglue/linker/Makefile
+    "
+  fi
 fi
 
 if [ "$OS_ARCH" = "WINNT" ]; then
   add_makefiles "
     build/win32/Makefile
     build/win32/crashinjectdll/Makefile
   "
 fi
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -42,17 +42,17 @@ pref("general.useragent.compatMode.firef
 pref("browser.chromeURL", "chrome://browser/content/");
 #ifdef MOZ_OFFICIAL_BRANDING
 pref("browser.homescreenURL", "file:///system/home/homescreen.html");
 #else
 pref("browser.homescreenURL", "file:///data/local/homescreen.html,file:///system/home/homescreen.html");
 #endif
 
 // URL for the dialer application.
-pref("dom.telephony.app.phone.url", "http://localhost:7777/dialer/dialer.html");
+pref("dom.telephony.app.phone.url", "http://localhost:6666/apps/dialer/dialer.html");
 
 // Device pixel to CSS px ratio, in percent. Set to -1 to calculate based on display density.
 pref("browser.viewport.scaleRatio", -1);
 
 /* disable text selection */
 pref("browser.ignoreNativeFrameTextSelection", true);
 
 /* cache prefs */
--- a/b2g/installer/package-manifest.in
+++ b/b2g/installer/package-manifest.in
@@ -397,17 +397,17 @@
 @BINPATH@/components/nsTelephonyWorker.manifest
 @BINPATH@/components/nsTelephonyWorker.js
 @BINPATH@/components/Telephony.manifest
 @BINPATH@/components/Telephony.js
 @BINPATH@/components/nsWifiWorker.js
 @BINPATH@/components/nsWifiWorker.manifest
 #endif
 #ifdef XP_MACOSX
-@BINPATH@/components/libalerts_s.dylib
+@BINPATH@/components/libalerts.dylib
 #endif
 #ifdef MOZ_ENABLE_DBUS
 @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
 #endif
 @BINPATH@/components/nsINIProcessor.manifest
 @BINPATH@/components/nsINIProcessor.js
 @BINPATH@/components/nsPrompter.manifest
 @BINPATH@/components/nsPrompter.js
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -78,17 +78,17 @@ pref("extensions.blocklist.level", 2);
 pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/3/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/%PING_COUNT%/%TOTAL_PING_COUNT%/%DAYS_SINCE_LAST_PING%/");
 pref("extensions.blocklist.detailsURL", "https://www.mozilla.com/%LOCALE%/blocklist/");
 pref("extensions.blocklist.itemURL", "https://addons.mozilla.org/%LOCALE%/%APP%/blocked/%blockID%");
 
 pref("extensions.update.autoUpdateDefault", true);
 
 pref("extensions.hotfix.id", "firefox-hotfix@mozilla.org");
 pref("extensions.hotfix.cert.checkAttributes", true);
-pref("extensions.hotfix.certs.1.sha1Fingerprint", "foo");
+pref("extensions.hotfix.certs.1.sha1Fingerprint", "F1:DB:F9:6A:7B:B8:04:FA:48:3C:16:95:C7:2F:17:C6:5B:C2:9F:45");
 
 // Disable add-ons installed into the shared user and shared system areas by
 // default. This does not include the application directory. See the SCOPE
 // constants in AddonManager.jsm for values to use here
 pref("extensions.autoDisableScopes", 15);
 
 // Dictionary download preference
 pref("browser.dictionaries.download.url", "https://addons.mozilla.org/%LOCALE%/firefox/dictionaries/");
@@ -1044,17 +1044,17 @@ pref("devtools.scratchpad.enabled", true
 
 // Enable the Style Editor.
 pref("devtools.styleeditor.enabled", true);
 
 // Enable tools for Chrome development.
 pref("devtools.chrome.enabled", false);
 
 // Disable the GCLI enhanced command line.
-pref("devtools.gcli.enable", false);
+pref("devtools.gcli.enable", true);
 
 // The last Web Console height. This is initially 0 which means that the Web
 // Console will use the default height next time it shows.
 // Change to -1 if you do not want the Web Console to remember its last height.
 pref("devtools.hud.height", 0);
 
 // Remember the Web Console position. Possible values:
 //   above - above the web page,
--- a/browser/base/content/syncUtils.js
+++ b/browser/base/content/syncUtils.js
@@ -192,17 +192,17 @@ let gSyncUtils = {
       filepicker.init(window, dialogTitle, Ci.nsIFilePicker.modeSave);
       filepicker.appendFilters(Ci.nsIFilePicker.filterHTML);
       filepicker.defaultString = defaultSaveName;
       let rv = filepicker.show();
       if (rv == Ci.nsIFilePicker.returnOK
           || rv == Ci.nsIFilePicker.returnReplace) {
         let stream = Cc["@mozilla.org/network/file-output-stream;1"]
                        .createInstance(Ci.nsIFileOutputStream);
-        stream.init(filepicker.file, -1, -1, 0);
+        stream.init(filepicker.file, -1, 0600, 0);
 
         let serializer = new XMLSerializer();
         let output = serializer.serializeToString(iframe.contentDocument);
         output = output.replace(/<!DOCTYPE (.|\n)*?]>/,
           '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" ' +
           '"DTD/xhtml1-strict.dtd">');
         output = Weave.Utils.encodeUTF8(output);
         stream.write(output, output.length);
--- a/browser/components/migration/content/migration.js
+++ b/browser/components/migration/content/migration.js
@@ -334,16 +334,19 @@ var MigrationWizard = {
         source = "sourceNameIE";
         break;
       case "safari":
         source = "sourceNameSafari";
         break;
       case "chrome":
         source = "sourceNameChrome";
         break;
+      case "firefox":
+        source = "sourceNameFirefox";
+        break;
     }
 
     // semi-wallpaper for crash when multiple profiles exist, since we haven't initialized mSourceProfile in places
     this._migrator.getMigrateData(this._selectedProfile, this._autoMigrate);
 
     var oldHomePageURL = this._migrator.sourceHomePageURL;
 
     if (oldHomePageURL && source) {
--- a/browser/components/migration/content/migration.xul
+++ b/browser/components/migration/content/migration.xul
@@ -71,16 +71,17 @@
 #ifdef XP_MACOSX
       <radio id="safari"    label="&importFromSafari.label;"    accesskey="&importFromSafari.accesskey;"/>
 #elifdef XP_WIN
 #ifndef NO_IE_MIGRATOR
       <radio id="ie"        label="&importFromIE.label;"        accesskey="&importFromIE.accesskey;"/>
 #endif
 #endif
       <radio id="chrome"    label="&importFromChrome.label;"    accesskey="&importFromChrome.accesskey;"/>
+      <radio id="firefox"   label="&importFromFirefox.label;"   accesskey="&importFromFirefox.accesskey;"/>
       <radio id="fromfile"  label="&importFromHTMLFile.label;"  accesskey="&importFromHTMLFile.accesskey;" hidden="true"/>
       <radio id="nothing"   label="&importFromNothing.label;"   accesskey="&importFromNothing.accesskey;" hidden="true"/>
     </radiogroup>
     <label id="noSources" hidden="true">&noMigrationSources.label;</label>
   </wizardpage>
 
   <wizardpage id="selectProfile" pageid="selectProfile" label="&selectProfile.title;"
               next="importItems"
--- a/browser/components/migration/src/BrowserProfileMigrators.manifest
+++ b/browser/components/migration/src/BrowserProfileMigrators.manifest
@@ -1,2 +1,4 @@
 component {4cec1de4-1671-4fc3-a53e-6c539dc77a26} ChromeProfileMigrator.js
 contract @mozilla.org/profile/migrator;1?app=browser&type=chrome {4cec1de4-1671-4fc3-a53e-6c539dc77a26}
+component {91185366-ba97-4438-acba-48deaca63386} FirefoxProfileMigrator.js
+contract @mozilla.org/profile/migrator;1?app=browser&type=firefox {91185366-ba97-4438-acba-48deaca63386}
--- a/browser/components/migration/src/ChromeProfileMigrator.js
+++ b/browser/components/migration/src/ChromeProfileMigrator.js
@@ -35,31 +35,23 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
+const MIGRATOR = Ci.nsIBrowserProfileMigrator;
 
 const LOCAL_FILE_CID = "@mozilla.org/file/local;1";
 const FILE_INPUT_STREAM_CID = "@mozilla.org/network/file-input-stream;1";
 
 const BUNDLE_MIGRATION = "chrome://browser/locale/migration/migration.properties";
 
-const MIGRATE_ALL = 0x0000;
-const MIGRATE_SETTINGS = 0x0001;
-const MIGRATE_COOKIES = 0x0002;
-const MIGRATE_HISTORY = 0x0004;
-const MIGRATE_FORMDATA = 0x0008;
-const MIGRATE_PASSWORDS = 0x0010;
-const MIGRATE_BOOKMARKS = 0x0020;
-const MIGRATE_OTHERDATA = 0x0040;
-
 const S100NS_FROM1601TO1970 = 0x19DB1DED53E8000;
 const S100NS_PER_MS = 10;
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
 
@@ -137,69 +129,69 @@ ChromeProfileMigrator.prototype = {
   _replaceBookmarks : false,
   _sourceProfile: null,
   _profilesCache: null,
 
   /**
    * Notify to observers to start migration
    *
    * @param   aType
-   *          notification type such as MIGRATE_BOOKMARKS
+   *          notification type such as MIGRATOR.BOOKMARKS
    */
   _notifyStart : function Chrome_notifyStart(aType)
   {
     Services.obs.notifyObservers(null, "Migration:ItemBeforeMigrate", aType);
     this._pendingCount++;
   },
 
   /**
    * Notify observers that a migration error occured with an item
    *
    * @param   aType
-   *          notification type such as MIGRATE_BOOKMARKS
+   *          notification type such as MIGRATOR.BOOKMARKS
    */
   _notifyError : function Chrome_notifyError(aType)
   {
     Services.obs.notifyObservers(null, "Migration:ItemError", aType);
   },
 
   /**
    * Notify to observers to finish migration for item
    * If all items are finished, it sends migration end notification.
    *
    * @param   aType
-   *          notification type such as MIGRATE_BOOKMARKS
+   *          notification type such as MIGRATOR.BOOKMARKS
    */
   _notifyCompleted : function Chrome_notifyIfCompleted(aType)
   {
     Services.obs.notifyObservers(null, "Migration:ItemAfterMigrate", aType);
     if (--this._pendingCount == 0) {
       // All items are migrated, so we have to send end notification.
       Services.obs.notifyObservers(null, "Migration:Ended", null);
     }
   },
 
   /**
    * Migrating bookmark items
    */
   _migrateBookmarks : function Chrome_migrateBookmarks()
   {
-    this._notifyStart(MIGRATE_BOOKMARKS);
+    this._notifyStart(MIGRATOR.BOOKMARKS);
 
     try {
       PlacesUtils.bookmarks.runInBatchMode({
         _self : this,
         runBatched : function (aUserData) {
           let migrator = this._self;
           let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
           file.initWithPath(migrator._paths.bookmarks);
 
           NetUtil.asyncFetch(file, function(aInputStream, aResultCode) {
             if (!Components.isSuccessCode(aResultCode)) {
-              migrator._notifyCompleted(MIGRATE_BOOKMARKS);
+              migrator._notifyCompleted(MIGRATOR.BOOKMARKS);
               return;
             }
 
             // Parse Chrome bookmark file that is JSON format
             let bookmarkJSON = NetUtil.readInputStreamToString(aInputStream,
                                                                aInputStream.available(),
                                                                { charset : "UTF-8" });
             let roots = JSON.parse(bookmarkJSON).roots;
@@ -227,33 +219,33 @@ ChromeProfileMigrator.prototype = {
                 parentId =
                   PlacesUtils.bookmarks.createFolder(parentId,
                                                      bookmarksSubfolderTitle,
                                                      PlacesUtils.bookmarks.DEFAULT_INDEX);
               }
               insertBookmarkItems(parentId, roots.other.children);
             }
 
-            migrator._notifyCompleted(MIGRATE_BOOKMARKS);
+            migrator._notifyCompleted(MIGRATOR.BOOKMARKS);
           });
         }
       }, null);
     } catch (e) {
       Cu.reportError(e);
-      this._notifyError(MIGRATE_BOOKMARKS);
-      this._notifyCompleted(MIGRATE_BOOKMARKS);
+      this._notifyError(MIGRATOR.BOOKMARKS);
+      this._notifyCompleted(MIGRATOR.BOOKMARKS);
     }
   },
 
   /**
    * Migrating history
    */
   _migrateHistory : function Chrome_migrateHistory()
   {
-    this._notifyStart(MIGRATE_HISTORY);
+    this._notifyStart(MIGRATOR.HISTORY);
 
     try {
       PlacesUtils.history.runInBatchMode({
         _self : this,
         runBatched : function (aUserData) {
           // access sqlite3 database of Chrome's history
           let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
           file.initWithPath(this._self._paths.history);
@@ -300,35 +292,35 @@ ChromeProfileMigrator.prototype = {
 
             handleError : function(aError) {
               Cu.reportError("Async statement execution returned with '" +
                              aError.result + "', '" + aError.message + "'");
             },
 
             handleCompletion : function(aReason) {
               this._db.asyncClose();
-              this._self._notifyCompleted(MIGRATE_HISTORY);
+              this._self._notifyCompleted(MIGRATOR.HISTORY);
             }
           });
           stmt.finalize();
         }
       }, null);
     } catch (e) {
       Cu.reportError(e);
-      this._notifyError(MIGRATE_HISTORY);
-      this._notifyCompleted(MIGRATE_HISTORY);
+      this._notifyError(MIGRATOR.HISTORY);
+      this._notifyCompleted(MIGRATOR.HISTORY);
     }
   },
 
   /**
    * Migrating cookies
    */
   _migrateCookies : function Chrome_migrateCookies()
   {
-    this._notifyStart(MIGRATE_COOKIES);
+    this._notifyStart(MIGRATOR.COOKIES);
 
     try {
       // Access sqlite3 database of Chrome's cookie
       let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
       file.initWithPath(this._paths.cookies);
 
       let dbConn = Services.storage.openUnsharedDatabase(file);
       let stmt = dbConn.createAsyncStatement(
@@ -364,24 +356,24 @@ ChromeProfileMigrator.prototype = {
 
         handleError : function(aError) {
           Cu.reportError("Async statement execution returned with '" +
                          aError.result + "', '" + aError.message + "'");
         },
 
         handleCompletion : function(aReason) {
           this._db.asyncClose();
-          this._self._notifyCompleted(MIGRATE_COOKIES);
+          this._self._notifyCompleted(MIGRATOR.COOKIES);
         },
       });
       stmt.finalize();
     } catch (e) {
       Cu.reportError(e);
-      this._notifyError(MIGRATE_COOKIES);
-      this._notifyCompleted(MIGRATE_COOKIES);
+      this._notifyError(MIGRATOR.COOKIES);
+      this._notifyCompleted(MIGRATOR.COOKIES);
     }
   },
 
   /**
    * nsIBrowserProfileMigrator interface implementation
    */
 
   /**
@@ -404,23 +396,23 @@ ChromeProfileMigrator.prototype = {
     this._sourceProfile = aProfile;
 
     Services.obs.notifyObservers(null, "Migration:Started", null);
 
     // Reset panding count.  If this count becomes 0, "Migration:Ended"
     // notification is sent
     this._pendingCount = 1;
 
-    if (aItems & MIGRATE_HISTORY)
+    if (aItems & MIGRATOR.HISTORY)
       this._migrateHistory();
 
-    if (aItems & MIGRATE_COOKIES)
+    if (aItems & MIGRATOR.COOKIES)
       this._migrateCookies();
 
-    if (aItems & MIGRATE_BOOKMARKS)
+    if (aItems & MIGRATOR.BOOKMARKS)
       this._migrateBookmarks();
 
     if (--this._pendingCount == 0) {
       // When async imports are immeditelly completed unfortunately,
       // this will be called.
       // Usually, this notification is sent by _notifyCompleted()
       Services.obs.notifyObservers(null, "Migration:Ended", null);
     }
@@ -447,17 +439,17 @@ ChromeProfileMigrator.prototype = {
 
     // bookmark and preference are JSON format
 
     try {
       let file = chromeProfileDir.clone();
       file.append("Bookmarks");
       if (file.exists()) {
         this._paths.bookmarks = file.path;
-        result += MIGRATE_BOOKMARKS;
+        result += MIGRATOR.BOOKMARKS;
       }
     } catch (e) {
       Cu.reportError(e);
     }
 
     if (!this._paths.prefs) {
       let file = chromeProfileDir.clone();
       file.append("Preferences");
@@ -466,28 +458,28 @@ ChromeProfileMigrator.prototype = {
 
     // history and cookies are SQLite database
 
     try {
       let file = chromeProfileDir.clone();
       file.append("History");
       if (file.exists()) {
         this._paths.history = file.path;
-        result += MIGRATE_HISTORY;
+        result += MIGRATOR.HISTORY;
       }
     } catch (e) {
       Cu.reportError(e);
     }
 
     try {
       let file = chromeProfileDir.clone();
       file.append("Cookies");
       if (file.exists()) {
         this._paths.cookies = file.path;
-        result += MIGRATE_COOKIES;
+        result += MIGRATOR.COOKIES;
       }
     } catch (e) {
       Cu.reportError(e);
     }
 
     return result;
   },
 
copy from browser/components/migration/src/ChromeProfileMigrator.js
copy to browser/components/migration/src/FirefoxProfileMigrator.js
--- a/browser/components/migration/src/ChromeProfileMigrator.js
+++ b/browser/components/migration/src/FirefoxProfileMigrator.js
@@ -1,613 +1,404 @@
 /* -*- Mode: js; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  * vim: sw=2 ts=2 sts=2 et
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License
- * Version 1.1 (the "License"); you may not use this file except in
- * compliance with the License. You may obtain a copy of the License
- * at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
- * the License for the specific language governing rights and
- * limitations under the License.
- *
- * The Original Code is the Browser Profile Migrator.
- *
- * The Initial Developer of the Original Code is the Mozilla Foundation.
- * Portions created by the Initial Developer are Copyright (C) 2011
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *   Makoto Kato <m_kato@ga2.so-net.ne.jp> (Original Author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
+ * This Source Code is subject to the terms of the Mozilla Public License
+ * version 2.0 (the "License"). You can obtain a copy of the License at
+ * http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Migrates from a Firefox profile in a lossy manner in order to clean up a user's profile. Data
+ * is only migrated where the benefits outweigh the potential problems caused by importing
+ * undesired/invalid configurations from the source profile.
+ */
 
 const Cc = Components.classes;
 const Ci = Components.interfaces;
 const Cu = Components.utils;
 const Cr = Components.results;
+const MIGRATOR = Ci.nsIBrowserProfileMigrator;
 
 const LOCAL_FILE_CID = "@mozilla.org/file/local;1";
-const FILE_INPUT_STREAM_CID = "@mozilla.org/network/file-input-stream;1";
-
-const BUNDLE_MIGRATION = "chrome://browser/locale/migration/migration.properties";
-
-const MIGRATE_ALL = 0x0000;
-const MIGRATE_SETTINGS = 0x0001;
-const MIGRATE_COOKIES = 0x0002;
-const MIGRATE_HISTORY = 0x0004;
-const MIGRATE_FORMDATA = 0x0008;
-const MIGRATE_PASSWORDS = 0x0010;
-const MIGRATE_BOOKMARKS = 0x0020;
-const MIGRATE_OTHERDATA = 0x0040;
-
-const S100NS_FROM1601TO1970 = 0x19DB1DED53E8000;
-const S100NS_PER_MS = 10;
 
 Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
 Components.utils.import("resource://gre/modules/Services.jsm");
 Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
 Components.utils.import("resource://gre/modules/NetUtil.jsm");
-
-XPCOMUtils.defineLazyGetter(this, "bookmarksSubfolderTitle", function () {
-  // get "import from google chrome" string for folder
-  let strbundle =
-    Services.strings.createBundle(BUNDLE_MIGRATION);
-  let sourceNameChrome = strbundle.GetStringFromName("sourceNameChrome");
-  return strbundle.formatStringFromName("importedBookmarksFolder",
-                                        [sourceNameChrome],
-                                        1);
-});
+Components.utils.import("resource://gre/modules/FileUtils.jsm");
 
-/**
- * Convert Chrome time format to Date object
- *
- * @param   aTime
- *          Chrome time 
- * @return  converted Date object
- * @note    Google Chrome uses FILETIME / 10 as time.
- *          FILETIME is based on same structure of Windows.
- */
-function chromeTimeToDate(aTime)
+function FirefoxProfileMigrator()
 {
-  return new Date((aTime * S100NS_PER_MS - S100NS_FROM1601TO1970 ) / 10000);
+  // profD is not available when the migrator is run during startup so use ProfDS.
+  this._paths.currentProfile = FileUtils.getDir("ProfDS", []);
 }
 
-/**
- * Insert bookmark items into specific folder.
- *
- * @param   aFolderId
- *          id of folder where items will be inserted
- * @param   aItems
- *          bookmark items to be inserted
- */
-function insertBookmarkItems(aFolderId, aItems)
-{
-  for (let i = 0; i < aItems.length; i++) {
-    let item = aItems[i];
-
-    try {
-      if (item.type == "url") {
-        PlacesUtils.bookmarks.insertBookmark(aFolderId,
-                                             NetUtil.newURI(item.url),
-                                             PlacesUtils.bookmarks.DEFAULT_INDEX,
-                                             item.name);
-      } else if (item.type == "folder") {
-        let newFolderId =
-          PlacesUtils.bookmarks.createFolder(aFolderId,
-                                             item.name,
-                                             PlacesUtils.bookmarks.DEFAULT_INDEX);
-
-        insertBookmarkItems(newFolderId, item.children);
-      }
-    } catch (e) {
-      Cu.reportError(e);
-    }
-  }
-}
-
-function ChromeProfileMigrator()
-{
-}
-
-ChromeProfileMigrator.prototype = {
+FirefoxProfileMigrator.prototype = {
   _paths: {
     bookmarks : null,
     cookies : null,
+    currentProfile: null,    // The currently running (destination) profile.
+    encryptionKey: null,
     history : null,
-    prefs : null,
-    userData : null,
+    passwords: null,
   },
 
   _homepageURL : null,
   _replaceBookmarks : false,
   _sourceProfile: null,
   _profilesCache: null,
 
   /**
    * Notify to observers to start migration
    *
    * @param   aType
-   *          notification type such as MIGRATE_BOOKMARKS
+   *          notification type such as MIGRATOR.BOOKMARKS
    */
-  _notifyStart : function Chrome_notifyStart(aType)
+  _notifyStart : function Firefox_notifyStart(aType)
   {
     Services.obs.notifyObservers(null, "Migration:ItemBeforeMigrate", aType);
     this._pendingCount++;
   },
 
   /**
    * Notify observers that a migration error occured with an item
    *
    * @param   aType
-   *          notification type such as MIGRATE_BOOKMARKS
+   *          notification type such as MIGRATOR.BOOKMARKS
    */
-  _notifyError : function Chrome_notifyError(aType)
+  _notifyError : function Firefox_notifyError(aType)
   {
     Services.obs.notifyObservers(null, "Migration:ItemError", aType);
   },
 
   /**
    * Notify to observers to finish migration for item
    * If all items are finished, it sends migration end notification.
    *
    * @param   aType
-   *          notification type such as MIGRATE_BOOKMARKS
+   *          notification type such as MIGRATOR.BOOKMARKS
    */
-  _notifyCompleted : function Chrome_notifyIfCompleted(aType)
+  _notifyCompleted : function Firefox_notifyIfCompleted(aType)
   {
     Services.obs.notifyObservers(null, "Migration:ItemAfterMigrate", aType);
     if (--this._pendingCount == 0) {
       // All items are migrated, so we have to send end notification.
       Services.obs.notifyObservers(null, "Migration:Ended", null);
     }
   },
 
   /**
+   * The directory used for bookmark backups
+   * @return  directory of the bookmark backups
+   */
+  get _bookmarks_backup_folder()
+  {
+    let bookmarksBackupRelativePath = PlacesUtils.backups.profileRelativeFolderPath;
+    let bookmarksBackupDir = this._sourceProfile.clone().QueryInterface(Ci.nsILocalFile);
+    bookmarksBackupDir.appendRelativePath(bookmarksBackupRelativePath);
+    return bookmarksBackupDir;
+  },
+
+  /**
    * Migrating bookmark items
    */
-  _migrateBookmarks : function Chrome_migrateBookmarks()
+  _migrateBookmarks : function Firefox_migrateBookmarks()
   {
-    this._notifyStart(MIGRATE_BOOKMARKS);
+    this._notifyStart(MIGRATOR.BOOKMARKS);
 
     try {
-      PlacesUtils.bookmarks.runInBatchMode({
-        _self : this,
-        runBatched : function (aUserData) {
-          let migrator = this._self;
-          let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
-          file.initWithPath(migrator._paths.bookmarks);
-
-          NetUtil.asyncFetch(file, function(aInputStream, aResultCode) {
-            if (!Components.isSuccessCode(aResultCode)) {
-              migrator._notifyCompleted(MIGRATE_BOOKMARKS);
-              return;
-            }
-
-            // Parse Chrome bookmark file that is JSON format
-            let bookmarkJSON = NetUtil.readInputStreamToString(aInputStream,
-                                                               aInputStream.available(),
-                                                               { charset : "UTF-8" });
-            let roots = JSON.parse(bookmarkJSON).roots;
-
-            // Importing bookmark bar items
-            if (roots.bookmark_bar.children &&
-                roots.bookmark_bar.children.length > 0) {
-              // Toolbar
-              let parentId = PlacesUtils.toolbarFolderId;
-              if (!migrator._replaceBookmarks) { 
-                parentId =
-                  PlacesUtils.bookmarks.createFolder(parentId,
-                                                     bookmarksSubfolderTitle,
-                                                     PlacesUtils.bookmarks.DEFAULT_INDEX);
-              }
-              insertBookmarkItems(parentId, roots.bookmark_bar.children);
-            }
-
-            // Importing bookmark menu items
-            if (roots.other.children &&
-                roots.other.children.length > 0) {
-              // Bookmark menu
-              let parentId = PlacesUtils.bookmarksMenuFolderId;
-              if (!migrator._replaceBookmarks) { 
-                parentId =
-                  PlacesUtils.bookmarks.createFolder(parentId,
-                                                     bookmarksSubfolderTitle,
-                                                     PlacesUtils.bookmarks.DEFAULT_INDEX);
-              }
-              insertBookmarkItems(parentId, roots.other.children);
-            }
-
-            migrator._notifyCompleted(MIGRATE_BOOKMARKS);
-          });
-        }
-      }, null);
+      let srcBackupsDir = this._bookmarks_backup_folder;
+      let backupFolder = this._paths.currentProfile.clone();
+      backupFolder.append(srcBackupsDir.leafName);
+      if (!backupFolder.exists())
+        srcBackupsDir.copyTo(this._paths.currentProfile, null);
     } catch (e) {
       Cu.reportError(e);
-      this._notifyError(MIGRATE_BOOKMARKS);
-      this._notifyCompleted(MIGRATE_BOOKMARKS);
+      // Don't notify about backup migration errors since actual bookmarks are
+      // migrated with history.
+    } finally {
+      this._notifyCompleted(MIGRATOR.BOOKMARKS);
     }
   },
 
   /**
    * Migrating history
    */
-  _migrateHistory : function Chrome_migrateHistory()
+  _migrateHistory : function Firefox_migrateHistory()
   {
-    this._notifyStart(MIGRATE_HISTORY);
+    this._notifyStart(MIGRATOR.HISTORY);
 
     try {
-      PlacesUtils.history.runInBatchMode({
-        _self : this,
-        runBatched : function (aUserData) {
-          // access sqlite3 database of Chrome's history
-          let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
-          file.initWithPath(this._self._paths.history);
-
-          let dbConn = Services.storage.openUnsharedDatabase(file);
-          let stmt = dbConn.createAsyncStatement(
-              "SELECT url, title, last_visit_time, typed_count FROM urls WHERE hidden = 0");
-
-          stmt.executeAsync({
-            _asyncHistory : Cc["@mozilla.org/browser/history;1"]
-                            .getService(Ci.mozIAsyncHistory),
-            _db : dbConn,
-            _self : this._self,
-            handleResult : function(aResults) {
-              let places = [];
-              for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) {
-                try {
-                  // if having typed_count, we changes transition type to typed.
-                  let transType = PlacesUtils.history.TRANSITION_LINK;
-                  if (row.getResultByName("typed_count") > 0)
-                    transType = PlacesUtils.history.TRANSITION_TYPED;
-
-                  places.push({
-                    uri: NetUtil.newURI(row.getResultByName("url")),
-                    title: row.getResultByName("title"),
-                    visits: [{
-                      transitionType: transType,
-                      visitDate: chromeTimeToDate(
-                                   row.getResultByName(
-                                     "last_visit_time")) * 1000,
-                    }],
-                  });
-                } catch (e) {
-                  Cu.reportError(e);
-                }
-              }
-
-              try {
-                this._asyncHistory.updatePlaces(places);
-              } catch (e) {
-                Cu.reportError(e);
-              }
-            },
-
-            handleError : function(aError) {
-              Cu.reportError("Async statement execution returned with '" +
-                             aError.result + "', '" + aError.message + "'");
-            },
-
-            handleCompletion : function(aReason) {
-              this._db.asyncClose();
-              this._self._notifyCompleted(MIGRATE_HISTORY);
-            }
-          });
-          stmt.finalize();
-        }
-      }, null);
+      // access sqlite3 database of history
+      let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+      file.initWithPath(this._paths.history);
+      file.copyTo(this._paths.currentProfile, null);
     } catch (e) {
       Cu.reportError(e);
-      this._notifyError(MIGRATE_HISTORY);
-      this._notifyCompleted(MIGRATE_HISTORY);
+      this._notifyError(MIGRATOR.HISTORY);
+    } finally {
+      this._notifyCompleted(MIGRATOR.HISTORY);
     }
   },
 
   /**
    * Migrating cookies
+   *
+   * @note    Cookie permissions are not migrated since they may be inadvertently set leading to
+   *          website login problems.
    */
-  _migrateCookies : function Chrome_migrateCookies()
+  _migrateCookies : function Firefox_migrateCookies()
   {
-    this._notifyStart(MIGRATE_COOKIES);
+    this._notifyStart(MIGRATOR.COOKIES);
 
     try {
-      // Access sqlite3 database of Chrome's cookie
+      // Access sqlite3 database of cookies
       let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
       file.initWithPath(this._paths.cookies);
-
-      let dbConn = Services.storage.openUnsharedDatabase(file);
-      let stmt = dbConn.createAsyncStatement(
-          "SELECT host_key, path, name, value, secure, httponly, expires_utc FROM cookies");
-
-      stmt.executeAsync({
-        _db : dbConn,
-        _self : this,
-        handleResult : function(aResults) {
-          for (let row = aResults.getNextRow(); row; row = aResults.getNextRow()) {
-            let host_key = row.getResultByName("host_key");
-            if (host_key.match(/^\./)) {
-              // 1st character of host_key may be ".", so we have to remove it
-              host_key = host_key.substr(1);
-            }
-
-            try {
-              let expiresUtc =
-                chromeTimeToDate(row.getResultByName("expires_utc")) / 1000;
-              Services.cookies.add(host_key,
-                                   row.getResultByName("path"),
-                                   row.getResultByName("name"),
-                                   row.getResultByName("value"),
-                                   row.getResultByName("secure"),
-                                   row.getResultByName("httponly"),
-                                   false,
-                                   parseInt(expiresUtc));
-            } catch (e) {
-              Cu.reportError(e);
-            }
-          }
-        },
-
-        handleError : function(aError) {
-          Cu.reportError("Async statement execution returned with '" +
-                         aError.result + "', '" + aError.message + "'");
-        },
-
-        handleCompletion : function(aReason) {
-          this._db.asyncClose();
-          this._self._notifyCompleted(MIGRATE_COOKIES);
-        },
-      });
-      stmt.finalize();
+      file.copyTo(this._paths.currentProfile, null);
     } catch (e) {
       Cu.reportError(e);
-      this._notifyError(MIGRATE_COOKIES);
-      this._notifyCompleted(MIGRATE_COOKIES);
+      this._notifyError(MIGRATOR.COOKIES);
+    } finally {
+      this._notifyCompleted(MIGRATOR.COOKIES);
     }
   },
 
   /**
+   * Migrating passwords
+   */
+  _migratePasswords : function Firefox_migratePasswords()
+  {
+    this._notifyStart(MIGRATOR.PASSWORDS);
+
+    try {
+      // Access sqlite3 database of passwords
+      let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+      file.initWithPath(this._paths.passwords);
+      file.copyTo(this._paths.currentProfile, null);
+
+      let encryptionKey = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+      encryptionKey.initWithPath(this._paths.encryptionKey);
+      encryptionKey.copyTo(this._paths.currentProfile, null);
+    } catch (e) {
+      Cu.reportError(e);
+      this._notifyError(MIGRATOR.PASSWORDS);
+    } finally {
+      this._notifyCompleted(MIGRATOR.PASSWORDS);
+    }
+  },
+
+
+  /**
    * nsIBrowserProfileMigrator interface implementation
    */
 
   /**
    * Let's migrate all items
    *
    * @param   aItems
    *          list of data items to migrate.
    * @param   aStartup
    *          non-null if called during startup.
    * @param   aProfile
-   *          profile directory name to migrate
+   *          profile directory path to migrate from
    */
-  migrate : function Chrome_migrate(aItems, aStartup, aProfile)
+  migrate : function Firefox_migrate(aItems, aStartup, aProfile)
   {
     if (aStartup) {
       aStartup.doStartup();
       this._replaceBookmarks = true;
     }
 
-    this._sourceProfile = aProfile;
-
     Services.obs.notifyObservers(null, "Migration:Started", null);
 
-    // Reset panding count.  If this count becomes 0, "Migration:Ended"
+    // Reset pending count.  If this count becomes 0, "Migration:Ended"
     // notification is sent
     this._pendingCount = 1;
 
-    if (aItems & MIGRATE_HISTORY)
+    if (aItems & MIGRATOR.HISTORY)
       this._migrateHistory();
 
-    if (aItems & MIGRATE_COOKIES)
+    if (aItems & MIGRATOR.COOKIES)
       this._migrateCookies();
 
-    if (aItems & MIGRATE_BOOKMARKS)
+    if (aItems & MIGRATOR.BOOKMARKS)
       this._migrateBookmarks();
 
+    if (aItems & MIGRATOR.PASSWORDS)
+      this._migratePasswords();
+
     if (--this._pendingCount == 0) {
-      // When async imports are immeditelly completed unfortunately,
+      // When async imports are immediately completed unfortunately,
       // this will be called.
       // Usually, this notification is sent by _notifyCompleted()
       Services.obs.notifyObservers(null, "Migration:Ended", null);
     }
   },
 
   /**
    * return supported migration types
    *
    * @param   aProfile
-   *          directory name of the profile
+   *          the profile path to migrate from
    * @param   aDoingStartup
    *          non-null if called during startup.
    * @return  supported migration types
+   *
+   * @todo    Bug 715315 - make sure source databases are not in-use
    */
-  getMigrateData: function Chrome_getMigrateData(aProfile, aDoingStartup)
+  getMigrateData: function Firefox_getMigrateData(aProfile, aDoingStartup)
   {
-    this._sourceProfile = aProfile;
-    let chromeProfileDir = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
-    chromeProfileDir.initWithPath(this._paths.userData + aProfile);
+    this._sourceProfile = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
+    this._sourceProfile.initWithPath(aProfile);
 
     let result = 0;
-    if (!chromeProfileDir.exists() || !chromeProfileDir.isReadable())
+    if (!this._sourceProfile.exists() || !this._sourceProfile.isReadable()) {
+      Cu.reportError("source profile directory doesn't exist or is not readable");
+      return result;
+    }
+
+    // Migration initiated from the UI is not supported.
+    if (!aDoingStartup)
       return result;
 
-    // bookmark and preference are JSON format
-
+    // Bookmark backups in JSON format
     try {
-      let file = chromeProfileDir.clone();
-      file.append("Bookmarks");
+      let file = this._bookmarks_backup_folder;
       if (file.exists()) {
         this._paths.bookmarks = file.path;
-        result += MIGRATE_BOOKMARKS;
+        result += MIGRATOR.BOOKMARKS;
       }
     } catch (e) {
       Cu.reportError(e);
     }
 
-    if (!this._paths.prefs) {
-      let file = chromeProfileDir.clone();
-      file.append("Preferences");
-      this._paths.prefs = file.path;
-    }
-
-    // history and cookies are SQLite database
-
+    // Bookmarks, history and favicons
     try {
-      let file = chromeProfileDir.clone();
-      file.append("History");
+      let file = this._sourceProfile.clone();
+      file.append("places.sqlite");
       if (file.exists()) {
         this._paths.history = file.path;
-        result += MIGRATE_HISTORY;
+        result += MIGRATOR.HISTORY;
+        result |= MIGRATOR.BOOKMARKS;
       }
     } catch (e) {
       Cu.reportError(e);
     }
 
+    // Cookies
     try {
-      let file = chromeProfileDir.clone();
-      file.append("Cookies");
+      let file = this._sourceProfile.clone();
+      file.append("cookies.sqlite");
       if (file.exists()) {
         this._paths.cookies = file.path;
-        result += MIGRATE_COOKIES;
+        result += MIGRATOR.COOKIES;
+      }
+    } catch (e) {
+      Cu.reportError(e);
+    }
+
+    // Passwords & encryption key
+    try {
+      let passwords = this._sourceProfile.clone();
+      passwords.append("signons.sqlite");
+      let encryptionKey = this._sourceProfile.clone();
+      encryptionKey.append("key3.db");
+      if (passwords.exists() && encryptionKey.exists()) {
+        this._paths.passwords = passwords.path;
+        this._paths.encryptionKey = encryptionKey.path;
+        result += MIGRATOR.PASSWORDS;
       }
     } catch (e) {
       Cu.reportError(e);
     }
 
     return result;
   },
 
   /**
-   * Whether we support migration of Chrome
+   * Whether we support migration of Firefox
    *
    * @return true if supported
    */
   get sourceExists()
   {
-#ifdef XP_WIN
-    this._paths.userData = Services.dirsvc.get("LocalAppData", Ci.nsIFile).path +
-                            "\\Google\\Chrome\\User Data\\";
-#elifdef XP_MACOSX
-    this._paths.userData = Services.dirsvc.get("Home", Ci.nsIFile).path +
-                            "/Library/Application Support/Google/Chrome/";
-#else
-    this._paths.userData = Services.dirsvc.get("Home", Ci.nsIFile).path +
-                            "/.config/google-chrome/";
-#endif
+    let userData = Services.dirsvc.get("DefProfRt", Ci.nsIFile).path;
     let result = 0;
     try {
       let userDataDir = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
-      userDataDir.initWithPath(this._paths.userData);
+      userDataDir.initWithPath(userData);
       if (!userDataDir.exists() || !userDataDir.isReadable())
         return false;
 
       let profiles = this.sourceProfiles;
       if (profiles.length < 1)
         return false;
-
-      // check that we can actually get data from the first profile
-      result = this.getMigrateData(profiles.queryElementAt(0, Ci.nsISupportsString), false);
+      // Check that we can get data from at least one profile since profile selection has not
+      // happened yet.
+      for (let i = 0; i < profiles.length; i++) {
+        result = this.getMigrateData(profiles.queryElementAt(i, Ci.nsISupportsString), true);
+        if (result)
+          break;
+      }
     } catch (e) {
       Cu.reportError(e);
     }
     return result > 0;
   },
 
   get sourceHasMultipleProfiles()
   {
     return this.sourceProfiles.length > 1;
   },
 
   get sourceProfiles()
   {
-    let profiles = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
-    try {
-      if (!this._profilesCache) {
-        let localState = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
-        // Local State is a JSON file that contains profile info.
-        localState.initWithPath(this._paths.userData + "Local State");
-        if (!localState.exists())
-          throw new Components.Exception("Chrome's 'Local State' file does not exist.",
-                                         Cr.NS_ERROR_FILE_NOT_FOUND);
-        if (!localState.isReadable())
-          throw new Components.Exception("Chrome's 'Local State' file could not be read.",
-                                         Cr.NS_ERROR_FILE_ACCESS_DENIED);
-        let fstream = Cc[FILE_INPUT_STREAM_CID].createInstance(Ci.nsIFileInputStream);
-        fstream.init(localState, -1, 0, 0);
-        let inputStream = NetUtil.readInputStreamToString(fstream, fstream.available(),
-                                                          { charset: "UTF-8" });
-        this._profilesCache = JSON.parse(inputStream).profile.info_cache;
-      }
+    try
+    {
+      if (!this._profilesCache)
+      {
+        this._profilesCache = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
+        let profileService = Cc["@mozilla.org/toolkit/profile-service;1"]
+                               .getService(Ci.nsIToolkitProfileService);
+        // Only allow migrating from the default (selected) profile since this will be the only one
+        // returned by the toolkit profile service after bug 214675 has landed.
+        var profile = profileService.selectedProfile;
+        if (profile.rootDir.path === this._paths.currentProfile.path)
+          return null;
 
-      for (let index in this._profilesCache) {
         let str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
-        str.data = index;
-        profiles.appendElement(str, false);
+        str.data = profile.rootDir.path;
+        this._profilesCache.appendElement(str, false);
       }
     } catch (e) {
-      Cu.reportError("Error detecting Chrome profiles: " + e);
-      // if we weren't able to detect any profiles above, fallback to the Default profile.
-      if (profiles.length < 1) {
-        let str = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
-        // the default profile name is "Default"
-        str.data = "Default";
-        profiles.appendElement(str, false);
-      }
+      Cu.reportError("Error detecting Firefox profiles: " + e);
     }
-    return profiles;
+    return this._profilesCache;
   },
 
   /**
    * Return home page URL
    *
    * @return  home page URL
+   *
+   * @todo    Bug 715348 will migrate preferences such as the homepage
    */
   get sourceHomePageURL()
   {
     try  {
       if (this._homepageURL)
         return this._homepageURL;
-
-      if (!this._paths.prefs)
-        this.getMigrateData(this._sourceProfile, false);
-
-      // XXX reading and parsing JSON is synchronous.
-      let file = Cc[LOCAL_FILE_CID].createInstance(Ci.nsILocalFile);
-      file.initWithPath(this._paths.prefs);
-      let fstream = Cc[FILE_INPUT_STREAM_CID].
-                    createInstance(Ci.nsIFileInputStream);
-      fstream.init(file, -1, 0, 0); 
-      this._homepageURL = JSON.parse(
-        NetUtil.readInputStreamToString(fstream, fstream.available(),
-                                        { charset: "UTF-8" })).homepage;
-      return this._homepageURL;
     } catch (e) {
       Cu.reportError(e);
     }
     return "";
   },
 
   QueryInterface: XPCOMUtils.generateQI([
     Ci.nsIBrowserProfileMigrator
   ]),
 
-  classDescription: "Chrome Profile Migrator",
-  contractID: "@mozilla.org/profile/migrator;1?app=browser&type=chrome",
-  classID: Components.ID("{4cec1de4-1671-4fc3-a53e-6c539dc77a26}")
+  classDescription: "Firefox Profile Migrator",
+  contractID: "@mozilla.org/profile/migrator;1?app=browser&type=firefox",
+  classID: Components.ID("{91185366-ba97-4438-acba-48deaca63386}")
 };
 
-const NSGetFactory = XPCOMUtils.generateNSGetFactory([ChromeProfileMigrator]);
+const NSGetFactory = XPCOMUtils.generateNSGetFactory([FirefoxProfileMigrator]);
--- a/browser/components/migration/src/Makefile.in
+++ b/browser/components/migration/src/Makefile.in
@@ -60,16 +60,17 @@ endif
 
 ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 CPPSRCS += nsSafariProfileMigrator.cpp \
            $(NULL)
 endif            
 
 EXTRA_PP_COMPONENTS = \
   ChromeProfileMigrator.js \
+  FirefoxProfileMigrator.js \
   $(NULL)
 
 EXTRA_COMPONENTS = \
 	BrowserProfileMigrators.manifest \
 	$(NULL)
 
 include $(topsrcdir)/config/rules.mk
 
--- a/browser/components/migration/src/nsProfileMigrator.cpp
+++ b/browser/components/migration/src/nsProfileMigrator.cpp
@@ -135,16 +135,17 @@ nsProfileMigrator::Migrate(nsIProfileSta
 
 NS_IMPL_ISUPPORTS1(nsProfileMigrator, nsIProfileMigrator)
 
 #ifdef XP_WIN
 
 #define INTERNAL_NAME_IEXPLORE        "iexplore"
 #define INTERNAL_NAME_MOZILLA_SUITE   "apprunner"
 #define INTERNAL_NAME_CHROME          "chrome"
+#define INTERNAL_NAME_FIREFOX         "firefox"
 #endif
 
 nsresult
 nsProfileMigrator::GetDefaultBrowserMigratorKey(nsACString& aKey,
                                                 nsCOMPtr<nsIBrowserProfileMigrator>& bpm)
 {
 #if XP_WIN
 
@@ -218,29 +219,34 @@ nsProfileMigrator::GetDefaultBrowserMigr
   if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_IEXPLORE)) {
     aKey = "ie";
     return NS_OK;
   }
   else if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_CHROME)) {
     aKey = "chrome";
     return NS_OK;
   }
+  else if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_FIREFOX)) {
+    aKey = "firefox";
+    return NS_OK;
+  }
 
 #else
   bool exists = false;
 #define CHECK_MIGRATOR(browser) do {\
   bpm = do_CreateInstance(NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX browser);\
   if (bpm)\
     bpm->GetSourceExists(&exists);\
   if (exists) {\
     aKey = browser;\
     return NS_OK;\
   }} while(0)
 
 #if defined(XP_MACOSX)
   CHECK_MIGRATOR("safari");
 #endif
   CHECK_MIGRATOR("chrome");
+  CHECK_MIGRATOR("firefox");
 
 #undef CHECK_MIGRATOR
 #endif
   return NS_ERROR_FAILURE;
 }
--- a/browser/components/search/test/browser_426329.js
+++ b/browser/components/search/test/browser_426329.js
@@ -3,16 +3,17 @@
 var chromeUtils = {};
 this._scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
                      getService(Ci.mozIJSSubScriptLoader);
 this._scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", chromeUtils);
 
 function test() {
   waitForExplicitFinish();
 
+  var searchEntries = ["test", "More Text", "Some Text"];
   var searchBar = BrowserSearch.searchBar;
   var searchButton = document.getAnonymousElementByAttribute(searchBar,
                      "anonid", "search-go-button");
   ok(searchButton, "got search-go-button");
 
   searchBar.value = "test";
 
   var ss = Services.search;
@@ -161,29 +162,48 @@ function test() {
   }
 
   function testDropLink() {
     init();
     chromeUtils.synthesizeDrop(searchBar.searchButton, searchBar.searchButton, [[ {type: "text/uri-list", data: "http://www.mozilla.org" } ]], "copy", window, EventUtils);
     is(searchBar.value, "More Text", "drop text/uri-list on searchbar");
     SimpleTest.executeSoon(testRightClick);
   }
-  
+
   function testRightClick() {
     init();
     searchBar.removeEventListener("popupshowing", stopPopup, true);
     content.location.href = "about:blank";
     simulateClick({ button: 2 }, searchButton);
     setTimeout(function() {
 
       is(gBrowser.tabs.length, preTabNo, "RightClick did not open new tab");
       is(gBrowser.currentURI.spec, "about:blank", "RightClick did nothing");
 
+      testSearchHistory();
+    }, 5000);
+  }
+
+  function testSearchHistory() {
+    var textbox = searchBar._textbox;
+    for (var i = 0; i < searchEntries.length; i++) {
+      let exists = textbox._formHistSvc.entryExists(textbox.searchParam, searchEntries[i]);
+      ok(exists, "form history entry '" + searchEntries[i] + "' should exist");
+    }
+    testAutocomplete();
+  }
+
+  function testAutocomplete() {
+    var popup = searchBar.textbox.popup;
+    popup.addEventListener("popupshowing", function() {
+      checkMenuEntries(searchEntries);
       finalize();
-    }, 5000);
+      popup.removeEventListener("popupshowing", this, false);
+    }, false);
+    searchBar.textbox.showHistoryPopup();
   }
 
   function finalize() {
     searchBar.value = "";
     while (gBrowser.tabs.length != 1) {
       gBrowser.removeTab(gBrowser.tabs[0]);
     }
     content.location.href = "about:blank";
@@ -206,10 +226,31 @@ function test() {
     var metaKeyArg  = aEvent.metaKey  || false;
     var buttonArg   = aEvent.button   || 0;
     event.initMouseEvent("click", true, true, window,
                           0, 0, 0, 0, 0,
                           ctrlKeyArg, altKeyArg, shiftKeyArg, metaKeyArg,
                           buttonArg, null); 
     aTarget.dispatchEvent(event);
   }
+
+  // modified from toolkit/components/satchel/test/test_form_autocomplete.html
+  function checkMenuEntries(expectedValues) {
+    var actualValues = getMenuEntries();
+    is(actualValues.length, expectedValues.length, "Checking length of expected menu");
+    for (var i = 0; i < expectedValues.length; i++)
+      is(actualValues[i], expectedValues[i], "Checking menu entry #"+i);
+  }
+
+  function getMenuEntries() {
+    var entries = [];
+    var autocompleteMenu = searchBar.textbox.popup;
+    // Could perhaps pull values directly from the controller, but it seems
+    // more reliable to test the values that are actually in the tree?
+    var column = autocompleteMenu.tree.columns[0];
+    var numRows = autocompleteMenu.tree.view.rowCount;
+    for (var i = 0; i < numRows; i++) {
+      entries.push(autocompleteMenu.tree.view.getValueAt(i, column));
+    }
+    return entries;
+  }
 }
 
--- a/browser/components/shell/src/nsGNOMEShellService.cpp
+++ b/browser/components/shell/src/nsGNOMEShellService.cpp
@@ -91,18 +91,16 @@ static const ProtocolAssociation appProt
   { "chrome", false }
 };
 
 static const MimeTypeAssociation appTypes[] = {
   { "text/html",             "htm html shtml" },
   { "application/xhtml+xml", "xhtml xht"      }
 };
 
-static const char kDocumentIconPath[] = "firefox-document.png";
-
 // GConf registry key constants
 #define DG_BACKGROUND "/desktop/gnome/background"
 
 static const char kDesktopImageKey[] = DG_BACKGROUND "/picture_filename";
 static const char kDesktopOptionsKey[] = DG_BACKGROUND "/picture_options";
 static const char kDesktopDrawBGKey[] = DG_BACKGROUND "/draw_background";
 static const char kDesktopColorKey[] = DG_BACKGROUND "/primary_color";
 
--- a/browser/devtools/webconsole/GcliCommands.jsm
+++ b/browser/devtools/webconsole/GcliCommands.jsm
@@ -80,16 +80,28 @@ gcli.addCommand({
   exec: function(args, context) {
     let hud = HUDService.getHudReferenceById(context.environment.hudId);
     hud.gcliterm.clearOutput();
   }
 });
 
 
 /**
+ * 'console close' command
+ */
+gcli.addCommand({
+  name: "console close",
+  description: gcli.lookup("consolecloseDesc"),
+  exec: function(args, context) {
+    let tab = HUDService.getHudReferenceById(context.environment.hudId).tab;
+    HUDService.deactivateHUDForContext(tab);
+  }
+});
+
+/**
  * 'inspect' command
  */
 gcli.addCommand({
   name: "inspect",
   description: gcli.lookup("inspectDesc"),
   manual: gcli.lookup("inspectManual"),
   params: [
     {
--- a/browser/devtools/webconsole/HUDService.jsm
+++ b/browser/devtools/webconsole/HUDService.jsm
@@ -3656,17 +3656,17 @@ HeadsUpDisplay.prototype = {
     this.createConsoleMenu(this.consoleWrap);
 
     this.filterPrefs = HUDService.getDefaultFilterPrefs(this.hudId);
 
     let consoleFilterToolbar = this.makeFilterToolbar();
     consoleFilterToolbar.setAttribute("id", "viewGroup");
     this.consoleFilterToolbar = consoleFilterToolbar;
 
-    this.hintNode = this.makeXULNode("div");
+    this.hintNode = this.makeXULNode("vbox");
     this.hintNode.setAttribute("class", "gcliterm-hint-node");
 
     let hintParentNode = this.makeXULNode("vbox");
     hintParentNode.setAttribute("flex", "0");
     hintParentNode.setAttribute("class", "gcliterm-hint-parent");
     hintParentNode.setAttribute("pack", "end");
     hintParentNode.appendChild(this.hintNode);
     hintParentNode.hidden = true;
@@ -6830,17 +6830,17 @@ GcliTerm.prototype = {
     this.element = this.document.createElement("vbox");
     this.element.setAttribute("class", "gcliterm-input-container");
     this.element.setAttribute("flex", "0");
 
     this.inputStack = this.document.createElement("stack");
     this.inputStack.setAttribute("class", "gcliterm-stack-node");
     this.element.appendChild(this.inputStack);
 
-    this.completeNode = this.document.createElement("div");
+    this.completeNode = this.document.createElementNS(HTML_NS, "div");
     this.completeNode.setAttribute("class", "gcliterm-complete-node");
     this.completeNode.setAttribute("aria-live", "polite");
     this.inputStack.appendChild(this.completeNode);
 
     this.inputNode = this.document.createElement("textbox");
     this.inputNode.setAttribute("class", "gcliterm-input-node");
     this.inputNode.setAttribute("rows", "1");
     this.inputStack.appendChild(this.inputNode);
@@ -6862,26 +6862,26 @@ GcliTerm.prototype = {
     if (aEvent.output.output == null) {
       return;
     }
 
     let output = aEvent.output.output;
     if (aEvent.output.command.returnType == "html" && typeof output == "string") {
       output = this.document.createRange().createContextualFragment(
           '<div xmlns="' + HTML_NS + '" xmlns:xul="' + XUL_NS + '">' +
-          output + '</div>').firstChild;
+          output + '</div>');
     }
 
     // See https://github.com/mozilla/domtemplate/blob/master/README.md
     // for docs on the template() function
     let element = this.document.createRange().createContextualFragment(
-      '<richlistitem xmlns="' + XUL_NS + '" clipboardText="${clipboardText}"' +
-      '    timestamp="${timestamp}" id="${id}" class="hud-msg-node">' +
-      '  <label class="webconsole-timestamp" value="${timestampString}"/>' +
-      '  <vbox class="webconsole-msg-icon-container" style="${iconContainerStyle}">' +
+      '<richlistitem xmlns="' + XUL_NS + '" _clipboardText="${clipboardText}"' +
+      '    _timestamp="${timestamp}" _id="${id}" class="hud-msg-node">' +
+      '  <label class="webconsole-timestamp" _value="${timestampString}"/>' +
+      '  <vbox class="webconsole-msg-icon-container" _style="${iconContainerStyle}">' +
       '    <image class="webconsole-msg-icon"/>' +
       '    <spacer flex="1"/>' +
       '  </vbox>' +
       '  <hbox flex="1" class="gcliterm-msg-body">${output}</hbox>' +
       '  <hbox align="start"><label value="1" class="webconsole-msg-repeat"/></hbox>' +
       '</richlistitem>').firstChild;
 
     let hud = HUDService.getHudReferenceById(this.hudId);
--- a/browser/devtools/webconsole/gcli.jsm
+++ b/browser/devtools/webconsole/gcli.jsm
@@ -3024,16 +3024,22 @@ JavascriptType.prototype.parse = functio
   // should be completed.
   var beginning = this._findCompletionBeginning(typed);
 
   // There was an error analyzing the string.
   if (beginning.err) {
     return new Conversion(typed, arg, Status.ERROR, beginning.err);
   }
 
+  // If the current state is ParseState.COMPLEX, then we can't do completion.
+  // so bail out now
+  if (beginning.state === ParseState.COMPLEX) {
+    return new Conversion(typed, arg);
+  }
+
   // If the current state is not ParseState.NORMAL, then we are inside of a
   // string which means that no completion is possible.
   if (beginning.state !== ParseState.NORMAL) {
     return new Conversion(typed, arg, Status.INCOMPLETE, '');
   }
 
   var completionPart = typed.substring(beginning.startPos);
   var properties = completionPart.split('.');
@@ -3063,17 +3069,17 @@ JavascriptType.prototype.parse = functio
 
       try {
         scope = scope[prop];
       }
       catch (ex) {
         // It would be nice to be able to report this error in some way but
         // as it can happen just when someone types '{sessionStorage.', it
         // almost doesn't really count as an error, so we ignore it
-        return new Conversion(typed, arg, Status.INCOMPLETE, '');
+        return new Conversion(typed, arg, Status.VALID, '');
       }
     }
   }
   else {
     matchProp = properties[0].trimLeft();
   }
 
   // If the reason we just stopped adjusting the scope was a non-simple string,
@@ -3241,30 +3247,54 @@ function isVendorPrefixed(name) {
          name.indexOf('webkit') === 0 ||
          name.indexOf('ms') === 0;
 }
 
 /**
  * Constants used in return value of _findCompletionBeginning()
  */
 var ParseState = {
+  /**
+   * We have simple input like window.foo, without any punctuation that makes
+   * completion prediction be confusing or wrong
+   */
   NORMAL: 0,
+
+  /**
+   * The cursor is in some Javascript that makes completion hard to predict,
+   * like console.log(
+   */
+  COMPLEX: 1,
+
+  /**
+   * The cursor is inside single quotes (')
+   */
   QUOTE: 2,
+
+  /**
+   * The cursor is inside single quotes (")
+   */
   DQUOTE: 3
 };
 
 var OPEN_BODY = '{[('.split('');
 var CLOSE_BODY = '}])'.split('');
 var OPEN_CLOSE_BODY = {
   '{': '}',
   '[': ']',
   '(': ')'
 };
 
 /**
+ * How we distinguish between simple and complex JS input. We attempt
+ * completion against simple JS.
+ */
+var simpleChars = /[a-zA-Z0-9.]/;
+
+/**
  * Analyzes a given string to find the last statement that is interesting for
  * later completion.
  * @param text A string to analyze
  * @return If there was an error in the string detected, then a object like
  *   { err: 'ErrorMesssage' }
  * is returned, otherwise a object like
  *   {
  *     state: ParseState.NORMAL|ParseState.QUOTE|ParseState.DQUOTE,
@@ -3272,18 +3302,23 @@ var OPEN_CLOSE_BODY = {
  *   }
  */
 JavascriptType.prototype._findCompletionBeginning = function(text) {
   var bodyStack = [];
 
   var state = ParseState.NORMAL;
   var start = 0;
   var c;
+  var complex = false;
+
   for (var i = 0; i < text.length; i++) {
     c = text[i];
+    if (!simpleChars.test(c)) {
+      complex = true;
+    }
 
     switch (state) {
       // Normal JS state.
       case ParseState.NORMAL:
         if (c === '"') {
           state = ParseState.DQUOTE;
         }
         else if (c === '\'') {
@@ -3339,16 +3374,20 @@ JavascriptType.prototype._findCompletion
         }
         else if (c === '\'') {
           state = ParseState.NORMAL;
         }
         break;
     }
   }
 
+  if (state === ParseState.NORMAL && complex) {
+    state = ParseState.COMPLEX;
+  }
+
   return {
     state: state,
     startPos: start
   };
 };
 
 /**
  * Return true if the passed object is either an iterator or a generator, and
@@ -4333,17 +4372,16 @@ Requisition.prototype.toCanonicalString 
     // named parameters in place of positional params. Both can wait.
     if (assignment.getValue() !== assignment.param.defaultValue) {
       line.push(' ');
       line.push(type.stringify(assignment.getValue()));
     }
   }, this);
 
   // Canonically, if we've opened with a { then we should have a } to close
-  var command = this.commandAssignment.getValue();
   if (cmd === '{') {
     if (this.getAssignment(0).getArg().suffix.indexOf('}') === -1) {
       line.push(' }');
     }
   }
 
   return line.join('');
 };
@@ -5286,19 +5324,16 @@ define('gcli/ui/domtemplate', ['require'
   exports.template = obj.template;
 
 });
 define("text!gcli/commands/help.css", [], void 0);
 define("text!gcli/commands/help_intro.html", [], "\n" +
   "<h2>${l10n.introHeader}</h2>\n" +
   "\n" +
   "<p>\n" +
-  "  <a target=\"_blank\" href=\"https://developer.mozilla.org/AppLinks/WebConsoleHelp?locale=${lang}\">\n" +
-  "    ${l10n.introBody}\n" +
-  "  </a>\n" +
   "</p>\n" +
   "");
 
 define("text!gcli/commands/help_list.html", [], "\n" +
   "<h3>${getHeading()}</h3>\n" +
   "\n" +
   "<table>\n" +
   "  <tr foreach=\"command in ${getMatchingCommands()}\"\n" +
@@ -5369,34 +5404,34 @@ function Console(options) {
 
   // Create a FocusManager for the various parts to register with
   this.focusManager = new FocusManager({ document: options.chromeDocument });
   this.focusManager.onFocus.add(this.gcliTerm.show, this.gcliTerm);
   this.focusManager.onBlur.add(this.gcliTerm.hide, this.gcliTerm);
   this.focusManager.addMonitoredElement(this.gcliTerm.hintNode, 'gcliTerm');
 
   this.inputter = new Inputter({
-    document: options.contentDocument,
+    document: options.chromeDocument,
     requisition: options.requisition,
     inputElement: options.inputElement,
     completeElement: options.completeElement,
     completionPrompt: '',
     backgroundElement: options.backgroundElement,
     focusManager: this.focusManager
   });
 
   this.menu = new CommandMenu({
-    document: options.contentDocument,
+    document: options.chromeDocument,
     requisition: options.requisition,
     menuClass: 'gcliterm-menu'
   });
   this.hintElement.appendChild(this.menu.element);
 
   this.argFetcher = new ArgFetcher({
-    document: options.contentDocument,
+    document: options.chromeDocument,
     requisition: options.requisition,
     argFetcherClass: 'gcliterm-argfetcher'
   });
   this.hintElement.appendChild(this.argFetcher.element);
 
   this.chromeWindow = options.chromeDocument.defaultView;
   this.resizer = this.resizer.bind(this);
   this.chromeWindow.addEventListener('resize', this.resizer, false);
@@ -5464,16 +5499,67 @@ Console.prototype.resizer = function() {
     }
     else {
       this.argFetcher.setMaxHeight(parentHeight);
 
       this.hintElement.style.overflowY = null;
       this.hintElement.style.borderBottomColor = 'white';
     }
   }
+
+  // We also try to make the max-width of any GCLI elements so they don't
+  // extend outside the scroll area.
+  var doc = this.hintElement.ownerDocument;
+
+  var outputNode = this.hintElement.parentNode.parentNode.children[1];
+  var outputs = outputNode.getElementsByClassName('gcliterm-msg-body');
+  var listItems = outputNode.getElementsByClassName('hud-msg-node');
+
+  // This is an top-side estimate. We could try to calculate it, maybe using
+  // something along these lines http://www.alexandre-gomes.com/?p=115 However
+  // experience has shown this to be hard to get to work reliably
+  // Also we don't need to be precise. If we use a number that is too big then
+  // the only down-side is too great a right margin
+  var scrollbarWidth = 20;
+
+  if (listItems.length > 0) {
+    var parentWidth = outputNode.getBoundingClientRect().width - scrollbarWidth;
+    var otherWidth;
+    var body;
+
+    for (var i = 0; i < listItems.length; ++i) {
+      var listItem = listItems[i];
+      // a.k.a 'var otherWidth = 132'
+      otherWidth = 0;
+      body = null;
+
+      for (var j = 0; j < listItem.children.length; j++) {
+        var child = listItem.children[j];
+
+        if (child.classList.contains('gcliterm-msg-body')) {
+          body = child.children[0];
+        }
+        else {
+          otherWidth += child.getBoundingClientRect().width;
+        }
+
+        var styles = doc.defaultView.getComputedStyle(child, null);
+        otherWidth += parseInt(styles.borderLeftWidth, 10) +
+                      parseInt(styles.borderRightWidth, 10) +
+                      parseInt(styles.paddingLeft, 10) +
+                      parseInt(styles.paddingRight, 10) +
+                      parseInt(styles.marginLeft, 10) +
+                      parseInt(styles.marginRight, 10);
+      }
+
+      if (body) {
+        body.style.width = (parentWidth - otherWidth) + 'px';
+      }
+    }
+  }
 };
 
 exports.Console = Console;
 
 });
 /*
  * Copyright 2009-2011 Mozilla Foundation and contributors
  * Licensed under the New BSD license. See LICENSE.txt or:
@@ -6034,17 +6120,17 @@ Completer.prototype.update = function(in
   //
   // <span class="gcli-prompt">${completionPrompt}</span>
   // ${appendMarkupStatus()}
   // ${prefix}
   // <span class="gcli-in-ontab">${contents}</span>
   // <span class="gcli-in-closebrace" if="${unclosedJs}">}<span>
 
   var document = this.element.ownerDocument;
-  var prompt = document.createElement('span');
+  var prompt = dom.createElement(document, 'span');
   prompt.classList.add('gcli-prompt');
   prompt.appendChild(document.createTextNode(this.completionPrompt + ' '));
   this.element.appendChild(prompt);
 
   if (input.typed.length > 0) {
     var scores = this.requisition.getInputStatusMarkup(input.cursor.start);
     this.appendMarkupStatus(this.element, scores, input);
   }
@@ -6066,31 +6152,31 @@ Completer.prototype.update = function(in
       prefix = ' \u00a0';         // aka &nbsp;
       contents = '\u21E5 ' + tab; // aka &rarr; the right arrow
     }
 
     if (prefix != null) {
       this.element.appendChild(document.createTextNode(prefix));
     }
 
-    var suffix = document.createElement('span');
+    var suffix = dom.createElement(document, 'span');
     suffix.classList.add('gcli-in-ontab');
     suffix.appendChild(document.createTextNode(contents));
     this.element.appendChild(suffix);
   }
 
   // Add a grey '}' to the end of the command line when we've opened
   // with a { but haven't closed it
   var command = this.requisition.commandAssignment.getValue();
   var unclosedJs = command && command.name === '{' &&
           this.requisition.getAssignment(0).getArg().suffix.indexOf('}') === -1;
   if (unclosedJs) {
-    var close = document.createElement('span');
+    var close = dom.createElement(document, 'span');
     close.classList.add('gcli-in-closebrace');
-    close.appendChild(document.createTextNode('}'));
+    close.appendChild(document.createTextNode(' }'));
     this.element.appendChild(close);
   }
 };
 
 /**
  * Mark-up an array of Status values with spans
  */
 Completer.prototype.appendMarkupStatus = function(element, scores, input) {
@@ -6106,17 +6192,17 @@ Completer.prototype.appendMarkupStatus =
 
   while (true) {
     if (lastStatus !== scores[i]) {
       var state = scores[i];
       if (!state) {
         console.error('No state at i=' + i + '. scores.len=' + scores.length);
         state = Status.VALID;
       }
-      span = document.createElement('span');
+      span = dom.createElement(document, 'span');
       span.classList.add('gcli-in-' + state.toString().toLowerCase());
       lastStatus = scores[i];
     }
     var char = input.typed[i];
     if (char === ' ') {
       char = '\u00a0';
     }
     contents += char;
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_579412_input_focus.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_579412_input_focus.js
@@ -37,17 +37,22 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the input field is focused when the console is opened.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testInputFocus, false);
 }
 
 function testInputFocus() {
   browser.removeEventListener("DOMContentLoaded", testInputFocus, false);
 
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_580001_closing_after_completion.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_580001_closing_after_completion.js
@@ -38,17 +38,22 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests to ensure that errors don't appear when the console is closed while a
 // completion is being performed.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testClosingAfterCompletion,
                            false);
 }
 
 function testClosingAfterCompletion() {
   browser.removeEventListener("DOMContentLoaded",
                               testClosingAfterCompletion, false);
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_580400_groups.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_580400_groups.js
@@ -37,17 +37,22 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that console groups behave properly.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testGroups, false);
 }
 
 function testGroups() {
   browser.removeEventListener("DOMContentLoaded", testGroups, false);
 
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_582201_duplicate_errors.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_582201_duplicate_errors.js
@@ -38,17 +38,22 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that exceptions thrown by content don't show up twice in the Web
 // Console.
 
 const TEST_DUPLICATE_ERROR_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-duplicate-error.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   expectUncaughtException();
   addTab(TEST_DUPLICATE_ERROR_URI);
   browser.addEventListener("DOMContentLoaded", testDuplicateErrors, false);
 }
 
 function testDuplicateErrors() {
   browser.removeEventListener("DOMContentLoaded", testDuplicateErrors,
                               false);
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_583816_No_input_and_Tab_key_pressed.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_583816_No_input_and_Tab_key_pressed.js
@@ -34,17 +34,22 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//browser/test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testCompletion, false);
 }
 
 function testCompletion() {
   browser.removeEventListener("DOMContentLoaded", testCompletion, false);
 
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_keys.js
@@ -33,17 +33,22 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "data:text/html,<p>bug 585991 - autocomplete popup keyboard usage test";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded() {
   browser.removeEventListener("load", tabLoaded, true);
   openConsole();
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_popup.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_585991_autocomplete_popup.js
@@ -33,17 +33,22 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "data:text/html,<p>bug 585991 - autocomplete popup test";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded() {
   browser.removeEventListener("load", tabLoaded, true);
   openConsole();
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_586388_select_all.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_586388_select_all.js
@@ -5,17 +5,22 @@
  *
  * Contributor(s):
  *  Patrick Walton <pcwalton@mozilla.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "http://example.com/";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded",
                            testSelectionWhenMovingBetweenBoxes, false);
 }
 
 function testSelectionWhenMovingBetweenBoxes() {
   browser.removeEventListener("DOMContentLoaded",
                               testSelectionWhenMovingBetweenBoxes, false);
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_587617_output_copy.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_587617_output_copy.js
@@ -5,17 +5,22 @@
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *  Patrick Walton <pcwalton@mozilla.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded() {
   browser.removeEventListener("load", tabLoaded, true);
   openConsole();
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_588342_document_focus.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_588342_document_focus.js
@@ -6,18 +6,22 @@
  * Contributor(s):
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "data:text/html,Web Console test for bug 588342";
 let fm, notificationBox, input;
 
-function test()
-{
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
+function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoad, true);
 }
 
 function tabLoad(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_588967_input_expansion.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_588967_input_expansion.js
@@ -33,17 +33,22 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testInputExpansion, false);
 }
 
 function testInputExpansion() {
   browser.removeEventListener("DOMContentLoaded", testInputExpansion, false);
 
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_592442_closing_brackets.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_592442_closing_brackets.js
@@ -8,17 +8,22 @@
  *  Patrick Walton <pcwalton@mozilla.com>
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that, when the user types an extraneous closing bracket, no error
 // appears.
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab("data:text/html,test for bug 592442");
   browser.addEventListener("load", testExtraneousClosingBrackets, true);
 }
 
 function testExtraneousClosingBrackets(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_594477_clickable_output.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_594477_clickable_output.js
@@ -149,13 +149,18 @@ function propertyPanelHidden(aEvent) {
 
   executeSoon(function() {
     document.removeEventListener("popupshown", propertyPanelShowFailure, false);
     outputItem = null;
     finishTest();
   });
 }
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoad1, true);
 }
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_594497_history_arrow_keys.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_594497_history_arrow_keys.js
@@ -150,13 +150,18 @@ function performTests() {
 
   ok(!inputNode.value,
      "VK_DOWN: inputNode.value is empty");
 
   inputNode = values = null;
   executeSoon(finishTest);
 }
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab("data:text/html,Web Console test for bug 594497 and bug 619598");
   browser.addEventListener("load", tabLoad, true);
 }
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_595934_message_categories.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_595934_message_categories.js
@@ -167,16 +167,17 @@ function testNext() {
     content.location = testLocation;
   }
   else {
     executeSoon(finish);
   }
 }
 
 function testEnd() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
   Services.console.unregisterListener(TestObserver);
   output.removeEventListener("DOMNodeInserted", onDOMNodeInserted, false);
   output = jsterm = null;
   finishTest();
 }
 
 function onDOMNodeInserted(aEvent) {
   let textContent = output.textContent;
@@ -186,14 +187,15 @@ function onDOMNodeInserted(aEvent) {
   }
 
   if (foundCategory) {
     executeSoon(testNext);
   }
 }
 
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   registerCleanupFunction(testEnd);
 
   addTab("data:text/html,Web Console test for bug 595934 - message categories coverage.");
   browser.addEventListener("load", tabLoad, true);
 }
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_598357_jsterm_output.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_598357_jsterm_output.js
@@ -220,13 +220,18 @@ function testEnd() {
       ok(false, "the property panel failed to show for inputValues[" + i + "]");
     }
   }
 
   eventHandlers = popupshown = null;
   executeSoon(finishTest);
 }
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoad, true);
 }
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_601352_scroll.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_601352_scroll.js
@@ -52,13 +52,18 @@ function tabLoad(aEvent) {
 
     ok(top >= 0 && Math.floor(bottom) <= height + 1,
        "last message is visible");
 
     finishTest();
   });
 }
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab("data:text/html,Web Console test for bug 601352");
   browser.addEventListener("load", tabLoad, true);
 }
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_611795.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_611795.js
@@ -27,22 +27,27 @@ function onContentLoaded()
   let msg = "The console output is repeated 10 times";
   let node = outputNode.querySelector(".webconsole-msg-console");
   is(node.childNodes[3].firstChild.getAttribute("value"), 10, msg);
 
   jsterm.clearOutput();
   finishTest();
 }
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 /**
  * Unit test for bug 611795:
  * Repeated CSS messages get collapsed into one.
  */
 function test()
 {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", function() {
     browser.removeEventListener("load", arguments.callee, true);
 
     openConsole();
     browser.addEventListener("load", onContentLoaded, true);
     content.location.reload();
   }, true);
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_613280_jsterm_copy.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_613280_jsterm_copy.js
@@ -3,17 +3,22 @@
  * http://creativecommons.org/publicdomain/zero/1.0/
  *
  * Contributor(s):
  *   Mihai Șucan <mihai.sucan@gmail.com>
  */
 
 const TEST_URI = "data:text/html,Web Console test for bug 613280";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded() {
   browser.removeEventListener("load", tabLoaded, true);
   openConsole();
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_614793_jsterm_scroll.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_614793_jsterm_scroll.js
@@ -31,13 +31,18 @@ function tabLoad(aEvent) {
   oldScrollTop = boxObject.scrollTop;
   outputNode.scrollBoxObject.ensureElementIsVisible(outputNode.lastChild);
 
   is(boxObject.scrollTop, oldScrollTop, "scroll location is the same");
 
   finishTest();
 }
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab("data:text/html,Web Console test for bug 614793: jsterm result scroll");
   browser.addEventListener("load", tabLoad, true);
 }
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_618311_close_panels.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_618311_close_panels.js
@@ -33,17 +33,22 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", function() {
     browser.removeEventListener("load", arguments.callee, true);
 
     openConsole();
     content.location.reload();
     browser.addEventListener("load", tabLoaded, true);
   }, true);
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_618311_private_browsing.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_618311_private_browsing.js
@@ -36,17 +36,22 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
 let pb = Cc["@mozilla.org/privatebrowsing;1"].
          getService(Ci.nsIPrivateBrowsingService);
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab("data:text/html,Web Console test for bug 618311 (private browsing)");
 
   browser.addEventListener("load", function() {
     browser.removeEventListener("load", arguments.callee, true);
 
     registerCleanupFunction(function() {
       pb.privateBrowsingEnabled = false;
       pb = null;
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_621644_jsterm_dollar.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_621644_jsterm_dollar.js
@@ -37,12 +37,17 @@ function tabLoad(aEvent) {
                      querySelector(".webconsole-msg-output:last-child");
     ok(outputItem.textContent.indexOf("621644") > -1,
        "jsterm output is correct for $$()");
 
     executeSoon(finishTest);
   }, content);
 }
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoad, true);
 }
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_626484_output_copy_order.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_626484_output_copy_order.js
@@ -1,13 +1,18 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 let itemsSet, HUD;
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab("data:text/html,Web Console test for bug 626484");
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
   openConsole();
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_632275_getters_document_width.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_632275_getters_document_width.js
@@ -1,14 +1,19 @@
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-bug-632275-getters.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded() {
   browser.removeEventListener("load", tabLoaded, true);
   openConsole();
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_632347_iterators_generators.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_632347_iterators_generators.js
@@ -33,17 +33,22 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-bug-632347-iterators-generators.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded() {
   browser.removeEventListener("load", tabLoaded, true);
   openConsole();
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_642615_autocomplete.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_642615_autocomplete.js
@@ -71,12 +71,17 @@ function tabLoad(aEvent) {
         goDoCommand("cmd_paste");
       },
       finish);
   }, false);
 
   EventUtils.synthesizeKey("u", {});
 }
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoad, true);
 }
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_644419_log_limits.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_644419_log_limits.js
@@ -7,17 +7,22 @@
 // Tests that the Web Console limits the number of lines displayed according to
 // the limit set for each category.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/" +
                  "webconsole/test/test-bug-644419-log-limits.html";
 
 var gOldPref, gHudId;
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab("data:text/html,Web Console test for bug 644419: Console should " +
          "have user-settable log limits for each message category");
   browser.addEventListener("load", onLoad, true);
 }
 
 function onLoad(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_651501_document_body_autocomplete.js
@@ -3,17 +3,22 @@
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // Tests that document.body autocompletes in the web console.
 
 Cu.import("resource:///modules/PropertyPanel.jsm");
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab("data:text/html,Web Console autocompletion bug in document.body");
   browser.addEventListener("load", onLoad, true);
 }
 
 var gHUD;
 
 function onLoad(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_653531_highlighter_console_helper.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_653531_highlighter_console_helper.js
@@ -128,18 +128,23 @@ function performTestComparisons(evt)
 }
 
 function finishUp() {
   InspectorUI.closeInspectorUI();
   gBrowser.removeCurrentTab();
   finish();
 }
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test()
 {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   waitForExplicitFinish();
   gBrowser.selectedTab = gBrowser.addTab();
   gBrowser.selectedBrowser.addEventListener("load", function() {
     gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
     doc = content.document;
     waitForFocus(createDocument, content);
   }, true);
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_658368_time_methods.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_658368_time_methods.js
@@ -1,17 +1,22 @@
 /* vim:set ts=2 sw=2 sts=2 et: */
 /*
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // Tests that the Console API implements the time() and timeEnd() methods.
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab("http://example.com/browser/browser/devtools/webconsole/" +
          "test/test-bug-658368-time-methods.html");
   openConsole();
   browser.addEventListener("load", onLoad, true);
 }
 
 function onLoad(aEvent) {
   browser.removeEventListener(aEvent.type, onLoad, true);
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_660806_history_nav.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_660806_history_nav.js
@@ -1,15 +1,20 @@
 /* vim:set ts=2 sw=2 sts=2 et: */
 /* Any copyright is dedicated to the Public Domain.
    http://creativecommons.org/publicdomain/zero/1.0/ */
 
 const TEST_URI = "data:text/html,<p>bug 660806 - history navigation must not show the autocomplete popup";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", tabLoaded, true);
 }
 
 function tabLoaded()
 {
   browser.removeEventListener("load", tabLoaded, true);
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_664131_console_group.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_664131_console_group.js
@@ -2,17 +2,22 @@
 /*
  * Any copyright is dedicated to the Public Domain.
  * http://creativecommons.org/publicdomain/zero/1.0/
  */
 
 // Tests that console.group/groupEnd works as intended.
 const GROUP_INDENT = 12;
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab("data:text/html,Web Console test for bug 664131: Expand console " +
          "object with group methods");
   browser.addEventListener("load", onLoad, true);
 }
 
 function onLoad(aEvent) {
   browser.removeEventListener(aEvent.type, arguments.callee, true);
 
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_704295.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_bug_704295.js
@@ -35,17 +35,22 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests for bug 704295
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testCompletion, false);
 }
 
 function testCompletion() {
   browser.removeEventListener("DOMContentLoaded", testCompletion, false);
 
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_chrome.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_chrome.js
@@ -37,17 +37,22 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that code completion works properly.
 
 const TEST_URI = "chrome://browser/content/browser.xul";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testChrome, false);
 }
 
 function testChrome() {
   browser.removeEventListener("DOMContentLoaded", testChrome, false);
 
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_completion.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_completion.js
@@ -37,17 +37,22 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that code completion works properly.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testCompletion, false);
 }
 
 function testCompletion() {
   browser.removeEventListener("DOMContentLoaded", testCompletion, false);
 
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_console_logging_api.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_console_logging_api.js
@@ -37,17 +37,22 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the basic console.log()-style APIs and filtering work.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", onLoad, false);
 }
 
 function onLoad() {
   browser.removeEventListener("DOMContentLoaded", onLoad, false);
 
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_consoleonpage.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_consoleonpage.js
@@ -6,18 +6,23 @@
  * Contributor(s):
  *  Julian Viereck <jviereck@mozilla.com>
  *  Mihai Șucan <mihai.sucan@gmail.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-own-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test()
 {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("load", function() {
     browser.removeEventListener("load", arguments.callee, true);
     testOpenWebConsole();
   }, true);
 }
 
 function testOpenWebConsole()
--- a/browser/devtools/webconsole/test/browser_webconsole_copying_multiple_messages_inserts_newlines_in_between.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_copying_multiple_messages_inserts_newlines_in_between.js
@@ -7,18 +7,23 @@
  *  Patrick Walton <pcwalton@mozilla.com>
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that copying multiple messages inserts newlines in between.
 
 const TEST_URI = "data:text/html,Web Console test for bug 586142";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test()
 {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", onLoad, false);
 }
 
 function onLoad() {
   browser.removeEventListener("DOMContentLoaded", onLoad,
                                                false);
   executeSoon(testNewlines);
--- a/browser/devtools/webconsole/test/browser_webconsole_execution_scope.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_execution_scope.js
@@ -37,17 +37,22 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that commands run by the user are executed in content space.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testExecutionScope, false);
 }
 
 function testExecutionScope() {
   browser.removeEventListener("DOMContentLoaded", testExecutionScope,
                               false);
 
--- a/browser/devtools/webconsole/test/browser_webconsole_history.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_history.js
@@ -41,17 +41,22 @@
 // Tests the console history feature accessed via the up and down arrow keys.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
 // Constants used for defining the direction of JSTerm input history navigation.
 const HISTORY_BACK = -1;
 const HISTORY_FORWARD = 1;
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testHistory, false);
 }
 
 function testHistory() {
   browser.removeEventListener("DOMContentLoaded", testHistory, false);
 
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_hud_getters.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_hud_getters.js
@@ -38,17 +38,22 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the HUD can be accessed via the HUD references in the HUD
 // service.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testHUDGetters, false);
 }
 
 function testHUDGetters() {
   browser.removeEventListener("DOMContentLoaded", testHUDGetters, false);
 
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_js_input_and_output_styling.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_js_input_and_output_styling.js
@@ -38,17 +38,22 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the correct CSS styles are applied to the lines of console
 // output.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testJSInputAndOutputStyling,
                            false);
 }
 
 function testJSInputAndOutputStyling() {
   browser.removeEventListener("DOMContentLoaded",
                               testJSInputAndOutputStyling, false);
--- a/browser/devtools/webconsole/test/browser_webconsole_js_input_expansion.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_js_input_expansion.js
@@ -37,17 +37,22 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that the input box expands as the user types long lines.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testJSInputExpansion, false);
 }
 
 function testJSInputExpansion() {
   browser.removeEventListener("DOMContentLoaded", testJSInputExpansion,
                               false);
 
--- a/browser/devtools/webconsole/test/browser_webconsole_jsterm.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_jsterm.js
@@ -38,17 +38,22 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
 let jsterm;
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testJSTerm, false);
 }
 
 function checkResult(msg, desc, lines) {
   let labels = jsterm.outputNode.querySelectorAll(".webconsole-msg-output");
   is(labels.length, lines, "correct number of results shown for " + desc);
   is(labels[lines-1].textContent.trim(), msg, "correct message shown for " +
--- a/browser/devtools/webconsole/test/browser_webconsole_null_and_undefined_output.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_null_and_undefined_output.js
@@ -38,17 +38,22 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Test that JavaScript expressions that evaluate to null or undefined produce
 // meaningful output.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testNullAndUndefinedOutput,
                            false);
 }
 
 function testNullAndUndefinedOutput() {
   browser.removeEventListener("DOMContentLoaded",
                               testNullAndUndefinedOutput, false);
--- a/browser/devtools/webconsole/test/browser_webconsole_output_order.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_output_order.js
@@ -38,17 +38,22 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests that any output created from calls to the console API comes after the
 // echoed JavaScript.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testOutputOrder, false);
 }
 
 function testOutputOrder() {
   browser.removeEventListener("DOMContentLoaded", testOutputOrder, false);
 
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_property_panel.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_property_panel.js
@@ -38,17 +38,22 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests the functionality of the "property panel", which allows JavaScript
 // objects and DOM nodes to be inspected.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testPropertyPanel, false);
 }
 
 function testPropertyPanel() {
   browser.removeEventListener("DOMContentLoaded", testPropertyPanel, false);
 
   openConsole();
--- a/browser/devtools/webconsole/test/browser_webconsole_property_provider.js
+++ b/browser/devtools/webconsole/test/browser_webconsole_property_provider.js
@@ -38,17 +38,22 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 // Tests the property provider, which is part of the code completion
 // infrastructure.
 
 const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-console.html";
 
+registerCleanupFunction(function() {
+  Services.prefs.clearUserPref("devtools.gcli.enable");
+});
+
 function test() {
+  Services.prefs.setBoolPref("devtools.gcli.enable", false);
   addTab(TEST_URI);
   browser.addEventListener("DOMContentLoaded", testPropertyProvider, false);
 }
 
 function testPropertyProvider() {
   browser.removeEventListener("DOMContentLoaded", testPropertyProvider,
                               false);
 
--- a/browser/installer/package-manifest.in
+++ b/browser/installer/package-manifest.in
@@ -367,18 +367,19 @@
 @BINPATH@/components/nsTelephonyWorker.js
 @BINPATH@/components/Telephony.manifest
 @BINPATH@/components/Telephony.js
 @BINPATH@/components/nsWifiWorker.js
 @BINPATH@/components/nsWifiWorker.manifest
 #endif
 @BINPATH@/components/BrowserProfileMigrators.manifest
 @BINPATH@/components/ChromeProfileMigrator.js
+@BINPATH@/components/FirefoxProfileMigrator.js
 #ifdef XP_MACOSX
-@BINPATH@/components/libalerts_s.dylib
+@BINPATH@/components/libalerts.dylib
 #endif
 #ifdef MOZ_ENABLE_DBUS
 @BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
 #endif
 @BINPATH@/components/nsINIProcessor.manifest
 @BINPATH@/components/nsINIProcessor.js
 @BINPATH@/components/nsPrompter.manifest
 @BINPATH@/components/nsPrompter.js
--- a/browser/installer/removed-files.in
+++ b/browser/installer/removed-files.in
@@ -39,16 +39,19 @@ chrome/toolkit.manifest
 component.reg
 components/browser.manifest
 components/components.list
 components/@DLL_PREFIX@browserdirprovider@DLL_SUFFIX@
 components/@DLL_PREFIX@brwsrdir@DLL_SUFFIX@
 components/@DLL_PREFIX@myspell@DLL_SUFFIX@
 components/@DLL_PREFIX@spellchecker@DLL_SUFFIX@
 components/@DLL_PREFIX@spellchk@DLL_SUFFIX@
+#ifdef XP_MACOSX
+components/libalerts_s.dylib
+#endif
 components/aboutCertError.js
 components/aboutPrivateBrowsing.js
 components/aboutRights.js
 components/aboutRobots.js
 components/aboutSessionRestore.js
 components/autocomplete.xpt
 components/airbag.xpt
 components/bookmarks.xpt
--- a/browser/locales/en-US/chrome/browser/devtools/gcli.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/gcli.properties
@@ -108,17 +108,17 @@ helpManual=Provide help either on a spec
 # parameter to the 'help' command. See helpSearchManual for a fuller
 # description of what it does. This string is designed to be shown in a dialog
 # with restricted space, which is why it should be as short as possible.
 helpSearchDesc=Search string
 
 # LOCALIZATION NOTE (helpSearchManual): A fuller description of the 'search'
 # parameter to the 'help' command. Displayed when the user asks for help on
 # what it does.
-helpSearchManual=A search string to use in narrowing down the list of commands that are displayed to the user. Any part of the string can match, regular expressions are not supported.
+helpSearchManual=A search string to use in narrowing down the list of commands that are displayed to the user. Any part of the command name can match, regular expressions are not supported.
 
 # LOCALIZATION NOTE (helpManSynopsis): A heading shown at the top of a help
 # page for a command in the console It labels a summary of the parameters to
 # the command
 helpManSynopsis=Synopsis
 
 # LOCALIZATION NOTE (helpManDescription): A heading shown in a help page for a
 # command in the console. This heading precedes the top level description.
--- a/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties
+++ b/browser/locales/en-US/chrome/browser/devtools/gclicommands.properties
@@ -50,8 +50,13 @@ inspectManual=Investigate the dimensions
 # 'node' parameter to the 'inspect' command, which is displayed in a dialog
 # when the user is using this command.
 inspectNodeDesc=CSS selector
 
 # LOCALIZATION NOTE (inspectNodeManual) A fuller description of the 'node'
 # parameter to the 'inspect' command, displayed when the user asks for help
 # on what it does.
 inspectNodeManual=A CSS selector for use with Document.querySelector which identifies a single element
+
+# LOCALIZATION NOTE (consolecloseDesc) A very short description of the
+# 'console close' command. This string is designed to be shown in a menu
+# alongside the command name, which is why it should be as short as possible.
+consolecloseDesc=Close the console
--- a/browser/locales/en-US/chrome/browser/migration/migration.dtd
+++ b/browser/locales/en-US/chrome/browser/migration/migration.dtd
@@ -8,16 +8,18 @@
 <!ENTITY importFromIE.label             "Microsoft Internet Explorer">
 <!ENTITY importFromIE.accesskey         "M">
 <!ENTITY importFromNothing.label        "Don't import anything">
 <!ENTITY importFromNothing.accesskey    "D">
 <!ENTITY importFromSafari.label         "Safari">
 <!ENTITY importFromSafari.accesskey     "S">
 <!ENTITY importFromChrome.label         "Chrome">
 <!ENTITY importFromChrome.accesskey     "C">
+<!ENTITY importFromFirefox.label        "Firefox">
+<!ENTITY importFromFirefox.accesskey    "X">
 <!ENTITY importFromHTMLFile.label       "From an HTML File">
 <!ENTITY importFromHTMLFile.accesskey   "F">
 
 <!ENTITY noMigrationSources.label       "No programs that contain bookmarks, history or password data could be found.">
 
 <!ENTITY importSource.title             "Import Settings and Data">
 <!ENTITY importItems.title              "Items to Import">
 <!ENTITY importItems.label              "Select which items to import:">
--- a/browser/locales/en-US/chrome/browser/migration/migration.properties
+++ b/browser/locales/en-US/chrome/browser/migration/migration.properties
@@ -1,43 +1,48 @@
 profileName_format=%S %S
 
 # Browser Specific
 sourceNameIE=Internet Explorer
 sourceNameSafari=Safari
 sourceNameChrome=Google Chrome
+sourceNameFirefox=Mozilla Firefox
 
 importedBookmarksFolder=From %S
 importedSearchURLsFolder=Keyword Searches (From %S)
 importedSearchURLsTitle=Search on %S
 importedSearchUrlDesc=Type "%S <search query>" in the Location Bar to perform a search on %S.
 
 importedSafariBookmarks=From Safari
 
 # Import Sources
 1_ie=Internet Options
 1_safari=Preferences
 1_chrome=Preferences
 
 2_ie=Cookies
 2_safari=Cookies
 2_chrome=Cookies
+2_firefox=Cookies
 
 4_ie=Browsing History
 4_safari=Browsing History
 4_chrome=Browsing History
+4_firefox=Browsing History
 
 8_ie=Saved Form History
 8_safari=Saved Form History
 8_chrome=Saved Form History
 
 16_ie=Saved Passwords
 16_safari=Saved Passwords
 16_chrome=Saved Passwords
+16_firefox=Saved Passwords
 
 32_ie=Favorites
 32_safari=Bookmarks
 32_chrome=Bookmarks
+32_firefox=Bookmarks
 
 64_ie=Other Data
 64_safari=Other Data
 64_chrome=Other Data
 
--- a/browser/themes/gnomestripe/devtools/webconsole.css
+++ b/browser/themes/gnomestripe/devtools/webconsole.css
@@ -62,21 +62,17 @@
 }
 
 /* General output styles */
 
 .webconsole-timestamp {
   color: GrayText;
   margin-top: 0;
   margin-bottom: 0;
-}
-
-.hud-msg-node {
-  list-style-image: url(chrome://browser/skin/devtools/webconsole.png);
-  -moz-image-region: rect(0, 1px, 0, 0);
+  font: 12px "DejaVu Sans Mono", monospace;
 }
 
 .webconsole-msg-icon {
   margin: 3px 4px;
   width: 8px;
   height: 8px;
 }
 
@@ -86,16 +82,19 @@
 }
 
 .webconsole-msg-body {
   margin-top: 0;
   margin-bottom: 3px;
   -moz-margin-start: 3px;
   -moz-margin-end: 6px;
   white-space: pre-wrap;
+  list-style-image: url(chrome://browser/skin/devtools/webconsole.png);
+  -moz-image-region: rect(0, 1px, 0, 0);
+  font: 12px "DejaVu Sans Mono", monospace;
 }
 
 .webconsole-msg-body-piece {
   margin: 0;
 }
 
 .webconsole-msg-url {
   margin: 0 6px;
@@ -128,17 +127,16 @@
   text-align: end;
 }
 
 .hud-msg-node[selected="true"] > .webconsole-timestamp,
 .hud-msg-node[selected="true"] > .webconsole-location {
   color: inherit;
 }
 
-.hud-output-node,
 .jsterm-input-node,
 .jsterm-complete-node {
   font: 12px "DejaVu Sans Mono", monospace;
 }
 
 .hud-output-node {
   -moz-appearance: none;
   border-bottom: 1px solid ThreeDShadow;
--- a/browser/themes/gnomestripe/inspector.css
+++ b/browser/themes/gnomestripe/inspector.css
@@ -152,19 +152,17 @@ code {
 
 .nodeBox.search-selection {
   -moz-user-select: text;
 }
 
 .twisty {
   position: absolute;
   left: 0px;
-  top: 0px;
-  width: 14px;
-  height: 14px;
+  padding: 8px;
 }
 
 .nodeChildBox {
   margin-left: 12px;
   display: none;
 }
 
 .nodeLabel,
--- a/browser/themes/pinstripe/devtools/webconsole.css
+++ b/browser/themes/pinstripe/devtools/webconsole.css
@@ -65,21 +65,17 @@
 }
 
 /* General output styles */
 
 .webconsole-timestamp {
   color: GrayText;
   margin-top: 0;
   margin-bottom: 0;
-}
-
-.hud-msg-node {
-  list-style-image: url(chrome://browser/skin/devtools/webconsole.png);
-  -moz-image-region: rect(0, 1px, 0, 0);
+  font: 11px Menlo, Monaco, monospace;
 }
 
 .webconsole-msg-icon {
   margin: 3px 4px;
   width: 8px;
   height: 8px;
 }
 
@@ -89,16 +85,19 @@
 }
 
 .webconsole-msg-body {
   margin-top: 0;
   margin-bottom: 3px;
   -moz-margin-start: 3px;
   -moz-margin-end: 6px;
   white-space: pre-wrap;
+  list-style-image: url(chrome://browser/skin/devtools/webconsole.png);
+  -moz-image-region: rect(0, 1px, 0, 0);
+  font: 11px Menlo, Monaco, monospace;
 }
 
 .webconsole-msg-body-piece {
   margin: 0;
 }
 
 .webconsole-msg-url {
   margin: 0 6px;
@@ -131,17 +130,16 @@
   text-align: end;
 }
 
 .hud-msg-node[selected="true"] > .webconsole-timestamp,
 .hud-msg-node[selected="true"] > .webconsole-location {
   color: inherit;
 }
 
-.hud-output-node,
 .jsterm-input-node,
 .jsterm-complete-node {
   font: 11px Menlo, Monaco, monospace;
 }
 
 .hud-output-node {
   -moz-appearance: none;
   border-bottom: 1px solid ThreeDShadow;
--- a/browser/themes/winstripe/devtools/webconsole.css
+++ b/browser/themes/winstripe/devtools/webconsole.css
@@ -61,21 +61,17 @@
 }
 
 /* General output styles */
 
 .webconsole-timestamp {
   color: GrayText;
   margin-top: 0;
   margin-bottom: 0;
-}
-
-.hud-msg-node {
-  list-style-image: url(chrome://browser/skin/devtools/webconsole.png);
-  -moz-image-region: rect(0, 1px, 0, 0);
+  font: 12px Consolas, Lucida Console, monospace;
 }
 
 .webconsole-msg-icon {
   margin: 3px 4px;
   width: 8px;
   height: 8px;
 }
 
@@ -85,16 +81,19 @@
 }
 
 .webconsole-msg-body {
   margin-top: 0;
   margin-bottom: 3px;
   -moz-margin-start: 3px;
   -moz-margin-end: 6px;
   white-space: pre-wrap;
+  list-style-image: url(chrome://browser/skin/devtools/webconsole.png);
+  -moz-image-region: rect(0, 1px, 0, 0);
+  font: 12px Consolas, Lucida Console, monospace;
 }
 
 .webconsole-msg-body-piece {
   margin: 0;
 }
 
 .webconsole-msg-url {
   margin: 0 6px;
@@ -127,17 +126,16 @@
   text-align: end;
 }
 
 .hud-msg-node[selected="true"] > .webconsole-timestamp,
 .hud-msg-node[selected="true"] > .webconsole-location {
   color: inherit;
 }
 
-.hud-output-node,
 .jsterm-input-node,
 .jsterm-complete-node {
   font: 12px Consolas, Lucida Console, monospace;
 }
 
 .hud-output-node {
   -moz-appearance: none;
   border-bottom: 1px solid ThreeDShadow;
--- a/build/autoconf/libstdcxx.py
+++ b/build/autoconf/libstdcxx.py
@@ -7,16 +7,17 @@
 
 # We find out both the host and target versions. Since the output
 # will be used from shell, we just print the two assignments and evaluate
 # them from shell.
 
 import os
 import subprocess
 import re
+import sys
 
 re_for_ld = re.compile('.*\((.*)\).*')
 
 def parse_readelf_line(x):
     """Return the version from a readelf line that looks like:
     0x00ec: Rev: 1  Flags: none  Index: 8  Cnt: 2  Name: GLIBCXX_3.4.6
     """
     return x.split(':')[-1].split('_')[-1].strip()
@@ -62,12 +63,24 @@ def find_version(e):
 
     p = subprocess.Popen(['readelf', '-V', libstdcxx], stdout=subprocess.PIPE)
     versions = [parse_readelf_line(x)
                 for x in p.stdout.readlines() if 'Name: GLIBCXX' in x]
     last_version = sorted(versions, cmp = cmp_ver)[-1]
     return encode_ver(last_version)
 
 if __name__ == '__main__':
-    cxx_env = os.environ['CXX']
-    print 'MOZ_LIBSTDCXX_TARGET_VERSION=%s' % find_version(cxx_env)
-    host_cxx_env = os.environ.get('HOST_CXX', cxx_env)
-    print 'MOZ_LIBSTDCXX_HOST_VERSION=%s' % find_version(host_cxx_env)
+    if os.uname()[0] == 'Darwin':
+        sdk_dir = os.environ['MACOS_SDK_DIR']
+        if 'MacOSX10.5.sdk' in sdk_dir:
+            target_ver = 0
+            host_ver = 0
+        else:
+            target_ver = encode_ver('3.4.9')
+            host_ver = encode_ver('3.4.9')
+    else:
+        cxx_env = os.environ['CXX']
+        target_ver = find_version(cxx_env)
+        host_cxx_env = os.environ.get('HOST_CXX', cxx_env)
+        host_ver = find_version(host_cxx_env)
+
+    print 'MOZ_LIBSTDCXX_TARGET_VERSION=%s' % target_ver
+    print 'MOZ_LIBSTDCXX_HOST_VERSION=%s' % host_ver
--- a/build/macosx/common
+++ b/build/macosx/common
@@ -1,2 +1,4 @@
 CC=/usr/bin/gcc-4.2
 CXX=/usr/bin/g++-4.2
+
+ac_add_options --enable-stdcxx-compat
--- a/build/mobile/robocop/FennecNativeDriver.java.in
+++ b/build/mobile/robocop/FennecNativeDriver.java.in
@@ -260,29 +260,34 @@ public class FennecNativeDriver implemen
     }
 
   }
 
   //Takes a filename, loads the file, 
   //  and returns a string version of the entire file.
   public static String getFile(String filename)
   {
-    File file = new File(filename);
     StringBuilder text = new StringBuilder();
 
+    BufferedReader br = null;
     try {
-      BufferedReader br = new BufferedReader(new FileReader(file));
+      br = new BufferedReader(new FileReader(filename));
       String line;
 
       while ((line = br.readLine()) != null) {
         text.append(line);
         text.append('\n');
       }
     } catch(IOException e) {
       e.printStackTrace();
+    } finally {
+      try {
+        br.close();
+      } catch (IOException e) {
+      }
     }
     return text.toString();  
   }
 
   // Takes a string of "key=value" pairs split by \n and creates a hash table.
   public static HashMap convertTextToTable(String data)
   {
     HashMap retVal = new HashMap();
--- a/build/mobile/robocop/FennecNativeElement.java.in
+++ b/build/mobile/robocop/FennecNativeElement.java.in
@@ -72,17 +72,19 @@ public class FennecNativeElement impleme
 
   public void click() {
     final SynchronousQueue syncQueue = new SynchronousQueue();
     mActivity.runOnUiThread(
         new Runnable() {
           public void run() {
             View view = (View)mActivity.findViewById(id);
             if(view != null) {
-              view.performClick();
+              if (!view.performClick()) {
+                Log.w("Robocop", "Robocop called click on an element with no listener");
+              }
             } else {
               throw new RoboCopException("click: unable to find view "+id); 
             }
             syncQueue.offer(new Object());
           }
         });
     try {
       syncQueue.take();
--- a/build/stdc++compat.cpp
+++ b/build/stdc++compat.cpp
@@ -52,16 +52,19 @@
 #define GLIBCXX_VERSION(a, b, c) (((a) << 16) | ((b) << 8) | (c))
 
 namespace std {
 #if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 9)
     /* Instantiate these templates to avoid GLIBCXX_3.4.9 symbol versions */
     template ostream& ostream::_M_insert(double);
     template ostream& ostream::_M_insert(long);
     template ostream& ostream::_M_insert(unsigned long);
+#ifdef DEBUG
+    template ostream& ostream::_M_insert(const void*);
+#endif
     template ostream& __ostream_insert(ostream&, const char*, streamsize);
     template istream& istream::_M_extract(double&);
 #endif
 #if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 14)
     /* Instantiate these templates to avoid GLIBCXX_3.4.14 symbol versions
      * depending on optimization level */
     template char *string::_S_construct_aux_2(size_type, char, allocator<char> const&);
 #ifdef _GLIBCXX_USE_WCHAR_T
--- a/config/Preprocessor.py
+++ b/config/Preprocessor.py
@@ -423,17 +423,17 @@ class Preprocessor:
     if isName:
       try:
         args = str(args)
         if not os.path.isabs(args):
           args = os.path.join(self.context['DIRECTORY'], args)
         args = open(args, 'rU')
       except:
         raise Preprocessor.Error(self, 'FILE_NOT_FOUND', str(args))
-    self.checkLineNumbers = bool(re.search('\.js(?:\.in)?$', args.name))
+    self.checkLineNumbers = bool(re.search('\.(js|java)(?:\.in)?$', args.name))
     oldFile = self.context['FILE']
     oldLine = self.context['LINE']
     oldDir = self.context['DIRECTORY']
     if args.isatty():
       # we're stdin, use '-' and '' for file and dir
       self.context['FILE'] = '-'
       self.context['DIRECTORY'] = ''
     else:
--- a/config/autoconf.mk.in
+++ b/config/autoconf.mk.in
@@ -116,16 +116,18 @@ MOZ_ENABLE_PROFILER_SPS = @MOZ_ENABLE_PR
 MOZ_JPROF       = @MOZ_JPROF@
 MOZ_SHARK       = @MOZ_SHARK@
 MOZ_CALLGRIND   = @MOZ_CALLGRIND@
 MOZ_VTUNE       = @MOZ_VTUNE@
 MOZ_ETW         = @MOZ_ETW@
 MOZ_TRACE_JSCALLS = @MOZ_TRACE_JSCALLS@
 DEHYDRA_PATH    = @DEHYDRA_PATH@
 
+MOZ_LINKER = @MOZ_LINKER@
+MOZ_OLD_LINKER = @MOZ_OLD_LINKER@
 NS_TRACE_MALLOC = @NS_TRACE_MALLOC@
 USE_ELF_DYNSTR_GC = @USE_ELF_DYNSTR_GC@
 USE_ELF_HACK = @USE_ELF_HACK@
 STDCXX_COMPAT = @STDCXX_COMPAT@
 MOZ_LIBSTDCXX_TARGET_VERSION=@MOZ_LIBSTDCXX_TARGET_VERSION@
 MOZ_LIBSTDCXX_HOST_VERSION=@MOZ_LIBSTDCXX_HOST_VERSION@
 INCREMENTAL_LINKER = @INCREMENTAL_LINKER@
 MACOSX_DEPLOYMENT_TARGET = @MACOSX_DEPLOYMENT_TARGET@
--- a/configure.in
+++ b/configure.in
@@ -2460,16 +2460,17 @@ ia64*-hpux*)
 
 *-android*|*-linuxandroid*)
     AC_DEFINE(NO_PW_GECOS)
     no_x=yes
     if test -n "$gonkdir"; then
         _PLATFORM_DEFAULT_TOOLKIT=cairo-gonk
     else
         _PLATFORM_DEFAULT_TOOLKIT=cairo-android
+        MOZ_LINKER=1
     fi
     TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"'
 
     MOZ_GFX_OPTIMIZE_MOBILE=1
     MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-reorder-functions"
     ;;
 
 *-*linux*)
@@ -2894,16 +2895,18 @@ ia64*-hpux*)
     ;;
 
 *-os2*)
     HOST_NSPR_MDCPUCFG='\"md/_os2.cfg\"'
     ;;
 
 esac
 
+AC_SUBST(MOZ_LINKER)
+
 dnl Only one oddball right now (QNX), but this gives us flexibility
 dnl if any other platforms need to override this in the future.
 AC_DEFINE_UNQUOTED(D_INO,$DIRENT_INO)
 
 dnl ========================================================
 dnl Any platform that doesn't have MKSHLIB_FORCE_ALL defined
 dnl by now will not have any way to link most binaries (tests
 dnl as well as viewer, apprunner, etc.), because some symbols
@@ -4054,17 +4057,18 @@ fi
 LDFLAGS="$LDFLAGS $DSO_PIC_CFLAGS $DSO_LDOPTS $MOZ_OPTIMIZE_LDFLAGS"
 AC_CACHE_CHECK(for __thread keyword for TLS variables,
                ac_cv_thread_keyword,
                [AC_TRY_LINK([__thread bool tlsIsMainThread = false;],
                             [return tlsIsMainThread;],
                             ac_cv_thread_keyword=yes,
                             ac_cv_thread_keyword=no)])
 LDFLAGS=$_SAVE_LDFLAGS
-if test "$ac_cv_thread_keyword" = yes; then
+# The custom dynamic linker doesn't support TLS variables
+if test "$ac_cv_thread_keyword" = yes -a "$MOZ_LINKER" != 1; then
   # mips builds fail with TLS variables because of a binutils bug.
   # See bug 528687
   case "${target}" in
     mips*-*)
       :
       ;;
     *-android*|*-linuxandroid*)
       :
@@ -4220,28 +4224,34 @@ dnl ====================================
 dnl = If NSPR was not detected in the system,
 dnl = use the one in the source tree (mozilla/nsprpub)
 dnl ========================================================
 MOZ_ARG_WITH_BOOL(system-nspr,
 [  --with-system-nspr      Use system installed NSPR],
     _USE_SYSTEM_NSPR=1 )
 
 if test -n "$_USE_SYSTEM_NSPR"; then
-    AM_PATH_NSPR(4.8.8, [MOZ_NATIVE_NSPR=1], [AC_MSG_ERROR([your don't have NSPR installed or your version is too old])])
+    AM_PATH_NSPR(4.9.0, [MOZ_NATIVE_NSPR=1], [AC_MSG_ERROR([your don't have NSPR installed or your version is too old])])
 fi
 
 if test -n "$MOZ_NATIVE_NSPR"; then
     _SAVE_CFLAGS=$CFLAGS
     CFLAGS="$CFLAGS $NSPR_CFLAGS"
     AC_TRY_COMPILE([#include "prtypes.h"],
                 [#ifndef PR_STATIC_ASSERT
-                 #error PR_STATIC_ASSERT not defined or requires including prlog.h
+                 #error PR_STATIC_ASSERT not defined or requires including prtypes.h
                  #endif],
                 [MOZ_NATIVE_NSPR=1],
                 AC_MSG_ERROR([system NSPR does not support PR_STATIC_ASSERT or including prtypes.h does not provide it]))
+    AC_TRY_COMPILE([#include "prtypes.h"],
+                [#ifndef PR_UINT64
+                 #error PR_UINT64 not defined or requires including prtypes.h
+                 #endif],
+                [MOZ_NATIVE_NSPR=1],
+                AC_MSG_ERROR([system NSPR does not support PR_UINT64 or including prtypes.h does not provide it]))
     CFLAGS=$_SAVE_CFLAGS
 else
     if test "$OS_ARCH" = "WINNT"; then
         NSPR_CFLAGS="-I${LIBXUL_DIST}/include/nspr"
         if test -n "$GNU_CC"; then
             NSPR_LIBS="-L${LIBXUL_DIST}/lib -lnspr${NSPR_VERSION} -lplc${NSPR_VERSION} -lplds${NSPR_VERSION}"
         else
             NSPR_LIBS="${LIBXUL_DIST}/lib/nspr${NSPR_VERSION}.lib ${LIBXUL_DIST}/lib/plc${NSPR_VERSION}.lib ${LIBXUL_DIST}/lib/plds${NSPR_VERSION}.lib "
@@ -4421,16 +4431,20 @@ CFLAGS=$_SAVE_CFLAGS
 LDFLAGS=$_SAVE_LDFLAGS
 LIBS=$_SAVE_LIBS
 
 if test "${ZLIB_DIR}" -a -d "${ZLIB_DIR}" -a "$SYSTEM_ZLIB" = 1; then
     ZLIB_CFLAGS="-I${ZLIB_DIR}/include"
     ZLIB_LIBS="-L${ZLIB_DIR}/lib ${ZLIB_LIBS}"
 fi
 
+if test "$MOZ_LINKER" = 1 -a "$SYSTEM_ZLIB" != 1; then
+    AC_MSG_ERROR([Custom dynamic linker requires --with-system-zlib])
+fi
+
 dnl system BZIP2 Support
 dnl ========================================================
 MOZ_ARG_WITH_STRING(system-bz2,
 [  --with-system-bz2[=PFX]
                           Use system libbz2 [installed at prefix PFX]],
     BZ2_DIR=$withval)
 
 _SAVE_CFLAGS=$CFLAGS
@@ -4883,30 +4897,32 @@ cairo-uikit)
 cairo-android)
     AC_DEFINE(MOZ_WIDGET_ANDROID)
     MOZ_WIDGET_TOOLKIT=android
     TK_CFLAGS='$(MOZ_CAIRO_CFLAGS)'
     TK_LIBS='$(MOZ_CAIRO_LIBS)'
     MOZ_WEBGL=1
     MOZ_PDF_PRINTING=1
     MOZ_INSTRUMENT_EVENT_LOOP=1
+    MOZ_OLD_LINKER=1
     ;;
 
 cairo-gonk)
     AC_DEFINE(MOZ_WIDGET_GONK)
     MOZ_WIDGET_TOOLKIT=gonk
     TK_CFLAGS='$(MOZ_CAIRO_CFLAGS)'
     TK_LIBS='$(MOZ_CAIRO_LIBS)'
     MOZ_WEBGL=1
     MOZ_PDF_PRINTING=1
     MOZ_B2G_RIL=1
     ;;
 
 esac
 
+AC_SUBST(MOZ_OLD_LINKER)
 AC_SUBST(MOZ_PDF_PRINTING)
 if test "$MOZ_PDF_PRINTING"; then
    PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
    AC_DEFINE(MOZ_PDF_PRINTING)
 fi
 
 if test "$MOZ_ENABLE_XREMOTE"; then
     AC_DEFINE(MOZ_ENABLE_XREMOTE)
@@ -7225,17 +7241,20 @@ AC_SUBST(WIN32_CRT_LIBS)
 dnl Need to set this for make because NSS doesn't have configure
 AC_SUBST(DLLFLAGS)
 
 dnl We need to wrap dlopen and related functions on Android because we use
 dnl our own linker.
 if test "$OS_TARGET" = Android; then
     WRAP_LDFLAGS="${WRAP_LDFLAGS} -L$_objdir/dist/lib -lmozglue"
     if test "$MOZ_WIDGET_TOOLKIT" = android; then
-        WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=dlopen,--wrap=dlclose,--wrap=dlerror,--wrap=dlsym,--wrap=dladdr,--wrap=getaddrinfo,--wrap=freeaddrinfo,--wrap=gai_strerror"
+        if test -n "$MOZ_OLD_LINKER"; then
+            WRAP_LDFLAGS="${WRAP_LDFLAGS} -Wl,--wrap=dlopen,--wrap=dlclose,--wrap=dlerror,--wrap=dlsym,--wrap=dladdr"
+        fi
+        WRAP_LDFLAGS="${WRAP_LDFLAGS} --wrap=getaddrinfo,--wrap=freeaddrinfo,--wrap=gai_strerror"
     fi
 fi
 
 dnl ========================================================
 dnl = Use malloc wrapper lib
 dnl ========================================================
 MOZ_ARG_ENABLE_BOOL(wrap-malloc,
 [  --enable-wrap-malloc    Wrap malloc calls (gnu linker only)],
@@ -7461,17 +7480,17 @@ dnl ====================================
 STDCXX_COMPAT=
 MOZ_ARG_ENABLE_BOOL(stdcxx-compat,
 [  --enable-stdcxx-compat  Enable compatibility with older libstdc++],
     STDCXX_COMPAT=stdc++compat.cpp)
 
 AC_SUBST(STDCXX_COMPAT)
 
 if test -n "$STDCXX_COMPAT"; then
-   eval $(CXX="$CXX" $PYTHON $_topsrcdir/build/autoconf/libstdcxx.py)
+   eval $(CXX="$CXX" MACOS_SDK_DIR="$MACOS_SDK_DIR" $PYTHON $_topsrcdir/build/autoconf/libstdcxx.py)
    AC_SUBST(MOZ_LIBSTDCXX_TARGET_VERSION)
    AC_SUBST(MOZ_LIBSTDCXX_HOST_VERSION)
 fi
 
 dnl ========================================================
 dnl =
 dnl = Profiling and Instrumenting
 dnl =
--- a/content/base/public/Makefile.in
+++ b/content/base/public/Makefile.in
@@ -57,17 +57,16 @@ nsIDocument.h \
 nsDeprecatedOperationList.h \
 nsIDocumentObserver.h \
 nsIMutationObserver.h \
 nsIMutationObserver2.h \
 nsINameSpaceManager.h \
 nsINode.h \
 nsINodeInfo.h \
 nsINodeList.h \
-nsIRange.h \
 nsIRangeUtils.h \
 nsIScriptElement.h \
 nsIStyleSheetLinkingElement.h \
 nsIContentSerializer.h \
 nsIHTMLToTextSink.h \
 nsIXPathEvaluatorInternal.h \
 mozISanitizingSerializer.h \
 nsCaseTreatment.h \
--- a/content/base/public/nsContentCID.h
+++ b/content/base/public/nsContentCID.h
@@ -92,20 +92,16 @@
  {0xb1, 0x58, 0x26, 0xbb, 0x5e, 0x9c, 0x65, 0xe9}}
 #endif
 
 #define NS_NAMESPACEMANAGER_CID                   \
 { /* d9783472-8fe9-11d2-9d3c-0060088f9ff7 */      \
  0xd9783472, 0x8fe9, 0x11d2,                      \
  {0x9d, 0x3c, 0x00, 0x60, 0x08, 0x8f, 0x9f, 0xf7}}
 
-#define NS_RANGE_CID \
-{/* {56AD2981-8A87-11d2-918C-0080C8E44DB5}*/ \
- 0x56ad2981, 0x8a87, 0x11d2, { 0x91, 0x8c, 0x0, 0x80, 0xc8, 0xe4, 0x4d, 0xb5 } }
-
 #define NS_CONTENTITERATOR_CID \
 {/* {a6cf90e3-15b3-11d2-932e-00805f8add32}*/ \
  0xa6cf90e3, 0x15b3, 0x11d2, {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32 } }
 
 #define NS_PRECONTENTITERATOR_CID \
 {/* {80D7E247-D4B8-45d7-BB59-6F1DD56F384C} */ \
  0x80d7e247, 0xd4b8, 0x45d7, { 0xbb, 0x59, 0x6f, 0x1d, 0xd5, 0x6f, 0x38, 0x4c } }
 
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1831,16 +1831,28 @@ public:
    * NOTE: the caller has to make sure autocomplete makes sense for the
    * element's type.
    *
    * @param aInput the input element to check. NOTE: aInput can't be null.
    * @return whether the input element has autocomplete enabled.
    */
   static bool IsAutocompleteEnabled(nsIDOMHTMLInputElement* aInput);
 
+  /**
+   * If the URI is chrome, return true unconditionarlly.
+   *
+   * Otherwise, get the contents of the given pref, and treat it as a
+   * comma-separated list of URIs.  Return true if the given URI's prepath is
+   * in the list, and false otherwise.
+   *
+   * Comparisons are case-insensitive, and whitespace between elements of the
+   * comma-separated list is ignored.
+   */
+  static bool URIIsChromeOrInPref(nsIURI *aURI, const char *aPref);
+
 private:
   static bool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static nsIDOMScriptObjectFactory *GetDOMScriptObjectFactory();
 
   static nsresult HoldScriptObject(PRUint32 aLangID, void* aObject);
--- a/content/base/public/nsDOMFile.h
+++ b/content/base/public/nsDOMFile.h
@@ -53,20 +53,17 @@
 #include "nsIXMLHttpRequest.h"
 #include "prmem.h"
 #include "nsAutoPtr.h"
 #include "mozilla/dom/indexedDB/FileInfo.h"
 #include "mozilla/dom/indexedDB/FileManager.h"
 #include "mozilla/dom/indexedDB/IndexedDatabaseManager.h"
 
 #include "mozilla/GuardObjects.h"
-
-#ifndef PR_UINT64_MAX
-#define PR_UINT64_MAX (~(PRUint64)(0))
-#endif
+#include "mozilla/StdInt.h"
 
 class nsIFile;
 class nsIInputStream;
 class nsIClassInfo;
 class nsIBlobBuilder;
 
 nsresult NS_NewBlobBuilder(nsISupports* *aSupports);
 
@@ -94,17 +91,17 @@ public:
     mContentType.SetIsVoid(false);
   }
 
   nsDOMFileBase(const nsAString& aContentType,
                 PRUint64 aStart, PRUint64 aLength)
     : mIsFile(false), mImmutable(false), mContentType(aContentType),
       mStart(aStart), mLength(aLength)
   {
-    NS_ASSERTION(aLength != PR_UINT64_MAX,
+    NS_ASSERTION(aLength != UINT64_MAX,
                  "Must know length when creating slice");
     // Ensure non-null mContentType by default
     mContentType.SetIsVoid(false);
   }
 
   virtual ~nsDOMFileBase() {}
 
   virtual already_AddRefed<nsIDOMBlob>
@@ -115,17 +112,17 @@ public:
   NS_DECL_NSIDOMBLOB
   NS_DECL_NSIDOMFILE
   NS_DECL_NSIXHRSENDABLE
   NS_DECL_NSIMUTABLE
 
 protected:
   bool IsSizeUnknown()
   {
-    return mLength == PR_UINT64_MAX;
+    return mLength == UINT64_MAX;
   }
 
   virtual bool IsStoredFile()
   {
     return false;
   }
 
   virtual bool IsWholeFile()
@@ -147,29 +144,29 @@ protected:
 };
 
 class nsDOMFileFile : public nsDOMFileBase,
                       public nsIJSNativeInitializer
 {
 public:
   // Create as a file
   nsDOMFileFile(nsIFile *aFile)
-    : nsDOMFileBase(EmptyString(), EmptyString(), PR_UINT64_MAX),
+    : nsDOMFileBase(EmptyString(), EmptyString(), UINT64_MAX),
       mFile(aFile), mWholeFile(true), mStoredFile(false)
   {
     NS_ASSERTION(mFile, "must have file");
     // Lazily get the content type and size
     mContentType.SetIsVoid(true);
     mFile->GetLeafName(mName);
   }
 
   // Create as a blob
   nsDOMFileFile(nsIFile *aFile, const nsAString& aContentType,
                 nsISupports *aCacheToken = nsnull)
-    : nsDOMFileBase(aContentType, PR_UINT64_MAX),
+    : nsDOMFileBase(aContentType, UINT64_MAX),
       mFile(aFile), mWholeFile(true), mStoredFile(false),
       mCacheToken(aCacheToken)
   {
     NS_ASSERTION(mFile, "must have file");
   }
 
   // Create as a stored file
   nsDOMFileFile(const nsAString& aName, const nsAString& aContentType,
@@ -189,17 +186,17 @@ public:
       mFile(aFile), mWholeFile(true), mStoredFile(true)
   {
     NS_ASSERTION(mFile, "must have file");
     mFileInfos.AppendElement(aFileInfo);
   }
 
   // Create as a file to be later initialized
   nsDOMFileFile()
-    : nsDOMFileBase(EmptyString(), EmptyString(), PR_UINT64_MAX),
+    : nsDOMFileBase(EmptyString(), EmptyString(), UINT64_MAX),
       mWholeFile(true), mStoredFile(false)
   {
     // Lazily get the content type and size
     mContentType.SetIsVoid(true);
     mName.SetIsVoid(true);
   }
 
   NS_DECL_ISUPPORTS_INHERITED
--- a/content/base/public/nsIContentIterator.h
+++ b/content/base/public/nsIContentIterator.h
@@ -37,18 +37,16 @@
 
 #ifndef __nsIContentIterator_h___
 #define __nsIContentIterator_h___
 
 #include "nsISupports.h"
 
 class nsINode;
 class nsIDOMRange;
-class nsIRange;
-class nsRange;
 
 #define NS_ICONTENTITERATOR_IID \
 { 0x2550078e, 0xae87, 0x4914, \
  { 0xb3, 0x04, 0xe4, 0xd1, 0x46, 0x19, 0x3d, 0x5f } }
 
 class nsIContentIterator : public nsISupports
 {
 public:
@@ -57,17 +55,16 @@ public:
   /* Initializes an iterator for the subtree rooted by the node aRoot
    */
   virtual nsresult Init(nsINode* aRoot) = 0;
 
   /* Initializes an iterator for the subtree defined by the range aRange
      Subclasses should make sure they implement both of these!
    */
   virtual nsresult Init(nsIDOMRange* aRange) = 0;
-  virtual nsresult Init(nsIRange* aRange) = 0;
 
   /** First will reset the list.
    */
   virtual void First() = 0;
 
   /** Last will reset the list to the end.
    */
   virtual void Last() = 0;
deleted file mode 100644
--- a/content/base/public/nsIRange.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla.org code.
- *
- * The Initial Developer of the Original Code is Mozilla.com.
- * Portions created by the Initial Developer are Copyright (C) 2006
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *         Boris Zbarsky <bzbarsky@mit.edu> (Original Author)
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either the GNU General Public License Version 2 or later (the "GPL"), or
- * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-#ifndef nsIRange_h___
-#define nsIRange_h___
-
-#include "nsISupports.h"
-#include "nsCOMPtr.h"
-#include "nsHashKeys.h"
-#include "nsINode.h"
-#include "nsIDOMRange.h"
-#include "nsTHashtable.h"
-
-// IID for the nsIRange interface
-#define NS_IRANGE_IID \
-{ 0x09dec26b, 0x1ab7, 0x4ff0, \
- { 0xa1, 0x67, 0x7f, 0x22, 0x9c, 0xaa, 0xc3, 0x04 } }
-
-class nsIDOMFontFaceList;
-
-class nsIRange : public nsIDOMRange {
-public:
-  NS_DECLARE_STATIC_IID_ACCESSOR(NS_IRANGE_IID)
-
-  nsIRange()
-    : mRoot(nsnull),
-      mStartOffset(0),
-      mEndOffset(0),
-      mIsPositioned(false),
-      mIsDetached(false),
-      mMaySpanAnonymousSubtrees(false),
-      mInSelection(false)
-  {
-  }
-
-  nsINode* GetRoot() const
-  {
-    return mRoot;
-  }
-
-  nsINode* GetStartParent() const
-  {
-    return mStartParent;
-  }
-
-  nsINode* GetEndParent() const
-  {
-    return mEndParent;
-  }
-
-  PRInt32 StartOffset() const
-  {
-    return mStartOffset;
-  }
-
-  PRInt32 EndOffset() const
-  {
-    return mEndOffset;
-  }
-  
-  bool IsPositioned() const
-  {
-    return mIsPositioned;
-  }
-
-  bool IsDetached() const
-  {
-    return mIsDetached;
-  }
-  
-  bool Collapsed() const
-  {
-    return mIsPositioned && mStartParent == mEndParent &&
-           mStartOffset == mEndOffset;
-  }
-
-  void SetMaySpanAnonymousSubtrees(bool aMaySpanAnonymousSubtrees)
-  {
-    mMaySpanAnonymousSubtrees = aMaySpanAnonymousSubtrees;
-  }
-
-  /**
-   * Return true iff this range is part of at least one Selection object
-   * and isn't detached.
-   */
-  bool IsInSelection() const
-  {
-    return mInSelection;
-  }
-
-  /**
-   * Called when the range is added/removed from a Selection.
-   */
-  void SetInSelection(bool aInSelection)
-  {
-    if (mInSelection == aInSelection || mIsDetached) {
-      return;
-    }
-    mInSelection = aInSelection;
-    nsINode* commonAncestor = GetCommonAncestor();
-    NS_ASSERTION(commonAncestor, "unexpected disconnected nodes");
-    if (mInSelection) {
-      RegisterCommonAncestor(commonAncestor);
-    } else {
-      UnregisterCommonAncestor(commonAncestor);
-    }
-  }
-
-  virtual nsINode* GetCommonAncestor() const = 0;
-
-  virtual void Reset() = 0;
-
-  // XXXbz we could make these non-virtual if a bunch of nsRange stuff
-  // became nsIRange stuff... and if no one outside layout needs them.
-  virtual nsresult SetStart(nsINode* aParent, PRInt32 aOffset) = 0;
-  virtual nsresult SetEnd(nsINode* aParent, PRInt32 aOffset) = 0;
-  virtual nsresult CloneRange(nsIRange** aNewRange) const = 0;
-
-  // Work around hiding warnings
-  NS_IMETHOD SetStart(nsIDOMNode* aParent, PRInt32 aOffset) = 0;
-  NS_IMETHOD SetEnd(nsIDOMNode* aParent, PRInt32 aOffset) = 0;
-  NS_IMETHOD CloneRange(nsIDOMRange** aNewRange) = 0;
-
-  // To support the font inspector API
-  NS_IMETHOD GetUsedFontFaces(nsIDOMFontFaceList** aResult) = 0;
-
-  typedef nsTHashtable<nsPtrHashKey<nsIRange> > RangeHashTable;
-protected:
-  void RegisterCommonAncestor(nsINode* aNode);
-  void UnregisterCommonAncestor(nsINode* aNode);
-  nsINode* IsValidBoundary(nsINode* aNode);
-
-  nsCOMPtr<nsINode> mRoot;
-  nsCOMPtr<nsINode> mStartParent;
-  nsCOMPtr<nsINode> mEndParent;
-  PRInt32 mStartOffset;
-  PRInt32 mEndOffset;
-
-  bool mIsPositioned;
-  bool mIsDetached;
-  bool mMaySpanAnonymousSubtrees;
-  bool mInSelection;
-};
-
-NS_DEFINE_STATIC_IID_ACCESSOR(nsIRange, NS_IRANGE_IID)
-
-#endif /* nsIRange_h___ */
--- a/content/base/public/nsIRangeUtils.h
+++ b/content/base/public/nsIRangeUtils.h
@@ -40,33 +40,33 @@
 /* A class for range utilities. */
 
 #ifndef nsIRangeUtils_h___
 #define nsIRangeUtils_h___
 
 #include "nsISupports.h"
 
 // Forward declarations
-class nsIDOMRange;
+class nsRange;
 class nsIDOMNode;
 class nsIContent;
 
 // IID for the nsIRangeUtils interface
 #define NS_IRANGEUTILS_IID       \
 { 0xa6cf9127, 0x15b3, 0x11d2, {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
 
 class nsIRangeUtils : public nsISupports {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IRANGEUTILS_IID)
 
   NS_IMETHOD_(PRInt32) ComparePoints(nsIDOMNode* aParent1, PRInt32 aOffset1,
                                      nsIDOMNode* aParent2, PRInt32 aOffset2) = 0;
                                
   NS_IMETHOD CompareNodeToRange(nsIContent* aNode, 
-                                nsIDOMRange* aRange,
+                                nsRange* aRange,
                                 bool *outNodeBefore,
                                 bool *outNodeAfter) = 0;
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIRangeUtils, NS_IRANGEUTILS_IID)
 
 #endif /* nsIRangeUtils_h___ */
 
--- a/content/base/public/nsISelectionPrivate.idl
+++ b/content/base/public/nsISelectionPrivate.idl
@@ -35,35 +35,36 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 #include "nsISelectionListener.idl"
 #include "nsIEnumerator.idl"
 #include "nsISelection.idl"
 
-interface nsIDOMRange;
+interface nsRange;
 interface nsIDOMNode;
 interface nsISelectionListener;
 interface nsIContent;
+interface nsINode;
 
 %{C++
 class nsFrameSelection;
 class nsIFrame;
 class nsIPresShell;
 struct nsTextRangeStyle;
 struct nsPoint;
 #include "nsIFrame.h"
-#include "nsCOMArray.h"
+#include "nsTArray.h"
 %}
 
 [ptr] native nsFrameSelection(nsFrameSelection);
 [ptr] native nsIFrame(nsIFrame);
 [ptr] native nsIPresShell(nsIPresShell);
-[ptr] native RangeArray(nsCOMArray<nsIDOMRange>);
+[ptr] native RangeArray(nsTArray<nsRange*>);
 [ref] native constTextRangeStyleRef(const nsTextRangeStyle);
 [ref] native nsPointRef(nsPoint);
 native nsDirection(nsDirection);
 
 [scriptable, uuid(1820a940-6203-4e27-bc94-fa81131722a4)]
 interface nsISelectionPrivate : nsISelection
  {
     const short ENDOFPRECEDINGLINE=0;
@@ -152,19 +153,19 @@ interface nsISelectionPrivate : nsISelec
      */
     void GetRangesForInterval(
         in nsIDOMNode beginNode, in PRInt32 beginOffset,
         in nsIDOMNode endNode, in PRInt32 endOffset,
         in boolean allowAdjacent,
         out PRUint32 resultCount,
         [retval, array, size_is(resultCount)] out nsIDOMRange results);
 
-    [noscript] void GetRangesForIntervalCOMArray(
-        in nsIDOMNode beginNode, in PRInt32 beginOffset,
-        in nsIDOMNode endNode, in PRInt32 endOffset,
+    [noscript] void GetRangesForIntervalArray(
+        in nsINode beginNode, in PRInt32 beginOffset,
+        in nsINode endNode, in PRInt32 endOffset,
         in boolean allowAdjacent,
         in RangeArray results);
 
     /**
      * Scrolls a region of the selection, so that it is visible in
      * the scrolled view.
      *
      * @param aRegion - the region inside the selection to scroll into view
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -53,16 +53,17 @@ EXPORTS		= \
 		nsAttrName.h \
 		nsContentList.h \
 		nsContentSink.h \
 		nsGkAtomList.h \
 		nsGkAtoms.h \
 		nsNodeInfoManager.h \
 		nsNodeUtils.h \
 		nsPropertyTable.h \
+		nsRange.h \
 		nsScriptLoader.h \
 		nsStubDocumentObserver.h \
 		nsStubImageDecoderObserver.h \
 		nsStubMutationObserver.h \
 		nsTextFragment.h \
 		mozAutoDocUpdate.h \
 		nsFrameMessageManager.h \
 		$(NULL)
--- a/content/base/src/nsContentIterator.cpp
+++ b/content/base/src/nsContentIterator.cpp
@@ -124,17 +124,16 @@ public:
   explicit nsContentIterator(bool aPre);
   virtual ~nsContentIterator();
 
   // nsIContentIterator interface methods ------------------------------
 
   virtual nsresult Init(nsINode* aRoot);
 
   virtual nsresult Init(nsIDOMRange* aRange);
-  virtual nsresult Init(nsIRange* aRange);
 
   virtual void First();
 
   virtual void Last();
   
   virtual void Next();
 
   virtual void Prev();
@@ -298,44 +297,36 @@ nsContentIterator::Init(nsINode* aRoot)
   }
 
   mCommonParent = aRoot;
   mCurNode = mFirst;
   RebuildIndexStack();
   return NS_OK;
 }
 
-
 nsresult
-nsContentIterator::Init(nsIDOMRange* aRange)
+nsContentIterator::Init(nsIDOMRange* aDOMRange)
 {
-  nsCOMPtr<nsIRange> range = do_QueryInterface(aRange);
-  return Init(range);
-
-}
-
-nsresult
-nsContentIterator::Init(nsIRange* aRange)
-{
-  NS_ENSURE_ARG_POINTER(aRange);
+  NS_ENSURE_ARG_POINTER(aDOMRange);
+  nsRange* range = static_cast<nsRange*>(aDOMRange);
 
   mIsDone = false;
 
   // get common content parent
-  mCommonParent = aRange->GetCommonAncestor();
+  mCommonParent = range->GetCommonAncestor();
   NS_ENSURE_TRUE(mCommonParent, NS_ERROR_FAILURE);
 
   // get the start node and offset
-  PRInt32 startIndx = aRange->StartOffset();
-  nsINode* startNode = aRange->GetStartParent();
+  PRInt32 startIndx = range->StartOffset();
+  nsINode* startNode = range->GetStartParent();
   NS_ENSURE_TRUE(startNode, NS_ERROR_FAILURE);
 
   // get the end node and offset
-  PRInt32 endIndx = aRange->EndOffset();
-  nsINode* endNode = aRange->GetEndParent();
+  PRInt32 endIndx = range->EndOffset();
+  nsINode* endNode = range->GetEndParent();
   NS_ENSURE_TRUE(endNode, NS_ERROR_FAILURE);
 
   bool startIsData = startNode->IsNodeOfType(nsINode::eDATA_NODE);
 
   // short circuit when start node == end node
   if (startNode == endNode)
   {
     // Check to see if we have a collapsed range, if so,
@@ -1174,17 +1165,16 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsContentSubtreeIterator, nsContentIterator)
 
   // nsContentIterator overrides ------------------------------
 
   virtual nsresult Init(nsINode* aRoot);
 
   virtual nsresult Init(nsIDOMRange* aRange);
-  virtual nsresult Init(nsIRange* aRange);
 
   virtual void Next();
 
   virtual void Prev();
 
   virtual nsresult PositionAt(nsINode* aCurNode);
 
   // Must override these because we don't do PositionAt
@@ -1197,17 +1187,17 @@ protected:
 
   nsresult GetTopAncestorInRange(nsINode *aNode,
                                  nsCOMPtr<nsINode> *outAnestor);
 
   // no copy's or assigns  FIX ME
   nsContentSubtreeIterator(const nsContentSubtreeIterator&);
   nsContentSubtreeIterator& operator=(const nsContentSubtreeIterator&);
 
-  nsCOMPtr<nsIDOMRange> mRange;
+  nsRefPtr<nsRange> mRange;
   // these arrays all typically are used and have elements
 #if 0
   nsAutoTArray<nsIContent*, 8> mStartNodes;
   nsAutoTArray<PRInt32, 8>     mStartOffsets;
 #endif
 
   nsAutoTArray<nsIContent*, 8> mEndNodes;
   nsAutoTArray<PRInt32, 8>     mEndOffsets;
@@ -1216,17 +1206,17 @@ protected:
 NS_IMPL_ADDREF_INHERITED(nsContentSubtreeIterator, nsContentIterator)
 NS_IMPL_RELEASE_INHERITED(nsContentSubtreeIterator, nsContentIterator)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsContentSubtreeIterator)
 NS_INTERFACE_MAP_END_INHERITING(nsContentIterator)
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsContentSubtreeIterator)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsContentSubtreeIterator, nsContentIterator)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRange)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mRange, nsIDOMRange)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsContentSubtreeIterator, nsContentIterator)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRange)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 nsresult NS_NewContentSubtreeIterator(nsIContentIterator** aInstancePtrResult);
 
 
@@ -1263,17 +1253,17 @@ nsresult nsContentSubtreeIterator::Init(
 
 nsresult nsContentSubtreeIterator::Init(nsIDOMRange* aRange)
 {
   if (!aRange) 
     return NS_ERROR_NULL_POINTER; 
 
   mIsDone = false;
 
-  mRange = aRange;
+  mRange = static_cast<nsRange*>(aRange);
   
   // get the start node and offset, convert to nsINode
   nsCOMPtr<nsIDOMNode> commonParent;
   nsCOMPtr<nsIDOMNode> startParent;
   nsCOMPtr<nsIDOMNode> endParent;
   nsCOMPtr<nsINode> nStartP;
   nsCOMPtr<nsINode> nEndP;
   nsCOMPtr<nsINode> n;
@@ -1361,17 +1351,17 @@ nsresult nsContentSubtreeIterator::Init(
   
   firstCandidate = GetDeepFirstChild(firstCandidate, nsnull);
   
   // confirm that this first possible contained node
   // is indeed contained.  Else we have a range that
   // does not fully contain any node.
   
   bool nodeBefore, nodeAfter;
-  if (NS_FAILED(nsRange::CompareNodeToRange(firstCandidate, aRange,
+  if (NS_FAILED(nsRange::CompareNodeToRange(firstCandidate, mRange,
                                             &nodeBefore, &nodeAfter)))
     return NS_ERROR_FAILURE;
 
   if (nodeBefore || nodeAfter)
   {
     MakeEmpty();
     return NS_OK;
   }
@@ -1412,17 +1402,17 @@ nsresult nsContentSubtreeIterator::Init(
   }
   
   lastCandidate = GetDeepLastChild(lastCandidate, nsnull);
   
   // confirm that this last possible contained node
   // is indeed contained.  Else we have a range that
   // does not fully contain any node.
   
-  if (NS_FAILED(nsRange::CompareNodeToRange(lastCandidate, aRange, &nodeBefore,
+  if (NS_FAILED(nsRange::CompareNodeToRange(lastCandidate, mRange, &nodeBefore,
                                             &nodeAfter)))
     return NS_ERROR_FAILURE;
 
   if (nodeBefore || nodeAfter)
   {
     MakeEmpty();
     return NS_OK;
   }
@@ -1433,22 +1423,16 @@ nsresult nsContentSubtreeIterator::Init(
   if (NS_FAILED(GetTopAncestorInRange(lastCandidate, address_of(mLast))))
     return NS_ERROR_FAILURE;
   
   mCurNode = mFirst;
 
   return NS_OK;
 }
 
-nsresult nsContentSubtreeIterator::Init(nsIRange* aRange)
-{
-  nsCOMPtr<nsIDOMRange> range = do_QueryInterface(aRange);
-  return Init(range);
-}
-
 /****************************************************************
  * nsContentSubtreeIterator overrides of ContentIterator routines
  ****************************************************************/
 
 // we can't call PositionAt in a subtree iterator...
 void
 nsContentSubtreeIterator::First()
 {
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -206,16 +206,18 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_
 #include "nsIScriptElement.h"
 #include "nsIContentViewer.h"
 #include "nsIObjectLoadingContent.h"
 
 #include "mozilla/Base64.h"
 #include "mozilla/Preferences.h"
 
 #include "nsWrapperCacheInlines.h"
+#include "nsCharSeparatedTokenizer.h"
+#include "nsUnicharUtils.h"
 
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 using namespace mozilla::widget;
 using namespace mozilla;
 
 const char kLoadAsData[] = "loadAsData";
 
@@ -669,16 +671,50 @@ nsContentUtils::IsAutocompleteEnabled(ns
     }
 
     form->GetAutocomplete(autocomplete);
   }
 
   return autocomplete.EqualsLiteral("on");
 }
 
+bool
+nsContentUtils::URIIsChromeOrInPref(nsIURI *aURI, const char *aPref)
+{
+  if (!aURI) {
+    return false;
+  }
+
+  nsCAutoString scheme;
+  aURI->GetScheme(scheme);
+  if (scheme.EqualsLiteral("chrome")) {
+    return true;
+  }
+
+  nsCAutoString prePathUTF8;
+  aURI->GetPrePath(prePathUTF8);
+  NS_ConvertUTF8toUTF16 prePath(prePathUTF8);
+
+  const nsAdoptingString& whitelist = Preferences::GetString(aPref);
+
+  // This tokenizer also strips off whitespace around tokens, as desired.
+  nsCharSeparatedTokenizer tokenizer(whitelist, ',',
+    nsCharSeparatedTokenizerTemplate<>::SEPARATOR_OPTIONAL);
+
+  while (tokenizer.hasMoreTokens()) {
+    const nsSubstring& whitelistItem = tokenizer.nextToken();
+
+    if (whitelistItem.Equals(prePath, nsCaseInsensitiveStringComparator())) {
+      return true;
+    }
+  }
+
+  return false;
+}
+
 /**
  * Access a cached parser service. Don't addref. We need only one
  * reference to it and this class has that one.
  */
 /* static */
 nsIParserService*
 nsContentUtils::GetParserService()
 {
--- a/content/base/src/nsCopySupport.cpp
+++ b/content/base/src/nsCopySupport.cpp
@@ -306,21 +306,19 @@ nsresult
 nsCopySupport::GetTransferableForNode(nsINode* aNode,
                                       nsIDocument* aDoc,
                                       nsITransferable** aTransferable)
 {
   nsCOMPtr<nsISelection> selection;
   // Make a temporary selection with aNode in a single range.
   nsresult rv = NS_NewDomSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr<nsIDOMRange> range;
-  rv = NS_NewRange(getter_AddRefs(range));
-  NS_ENSURE_SUCCESS(rv, rv);
   nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aNode);
   NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
+  nsRefPtr<nsRange> range = new nsRange();
   rv = range->SelectNode(node);
   NS_ENSURE_SUCCESS(rv, rv);
   rv = selection->AddRange(range);
   NS_ENSURE_SUCCESS(rv, rv);
   // It's not the primary selection - so don't skip invisible content.
   PRUint32 flags = 0;
   return SelectionCopyHelper(selection, aDoc, false, 0, flags,
                              aTransferable);
--- a/content/base/src/nsCrossSiteListenerProxy.cpp
+++ b/content/base/src/nsCrossSiteListenerProxy.cpp
@@ -408,16 +408,40 @@ nsCORSListenerProxy::nsCORSListenerProxy
     mOuterNotificationCallbacks = nsnull;
   }
 }
 
 nsCORSListenerProxy::nsCORSListenerProxy(nsIStreamListener* aOuter,
                                          nsIPrincipal* aRequestingPrincipal,
                                          nsIChannel* aChannel,
                                          bool aWithCredentials,
+                                         bool aAllowDataURI,
+                                         nsresult* aResult)
+  : mOuterListener(aOuter),
+    mRequestingPrincipal(aRequestingPrincipal),
+    mWithCredentials(aWithCredentials && !gDisableCORSPrivateData),
+    mRequestApproved(false),
+    mHasBeenCrossSite(false),
+    mIsPreflight(false)
+{
+  aChannel->GetNotificationCallbacks(getter_AddRefs(mOuterNotificationCallbacks));
+  aChannel->SetNotificationCallbacks(this);
+
+  *aResult = UpdateChannel(aChannel, aAllowDataURI);
+  if (NS_FAILED(*aResult)) {
+    mOuterListener = nsnull;
+    mRequestingPrincipal = nsnull;
+    mOuterNotificationCallbacks = nsnull;
+  }
+}
+
+nsCORSListenerProxy::nsCORSListenerProxy(nsIStreamListener* aOuter,
+                                         nsIPrincipal* aRequestingPrincipal,
+                                         nsIChannel* aChannel,
+                                         bool aWithCredentials,
                                          const nsCString& aPreflightMethod,
                                          const nsTArray<nsCString>& aPreflightHeaders,
                                          nsresult* aResult)
   : mOuterListener(aOuter),
     mRequestingPrincipal(aRequestingPrincipal),
     mWithCredentials(aWithCredentials && !gDisableCORSPrivateData),
     mRequestApproved(false),
     mHasBeenCrossSite(false),
@@ -718,23 +742,33 @@ nsCORSListenerProxy::OnRedirectVerifyCal
   mOldRedirectChannel = nsnull;
   mNewRedirectChannel = nsnull;
   mRedirectCallback->OnRedirectVerifyCallback(result);
   mRedirectCallback   = nsnull;
   return NS_OK;
 }
 
 nsresult
-nsCORSListenerProxy::UpdateChannel(nsIChannel* aChannel)
+nsCORSListenerProxy::UpdateChannel(nsIChannel* aChannel, bool aAllowDataURI)
 {
   nsCOMPtr<nsIURI> uri, originalURI;
   nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
   NS_ENSURE_SUCCESS(rv, rv);
   rv = aChannel->GetOriginalURI(getter_AddRefs(originalURI));
-  NS_ENSURE_SUCCESS(rv, rv);  
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // exempt data URIs from the same origin check.
+  if (aAllowDataURI && originalURI == uri) {
+    bool dataScheme = false;
+    rv = uri->SchemeIs("data", &dataScheme);
+    NS_ENSURE_SUCCESS(rv, rv);
+    if (dataScheme) {
+      return NS_OK;
+    }
+  }
 
   // Check that the uri is ok to load
   rv = nsContentUtils::GetSecurityManager()->
     CheckLoadURIWithPrincipal(mRequestingPrincipal, uri,
                               nsIScriptSecurityManager::STANDARD);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (originalURI != uri) {
--- a/content/base/src/nsCrossSiteListenerProxy.h
+++ b/content/base/src/nsCrossSiteListenerProxy.h
@@ -73,16 +73,22 @@ public:
                       nsIPrincipal* aRequestingPrincipal,
                       nsIChannel* aChannel,
                       bool aWithCredentials,
                       nsresult* aResult);
   nsCORSListenerProxy(nsIStreamListener* aOuter,
                       nsIPrincipal* aRequestingPrincipal,
                       nsIChannel* aChannel,
                       bool aWithCredentials,
+                      bool aAllowDataURI,
+                      nsresult* aResult);
+  nsCORSListenerProxy(nsIStreamListener* aOuter,
+                      nsIPrincipal* aRequestingPrincipal,
+                      nsIChannel* aChannel,
+                      bool aWithCredentials,
                       const nsCString& aPreflightMethod,
                       const nsTArray<nsCString>& aPreflightHeaders,
                       nsresult* aResult);
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIINTERFACEREQUESTOR
@@ -90,17 +96,17 @@ public:
   NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
 
   // Must be called at startup.
   static void Startup();
 
   static void Shutdown();
 
 private:
-  nsresult UpdateChannel(nsIChannel* aChannel);
+  nsresult UpdateChannel(nsIChannel* aChannel, bool aAllowDataURI = false);
   nsresult CheckRequestApproved(nsIRequest* aRequest);
 
   nsCOMPtr<nsIStreamListener> mOuterListener;
   nsCOMPtr<nsIPrincipal> mRequestingPrincipal;
   nsCOMPtr<nsIInterfaceRequestor> mOuterNotificationCallbacks;
   bool mWithCredentials;
   bool mRequestApproved;
   bool mHasBeenCrossSite;
--- a/content/base/src/nsDOMBlobBuilder.cpp
+++ b/content/base/src/nsDOMBlobBuilder.cpp
@@ -41,38 +41,36 @@
 #include "nsDOMFile.h"
 #include "nsIMultiplexInputStream.h"
 #include "nsStringStream.h"
 #include "nsTArray.h"
 #include "nsJSUtils.h"
 #include "nsContentUtils.h"
 #include "CheckedInt.h"
 
-// XXXkhuey shamelessly stolen from VideoUtils.h.  We should patch NSPR.
-#define PR_INT64_MAX (~((PRInt64)(1) << 63))
-#define PR_INT64_MIN (-PR_INT64_MAX - 1)
+#include "mozilla/StdInt.h"
 
 using namespace mozilla;
 
 class nsDOMMultipartFile : public nsDOMFileBase
 {
 public:
   // Create as a file
   nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> > aBlobs,
                      const nsAString& aName,
                      const nsAString& aContentType)
-    : nsDOMFileBase(aName, aContentType, PR_UINT64_MAX),
+    : nsDOMFileBase(aName, aContentType, UINT64_MAX),
       mBlobs(aBlobs)
   {
   }
 
   // Create as a blob
   nsDOMMultipartFile(nsTArray<nsCOMPtr<nsIDOMBlob> > aBlobs,
                      const nsAString& aContentType)
-    : nsDOMFileBase(aContentType, PR_UINT64_MAX),
+    : nsDOMFileBase(aContentType, UINT64_MAX),
       mBlobs(aBlobs)
   {
   }
 
   already_AddRefed<nsIDOMBlob>
   CreateSlice(PRUint64 aStart, PRUint64 aLength, const nsAString& aContentType);
 
   NS_IMETHOD GetSize(PRUint64*);
@@ -80,17 +78,17 @@ public:
 
 protected:
   nsTArray<nsCOMPtr<nsIDOMBlob> > mBlobs;
 };
 
 NS_IMETHODIMP
 nsDOMMultipartFile::GetSize(PRUint64* aLength)
 {
-  if (mLength == PR_UINT64_MAX) {
+  if (mLength == UINT64_MAX) {
     CheckedUint64 length = 0;
   
     PRUint32 i;
     PRUint32 len = mBlobs.Length();
     for (i = 0; i < len; i++) {
       nsIDOMBlob* blob = mBlobs.ElementAt(i).get();
       PRUint64 l = 0;
   
--- a/content/base/src/nsDocumentEncoder.cpp
+++ b/content/base/src/nsDocumentEncoder.cpp
@@ -57,17 +57,17 @@
 #include "nsIOutputStream.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMText.h"
 #include "nsIDOMCDATASection.h"
 #include "nsIDOMComment.h"
 #include "nsIDOMProcessingInstruction.h"
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMNodeList.h"
-#include "nsIRange.h"
+#include "nsRange.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMDocument.h"
 #include "nsICharsetConverterManager.h"
 #include "nsGkAtoms.h"
 #include "nsIContent.h"
 #include "nsIEnumerator.h"
 #include "nsIParserService.h"
 #include "nsIScriptContext.h"
@@ -108,19 +108,19 @@ protected:
                               nsINode* aOriginalNode = nsnull);
   nsresult SerializeToStringRecursive(nsINode* aNode,
                                       nsAString& aStr,
                                       bool aDontSerializeRoot);
   nsresult SerializeNodeEnd(nsINode* aNode, nsAString& aStr);
   // This serializes the content of aNode.
   nsresult SerializeToStringIterative(nsINode* aNode,
                                       nsAString& aStr);
-  nsresult SerializeRangeToString(nsIRange *aRange,
+  nsresult SerializeRangeToString(nsRange *aRange,
                                   nsAString& aOutputString);
-  nsresult SerializeRangeNodes(nsIRange* aRange, 
+  nsresult SerializeRangeNodes(nsRange* aRange, 
                                nsINode* aNode, 
                                nsAString& aString,
                                PRInt32 aDepth);
   nsresult SerializeRangeContextStart(const nsTArray<nsINode*>& aAncestorArray,
                                       nsAString& aString);
   nsresult SerializeRangeContextEnd(const nsTArray<nsINode*>& aAncestorArray,
                                     nsAString& aString);
 
@@ -150,17 +150,17 @@ protected:
   }
 
   static bool IsTag(nsIContent* aContent, nsIAtom* aAtom);
   
   virtual bool IncludeInContext(nsINode *aNode);
 
   nsCOMPtr<nsIDocument>          mDocument;
   nsCOMPtr<nsISelection>         mSelection;
-  nsCOMPtr<nsIRange>             mRange;
+  nsRefPtr<nsRange>              mRange;
   nsCOMPtr<nsINode>              mNode;
   nsCOMPtr<nsIOutputStream>      mStream;
   nsCOMPtr<nsIContentSerializer> mSerializer;
   nsCOMPtr<nsIUnicodeEncoder>    mUnicodeEncoder;
   nsCOMPtr<nsINode>              mCommonParent;
   nsCOMPtr<nsIDocumentEncoderNodeFixup> mNodeFixup;
   nsCOMPtr<nsICharsetConverterManager> mCharsetConverterManager;
 
@@ -199,17 +199,17 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ns
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mRange)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNode)
   NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mCommonParent)
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDocumentEncoder)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mDocument)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSelection)
-  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRange)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mRange, nsIDOMRange)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNode)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCommonParent)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 nsDocumentEncoder::nsDocumentEncoder() : mCachedBuffer(nsnull)
 {
   Initialize();
   mMimeType.AssignLiteral("text/plain");
@@ -284,17 +284,17 @@ nsDocumentEncoder::SetSelection(nsISelec
 {
   mSelection = aSelection;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocumentEncoder::SetRange(nsIDOMRange* aRange)
 {
-  mRange = do_QueryInterface(aRange);
+  mRange = static_cast<nsRange*>(aRange);
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDocumentEncoder::SetNode(nsIDOMNode* aNode)
 {
   mNodeIsContainer = false;
   mNode = do_QueryInterface(aNode);
@@ -761,17 +761,17 @@ static nsresult GetLengthOfDOMNode(nsIDO
         nodeList->GetLength(&aCount);
       }
     }
   }
   return result;
 }
 
 nsresult
-nsDocumentEncoder::SerializeRangeNodes(nsIRange* aRange,
+nsDocumentEncoder::SerializeRangeNodes(nsRange* aRange,
                                        nsINode* aNode,
                                        nsAString& aString,
                                        PRInt32 aDepth)
 {
   nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
   NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
 
   if (!IsVisibleNode(aNode))
@@ -932,17 +932,17 @@ nsDocumentEncoder::SerializeRangeContext
         break;
     }
   }
 
   return rv;
 }
 
 nsresult
-nsDocumentEncoder::SerializeRangeToString(nsIRange *aRange,
+nsDocumentEncoder::SerializeRangeToString(nsRange *aRange,
                                           nsAString& aOutputString)
 {
   if (!aRange || aRange->Collapsed())
     return NS_OK;
 
   mCommonParent = aRange->GetCommonAncestor();
 
   if (!mCommonParent)
@@ -1074,17 +1074,17 @@ nsDocumentEncoder::EncodeToString(nsAStr
         if (content && content->Tag() == nsGkAtoms::tr) {
           nsCOMPtr<nsINode> n = do_QueryInterface(node);
           rv = SerializeNodeStart(n, 0, -1, output);
           NS_ENSURE_SUCCESS(rv, rv);
           prevNode = node;
         }
       }
 
-      nsCOMPtr<nsIRange> r = do_QueryInterface(range);
+      nsRange* r = static_cast<nsRange*>(range.get());
       rv = SerializeRangeToString(r, output);
       NS_ENSURE_SUCCESS(rv, rv);
     }
     if (prevNode) {
       nsCOMPtr<nsINode> p = do_QueryInterface(prevNode);
       rv = SerializeNodeEnd(p, output);
       NS_ENSURE_SUCCESS(rv, rv);
     }
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -33,17 +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 "ContentChild.h"
 #include "ContentParent.h"
-#include "jscntxt.h"
 #include "nsFrameMessageManager.h"
 #include "nsContentUtils.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
 #include "nsJSUtils.h"
 #include "nsNetUtil.h"
 #include "nsScriptLoader.h"
 #include "nsIJSContextStack.h"
@@ -420,17 +419,17 @@ nsFrameMessageManager::ReceiveMessage(ns
           // Because we want JS messages to have always the same properties,
           // create array even if len == 0.
           aObjectsArray = JS_NewArrayObject(ctx, 0, NULL);
           if (!aObjectsArray) {
             return NS_ERROR_OUT_OF_MEMORY;
           }
         }
 
-        js::AutoValueRooter objectsv(ctx);
+        JS::AutoValueRooter objectsv(ctx);
         objectsv.set(OBJECT_TO_JSVAL(aObjectsArray));
         if (!JS_WrapValue(ctx, objectsv.jsval_addr()))
             return NS_ERROR_UNEXPECTED;
 
         jsval json = JSVAL_NULL;
         if (!aJSON.IsEmpty()) {
           if (!JS_ParseJSON(ctx, static_cast<const jschar*>(PromiseFlatString(aJSON).get()),
                             aJSON.Length(), &json)) {
@@ -476,17 +475,17 @@ nsFrameMessageManager::ReceiveMessage(ns
                           !JSVAL_IS_NULL(funval));
           JSObject* funobject = JSVAL_TO_OBJECT(funval);
           NS_ENSURE_STATE(JS_ObjectIsCallable(ctx, funobject));
           thisValue = OBJECT_TO_JSVAL(object);
         }
 
         jsval rval = JSVAL_VOID;
 
-        js::AutoValueRooter argv(ctx);
+        JS::AutoValueRooter argv(ctx);
         argv.set(OBJECT_TO_JSVAL(param));
 
         {
           JSAutoEnterCompartment tac;
 
           JSObject* thisObject = JSVAL_TO_OBJECT(thisValue);
 
           if (!tac.enter(ctx, thisObject) ||
--- a/content/base/src/nsGenericElement.cpp
+++ b/content/base/src/nsGenericElement.cpp
@@ -87,17 +87,17 @@
 #include "nsNodeUtils.h"
 #include "nsDocument.h"
 #ifdef MOZ_XUL
 #include "nsXULElement.h"
 #endif /* MOZ_XUL */
 #include "nsFrameManager.h"
 #include "nsFrameSelection.h"
 #ifdef DEBUG
-#include "nsIRange.h"
+#include "nsRange.h"
 #endif
 
 #include "nsBindingManager.h"
 #include "nsXBLBinding.h"
 #include "nsIXBLService.h"
 #include "nsPIDOMWindow.h"
 #include "nsPIBoxObject.h"
 #include "nsClientRect.h"
@@ -150,16 +150,17 @@
 #include "nsCSSParser.h"
 #include "prprf.h"
 
 #include "nsSVGFeatures.h"
 #include "nsDOMMemoryReporter.h"
 #include "nsWrapperCacheInlines.h"
 
 #include "xpcpublic.h"
+#include "xpcprivate.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_DEFINE_IID(kThisPtrOffsetsSID, NS_THISPTROFFSETS_SID);
 
 PRInt32 nsIContent::sTabFocusModel = eTabFocus_any;
 bool nsIContent::sTabFocusModelAppliesToXUL = false;
@@ -4969,18 +4970,18 @@ nsGenericElement::List(FILE* out, PRInt3
 
   fprintf(out, "@%p", (void *)this);
 
   ListAttributes(out);
 
   fprintf(out, " state=[%llx]", State().GetInternalValue());
   fprintf(out, " flags=[%08x]", static_cast<unsigned int>(GetFlags()));
   if (IsCommonAncestorForRangeInSelection()) {
-    nsIRange::RangeHashTable* ranges =
-      static_cast<nsIRange::RangeHashTable*>(GetProperty(nsGkAtoms::range));
+    nsRange::RangeHashTable* ranges =
+      static_cast<nsRange::RangeHashTable*>(GetProperty(nsGkAtoms::range));
     fprintf(out, " ranges:%d", ranges ? ranges->Count() : 0);
   }
   fprintf(out, " primaryframe=%p", static_cast<void*>(GetPrimaryFrame()));
   fprintf(out, " refcount=%d<", mRefCnt.get());
 
   nsIContent* child = GetFirstChild();
   if (child) {
     fputs("\n", out);
--- a/content/base/src/nsGkAtomList.h
+++ b/content/base/src/nsGkAtomList.h
@@ -163,16 +163,17 @@ GK_ATOM(bottompadding, "bottompadding")
 GK_ATOM(bottomright, "bottomright")
 GK_ATOM(box, "box")
 GK_ATOM(br, "br")
 GK_ATOM(braille, "braille")
 GK_ATOM(broadcast, "broadcast")
 GK_ATOM(broadcaster, "broadcaster")
 GK_ATOM(broadcasterset, "broadcasterset")
 GK_ATOM(browser, "browser")
+GK_ATOM(mozbrowser, "mozbrowser")
 GK_ATOM(bulletinboard, "bulletinboard")
 GK_ATOM(button, "button")
 GK_ATOM(callTemplate, "call-template")
 GK_ATOM(cancel, "cancel")
 GK_ATOM(canvas, "canvas")
 GK_ATOM(caption, "caption")
 GK_ATOM(capture, "capture")
 GK_ATOM(caseOrder, "case-order")
@@ -1531,46 +1532,42 @@ GK_ATOM(logbase_, "logbase")
 GK_ATOM(log_, "log")
 GK_ATOM(longdivstyle_, "longdivstyle")
 GK_ATOM(lowlimit_, "lowlimit")
 GK_ATOM(lquote_, "lquote")
 GK_ATOM(lspace_, "lspace")
 GK_ATOM(lt_, "lt")
 GK_ATOM(maction_, "maction")
 GK_ATOM(maligngroup_, "maligngroup")
-GK_ATOM(malign_, "malign")
 GK_ATOM(malignmark_, "malignmark")
-GK_ATOM(malignscope_, "malignscope")
 GK_ATOM(mathbackground_, "mathbackground")
 GK_ATOM(mathcolor_, "mathcolor")
 GK_ATOM(mathsize_, "mathsize")
 GK_ATOM(mathvariant_, "mathvariant")
 GK_ATOM(matrixrow_, "matrixrow")
 GK_ATOM(maxsize_, "maxsize")
 GK_ATOM(mean_, "mean")
 GK_ATOM(median_, "median")
 GK_ATOM(mediummathspace_, "mediummathspace")
 GK_ATOM(menclose_, "menclose")
 GK_ATOM(merror_, "merror")
 GK_ATOM(mfenced_, "mfenced")
 GK_ATOM(mfrac_, "mfrac")
-GK_ATOM(mfraction_, "mfraction")
 GK_ATOM(mglyph_, "mglyph")
 GK_ATOM(mi_, "mi")
 GK_ATOM(minlabelspacing_, "minlabelspacing")
 GK_ATOM(minsize_, "minsize")
 GK_ATOM(minus_, "minus")
 GK_ATOM(mlabeledtr_, "mlabeledtr")
 GK_ATOM(mlongdiv_, "mlongdiv")
 GK_ATOM(mmultiscripts_, "mmultiscripts")
 GK_ATOM(mn_, "mn")
 GK_ATOM(momentabout_, "momentabout")
 GK_ATOM(moment_, "moment")
 GK_ATOM(mo_, "mo")
-GK_ATOM(monospaced_, "monospaced")
 GK_ATOM(movablelimits_, "movablelimits")
 GK_ATOM(mover_, "mover")
 GK_ATOM(mpadded_, "mpadded")
 GK_ATOM(mphantom_, "mphantom")
 GK_ATOM(mprescripts_, "mprescripts")
 GK_ATOM(mroot_, "mroot")
 GK_ATOM(mrow_, "mrow")
 GK_ATOM(mscarries_, "mscarries")
--- a/content/base/src/nsRange.cpp
+++ b/content/base/src/nsRange.cpp
@@ -114,29 +114,17 @@ static void InvalidateAllFrames(nsINode*
 // If outNodeBefore is returned true, then the node starts before the range does.
 // If outNodeAfter is returned true, then the node ends after the range does.
 // Note that both of the above might be true.
 // If neither are true, the node is contained inside of the range.
 // XXX - callers responsibility to ensure node in same doc as range! 
 
 // static
 nsresult
-nsRange::CompareNodeToRange(nsINode* aNode, nsIDOMRange* aRange,
-                            bool *outNodeBefore, bool *outNodeAfter)
-{
-  nsresult rv;
-  nsCOMPtr<nsIRange> range = do_QueryInterface(aRange, &rv);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  return CompareNodeToRange(aNode, range, outNodeBefore, outNodeAfter);
-}
-
-// static
-nsresult
-nsRange::CompareNodeToRange(nsINode* aNode, nsIRange* aRange,
+nsRange::CompareNodeToRange(nsINode* aNode, nsRange* aRange,
                             bool *outNodeBefore, bool *outNodeAfter)
 {
   NS_ENSURE_STATE(aNode);
   // create a pair of dom points that expresses location of node:
   //     NODE(start), NODE(end)
   // Let incoming range be:
   //    {RANGE(start), RANGE(end)}
   // if (RANGE(start) <= NODE(start))  and (RANGE(end) => NODE(end))
@@ -181,25 +169,25 @@ nsRange::CompareNodeToRange(nsINode* aNo
                                                 &disconnected) < 0;
   NS_ENSURE_TRUE(!disconnected, NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
   return NS_OK;
 }
 
 struct FindSelectedRangeData
 {
   nsINode*  mNode;
-  nsIRange* mResult;
+  nsRange* mResult;
   PRUint32  mStartOffset;
   PRUint32  mEndOffset;
 };
 
 static PLDHashOperator
-FindSelectedRange(nsPtrHashKey<nsIRange>* aEntry, void* userArg)
+FindSelectedRange(nsPtrHashKey<nsRange>* aEntry, void* userArg)
 {
-  nsIRange* range = aEntry->GetKey();
+  nsRange* range = aEntry->GetKey();
   if (range->IsInSelection() && !range->Collapsed()) {
     FindSelectedRangeData* data = static_cast<FindSelectedRangeData*>(userArg);
     PRInt32 cmp = nsContentUtils::ComparePoints(data->mNode, data->mEndOffset,
                                                 range->GetStartParent(),
                                                 range->StartOffset());
     if (cmp == 1) {
       cmp = nsContentUtils::ComparePoints(data->mNode, data->mStartOffset,
                                           range->GetEndParent(),
@@ -280,41 +268,24 @@ nsRangeUtils::ComparePoints(nsIDOMNode* 
   nsCOMPtr<nsINode> parent2 = do_QueryInterface(aParent2);
 
   NS_ENSURE_TRUE(parent1 && parent2, -1);
 
   return nsContentUtils::ComparePoints(parent1, aOffset1, parent2, aOffset2);
 }
 
 NS_IMETHODIMP
-nsRangeUtils::CompareNodeToRange(nsIContent* aNode, nsIDOMRange* aRange,
+nsRangeUtils::CompareNodeToRange(nsIContent* aNode, nsRange* aRange,
                                  bool *outNodeBefore, bool *outNodeAfter)
 {
   return nsRange::CompareNodeToRange(aNode, aRange, outNodeBefore,
                                      outNodeAfter);
 }
 
 /******************************************************
- * non members
- ******************************************************/
-
-nsresult
-NS_NewRange(nsIDOMRange** aResult)
-{
-  NS_ENSURE_ARG_POINTER(aResult);
-
-  nsRange * range = new nsRange();
-  if (!range) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
-
-  return CallQueryInterface(range, aResult);
-}
-
-/******************************************************
  * constructor/destructor
  ******************************************************/
 
 nsRange::~nsRange() 
 {
   NS_ASSERTION(!IsInSelection(), "deleting nsRange that is in use");
 
   // we want the side effects (releases and list removals)
@@ -330,20 +301,18 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(nsRange)
 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsRange)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsRange)
 
 DOMCI_DATA(Range, nsRange)
 
 // QueryInterface implementation for nsRange
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsRange)
   NS_INTERFACE_MAP_ENTRY(nsIDOMRange)
-  NS_INTERFACE_MAP_ENTRY(nsIRange)
-  NS_INTERFACE_MAP_ENTRY(nsIDOMNSRange)
   NS_INTERFACE_MAP_ENTRY(nsIMutationObserver)
-  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIRange)
+  NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMRange)
   NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Range)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsRange)
   tmp->Reset();
 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
 
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsRange)
@@ -351,18 +320,18 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEndParent)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRoot)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 static void
 RangeHashTableDtor(void* aObject, nsIAtom* aPropertyName, void* aPropertyValue,
                    void* aData)
 {
-  nsIRange::RangeHashTable* ranges =
-    static_cast<nsIRange::RangeHashTable*>(aPropertyValue);
+  nsRange::RangeHashTable* ranges =
+    static_cast<nsRange::RangeHashTable*>(aPropertyValue);
   delete ranges;
 }
 
 static void MarkDescendants(nsINode* aNode)
 {
   // Set NodeIsDescendantOfCommonAncestorForRangeInSelection on aNode's
   // descendants unless aNode is already marked as a range common ancestor
   // or a descendant of one, in which case all of our descendants have the
@@ -399,17 +368,17 @@ static void UnmarkDescendants(nsINode* a
         // We found an ancestor of an overlapping range, skip its descendants.
         node = node->GetNextNonChildNode(aNode);
       }
     }
   }
 }
 
 void
-nsIRange::RegisterCommonAncestor(nsINode* aNode)
+nsRange::RegisterCommonAncestor(nsINode* aNode)
 {
   NS_PRECONDITION(aNode, "bad arg");
   NS_ASSERTION(IsInSelection(), "registering range not in selection");
 
   MarkDescendants(aNode);
 
   RangeHashTable* ranges =
     static_cast<RangeHashTable*>(aNode->GetProperty(nsGkAtoms::range));
@@ -418,17 +387,17 @@ nsIRange::RegisterCommonAncestor(nsINode
     ranges->Init();
     aNode->SetProperty(nsGkAtoms::range, ranges, RangeHashTableDtor, true);
   }
   ranges->PutEntry(this);
   aNode->SetCommonAncestorForRangeInSelection();
 }
 
 void
-nsIRange::UnregisterCommonAncestor(nsINode* aNode)
+nsRange::UnregisterCommonAncestor(nsINode* aNode)
 {
   NS_PRECONDITION(aNode, "bad arg");
   NS_ASSERTION(aNode->IsCommonAncestorForRangeInSelection(), "wrong node");
   RangeHashTable* ranges =
     static_cast<RangeHashTable*>(aNode->GetProperty(nsGkAtoms::range));
   NS_ASSERTION(ranges->GetEntry(this), "unknown range");
 
   if (ranges->Count() == 1) {
@@ -660,19 +629,19 @@ nsRange::ParentChainChanged(nsIContent *
   NS_ASSERTION(newRoot, "No valid boundary or root found!");
   NS_ASSERTION(newRoot == IsValidBoundary(mEndParent),
                "Start parent and end parent give different root!");
   // This is safe without holding a strong ref to self as long as the change
   // of mRoot is the last thing in DoSetRange.
   DoSetRange(mStartParent, mStartOffset, mEndParent, mEndOffset, newRoot);
 }
 
-/********************************************************
- * Utilities for comparing points: API from nsIDOMNSRange
- ********************************************************/
+/******************************************************
+ * Utilities for comparing points: API from nsIDOMRange
+ ******************************************************/
 NS_IMETHODIMP
 nsRange::IsPointInRange(nsIDOMNode* aParent, PRInt32 aOffset, bool* aResult)
 {
   PRInt16 compareResult = 0;
   nsresult rv = ComparePoint(aParent, aOffset, &compareResult);
   // If the node isn't in the range's document, it clearly isn't in the range.
   if (rv == NS_ERROR_DOM_WRONG_DOCUMENT_ERR) {
     *aResult = false;
@@ -815,29 +784,25 @@ IndexOf(nsIDOMNode* aChildNode)
   }
 
   nsINode *parent = child->GetNodeParent();
 
   // finally we get the index
   return parent ? parent->IndexOf(child) : -1;
 }
 
-/******************************************************
- * nsIRange implementation
- ******************************************************/
-
-/* virtual */ nsINode*
+nsINode*
 nsRange::GetCommonAncestor() const
 {
   return mIsPositioned ?
     nsContentUtils::GetCommonAncestor(mStartParent, mEndParent) :
     nsnull;
 }
 
-/* virtual */ void
+void
 nsRange::Reset()
 {
   DoSetRange(nsnull, 0, nsnull, 0, nsnull);
 }
 
 /******************************************************
  * public functionality
  ******************************************************/
@@ -907,17 +872,18 @@ nsRange::GetCommonAncestorContainer(nsID
   nsINode* container = nsContentUtils::GetCommonAncestor(mStartParent, mEndParent);
   if (container) {
     return CallQueryInterface(container, aCommonParent);
   }
 
   return NS_ERROR_NOT_INITIALIZED;
 }
 
-nsINode* nsIRange::IsValidBoundary(nsINode* aNode)
+nsINode*
+nsRange::IsValidBoundary(nsINode* aNode)
 {
   if (!aNode) {
     return nsnull;
   }
 
   if (aNode->IsNodeOfType(nsINode::eCONTENT)) {
     nsIContent* content = static_cast<nsIContent*>(aNode);
     if (content->Tag() == nsGkAtoms::documentTypeNodeName) {
@@ -1795,17 +1761,17 @@ nsRange::ExtractContents(nsIDOMDocumentF
   NS_ENSURE_ARG_POINTER(aReturn);
   return CutContents(aReturn);
 }
 
 NS_IMETHODIMP
 nsRange::CompareBoundaryPoints(PRUint16 aHow, nsIDOMRange* aOtherRange,
                                PRInt16* aCmpRet)
 {
-  nsCOMPtr<nsIRange> otherRange = do_QueryInterface(aOtherRange);
+  nsRange* otherRange = static_cast<nsRange*>(aOtherRange);
   NS_ENSURE_TRUE(otherRange, NS_ERROR_NULL_POINTER);
 
   if(mIsDetached || otherRange->IsDetached())
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   if (!mIsPositioned || !otherRange->IsPositioned())
     return NS_ERROR_NOT_INITIALIZED;
 
   nsINode *ourNode, *otherNode;
@@ -2091,52 +2057,45 @@ nsRange::CloneContents(nsIDOMDocumentFra
   }
 
   *aReturn = clonedFrag;
   NS_IF_ADDREF(*aReturn);
 
   return NS_OK;
 }
 
-nsresult nsRange::DoCloneRange(nsIRange** aReturn) const
+nsresult
+nsRange::CloneRange(nsRange** aReturn) const
 {
   if(mIsDetached)
     return NS_ERROR_DOM_INVALID_STATE_ERR;
 
   if (aReturn == 0)
     return NS_ERROR_NULL_POINTER;
 
   nsRefPtr<nsRange> range = new nsRange();
-  NS_ENSURE_TRUE(range, NS_ERROR_OUT_OF_MEMORY);
 
   range->SetMaySpanAnonymousSubtrees(mMaySpanAnonymousSubtrees);
 
   range->DoSetRange(mStartParent, mStartOffset, mEndParent, mEndOffset, mRoot);
 
-  *aReturn = range.forget().get();
+  range.forget(aReturn);
 
   return NS_OK;
 }
 
-NS_IMETHODIMP nsRange::CloneRange(nsIDOMRange** aReturn)
+NS_IMETHODIMP
+nsRange::CloneRange(nsIDOMRange** aReturn)
 {
-  nsIRange* clone;
-  nsresult rv = DoCloneRange(&clone);
-  if (NS_SUCCEEDED(rv)) {
-    *aReturn = clone;
-  }
+  nsRefPtr<nsRange> range;
+  nsresult rv = CloneRange(getter_AddRefs(range));
+  range.forget(aReturn);
   return rv;
 }
 
-/* virtual */ nsresult
-nsRange::CloneRange(nsIRange** aReturn) const
-{
-  return DoCloneRange(aReturn);
-}
-
 NS_IMETHODIMP
 nsRange::InsertNode(nsIDOMNode* aN)
 {
   VALIDATE_ACCESS(aN);
   
   nsresult res;
   PRInt32 tStartOffset;
   this->GetStartOffset(&tStartOffset);
@@ -2307,17 +2266,17 @@ nsRange::ToString(nsAString& aReturn)
   
   /* complex case: mStartParent != mEndParent, or mStartParent not a text node
      revisit - there are potential optimizations here and also tradeoffs.
   */
 
   nsCOMPtr<nsIContentIterator> iter;
   nsresult rv = NS_NewContentIterator(getter_AddRefs(iter));
   NS_ENSURE_SUCCESS(rv, rv);
-  rv = iter->Init(static_cast<nsIRange*>(this));
+  rv = iter->Init(this);
   NS_ENSURE_SUCCESS(rv, rv);
   
   nsString tempString;
  
   // loop through the content iterator, which returns nodes in the range in 
   // close tag order, and grab the text from any text node
   while (!iter->IsDone())
   {
@@ -2372,17 +2331,16 @@ nsRange::Detach()
 
   mIsDetached = true;
 
   DoSetRange(nsnull, 0, nsnull, 0, nsnull);
   
   return NS_OK;
 }
 
-// nsIDOMNSRange interface
 NS_IMETHODIMP    
 nsRange::CreateContextualFragment(const nsAString& aFragment,
                                   nsIDOMDocumentFragment** aReturn)
 {
   if (mIsPositioned) {
     return nsContentUtils::CreateContextualFragment(mStartParent, aFragment,
                                                     false, aReturn);
   }
--- a/content/base/src/nsRange.h
+++ b/content/base/src/nsRange.h
@@ -37,69 +37,124 @@
 
 /*
  * Implementation of the DOM nsIDOMRange object.
  */
 
 #ifndef nsRange_h___
 #define nsRange_h___
 
-#include "nsIRange.h"
 #include "nsIDOMRange.h"
 #include "nsIRangeUtils.h"
-#include "nsIDOMNSRange.h"
 #include "nsCOMPtr.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsIContent.h"
 #include "nsIDOMNode.h"
 #include "prmon.h"
 #include "nsStubMutationObserver.h"
 
-// -------------------------------------------------------------------------------
-
-class nsRangeUtils : public nsIRangeUtils
-{
-public:
-  NS_DECL_ISUPPORTS
-
-  // nsIRangeUtils interface
-  NS_IMETHOD_(PRInt32) ComparePoints(nsIDOMNode* aParent1, PRInt32 aOffset1,
-                                     nsIDOMNode* aParent2, PRInt32 aOffset2);
-                               
-  NS_IMETHOD CompareNodeToRange(nsIContent* aNode, 
-                                nsIDOMRange* aRange,
-                                bool *outNodeBefore,
-                                bool *outNodeAfter);
-};
-
-// -------------------------------------------------------------------------------
-
-class nsRange : public nsIRange,
-                public nsIDOMNSRange,
+class nsRange : public nsIDOMRange,
                 public nsStubMutationObserver
 {
 public:
-  nsRange(){}
+  nsRange()
+    : mRoot(nsnull)
+    , mStartOffset(0)
+    , mEndOffset(0)
+    , mIsPositioned(false)
+    , mIsDetached(false)
+    , mMaySpanAnonymousSubtrees(false)
+    , mInSelection(false)
+  {}
   virtual ~nsRange();
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
-  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsRange, nsIRange)
+  NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsRange, nsIDOMRange)
 
   // nsIDOMRange interface
   NS_DECL_NSIDOMRANGE
+  
+  nsINode* GetRoot() const
+  {
+    return mRoot;
+  }
 
-  // nsIDOMNSRange interface
-  NS_DECL_NSIDOMNSRANGE
+  nsINode* GetStartParent() const
+  {
+    return mStartParent;
+  }
+
+  nsINode* GetEndParent() const
+  {
+    return mEndParent;
+  }
+
+  PRInt32 StartOffset() const
+  {
+    return mStartOffset;
+  }
+
+  PRInt32 EndOffset() const
+  {
+    return mEndOffset;
+  }
+  
+  bool IsPositioned() const
+  {
+    return mIsPositioned;
+  }
+
+  bool IsDetached() const
+  {
+    return mIsDetached;
+  }
   
-  // nsIRange interface
-  virtual nsINode* GetCommonAncestor() const;
-  virtual void Reset();
-  virtual nsresult SetStart(nsINode* aParent, PRInt32 aOffset);
-  virtual nsresult SetEnd(nsINode* aParent, PRInt32 aOffset);
-  virtual nsresult CloneRange(nsIRange** aNewRange) const;
+  bool Collapsed() const
+  {
+    return mIsPositioned && mStartParent == mEndParent &&
+           mStartOffset == mEndOffset;
+  }
+
+  void SetMaySpanAnonymousSubtrees(bool aMaySpanAnonymousSubtrees)
+  {
+    mMaySpanAnonymousSubtrees = aMaySpanAnonymousSubtrees;
+  }
+  
+  /**
+   * Return true iff this range is part of at least one Selection object
+   * and isn't detached.
+   */
+  bool IsInSelection() const
+  {
+    return mInSelection;
+  }
+
+  /**
+   * Called when the range is added/removed from a Selection.
+   */
+  void SetInSelection(bool aInSelection)
+  {
+    if (mInSelection == aInSelection || mIsDetached) {
+      return;
+    }
+    mInSelection = aInSelection;
+    nsINode* commonAncestor = GetCommonAncestor();
+    NS_ASSERTION(commonAncestor, "unexpected disconnected nodes");
+    if (mInSelection) {
+      RegisterCommonAncestor(commonAncestor);
+    } else {
+      UnregisterCommonAncestor(commonAncestor);
+    }
+  }
+
+  nsINode* GetCommonAncestor() const;
+  void Reset();
+  nsresult SetStart(nsINode* aParent, PRInt32 aOffset);
+  nsresult SetEnd(nsINode* aParent, PRInt32 aOffset);
+  nsresult CloneRange(nsRange** aNewRange) const;
 
   nsresult Set(nsINode* aStartParent, PRInt32 aStartOffset,
                nsINode* aEndParent, PRInt32 aEndOffset)
   {
     // If this starts being hot, we may be able to optimize this a bit,
     // but for now just set start and end separately.
     nsresult rv = SetStart(aStartParent, aStartOffset);
     NS_ENSURE_SUCCESS(rv, rv);
@@ -124,45 +179,42 @@ private:
   /**
    * Cut or delete the range's contents.
    *
    * @param aFragment nsIDOMDocumentFragment containing the nodes.
    *                  May be null to indicate the caller doesn't want a fragment.
    */
   nsresult CutContents(nsIDOMDocumentFragment** frag);
 
-  /**
-   * Guts of cloning a range.  Addrefs the new range.
-   */
-  nsresult DoCloneRange(nsIRange** aNewRange) const;
-
   static nsresult CloneParentsBetween(nsIDOMNode *aAncestor,
                                       nsIDOMNode *aNode,
                                       nsIDOMNode **aClosestAncestor,
                                       nsIDOMNode **aFarthestAncestor);
 
 public:
 /******************************************************************************
  *  Utility routine to detect if a content node starts before a range and/or 
  *  ends after a range.  If neither it is contained inside the range.
  *  
  *  XXX - callers responsibility to ensure node in same doc as range!
  *
  *****************************************************************************/
-  static nsresult CompareNodeToRange(nsINode* aNode, nsIDOMRange* aRange,
-                                     bool *outNodeBefore,
-                                     bool *outNodeAfter);
-  static nsresult CompareNodeToRange(nsINode* aNode, nsIRange* aRange,
+  static nsresult CompareNodeToRange(nsINode* aNode, nsRange* aRange,
                                      bool *outNodeBefore,
                                      bool *outNodeAfter);
 
   static bool IsNodeSelected(nsINode* aNode, PRUint32 aStartOffset,
                              PRUint32 aEndOffset);
 
+  typedef nsTHashtable<nsPtrHashKey<nsRange> > RangeHashTable;
 protected:
+  void RegisterCommonAncestor(nsINode* aNode);
+  void UnregisterCommonAncestor(nsINode* aNode);
+  nsINode* IsValidBoundary(nsINode* aNode);
+
   // CharacterDataChanged set aNotInsertedYet to true to disable an assertion
   // and suppress re-registering a range common ancestor node since
   // the new text node of a splitText hasn't been inserted yet.
   // CharacterDataChanged does the re-registering when needed.
   void DoSetRange(nsINode* aStartN, PRInt32 aStartOffset,
                   nsINode* aEndN, PRInt32 aEndOffset,
                   nsINode* aRoot, bool aNotInsertedYet = false);
 
@@ -194,17 +246,40 @@ protected:
     nsRange* mRange;
     nsRefPtr<nsINode> mCommonAncestor;
 #ifdef DEBUG
     bool mWasInSelection;
 #endif
     static bool mIsNested;
   };
   
+  nsCOMPtr<nsINode> mRoot;
+  nsCOMPtr<nsINode> mStartParent;
+  nsCOMPtr<nsINode> mEndParent;
+  PRInt32 mStartOffset;
+  PRInt32 mEndOffset;
+
+  bool mIsPositioned;
+  bool mIsDetached;
+  bool mMaySpanAnonymousSubtrees;
+  bool mInSelection;
 };
 
-// Make a new nsIDOMRange object
-nsresult NS_NewRange(nsIDOMRange** aInstancePtrResult);
+
+class nsRangeUtils : public nsIRangeUtils
+{
+public:
+  NS_DECL_ISUPPORTS
+
+  // nsIRangeUtils interface
+  NS_IMETHOD_(PRInt32) ComparePoints(nsIDOMNode* aParent1, PRInt32 aOffset1,
+                                     nsIDOMNode* aParent2, PRInt32 aOffset2);
+                               
+  NS_IMETHOD CompareNodeToRange(nsIContent* aNode, 
+                                nsRange* aRange,
+                                bool *outNodeBefore,
+                                bool *outNodeAfter);
+};
 
 // Make a new nsIRangeUtils object
 nsresult NS_NewRangeUtils(nsIRangeUtils** aInstancePtrResult);
 
 #endif /* nsRange_h___ */
--- a/content/base/src/nsTextNode.cpp
+++ b/content/base/src/nsTextNode.cpp
@@ -42,17 +42,17 @@
 #include "nsTextNode.h"
 #include "nsContentUtils.h"
 #include "nsIDOMEventListener.h"
 #include "nsIDOMMutationEvent.h"
 #include "nsIAttribute.h"
 #include "nsIDocument.h"
 #include "nsThreadUtils.h"
 #ifdef DEBUG
-#include "nsIRange.h"
+#include "nsRange.h"
 #endif
 
 using namespace mozilla::dom;
 
 /**
  * class used to implement attr() generated content
  */
 class nsAttributeTextNode : public nsTextNode,
@@ -223,17 +223,17 @@ void
 nsTextNode::List(FILE* out, PRInt32 aIndent) const
 {
   PRInt32 index;
   for (index = aIndent; --index >= 0; ) fputs("  ", out);
 
   fprintf(out, "Text@%p", static_cast<const void*>(this));
   fprintf(out, " flags=[%08x]", static_cast<unsigned int>(GetFlags()));
   if (IsCommonAncestorForRangeInSelection()) {
-    typedef nsTHashtable<nsPtrHashKey<nsIRange> > RangeHashTable;
+    typedef nsTHashtable<nsPtrHashKey<nsRange> > RangeHashTable;
     RangeHashTable* ranges =
       static_cast<RangeHashTable*>(GetProperty(nsGkAtoms::range));
     fprintf(out, " ranges:%d", ranges ? ranges->Count() : 0);
   }
   fprintf(out, " primaryframe=%p", static_cast<void*>(GetPrimaryFrame()));
   fprintf(out, " refcount=%d<", mRefCnt.get());
 
   nsAutoString tmp;
--- a/content/base/src/nsTreeSanitizer.cpp
+++ b/content/base/src/nsTreeSanitizer.cpp
@@ -733,31 +733,28 @@ nsIAtom** const kElementsMathML[] = {
    &nsGkAtoms::limit_, // limit
    &nsGkAtoms::list_, // list
    &nsGkAtoms::ln_, // ln
    &nsGkAtoms::log_, // log
    &nsGkAtoms::logbase_, // logbase
    &nsGkAtoms::lowlimit_, // lowlimit
    &nsGkAtoms::lt_, // lt
    &nsGkAtoms::maction_, // maction
-   &nsGkAtoms::malign_, // malign
    &nsGkAtoms::maligngroup_, // maligngroup
    &nsGkAtoms::malignmark_, // malignmark
-   &nsGkAtoms::malignscope_, // malignscope
    &nsGkAtoms::math, // math
    &nsGkAtoms::matrix, // matrix
    &nsGkAtoms::matrixrow_, // matrixrow
    &nsGkAtoms::max, // max
    &nsGkAtoms::mean_, // mean
    &nsGkAtoms::median_, // median
    &nsGkAtoms::menclose_, // menclose
    &nsGkAtoms::merror_, // merror
    &nsGkAtoms::mfenced_, // mfenced
    &nsGkAtoms::mfrac_, // mfrac
-   &nsGkAtoms::mfraction_, // mfraction
    &nsGkAtoms::mglyph_, // mglyph
    &nsGkAtoms::mi_, // mi
    &nsGkAtoms::min, // min
    &nsGkAtoms::minus_, // minus
    &nsGkAtoms::mlabeledtr_, // mlabeledtr
    &nsGkAtoms::mlongdiv_, // mlongdiv
    &nsGkAtoms::mmultiscripts_, // mmultiscripts
    &nsGkAtoms::mn_, // mn
@@ -919,17 +916,16 @@ nsIAtom** const kAttributesMathML[] = {
    &nsGkAtoms::mathbackground_, // mathbackground
    &nsGkAtoms::mathcolor_, // mathcolor
    &nsGkAtoms::mathsize_, // mathsize
    &nsGkAtoms::mathvariant_, // mathvariant
    &nsGkAtoms::maxsize_, // maxsize
    &nsGkAtoms::mediummathspace_, // mediummathspace
    &nsGkAtoms::minlabelspacing_, // minlabelspacing
    &nsGkAtoms::minsize_, // minsize
-   &nsGkAtoms::monospaced_, // monospaced
    &nsGkAtoms::movablelimits_, // movablelimits
    &nsGkAtoms::msgroup_, // msgroup
    &nsGkAtoms::name, // name
    &nsGkAtoms::negativemediummathspace_, // negativemediummathspace
    &nsGkAtoms::negativethickmathspace_, // negativethickmathspace
    &nsGkAtoms::negativethinmathspace_, // negativethinmathspace
    &nsGkAtoms::negativeverythickmathspace_, // negativeverythickmathspace
    &nsGkAtoms::negativeverythinmathspace_, // negativeverythinmathspace
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -1454,23 +1454,33 @@ nsXMLHttpRequest::CheckChannelForCrossSi
     return NS_OK;
   }
 
   // ...or if this is a same-origin request.
   if (nsContentUtils::CheckMayLoad(mPrincipal, aChannel)) {
     return NS_OK;
   }
 
+  // exempt data URIs from the same origin check.
+  nsCOMPtr<nsIURI> channelURI;
+  bool dataScheme = false;
+  if (NS_SUCCEEDED(NS_GetFinalChannelURI(aChannel,
+                                         getter_AddRefs(channelURI))) &&
+      NS_SUCCEEDED(channelURI->SchemeIs("data", &dataScheme)) &&
+      dataScheme) {
+    return NS_OK;
+  }
+
   // This is a cross-site request
   mState |= XML_HTTP_REQUEST_USE_XSITE_AC;
 
   // Check if we need to do a preflight request.
   nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(aChannel);
   NS_ENSURE_TRUE(httpChannel, NS_ERROR_DOM_BAD_URI);
-    
+
   nsCAutoString method;
   httpChannel->GetRequestMethod(method);
   if (!mCORSUnsafeHeaders.IsEmpty() ||
       HasListenersFor(NS_LITERAL_STRING(UPLOADPROGRESS_STR)) ||
       (mUpload && mUpload->HasListeners()) ||
       (!method.LowerCaseEqualsLiteral("get") &&
        !method.LowerCaseEqualsLiteral("post") &&
        !method.LowerCaseEqualsLiteral("head"))) {
@@ -2582,17 +2592,17 @@ nsXMLHttpRequest::Send(nsIVariant *aBody
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   if (!IsSystemXHR()) {
     // Always create a nsCORSListenerProxy here even if it's
     // a same-origin request right now, since it could be redirected.
     listener = new nsCORSListenerProxy(listener, mPrincipal, mChannel,
-                                       withCredentials, &rv);
+                                       withCredentials, true, &rv);
     NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Bypass the network cache in cases where it makes no sense:
   // 1) Multipart responses are very large and would likely be doomed by the
   //    cache once they grow too large, so they are not worth caching.
   // 2) POST responses are always unique, and we provide no API that would
--- a/content/base/test/test_XHR.html
+++ b/content/base/test/test_XHR.html
@@ -16,32 +16,34 @@ SimpleTest.waitForExplicitFinish();
 
 var gen = runTests();
 function continueTest() { gen.next(); }
 
 function runTests() {
 
 var path = "/tests/content/base/test/";
 
-var passFiles = [['file_XHR_pass1.xml', 'GET'],
-                 ['file_XHR_pass2.txt', 'GET'],
-                 ['file_XHR_pass3.txt', 'GET'],
+var passFiles = [['file_XHR_pass1.xml', 'GET', 200],
+                 ['file_XHR_pass2.txt', 'GET', 200],
+                 ['file_XHR_pass3.txt', 'GET', 200],
+                 ['data:text/xml,%3Cres%3Ehello%3C/res%3E%0A', 'GET', 0],
+                 ['data:text/plain,hello%20pass%0A', 'GET', 0],
                  ];
 
 var failFiles = [['//example.com' + path + 'file_XHR_pass1.xml', 'GET'],
                  ['ftp://localhost' + path + 'file_XHR_pass1.xml', 'GET'],
                  ['file_XHR_fail1.txt', 'GET'],
                  ];
 
 for (i = 0; i < passFiles.length; ++i) {
   xhr = new XMLHttpRequest();
   is(xhr.responseType, "", "wrong initial responseType");
   xhr.open(passFiles[i][1], passFiles[i][0], false); 
   xhr.send(null);
-  is(xhr.status, 200, "wrong status");
+  is(xhr.status, passFiles[i][2], "wrong status");
   if (xhr.responseXML) {
     is((new XMLSerializer()).serializeToString(xhr.responseXML.documentElement),
        "<res>hello</res>",
        "wrong responseXML");
     is(xhr.response, "<res>hello</res>\n", "wrong response");
   }
   else {
     is(xhr.responseText, "hello pass\n", "wrong responseText");
--- a/content/base/test/test_bug451376.html
+++ b/content/base/test/test_bug451376.html
@@ -25,18 +25,17 @@ https://bugzilla.mozilla.org/show_bug.cg
 
     function testRange(aRangeID,
                        aStartNode, aStartOffset,
                        aEndNode, aEndOffset,
                        aBeforeRangeNode, aBeforeRangeOffset,
                        aInRangeNode, aInRangeOffset,
                        aAfterRangeNode, aAfterRangeOffset)
     {
-      var range = document.createRange().
-        QueryInterface(Components.interfaces.nsIDOMNSRange);
+      var range = document.createRange();
 
       range.setStart(aStartNode, aStartOffset);
       range.setEnd(aEndNode, aEndOffset);
 
       if (aBeforeRangeNode)
         is(range.comparePoint(aBeforeRangeNode, aBeforeRangeOffset), -1,
            "Wrong result for the point before the range '" + aRangeID + "'");
       if (aInRangeNode)
--- a/content/canvas/src/CustomQS_Canvas2D.h
+++ b/content/canvas/src/CustomQS_Canvas2D.h
@@ -38,29 +38,31 @@
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsDOMError.h"
 #include "nsIDOMCanvasRenderingContext2D.h"
 #include "CheckedInt.h"
 #include "nsMathUtils.h"
 
+#include "jsapi.h"
+
 typedef NS_STDCALL_FUNCPROTO(nsresult, CanvasStyleSetterType, nsIDOMCanvasRenderingContext2D,
                              SetStrokeStyle_multi, (const nsAString &, nsISupports *));
 typedef NS_STDCALL_FUNCPROTO(nsresult, CanvasStyleGetterType, nsIDOMCanvasRenderingContext2D,
                              GetStrokeStyle_multi, (nsAString &, nsISupports **, PRInt32 *));
 
 static JSBool
 Canvas2D_SetStyleHelper(JSContext *cx, JSObject *obj, jsid id, jsval *vp,
                         CanvasStyleSetterType setfunc)
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     nsIDOMCanvasRenderingContext2D *self;
     xpc_qsSelfRef selfref;
-    js::AutoValueRooter tvr(cx);
+    JS::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     nsresult rv = NS_OK;
     if (JSVAL_IS_STRING(*vp)) {
         xpc_qsDOMString arg0(cx, *vp, vp,
                              xpc_qsDOMString::eDefaultNullBehavior,
                              xpc_qsDOMString::eDefaultUndefinedBehavior);
@@ -173,17 +175,17 @@ CreateImageData(JSContext* cx,
     CheckedInt<uint32_t> len = CheckedInt<uint32_t>(w) * h * 4;
     if (!len.valid()) {
         return xpc_qsThrow(cx, NS_ERROR_DOM_INDEX_SIZE_ERR);
     }
 
     // Create the fast typed array; it's initialized to 0 by default.
     JSObject* darray =
       js_CreateTypedArray(cx, js::TypedArray::TYPE_UINT8_CLAMPED, len.value());
-    js::AutoObjectRooter rd(cx, darray);
+    JS::AutoObjectRooter rd(cx, darray);
     if (!darray) {
         return false;
     }
 
     if (self) {
         JSObject *tdest = js::TypedArray::getTypedArray(darray);
 
         // make the call
@@ -194,17 +196,17 @@ CreateImageData(JSContext* cx,
         if (NS_FAILED(rv)) {
             return xpc_qsThrowMethodFailed(cx, rv, vp);
         }
     }
 
     // Do JS_NewObject after CreateTypedArray, so that gc will get
     // triggered here if necessary
     JSObject* result = JS_NewObject(cx, NULL, NULL, NULL);
-    js::AutoObjectRooter rr(cx, result);
+    JS::AutoObjectRooter rr(cx, result);
     if (!result) {
         return false;
     }
 
     if (!JS_DefineProperty(cx, result, "width", INT_TO_JSVAL(w), NULL, NULL,
                            JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
         !JS_DefineProperty(cx, result, "height", INT_TO_JSVAL(h), NULL, NULL,
                            JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT) ||
@@ -295,17 +297,17 @@ nsIDOMCanvasRenderingContext2D_GetImageD
     XPC_QS_ASSERT_CONTEXT_OK(cx);
 
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsIDOMCanvasRenderingContext2D *self;
     xpc_qsSelfRef selfref;
-    js::AutoValueRooter tvr(cx);
+    JS::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 4)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -354,17 +356,17 @@ nsIDOMCanvasRenderingContext2D_PutImageD
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsIDOMCanvasRenderingContext2D *self;
     xpc_qsSelfRef selfref;
-    js::AutoValueRooter tvr(cx);
+    JS::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -382,17 +384,17 @@ nsIDOMCanvasRenderingContext2D_PutImageD
     if (!NS_finite(xd) || !NS_finite(yd)) {
         return xpc_qsThrow(cx, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
     }
 
     int32_t x = JS_DoubleToInt32(xd);
     int32_t y = JS_DoubleToInt32(yd);
 
     // Grab width, height, and the dense array from the dataObject.
-    js::AutoValueRooter tv(cx);
+    JS::AutoValueRooter tv(cx);
 
     uint32_t w, h;
     if (!GetImageDataDimensions(cx, dataObject, &w, &h))
         return JS_FALSE;
 
     // the optional dirty rect
     bool hasDirtyRect = false;
     int32_t dirtyX = 0,
@@ -425,17 +427,17 @@ nsIDOMCanvasRenderingContext2D_PutImageD
     if (!JS_GetProperty(cx, dataObject, "data", tv.jsval_addr()))
         return JS_FALSE;
 
     if (JSVAL_IS_PRIMITIVE(tv.jsval_value()))
         return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR);
 
     JSObject *darray = JSVAL_TO_OBJECT(tv.jsval_value());
 
-    js::AutoValueRooter tsrc_tvr(cx);
+    JS::AutoValueRooter tsrc_tvr(cx);
 
     JSObject *tsrc = NULL;
     if (js::GetObjectClass(darray) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8] ||
         js::GetObjectClass(darray) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_UINT8_CLAMPED])
     {
         tsrc = js::TypedArray::getTypedArray(darray);
     } else if (JS_IsArrayObject(cx, darray) || js_IsTypedArray(darray)) {
         // ugh, this isn't a uint8 typed array, someone made their own object; convert it to a typed array
--- a/content/canvas/src/CustomQS_WebGL.h
+++ b/content/canvas/src/CustomQS_WebGL.h
@@ -35,16 +35,17 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 /*
  * Intended to be #included in dom_quickstubs.cpp via qsconf!
  */
 
+#include "jsapi.h"
 #include "jstypedarray.h"
 
 #define GET_INT32_ARG(var, index) \
   int32_t var; \
   do { \
     if (!JS_ValueToECMAInt32(cx, argv[index], &(var))) \
       return JS_FALSE; \
   } while (0)
@@ -86,17 +87,17 @@ nsIDOMWebGLRenderingContext_BufferData(J
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsIDOMWebGLRenderingContext *self;
     xpc_qsSelfRef selfref;
-    js::AutoValueRooter tvr(cx);
+    JS::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -159,17 +160,17 @@ nsIDOMWebGLRenderingContext_BufferSubDat
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsIDOMWebGLRenderingContext *self;
     xpc_qsSelfRef selfref;
-    js::AutoValueRooter tvr(cx);
+    JS::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -233,17 +234,17 @@ nsIDOMWebGLRenderingContext_ReadPixels(J
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsIDOMWebGLRenderingContext *self;
     xpc_qsSelfRef selfref;
-    js::AutoValueRooter tvr(cx);
+    JS::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 7)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -293,17 +294,17 @@ nsIDOMWebGLRenderingContext_TexImage2D(J
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsIDOMWebGLRenderingContext *self;
     xpc_qsSelfRef selfref;
-    js::AutoValueRooter tvr(cx);
+    JS::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 6 || argc == 7 || argc == 8)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -414,17 +415,17 @@ nsIDOMWebGLRenderingContext_TexSubImage2
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsIDOMWebGLRenderingContext *self;
     xpc_qsSelfRef selfref;
-    js::AutoValueRooter tvr(cx);
+    JS::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 7 || argc == 8)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -525,17 +526,17 @@ helper_nsIDOMWebGLRenderingContext_Unifo
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsIDOMWebGLRenderingContext *self;
     xpc_qsSelfRef selfref;
-    js::AutoValueRooter tvr(cx);
+    JS::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 2)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -549,17 +550,17 @@ helper_nsIDOMWebGLRenderingContext_Unifo
 
     if (JSVAL_IS_PRIMITIVE(argv[1])) {
         xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
         return JS_FALSE;
     }
 
     JSObject *arg1 = JSVAL_TO_OBJECT(argv[1]);
 
-    js::AutoValueRooter obj_tvr(cx);
+    JS::AutoValueRooter obj_tvr(cx);
 
     JSObject *wa = 0;
 
     if (helper_isInt32Array(arg1)) {
         wa = js::TypedArray::getTypedArray(arg1);
     }  else if (JS_IsArrayObject(cx, arg1)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_INT32, arg1);
         if (!nobj) {
@@ -599,17 +600,17 @@ helper_nsIDOMWebGLRenderingContext_Unifo
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsresult rv;
 
     nsIDOMWebGLRenderingContext *self;
     xpc_qsSelfRef selfref;
-    js::AutoValueRooter tvr(cx);
+    JS::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 2)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -623,17 +624,17 @@ helper_nsIDOMWebGLRenderingContext_Unifo
 
     if (JSVAL_IS_PRIMITIVE(argv[1])) {
         xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
         return JS_FALSE;
     }
 
     JSObject *arg1 = JSVAL_TO_OBJECT(argv[1]);
 
-    js::AutoValueRooter obj_tvr(cx);
+    JS::AutoValueRooter obj_tvr(cx);
 
     JSObject *wa = 0;
 
     if (helper_isFloat32Array(arg1)) {
         wa = js::TypedArray::getTypedArray(arg1);
     }  else if (JS_IsArrayObject(cx, arg1)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg1);
         if (!nobj) {
@@ -671,17 +672,17 @@ helper_nsIDOMWebGLRenderingContext_Unifo
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsIDOMWebGLRenderingContext *self;
     xpc_qsSelfRef selfref;
-    js::AutoValueRooter tvr(cx);
+    JS::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 3)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -699,17 +700,17 @@ helper_nsIDOMWebGLRenderingContext_Unifo
 
     if (JSVAL_IS_PRIMITIVE(argv[2])) {
         xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 2);
         return JS_FALSE;
     }
 
     JSObject *arg2 = JSVAL_TO_OBJECT(argv[2]);
 
-    js::AutoValueRooter obj_tvr(cx);
+    JS::AutoValueRooter obj_tvr(cx);
 
     JSObject *wa = 0;
 
     if (helper_isFloat32Array(arg2)) {
         wa = js::TypedArray::getTypedArray(arg2);
     }  else if (JS_IsArrayObject(cx, arg2)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg2);
         if (!nobj) {
@@ -744,17 +745,17 @@ helper_nsIDOMWebGLRenderingContext_Verte
 {
     XPC_QS_ASSERT_CONTEXT_OK(cx);
     JSObject *obj = JS_THIS_OBJECT(cx, vp);
     if (!obj)
         return JS_FALSE;
 
     nsIDOMWebGLRenderingContext *self;
     xpc_qsSelfRef selfref;
-    js::AutoValueRooter tvr(cx);
+    JS::AutoValueRooter tvr(cx);
     if (!xpc_qsUnwrapThis(cx, obj, nsnull, &self, &selfref.ptr, tvr.jsval_addr(), nsnull))
         return JS_FALSE;
 
     if (argc < 2)
         return xpc_qsThrow(cx, NS_ERROR_XPC_NOT_ENOUGH_ARGS);
 
     jsval *argv = JS_ARGV(cx, vp);
 
@@ -764,17 +765,17 @@ helper_nsIDOMWebGLRenderingContext_Verte
 
     if (JSVAL_IS_PRIMITIVE(argv[1])) {
         xpc_qsThrowBadArg(cx, NS_ERROR_FAILURE, vp, 1);
         return JS_FALSE;
     }
 
     JSObject *arg1 = JSVAL_TO_OBJECT(argv[1]);
 
-    js::AutoValueRooter obj_tvr(cx);
+    JS::AutoValueRooter obj_tvr(cx);
 
     JSObject *wa = 0;
 
     if (helper_isFloat32Array(arg1)) {
         wa = js::TypedArray::getTypedArray(arg1);
     }  else if (JS_IsArrayObject(cx, arg1)) {
         JSObject *nobj = js_CreateTypedArrayWithArray(cx, js::TypedArray::TYPE_FLOAT32, arg1);
         if (!nobj) {
--- a/content/events/src/nsContentEventHandler.cpp
+++ b/content/events/src/nsContentEventHandler.cpp
@@ -93,18 +93,17 @@ nsContentEventHandler::InitCommon()
   nsCopySupport::GetSelectionForCopy(mPresShell->GetDocument(),
                                      getter_AddRefs(mSelection));
 
   nsCOMPtr<nsIDOMRange> firstRange;
   nsresult rv = mSelection->GetRangeAt(0, getter_AddRefs(firstRange));
   // This shell doesn't support selection.
   if (NS_FAILED(rv))
     return NS_ERROR_NOT_AVAILABLE;
-  mFirstSelectedRange = do_QueryInterface(firstRange);
-  NS_ENSURE_TRUE(mFirstSelectedRange, NS_ERROR_FAILURE);
+  mFirstSelectedRange = static_cast<nsRange*>(firstRange.get());
 
   nsINode* startNode = mFirstSelectedRange->GetStartParent();
   NS_ENSURE_TRUE(startNode, NS_ERROR_FAILURE);
   nsINode* endNode = mFirstSelectedRange->GetEndParent();
   NS_ENSURE_TRUE(endNode, NS_ERROR_FAILURE);
 
   // See bug 537041 comment 5, the range could have removed node.
   NS_ENSURE_TRUE(startNode->GetCurrentDoc() == mPresShell->GetDocument(),
@@ -275,26 +274,24 @@ static PRUint32 ConvertToXPOffset(nsICon
   // offset minus the number of newlines encountered in the string.
   return aNativeOffset - CountNewlinesIn(aContent, aNativeOffset);
 #else
   // On other platforms, the native and XP newlines are the same.
   return aNativeOffset;
 #endif
 }
 
-static nsresult GenerateFlatTextContent(nsIRange* aRange,
+static nsresult GenerateFlatTextContent(nsRange* aRange,
                                         nsAFlatString& aString)
 {
   nsCOMPtr<nsIContentIterator> iter;
   nsresult rv = NS_NewContentIterator(getter_AddRefs(iter));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ASSERTION(iter, "NS_NewContentIterator succeeded, but the result is null");
-  nsCOMPtr<nsIDOMRange> domRange(do_QueryInterface(aRange));
-  NS_ASSERTION(domRange, "aRange doesn't have nsIDOMRange!");
-  iter->Init(domRange);
+  iter->Init(aRange);
 
   NS_ASSERTION(aString.IsEmpty(), "aString must be empty string");
 
   nsINode* startNode = aRange->GetStartParent();
   NS_ENSURE_TRUE(startNode, NS_ERROR_FAILURE);
   nsINode* endNode = aRange->GetEndParent();
   NS_ENSURE_TRUE(endNode, NS_ERROR_FAILURE);
 
@@ -369,29 +366,27 @@ nsContentEventHandler::ExpandToClusterBo
   newOffsetInFrame += aForward ? -1 : 1;
   textFrame->PeekOffsetCharacter(aForward, &newOffsetInFrame);
   *aXPOffset = startOffset + newOffsetInFrame;
   return NS_OK;
 }
 
 nsresult
 nsContentEventHandler::SetRangeFromFlatTextOffset(
-                              nsIRange* aRange,
+                              nsRange* aRange,
                               PRUint32 aNativeOffset,
                               PRUint32 aNativeLength,
                               bool aExpandToClusterBoundaries)
 {
   nsCOMPtr<nsIContentIterator> iter;
   nsresult rv = NS_NewContentIterator(getter_AddRefs(iter));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ASSERTION(iter, "NS_NewContentIterator succeeded, but the result is null");
   rv = iter->Init(mRootContent);
   NS_ENSURE_SUCCESS(rv, rv);
-  nsCOMPtr<nsIDOMRange> domRange(do_QueryInterface(aRange));
-  NS_ASSERTION(domRange, "aRange doesn't have nsIDOMRange!");
 
   PRUint32 nativeOffset = 0;
   PRUint32 nativeEndOffset = aNativeOffset + aNativeLength;
   nsCOMPtr<nsIContent> content;
   for (; !iter->IsDone(); iter->Next()) {
     nsINode* node = iter->GetCurrentNode();
     if (!node || !node->IsNodeOfType(nsINode::eCONTENT))
       continue;
@@ -411,21 +406,21 @@ nsContentEventHandler::SetRangeFromFlatT
         content->IsNodeOfType(nsINode::eTEXT) ?
           ConvertToXPOffset(content, aNativeOffset - nativeOffset) : 0;
 
       if (aExpandToClusterBoundaries) {
         rv = ExpandToClusterBoundary(content, false, &xpOffset);
         NS_ENSURE_SUCCESS(rv, rv);
       }
 
-      rv = domRange->SetStart(domNode, PRInt32(xpOffset));
+      rv = aRange->SetStart(domNode, PRInt32(xpOffset));
       NS_ENSURE_SUCCESS(rv, rv);
       if (aNativeLength == 0) {
         // Ensure that the end offset and the start offset are same.
-        rv = domRange->SetEnd(domNode, PRInt32(xpOffset));
+        rv = aRange->SetEnd(domNode, PRInt32(xpOffset));
         NS_ENSURE_SUCCESS(rv, rv);
         return NS_OK;
       }
     }
     if (nativeEndOffset <= nativeOffset + nativeTextLength) {
       nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(content));
       NS_ASSERTION(domNode, "aContent doesn't have nsIDOMNode!");
 
@@ -441,34 +436,34 @@ nsContentEventHandler::SetRangeFromFlatT
         // by ContentIterator when the offset is zero.
         xpOffset = 0;
         iter->Next();
         if (iter->IsDone())
           break;
         domNode = do_QueryInterface(iter->GetCurrentNode());
       }
 
-      rv = domRange->SetEnd(domNode, PRInt32(xpOffset));
+      rv = aRange->SetEnd(domNode, PRInt32(xpOffset));
       NS_ENSURE_SUCCESS(rv, rv);
       return NS_OK;
     }
 
     nativeOffset += nativeTextLength;
   }
 
   if (nativeOffset < aNativeOffset)
     return NS_ERROR_FAILURE;
 
   nsCOMPtr<nsIDOMNode> domNode(do_QueryInterface(mRootContent));
   NS_ASSERTION(domNode, "lastContent doesn't have nsIDOMNode!");
   if (!content) {
-    rv = domRange->SetStart(domNode, 0);
+    rv = aRange->SetStart(domNode, 0);
     NS_ENSURE_SUCCESS(rv, rv);
   }
-  rv = domRange->SetEnd(domNode, PRInt32(mRootContent->GetChildCount()));
+  rv = aRange->SetEnd(domNode, PRInt32(mRootContent->GetChildCount()));
   NS_ASSERTION(NS_SUCCEEDED(rv), "nsIDOMRange::SetEnd failed");
   return rv;
 }
 
 nsresult
 nsContentEventHandler::OnQuerySelectedText(nsQueryContentEvent* aEvent)
 {
   nsresult rv = Init(aEvent);
@@ -498,18 +493,17 @@ nsContentEventHandler::OnQuerySelectedTe
   nsCOMPtr<nsINode> focusNode(do_QueryInterface(focusDomNode));
   NS_ENSURE_TRUE(anchorNode && focusNode, NS_ERROR_UNEXPECTED);
 
   PRInt16 compare = nsContentUtils::ComparePoints(anchorNode, anchorOffset,
                                                   focusNode, focusOffset);
   aEvent->mReply.mReversed = compare > 0;
 
   if (compare) {
-    nsCOMPtr<nsIRange> range = mFirstSelectedRange;
-    rv = GenerateFlatTextContent(range, aEvent->mReply.mString);
+    rv = GenerateFlatTextContent(mFirstSelectedRange, aEvent->mReply.mString);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   aEvent->mSucceeded = true;
   return NS_OK;
 }
 
 nsresult
@@ -517,18 +511,17 @@ nsContentEventHandler::OnQueryTextConten
 {
   nsresult rv = Init(aEvent);
   if (NS_FAILED(rv))
     return rv;
 
   NS_ASSERTION(aEvent->mReply.mString.IsEmpty(),
                "The reply string must be empty");
 
-  nsCOMPtr<nsIRange> range = new nsRange();
-  NS_ENSURE_TRUE(range, NS_ERROR_OUT_OF_MEMORY);
+  nsRefPtr<nsRange> range = new nsRange();
   rv = SetRangeFromFlatTextOffset(range, aEvent->mInput.mOffset,
                                   aEvent->mInput.mLength, false);
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = GenerateFlatTextContent(range, aEvent->mReply.mString);
   NS_ENSURE_SUCCESS(rv, rv);
 
   aEvent->mSucceeded = true;
@@ -575,20 +568,17 @@ static nsresult GetFrameForTextRect(nsIN
 
 nsresult
 nsContentEventHandler::OnQueryTextRect(nsQueryContentEvent* aEvent)
 {
   nsresult rv = Init(aEvent);
   if (NS_FAILED(rv))
     return rv;
 
-  nsCOMPtr<nsIRange> range = new nsRange();
-  if (!range) {
-    return NS_ERROR_OUT_OF_MEMORY;
-  }
+  nsRefPtr<nsRange> range = new nsRange();
   rv = SetRangeFromFlatTextOffset(range, aEvent->mInput.mOffset,
                                   aEvent->mInput.mLength, true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // used to iterate over all contents and their frames
   nsCOMPtr<nsIContentIterator> iter;
   rv = NS_NewContentIterator(getter_AddRefs(iter));
   NS_ENSURE_SUCCESS(rv, rv);
@@ -723,18 +713,17 @@ nsContentEventHandler::OnQueryCaretRect(
       aEvent->mReply.mRect =
         rect.ToOutsidePixels(caretFrame->PresContext()->AppUnitsPerDevPixel());
       aEvent->mSucceeded = true;
       return NS_OK;
     }
   }
 
   // Otherwise, we should set the guessed caret rect.
-  nsCOMPtr<nsIRange> range = new nsRange();
-  NS_ENSURE_TRUE(range, NS_ERROR_OUT_OF_MEMORY);
+  nsRefPtr<nsRange> range = new nsRange();
   rv = SetRangeFromFlatTextOffset(range, aEvent->mInput.mOffset, 0, true);
   NS_ENSURE_SUCCESS(rv, rv);
 
   PRInt32 offsetInFrame;
   nsIFrame* frame;
   rv = GetStartFrameAndOffset(range, &frame, &offsetInFrame);
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -911,32 +900,29 @@ nsContentEventHandler::OnQueryDOMWidgetH
 nsresult
 nsContentEventHandler::GetFlatTextOffsetOfRange(nsIContent* aRootContent,
                                                 nsINode* aNode,
                                                 PRInt32 aNodeOffset,
                                                 PRUint32* aNativeOffset)
 {
   NS_ASSERTION(aNativeOffset, "param is invalid");
 
-  nsCOMPtr<nsIRange> prev = new nsRange();
-  NS_ENSURE_TRUE(prev, NS_ERROR_OUT_OF_MEMORY);
-  nsCOMPtr<nsIDOMRange> domPrev(do_QueryInterface(prev));
-  NS_ASSERTION(domPrev, "nsRange doesn't have nsIDOMRange??");
+  nsRefPtr<nsRange> prev = new nsRange();
   nsCOMPtr<nsIDOMNode> rootDOMNode(do_QueryInterface(aRootContent));
-  domPrev->SetStart(rootDOMNode, 0);
+  prev->SetStart(rootDOMNode, 0);
 
   nsCOMPtr<nsIDOMNode> startDOMNode(do_QueryInterface(aNode));
   NS_ASSERTION(startDOMNode, "startNode doesn't have nsIDOMNode");
-  domPrev->SetEnd(startDOMNode, aNodeOffset);
+  prev->SetEnd(startDOMNode, aNodeOffset);
 
   nsCOMPtr<nsIContentIterator> iter;
   nsresult rv = NS_NewContentIterator(getter_AddRefs(iter));
   NS_ENSURE_SUCCESS(rv, rv);
   NS_ASSERTION(iter, "NS_NewContentIterator succeeded, but the result is null");
-  iter->Init(domPrev);
+  iter->Init(prev);
 
   nsCOMPtr<nsINode> startNode = do_QueryInterface(startDOMNode);
   nsINode* endNode = aNode;
 
   *aNativeOffset = 0;
   for (; !iter->IsDone(); iter->Next()) {
     nsINode* node = iter->GetCurrentNode();
     if (!node || !node->IsNodeOfType(nsINode::eCONTENT))
@@ -959,28 +945,28 @@ nsContentEventHandler::GetFlatTextOffset
 #endif
     }
   }
   return NS_OK;
 }
 
 nsresult
 nsContentEventHandler::GetFlatTextOffsetOfRange(nsIContent* aRootContent,
-                                                nsIRange* aRange,
+                                                nsRange* aRange,
                                                 PRUint32* aNativeOffset)
 {
   nsINode* startNode = aRange->GetStartParent();
   NS_ENSURE_TRUE(startNode, NS_ERROR_FAILURE);
   PRInt32 startOffset = aRange->StartOffset();
   return GetFlatTextOffsetOfRange(aRootContent, startNode, startOffset,
                                   aNativeOffset);
 }
 
 nsresult
-nsContentEventHandler::GetStartFrameAndOffset(nsIRange* aRange,
+nsContentEventHandler::GetStartFrameAndOffset(nsRange* aRange,
                                               nsIFrame** aFrame,
                                               PRInt32* aOffsetInFrame)
 {
   NS_ASSERTION(aRange && aFrame && aOffsetInFrame, "params are invalid");
 
   nsIContent* content = nsnull;
   nsINode* node = aRange->GetStartParent();
   if (node && node->IsNodeOfType(nsINode::eCONTENT))
--- a/content/events/src/nsContentEventHandler.h
+++ b/content/events/src/nsContentEventHandler.h
@@ -39,17 +39,17 @@
 
 #ifndef nsContentEventHandler_h__
 #define nsContentEventHandler_h__
 
 #include "nscore.h"
 #include "nsCOMPtr.h"
 
 #include "nsISelection.h"
-#include "nsIRange.h"
+#include "nsRange.h"
 #include "nsIContent.h"
 #include "nsIDOMTreeWalker.h"
 
 class nsPresContext;
 class nsIPresShell;
 class nsQueryContentEvent;
 class nsSelectionEvent;
 class nsCaret;
@@ -88,17 +88,17 @@ public:
 
   // NS_SELECTION_* event
   nsresult OnSelectionEvent(nsSelectionEvent* aEvent);
 
 protected:
   nsPresContext* mPresContext;
   nsCOMPtr<nsIPresShell> mPresShell;
   nsCOMPtr<nsISelection> mSelection;
-  nsCOMPtr<nsIRange> mFirstSelectedRange;
+  nsRefPtr<nsRange> mFirstSelectedRange;
   nsCOMPtr<nsIContent> mRootContent;
 
   nsresult Init(nsQueryContentEvent* aEvent);
   nsresult Init(nsSelectionEvent* aEvent);
 
   // InitCommon() is called from each Init().
   nsresult InitCommon();
 
@@ -107,29 +107,29 @@ public:
   // are replaced to native linefeeds. Other elements are ignored.
 
   // Get the offset in FlatText of the range. (also used by nsIMEStateManager)
   static nsresult GetFlatTextOffsetOfRange(nsIContent* aRootContent,
                                            nsINode* aNode,
                                            PRInt32 aNodeOffset,
                                            PRUint32* aOffset);
   static nsresult GetFlatTextOffsetOfRange(nsIContent* aRootContent,
-                                           nsIRange* aRange,
+                                           nsRange* aRange,
                                            PRUint32* aOffset);
 protected:
   // Make the DOM range from the offset of FlatText and the text length.
   // If aExpandToClusterBoundaries is true, the start offset and the end one are
   // expanded to nearest cluster boundaries.
-  nsresult SetRangeFromFlatTextOffset(nsIRange* aRange,
+  nsresult SetRangeFromFlatTextOffset(nsRange* aRange,
                                       PRUint32 aNativeOffset,
                                       PRUint32 aNativeLength,
                                       bool aExpandToClusterBoundaries);
   // Find the first textframe for the range, and get the start offset in
   // the frame.
-  nsresult GetStartFrameAndOffset(nsIRange* aRange,
+  nsresult GetStartFrameAndOffset(nsRange* aRange,
                                   nsIFrame** aFrame,
                                   PRInt32* aOffsetInFrame);
   // Convert the frame relative offset to the root view relative offset.
   nsresult ConvertToRootViewRelativeOffset(nsIFrame* aFrame,
                                            nsRect& aRect);
   // Expand aXPOffset to the nearest offset in cluster boundary. aForward is
   // true, it is expanded to forward.
   nsresult ExpandToClusterBoundary(nsIContent* aContent, bool aForward,
--- a/content/events/src/nsIMEStateManager.cpp
+++ b/content/events/src/nsIMEStateManager.cpp
@@ -487,17 +487,17 @@ nsTextStateManager::Init(nsIWidget* aWid
   nsresult rv = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL,
                                      getter_AddRefs(sel));
   NS_ENSURE_TRUE(sel, NS_ERROR_UNEXPECTED);
 
   nsCOMPtr<nsIDOMRange> selDomRange;
   rv = sel->GetRangeAt(0, getter_AddRefs(selDomRange));
 
   if (NS_SUCCEEDED(rv)) {
-    nsCOMPtr<nsIRange> selRange(do_QueryInterface(selDomRange));
+    nsRange* selRange = static_cast<nsRange*>(selDomRange.get());
     NS_ENSURE_TRUE(selRange && selRange->GetStartParent(),
                    NS_ERROR_UNEXPECTED);
 
     mRootContent = selRange->GetStartParent()->
                      GetSelectionRootContent(presShell);
   } else {
     mRootContent = aNode->GetSelectionRootContent(presShell);
   }
--- a/content/events/test/test_bug489671.html
+++ b/content/events/test/test_bug489671.html
@@ -25,17 +25,17 @@ const Ci = Components.interfaces;
 const Cr = Components.results;
 
 var listener = {
   observe: function(message) {
     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
 
     is(message.QueryInterface(Ci.nsIScriptError).errorMessage,
        "uncaught exception: Got click");
-    nextTest();
+    SimpleTest.executeSoon(nextTest);
   },
 
   QueryInterface: function(iid) {
     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
     if (iid.equals(Ci.nsIConsoleListener) ||
         iid.equals(Ci.nsISupports)) {
       return this;
     }
--- a/content/events/test/test_eventctors.xul
+++ b/content/events/test/test_eventctors.xul
@@ -38,14 +38,12 @@ https://bugzilla.mozilla.org/show_bug.cg
   
   e = new Event("hello");
   ok(e.type, "hello", "Wrong event type!");
   ok(e.isTrusted, "Event should be trusted!");
   ok(!e.bubbles, "Event shouldn't bubble!");
   ok(!e.cancelable, "Event shouldn't be cancelable!");
   document.dispatchEvent(e);
   is(receivedEvent, e, "Wrong event!");
-  
-  SimpleTest.finish();
 
   ]]>
   </script>
 </window>
--- a/content/html/content/src/nsGenericHTMLElement.cpp
+++ b/content/html/content/src/nsGenericHTMLElement.cpp
@@ -1619,26 +1619,26 @@ nsGenericHTMLElement::GetLayoutHistoryAn
 }
 
 bool
 nsGenericHTMLElement::RestoreFormControlState(nsGenericHTMLElement* aContent,
                                               nsIFormControl* aControl)
 {
   nsCOMPtr<nsILayoutHistoryState> history;
   nsCAutoString key;
-  nsresult rv = GetLayoutHistoryAndKey(aContent, true,
-                                       getter_AddRefs(history), key);
+  GetLayoutHistoryAndKey(aContent, true,
+                         getter_AddRefs(history), key);
   if (!history) {
     return false;
   }
 
   nsPresState *state;
   // Get the pres state for this key
-  rv = history->GetState(key, &state);
-  if (state) {
+  nsresult rv = history->GetState(key, &state);
+  if (NS_SUCCEEDED(rv) && state) {
     bool result = aControl->RestoreState(state);
     history->RemoveState(key);
     return result;
   }
 
   return false;
 }
 
@@ -2554,16 +2554,17 @@ nsGenericHTMLElement::GetContextMenu(nsI
   }
 
   return NS_OK;
 }
 
 //----------------------------------------------------------------------
 
 NS_IMPL_INT_ATTR(nsGenericHTMLFrameElement, TabIndex, tabindex)
+NS_IMPL_BOOL_ATTR(nsGenericHTMLFrameElement, MozBrowser, mozbrowser)
 
 nsGenericHTMLFormElement::nsGenericHTMLFormElement(already_AddRefed<nsINodeInfo> aNodeInfo)
   : nsGenericHTMLElement(aNodeInfo)
   , mForm(nsnull)
   , mFieldSet(nsnull)
 {
   // We should add the NS_EVENT_STATE_ENABLED bit here as needed, but
   // that depends on our type, which is not initialized yet.  So we
@@ -3222,18 +3223,19 @@ nsGenericHTMLFrameElement::~nsGenericHTM
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericHTMLFrameElement)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGenericHTMLFrameElement,
                                                   nsGenericHTMLElement)
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mFrameLoader, nsIFrameLoader)
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_INTERFACE_TABLE_HEAD(nsGenericHTMLFrameElement)
-  NS_INTERFACE_TABLE_INHERITED1(nsGenericHTMLFrameElement,
-                                nsIFrameLoaderOwner)
+  NS_INTERFACE_TABLE_INHERITED2(nsGenericHTMLFrameElement,
+                                nsIFrameLoaderOwner,
+                                nsIDOMMozBrowserFrameElement)
   NS_INTERFACE_TABLE_TO_MAP_SEGUE_CYCLE_COLLECTION(nsGenericHTMLFrameElement)
 NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLElement)
 
 nsresult
 nsGenericHTMLFrameElement::GetContentDocument(nsIDOMDocument** aContentDocument)
 {
   NS_PRECONDITION(aContentDocument, "Null out param");
   *aContentDocument = nsnull;
@@ -3430,16 +3432,118 @@ nsGenericHTMLFrameElement::SizeOf() cons
 {
   PRInt64 size = MemoryReporter::GetBasicSize<nsGenericHTMLFrameElement,
                                               nsGenericHTMLElement>(this);
   // TODO: need to implement SizeOf() in nsFrameLoader, bug 672539.
   size += mFrameLoader ? sizeof(*mFrameLoader.get()) : 0;
   return size;
 }
 
+namespace {
+
+// GetContentStateCallbackRunnable is used by MozGetContentState to fire its callback
+// asynchronously.
+class GetContentStateCallbackRunnable : public nsRunnable
+{
+public:
+  GetContentStateCallbackRunnable(nsIDOMMozGetContentStateCallback *aCallback,
+                             nsIDOMEventTarget *aEventTarget,
+                             const nsAString &aResult)
+    : mCallback(aCallback)
+    , mEventTarget(aEventTarget)
+    , mResult(aResult)
+  {
+  }
+
+  NS_IMETHOD Run()
+  {
+    FireCallback();
+
+    // Break cycles.
+    mCallback = NULL;
+    mEventTarget = NULL;
+    return NS_OK;
+  }
+
+private:
+  void FireCallback()
+  {
+    nsCxPusher pusher;
+    if (!pusher.Push(mEventTarget)) {
+      return;
+    }
+
+    mCallback->Callback(mResult);
+  }
+
+  nsCOMPtr<nsIDOMMozGetContentStateCallback> mCallback;
+  nsCOMPtr<nsIDOMEventTarget> mEventTarget;
+  const nsString mResult;
+};
+
+} // anonymous namespace
+
+nsresult
+nsGenericHTMLFrameElement::BrowserFrameSecurityCheck()
+{
+  if (!Preferences::GetBool("dom.mozBrowserFramesEnabled")) {
+    return NS_ERROR_FAILURE;
+  }
+
+  bool browser;
+  GetMozBrowser(&browser);
+  if (!browser) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsIPrincipal *principal = NodePrincipal();
+  nsCOMPtr<nsIURI> principalURI;
+  principal->GetURI(getter_AddRefs(principalURI));
+  if (!nsContentUtils::URIIsChromeOrInPref(principalURI,
+                                           "dom.mozBrowserFramesWhitelist")) {
+    return NS_ERROR_DOM_SECURITY_ERR;
+  }
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsGenericHTMLFrameElement::MozGetContentState(const nsAString &aProperty,
+                                              nsIDOMMozGetContentStateCallback *aCallback)
+{
+  nsresult rv = BrowserFrameSecurityCheck();
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  if (!aProperty.EqualsLiteral("location")) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCOMPtr<nsIDOMWindow> contentWindow;
+  GetContentWindow(getter_AddRefs(contentWindow));
+  NS_ENSURE_TRUE(contentWindow, NS_ERROR_FAILURE);
+
+  nsCOMPtr<nsIDOMLocation> location;
+  rv = contentWindow->GetLocation(getter_AddRefs(location));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsAutoString href;
+  rv = location->ToString(href);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIDOMEventTarget> eventTarget =
+    do_QueryInterface(nsContentUtils::GetWindowFromCaller());
+  NS_ENSURE_TRUE(eventTarget, NS_ERROR_FAILURE);
+
+  // Asynchronously fire the callback.
+  nsRefPtr<GetContentStateCallbackRunnable> runnable =
+    new GetContentStateCallbackRunnable(aCallback, eventTarget, href);
+  NS_DispatchToMainThread(runnable);
+  return NS_OK;
+}
+
 //----------------------------------------------------------------------
 
 nsresult
 nsGenericHTMLElement::Blur()
 {
   if (!ShouldBlur(this)) {
     return NS_OK;
   }
--- a/content/html/content/src/nsGenericHTMLElement.h
+++ b/content/html/content/src/nsGenericHTMLElement.h
@@ -42,16 +42,17 @@
 #include "nsIDOMHTMLElement.h"
 #include "nsINameSpaceManager.h"  // for kNameSpaceID_None
 #include "nsIFormControl.h"
 #include "nsIDOMHTMLFrameElement.h"
 #include "nsFrameLoader.h"
 #include "nsGkAtoms.h"
 #include "nsContentCreatorFunctions.h"
 #include "nsDOMMemoryReporter.h"
+#include "nsIDOMMozBrowserFrameElement.h"
 
 class nsIDOMAttr;
 class nsIDOMEventListener;
 class nsIDOMNodeList;
 class nsIFrame;
 class nsIStyleRule;
 class nsChildContentList;
 class nsDOMCSSDeclaration;
@@ -1014,17 +1015,18 @@ PR_STATIC_ASSERT(ELEMENT_TYPE_SPECIFIC_B
 
 //----------------------------------------------------------------------
 
 /**
  * A helper class for frame elements
  */
 
 class nsGenericHTMLFrameElement : public nsGenericHTMLElement,
-                                  public nsIFrameLoaderOwner
+                                  public nsIFrameLoaderOwner,
+                                  public nsIDOMMozBrowserFrameElement
 {
 public:
   nsGenericHTMLFrameElement(already_AddRefed<nsINodeInfo> aNodeInfo,
                             mozilla::dom::FromParser aFromParser)
     : nsGenericHTMLElement(aNodeInfo)
   {
     mNetworkCreated = aFromParser == mozilla::dom::FROM_PARSER_NETWORK;
   }
@@ -1059,24 +1061,29 @@ public:
 
   // nsIDOMHTMLElement 
   NS_IMETHOD GetTabIndex(PRInt32 *aTabIndex);
   NS_IMETHOD SetTabIndex(PRInt32 aTabIndex);
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsGenericHTMLFrameElement,
                                                      nsGenericHTMLElement)
 
+  // nsIDOMMozBrowserFrameElement
+  NS_DECL_NSIDOMMOZBROWSERFRAMEELEMENT
+
 protected:
   // This doesn't really ensure a frame loade in all cases, only when
   // it makes sense.
   nsresult EnsureFrameLoader();
   nsresult LoadSrc();
   nsresult GetContentDocument(nsIDOMDocument** aContentDocument);
   nsresult GetContentWindow(nsIDOMWindow** aContentWindow);
 
+  nsresult BrowserFrameSecurityCheck();
+
   nsRefPtr<nsFrameLoader> mFrameLoader;
   // True when the element is created by the parser
   // using NS_FROM_PARSER_NETWORK flag.
   // If the element is modified, it may lose the flag.
   bool                    mNetworkCreated;
 };
 
 //----------------------------------------------------------------------
--- a/content/html/content/src/nsHTMLAudioElement.cpp
+++ b/content/html/content/src/nsHTMLAudioElement.cpp
@@ -52,17 +52,16 @@
 #include "nsNetUtil.h"
 #include "nsXPCOMStrings.h"
 #include "prlock.h"
 #include "nsThreadUtils.h"
 
 #include "nsIScriptSecurityManager.h"
 #include "nsIXPConnect.h"
 #include "jsapi.h"
-#include "jscntxt.h"
 #include "jsfriendapi.h"
 #include "jstypedarray.h"
 #include "nsJSUtils.h"
 
 #include "nsITimer.h"
 
 #include "nsEventDispatcher.h"
 #include "nsIDOMProgressEvent.h"
@@ -192,17 +191,17 @@ nsHTMLAudioElement::MozWriteAudio(const 
     return NS_ERROR_DOM_INVALID_STATE_ERR;
   }
 
   if (JSVAL_IS_PRIMITIVE(aData)) {
     return NS_ERROR_DOM_TYPE_MISMATCH_ERR;
   }
 
   JSObject *darray = JSVAL_TO_OBJECT(aData);
-  js::AutoValueRooter tsrc_tvr(aCx);
+  JS::AutoValueRooter tsrc_tvr(aCx);
   JSObject *tsrc = NULL;
 
   // Allow either Float32Array or plain JS Array
   if (js::GetObjectClass(darray) == &js::TypedArray::fastClasses[js::TypedArray::TYPE_FLOAT32])
   {
     tsrc = js::TypedArray::getTypedArray(darray);
   } else if (JS_IsArrayObject(aCx, darray)) {
     JSObject *nobj = js_CreateTypedArrayWithArray(aCx, js::TypedArray::TYPE_FLOAT32, darray);
--- a/content/html/content/src/nsHTMLCanvasElement.cpp
+++ b/content/html/content/src/nsHTMLCanvasElement.cpp
@@ -496,52 +496,49 @@ nsHTMLCanvasElement::GetContext(const ns
 
       // note: if any contexts end up supporting something other
       // than objects, e.g. plain strings, then we'll need to expand
       // this to know how to create nsISupportsStrings etc.
       if (JSVAL_IS_OBJECT(aContextOptions)) {
         contextProps = do_CreateInstance("@mozilla.org/hash-property-bag;1");
 
         JSObject *opts = JSVAL_TO_OBJECT(aContextOptions);
-        JSIdArray *props = JS_Enumerate(cx, opts);
-        for (int i = 0; props && i < JS_IdArrayLength(cx, props); ++i) {
-          jsid propid = JS_IdArrayGet(cx, props, i);
+        JS::AutoIdArray props(cx, JS_Enumerate(cx, opts));
+        for (size_t i = 0; !!props && i < props.length(); ++i) {
+          jsid propid = props[i];
           jsval propname, propval;
           if (!JS_IdToValue(cx, propid, &propname) ||
               !JS_GetPropertyById(cx, opts, propid, &propval)) {
             continue;
           }
 
           JSString *propnameString = JS_ValueToString(cx, propname);
           nsDependentJSString pstr;
           if (!propnameString || !pstr.init(cx, propnameString)) {
-            JS_DestroyIdArray(cx, props);
             mCurrentContext = nsnull;
             return NS_ERROR_FAILURE;
           }
 
           if (JSVAL_IS_BOOLEAN(propval)) {
-            contextProps->SetPropertyAsBool(pstr, propval == JSVAL_TRUE ? true : false);
+            contextProps->SetPropertyAsBool(pstr, JSVAL_TO_BOOLEAN(propval));
           } else if (JSVAL_IS_INT(propval)) {
             contextProps->SetPropertyAsInt32(pstr, JSVAL_TO_INT(propval));
           } else if (JSVAL_IS_DOUBLE(propval)) {
             contextProps->SetPropertyAsDouble(pstr, JSVAL_TO_DOUBLE(propval));
           } else if (JSVAL_IS_STRING(propval)) {
             JSString *propvalString = JS_ValueToString(cx, propval);
             nsDependentJSString vstr;
             if (!propvalString || !vstr.init(cx, propvalString)) {
-              JS_DestroyIdArray(cx, props);
               mCurrentContext = nsnull;
               return NS_ERROR_FAILURE;
             }
 
             contextProps->SetPropertyAsAString(pstr, vstr);
           }
         }
-        JS_DestroyIdArray(cx, props);
       }
     }
 
     rv = UpdateContext(contextProps);
     if (NS_FAILED(rv)) {
       if (!forceThebes) {
         // Try again with a Thebes context
         forceThebes = true;
--- a/content/html/content/src/nsHTMLMediaElement.cpp
+++ b/content/html/content/src/nsHTMLMediaElement.cpp
@@ -1312,46 +1312,78 @@ public:
 
 typedef nsTHashtable<MediaElementSetForURI> MediaElementURITable;
 // Elements in this table must have non-null mDecoder and mLoadingSrc, and those
 // can't change while the element is in the table. The table is keyed by
 // the element's mLoadingSrc. Each entry has a list of all elements with the
 // same mLoadingSrc.
 static MediaElementURITable* gElementTable;
 
+#ifdef DEBUG
+// Returns the number of times aElement appears in the media element table
+// for aURI. If this returns other than 0 or 1, there's a bug somewhere!
+static unsigned
+MediaElementTableCount(nsHTMLMediaElement* aElement, nsIURI* aURI)
+{
+  if (!gElementTable || !aElement || !aURI) {
+    return 0;
+  }
+  MediaElementSetForURI* entry = gElementTable->GetEntry(aURI);
+  if (!entry) {
+    return 0;
+  }
+  PRUint32 count = 0;
+  for (PRUint32 i = 0; i < entry->mElements.Length(); ++i) {
+    nsHTMLMediaElement* elem = entry->mElements[i];
+    if (elem == aElement) {
+      count++;
+    }
+  }
+  return count;
+}
+#endif
+
 void
 nsHTMLMediaElement::AddMediaElementToURITable()
 {
   NS_ASSERTION(mDecoder && mDecoder->GetStream(), "Call this only with decoder Load called");
+  NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 0,
+    "Should not have entry for element in element table before addition");
   if (!gElementTable) {
     gElementTable = new MediaElementURITable();
     gElementTable->Init();
   }
   MediaElementSetForURI* entry = gElementTable->PutEntry(mLoadingSrc);
   entry->mElements.AppendElement(this);
+  NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 1,
+    "Should have a single entry for element in element table after addition");
 }
 
 void
 nsHTMLMediaElement::RemoveMediaElementFromURITable()
 {
+  NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 1,
+    "Before remove, should have a single entry for element in element table");
   NS_ASSERTION(mDecoder, "Don't call this without decoder!");
   NS_ASSERTION(mLoadingSrc, "Can't have decoder without source!");
   if (!gElementTable)
     return;
   MediaElementSetForURI* entry = gElementTable->GetEntry(mLoadingSrc);
   if (!entry)
     return;
   entry->mElements.RemoveElement(this);
   if (entry->mElements.IsEmpty()) {
     gElementTable->RemoveEntry(mLoadingSrc);
     if (gElementTable->Count() == 0) {
       delete gElementTable;
       gElementTable = nsnull;
     }
   }
+  NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 0,
+    "After remove, should no longer have an entry in element table");
 }
 
 nsHTMLMediaElement*
 nsHTMLMediaElement::LookupMediaElementURITable(nsIURI* aURI)
 {
   if (!gElementTable)
     return nsnull;
   MediaElementSetForURI* entry = gElementTable->GetEntry(aURI);
@@ -1426,16 +1458,20 @@ nsHTMLMediaElement::~nsHTMLMediaElement(
   NS_ASSERTION(!mHasSelfReference,
                "How can we be destroyed if we're still holding a self reference?");
 
   UnregisterFreezableElement();
   if (mDecoder) {
     RemoveMediaElementFromURITable();
     mDecoder->Shutdown();
   }
+
+  NS_ASSERTION(MediaElementTableCount(this, mLoadingSrc) == 0,
+    "Destroyed media element should no longer be in element table");
+
   if (mChannel) {
     mChannel->Cancel(NS_BINDING_ABORTED);
   }
   if (mAudioStream) {
     mAudioStream->Shutdown();
   }
 }
 
@@ -1946,16 +1982,17 @@ nsHTMLMediaElement::CreateDecoder(const 
   }
 #endif
   return nsnull;
 }
 
 nsresult nsHTMLMediaElement::InitializeDecoderAsClone(nsMediaDecoder* aOriginal)
 {
   NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set");
+  NS_ASSERTION(mDecoder == nsnull, "Shouldn't have a decoder");
 
   nsMediaStream* originalStream = aOriginal->GetStream();
   if (!originalStream)
     return NS_ERROR_FAILURE;
   nsRefPtr<nsMediaDecoder> decoder = aOriginal->Clone();
   if (!decoder)
     return NS_ERROR_FAILURE;
 
@@ -1985,16 +2022,17 @@ nsresult nsHTMLMediaElement::InitializeD
 
   return FinishDecoderSetup(decoder);
 }
 
 nsresult nsHTMLMediaElement::InitializeDecoderForChannel(nsIChannel *aChannel,
                                                          nsIStreamListener **aListener)
 {
   NS_ASSERTION(mLoadingSrc, "mLoadingSrc must already be set");
+  NS_ASSERTION(mDecoder == nsnull, "Shouldn't have a decoder");
 
   nsCAutoString mimeType;
   aChannel->GetContentType(mimeType);
 
   nsRefPtr<nsMediaDecoder> decoder = CreateDecoder(mimeType);
   if (!decoder) {
     nsAutoString src;
     GetCurrentSrc(src);
@@ -2054,16 +2092,25 @@ nsresult nsHTMLMediaElement::FinishDecod
       rv = mDecoder->Play();
     }
   }
 
   if (OwnerDoc()->HasAudioAvailableListeners()) {
     NotifyAudioAvailableListener();
   }
 
+  if (NS_FAILED(rv)) {
+    RemoveMediaElementFromURITable();
+    mDecoder->Shutdown();
+    mDecoder = nsnull;
+  }
+
+  NS_ASSERTION(NS_SUCCEEDED(rv) == (MediaElementTableCount(this, mLoadingSrc) == 1),
+    "Media element should have single table entry if decode initialized");
+
   mBegun = true;
   return rv;
 }
 
 nsresult nsHTMLMediaElement::NewURIFromString(const nsAutoString& aURISpec, nsIURI** aURI)
 {
   NS_ENSURE_ARG_POINTER(aURI);
 
@@ -2659,17 +2706,17 @@ nsIContent* nsHTMLMediaElement::GetNextS
 {
   nsCOMPtr<nsIDOMNode> thisDomNode = do_QueryObject(this);
 
   mSourceLoadCandidate = nsnull;
 
   nsresult rv = NS_OK;
   if (!mSourcePointer) {
     // First time this has been run, create a selection to cover children.
-    mSourcePointer = do_CreateInstance("@mozilla.org/content/range;1");
+    mSourcePointer = new nsRange();
 
     rv = mSourcePointer->SelectNodeContents(thisDomNode);
     if (NS_FAILED(rv)) return nsnull;
 
     rv = mSourcePointer->Collapse(true);
     if (NS_FAILED(rv)) return nsnull;
   }
 
--- a/content/html/content/test/test_bug389797.html
+++ b/content/html/content/test/test_bug389797.html
@@ -138,31 +138,31 @@ HTML_TAG("dt", "");
 HTML_TAG("em", "");
 HTML_TAG("embed", "Embed", [ "nsIDOMGetSVGDocument" ], objectIfaces);
 HTML_TAG("fieldset", "FieldSet");
 HTML_TAG("figcaption", "")
 HTML_TAG("figure", "")
 HTML_TAG("font", "Font");
 HTML_TAG("footer", "")
 HTML_TAG("form", "Form", [], [ "nsIWebProgressListener" ]);
-HTML_TAG("frame", "Frame", [], [ "nsIFrameLoaderOwner" ]);
+HTML_TAG("frame", "Frame", [ "nsIDOMMozBrowserFrameElement" ], [ "nsIFrameLoaderOwner" ]);
 HTML_TAG("frameset", "FrameSet");
 HTML_TAG("h1", "Heading");
 HTML_TAG("h2", "Heading");
 HTML_TAG("h3", "Heading");
 HTML_TAG("h4", "Heading");
 HTML_TAG("h5", "Heading");
 HTML_TAG("h6", "Heading");
 HTML_TAG("head", "Head");
 HTML_TAG("header", "")
 HTML_TAG("hgroup", "")
 HTML_TAG("hr", "HR");
 HTML_TAG("html", "Html");
 HTML_TAG("i", "");
-HTML_TAG("iframe", "IFrame", [ "nsIDOMGetSVGDocument" ],
+HTML_TAG("iframe", "IFrame", [ "nsIDOMGetSVGDocument", "nsIDOMMozBrowserFrameElement" ],
                              [ "nsIFrameLoaderOwner" ]);
 HTML_TAG("image", "Span");
 HTML_TAG("img", "Image", [], [ "imgIDecoderObserver",
                                "nsIImageLoadingContent" ]);
 HTML_TAG("input", "Input", [], [ "imgIDecoderObserver",
                                  "nsIImageLoadingContent",
                                  "nsIDOMNSEditableElement" ]);
 HTML_TAG("ins", "Mod");
--- a/content/html/document/src/nsHTMLDocument.cpp
+++ b/content/html/document/src/nsHTMLDocument.cpp
@@ -2521,20 +2521,17 @@ nsHTMLDocument::DeferredContentEditableC
 
       nsCOMPtr<nsIEditorDocShell> editorDocShell =
         do_QueryInterface(docshell, &rv);
       NS_ENSURE_SUCCESS(rv, );
 
       nsCOMPtr<nsIEditor> editor;
       editorDocShell->GetEditor(getter_AddRefs(editor));
       if (editor) {
-        nsCOMPtr<nsIDOMRange> range;
-        rv = NS_NewRange(getter_AddRefs(range));
-        NS_ENSURE_SUCCESS(rv, );
-
+        nsRefPtr<nsRange> range = new nsRange();
         rv = range->SelectNode(node);
         if (NS_FAILED(rv)) {
           // The node might be detached from the document at this point,
           // which would cause this call to fail.  In this case, we can
           // safely ignore the contenteditable count change.
           return;
         }
 
--- a/content/media/VideoUtils.cpp
+++ b/content/media/VideoUtils.cpp
@@ -34,16 +34,18 @@
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "VideoUtils.h"
 #include "nsMathUtils.h"
 #include "prtypes.h"
 
+#include "mozilla/StdInt.h"
+
 // Adds two 32bit unsigned numbers, retuns true if addition succeeded,
 // or false the if addition would result in an overflow.
 bool AddOverflow32(PRUint32 a, PRUint32 b, PRUint32& aResult) {
   PRUint64 rl = static_cast<PRUint64>(a) + static_cast<PRUint64>(b);
   if (rl > PR_UINT32_MAX) {
     return false;
   }
   aResult = static_cast<PRUint32>(rl);
@@ -63,21 +65,21 @@ bool MulOverflow32(PRUint32 a, PRUint32 
   aResult = static_cast<PRUint32>(r64);
   return true;
 }
 
 // Adds two 64bit numbers, retuns true if addition succeeded, or false
 // if addition would result in an overflow.
 bool AddOverflow(PRInt64 a, PRInt64 b, PRInt64& aResult) {
   if (b < 1) {
-    if (PR_INT64_MIN - b <= a) {
+    if (INT64_MIN - b <= a) {
       aResult = a + b;
       return true;
     }
-  } else if (PR_INT64_MAX - b >= a) {
+  } else if (INT64_MAX - b >= a) {
     aResult = a + b;
     return true;
   }
   return false;
 }
 
 // 64 bit integer multiplication with overflow checking. Returns true
 // if the multiplication was successful, or false if the operation resulted
@@ -94,38 +96,38 @@ bool MulOverflow(PRInt64 a, PRInt64 b, P
   // (sign_a * sign_b) *
   // ((a_hi * b_hi << 64) +
   //  (a_hi * b_lo << 32) + (a_lo * b_hi << 32) +
   //   a_lo * b_lo)
   //
   // So to check if a*b overflows, we must check each sub part of the above
   // sum.
   //
-  // Note: -1 * PR_INT64_MIN == PR_INT64_MIN ; we can't negate PR_INT64_MIN!
+  // Note: -1 * INT64_MIN == INT64_MIN ; we can't negate INT64_MIN!
   // Note: Shift of negative numbers is undefined.
   //
   // Figure out the sign after multiplication. Then we can just work with
   // unsigned numbers.
   PRInt64 sign = (!(a < 0) == !(b < 0)) ? 1 : -1;
 
   PRInt64 abs_a = (a < 0) ? -a : a;
   PRInt64 abs_b = (b < 0) ? -b : b;
 
   if (abs_a < 0) {
-    NS_ASSERTION(a == PR_INT64_MIN, "How else can this happen?");
+    NS_ASSERTION(a == INT64_MIN, "How else can this happen?");
     if (b == 0 || b == 1) {
       aResult = a * b;
       return true;
     } else {
       return false;
     }
   }
 
   if (abs_b < 0) {
-    NS_ASSERTION(b == PR_INT64_MIN, "How else can this happen?");
+    NS_ASSERTION(b == INT64_MIN, "How else can this happen?");
     if (a == 0 || a == 1) {
       aResult = a * b;
       return true;
     } else {
       return false;
     }
   }
 
@@ -157,17 +159,17 @@ bool MulOverflow(PRInt64 a, PRInt64 b, P
   if (q > PR_INT32_MAX) {
     // q will overflow when we shift by 32; abort.
     return false;
   }
   q <<= 32;
 
   // Both a_lo and b_lo are less than INT32_MAX, so can't overflow.
   PRUint64 lo = a_lo * b_lo;
-  if (lo > PR_INT64_MAX) {
+  if (lo > INT64_MAX) {
     return false;
   }
 
   // Add the final result. We must check for overflow during addition.
   if (!AddOverflow(q, static_cast<PRInt64>(lo), aResult)) {
     return false;
   }
 
--- a/content/media/VideoUtils.h
+++ b/content/media/VideoUtils.h
@@ -44,29 +44,16 @@
 #include "nsRect.h"
 #include "nsIThreadManager.h"
 
 // This file contains stuff we'd rather put elsewhere, but which is
 // dependent on other changes which we don't want to wait for. We plan to
 // remove this file in the near future.
 
 
-// This belongs in prtypes.h
-/************************************************************************
- * MACROS:      PR_INT64_MAX
- *              PR_INT64_MIN
- *              PR_UINT64_MAX
- * DESCRIPTION:
- *  The maximum and minimum values of a PRInt64 or PRUint64.
-************************************************************************/
-
-#define PR_INT64_MAX (~((PRInt64)(1) << 63))
-#define PR_INT64_MIN (-PR_INT64_MAX - 1)
-#define PR_UINT64_MAX (~(PRUint64)(0))
-
 // This belongs in xpcom/monitor/Monitor.h, once we've made
 // mozilla::Monitor non-reentrant.
 namespace mozilla {
 
 /**
  * ReentrantMonitorAutoExit
  * Exit the ReentrantMonitor when it enters scope, and enters it when it leaves 
  * scope.
--- a/content/media/nsBuiltinDecoder.cpp
+++ b/content/media/nsBuiltinDecoder.cpp
@@ -197,22 +197,24 @@ nsresult nsBuiltinDecoder::Load(nsMediaS
       return rv;
     }
 
     mStream = aStream;
   }
 
   mDecoderStateMachine = CreateStateMachine();
   if (!mDecoderStateMachine) {
+    LOG(PR_LOG_DEBUG, ("%p Failed to create state machine!", this));
     return NS_ERROR_FAILURE;
   }
 
   nsBuiltinDecoder* cloneDonor = static_cast<nsBuiltinDecoder*>(aCloneDonor);
   if (NS_FAILED(mDecoderStateMachine->Init(cloneDonor ?
                                            cloneDonor->mDecoderStateMachine : nsnull))) {
+    LOG(PR_LOG_DEBUG, ("%p Failed to init state machine!", this));
     return NS_ERROR_FAILURE;
   }
   {
     ReentrantMonitorAutoEnter mon(mReentrantMonitor);
     mDecoderStateMachine->SetSeekable(mSeekable);
     mDecoderStateMachine->SetDuration(mDuration);
     
     if (mFrameBufferLength > 0) {
--- a/content/media/nsBuiltinDecoderReader.cpp
+++ b/content/media/nsBuiltinDecoderReader.cpp
@@ -38,18 +38,20 @@
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISeekableStream.h"
 #include "nsClassHashtable.h"
 #include "nsTArray.h"
 #include "nsBuiltinDecoder.h"
 #include "nsBuiltinDecoderReader.h"
 #include "nsBuiltinDecoderStateMachine.h"
+#include "VideoUtils.h"
+
 #include "mozilla/mozalloc.h"
-#include "VideoUtils.h"
+#include "mozilla/StdInt.h"
 
 using namespace mozilla;
 using mozilla::layers::ImageContainer;
 using mozilla::layers::PlanarYCbCrImage;
 
 // Verify these values are sane. Once we've checked the frame sizes, we then
 // can do less integer overflow checking.
 PR_STATIC_ASSERT(MAX_VIDEO_WIDTH < PlanarYCbCrImage::MAX_DIMENSION);
@@ -211,18 +213,18 @@ nsresult nsBuiltinDecoderReader::ResetDe
 
 VideoData* nsBuiltinDecoderReader::FindStartTime(PRInt64& aOutStartTime)
 {
   NS_ASSERTION(mDecoder->OnStateMachineThread() || mDecoder->OnDecodeThread(),
                "Should be on state machine or decode thread.");
 
   // Extract the start times of the bitstreams in order to calculate
   // the duration.
-  PRInt64 videoStartTime = PR_INT64_MAX;
-  PRInt64 audioStartTime = PR_INT64_MAX;
+  PRInt64 videoStartTime = INT64_MAX;
+  PRInt64 audioStartTime = INT64_MAX;
   VideoData* videoData = nsnull;
 
   if (HasVideo()) {
     videoData = DecodeToFirstData(&nsBuiltinDecoderReader::DecodeVideoFrame,
                                   mVideoQueue);
     if (videoData) {
       videoStartTime = videoData->mTime;
     }
@@ -231,17 +233,17 @@ VideoData* nsBuiltinDecoderReader::FindS
     AudioData* audioData = DecodeToFirstData(&nsBuiltinDecoderReader::DecodeAudioData,
                                              mAudioQueue);
     if (audioData) {
       audioStartTime = audioData->mTime;
     }
   }
 
   PRInt64 startTime = NS_MIN(videoStartTime, audioStartTime);
-  if (startTime != PR_INT64_MAX) {
+  if (startTime != INT64_MAX) {
     aOutStartTime = startTime;
   }
 
   return videoData;
 }
 
 template<class Data>
 Data* nsBuiltinDecoderReader::DecodeToFirstData(DecodeFn aDecodeFn,
--- a/content/media/nsBuiltinDecoderStateMachine.cpp
+++ b/content/media/nsBuiltinDecoderStateMachine.cpp
@@ -40,17 +40,19 @@
 #include "nsAudioStream.h"
 #include "nsTArray.h"
 #include "nsBuiltinDecoder.h"
 #include "nsBuiltinDecoderReader.h"
 #include "nsBuiltinDecoderStateMachine.h"
 #include "mozilla/mozalloc.h"
 #include "VideoUtils.h"
 #include "nsTimeRanges.h"
+
 #include "mozilla/Preferences.h"
+#include "mozilla/StdInt.h"
 
 using namespace mozilla;
 using namespace mozilla::layers;
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gBuiltinDecoderLog;
 #define LOG(type, msg) PR_LOG(gBuiltinDecoderLog, type, msg)
 #else
@@ -1157,17 +1159,17 @@ void nsBuiltinDecoderStateMachine::Seek(
   ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
   // nsBuiltinDecoder::mPlayState should be SEEKING while we seek, and
   // in that case nsBuiltinDecoder shouldn't be calling us.
   NS_ASSERTION(mState != DECODER_STATE_SEEKING,
                "We shouldn't already be seeking");
   NS_ASSERTION(mState >= DECODER_STATE_DECODING,
                "We should have loaded metadata");
   double t = aTime * static_cast<double>(USECS_PER_S);
-  if (t > PR_INT64_MAX) {
+  if (t > INT64_MAX) {
     // Prevent integer overflow.
     return;
   }
 
   mSeekTime = static_cast<PRInt64>(t) + mStartTime;
   NS_ASSERTION(mSeekTime >= mStartTime && mSeekTime <= mEndTime,
                "Can only seek in range [0,duration]");
 
--- a/content/media/ogg/nsOggCodecState.cpp
+++ b/content/media/ogg/nsOggCodecState.cpp
@@ -39,16 +39,18 @@
 #include "nsDebug.h"
 #include "nsOggCodecState.h"
 #include "nsOggDecoder.h"
 #include <string.h>
 #include "nsTraceRefcnt.h"
 #include "VideoUtils.h"
 #include "nsBuiltinDecoderReader.h"
 
+#include "mozilla/StdInt.h"
+
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gBuiltinDecoderLog;
 #define LOG(type, msg) PR_LOG(gBuiltinDecoderLog, type, msg)
 #else
 #define LOG(type, msg)
 #endif
 
 nsOggCodecState*
@@ -1040,18 +1042,18 @@ nsresult nsSkeletonState::GetDuration(co
 {
   if (!mActive ||
       mVersion < SKELETON_VERSION(4,0) ||
       !HasIndex() ||
       aTracks.Length() == 0)
   {