Merge from mozilla-central.
authorDavid Anderson <danderson@mozilla.com>
Wed, 11 Jan 2012 14:11:45 -0800
changeset 109148 91c7d8b9c9e96bed8c5f867ccd98fed385638c48
parent 109147 6e4acb5ff1b82b0fdf4b3849380124f587b4669c (current diff)
parent 85497 7c7d2a8db7ffd00d817249c1cfd3939465418894 (diff)
child 109149 a12010ca115a11b5b6701cbc16dcf7910637941e
push id2248
push userakeybl@mozilla.com
push dateMon, 08 Oct 2012 19:23:44 +0000
treeherdermozilla-aurora@118a3b748323 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone12.0a1
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) {