Merge backout of bug 830347.
authorKyle Huey <khuey@kylehuey.com>
Wed, 08 May 2013 12:06:17 -0700
changeset 138069 570a6739752c542d3c27a40fa82b9ce6db91345a
parent 138068 24d361942d24229dd9fdebbe2f5cdb2fcb908881 (current diff)
parent 138055 948efc855b5b2185990d94f136df33ffe8f264a6 (diff)
child 138070 fb709d42a984240d740de5aa2eb507d1afe878ae
push id3752
push userlsblakk@mozilla.com
push dateMon, 13 May 2013 17:21:10 +0000
treeherdermozilla-aurora@1580544aef0b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs830347
milestone23.0a1
Merge backout of bug 830347.
browser/metro/components/CapturePicker.js
gfx/2d/ScaledFontFreetype.cpp
gfx/2d/ScaledFontFreetype.h
gfx/layers/Makefile.in
gfx/layers/moz.build
js/src/vm/ParallelDo.cpp
js/src/vm/ParallelDo.h
layout/base/tests/cpp-tests/Makefile.in
layout/base/tests/cpp-tests/TestPoisonArea.cpp
layout/base/tests/cpp-tests/moz.build
netwerk/protocol/device/GonkCaptureProvider.cpp
netwerk/protocol/device/GonkCaptureProvider.h
netwerk/protocol/device/gonk/Camera.h
netwerk/protocol/device/gonk/CameraHardwareInterface.h
netwerk/protocol/device/gonk/CameraParameters.h
netwerk/protocol/device/gonk/ICameraClient.h
--- a/accessible/src/base/nsAccUtils.cpp
+++ b/accessible/src/base/nsAccUtils.cpp
@@ -434,23 +434,26 @@ nsAccUtils::TextLength(Accessible* aAcce
   return text.Length();
 }
 
 bool
 nsAccUtils::MustPrune(Accessible* aAccessible)
 { 
   roles::Role role = aAccessible->Role();
 
-  // We don't prune buttons any more however AT don't expect children inside of
-  // button in general, we allow menu buttons to have children to make them
-  // accessible.
-  return role == roles::MENUITEM || 
-    role == roles::COMBOBOX_OPTION ||
-    role == roles::OPTION ||
-    role == roles::ENTRY ||
-    role == roles::FLAT_EQUATION ||
-    role == roles::PASSWORD_TEXT ||
-    role == roles::TOGGLE_BUTTON ||
-    role == roles::GRAPHIC ||
-    role == roles::SLIDER ||
-    role == roles::PROGRESSBAR ||
-    role == roles::SEPARATOR;
+  // Don't prune the tree for certain roles if the tree is more complex than
+  // a single text leaf.
+  return
+    (role == roles::MENUITEM ||
+     role == roles::COMBOBOX_OPTION ||
+     role == roles::OPTION ||
+     role == roles::ENTRY ||
+     role == roles::FLAT_EQUATION ||
+     role == roles::PASSWORD_TEXT ||
+     role == roles::PUSHBUTTON ||
+     role == roles::TOGGLE_BUTTON ||
+     role == roles::GRAPHIC ||
+     role == roles::SLIDER ||
+     role == roles::PROGRESSBAR ||
+     role == roles::SEPARATOR) &&
+    aAccessible->ContentChildCount() == 1 &&
+    aAccessible->ContentChildAt(0)->IsTextLeaf();
 }
--- a/accessible/src/generic/HyperTextAccessible.cpp
+++ b/accessible/src/generic/HyperTextAccessible.cpp
@@ -1065,19 +1065,16 @@ HyperTextAccessible::GetTextAtOffset(int
 {
   if (IsDefunct())
     return NS_ERROR_FAILURE;
 
   int32_t offset = ConvertMagicOffset(aOffset);
   if (offset < 0)
     return NS_ERROR_INVALID_ARG;
 
-  EWordMovementType wordMovementType = eDefaultBehavior;
-  bool moveForwardThenBack = true;
-
   switch (aBoundaryType) {
     case BOUNDARY_CHAR:
       return GetCharAt(aOffset, eGetAt, aText, aStartOffset, aEndOffset) ?
         NS_OK : NS_ERROR_INVALID_ARG;
 
     case BOUNDARY_WORD_START:
       *aEndOffset = FindWordBoundary(offset, eDirNext, eStartWord);
       *aStartOffset = FindWordBoundary(*aEndOffset, eDirPrevious, eStartWord);
--- a/accessible/tests/mochitest/hittest/test_general.html
+++ b/accessible/tests/mochitest/hittest/test_general.html
@@ -44,17 +44,17 @@ if (!MAC) {
       testChildAtPoint(txt, -1, 1, null, null);
 
       // ::MustPrune case, point is outside of root accessible.
       testChildAtPoint(txt, -10000, 10000, null, null);
 
       // Not specific case, point is inside of btn accessible.
       var btn = getAccessible("btn");
       var btnText = btn.firstChild;
-      testChildAtPoint(btn, 1, 1, btnText, btnText);
+      testChildAtPoint(btn, 1, 1, btn, btn);
   
       // Not specific case, point is outside of btn accessible.
       testChildAtPoint(btn, -1, 1, null, null);
 
       // Out of flow accessible testing, do not return out of flow accessible
       // because it's not a child of the accessible even visually it is.
       var rectArea = getNode("area").getBoundingClientRect();
       var outOfFlow = getNode("outofflow");
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/data/testLocalXhr.json
@@ -0,0 +1,1 @@
+{}
--- a/addon-sdk/source/doc/dev-guide-source/guides/content-scripts/communicating-with-other-scripts.md
+++ b/addon-sdk/source/doc/dev-guide-source/guides/content-scripts/communicating-with-other-scripts.md
@@ -16,17 +16,17 @@ included using `<script>` tags)
 ## main.js ##
 
 Your content scripts can communicate with your add-on's "main.js"
 (or any other modules you're written for your add-on) by sending it messages,
 using either the `port.emit()` API or the `postMessage()` API. See the
 articles on
 [using `postMessage()`](dev-guide/guides/content-scripts/using-postmessage.html)
 and
-[using `port`](dev-guide/guides/content-scripts//using-port.html) for details.
+[using `port`](dev-guide/guides/content-scripts/using-port.html) for details.
 
 ## Content Scripts ##
 
 Content scripts loaded into the same document can interact
 with each other directly as well as with the web content itself. However,
 content scripts which have been loaded into different documents
 cannot interact with each other.
 
--- a/addon-sdk/source/lib/sdk/context-menu.js
+++ b/addon-sdk/source/lib/sdk/context-menu.js
@@ -6,17 +6,17 @@
 module.metadata = {
   "stability": "stable"
 };
 
 const { Class, mix } = require("./core/heritage");
 const { addCollectionProperty } = require("./util/collection");
 const { ns } = require("./core/namespace");
 const { validateOptions, getTypeOf } = require("./deprecated/api-utils");
-const { URL } = require("./url");
+const { URL, isValidURI } = require("./url");
 const { WindowTracker, browserWindowIterator } = require("./deprecated/window-utils");
 const { isBrowser, getInnerId } = require("./window/utils");
 const { Ci } = require("chrome");
 const { MatchPattern } = require("./page-mod/match-pattern");
 const { Worker } = require("./content/worker");
 const { EventTarget } = require("./event/target");
 const { emit } = require('./event/core');
 const { when } = require('./system/unload');
@@ -259,17 +259,23 @@ let labelledItemRules =  mix(baseItemRul
   label: {
     map: stringOrNull,
     is: ["string"],
     ok: function (v) !!v,
     msg: "The item must have a non-empty string label."
   },
   image: {
     map: stringOrNull,
-    is: ["string", "undefined", "null"]
+    is: ["string", "undefined", "null"],
+    ok: function (url) {
+      if (!url)
+        return true;
+      return isValidURI(url);
+    },
+    msg: "Image URL validation failed"
   }
 });
 
 // Additional validation rules for Item
 let itemRules = mix(labelledItemRules, {
   data: {
     map: stringOrNull,
     is: ["string", "undefined", "null"]
--- a/addon-sdk/source/lib/sdk/io/data.js
+++ b/addon-sdk/source/lib/sdk/io/data.js
@@ -5,50 +5,75 @@
 "use strict";
 
 module.metadata = {
   "stability": "unstable"
 };
 
 const { Cc, Ci, Cu } = require("chrome");
 const base64 = require("../base64");
+const { defer } = require("../core/promise");
+const { newURI } = require("../url/utils");
 
 const IOService = Cc["@mozilla.org/network/io-service;1"].
   getService(Ci.nsIIOService);
 
+const { deprecateFunction } = require('../util/deprecate');
 const { NetUtil } = Cu.import("resource://gre/modules/NetUtil.jsm");
 const FaviconService = Cc["@mozilla.org/browser/favicon-service;1"].
                           getService(Ci.nsIFaviconService);
-const { deprecateFunction } = require("../util/deprecate");
+const AsyncFavicons = FaviconService.QueryInterface(Ci.mozIAsyncFavicons);
 
 const PNG_B64 = "data:image/png;base64,";
 const DEF_FAVICON_URI = "chrome://mozapps/skin/places/defaultFavicon.png";
 let   DEF_FAVICON = null;
 
 /**
+ * Takes URI of the page and returns a promise that resolves
+ * to the page's favicon URI.
+ * @param {String} uri
+ * @param {Function} (callback)
+ * @returns {Promise}
+ */
+
+exports.getFavicon = function getFavicon(uri, callback) {
+  let pageURI = newURI(uri);
+  let deferred = defer();
+  AsyncFavicons.getFaviconURLForPage(pageURI, function (aURI) {
+    if (aURI && aURI.spec)
+      deferred.resolve(aURI.spec.toString());
+    else
+      deferred.reject(null);
+  });
+  if (callback) deferred.promise.then(callback, callback);
+  return deferred.promise;
+};
+
+/**
  * Takes URI of the page and returns associated favicon URI.
  * If page under passed uri has no favicon then base64 encoded data URI of
  * default faveicon is returned.
  * @param {String} uri
  * @returns {String}
  */
-exports.getFaviconURIForLocation = function getFaviconURIForLocation(uri) {
+function getFaviconURIForLocation(uri) {
   let pageURI = NetUtil.newURI(uri);
   try {
     return FaviconService.getFaviconDataAsDataURL(
                   FaviconService.getFaviconForPage(pageURI));
   }
   catch(e) {
     if (!DEF_FAVICON) {
       DEF_FAVICON = PNG_B64 +
                     base64.encode(getChromeURIContent(DEF_FAVICON_URI));
     }
     return DEF_FAVICON;
   }
 }
+exports.getFaviconURIForLocation = getFaviconURIForLocation;
 
 /**
  * Takes chrome URI and returns content under that URI.
  * @param {String} chromeURI
  * @returns {String}
  */
 function getChromeURIContent(chromeURI) {
   let channel = IOService.newChannel(chromeURI, null, null);
--- a/addon-sdk/source/lib/sdk/test/httpd.js
+++ b/addon-sdk/source/lib/sdk/test/httpd.js
@@ -506,17 +506,17 @@ nsHttpServer.prototype =
       }
 
       var socket = new ServerSocket(this._port,
                                     loopback, // true = localhost, false = everybody
                                     maxConnections);
       dumpn(">>> listening on port " + socket.port + ", " + maxConnections +
             " pending connections");
       socket.asyncListen(this);
-      this._identity._initialize(port, host, true);
+      this._identity._initialize(socket.port, host, true);
       this._socket = socket;
     }
     catch (e)
     {
       dumpn("!!! could not start server on port " + port + ": " + e);
       throw Cr.NS_ERROR_NOT_AVAILABLE;
     }
   },
@@ -5173,17 +5173,16 @@ function server(port, basePath)
 
   // if you're running this, you probably want to see debugging info
   DEBUG = true;
 
   var srv = new nsHttpServer();
   if (lp)
     srv.registerDirectory("/", lp);
   srv.registerContentType("sjs", SJS_TYPE);
-  srv.identity.setPrimary("http", "localhost", port);
   srv.start(port);
 
   var thread = gThreadManager.currentThread;
   while (!srv.isStopped())
     thread.processNextEvent(true);
 
   // get rid of any pending requests
   while (thread.hasPendingEvents())
@@ -5200,17 +5199,16 @@ function startServerAsync(port, basePath
                .createInstance(Ci.nsILocalFile);
     lp.initWithPath(basePath);
   }
 
   var srv = new nsHttpServer();
   if (lp)
     srv.registerDirectory("/", lp);
   srv.registerContentType("sjs", "sjs");
-  srv.identity.setPrimary("http", "localhost", port);
   srv.start(port);
   return srv;
 }
 
 exports.nsHttpServer = nsHttpServer;
 exports.ScriptableInputStream = ScriptableInputStream;
 exports.server = server;
 exports.startServerAsync = startServerAsync;
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/lib/sdk/url/utils.js
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+"use strict";
+
+module.metadata = {
+  "stability": "experimental"
+};
+
+const { Cc, Ci, Cr } = require("chrome");
+const IOService = Cc["@mozilla.org/network/io-service;1"].
+                    getService(Ci.nsIIOService);
+const { isValidURI } = require("../url");
+    
+function newURI (uri) {
+  if (!isValidURI(uri))
+    throw new Error("malformed URI: " + uri);
+  return IOService.newURI(uri, null, null);
+}
+exports.newURI = newURI;
--- a/addon-sdk/source/python-lib/cuddlefish/__init__.py
+++ b/addon-sdk/source/python-lib/cuddlefish/__init__.py
@@ -894,17 +894,19 @@ def run(arguments=sys.argv[1:], target_c
         # Generate xpi filepath
         xpi_path = XPI_FILENAME % target_cfg.name
         print >>stdout, "Exporting extension to %s." % xpi_path
         build_xpi(template_root_dir=app_extension_dir,
                   manifest=manifest_rdf,
                   xpi_path=xpi_path,
                   harness_options=harness_options,
                   limit_to=used_files,
-                  extra_harness_options=extra_harness_options)
+                  extra_harness_options=extra_harness_options,
+                  bundle_sdk=True,
+                  pkgdir=options.pkgdir)
     else:
         from cuddlefish.runner import run_app
 
         if options.profiledir:
             options.profiledir = os.path.expanduser(options.profiledir)
             options.profiledir = os.path.abspath(options.profiledir)
 
         if options.addons is not None:
@@ -926,17 +928,18 @@ def run(arguments=sys.argv[1:], target_c
                              extra_environment=extra_environment,
                              norun=options.no_run,
                              used_files=used_files,
                              enable_mobile=options.enable_mobile,
                              mobile_app_name=options.mobile_app_name,
                              env_root=env_root,
                              is_running_tests=(command == "test"),
                              overload_modules=options.overload_modules,
-                             bundle_sdk=options.bundle_sdk)
+                             bundle_sdk=options.bundle_sdk,
+                             pkgdir=options.pkgdir)
         except ValueError, e:
             print ""
             print "A given cfx option has an inappropriate value:"
             print >>sys.stderr, "  " + "  \n  ".join(str(e).split("\n"))
             retval = -1
         except Exception, e:
             if str(e).startswith(MOZRUNNER_BIN_NOT_FOUND):
                 print >>sys.stderr, MOZRUNNER_BIN_NOT_FOUND_HELP.strip()
--- a/addon-sdk/source/python-lib/cuddlefish/runner.py
+++ b/addon-sdk/source/python-lib/cuddlefish/runner.py
@@ -25,17 +25,17 @@ FILTER_ONLY_CONSOLE_FROM_ADB = re.compil
 
 # Used to detect the currently running test
 PARSEABLE_TEST_NAME = re.compile(r'TEST-START \| ([^\n]+)\n')
 
 # Maximum time we'll wait for tests to finish, in seconds.
 # The purpose of this timeout is to recover from infinite loops.  It should be
 # longer than the amount of time any test run takes, including those on slow
 # machines running slow (debug) versions of Firefox.
-RUN_TIMEOUT = 30 * 60 # 30 minutes
+RUN_TIMEOUT = 45 * 60 # 45 minutes
 
 # Maximum time we'll wait for tests to emit output, in seconds.
 # The purpose of this timeout is to recover from hangs.  It should be longer
 # than the amount of time any test takes to report results.
 OUTPUT_TIMEOUT = 60 # one minute
 
 def follow_file(filename):
     """
@@ -407,17 +407,18 @@ def run_app(harness_root_dir, manifest_r
             parseable=False, enforce_timeouts=False,
             logfile=None, addons=None, args=None, extra_environment={},
             norun=None,
             used_files=None, enable_mobile=False,
             mobile_app_name=None,
             env_root=None,
             is_running_tests=False,
             overload_modules=False,
-            bundle_sdk=True):
+            bundle_sdk=True,
+            pkgdir=""):
     if binary:
         binary = os.path.expanduser(binary)
 
     if addons is None:
         addons = []
     else:
         addons = list(addons)
 
@@ -511,17 +512,18 @@ def run_app(harness_root_dir, manifest_r
     # We delete it below after getting mozrunner to create the profile.
     from cuddlefish.xpi import build_xpi
     xpi_path = tempfile.mktemp(suffix='cfx-tmp.xpi')
     build_xpi(template_root_dir=harness_root_dir,
               manifest=manifest_rdf,
               xpi_path=xpi_path,
               harness_options=harness_options,
               limit_to=used_files,
-              bundle_sdk=bundle_sdk)
+              bundle_sdk=bundle_sdk,
+              pkgdir=pkgdir)
     addons.append(xpi_path)
 
     starttime = last_output_time = time.time()
 
     # Redirect runner output to a file so we can catch output not generated
     # by us.
     # In theory, we could do this using simple redirection on all platforms
     # other than Windows, but this way we only have a single codepath to
--- a/addon-sdk/source/python-lib/cuddlefish/xpi.py
+++ b/addon-sdk/source/python-lib/cuddlefish/xpi.py
@@ -18,32 +18,63 @@ def make_zipfile_path(localroot, localpa
 
 def mkzipdir(zf, path):
     dirinfo = zipfile.ZipInfo(path)
     dirinfo.external_attr = int("040755", 8) << 16L
     zf.writestr(dirinfo, "")
 
 def build_xpi(template_root_dir, manifest, xpi_path,
               harness_options, limit_to=None, extra_harness_options={},
-              bundle_sdk=True):
+              bundle_sdk=True, pkgdir=""):
+    IGNORED_FILES = [".hgignore", ".DS_Store", "install.rdf",
+                     "application.ini", xpi_path]
+
+    files_to_copy = {} # maps zipfile path to local-disk abspath
+    dirs_to_create = set() # zipfile paths, no trailing slash
+
     zf = zipfile.ZipFile(xpi_path, "w", zipfile.ZIP_DEFLATED)
 
     open('.install.rdf', 'w').write(str(manifest))
     zf.write('.install.rdf', 'install.rdf')
     os.remove('.install.rdf')
 
     # Handle add-on icon
     if 'icon' in harness_options:
         zf.write(str(harness_options['icon']), 'icon.png')
         del harness_options['icon']
 
     if 'icon64' in harness_options:
         zf.write(str(harness_options['icon64']), 'icon64.png')
         del harness_options['icon64']
 
+    # chrome.manifest
+    if os.path.isfile(os.path.join(pkgdir, 'chrome.manifest')):
+      files_to_copy['chrome.manifest'] = os.path.join(pkgdir, 'chrome.manifest')
+
+    # chrome folder (would contain content, skin, and locale folders typically)
+    folder = 'chrome'
+    if os.path.exists(os.path.join(pkgdir, folder)):
+      dirs_to_create.add('chrome')
+      # cp -r folder
+      abs_dirname = os.path.join(pkgdir, folder)
+      for dirpath, dirnames, filenames in os.walk(abs_dirname):
+          goodfiles = list(filter_filenames(filenames, IGNORED_FILES))
+          dirnames[:] = filter_dirnames(dirnames)
+          for dirname in dirnames:
+            arcpath = make_zipfile_path(template_root_dir,
+                                        os.path.join(dirpath, dirname))
+            dirs_to_create.add(arcpath)
+          for filename in goodfiles:
+              abspath = os.path.join(dirpath, filename)
+              arcpath = ZIPSEP.join(
+                  [folder,
+                   make_zipfile_path(abs_dirname, os.path.join(dirpath, filename)),
+                   ])
+              files_to_copy[str(arcpath)] = str(abspath)
+
     # Handle simple-prefs
     if 'preferences' in harness_options:
         from options_xul import parse_options, validate_prefs
 
         validate_prefs(harness_options["preferences"])
 
         opts_xul = parse_options(harness_options["preferences"],
                                  harness_options["jetpackID"])
@@ -58,22 +89,16 @@ def build_xpi(template_root_dir, manifes
 
     else:
         open('.prefs.js', 'wb').write("")
 
     zf.write('.prefs.js', 'defaults/preferences/prefs.js')
     os.remove('.prefs.js')
 
 
-    IGNORED_FILES = [".hgignore", ".DS_Store", "install.rdf",
-                     "application.ini", xpi_path]
-
-    files_to_copy = {} # maps zipfile path to local-disk abspath
-    dirs_to_create = set() # zipfile paths, no trailing slash
-
     for dirpath, dirnames, filenames in os.walk(template_root_dir):
         filenames = list(filter_filenames(filenames, IGNORED_FILES))
         dirnames[:] = filter_dirnames(dirnames)
         for dirname in dirnames:
             arcpath = make_zipfile_path(template_root_dir,
                                         os.path.join(dirpath, dirname))
             dirs_to_create.add(arcpath)
         for filename in filenames:
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/addons/chrome/chrome.manifest
@@ -0,0 +1,5 @@
+content    test    chrome/content/
+skin       test    classic/1.0 chrome/skin/
+
+locale     test  en-US  chrome/locale/en-US/
+locale     test  ja-JP  chrome/locale/ja-JP/
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/addons/chrome/chrome/content/new-window.xul
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+        windowtype="test:window">
+</dialog>
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/addons/chrome/chrome/locale/en-US/description.properties
@@ -0,0 +1,1 @@
+test=Test
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/addons/chrome/chrome/locale/ja-JP/description.properties
@@ -0,0 +1,1 @@
+test=テスト
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/addons/chrome/chrome/skin/style.css
@@ -0,0 +1,1 @@
+test{}
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/addons/chrome/main.js
@@ -0,0 +1,68 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+'use strict'
+
+const { Cu, Cc, Ci } = require('chrome');
+const Request = require('sdk/request').Request;
+const { WindowTracker } = require('sdk/deprecated/window-utils');
+const { close, open } = require('sdk/window/helpers');
+
+const XUL_URL = 'chrome://test/content/new-window.xul'
+
+const { Services } = Cu.import('resource://gre/modules/Services.jsm', {});
+const { NetUtil } = Cu.import('resource://gre/modules/NetUtil.jsm', {});
+
+exports.testChromeSkin = function(assert, done) {
+  let skinURL = 'chrome://test/skin/style.css';
+
+  Request({
+    url: skinURL,
+    overrideMimeType: 'text/plain',
+    onComplete: function (response) {
+      assert.equal(response.text, 'test{}\n', 'chrome.manifest skin folder was registered!');
+      done();
+    }
+  }).get();
+
+  assert.pass('requesting ' + skinURL);
+}
+
+exports.testChromeContent = function(assert, done) {
+  let wt = WindowTracker({
+    onTrack: function(window) {
+      if (window.document.documentElement.getAttribute('windowtype') === 'test:window') {
+      	assert.pass('test xul window was opened');
+        wt.unload();
+
+      	close(window).then(done, assert.fail);
+      }
+    }
+  });
+
+  open(XUL_URL).then(
+    assert.pass.bind(assert, 'opened ' + XUL_URL),
+    assert.fail);
+
+  assert.pass('opening ' + XUL_URL);
+}
+
+exports.testChromeLocale = function(assert) {
+  let jpLocalePath = Cc['@mozilla.org/chrome/chrome-registry;1'].
+                       getService(Ci.nsIChromeRegistry).
+                       convertChromeURL(NetUtil.newURI('chrome://test/locale/description.properties')).
+                       spec.replace(/(en\-US|ja\-JP)/, 'ja-JP');
+  let enLocalePath = jpLocalePath.replace(/ja\-JP/, 'en-US');
+
+  let jpStringBundle = Services.strings.createBundle(jpLocalePath);
+  assert.equal(jpStringBundle.GetStringFromName('test'),
+               'テスト',
+               'locales ja-JP folder was copied correctly');
+
+  let enStringBundle = Services.strings.createBundle(enLocalePath);
+  assert.equal(enStringBundle.GetStringFromName('test'),
+               'Test',
+               'locales en-US folder was copied correctly');
+}
+
+require('sdk/test/runner').runTestsFromModule(module);
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/addons/chrome/package.json
@@ -0,0 +1,3 @@
+{
+  "id": "test-chrome"
+}
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/favicon-helpers.js
@@ -0,0 +1,74 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const { Cc, Ci, Cu } = require('chrome');
+const { Loader } = require('sdk/test/loader');
+const loader = Loader(module);
+const file = require('sdk/io/file');
+const httpd = loader.require('sdk/test/httpd');
+const { pathFor } = require('sdk/system');
+const { startServerAsync } = httpd;
+const basePath = pathFor('ProfD');
+const { atob } = Cu.import("resource://gre/modules/Services.jsm", {});
+const historyService = Cc["@mozilla.org/browser/nav-history-service;1"]
+                       .getService(Ci.nsINavHistoryService);
+Cu.import('resource://gre/modules/XPCOMUtils.jsm');
+const ObserverShimMethods = ['onBeginUpdateBatch', 'onEndUpdateBatch',
+  'onVisit', 'onTitleChanged', 'onDeleteURI', 'onClearHistory',
+  'onPageChanged', 'onDeleteVisits'];
+
+/*
+ * Shims NavHistoryObserver
+ */
+
+let noop = function () {}
+let NavHistoryObserver = function () {};
+ObserverShimMethods.forEach(function (method) {
+  NavHistoryObserver.prototype[method] = noop;
+});
+NavHistoryObserver.prototype.QueryInterface = XPCOMUtils.generateQI([
+  Ci.nsINavHistoryObserver
+]);
+
+/*
+ * Uses history observer to watch for an onPageChanged event,
+ * which detects when a favicon is updated in the registry.
+ */
+function onFaviconChange (uri, callback) {
+  let observer = Object.create(NavHistoryObserver.prototype, {
+    onPageChanged: {
+      value: function onPageChanged(aURI, aWhat, aValue, aGUID) {
+        if (aWhat !== Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON)
+          return;
+        if (aURI.spec !== uri)
+          return;
+        historyService.removeObserver(this);
+        callback(aValue);
+      }
+    }
+  });
+  historyService.addObserver(observer, false);
+}
+exports.onFaviconChange = onFaviconChange;
+
+/*
+ * Takes page content, a page path, and favicon binary data
+ */
+function serve ({name, favicon, port, host}) {
+  let faviconTag = '<link rel="icon" type="image/x-icon" href="/'+ name +'.ico"/>';
+  let content = '<html><head>' + faviconTag + '<title>'+name+'</title></head><body></body></html>';
+  let srv = startServerAsync(port, basePath);
+  let pagePath = file.join(basePath, name + '.html');
+  let iconPath = file.join(basePath, name + '.ico');
+  let pageStream = file.open(pagePath, 'w');
+  let iconStream = file.open(iconPath, 'wb');
+  iconStream.write(favicon);
+  iconStream.close();
+  pageStream.write(content);
+  pageStream.close();
+  return srv;
+}
+exports.serve = serve;
+
+let binFavicon = exports.binFavicon = atob('AAABAAEAEBAAAAAAAABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAAAAAACAAACAAAAAgIAAgAAAAIAAgACAgAAAwMDAAMDcwADwyqYABAQEAAgICAAMDAwAERERABYWFgAcHBwAIiIiACkpKQBVVVUATU1NAEJCQgA5OTkAgHz/AFBQ/wCTANYA/+zMAMbW7wDW5+cAkKmtAAAAMwAAAGYAAACZAAAAzAAAMwAAADMzAAAzZgAAM5kAADPMAAAz/wAAZgAAAGYzAABmZgAAZpkAAGbMAABm/wAAmQAAAJkzAACZZgAAmZkAAJnMAACZ/wAAzAAAAMwzAADMZgAAzJkAAMzMAADM/wAA/2YAAP+ZAAD/zAAzAAAAMwAzADMAZgAzAJkAMwDMADMA/wAzMwAAMzMzADMzZgAzM5kAMzPMADMz/wAzZgAAM2YzADNmZgAzZpkAM2bMADNm/wAzmQAAM5kzADOZZgAzmZkAM5nMADOZ/wAzzAAAM8wzADPMZgAzzJkAM8zMADPM/wAz/zMAM/9mADP/mQAz/8wAM///AGYAAABmADMAZgBmAGYAmQBmAMwAZgD/AGYzAABmMzMAZjNmAGYzmQBmM8wAZjP/AGZmAABmZjMAZmZmAGZmmQBmZswAZpkAAGaZMwBmmWYAZpmZAGaZzABmmf8AZswAAGbMMwBmzJkAZszMAGbM/wBm/wAAZv8zAGb/mQBm/8wAzAD/AP8AzACZmQAAmTOZAJkAmQCZAMwAmQAAAJkzMwCZAGYAmTPMAJkA/wCZZgAAmWYzAJkzZgCZZpkAmWbMAJkz/wCZmTMAmZlmAJmZmQCZmcwAmZn/AJnMAACZzDMAZsxmAJnMmQCZzMwAmcz/AJn/AACZ/zMAmcxmAJn/mQCZ/8wAmf//AMwAAACZADMAzABmAMwAmQDMAMwAmTMAAMwzMwDMM2YAzDOZAMwzzADMM/8AzGYAAMxmMwCZZmYAzGaZAMxmzACZZv8AzJkAAMyZMwDMmWYAzJmZAMyZzADMmf8AzMwAAMzMMwDMzGYAzMyZAMzMzADMzP8AzP8AAMz/MwCZ/2YAzP+ZAMz/zADM//8AzAAzAP8AZgD/AJkAzDMAAP8zMwD/M2YA/zOZAP8zzAD/M/8A/2YAAP9mMwDMZmYA/2aZAP9mzADMZv8A/5kAAP+ZMwD/mWYA/5mZAP+ZzAD/mf8A/8wAAP/MMwD/zGYA/8yZAP/MzAD/zP8A//8zAMz/ZgD//5kA///MAGZm/wBm/2YAZv//AP9mZgD/Zv8A//9mACEApQBfX18Ad3d3AIaGhgCWlpYAy8vLALKysgDX19cA3d3dAOPj4wDq6uoA8fHxAPj4+ADw+/8ApKCgAICAgAAAAP8AAP8AAAD//wD/AAAA/wD/AP//AAD///8ACgoKCgoKCgoKCgoKCgoKCgoKCgoHAQEMbQoKCgoKCgoAAAdDH/kgHRIAAAAAAAAAAADrHfn5ASQQAAAAAAAAAArsBx0B+fkgHesAAAAAAAD/Cgwf+fn5IA4dEus/IvcACgcMAfkg+QEB+SABHushbf8QHR/5HQH5+QEdHetEHx4K7B/5+QH5+fkdDBL5+SBE/wwdJfkf+fn5AR8g+fkfEArsCh/5+QEeJR/5+SAeBwAACgoe+SAlHwFAEhAfAAAAAPcKHh8eASYBHhAMAAAAAAAA9EMdIB8gHh0dBwAAAAAAAAAA7BAdQ+wHAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AADwfwAAwH8AAMB/AAAAPwAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAgAcAAIAPAADADwAA8D8AAP//AAA');
--- a/addon-sdk/source/test/test-content-symbiont.js
+++ b/addon-sdk/source/test/test-content-symbiont.js
@@ -1,17 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
 "use strict";
 
 const { Cc, Ci } = require('chrome');
 const { Symbiont } = require('sdk/content/symbiont');
-const self = require("sdk/self");
+const self = require('sdk/self');
+const { close } = require('sdk/window/helpers');
 
 function makeWindow() {
   let content =
     '<?xml version="1.0"?>' +
     '<window ' +
     'xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">' +
     '<iframe id="content" type="content"/>' +
     '</window>';
@@ -73,19 +73,19 @@ exports["test:communication with worker 
     assert.equal(message, 1, "Program gets message via onMessage.");
     contentSymbiont.removeListener('message', onMessage1);
     contentSymbiont.on('message', onMessage2);
     contentSymbiont.postMessage(2);
   };
 
   function onMessage2(message) {
     if (5 == message) {
-      window.close();
-      done();
-    } else {
+      close(window).then(done);
+    }
+    else {
       assert.equal(message, 3, "Program gets message via onMessage2.");
       contentSymbiont.postMessage(4)
     }
   }
 
   window.addEventListener("load", function onLoad() {
     window.removeEventListener("load", onLoad, false);
     let frame = window.document.getElementById("content");
--- a/addon-sdk/source/test/test-content-worker.js
+++ b/addon-sdk/source/test/test-content-worker.js
@@ -3,16 +3,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 "use stirct";
 
 const { Cc, Ci } = require("chrome");
 const { setTimeout } = require("sdk/timers");
 const { LoaderWithHookedConsole } = require("sdk/test/loader");
 const { Worker } = require("sdk/content/worker");
+const { close } = require("sdk/window/helpers");
 
 const DEFAULT_CONTENT_URL = "data:text/html;charset=utf-8,foo";
 
 function makeWindow(contentURL) {
   let content =
     "<?xml version=\"1.0\"?>" +
     "<window " +
     "xmlns=\"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul\">" +
@@ -59,18 +60,18 @@ function WorkerTest(url, callback) {
       let browser = chromeWindow.document.createElement("browser");
       browser.setAttribute("type", "content");
       chromeWindow.document.documentElement.appendChild(browser);
       // Wait for about:blank load event ...
       listenOnce(browser, "load", function onAboutBlankLoad() {
         // ... before loading the expected doc and waiting for its load event
         loadAndWait(browser, url, function onDocumentLoaded() {
           callback(assert, browser, function onTestDone() {
-            chromeWindow.close();
-            done();
+
+            close(chromeWindow).then(done);
           });
         });
       });
     }, true);
   };
 }
 
 exports["test:sample"] = WorkerTest(
@@ -313,18 +314,17 @@ exports["test:chrome is unwrapped"] = fu
       window: window,
       contentScript: "new " + function WorkerScope() {
         self.postMessage(window.documentValue);
       },
       contentScriptWhen: "ready",
       onMessage: function(msg) {
         assert.ok(msg,
           "content script has an unwrapped access to chrome document");
-        window.close();
-        done();
+        close(window).then(done);
       }
     });
 
   });
 }
 
 exports["test:nothing is leaked to content script"] = WorkerTest(
   DEFAULT_CONTENT_URL,
--- a/addon-sdk/source/test/test-context-menu.js
+++ b/addon-sdk/source/test/test-context-menu.js
@@ -2692,16 +2692,57 @@ exports.testItemImage = function (test) 
     test.assertEqual(item.image, null, "Should have set the image correctly");
     test.assertEqual(menu.image, null, "Should have set the image correctly");
     test.checkMenu([item, menu], [], []);
 
     test.done();
   });
 };
 
+// Test image URL validation.
+exports.testItemImageValidURL = function (test) {
+  test = new TestHelper(test);
+  let loader = test.newLoader();
+ 
+  test.assertRaises(function(){
+      new loader.cm.Item({
+        label: "item 1",
+        image: "foo"
+      })
+    }, "Image URL validation failed"
+  );
+
+  test.assertRaises(function(){
+      new loader.cm.Item({
+        label: "item 2",
+        image: false
+      })
+    }, "Image URL validation failed"
+  );
+
+  test.assertRaises(function(){
+      new loader.cm.Item({
+        label: "item 3",
+        image: 0
+      })
+    }, "Image URL validation failed"
+  );
+   
+  let imageURL = require("sdk/self").data.url("moz_favicon.ico");
+  let item4 = new loader.cm.Item({ label: "item 4", image: imageURL });
+  let item5 = new loader.cm.Item({ label: "item 5", image: null });
+  let item6 = new loader.cm.Item({ label: "item 6", image: undefined });
+
+  test.assertEqual(item4.image, imageURL, "Should be proper image URL");
+  test.assertEqual(item5.image, null, "Should be null image");
+  test.assertEqual(item6.image, undefined, "Should be undefined image");
+
+  test.done();
+}
+
 
 // Menu.destroy should destroy the item tree rooted at that menu.
 exports.testMenuDestroy = function (test) {
   test = new TestHelper(test);
   let loader = test.newLoader();
 
   let menu = loader.cm.Menu({
     label: "menu",
--- a/addon-sdk/source/test/test-frame-utils.js
+++ b/addon-sdk/source/test/test-frame-utils.js
@@ -1,71 +1,59 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
 'use strict';
 
-const { open } = require('sdk/window/utils');
 const { create } = require('sdk/frame/utils');
+const { open, close } = require('sdk/window/helpers');
 
 exports['test frame creation'] = function(assert, done) {
-  let window = open('data:text/html;charset=utf-8,Window');
-  window.addEventListener('DOMContentLoaded', function windowReady() {
-
+  open('data:text/html;charset=utf-8,Window').then(function (window) {
     let frame = create(window.document);
 
     assert.equal(frame.getAttribute('type'), 'content',
                  'frame type is content');
     assert.ok(frame.contentWindow, 'frame has contentWindow');
     assert.equal(frame.contentWindow.location.href, 'about:blank',
                  'by default "about:blank" is loaded');
     assert.equal(frame.docShell.allowAuth, false, 'auth disabled by default');
     assert.equal(frame.docShell.allowJavascript, false, 'js disabled by default');
     assert.equal(frame.docShell.allowPlugins, false,
                  'plugins disabled by default');
-    window.close();
-    done();
-  }, false);
+    close(window).then(done);
+  });
 };
 
 exports['test fram has js disabled by default'] = function(assert, done) {
-  let window = open('data:text/html;charset=utf-8,window');
-  window.addEventListener('DOMContentLoaded', function windowReady() {
-    window.removeEventListener('DOMContentLoaded', windowReady, false);
+  open('data:text/html;charset=utf-8,window').then(function (window) {
     let frame = create(window.document, {
       uri: 'data:text/html;charset=utf-8,<script>document.documentElement.innerHTML' +
            '= "J" + "S"</script>',
     });
     frame.contentWindow.addEventListener('DOMContentLoaded', function ready() {
       frame.contentWindow.removeEventListener('DOMContentLoaded', ready, false);
       assert.ok(!~frame.contentDocument.documentElement.innerHTML.indexOf('JS'),
                 'JS was executed');
 
-      window.close();
-      done();
+      close(window).then(done);
     }, false);
-
-  }, false);
+  });
 };
 
 exports['test frame with js enabled'] = function(assert, done) {
-  let window = open('data:text/html;charset=utf-8,window');
-  window.addEventListener('DOMContentLoaded', function windowReady() {
-    window.removeEventListener('DOMContentLoaded', windowReady, false);
+  open('data:text/html;charset=utf-8,window').then(function (window) {
     let frame = create(window.document, {
       uri: 'data:text/html;charset=utf-8,<script>document.documentElement.innerHTML' +
            '= "J" + "S"</script>',
       allowJavascript: true
     });
     frame.contentWindow.addEventListener('DOMContentLoaded', function ready() {
       frame.contentWindow.removeEventListener('DOMContentLoaded', ready, false);
       assert.ok(~frame.contentDocument.documentElement.innerHTML.indexOf('JS'),
                 'JS was executed');
 
-      window.close();
-      done();
+      close(window).then(done);
     }, false);
-
-  }, false);
+  });
 };
 
 require('test').run(exports);
--- a/addon-sdk/source/test/test-httpd.js
+++ b/addon-sdk/source/test/test-httpd.js
@@ -72,8 +72,21 @@ exports.testDynamicServer = function (te
 
   function done() {
     srv.stop(function() {
       test.done();
     });
   }
 
 }
+
+exports.testAutomaticPortSelection = function (test) {
+  const srv = httpd.startServerAsync(-1);
+
+  test.waitUntilDone();
+
+  const port = srv.identity.primaryPort;
+  test.assert(0 <= port && port <= 65535);
+
+  srv.stop(function() {
+    test.done();
+  });
+}
new file mode 100644
--- /dev/null
+++ b/addon-sdk/source/test/test-io-data.js
@@ -0,0 +1,112 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const { Cc, Ci, Cu } = require('chrome');
+const { getFavicon, getFaviconURIForLocation } = require('sdk/io/data');
+const tabs = require('sdk/tabs');
+const open = tabs.open;
+const port = 8099;
+const host = 'http://localhost:' + port;
+const { onFaviconChange, serve, binFavicon } = require('./favicon-helpers');
+const { once } = require('sdk/system/events');
+const faviconService = Cc["@mozilla.org/browser/favicon-service;1"].
+                         getService(Ci.nsIFaviconService);
+
+exports.testGetFaviconCallbackSuccess = function (assert, done) {
+  let name = 'callbacksuccess'
+  let srv = serve({name: name, favicon: binFavicon, port: port, host: host});
+  let url = host + '/' + name + '.html';
+  let favicon = host + '/' + name + '.ico';
+  let tab;
+
+  onFaviconChange(url, function (faviconUrl) {
+    getFavicon(url, function (url) {
+      assert.equal(favicon, url, 'Callback returns correct favicon url');
+      complete(tab, srv, done);
+    });
+  });
+
+  open({
+    url: url,
+    onOpen: function (newTab) tab = newTab,
+    inBackground: true
+  });
+};
+
+exports.testGetFaviconCallbackFailure = function (assert, done) {
+  let name = 'callbackfailure';
+  let srv = serve({name: name, favicon: binFavicon, port: port, host: host});
+  let url = host + '/' + name + '.html';
+  let tab;
+
+  onFaviconChange(url, function (faviconUrl) {
+    once('places-favicons-expired', function () {
+      getFavicon(url, function (url) {
+        assert.equal(url, null, 'Callback returns null');
+        complete(tab, srv, done);
+      });
+    });
+    faviconService.expireAllFavicons();
+  });
+
+  open({
+    url: url,
+    onOpen: function (newTab) tab = newTab,
+    inBackground: true
+  });
+};
+
+exports.testGetFaviconPromiseSuccess = function (assert, done) {
+  let name = 'promisesuccess'
+  let srv = serve({name: name, favicon: binFavicon, port: port, host: host});
+  let url = host + '/' + name + '.html';
+  let favicon = host + '/' + name + '.ico';
+  let tab;
+
+  onFaviconChange(url, function (faviconUrl) {
+    getFavicon(url).then(function (url) {
+      assert.equal(url, favicon, 'Callback returns null');
+    }, function (err) {
+      assert.fail('Reject should not be called');
+    }).then(complete.bind(null, tab, srv, done));
+  });
+
+  open({
+    url: url,
+    onOpen: function (newTab) tab = newTab,
+    inBackground: true
+  });
+};
+
+exports.testGetFaviconPromiseFailure = function (assert, done) {
+  let name = 'promisefailure'
+  let srv = serve({name: name, favicon: binFavicon, port: port, host: host});
+  let url = host + '/' + name + '.html';
+  let tab;
+
+  onFaviconChange(url, function (faviconUrl) {
+    once('places-favicons-expired', function () {
+      getFavicon(url).then(function (url) {
+        assert.fail('success should not be called');
+      }, function (err) {
+        assert.equal(err, null, 'should call reject');
+      }).then(complete.bind(null, tab, srv, done));
+    });
+    faviconService.expireAllFavicons();
+  });
+
+  open({
+    url: url,
+    onOpen: function (newTab) tab = newTab,
+    inBackground: true
+  });
+};
+
+function complete(tab, srv, done) {
+  tab.close(function () {
+    srv.stop(done);
+  })
+}
+
+require("test").run(exports);
--- a/addon-sdk/source/test/test-page-mod.js
+++ b/addon-sdk/source/test/test-page-mod.js
@@ -370,20 +370,21 @@ exports.testRelatedTabNoRequireTab = fun
   let loader = Loader(module);
   let tab;
   let url = "data:text/html;charset=utf-8," + encodeURI("Test related worker tab 2");
   let { PageMod } = loader.require("sdk/page-mod");
   let pageMod = new PageMod({
     include: url,
     onAttach: function(worker) {
       test.assertEqual(worker.tab.url, url, "Worker.tab.url is valid");
-      worker.tab.close();
-      pageMod.destroy();
-      loader.unload();
-      test.done();
+      worker.tab.close(function() {
+        pageMod.destroy();
+        loader.unload();
+        test.done();
+      });
     }
   });
 
   tabs.open(url);
 };
 
 exports.testRelatedTabNoOtherReqs = function(test) {
   test.waitUntilDone();
@@ -421,18 +422,17 @@ exports.testWorksWithExistingTabs = func
         attachTo: ["existing", "top", "frame"],
         onAttach: function(worker) {
           test.assert(!!worker.tab, "Worker.tab exists");
           test.assertEqual(tab, worker.tab, "A worker has been created on this existing tab");
 
           timer.setTimeout(function() {
             pageModOnExisting.destroy();
             pageModOffExisting.destroy();
-            tab.close();
-            test.done();
+            tab.close(test.done.bind(test));
           }, 0);
         }
       });
 
       let pageModOffExisting = new PageMod({
         include: url,
         onAttach: function(worker) {
           test.fail("pageModOffExisting page-mod should not have attached to anything");
@@ -466,21 +466,23 @@ exports.testTabWorkerOnMessage = functio
             test.assertEqual(this.tab.url, data.url, "location is correct");
             test.assertEqual(this.tab.title, data.title, "title is correct");
             if (this.tab.url === url1) {
               worker1 = this;
               tabs.open({ url: url2, inBackground: true });
             }
             else if (this.tab.url === url2) {
               mod.destroy();
-              worker1.tab.close();
-              worker1.destroy();
-              worker.tab.close();
-              worker.destroy();
-              test.done();
+              worker1.tab.close(function() {
+                worker1.destroy();
+                worker.tab.close(function() {
+                  worker.destroy();
+                  test.done();
+                });
+              });
             }
           }
         });
       });
     }
   });
 
   tabs.open(url1);
@@ -502,21 +504,19 @@ exports.testAutomaticDestroy = function(
   loader.unload();
 
   // Then create a second tab to ensure that it is correctly destroyed
   let tabs = require("sdk/tabs");
   tabs.open({
     url: "about:",
     onReady: function onReady(tab) {
       test.pass("check automatic destroy");
-      tab.close();
-      test.done();
+      tab.close(test.done.bind(test));
     }
   });
-
 }
 
 exports.testAttachToTabsOnly = function(test) {
   test.waitUntilDone();
 
   let { PageMod } = require('sdk/page-mod');
   let openedTab = null; // Tab opened in openTabWithIframe()
   let workerCount = 0;
@@ -851,18 +851,17 @@ exports.testPageModCssAutomaticDestroy =
       loader.unload();
 
       test.assertEqual(
         style.width,
         "200px",
         "PageMod contentStyle is removed after loader's unload"
       );
 
-      tab.close();
-      test.done();
+      tab.close(test.done.bind(test));
     }
   });
 };
 
 
 exports.testPageModTimeout = function(test) {
   test.waitUntilDone();
   let tab = null
@@ -877,20 +876,21 @@ exports.testPageModTimeout = function(te
       }, 10)
       self.port.emit("scheduled", id);
     }),
     onAttach: function(worker) {
       worker.port.on("scheduled", function(id) {
         test.pass("timer was scheduled")
         worker.port.on("fired", function(data) {
           test.assertEqual(id, data, "timer was fired")
-          tab.close()
-          worker.destroy()
-          loader.unload()
-          test.done()
+          tab.close(function() {
+            worker.destroy()
+            loader.unload()
+            test.done()
+          });
         })
       })
     }
   });
 
   tabs.open({
     url: "data:text/html;charset=utf-8,timeout",
     onReady: function($) { tab = $ }
@@ -916,21 +916,22 @@ exports.testPageModcancelTimeout = funct
       clearTimeout(id1)
     }),
     onAttach: function(worker) {
       worker.port.on("failed", function() {
         test.fail("cancelled timeout fired")
       })
       worker.port.on("timeout", function(id) {
         test.pass("timer was scheduled")
-        tab.close();
-        worker.destroy();
-        mod.destroy();
-        loader.unload();
-        test.done();
+        tab.close(function() {
+          worker.destroy();
+          mod.destroy();
+          loader.unload();
+          test.done();
+        });
       })
     }
   });
 
   tabs.open({
     url: "data:text/html;charset=utf-8,cancell timeout",
     onReady: function($) { tab = $ }
   })
--- a/addon-sdk/source/test/test-tab-browser.js
+++ b/addon-sdk/source/test/test-tab-browser.js
@@ -1,14 +1,15 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+"use strict";
 
 var timer = require("sdk/timers");
-var {Cc,Ci} = require("chrome");
+var { Cc, Ci } = require("chrome");
 
 function onBrowserLoad(callback, event) {
   if (event.target && event.target.defaultView == this) {
     this.removeEventListener("load", onBrowserLoad, true);
     let browsers = this.document.getElementsByTagName("tabbrowser");
     try {
       timer.setTimeout(function (window) {
         callback(window, browsers[0]);
--- a/addon-sdk/source/test/test-tab-utils.js
+++ b/addon-sdk/source/test/test-tab-utils.js
@@ -1,73 +1,77 @@
 'use strict';
 
 const { getTabs } = require('sdk/tabs/utils');
 const { isGlobalPBSupported, isWindowPBSupported, isTabPBSupported } = require('sdk/private-browsing/utils');
 const { browserWindows } = require('sdk/windows');
 const tabs = require('sdk/tabs');
 const { pb } = require('./private-browsing/helper');
 const { isPrivate } = require('sdk/private-browsing');
-const { openTab } = require('sdk/tabs/utils');
+const { openTab, closeTab, getTabContentWindow } = require('sdk/tabs/utils');
 const { open, close } = require('sdk/window/helpers');
 const { windows } = require('sdk/window/utils');
 const { getMostRecentBrowserWindow } = require('sdk/window/utils');
 const { fromIterator } = require('sdk/util/array');
 
 if (isGlobalPBSupported) {
   exports.testGetTabs = function(assert, done) {
     pb.once('start', function() {
       tabs.open({
-      	url: 'about:blank',
-      	inNewWindow: true,
-      	onOpen: function(tab) {
+        url: 'about:blank',
+        inNewWindow: true,
+        onOpen: function(tab) {
           assert.equal(getTabs().length, 2, 'there are two tabs');
           assert.equal(browserWindows.length, 2, 'there are two windows');
           pb.once('stop', function() {
-          	done();
+            done();
           });
           pb.deactivate();
-      	}
+        }
       });
     });
     pb.activate();
   };
 }
 else if (isWindowPBSupported) {
   exports.testGetTabs = function(assert, done) {
     open(null, {
-      features: {
-      	private: true,
-      	toolbar: true,
-      	chrome: true
+        features: {
+        private: true,
+        toolbar: true,
+        chrome: true
       }
     }).then(function(window) {
       assert.ok(isPrivate(window), 'new tab is private');
       assert.equal(getTabs().length, 1, 'there is one tab found');
       assert.equal(browserWindows.length, 1, 'there is one window found');
       fromIterator(browserWindows).forEach(function(window) {
         assert.ok(!isPrivate(window), 'all found windows are not private');
       });
       assert.equal(windows(null, {includePrivate: true}).length, 2, 'there are really two windows');
       close(window).then(done);
     });
   };
 }
 else if (isTabPBSupported) {
   exports.testGetTabs = function(assert, done) {
-    tabs.once('open', function(tab) {
-      assert.ok(isPrivate(tab), 'new tab is private');
-      assert.equal(getTabs().length, 2, 'there are two tabs found');
-      assert.equal(browserWindows.length, 1, 'there is one window');
-      tab.close(function() {
-        done();
-      });
-	});
-    openTab(getMostRecentBrowserWindow(), 'about:blank', {
+    let startTabCount = getTabs().length;
+    let tab = openTab(getMostRecentBrowserWindow(), 'about:blank', {
       isPrivate: true
     });
+
+    assert.ok(isPrivate(getTabContentWindow(tab)), 'new tab is private');
+    let utils_tabs = getTabs();
+    assert.equal(utils_tabs.length, startTabCount + 1,
+                 'there are two tabs found');
+    assert.equal(utils_tabs[utils_tabs.length-1], tab,
+                 'the last tab is the opened tab');
+    assert.equal(browserWindows.length, 1, 'there is only one window');
+    closeTab(tab);
+
+    done();
   };
 }
 
 // Test disabled because of bug 855771
 module.exports = {};
 
 require('test').run(exports);
--- a/addon-sdk/source/test/test-tabs-common.js
+++ b/addon-sdk/source/test/test-tabs-common.js
@@ -7,16 +7,17 @@ const { Loader, LoaderWithHookedConsole 
 const { browserWindows } = require('sdk/windows');
 const tabs = require('sdk/tabs');
 const { isPrivate } = require('sdk/private-browsing');
 const { openDialog } = require('sdk/window/utils');
 const { isWindowPrivate } = require('sdk/window/utils');
 const { setTimeout } = require('sdk/timers');
 const { openWebpage } = require('./private-browsing/helper');
 const { isTabPBSupported, isWindowPBSupported } = require('sdk/private-browsing/utils');
+const app = require("sdk/system/xul-app");
 
 const URL = 'data:text/html;charset=utf-8,<html><head><title>#title#</title></head></html>';
 
 // TEST: tab count
 exports.testTabCounts = function(test) {
   test.waitUntilDone();
 
   tabs.open({
@@ -349,30 +350,42 @@ exports.testPrivateAreNotListed = functi
 }
 
 // If we close the tab while being in `onOpen` listener,
 // we end up synchronously consuming TabOpen, closing the tab and still
 // synchronously consuming the related TabClose event before the second
 // loader have a change to process the first TabOpen event!
 exports.testImmediateClosing = function (test) {
   test.waitUntilDone();
+
+  let tabURL = 'data:text/html,foo';
+
   let { loader, messages } = LoaderWithHookedConsole(module, onMessage);
   let concurrentTabs = loader.require("sdk/tabs");
-  concurrentTabs.on("open", function () {
-    test.fail("Concurrent loader manager receive a tabs `open` event");
-    // It shouldn't receive such event as the other loader will just open
-    // and destroy the tab without giving a change to other loader to even know
-    // about the existance of this tab.
+  concurrentTabs.on("open", function (tab) {
+    // On Firefox, It shouldn't receive such event as the other loader will just
+    // open and destroy the tab without giving a chance to other loader to even
+    // know about the existance of this tab.
+    if (app.is("Firefox")) {
+      test.fail("Concurrent loader received a tabs `open` event");
+    }
+    else {
+      // On mobile, we can still receive an open event,
+      // but not the related ready event
+      tab.on("ready", function () {
+        test.fail("Concurrent loader received a tabs `ready` event");
+      });
+    }
   });
   function onMessage(type, msg) {
     test.fail("Unexpected mesage on concurrent loader: " + msg);
   }
 
   tabs.open({
-    url: 'about:blank',
+    url: tabURL,
     onOpen: function(tab) {
       tab.close(function () {
         test.pass("Tab succesfully removed");
         // Let a chance to the concurrent loader to receive a TabOpen event
         // on the next event loop turn
         setTimeout(function () {
           loader.unload();
           test.done();
--- a/addon-sdk/source/test/test-window-observer.js
+++ b/addon-sdk/source/test/test-window-observer.js
@@ -1,55 +1,50 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
 "use strict";
 
 const { Loader } = require("sdk/test/loader");
-const timer = require("sdk/timers");
+const { open, close } = require("sdk/window/helpers");
+const { browserWindows: windows } = require("sdk/windows");
+const { isBrowser } = require('sdk/window/utils');
 
 exports["test unload window observer"] = function(assert, done) {
   // Hacky way to be able to create unloadable modules via makeSandboxedLoader.
   let loader = Loader(module);
-
-  let utils = loader.require("sdk/deprecated/window-utils");
-  let { activeBrowserWindow: activeWindow } = utils;
-  let { isBrowser } = require('sdk/window/utils');
   let observer = loader.require("sdk/windows/observer").observer;
   let opened = 0;
   let closed = 0;
+  let windowsOpen = windows.length;
 
   observer.on("open", function onOpen(window) {
     // Ignoring non-browser windows
     if (isBrowser(window))
       opened++;
   });
   observer.on("close", function onClose(window) {
     // Ignore non-browser windows & already opened `activeWindow` (unload will
     // emit close on it even though it is not actually closed).
-    if (isBrowser(window) && window !== activeWindow)
+    if (isBrowser(window))
       closed++;
   });
 
   // Open window and close it to trigger observers.
-  activeWindow.open().close();
-
-  // Unload the module so that all listeners set by observer are removed.
-  loader.unload();
-
-  // Open and close window once again.
-  activeWindow.open().close();
-
-  // Enqueuing asserts to make sure that assertion is not performed early.
-  timer.setTimeout(function () {
-    assert.equal(1, opened, "observer open was called before unload only");
-    assert.equal(1, closed, "observer close was called before unload only");
-    done();
-  }, 0);
+  open().
+    then(close).
+    then(loader.unload).
+    then(open).
+    then(close).
+    then(function() {
+      // Enqueuing asserts to make sure that assertion is not performed early.
+      assert.equal(1, opened, "observer open was called before unload only");
+      assert.equal(windowsOpen + 1, closed, "observer close was called before unload only");
+    }).
+    then(done, assert.fail);
 };
 
 if (require("sdk/system/xul-app").is("Fennec")) {
   module.exports = {
     "test Unsupported Test": function UnsupportedTest (assert) {
         assert.pass(
           "Skipping this test until Fennec support is implemented." +
           "See bug 793071");
--- a/addon-sdk/source/test/test-xhr.js
+++ b/addon-sdk/source/test/test-xhr.js
@@ -1,38 +1,38 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  'use strict'
 
 const xhr = require('sdk/net/xhr');
 const { Loader } = require('sdk/test/loader');
 const xulApp = require('sdk/system/xul-app');
+const { data } = require('sdk/self');
 
 // TODO: rewrite test below
 /* Test is intentionally disabled until platform bug 707256 is fixed.
 exports.testAbortedXhr = function(test) {
   var req = new xhr.XMLHttpRequest();
   test.assertEqual(xhr.getRequestCount(), 1);
   req.abort();
   test.assertEqual(xhr.getRequestCount(), 0);
 };
 */
 
 exports.testLocalXhr = function(assert, done) {
   var req = new xhr.XMLHttpRequest();
   let ready = false;
 
   req.overrideMimeType('text/plain');
-  req.open('GET', module.uri);
+  req.open('GET', data.url('testLocalXhr.json'));
   req.onreadystatechange = function() {
     if (req.readyState == 4 && (req.status == 0 || req.status == 200)) {
       ready = true;
-      assert.ok(req.responseText.match(/onreadystatechange/i),
-                'XMLHttpRequest should get local files');
+      assert.equal(req.responseText, '{}\n', 'XMLHttpRequest should get local files');
     }
   };
   req.addEventListener('load', function onload() {
     req.removeEventListener('load', onload);
     assert.pass('addEventListener for load event worked');
     assert.ok(ready, 'onreadystatechange listener worked');
     assert.equal(xhr.getRequestCount(), 0, 'request count is 0');
     done();
--- a/addon-sdk/source/test/windows/test-firefox-windows.js
+++ b/addon-sdk/source/test/windows/test-firefox-windows.js
@@ -305,24 +305,25 @@ exports.testTrackWindows = function(test
 
         test.assertEqual(actions.join(), expects.slice(0, index*4).join(), expects[index*4]);
         actions.push("activate " + index);
 
         if (windows.length < 3) {
           openWindow()
         }
         else {
-          let count = windows.length;
-          for each (let win in windows) {
-            win.close(function() {
-              if (--count == 0) {
-                test.done();
-              }
+          (function closeWindows(windows) {
+            if (!windows.length)
+              return test.done();
+
+            return windows.pop().close(function() {
+              test.pass('window was closed');
+              closeWindows(windows);
             });
-          }
+          })(windows)
         }
       },
 
       onDeactivate: function(window) {
         let index = windows.indexOf(window);
 
         test.assertEqual(actions.join(), expects.slice(0, index*4 + 2).join(), expects[index*4 + 2]);
         actions.push("deactivate " + index)
--- a/b2g/app/b2g.js
+++ b/b2g/app/b2g.js
@@ -376,16 +376,17 @@ pref("dom.mozBrowserFramesEnabled", true
 // We'll run out of PIDs on UNIX-y systems before we hit this limit.
 pref("dom.ipc.processCount", 100000);
 
 pref("dom.ipc.browser_frames.oop_by_default", false);
 
 // Temporary permission hack for WebSMS
 pref("dom.sms.enabled", true);
 pref("dom.sms.strict7BitEncoding", false); // Disabled by default.
+pref("dom.sms.requestStatusReport", true); // Enabled by default.
 
 // Temporary permission hack for WebContacts
 pref("dom.mozContacts.enabled", true);
 
 // WebAlarms
 pref("dom.mozAlarms.enabled", true);
 
 // SimplePush
@@ -685,10 +686,14 @@ pref("b2g.version", @MOZ_B2G_VERSION@);
 // Disable console buffering to save memory.
 pref("consoleservice.buffered", false);
 
 #ifdef MOZ_WIDGET_GONK
 // Performance testing suggests 2k is a better page size for SQLite.
 pref("toolkit.storage.pageSize", 2048);
 #endif
 
+// Enable captive portal detection.
+pref("captivedetect.canonicalURL", "http://detectportal.firefox.com/success.txt");
+pref("captivedetect.canonicalContent", "success\n");
+
 // The url of the manifest we use for ADU pings.
 pref("ping.manifestURL", "https://marketplace.firefox.com/packaged.webapp");
--- a/b2g/chrome/content/settings.js
+++ b/b2g/chrome/content/settings.js
@@ -159,16 +159,21 @@ SettingsListener.observe('language.curre
     function(value) {
       Services.prefs.setCharPref('dom.mms.retrieval_mode', value);
   });
 
   SettingsListener.observe('ril.sms.strict7BitEncoding.enabled', false,
     function(value) {
       Services.prefs.setBoolPref('dom.sms.strict7BitEncoding', value);
   });
+
+  SettingsListener.observe('ril.sms.requestStatusReport.enabled', true,
+    function(value) {
+      Services.prefs.setBoolPref('dom.sms.requestStatusReport', value);
+  });
 })();
 
 //=================== DeviceInfo ====================
 Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
 Components.utils.import('resource://gre/modules/ctypes.jsm');
 (function DeviceInfoToSettings() {
   XPCOMUtils.defineLazyServiceGetter(this, 'gSettingsService',
                                      '@mozilla.org/settingsService;1',
new file mode 100644
--- /dev/null
+++ b/b2g/config/emulator/config.json
@@ -0,0 +1,22 @@
+{
+    "config_version": 2,
+    "tooltool_manifest": "releng-emulator.tt",
+    "mock_target": "mozilla-centos6-x86_64",
+    "mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git"],
+    "mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
+    "build_targets": ["droid", "package-emulator"],
+    "upload_files": [
+        "{workdir}/out/emulator.tar.gz",
+        "{objdir}/dist/b2g-*.crashreporter-symbols.zip",
+        "{workdir}/sources.xml"
+    ],
+    "gecko_l10n_root": "http://hg.mozilla.org/l10n-central",
+    "gaia": {
+        "l10n": {
+            "vcs": "hgtool",
+            "root": "http://hg.mozilla.org/gaia-l10n"
+        }
+    },
+    "b2g_manifest": "emulator.xml",
+    "b2g_manifest_branch": "master"
+}
new file mode 100644
--- /dev/null
+++ b/b2g/config/emulator/releng-emulator.tt
@@ -0,0 +1,2 @@
+[
+]
--- a/browser/config/mozconfigs/linux32/l10n-mozconfig
+++ b/browser/config/mozconfigs/linux32/l10n-mozconfig
@@ -1,9 +1,9 @@
-ac_add_options --with-l10n-base=../../l10n-central
+ac_add_options --with-l10n-base=../../l10n
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 . $topsrcdir/build/unix/mozconfig.linux32
 
--- a/browser/config/mozconfigs/linux64/l10n-mozconfig
+++ b/browser/config/mozconfigs/linux64/l10n-mozconfig
@@ -1,9 +1,9 @@
-ac_add_options --with-l10n-base=../../l10n-central
+ac_add_options --with-l10n-base=../../l10n
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 
 # Avoid dependency on libstdc++ 4.5
 ac_add_options --enable-stdcxx-compat
 
 . $topsrcdir/build/unix/mozconfig.linux
 
--- a/browser/config/mozconfigs/macosx-universal/l10n-mozconfig
+++ b/browser/config/mozconfigs/macosx-universal/l10n-mozconfig
@@ -1,11 +1,11 @@
 . "$topsrcdir/browser/config/mozconfigs/common"
 
-ac_add_options --with-l10n-base=../../../l10n-central
+ac_add_options --with-l10n-base=../../../l10n
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --with-macbundlename-prefix=Firefox
 ac_add_options --with-ccache
 
 export MOZILLA_OFFICIAL=1
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/macosx64/l10n-mozconfig
+++ b/browser/config/mozconfigs/macosx64/l10n-mozconfig
@@ -1,8 +1,8 @@
 . "$topsrcdir/browser/config/mozconfigs/common"
 
-ac_add_options --with-l10n-base=../../l10n-central
+ac_add_options --with-l10n-base=../../l10n
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
 ac_add_options --with-ccache
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/win32/l10n-mozconfig
+++ b/browser/config/mozconfigs/win32/l10n-mozconfig
@@ -1,13 +1,13 @@
 . "$topsrcdir/browser/config/mozconfigs/common"
 
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 ac_add_options --enable-update-packaging
-ac_add_options --with-l10n-base=../../l10n-central
+ac_add_options --with-l10n-base=../../l10n
 ac_add_options --enable-metro
 ac_add_options --with-windows-version=601
 
 export MOZILLA_OFFICIAL=1
 
 if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
   . $topsrcdir/build/win32/mozconfig.vs2010-win64
 else
--- a/browser/metro/base/content/RemoteTabs.js
+++ b/browser/metro/base/content/RemoteTabs.js
@@ -5,121 +5,118 @@
 
 'use strict';
 Components.utils.import("resource://services-sync/main.js");
 
 /**
  * Wraps a list/grid control implementing nsIDOMXULSelectControlElement and
  * fills it with the user's synced tabs.
  *
+ * Note, the Sync module takes care of initializing the sync service. We should
+ * not make calls that start sync or sync tabs since this module loads really
+ * early during startup.
+ *
  * @param    aSet         Control implementing nsIDOMXULSelectControlElement.
  * @param    aSetUIAccess The UI element that should be hidden when Sync is
  *                          disabled. Must sanely support 'hidden' attribute.
  *                          You may only have one UI access point at this time.
  */
-function RemoteTabsView(aSet, aSetUIAccess) {
+function RemoteTabsView(aSet, aSetUIAccessList) {
   this._set = aSet;
   this._set.controller = this;
-  this._uiAccessElement = aSetUIAccess;
+  this._uiAccessElements = aSetUIAccessList;
 
   // Sync uses special voodoo observers.
   // If you want to change this code, talk to the fx-si team
-  Weave.Svc.Obs.add("weave:service:setup-complete", this);
   Weave.Svc.Obs.add("weave:service:sync:finish", this);
   Weave.Svc.Obs.add("weave:service:start-over", this);
   if (this.isSyncEnabled() ) {
-    this.populateTabs();
     this.populateGrid();
-    this.setUIAccessVisible(true);
   }
   else {
     this.setUIAccessVisible(false);
   }
 }
 
 RemoteTabsView.prototype = {
   _set: null,
-  _uiAccessElement: null,
+  _uiAccessElements: [],
 
   handleItemClick: function tabview_handleItemClick(aItem) {
     let url = aItem.getAttribute("value");
     BrowserUI.goToURI(url);
   },
 
   observe: function(subject, topic, data) {
     switch (topic) {
-      case "weave:service:setup-complete":
-        this.populateTabs();
-        this.setUIAccessVisible(true);
-        break;
       case "weave:service:sync:finish":
         this.populateGrid();
         break;
       case "weave:service:start-over":
         this.setUIAccessVisible(false);
         break;
     }
   },
 
   setUIAccessVisible: function setUIAccessVisible(aVisible) {
-    this._uiAccessElement.hidden = !aVisible;
+    for (let elem of this._uiAccessElements) {
+      elem.hidden = !aVisible;
+    }
   },
 
   populateGrid: function populateGrid() {
 
     let tabsEngine = Weave.Service.engineManager.get("tabs");
     let list = this._set;
     let seenURLs = new Set();
 
     // Clear grid, We don't know what has happened to tabs since last sync
     // Also can result in duplicate tabs(bug 864614)
     this._set.clearAll();
-
+    let show = false;
     for (let [guid, client] in Iterator(tabsEngine.getAllClients())) {
       client.tabs.forEach(function({title, urlHistory, icon}) {
         let url = urlHistory[0];
         if (tabsEngine.locallyOpenTabMatchesURL(url) || seenURLs.has(url)) {
           return;
         }
         seenURLs.add(url);
+        show = true;
 
         // If we wish to group tabs by client, we should be looking for records
         //  of {type:client, clientName, class:{mobile, desktop}} and will
         //  need to readd logic to reset seenURLs for each client.
 
         let item = this._set.appendItem((title || url), url);
         item.setAttribute("iconURI", Weave.Utils.getIcon(icon));
 
       }, this);
     }
-  },
-
-  populateTabs: function populateTabs() {
-    Weave.Service.scheduler.scheduleNextSync(0);
+    this.setUIAccessVisible(show);
   },
 
   destruct: function destruct() {
-    Weave.Svc.Obs.remove("weave:service:setup-complete", this);
     Weave.Svc.Obs.remove("weave:engine:sync:finish", this);
     Weave.Svc.Obs.remove("weave:service:logout:start-over", this);
   },
 
   isSyncEnabled: function isSyncEnabled() {
     return (Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED);
   }
 
 };
 
 let RemoteTabsStartView = {
   _view: null,
   get _grid() { return document.getElementById("start-remotetabs-grid"); },
 
   init: function init() {
     let vbox = document.getElementById("start-remotetabs");
-    this._view = new RemoteTabsView(this._grid, vbox);
+    let uiList = [vbox];
+    this._view = new RemoteTabsView(this._grid, uiList);
   },
 
   uninit: function uninit() {
     this._view.destruct();
   },
 
   show: function show() {
     this._grid.arrangeItems();
@@ -128,19 +125,21 @@ let RemoteTabsStartView = {
 
 let RemoteTabsPanelView = {
   _view: null,
 
   get _grid() { return document.getElementById("remotetabs-list"); },
   get visible() { return PanelUI.isPaneVisible("remotetabs-container"); },
 
   init: function init() {
-    //decks are fragile, don't hide the tab panel(bad things happen), hide link.
+    //decks are fragile, don't hide the tab panel(bad things happen), hide link in menu.
     let menuEntry = document.getElementById("menuitem-remotetabs");
-    this._view = new RemoteTabsView(this._grid, menuEntry);
+    let snappedEntry = document.getElementById("snappedRemoteTabsLabel");
+    let uiList = [menuEntry, snappedEntry];
+    this._view = new RemoteTabsView(this._grid, uiList);
   },
 
   show: function show() {
     this._grid.arrangeItems();
   },
 
   uninit: function uninit() {
     this._view.destruct();
new file mode 100644
--- /dev/null
+++ b/browser/metro/base/content/bindings/cssthrobber.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+   - License, v. 2.0. If a copy of the MPL was not distributed with this
+   - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<bindings
+    xmlns="http://www.mozilla.org/xbl"
+    xmlns:xbl="http://www.mozilla.org/xbl"
+    xmlns:html="http://www.w3.org/1999/xhtml"
+    xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+  <binding id="cssthrobberBinding" extends="xul:box">
+    <content>
+      <html:div class="progressContainer">
+        <html:div class="progressBall" />
+        <html:div class="progressBall" />
+        <html:div class="progressBall" />
+        <html:div class="progressBall" />
+        <html:div class="progressBall" />
+      </html:div>
+    </content>
+  </binding>
+</bindings>
--- a/browser/metro/base/content/browser-scripts.js
+++ b/browser/metro/base/content/browser-scripts.js
@@ -129,17 +129,17 @@ let ScriptContexts = {};
   ["TopSitesView", "chrome://browser/content/TopSites.js"],
   ["TopSitesSnappedView", "chrome://browser/content/TopSites.js"],
   ["TopSitesStartView", "chrome://browser/content/TopSites.js"],
   ["Sanitizer", "chrome://browser/content/sanitize.js"],
   ["SanitizeUI", "chrome://browser/content/sanitizeUI.js"],
   ["SSLExceptions", "chrome://browser/content/exceptions.js"],
   ["ItemPinHelper", "chrome://browser/content/helperui/ItemPinHelper.js"],
 #ifdef MOZ_SERVICES_SYNC
-  ["WeaveGlue", "chrome://browser/content/sync.js"],
+  ["Sync", "chrome://browser/content/sync.js"],
   ["SyncPairDevice", "chrome://browser/content/sync.js"],
   ["RemoteTabsView", "chrome://browser/content/RemoteTabs.js"],
   ["RemoteTabsPanelView", "chrome://browser/content/RemoteTabs.js"],
   ["RemoteTabsStartView", "chrome://browser/content/RemoteTabs.js"],
 #endif
 ].forEach(function (aScript) {
   let [name, script] = aScript;
   XPCOMUtils.defineLazyGetter(window, name, function() {
--- a/browser/metro/base/content/browser-ui.js
+++ b/browser/metro/base/content/browser-ui.js
@@ -72,16 +72,17 @@ var Strings = {};
   });
 });
 
 var BrowserUI = {
   get _edit() { return document.getElementById("urlbar-edit"); },
   get _back() { return document.getElementById("cmd_back"); },
   get _forward() { return document.getElementById("cmd_forward"); },
 
+  lastKnownGoodURL: "", //used when the user wants to escape unfinished url entry
   init: function() {
     // listen content messages
     messageManager.addMessageListener("DOMTitleChanged", this);
     messageManager.addMessageListener("DOMWillOpenModalDialog", this);
     messageManager.addMessageListener("DOMWindowClose", this);
 
     messageManager.addMessageListener("Browser:OpenURI", this);
     messageManager.addMessageListener("Browser:SaveAs:Return", this);
@@ -142,17 +143,17 @@ var BrowserUI = {
       try {
         BrowserUI._updateTabsOnly();
         Downloads.init();
         DialogUI.init();
         FormHelperUI.init();
         FindHelperUI.init();
         PdfJs.init();
 #ifdef MOZ_SERVICES_SYNC
-        WeaveGlue.init();
+        Sync.init();
 #endif
       } catch(ex) {
         Util.dumpLn("Exception in delay load module:", ex.message);
       }
 
 #ifdef MOZ_UPDATER
       // Check for updates in progress
       let updatePrompt = Cc["@mozilla.org/updates/update-prompt;1"].createInstance(Ci.nsIUpdatePrompt);
@@ -637,16 +638,17 @@ var BrowserUI = {
     if (isLoading && mode != "loading")
       Elements.urlbarState.setAttribute("mode", "loading");
     else if (!isLoading && mode != "edit")
       Elements.urlbarState.setAttribute("mode", "view");
   },
 
   _setURI: function _setURI(aURL) {
     this._edit.value = aURL;
+    this.lastKnownGoodURL = aURL;
   },
 
   _urlbarClicked: function _urlbarClicked() {
     // If the urlbar is not already focused, focus it and select the contents.
     if (Elements.urlbarState.getAttribute("mode") != "edit")
       this._editURI(true);
   },
 
@@ -722,16 +724,17 @@ var BrowserUI = {
 
   // Checks if various different parts of the UI is visible and closes
   // them one at a time.
   handleEscape: function (aEvent) {
     aEvent.stopPropagation();
     aEvent.preventDefault();
 
     if (this._edit.popupOpen) {
+      this._edit.value = this.lastKnownGoodURL;
       this._edit.closePopup();
       StartUI.hide();
       ContextUI.dismiss();
       return;
     }
 
     // Check open popups
     if (DialogUI._popup) {
@@ -742,18 +745,19 @@ var BrowserUI = {
     // Check open dialogs
     let dialog = DialogUI.activeDialog;
     if (dialog) {
       dialog.close();
       return;
     }
 
     // Check open modal elements
-    if (DialogUI.modals.length > 0)
+    if (DialogUI.modals.length > 0) {
       return;
+    }
 
     // Check open panel
     if (PanelUI.isVisible) {
       PanelUI.hide();
       return;
     }
 
     // Check content helper
@@ -1036,17 +1040,17 @@ var BrowserUI = {
       case "cmd_bookmarks":
         PanelUI.show("bookmarks-container");
         break;
       case "cmd_history":
         PanelUI.show("history-container");
         break;
       case "cmd_remoteTabs":
         if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED) {
-          WeaveGlue.open();
+          Sync.open();
         } else {
           PanelUI.show("remotetabs-container");
         }
         break;
       case "cmd_quit":
         // Only close one window
         this._closeOrQuit();
         break;
@@ -1473,17 +1477,17 @@ var StartUI = {
 };
 
 var SyncPanelUI = {
   init: function() {
     // Run some setup code the first time the panel is shown.
     Elements.syncFlyout.addEventListener("PopupChanged", function onShow(aEvent) {
       if (aEvent.detail && aEvent.target === Elements.syncFlyout) {
         Elements.syncFlyout.removeEventListener("PopupChanged", onShow, false);
-        WeaveGlue.init();
+        Sync.init();
       }
     }, false);
   }
 };
 
 var FlyoutPanelsUI = {
   get _aboutVersionLabel() {
     return document.getElementById('about-version-label');
--- a/browser/metro/base/content/browser.css
+++ b/browser/metro/base/content/browser.css
@@ -25,16 +25,20 @@ documenttab {
 appbar {
   -moz-binding: url('chrome://browser/content/bindings/appbar.xml#appbarBinding');
 }
 
 flyoutpanel {
   -moz-binding: url('chrome://browser/content/bindings/flyoutpanel.xml#flyoutpanelBinding');
 }
 
+cssthrobber {
+  -moz-binding: url('chrome://browser/content/bindings/cssthrobber.xml#cssthrobberBinding');
+}
+
 settings {
   -moz-binding: url("chrome://mozapps/content/extensions/setting.xml#settings");
 }
 
 setting {
   display: none;
 }
 
--- a/browser/metro/base/content/browser.xul
+++ b/browser/metro/base/content/browser.xul
@@ -3,16 +3,17 @@
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 <?xml-stylesheet href="chrome://browser/skin/platform.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/skin/browser.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/skin/forms.css" type="text/css"?>
 <?xml-stylesheet href="chrome://browser/content/browser.css" type="text/css"?>
+<?xml-stylesheet href="chrome://browser/skin/cssthrobber.css" type="text/css"?>
 
 <!DOCTYPE window [
 <!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
 %globalDTD;
 <!ENTITY % browserDTD SYSTEM "chrome://browser/locale/browser.dtd">
 %browserDTD;
 <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
 %brandDTD;
@@ -279,23 +280,23 @@
             </vbox>
             </scrollbox>
           </hbox>
           <!-- snapped view -->
           <vbox id="snapped-start" class="start-page" observes="bcast_windowState">
             <scrollbox id="snapped-scrollbox" orient="vertical" flex="1">
               <vbox id="snapped-topsites">
                 <label class="meta-section-title" value="&startTopSitesHeader.label;"/>
-                <richgrid id="snapped-topsites-grid" rows="8" columns="1" flex="1"/>
+                <richgrid id="snapped-topsites-grid" class="canSnapTiles" rows="8" columns="1" flex="1"/>
               </vbox>
               <label class="meta-section-title" value="&startBookmarksHeader.label;"
                 onclick="PanelUI.show('bookmarks-container');"/>
               <label class="meta-section-title" value="&startHistoryHeader.label;"
                 onclick="PanelUI.show('history-container');" inputProcessing="true"/>
-              <label class="meta-section-title" value="&startRemoteTabsHeader.label;"
+              <label id="snappedRemoteTabsLabel" class="meta-section-title" value="&snappedRemoteTabsHeader.label;"
                 onclick="PanelUI.show('remotetabs-container');" inputProcessing="true"/>
             </scrollbox>
           </vbox>
           <!-- Autocompletion interface -->
           <box id="start-autocomplete" observes="bcast_windowState"/>
         </hbox>
       </vbox> <!-- end tray -->
 
@@ -396,29 +397,47 @@
         <label value="&aboutHeader.company.label;"/>
 #expand <label id="about-version-label">__MOZ_APP_VERSION__</label>
         <label id="about-policy-label"
                onclick="if (event.button == 0) { Browser.onAboutPolicyClick(); }"
                class="text-link" value="&aboutHeader.policy.label;"/>
     </flyoutpanel>
 
     <flyoutpanel id="sync-flyoutpanel" headertext="&syncHeader.title;">
-      <setting id="sync-connect" title="&sync.notconnected;" type="control">
-        <button label="&sync.connect;" oncommand="WeaveGlue.tryConnect();" />
+      <description>&sync.setup.description;</description> 
+      <description id="sync-accountinfo" collapsed="true"></description> 
+      <description id="sync-lastsync" collapsed="true"></description> 
+      <description id="sync-errordescription" collapsed="true"></description> 
+      <setting id="sync-connect" type="control" collapsed="true">
+        <button label="&sync.setupbutton.label;" oncommand="Sync.tryConnect();" />
       </setting>
-      <setting id="sync-connected" class="setting-group" title="&sync.connected;" type="control" collapsed="true">
+      <setting id="sync-connected" class="setting-group" type="control" collapsed="true">
         <button id="sync-pairdevice" label="&sync.pair.button;" oncommand="SyncPairDevice.open();" />
       </setting>
-      <setting id="sync-sync" class="setting-subgroup" type="control" collapsed="true">
-        <button id="sync-syncButton" label="&sync.syncNow2;" oncommand="WeaveGlue.sync();"/>
+      <setting id="sync-device" class="setting-subgroup" type="string" title="&sync.deviceName;" onchange="Sync.changeName(this);" collapsed="true"/>
+      <setting id="sync-disconnect" class="setting-subgroup" type="control" collapsed="true">
+        <button label="&sync.removebutton.label;" oncommand="Sync.onDisconnect();" />
       </setting>
-      <setting id="sync-device" class="setting-subgroup" type="string" title="&sync.deviceName;" onchange="WeaveGlue.changeName(this);" collapsed="true"/>
-      <setting id="sync-disconnect" class="setting-subgroup" type="control" collapsed="true">
-        <button label="&sync.disconnect;" oncommand="WeaveGlue.disconnect();" />
-      </setting>
+      <vbox id="sync-disconnectwarnpanel" collapsed="true">
+        <description id="sync-disconnectwarntitle"></description>
+        <description id="sync-disconnectwarnmsg">&sync.removewarn.note;</description>
+        <hbox>
+          <spacer flex="1" />
+          <button label="&sync.setup.cancel;" oncommand="Sync.onCancelDisconnect();" />
+          <button label="&sync.setup.remove;" oncommand="Sync.disconnect();" />
+        </hbox>
+      </vbox>
+      <vbox id="sync-disconnectthrobber" collapsed="true">
+        <hbox>
+          <spacer flex="1" />
+          <cssthrobber id="syncdisconnectthrobber" />
+          <label>&sync.removethrobber.label;</label>
+          <spacer flex="1" />
+        </hbox>
+      </vbox>
     </flyoutpanel>
 
     <flyoutpanel id="prefs-flyoutpanel" headertext="&optionsHeader.title;">
       <settings id="prefs-startup" label="&optionsHeader.startup.title;"> <!-- note, this element has a custom margin-top -->
         <setting id="prefs-homepage" title="&optionsHeader.homepage.title;" type="menulist" pref="browser.startup.sessionRestore" class="setting-expanded">
           <menulist id="prefs-homepage-options">
             <menupopup id="prefs-homepage-popup" position="after_end">
               <menuitem id="prefs-homepage-default" label="&optionsHeader.homepage.startPage.button;" value="false"/>
@@ -473,89 +492,89 @@
       </settings>
     </flyoutpanel>
 
 #ifdef MOZ_SERVICES_SYNC
     <box id="syncsetup-container" class="perm-modal-block" hidden="true">
       <dialog id="syncsetup-dialog" class="content-dialog" flex="1">
         <vbox class="prompt-inner">
           <hbox class="prompt-title">
-            <description>&sync.setup.title;</description>
+            <description>&sync.setup2.title;</description>
           </hbox>
           <vbox id="syncsetup-simple" class="syncsetup-page" flex="1">
             <scrollbox id="sync-message" class="prompt-message" orient="vertical" flex="1">
               <description class="syncsetup-desc" flex="1">&sync.setup.pair2;</description>
-              <description class="link" flex="1" onclick="WeaveGlue.openTutorial();">&sync.setup.tutorial;</description>
+              <description class="link" flex="1" onclick="Sync.openTutorial();">&sync.setup.tutorial;</description>
               <separator/>
               <vbox flex="1" pack="center" align="start">
                 <description id="syncsetup-code1" class="syncsetup-code">....</description>
                 <description id="syncsetup-code2" class="syncsetup-code">....</description>
                 <description id="syncsetup-code3" class="syncsetup-code">....</description>
               </vbox>
               <separator/>
-              <description class="link" flex="1" onclick="WeaveGlue.openManual();">&sync.fallback;</description>
+              <description class="link" flex="1" onclick="Sync.openManual();">&sync.fallback;</description>
               <separator flex="1"/>
             </scrollbox>
             <hbox class="prompt-buttons">
-              <button class="prompt-button" oncommand="WeaveGlue.close();">&sync.setup.cancel;</button>
+              <button oncommand="Sync.close();">&sync.setup.cancel;</button>
             </hbox>
           </vbox>
           <vbox id="syncsetup-waiting" class="syncsetup-page" flex="1" hidden="true">
             <progressmeter id="syncsetup-progressbar" mode="undetermined"/>
             <vbox id="syncsetup-waiting-top" align="center" flex="1">
               <description id="syncsetup-waiting-desc" class="syncsetup-desc" flex="1">&sync.setup.waiting2;</description>
               <description id="syncsetup-waitingdownload-desc" class="syncsetup-desc" hidden="true" flex="1">&sync.setup.waitingdownload;</description>
             </vbox>
             <hbox class="prompt-buttons" pack="center" align="end">
-              <button id="syncsetup-waiting-cancel" class="prompt-button" oncommand="WeaveGlue.close();">&sync.setup.cancel;</button>
-              <button id="syncsetup-waiting-close" class="prompt-button" hidden="true" oncommand="WeaveGlue.close();">&sync.setup.close;</button>
+              <button id="syncsetup-waiting-cancel" oncommand="Sync.close();">&sync.setup.cancel;</button>
+              <button id="syncsetup-waiting-close" hidden="true" oncommand="Sync.close();">&sync.setup.close;</button>
             </hbox>
           </vbox>
           <vbox id="syncsetup-fallback" class="syncsetup-page" flex="1" hidden="true">
             <scrollbox class="prompt-message" orient="vertical" flex="1">
               <description class="syncsetup-desc" flex="1">&sync.setup.manual;</description>
               <separator/>
-              <textbox id="syncsetup-account" class="prompt-edit" placeholder="&sync.account;" oninput="WeaveGlue.canConnect();"/>
-              <textbox id="syncsetup-password" class="prompt-edit" placeholder="&sync.password;" type="password" oninput="WeaveGlue.canConnect();"/>
-              <textbox id="syncsetup-synckey" class="prompt-edit" placeholder="&sync.recoveryKey;" oninput="WeaveGlue.canConnect();"/>
+              <textbox id="syncsetup-account" class="prompt-edit" placeholder="&sync.account;" oninput="Sync.canConnect();"/>
+              <textbox id="syncsetup-password" class="prompt-edit" placeholder="&sync.password;" type="password" oninput="Sync.canConnect();"/>
+              <textbox id="syncsetup-synckey" class="prompt-edit" placeholder="&sync.recoveryKey;" oninput="Sync.canConnect();"/>
               <separator class="thin"/>
-              <checkbox id="syncsetup-usecustomserver" label="&sync.customServer;" oncommand="WeaveGlue.toggleCustomServer();"/>
+              <checkbox id="syncsetup-usecustomserver" label="&sync.customServer;" oncommand="Sync.toggleCustomServer();"/>
               <textbox id="syncsetup-customserver" class="prompt-edit" placeholder="&sync.serverURL;"/>
               <separator flex="1"/>
             </scrollbox>
             <hbox class="prompt-buttons">
-              <button class="prompt-button" oncommand="WeaveGlue.close();">&sync.setup.cancel;</button>
+              <button oncommand="Sync.close();">&sync.setup.cancel;</button>
               <separator/>
-              <button id="syncsetup-button-connect" class="prompt-button" oncommand="WeaveGlue.close(); WeaveGlue.connect();">&sync.setup.connect;</button>
+              <button id="syncsetup-button-connect" oncommand="Sync.close(); Sync.connect();">&sync.setup.connect2;</button>
             </hbox>
           </vbox>
         </vbox>
       </dialog>
     </box>
 
     <box id="syncpair-container" class="perm-modal-block" hidden="true">
       <dialog id="syncpair-dialog" class="content-dialog" flex="1">
         <vbox class="prompt-inner">
           <hbox class="prompt-title">
             <description>&sync.pair.title;</description>
           </hbox>
           <vbox id="syncpair-simple" class="syncsetup-page" flex="1">
             <vbox id="sync-message" class="prompt-message" orient="vertical" flex="1">
               <description class="syncsetup-desc" flex="1">&sync.pair.description;</description>
-              <description class="link" flex="1" onclick="SyncPairDevice.close(); WeaveGlue.openTutorial();">&sync.setup.tutorial;</description>
+              <description class="link" flex="1" onclick="SyncPairDevice.close(); Sync.openTutorial();">&sync.setup.tutorial;</description>
               <separator/>
               <vbox align="center" flex="1">
                 <textbox id="syncpair-code1" class="syncsetup-code" oninput="SyncPairDevice.onTextBoxInput(this);"/>
                 <textbox id="syncpair-code2" class="syncsetup-code" oninput="SyncPairDevice.onTextBoxInput(this);"/>
                 <textbox id="syncpair-code3" class="syncsetup-code" oninput="SyncPairDevice.onTextBoxInput(this);"/>
               </vbox>
             </vbox>
             <hbox class="prompt-buttons" pack="center">
-              <button class="prompt-button" oncommand="SyncPairDevice.close();">&sync.setup.cancel;</button>
-              <button id="syncpair-connectbutton" class="prompt-button" disabled="true" oncommand="SyncPairDevice.connect();">&sync.setup.connect;</button>
+              <button oncommand="SyncPairDevice.close();">&sync.setup.cancel;</button>
+              <button id="syncpair-connectbutton" disabled="true" oncommand="SyncPairDevice.connect();">&sync.setup.connect2;</button>
             </hbox>
           </vbox>
         </vbox>
       </dialog>
     </box>
 #endif
 
     <box onclick="event.stopPropagation();" id="context-container" class="menu-container" hidden="true">
--- a/browser/metro/base/content/prompt/confirm.xul
+++ b/browser/metro/base/content/prompt/confirm.xul
@@ -29,13 +29,13 @@
       <scrollbox orient="vertical" class="prompt-message" flex="1">
         <description id="prompt-confirm-message"/>
       </scrollbox>
   
       <checkbox id="prompt-confirm-checkbox" collapsed="true" pack="start" flex="1"/>
     </vbox>
   
     <hbox id="prompt-confirm-buttons-box" class="prompt-buttons">
-      <button class="prompt-button button-default" label="&ok.label;" command="cmd_ok"/>
-      <button class="prompt-button" label="&cancel.label;" command="cmd_cancel"/>
+      <button class="button-default" label="&ok.label;" command="cmd_ok"/>
+      <button label="&cancel.label;" command="cmd_cancel"/>
     </hbox>
   </vbox>
 </dialog>
--- a/browser/metro/base/content/prompt/prompt.xul
+++ b/browser/metro/base/content/prompt/prompt.xul
@@ -31,13 +31,13 @@
       </scrollbox>
   
       <textbox id="prompt-prompt-textbox" class="prompt-edit"/>
   
       <button id="prompt-prompt-checkbox" collapsed="true" pack="start" flex="1"/>
     </vbox>
   
     <hbox class="prompt-buttons">
-      <button class="prompt-button" label="&ok.label;" command="cmd_ok"/>
-      <button class="prompt-button" label="&cancel.label;" command="cmd_cancel"/>
+      <button label="&ok.label;" command="cmd_ok"/>
+      <button label="&cancel.label;" command="cmd_cancel"/>
     </hbox>
   </vbox>
 </dialog>
--- a/browser/metro/base/content/prompt/promptPassword.xul
+++ b/browser/metro/base/content/prompt/promptPassword.xul
@@ -51,13 +51,13 @@
           </row>
         </rows>
       </grid>
     
       <checkbox id="prompt-password-checkbox" collapsed="true" pack="start" flex="1"/>
     </vbox>
   
     <hbox class="prompt-buttons">
-      <button class="prompt-button button-default" label="&ok.label;" command="cmd_ok"/>
-      <button class="prompt-button" label="&cancel.label;" command="cmd_cancel"/>
+      <button class="button-default" label="&ok.label;" command="cmd_ok"/>
+      <button label="&cancel.label;" command="cmd_cancel"/>
   </hbox>
   </vbox>
 </dialog>
--- a/browser/metro/base/content/prompt/select.xul
+++ b/browser/metro/base/content/prompt/select.xul
@@ -29,13 +29,13 @@
       <scrollbox orient="vertical" class="prompt-message" flex="1">
         <description id="prompt-select-message"/>
       </scrollbox>
   
       <menulist id="prompt-select-list"/>
     </vbox>
   
     <hbox class="prompt-buttons">
-      <button class="prompt-button button-default" label="&ok.label;" command="cmd_ok"/>
-      <button class="prompt-button" label="&cancel.label;" command="cmd_cancel"/>
+      <button class="button-default" label="&ok.label;" command="cmd_ok"/>
+      <button label="&cancel.label;" command="cmd_cancel"/>
     </hbox>
   </vbox>
 </dialog>
--- a/browser/metro/base/content/sanitize.js
+++ b/browser/metro/base/content/sanitize.js
@@ -61,17 +61,17 @@ Sanitizer.prototype = {
   
   items: {
     // Clear Sync account before passwords so that Sync still has access to the
     // credentials to clean up device-specific records on the server. Also
     // disable it before wiping history so we don't accidentally sync that.
     syncAccount: {
       clear: function ()
       {
-        WeaveGlue.disconnect();
+        Sync.disconnect();
       },
 
       get canClear()
       {
         return (Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED);
       }
     },
 
--- a/browser/metro/base/content/sync.js
+++ b/browser/metro/base/content/sync.js
@@ -1,34 +1,50 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-let WeaveGlue = {
+let Sync = {
   setupData: null,
   _boundOnEngineSync: null,     // Needed to unhook the observers in close().
   _boundOnServiceSync: null,
   jpake: null,
   _bundle: null,
   _loginError: false,
   _progressBar: null,
   _progressValue: 0,
   _progressMax: null,
+  _disconnecting: false,
+
+  get _isSetup() {
+    if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED) {
+      return false;
+    }
+    // check for issues related to failed logins that do not have anything to
+    // do with network, server, and other non-client issues. See the login
+    // failure status codes in sync service.
+    return (Weave.Status.login != Weave.LOGIN_FAILED_NO_USERNAME &&
+            Weave.Status.login != Weave.LOGIN_FAILED_NO_PASSWORD &&
+            Weave.Status.login != Weave.LOGIN_FAILED_NO_PASSPHRASE &&
+            Weave.Status.login != Weave.LOGIN_FAILED_INVALID_PASSPHRASE &&
+            Weave.Status.login != Weave.LOGIN_FAILED_LOGIN_REJECTED);
+  },
 
   init: function init() {
     if (this._bundle) {
       return;
     }
 
     let service = Components.classes["@mozilla.org/weave/service;1"]
                                     .getService(Components.interfaces.nsISupports)
                                     .wrappedJSObject;
 
     if (service.ready) {
       this._init();
+      Weave.Service.scheduler.scheduleNextSync(10*1000); // ten seconds after we startup
     } else {
       Services.obs.addObserver(this, "weave:service:ready", false);
       service.ensureLoaded();
     }
   },
 
 #ifdef XP_WIN
   _securelySetupFromMetro: function() {
@@ -60,34 +76,28 @@ let WeaveGlue = {
 
     this.connect();
     return true;
   },
 #endif
 
   _init: function () {
     this._bundle = Services.strings.createBundle("chrome://browser/locale/sync.properties");
-    this._msg = document.getElementById("prefs-messages");
 
     this._addListeners();
 
     this.setupData = { account: "", password: "" , synckey: "", serverURL: "" };
 
-    if (Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED) {
-      // Put the settings UI into a state of "connecting..." if we are going to auto-connect
-      this._elements.connect.firstChild.disabled = true;
-      this._elements.connect.setAttribute("title", this._bundle.GetStringFromName("connecting.label"));
-
-      try {
-        this._elements.device.value = Services.prefs.getCharPref("services.sync.client.name");
-      } catch(e) {}
-    } else if (Weave.Status.login != Weave.LOGIN_FAILED_NO_USERNAME) {
+    if (this._isSetup) {
       this.loadSetupData();
     }
 
+    // Update the state of the ui
+    this._updateUI();
+
     this._boundOnEngineSync = this.onEngineSync.bind(this);
     this._boundOnServiceSync = this.onServiceSync.bind(this);
     this._progressBar = document.getElementById("syncsetup-progressbar");
 
 #ifdef XP_WIN
     if (Weave.Status.checkSetup() == Weave.CLIENT_NOT_CONFIGURED) {
       this._securelySetupFromMetro();
     }
@@ -365,179 +375,219 @@ let WeaveGlue = {
       Weave.Service.serverURL = this.setupData.serverURL;
 
     // Sync will use the account value and munge it into a username, as needed
     Weave.Service.identity.account = this.setupData.account;
     Weave.Service.identity.basicPassword = this.setupData.password;
     Weave.Service.identity.syncKey = this.setupData.synckey;
     Weave.Service.persistLogin();
     Weave.Svc.Obs.notify("weave:service:setup-complete");
-    setTimeout(function () { Weave.Service.sync(); }, 0);
+    this.sync();
+  },
+
+  // called when the user taps the disconnect button
+  onDisconnect: function onDisconnect() {
+    Weave.Service.logout();
+    let bundle = Services.strings.createBundle("chrome://branding/locale/brand.properties");
+    let brandName = bundle.GetStringFromName("brandShortName");
+    let warnStr = this._bundle.formatStringFromName("sync.disconnectPrompt", [brandName], 1);
+    this._elements.disconnectwarntitle.textContent = warnStr;
+    this._elements.disconnectwarnpanel.collapsed = false;
   },
 
-  disconnect: function disconnect() {
-    // Save credentials for undo
-    let undoData = this.setupData;
-
-    // Remove all credentials
-    this.setupData = null;
-    Weave.Service.startOver();
+  // called when the user taps the cancel button on
+  // the disconnect warning panel.
+  onCancelDisconnect: function onCancelDisconnect() {
+    this._elements.disconnectwarnpanel.collapsed = true;
+    this._updateUI();
+    Weave.Service.login();
+  },
 
-    let message = this._bundle.GetStringFromName("notificationDisconnect.label");
-    let button = this._bundle.GetStringFromName("notificationDisconnect.button");
-    let buttons = [ {
-      label: button,
-      accessKey: "",
-      callback: function() { WeaveGlue.connect(undoData); }
-    } ];
-    this.showMessage(message, "undo-disconnect", buttons);
-
-    // Hide the notification when the panel is changed or closed.
-    let panel = document.getElementById("prefs-container");
-    panel.addEventListener("ToolPanelHidden", function onHide(aEvent) {
-      panel.removeEventListener(aEvent.type, onHide, false);
-      let notification = WeaveGlue._msg.getNotificationWithValue("undo-disconnect");
-      if (notification)
-        notification.close();
-    }, false);
-
-    Weave.Service.logout();
+  // called when the user taps the remove button on
+  // the disconnect warning panel.
+  disconnect: function disconnect() {
+    this._elements.disconnectwarnpanel.collapsed = true;
+    this.setupData = null;
+    this._disconnecting = true;
+    this._updateUI();
+    Weave.Service.startOver();
   },
 
   sync: function sync() {
-    Weave.Service.sync();
+    Weave.Service.scheduler.scheduleNextSync(0);
   },
 
   _addListeners: function _addListeners() {
     let topics = ["weave:service:setup-complete",
       "weave:service:sync:start", "weave:service:sync:finish",
       "weave:service:sync:error", "weave:service:login:start",
       "weave:service:login:finish", "weave:service:login:error",
       "weave:ui:login:error",
+      "weave:service:start-over", "weave:service:start-over:finish",
       "weave:service:logout:finish"];
 
-    // For each topic, add WeaveGlue the observer
+    // For each topic, add Sync the observer
     topics.forEach(function(topic) {
-      Services.obs.addObserver(WeaveGlue, topic, false);
+      Services.obs.addObserver(Sync, topic, false);
     });
 
     // Remove them on unload
     addEventListener("unload", function() {
       topics.forEach(function(topic) {
-        Services.obs.removeObserver(WeaveGlue, topic);
+        Services.obs.removeObserver(Sync, topic);
       });
     }, false);
   },
 
   get _elements() {
-    // Do a quick test to see if the options exist yet
-    let syncButton = document.getElementById("sync-syncButton");
-    if (syncButton == null)
-      return null;
-
     // Get all the setting nodes from the add-ons display
     let elements = {};
     let setupids = ["account", "password", "synckey", "usecustomserver", "customserver"];
     setupids.forEach(function(id) {
       elements[id] = document.getElementById("syncsetup-" + id);
     });
 
-    let settingids = ["device", "connect", "connected", "disconnect", "sync", "pairdevice"];
+    let settingids = ["device", "connect", "connected", "disconnect", "lastsync", "pairdevice",
+                      "errordescription", "accountinfo", "disconnectwarnpanel", "disconnectthrobber",
+                      "disconnectwarntitle"];
     settingids.forEach(function(id) {
       elements[id] = document.getElementById("sync-" + id);
     });
 
     // Replace the getter with the collection of settings
     delete this._elements;
     return this._elements = elements;
   },
 
+  _updateUI: function _updateUI() {
+    if (this._elements == null)
+      return;
+
+    let connect = this._elements.connect;
+    let connected = this._elements.connected;
+    let device = this._elements.device;
+    let disconnect = this._elements.disconnect;
+    let lastsync = this._elements.lastsync;
+    let pairdevice = this._elements.pairdevice;
+    let accountinfo = this._elements.accountinfo;
+    let disconnectthrobber = this._elements.disconnectthrobber;
+
+    // This gets updated when an error occurs
+    this._elements.errordescription.collapsed = true;
+
+    let isConfigured = (!this._loginError && this._isSetup);
+
+    // If we're in the process of disconnecting we are no longer configured.
+    if (this._disconnecting) {
+      isConfigured = false;
+      // display the throbber with the appropriate message
+      disconnectthrobber.collapsed = false;
+    } else {
+      disconnectthrobber.collapsed = true;
+    }
+
+    connect.collapsed = isConfigured;
+    connected.collapsed = !isConfigured;
+    lastsync.collapsed = !isConfigured;
+    device.collapsed = !isConfigured;
+    disconnect.collapsed = !isConfigured;
+
+    if (this._disconnecting) {
+      connect.collapsed = true;
+    }
+
+    // Set the device name text edit to configured name or the auto generated
+    // name if we aren't set up.
+    try {
+      device.value = Services.prefs.getCharPref("services.sync.client.name");
+    } catch(ex) {
+      device.value = Weave.Service.clientsEngine.localName || "";
+    }
+
+    // Account information header
+    accountinfo.collapsed = true;
+    try {
+      let account = Weave.Service.identity.account;
+      if (account != null && isConfigured) {
+        let accountStr = this._bundle.formatStringFromName("account.label", [account], 1);
+        accountinfo.textContent = accountStr;
+        accountinfo.collapsed = false;
+      }
+    } catch (ex) {}
+
+    // If we're already locked, a sync is in progress..
+    if (Weave.Service.locked && isConfigured) {
+      connect.firstChild.disabled = true;
+    }
+
+    // Show the day-of-week and time (HH:MM) of last sync
+    let lastSync = Weave.Svc.Prefs.get("lastSync");
+    lastsync.textContent = "";
+    if (lastSync != null) {
+      let syncDate = new Date(lastSync).toLocaleFormat("%A %I:%M %p");
+      let dateStr = this._bundle.formatStringFromName("lastSync2.label", [syncDate], 1);
+      lastsync.textContent = dateStr;
+    }
+
+    // Check the lock again on a timeout since it's set after observers notify
+    setTimeout(function(self) {
+      // Prevent certain actions when the service is locked
+      if (Weave.Service.locked) {
+        connect.firstChild.disabled = true;
+      } else {
+        connect.firstChild.disabled = false;
+      }
+    }, 100, this);
+  },
+
   observe: function observe(aSubject, aTopic, aData) {
     if (aTopic == "weave:service:ready") {
       Services.obs.removeObserver(this, aTopic);
       this._init();
       return;
     }
 
     // Make sure we're online when connecting/syncing
     Util.forceOnline();
 
+    if (aTopic == "weave:service:start-over") {
+      this._disconnecting = true;
+    } else if (aTopic == "weave:service:start-over:finish") {
+      this._disconnecting = false;
+    }
+
     // Can't do anything before settings are loaded
     if (this._elements == null)
       return;
 
-    // Make some aliases
-    let connect = this._elements.connect;
-    let connected = this._elements.connected;
-    let device = this._elements.device;
-    let disconnect = this._elements.disconnect;
-    let sync = this._elements.sync;
-    let pairdevice = this._elements.pairdevice;
+    // Update the state of the ui
+    this._updateUI();
+
+    let errormsg = this._elements.errordescription;
+    let accountinfo = this._elements.accountinfo;
 
     // Show what went wrong with login if necessary
     if (aTopic == "weave:ui:login:error") {
       this._loginError = true;
-      connect.setAttribute("desc", Weave.Utils.getErrorString(Weave.Status.login));
-    } else {
-      connect.removeAttribute("desc");
+      errormsg.textContent = Weave.Utils.getErrorString(Weave.Status.login);
+      errormsg.collapsed = false;
     }
 
     if (aTopic == "weave:service:login:finish") {
       this._loginError = false;
       // Init the setup data if we just logged in
       if (!this.setupData)
         this.loadSetupData();
     }
 
-    let isConfigured = (!this._loginError && Weave.Status.checkSetup() != Weave.CLIENT_NOT_CONFIGURED);
-
-    connect.collapsed = isConfigured;
-    connected.collapsed = !isConfigured;
-
-    if (!isConfigured) {
-      connect.setAttribute("title", this._bundle.GetStringFromName("notconnected.label"));
-      connect.firstChild.disabled = false;
-    }
-
-    sync.collapsed = !isConfigured;
-    device.collapsed = !isConfigured;
-    disconnect.collapsed = !isConfigured;
-
-    // Check the lock on a timeout because it's set just after notifying
-    setTimeout(function(self) {
-      // Prevent certain actions when the service is locked
-      if (Weave.Service.locked) {
-        connect.firstChild.disabled = true;
-        sync.firstChild.disabled = true;
-
-        if (aTopic == "weave:service:login:start")
-          connect.setAttribute("title", self._bundle.GetStringFromName("connecting.label"));
-
-        if (aTopic == "weave:service:sync:start")
-          sync.setAttribute("title", self._bundle.GetStringFromName("lastSyncInProgress2.label"));
-      } else {
-        connect.firstChild.disabled = false;
-        sync.firstChild.disabled = false;
-      }
-    }, 0, this);
-
-    // Dynamically generate some strings
-    let accountStr = this._bundle.formatStringFromName("account.label", [Weave.Service.identity.account], 1);
-    disconnect.setAttribute("title", accountStr);
-
-    // Show the day-of-week and time (HH:MM) of last sync
-    let lastSync = Weave.Svc.Prefs.get("lastSync");
-    if (lastSync != null) {
-      let syncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
-      let dateStr = this._bundle.formatStringFromName("lastSync2.label", [syncDate], 1);
-      sync.setAttribute("title", dateStr);
-    }
-
     // Check for a storage format update, update the user and load the Sync update page
     if (aTopic =="weave:service:sync:error") {
+      errormsg.textContent = Weave.Utils.getErrorString(Weave.Status.sync);
+      errormsg.collapsed = false;
+
       let clientOutdated = false, remoteOutdated = false;
       if (Weave.Status.sync == Weave.VERSION_OUT_OF_DATE) {
         clientOutdated = true;
       } else if (Weave.Status.sync == Weave.DESKTOP_VERSION_OUT_OF_DATE) {
         remoteOutdated = true;
       } else if (Weave.Status.service == Weave.SYNC_FAILED_PARTIAL) {
         // Some engines failed, check for per-engine compat
         for (let [engine, reason] in Iterator(Weave.Status.engines)) {
@@ -560,47 +610,37 @@ let WeaveGlue = {
 
         let flags = Services.prompt.BUTTON_POS_0 * Services.prompt.BUTTON_TITLE_IS_STRING +
                     Services.prompt.BUTTON_POS_1 * Services.prompt.BUTTON_TITLE_IS_STRING;
         let choice = Services.prompt.confirmEx(window, title, message, flags, button, close, null, null, {});
         if (choice == 0)
           Browser.addTab("https://services.mozilla.com/update/", true, Browser.selectedTab);
       }
     }
-
-    device.value = Weave.Service.clientsEngine.localName || "";
   },
 
   changeName: function changeName(aInput) {
     // Make sure to update to a modified name, e.g., empty-string -> default
     Weave.Service.clientsEngine.localName = aInput.value;
     aInput.value = Weave.Service.clientsEngine.localName;
   },
 
-  showMessage: function showMessage(aMsg, aValue, aButtons) {
-    let notification = this._msg.getNotificationWithValue(aValue);
-    if (notification)
-      return;
-
-    this._msg.appendNotification(aMsg, aValue, "", this._msg.PRIORITY_WARNING_LOW, aButtons);
-  },
-
   _validateServer: function _validateServer(aURL) {
     let uri = Weave.Utils.makeURI(aURL);
 
     if (!uri && aURL)
       uri = Weave.Utils.makeURI("https://" + aURL);
 
     if (!uri)
       return "";
     return uri.spec;
   },
 
   openTutorial: function _openTutorial() {
-    WeaveGlue.close();
+    Sync.close();
 
     let formatter = Cc["@mozilla.org/toolkit/URLFormatterService;1"].getService(Ci.nsIURLFormatter);
     let url = formatter.formatURLPref("app.sync.tutorialURL");
     BrowserUI.newTab(url, Browser.selectedTab);
   },
 
   loadSetupData: function _loadSetupData() {
     this.setupData = {};
--- a/browser/metro/base/jar.mn
+++ b/browser/metro/base/jar.mn
@@ -21,16 +21,17 @@ chrome.jar:
   content/bindings/console.xml                 (content/bindings/console.xml)
   content/bindings/dialog.xml                  (content/bindings/dialog.xml)
   content/bindings/arrowbox.xml                (content/bindings/arrowbox.xml)
   content/bindings/grid.xml                    (content/bindings/grid.xml)
   content/bindings/autocomplete.xml            (content/bindings/autocomplete.xml)
   content/bindings/appbar.xml                  (content/bindings/appbar.xml)
   content/bindings/flyoutpanel.xml             (content/bindings/flyoutpanel.xml)
   content/bindings/selectionoverlay.xml        (content/bindings/selectionoverlay.xml)
+  content/bindings/cssthrobber.xml             (content/bindings/cssthrobber.xml)
 
   content/prompt/alert.xul                     (content/prompt/alert.xul)
   content/prompt/confirm.xul                   (content/prompt/confirm.xul)
   content/prompt/prompt.xul                    (content/prompt/prompt.xul)
   content/prompt/promptPassword.xul            (content/prompt/promptPassword.xul)
   content/prompt/select.xul                    (content/prompt/select.xul)
   content/prompt/prompt.js                     (content/prompt/prompt.js)
 
--- a/browser/metro/base/tests/mochitest/browser_remotetabs.js
+++ b/browser/metro/base/tests/mochitest/browser_remotetabs.js
@@ -1,47 +1,48 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set ts=2 et sw=2 tw=80: */
-/* Any copyright is dedicated to the Public Domain.
-   http://creativecommons.org/publicdomain/zero/1.0/ */
-"use strict";
-
-////////////////////////////////////////////////////////////////////////////////
-//// Globals
-
-Components.utils.import("resource://services-sync/main.js");
-////////////////////////////////////////////////////////////////////////////////
-//// Test(s)
-
-function test() {
-  is(Weave.Status.checkSetup(), Weave.CLIENT_NOT_CONFIGURED, "Sync should be disabled on start");
-  // check start page is hidden
-
-  let vbox = document.getElementById("start-remotetabs");
-  ok(vbox.hidden, "remote tabs in the start page should be hidden when sync is not enabled");
-  // check container link is hidden
-  let menulink = document.getElementById("menuitem-remotetabs");
-  ok(menulink.hidden, "link to container should be hidden when sync is not enabled");
-
-  // hacky-fake sync setup and enabled. Note the Sync Tracker will spit
-  // a number of warnings about undefined ids
-  Weave.Status._authManager.username = "jane doe"; // must set username before key
-  Weave.Status._authManager.basicPassword = "goatcheesesalad";
-  Weave.Status._authManager.syncKey = "a-bcdef-abcde-acbde-acbde-acbde";
-  // check that it worked
-  isnot(Weave.Status.checkSetup(), Weave.CLIENT_NOT_CONFIGURED, "Sync is enabled");
-  Weave.Svc.Obs.notify("weave:service:setup-complete");
-
-  // start page grid should be visible
-  ok(vbox, "remote tabs grid is present on start page");
-  //PanelUI.show("remotetabs-container");
-  is(vbox.hidden, false, "remote tabs should be visible in start page when sync is enabled");
-  // container link should be visible
-  is(menulink.hidden, false, "link to container should be visible when sync is enabled");
-
-  // hacky-fake sync disable
-  Weave.Status._authManager.deleteSyncCredentials();
-  Weave.Svc.Obs.notify("weave:service:start-over");
-  is(Weave.Status.checkSetup(), Weave.CLIENT_NOT_CONFIGURED, "Sync has been disabled");
-  ok(vbox.hidden, "remote tabs in the start page should be hidden when sync is not enabled");
-  ok(menulink.hidden, "link to container should be hidden when sync is not enabled");
-
-}
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+"use strict";
+
+////////////////////////////////////////////////////////////////////////////////
+//// Globals
+
+Components.utils.import("resource://services-sync/main.js");
+////////////////////////////////////////////////////////////////////////////////
+//// Test(s)
+
+function test() {
+  runTests();
+}
+
+gTests.push({
+  desc: "Test sync tabs from other devices UI",
+  run: function run() {
+    if (StartUI.isStartPageVisible)
+      return;
+
+    yield addTab("about:start");
+    yield waitForCondition(() => StartUI.isStartPageVisible);
+    yield hideContextUI();
+
+    is(Weave.Status.checkSetup(), Weave.CLIENT_NOT_CONFIGURED, "Sync should be disabled on start");
+
+    let vbox = document.getElementById("start-remotetabs");
+    ok(vbox.hidden, "remote tabs in the start page should be hidden when sync is not enabled");
+
+    // check container link is hidden
+    let menulink = document.getElementById("menuitem-remotetabs");
+    ok(menulink.hidden, "link to container should be hidden when sync is not enabled");
+
+    RemoteTabsStartView._view.setUIAccessVisible(true);
+
+    // start page grid should be visible
+    ok(vbox, "remote tabs grid is present on start page");
+    is(vbox.hidden, false, "remote tabs should be visible in start page when sync is enabled");
+
+    RemoteTabsStartView._view.setUIAccessVisible(false);
+
+    ok(vbox.hidden, "remote tabs in the start page should be hidden when sync is not enabled");
+    ok(menulink.hidden, "link to container should be hidden when sync is not enabled");
+  }
+});
deleted file mode 100644
--- a/browser/metro/components/CapturePicker.js
+++ /dev/null
@@ -1,85 +0,0 @@
-/* -*- Mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil; -*- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const Cc = Components.classes;
-const Ci = Components.interfaces;
-const Cr = Components.results;
-const Cu = Components.utils;
-
-Cu.import("resource://gre/modules/XPCOMUtils.jsm");
-Cu.import("resource://gre/modules/Services.jsm");
-
-function CapturePicker() {
-  this.messageManager = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
-}
-
-CapturePicker.prototype = {
-  _file: null,
-  _mode: -1,
-  _result: -1,
-  _shown: false,
-  _title: "",
-  _type: "",
-  _window: null,
-
-  //
-  // nsICapturePicker
-  //
-  init: function(aWindow, aTitle, aMode) {
-    this._window = aWindow;
-    this._title = aTitle;
-    this._mode = aMode;
-  },
-
-  show: function() {
-    if (this._shown)
-      throw Cr.NS_ERROR_UNEXPECTED;
-
-    this._shown = true;
-
-    let res = this.messageManager.sendSyncMessage("CapturePicker:Show", { title: this._title, mode: this._mode, type: this._type })[0];
-    if (res.value)
-      this._file = res.path;
-
-    return (res.value ? Ci.nsICapturePicker.RETURN_OK : Ci.nsICapturePicker.RETURN_CANCEL);
-  },
-
-  modeMayBeAvailable: function(aMode) {
-    if (aMode != Ci.nsICapturePicker.MODE_STILL)
-      return false;
-    return true;
-  },
-
-  get file() {
-    if (this._file) { 
-      let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
-      file.initWithPath(this._file);
-      let utils = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
-      return utils.wrapDOMFile(file);
-    } else {
-      throw Cr.NS_ERROR_FAILURE;
-    }
-  },
-
-  get type() {
-    return this._type;
-  },
-
-  set type(aNewType) {
-    if (this._shown)
-      throw Cr.NS_ERROR_UNEXPECTED;
-    else 
-      this._type = aNewType;
-  },
-
-  // QI
-  QueryInterface: XPCOMUtils.generateQI([Ci.nsICapturePicker]),
-
-  // XPCOMUtils factory
-  classID: Components.ID("{cb5a47f0-b58c-4fc3-b61a-358ee95f8238}"),
-};
-
-var components = [ CapturePicker ];
-this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);
--- a/browser/metro/components/Makefile.in
+++ b/browser/metro/components/Makefile.in
@@ -25,17 +25,16 @@ EXTRA_PP_COMPONENTS = \
 EXTRA_COMPONENTS = \
         AlertsService.js \
         ContentPermissionPrompt.js \
         DownloadManagerUI.js \
         PromptService.js \
         ContentDispatchChooser.js \
         FormAutoComplete.js \
         LoginManagerPrompter.js \
-        CapturePicker.js \
         $(NULL)
 
 ifdef MOZ_SAFE_BROWSING
 EXTRA_COMPONENTS += SafeBrowsing.js
 endif
 
 ifdef MOZ_UPDATER
 EXTRA_COMPONENTS += UpdatePrompt.js
--- a/browser/metro/components/PromptService.js
+++ b/browser/metro/components/PromptService.js
@@ -414,17 +414,16 @@ Prompt.prototype = {
         break;
         case Ci.nsIPromptService.BUTTON_TITLE_IS_STRING :
           bTitle = titles[i];
         break;
       }
 
       if (bTitle) {
         let button = doc.createElement("button");
-        button.className = "prompt-button";
         this.setLabelForNode(button, bTitle);
         if (i == defaultButton) {
           button.setAttribute("command", "cmd_ok");
         }
         else {
           button.setAttribute("oncommand",
             "document.getElementById('prompt-confirm-dialog').PromptHelper.closeConfirm(" + i + ")");
         }
--- a/browser/metro/locales/en-US/chrome/browser.dtd
+++ b/browser/metro/locales/en-US/chrome/browser.dtd
@@ -12,16 +12,19 @@
 
 <!ENTITY appbarFindInPage2.label    "Find in page">
 <!ENTITY appbarViewOnDesktop2.label "View on desktop">
 
 <!ENTITY startTopSitesHeader.label        "Top Sites">
 <!ENTITY startBookmarksHeader.label       "Bookmarks">
 <!ENTITY startHistoryHeader.label         "Recent History">
 <!ENTITY startRemoteTabsHeader.label      "Tabs from Other Devices">
+<!-- LOCALIZATION NOTE (snappedRemoteTabsHeader.label): shortened version of startRemoteTabsHeader.label.
+     Needs to be two words or shorter to fit in narrow vertical space.-->
+<!ENTITY snappedRemoteTabsHeader.label    "Remote Tabs">
 
 <!ENTITY autocompleteResultsHeader.label  "Your Results">
 <!ENTITY autocompleteSearchesHeader.label "Internet Searches"> 
 
 <!ENTITY downloadsHeader.label     "Downloads">
 <!ENTITY downloadShowPage.label    "Go to Page">
 <!ENTITY downloadShow2.label       "Find">
 <!ENTITY downloadOpen2.label       "Open">
--- a/browser/metro/locales/en-US/chrome/sync.dtd
+++ b/browser/metro/locales/en-US/chrome/sync.dtd
@@ -1,32 +1,39 @@
 <!-- This Source Code Form is subject to the terms of the Mozilla Public
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
 
 
+<!-- flyout header -->
 <!ENTITY syncHeader.title           "Sync">
-<!ENTITY sync.notconnected          "Not connected">
-<!ENTITY sync.connect               "Connect">
-<!ENTITY sync.connected             "Connected">
+<!-- not connected yet -->
+<!ENTITY sync.setup.description     "Access your bookmarks, passwords, and open tabs across your devices">
+<!ENTITY sync.setupbutton.label     "Set up Sync">
+<!-- sync now button -->
+<!ENTITY sync.syncNow2              "Sync now">
+<!-- device name text edit -->
 <!ENTITY sync.deviceName            "This device">
-<!ENTITY sync.disconnect            "Disconnect">
-<!ENTITY sync.syncNow2              "Sync now">
+<!-- remove this device button -->
+<!ENTITY sync.removebutton.label    "Remove this device">
+<!ENTITY sync.removewarn.note       "Your browser data on this device will remain intact, but you will no longer be able to sync with this account.">
+<!ENTITY sync.removethrobber.label  "Removing device">
 
-<!ENTITY sync.setup.title           "Connect to Sync">
+<!ENTITY sync.setup2.title          "Set up Sync">
 <!ENTITY sync.setup.pair2           "To activate, select &#x0022;Pair a device&#x0022; on your other device.">
-<!ENTITY sync.fallback              "I'm not near my computer…">
+<!ENTITY sync.fallback              "Enter or edit account information…">
 <!ENTITY sync.setup.manual          "Enter your Sync account information">
 <!ENTITY sync.account               "Account Name">
 <!ENTITY sync.password              "Password">
 <!ENTITY sync.recoveryKey           "Recovery Key">
 <!ENTITY sync.customServer          "Use custom server">
 <!ENTITY sync.serverURL             "Server URL">
-<!ENTITY sync.setup.connect         "Connect">
+<!ENTITY sync.setup.connect2        "Add device">
 <!ENTITY sync.setup.cancel          "Cancel">
+<!ENTITY sync.setup.remove          "Remove">
 <!ENTITY sync.setup.tutorial        "Show me how">
 <!ENTITY sync.setup.waiting2        "Waiting for other device…">
 
 <!ENTITY sync.pair.title            "Pair a Device">
 <!ENTITY sync.pair.button           "Pair a device">
 <!ENTITY sync.pair.description      "To activate your new device, select &#x0022;Set up Sync&#x0022; on the device.">
 <!ENTITY sync.setup.close           "Close">
 <!ENTITY sync.setup.waitingdownload "Your data is now being downloaded in the background. You can close this window at any time.">
--- a/browser/metro/locales/en-US/chrome/sync.properties
+++ b/browser/metro/locales/en-US/chrome/sync.properties
@@ -1,21 +1,24 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
-# Mobile Sync
+# LOCALIZATION NOTE: Used in the default os description when a new account
+# is being set up. Should be unique to Metro, so that it does not conflict
+# with Desktop. See /services/sync/modules/engines/clients.js locaName.
+sync.defaultAccountApplication=Metro %S
+
+sync.disconnectPrompt=Remove Windows 8 style %S from your Sync Account?
 
 # %S is the date and time at which the last sync successfully completed
 lastSync2.label=Last sync: %S
-lastSyncInProgress2.label=Last sync: in progress…
 
 # %S is the username logged in
 account.label=Account: %S
-notconnected.label=Not connected
 connecting.label=Connecting…
 
 notificationDisconnect.label=Your Firefox Sync account has been removed
 notificationDisconnect.button=Undo
 
 # LOCALIZATION NOTE (sync.clientUpdate, sync.remoteUpdate):
 # #1 is the "application name"
 # #2 is the "version"
--- a/browser/metro/profile/metro.js
+++ b/browser/metro/profile/metro.js
@@ -411,17 +411,16 @@ pref("app.update.showInstalledUI", false
 pref("app.update.incompatible.mode", 0);
 
 // replace newlines with spaces on paste into single-line text boxes
 pref("editor.singleLine.pasteNewlines", 2);
 
 #ifdef MOZ_SERVICES_SYNC
 // sync service
 pref("services.sync.registerEngines", "Tab,Bookmarks,Form,History,Password,Prefs");
-pref("services.sync.autoconnectDelay", 5);
 
 // prefs to sync by default
 pref("services.sync.prefs.sync.browser.startup.sessionRestore", true);
 pref("services.sync.prefs.sync.browser.tabs.warnOnClose", true);
 pref("services.sync.prefs.sync.devtools.errorconsole.enabled", true);
 pref("services.sync.prefs.sync.lightweightThemes.isThemeSelected", true);
 pref("services.sync.prefs.sync.lightweightThemes.usedThemes", true);
 pref("services.sync.prefs.sync.privacy.donottrackheader.enabled", true);
--- a/browser/metro/theme/browser.css
+++ b/browser/metro/theme/browser.css
@@ -715,16 +715,41 @@ flyoutpanel > settings:first-child {
 }
 
 /* Sync flyout pane */
 
 #sync-flyoutpanel {
   width: 400px;
 }
 
+#sync-disconnectwarntitle {
+  font-weight: bold;
+}
+
+#sync-disconnectthrobber {
+  margin-top: 25px;
+}
+
+#disconnectthrobber {
+  width: 25px;
+  height: 25px;
+}
+
+#syncdisconnectthrobber .progressContainer {
+  width: 25px;
+  height: 25px;
+  margin-right: 10px;
+}
+
+#syncdisconnectthrobber .progressBall {
+  margin: 2px;
+  width: 22px;
+  height: 22px;
+}
+
 /* About flyout pane */
 
 #about-flyoutpanel {
   width: 350px;
   background-image:url('chrome://browser/skin/images/about-footer.png');
   background-repeat: no-repeat;
   background-attachment: fixed;
   background-position: right bottom;
@@ -866,16 +891,20 @@ setting[type="radio"] > vbox {
   visibility: collapse;
 }
 
 /*tile content should be on same line in snapped view */
 #snapped-topsites-grid > richgriditem > .richgrid-item-content {
   -moz-box-orient: horizontal;
 }
 
+[viewstate="snapped"] .canSnapTiles .richgrid-item-desc {
+ -moz-margin-start: 8px;
+}
+
 /* if snapped, hide the fullscreen awesome screen, if viewstate is anything
  *  other than snapped, hide the snapped awesome screen */
 #start[viewstate="snapped"],
 #snapped-start:not([viewstate="snapped"]) {
   visibility: collapse;
 }
 
 /*Formatting for the limited horizontal space of snapped*/
@@ -1165,22 +1194,8 @@ setting[type="radio"] > vbox {
 #selectionhandle-mark3 {
   list-style-image: url("chrome://browser/skin/images/selection-monocle.png");
   border: 0px solid gray;
   padding: 0px;
   margin-top: -30px;
   margin-left: -18px;
   pointer-events: auto;
 }
-
-/* Capture picker ------------------------------------------------------------- */
-
-#capturepicker-video {
-  border: @border_width_tiny@ solid white;
-}
-
-#capturepicker-container {
-  margin: @margin_normal@;
-}
-
-#capturepicker-container.vertical {
-  height: 330px;
-}
new file mode 100644
--- /dev/null
+++ b/browser/metro/theme/cssthrobber.css
@@ -0,0 +1,102 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+%filter substitution
+%include defines.inc
+
+.progressContainer {
+}
+
+.progressBall {
+  position: absolute;
+  opacity: 0;
+  transform: rotate(225deg);
+  animation: orbit 7.15s infinite;
+}
+
+.progressBall:nth-child(1) {
+  animation-delay: 1.56s;
+}
+
+.progressBall:nth-child(2) {
+  animation-delay: 0.31s;
+}
+
+.progressBall:nth-child(3) {
+  animation-delay: 0.62s;
+}
+
+.progressBall:nth-child(4) {
+  animation-delay: 0.94s;
+}
+
+.progressBall:nth-child(5) {
+  animation-delay: 1.25s;
+}
+
+.progressBall:nth-child(1)::after,
+.progressBall:nth-child(2)::after,
+.progressBall:nth-child(3)::after,
+.progressBall:nth-child(4)::after,
+.progressBall:nth-child(5)::after {
+  content: "";
+  display: block;
+  width: 5px;
+  height: 5px;
+  border-radius: 5px;
+  position: absolute;
+  background: #0095dd;
+  left:0px;
+  top:0px;
+}
+
+
+@keyframes orbit {
+  0% {
+    opacity: 1;
+    z-index:99;
+    transform: rotate(180deg);
+    animation-timing-function: ease-out;
+  }
+
+  7% {
+    opacity: 1;
+    transform: rotate(300deg);
+    animation-timing-function: linear;
+    origin:0%;
+  }
+
+  30% {
+    opacity: 1;
+    transform:rotate(410deg);
+    animation-timing-function: ease-in-out;
+    origin:7%;
+  }
+
+  39% {
+    opacity: 1;
+    transform: rotate(645deg);
+    animation-timing-function: linear;
+    origin:30%;
+  }
+
+  70% {
+    opacity: 1;
+    transform: rotate(770deg);
+    animation-timing-function: ease-out;
+    origin:39%;
+  }
+
+  75% {
+    opacity: 1;
+    transform: rotate(900deg);
+    animation-timing-function: ease-out;
+    origin:70%;
+  }
+
+  76%, 100% {
+    opacity: 0;
+    transform:rotate(900deg);
+  }
+}
--- a/browser/metro/theme/jar.mn
+++ b/browser/metro/theme/jar.mn
@@ -4,16 +4,17 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 
 chrome.jar:
 % skin browser classic/1.0 %skin/
   skin/aboutPage.css                        (aboutPage.css)
   skin/about.css                            (about.css)
 * skin/flyoutpanel.css                      (flyoutpanel.css)
+* skin/cssthrobber.css                      (cssthrobber.css)
 * skin/browser.css                          (browser.css)
 * skin/content.css                          (content.css)
   skin/config.css                           (config.css)
 * skin/forms.css                            (forms.css)
 * skin/platform.css                         (platform.css)
   skin/touchcontrols.css                    (touchcontrols.css)
   skin/netError.css                         (netError.css)
 % override chrome://global/skin/about.css chrome://browser/skin/about.css
--- a/browser/metro/theme/platform.css
+++ b/browser/metro/theme/platform.css
@@ -567,17 +567,17 @@ richgriditem[customColor] .richgrid-icon
 /* hide icon if there is an image background */
 .richgrid-icon-container[customImage] {
   visibility: collapse;
 }
 
 .richgrid-item-desc {
   width: @tile_width@;
   font-size: @metro_font_normal@;
-  margin-left: 0px !important;
+  margin-left: 0px;
   padding-left: 0px !important;
 }
 
 .richgrid-item-content[customImage] > .richgrid-item-desc {
   background: hsla(0,2%,98%,.95);
   /*margin-bottom: 0px;
   margin-right: 0px;*/
   margin: 0px;
--- a/browser/modules/SignInToWebsite.jsm
+++ b/browser/modules/SignInToWebsite.jsm
@@ -131,35 +131,26 @@ this.SignInToWebsiteUX = {
   },
 
   // Private
 
   /**
    * Return the chrome window and <browser> for the given outer window ID.
    */
   _getUIForWindowID: function(aWindowID) {
-    let someWindow = Services.wm.getMostRecentWindow("navigator:browser");
-    if (!someWindow) {
-      Logger.reportError("SignInToWebsiteUX", "no window");
-      return [null, null];
-    }
-
-    let windowUtils = someWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                                .getInterface(Ci.nsIDOMWindowUtils);
-    let content = windowUtils.getOuterWindowWithId(aWindowID);
-
+    let content = Services.wm.getOuterWindowWithId(aWindowID);
     if (content) {
       let browser = content.QueryInterface(Ci.nsIInterfaceRequestor)
                            .getInterface(Ci.nsIWebNavigation)
                            .QueryInterface(Ci.nsIDocShell).chromeEventHandler;
       let chromeWin = browser.ownerDocument.defaultView;
       return [chromeWin, browser];
     }
+
     Logger.reportError("SignInToWebsiteUX", "no content");
-
     return [null, null];
   },
 
   /**
    * Open UI with a content frame displaying aAuthURI so that the user can authenticate with their
    * IDP.  Then tell Identity.jsm the identifier for the window so that it knows that the DOM API
    * calls are for this authentication flow.
    */
--- a/browser/modules/webappsUI.jsm
+++ b/browser/modules/webappsUI.jsm
@@ -82,29 +82,23 @@ this.webappsUI = {
         browser.pinTab(tab);
         browser.selectedTab = tab;
         ss.setTabValue(tab, "appOrigin", aOrigin);
       }
     }
   },
 
   _getBrowserForId: function(aId) {
-    let someWindow = Services.wm.getMostRecentWindow(null);
-
-    if (someWindow) {
-      let windowUtils = someWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                                  .getInterface(Ci.nsIDOMWindowUtils);
-      let content = windowUtils.getOuterWindowWithId(aId);
-      if (content) {
-        let browser = content.QueryInterface(Ci.nsIInterfaceRequestor)
-                      .getInterface(Ci.nsIWebNavigation)
-                      .QueryInterface(Ci.nsIDocShell).chromeEventHandler;
-        let win = browser.ownerDocument.defaultView;
-        return [win, browser];
-      }
+    let content = Services.wm.getOuterWindowWithId(aId);
+    if (content) {
+      let browser = content.QueryInterface(Ci.nsIInterfaceRequestor)
+                    .getInterface(Ci.nsIWebNavigation)
+                    .QueryInterface(Ci.nsIDocShell).chromeEventHandler;
+      let win = browser.ownerDocument.defaultView;
+      return [win, browser];
     }
 
     return [null, null];
   },
 
   doInstall: function(aData, aBrowser, aWindow) {
     let bundle = aWindow.gNavigatorBundle;
 
--- a/browser/modules/webrtcUI.jsm
+++ b/browser/modules/webrtcUI.jsm
@@ -52,20 +52,17 @@ this.webrtcUI = {
         });
       }
     }
     return activeStreams;
   }
 }
 
 function getBrowserForWindowId(aWindowID) {
-  let someWindow = Services.wm.getMostRecentWindow(null);
-  let contentWindow = someWindow.QueryInterface(Ci.nsIInterfaceRequestor)
-                                .getInterface(Ci.nsIDOMWindowUtils)
-                                .getOuterWindowWithId(aWindowID);
+  let contentWindow = Services.wm.getOuterWindowWithId(aWindowID);
   return contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
                       .getInterface(Ci.nsIWebNavigation)
                       .QueryInterface(Ci.nsIDocShell)
                       .chromeEventHandler;
 }
 
 function handleRequest(aSubject, aTopic, aData) {
   let {windowID: windowID, callID: callID} = JSON.parse(aData);
--- a/build/macosx/mozconfig.common
+++ b/build/macosx/mozconfig.common
@@ -20,11 +20,8 @@ if [ -z "$CC" ]; then
 fi
 
 # If not set use the system default clang++
 if [ -z "$CXX" ]; then
     export CXX=clang++
 fi
 
 ac_add_options --with-ccache
-
-# Enable ECMAScript Internationalization API
-ac_add_options --enable-intl-api
--- a/build/mozconfig.vs2010-common
+++ b/build/mozconfig.vs2010-common
@@ -1,11 +1,8 @@
-# Pymake needs Windows-style paths. Use cmd.exe to hack around this.
-mk_export_correct_style() {
-  if test -n "${_PYMAKE}"; then
-    mk_add_options "export $1=$(cmd.exe //c echo %$1%)"
-  else
-    mk_add_options "export $1=$(eval echo \$$1)"
-  fi
-}
-
-# Enable ECMAScript Internationalization API
-ac_add_options --enable-intl-api
+# Pymake needs Windows-style paths. Use cmd.exe to hack around this.
+mk_export_correct_style() {
+  if test -n "${_PYMAKE}"; then
+    mk_add_options "export $1=$(cmd.exe //c echo %$1%)"
+  else
+    mk_add_options "export $1=$(eval echo \$$1)"
+  fi
+}
--- a/build/unix/mozconfig.linux
+++ b/build/unix/mozconfig.linux
@@ -1,7 +1,4 @@
 . "$topsrcdir/build/mozconfig.common"
 
 CC=/tools/gcc-4.5-0moz3/bin/gcc
 CXX=/tools/gcc-4.5-0moz3/bin/g++
-
-# Enable ECMAScript Internationalization API
-ac_add_options --enable-intl-api
--- a/caps/src/nsSecurityManagerFactory.cpp
+++ b/caps/src/nsSecurityManagerFactory.cpp
@@ -60,18 +60,19 @@ static const JSFunctionSpec PrivilegeMan
 
 /*
  * "Steal" calls to netscape.security.PrivilegeManager.enablePrivilege,
  * et al. so that code that worked with 4.0 can still work.
  */
 NS_IMETHODIMP
 nsSecurityNameSet::InitializeNameSet(nsIScriptContext* aScriptContext)
 {
-    AutoPushJSContext cx(aScriptContext->GetNativeContext());
-    JS::Rooted<JSObject*> global(cx, JS_ObjectToInnerObject(cx, JS_GetGlobalObject(cx)));
+    AutoJSContext cx;
+    JS::Rooted<JSObject*> global(cx, aScriptContext->GetNativeGlobal());
+    JSAutoCompartment ac(cx, global);
 
     /*
      * Find Object.prototype's class by walking up the global object's
      * prototype chain.
      */
     JS::Rooted<JSObject*> obj(cx, global);
     JS::Rooted<JSObject*> proto(cx);
     JSAutoRequest ar(cx);
--- a/configure.in
+++ b/configure.in
@@ -200,16 +200,20 @@ if test -n "$gonkdir" ; then
         ARCH_DIR=arch-x86
         ;;
     esac
 
     case "$ANDROID_VERSION" in
     15)
         GONK_INCLUDES="-I$gonkdir/frameworks/base/opengl/include -I$gonkdir/frameworks/base/native/include -I$gonkdir/frameworks/base/include -I$gonkdir/frameworks/base/services/camera -I$gonkdir/frameworks/base/include/media/stagefright -I$gonkdir/frameworks/base/include/media/stagefright/openmax -I$gonkdir/frameworks/base/media/libstagefright/rtsp -I$gonkdir/frameworks/base/media/libstagefright/include -I$gonkdir/external/dbus -I$gonkdir/external/bluetooth/bluez/lib -I$gonkdir/dalvik/libnativehelper/include/nativehelper"
         MOZ_B2G_BT=1
+        MOZ_B2G_CAMERA=1
+        MOZ_OMX_DECODER=1
+        AC_DEFINE(MOZ_OMX_DECODER)
+        AC_SUBST(MOZ_OMX_DECODER)
         ;;
     17)
         GONK_INCLUDES="-I$gonkdir/frameworks/native/include"
         ;;
     *)
         AC_MSG_ERROR([Unsupported platform version: $ANDROID_VERSION])
         ;;
     esac
--- a/content/base/public/nsContentUtils.h
+++ b/content/base/public/nsContentUtils.h
@@ -1721,17 +1721,17 @@ public:
   /**
    * Creates an arraybuffer from a binary string.
    */
   static nsresult CreateArrayBuffer(JSContext *aCx, const nsACString& aData,
                                     JSObject** aResult);
 
   static nsresult CreateBlobBuffer(JSContext* aCx,
                                    const nsACString& aData,
-                                   JS::Value& aBlob);
+                                   JS::MutableHandle<JS::Value> aBlob);
 
   static void StripNullChars(const nsAString& aInStr, nsAString& aOutStr);
 
   /**
    * Strip all \n, \r and nulls from the given string
    * @param aString the string to remove newlines from [in/out]
    */
   static void RemoveNewlines(nsString &aString);
--- a/content/base/src/EventSource.cpp
+++ b/content/base/src/EventSource.cpp
@@ -1227,17 +1227,17 @@ EventSource::DispatchAllMessageEvents()
   AutoPushJSContext cx(scriptContext->GetNativeContext());
   NS_ENSURE_TRUE_VOID(cx);
 
   while (mMessagesToDispatch.GetSize() > 0) {
     nsAutoPtr<Message>
       message(static_cast<Message*>(mMessagesToDispatch.PopFront()));
 
     // Now we can turn our string into a jsval
-    JS::Value jsData;
+    JS::Rooted<JS::Value> jsData(cx);
     {
       JSString* jsString;
       JSAutoRequest ar(cx);
       jsString = JS_NewUCStringCopyN(cx,
                                      message->mData.get(),
                                      message->mData.Length());
       NS_ENSURE_TRUE_VOID(jsString);
 
--- a/content/base/src/WebSocket.cpp
+++ b/content/base/src/WebSocket.cpp
@@ -879,26 +879,26 @@ WebSocket::CreateAndDispatchMessageEvent
 
   nsIScriptContext* scriptContext = sgo->GetContext();
   NS_ENSURE_TRUE(scriptContext, NS_ERROR_FAILURE);
 
   AutoPushJSContext cx(scriptContext->GetNativeContext());
   NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
 
   // Create appropriate JS object for message
-  JS::Value jsData;
+  JS::Rooted<JS::Value> jsData(cx);
   {
     JSAutoRequest ar(cx);
     if (isBinary) {
       if (mBinaryType == dom::BinaryType::Blob) {
-        rv = nsContentUtils::CreateBlobBuffer(cx, aData, jsData);
+        rv = nsContentUtils::CreateBlobBuffer(cx, aData, &jsData);
         NS_ENSURE_SUCCESS(rv, rv);
       } else if (mBinaryType == dom::BinaryType::Arraybuffer) {
-        JSObject* arrayBuf;
-        rv = nsContentUtils::CreateArrayBuffer(cx, aData, &arrayBuf);
+        JS::Rooted<JSObject*> arrayBuf(cx);
+        rv = nsContentUtils::CreateArrayBuffer(cx, aData, arrayBuf.address());
         NS_ENSURE_SUCCESS(rv, rv);
         jsData = OBJECT_TO_JSVAL(arrayBuf);
       } else {
         NS_RUNTIMEABORT("Unknown binary type!");
         return NS_ERROR_UNEXPECTED;
       }
     } else {
       // JS string
--- a/content/base/src/nsContentList.cpp
+++ b/content/base/src/nsContentList.cpp
@@ -670,18 +670,18 @@ nsContentList::NamedItem(JSContext* cx, 
                          mozilla::ErrorResult& error)
 {
   nsIContent *item = NamedItem(name, true);
   if (!item) {
     return nullptr;
   }
   JS::Rooted<JSObject*> wrapper(cx, GetWrapper());
   JSAutoCompartment ac(cx, wrapper);
-  JS::Value v;
-  if (!mozilla::dom::WrapObject(cx, wrapper, item, item, nullptr, &v)) {
+  JS::Rooted<JS::Value> v(cx);
+  if (!mozilla::dom::WrapObject(cx, wrapper, item, item, nullptr, v.address())) {
     error.Throw(NS_ERROR_FAILURE);
     return nullptr;
   }
   return &v.toObject();
 }
 
 void
 nsContentList::AttributeChanged(nsIDocument *aDocument, Element* aElement,
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -5914,29 +5914,30 @@ nsContentUtils::CreateArrayBuffer(JSCont
   return NS_OK;
 }
 
 // Initial implementation: only stores to RAM, not file
 // TODO: bug 704447: large file support
 nsresult
 nsContentUtils::CreateBlobBuffer(JSContext* aCx,
                                  const nsACString& aData,
-                                 JS::Value& aBlob)
+                                 JS::MutableHandle<JS::Value> aBlob)
 {
   uint32_t blobLen = aData.Length();
   void* blobData = moz_malloc(blobLen);
   nsCOMPtr<nsIDOMBlob> blob;
   if (blobData) {
     memcpy(blobData, aData.BeginReading(), blobLen);
     blob = new nsDOMMemoryFile(blobData, blobLen, EmptyString());
   } else {
     return NS_ERROR_OUT_OF_MEMORY;
   }
   JS::Rooted<JSObject*> scope(aCx, JS_GetGlobalForScopeChain(aCx));
-  return nsContentUtils::WrapNative(aCx, scope, blob, &aBlob, nullptr, true);
+  return nsContentUtils::WrapNative(aCx, scope, blob, aBlob.address(), nullptr,
+                                    true);
 }
 
 void
 nsContentUtils::StripNullChars(const nsAString& aInStr, nsAString& aOutStr)
 {
   // In common cases where we don't have nulls in the
   // string we can simple simply bypass the checking code.
   int32_t firstNullPos = aInStr.FindChar('\0');
@@ -6620,18 +6621,18 @@ void
 nsContentUtils::ReleaseWrapper(void* aScriptObjectHolder,
                                nsWrapperCache* aCache)
 {
   if (aCache->PreservingWrapper()) {
     // PreserveWrapper puts new DOM bindings in the JS holders hash, but they
     // can also be in the DOM expando hash, so we need to try to remove them
     // from both here.
     JSObject* obj = aCache->GetWrapperPreserveColor();
-    if (aCache->IsDOMBinding() && obj) {
-      xpc::GetObjectScope(obj)->RemoveDOMExpandoObject(obj);
+    if (aCache->IsDOMBinding() && obj && js::IsProxy(obj)) {
+        DOMProxyHandler::GetAndClearExpandoObject(obj);
     }
     aCache->SetPreservingWrapper(false);
     DropJSObjects(aScriptObjectHolder);
   }
 }
 
 // static
 void
--- a/content/base/src/nsDOMDataChannel.cpp
+++ b/content/base/src/nsDOMDataChannel.cpp
@@ -333,20 +333,21 @@ nsDOMDataChannel::GetSendParams(nsIVaria
       dataType == nsIDataType::VTYPE_INTERFACE_IS) {
     nsCOMPtr<nsISupports> supports;
     nsID* iid;
     rv = aData->GetAsInterface(&iid, getter_AddRefs(supports));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsMemory::Free(iid);
 
+    AutoSafeJSContext cx;
     // ArrayBuffer?
-    JS::Value realVal;
-    JSObject* obj;
-    nsresult rv = aData->GetAsJSVal(&realVal);
+    JS::Rooted<JS::Value> realVal(cx);
+    JS::Rooted<JSObject*> obj(cx);
+    nsresult rv = aData->GetAsJSVal(realVal.address());
     if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal) &&
         (obj = JSVAL_TO_OBJECT(realVal)) &&
         (JS_IsArrayBufferObject(obj))) {
       int32_t len = JS_GetArrayBufferByteLength(obj);
       char* data = reinterpret_cast<char*>(JS_GetArrayBufferData(obj));
 
       aStringOut.Assign(data, len);
       aIsBinary = true;
@@ -409,25 +410,25 @@ nsDOMDataChannel::DoOnMessageAvailable(c
 
   nsIScriptContext* sc = sgo->GetContext();
   NS_ENSURE_TRUE(sc, NS_ERROR_FAILURE);
 
   AutoPushJSContext cx(sc->GetNativeContext());
   NS_ENSURE_TRUE(cx, NS_ERROR_FAILURE);
 
   JSAutoRequest ar(cx);
-  JS::Value jsData;
+  JS::Rooted<JS::Value> jsData(cx);
 
   if (aBinary) {
     if (mBinaryType == DC_BINARY_TYPE_BLOB) {
-      rv = nsContentUtils::CreateBlobBuffer(cx, aData, jsData);
+      rv = nsContentUtils::CreateBlobBuffer(cx, aData, &jsData);
       NS_ENSURE_SUCCESS(rv, rv);
     } else if (mBinaryType == DC_BINARY_TYPE_ARRAYBUFFER) {
-      JSObject* arrayBuf;
-      rv = nsContentUtils::CreateArrayBuffer(cx, aData, &arrayBuf);
+      JS::Rooted<JSObject*> arrayBuf(cx);
+      rv = nsContentUtils::CreateArrayBuffer(cx, aData, arrayBuf.address());
       NS_ENSURE_SUCCESS(rv, rv);
       jsData = OBJECT_TO_JSVAL(arrayBuf);
     } else {
       NS_RUNTIMEABORT("Unknown binary type!");
       return NS_ERROR_UNEXPECTED;
     }
   } else {
     NS_ConvertUTF8toUTF16 utf16data(aData);
--- a/content/base/src/nsFrameMessageManager.cpp
+++ b/content/base/src/nsFrameMessageManager.cpp
@@ -374,30 +374,31 @@ nsFrameMessageManager::SendSyncMessage(c
   }
   data.mData = buffer.data();
   data.mDataLength = buffer.nbytes();
 
   InfallibleTArray<nsString> retval;
   if (mCallback->DoSendSyncMessage(aMessageName, data, &retval)) {
     JSAutoRequest ar(aCx);
     uint32_t len = retval.Length();
-    JSObject* dataArray = JS_NewArrayObject(aCx, len, nullptr);
+    JS::Rooted<JSObject*> dataArray(aCx, JS_NewArrayObject(aCx, len, nullptr));
     NS_ENSURE_TRUE(dataArray, NS_ERROR_OUT_OF_MEMORY);
 
     for (uint32_t i = 0; i < len; ++i) {
       if (retval[i].IsEmpty()) {
         continue;
       }
 
-      JS::Value ret = JSVAL_VOID;
+      JS::Rooted<JS::Value> ret(aCx);
       if (!JS_ParseJSON(aCx, static_cast<const jschar*>(retval[i].get()),
-                        retval[i].Length(), &ret)) {
+                        retval[i].Length(), ret.address())) {
         return NS_ERROR_UNEXPECTED;
       }
-      NS_ENSURE_TRUE(JS_SetElement(aCx, dataArray, i, &ret), NS_ERROR_OUT_OF_MEMORY);
+      NS_ENSURE_TRUE(JS_SetElement(aCx, dataArray, i, ret.address()),
+                     NS_ERROR_OUT_OF_MEMORY);
     }
 
     *aRetval = OBJECT_TO_JSVAL(dataArray);
   }
   return NS_OK;
 }
 
 nsresult
@@ -627,18 +628,18 @@ nsFrameMessageManager::ReceiveMessage(ns
                                       const StructuredCloneData* aCloneData,
                                       JSObject* aObjectsArray,
                                       InfallibleTArray<nsString>* aJSONRetVal,
                                       JSContext* aContext)
 {
   JSContext *cxToUse = mContext ? mContext
                                 : (aContext ? aContext
                                             : nsContentUtils::GetSafeJSContext());
+  JS::Rooted<JSObject*> objectsArray(cxToUse, aObjectsArray);
   AutoPushJSContext ctx(cxToUse);
-  JS::Rooted<JSObject*> objectsArray(ctx, aObjectsArray);
   if (mListeners.Length()) {
     nsCOMPtr<nsIAtom> name = do_GetAtom(aMessage);
     MMListenerRemover lr(this);
 
     for (uint32_t i = 0; i < mListeners.Length(); ++i) {
       if (mListeners[i].mMessage == name) {
         nsCOMPtr<nsIXPConnectWrappedJS> wrappedJS =
           do_QueryInterface(mListeners[i].mListener);
@@ -682,20 +683,20 @@ nsFrameMessageManager::ReceiveMessage(ns
             return NS_ERROR_UNEXPECTED;
 
         JS::Rooted<JS::Value> json(ctx, JS::NullValue());
         if (aCloneData && aCloneData->mDataLength &&
             !ReadStructuredClone(ctx, *aCloneData, json.address())) {
           JS_ClearPendingException(ctx);
           return NS_OK;
         }
-        JSString* jsMessage =
+        JS::Rooted<JSString*> jsMessage(ctx,
           JS_NewUCStringCopyN(ctx,
                               static_cast<const jschar*>(aMessage.BeginReading()),
-                              aMessage.Length());
+                              aMessage.Length()));
         NS_ENSURE_TRUE(jsMessage, NS_ERROR_OUT_OF_MEMORY);
         JS_DefineProperty(ctx, param, "target", targetv, nullptr, nullptr, JSPROP_ENUMERATE);
         JS_DefineProperty(ctx, param, "name",
                           STRING_TO_JSVAL(jsMessage), nullptr, nullptr, JSPROP_ENUMERATE);
         JS_DefineProperty(ctx, param, "sync",
                           BOOLEAN_TO_JSVAL(aSync), nullptr, nullptr, JSPROP_ENUMERATE);
         JS_DefineProperty(ctx, param, "json", json, nullptr, nullptr, JSPROP_ENUMERATE); // deprecated
         JS_DefineProperty(ctx, param, "data", json, nullptr, nullptr, JSPROP_ENUMERATE);
@@ -1003,18 +1004,18 @@ nsFrameScriptExecutor::LoadFrameScriptIn
 
   if (holder) {
     nsCxPusher pusher;
     pusher.Push(mCx);
     {
       // Need to scope JSAutoRequest to happen after Push but before Pop,
       // at least for now. See bug 584673.
       JSAutoRequest ar(mCx);
-      JSObject* global = nullptr;
-      mGlobal->GetJSObject(&global);
+      JS::Rooted<JSObject*> global(mCx);
+      mGlobal->GetJSObject(global.address());
       if (global) {
         (void) JS_ExecuteScript(mCx, global, holder->mScript, nullptr);
       }
     }
   }
 }
 
 void
@@ -1062,18 +1063,18 @@ nsFrameScriptExecutor::TryCacheLoadAndCo
 
   if (!dataString.IsEmpty()) {
     nsCxPusher pusher;
     pusher.Push(mCx);
     {
       // Need to scope JSAutoRequest to happen after Push but before Pop,
       // at least for now. See bug 584673.
       JSAutoRequest ar(mCx);
-      JSObject* global = nullptr;
-      mGlobal->GetJSObject(&global);
+      JS::Rooted<JSObject*> global(mCx);
+      mGlobal->GetJSObject(global.address());
       if (global) {
         JSAutoCompartment ac(mCx, global);
         JS::CompileOptions options(mCx);
         options.setNoScriptRval(true)
                .setFileAndLine(url.get(), 1)
                .setPrincipals(nsJSPrincipals::get(mPrincipal));
         JS::RootedObject empty(mCx, nullptr);
         JS::Rooted<JSScript*> script(mCx,
@@ -1132,18 +1133,18 @@ nsFrameScriptExecutor::InitTabChildGloba
   JS_SetContextPrivate(cx, aScope);
 
   nsresult rv =
     xpc->InitClassesWithNewWrappedGlobal(cx, aScope, mPrincipal,
                                          flags, JS::SystemZone, getter_AddRefs(mGlobal));
   NS_ENSURE_SUCCESS(rv, false);
 
     
-  JSObject* global = nullptr;
-  rv = mGlobal->GetJSObject(&global);
+  JS::Rooted<JSObject*> global(cx);
+  rv = mGlobal->GetJSObject(global.address());
   NS_ENSURE_SUCCESS(rv, false);
 
   JS_SetGlobalObject(cx, global);
 
   // Set the location information for the new global, so that tools like
   // about:memory may use that information.
   xpc::SetLocationForGlobal(global, aID);
 
--- a/content/base/src/nsINode.cpp
+++ b/content/base/src/nsINode.cpp
@@ -692,35 +692,35 @@ nsINode::SetUserData(JSContext* aCx, con
   if (aError.Failed()) {
     return JS::UndefinedValue();
   }
 
   if (!oldData) {
     return JS::NullValue();
   }
 
-  JS::Value result;
+  JS::Rooted<JS::Value> result(aCx);
   JSAutoCompartment ac(aCx, GetWrapper());
   aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), oldData,
-                                                    &result);
+                                                    result.address());
   return result;
 }
 
 JS::Value
 nsINode::GetUserData(JSContext* aCx, const nsAString& aKey, ErrorResult& aError)
 {
   nsIVariant* data = GetUserData(aKey);
   if (!data) {
     return JS::NullValue();
   }
 
-  JS::Value result;
+  JS::Rooted<JS::Value> result(aCx);
   JSAutoCompartment ac(aCx, GetWrapper());
   aError = nsContentUtils::XPConnect()->VariantToJS(aCx, GetWrapper(), data,
-                                                    &result);
+                                                    result.address());
   return result;
 }
 
 //static
 bool
 nsINode::IsChromeOrXBL(JSContext* aCx, JSObject* /* unused */)
 {
   JSCompartment* compartment = js::GetContextCompartment(aCx);
@@ -2389,17 +2389,17 @@ nsINode::WrapObject(JSContext *aCx, JS::
   bool hasHadScriptHandlingObject = false;
   if (!OwnerDoc()->GetScriptHandlingObject(hasHadScriptHandlingObject) &&
       !hasHadScriptHandlingObject &&
       !nsContentUtils::IsCallerChrome()) {
     Throw<true>(aCx, NS_ERROR_UNEXPECTED);
     return nullptr;
   }
 
-  JSObject* obj = WrapNode(aCx, aScope);
+  JS::Rooted<JSObject*> obj(aCx, WrapNode(aCx, aScope));
   if (obj && ChromeOnlyAccess() &&
       !nsContentUtils::IsSystemPrincipal(NodePrincipal()) &&
       xpc::AllowXBLScope(js::GetContextCompartment(aCx)))
   {
     // Create a new wrapper and cache it.
     JSAutoCompartment ac(aCx, obj);
     JSObject* wrapper = xpc::WrapperFactory::WrapSOWObject(aCx, obj);
     if (!wrapper) {
--- a/content/base/src/nsNodeUtils.cpp
+++ b/content/base/src/nsNodeUtils.cpp
@@ -377,17 +377,17 @@ nsNodeUtils::CloneNodeImpl(nsINode *aNod
 
   return NS_OK;
 }
 
 /* static */
 nsresult
 nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
                            nsNodeInfoManager *aNewNodeInfoManager,
-                           JSObject *aReparentScope,
+                           JS::Handle<JSObject*> aReparentScope,
                            nsCOMArray<nsINode> &aNodesWithProperties,
                            nsINode *aParent, nsINode **aResult)
 {
   NS_PRECONDITION((!aClone && aNewNodeInfoManager) || !aReparentScope,
                   "If cloning or not getting a new nodeinfo we shouldn't "
                   "rewrap");
   NS_PRECONDITION(!aParent || aNode->IsNodeOfType(nsINode::eCONTENT),
                   "Can't insert document or attribute nodes into a parent");
--- a/content/base/src/nsNodeUtils.h
+++ b/content/base/src/nsNodeUtils.h
@@ -148,26 +148,26 @@ public:
    * @param aResult *aResult will contain the cloned node.
    */
   static nsresult Clone(nsINode *aNode, bool aDeep,
                         nsNodeInfoManager *aNewNodeInfoManager,
                         nsCOMArray<nsINode> &aNodesWithProperties,
                         nsINode **aResult)
   {
     return CloneAndAdopt(aNode, true, aDeep, aNewNodeInfoManager,
-                         nullptr, aNodesWithProperties, nullptr, aResult);
+                         JS::NullPtr(), aNodesWithProperties, nullptr, aResult);
   }
 
   /**
    * Clones aNode, its attributes and, if aDeep is true, its descendant nodes
    */
   static nsresult Clone(nsINode *aNode, bool aDeep, nsINode **aResult)
   {
     nsCOMArray<nsINode> dummyNodeWithProperties;
-    return CloneAndAdopt(aNode, true, aDeep, nullptr, nullptr,
+    return CloneAndAdopt(aNode, true, aDeep, nullptr, JS::NullPtr(),
                          dummyNodeWithProperties, aNode->GetParent(), aResult);
   }
 
   /**
    * Walks aNode, its attributes and descendant nodes. If aNewNodeInfoManager is
    * not null, it is used to create new nodeinfos for the nodes. Also reparents
    * the XPConnect wrappers for the nodes into aReparentScope if non-null.
    * aNodesWithProperties will be filled with all the nodes that have
@@ -179,17 +179,17 @@ public:
    *                            descendants. May be null if the nodeinfos
    *                            shouldn't be changed.
    * @param aReparentScope New scope for the wrappers, or null if no reparenting
    *                       should be done.
    * @param aNodesWithProperties All nodes (from amongst aNode and its
    *                             descendants) with properties.
    */
   static nsresult Adopt(nsINode *aNode, nsNodeInfoManager *aNewNodeInfoManager,
-                        JSObject *aReparentScope,
+                        JS::Handle<JSObject*> aReparentScope,
                         nsCOMArray<nsINode> &aNodesWithProperties)
   {
     nsCOMPtr<nsINode> node;
     nsresult rv = CloneAndAdopt(aNode, false, true, aNewNodeInfoManager,
                                 aReparentScope, aNodesWithProperties,
                                 nullptr, getter_AddRefs(node));
 
     nsMutationGuard::DidMutate();
@@ -289,14 +289,14 @@ private:
    * @param aParent If aClone is true the cloned node will be appended to
    *                aParent's children. May be null. If not null then aNode
    *                must be an nsIContent.
    * @param aResult If aClone is true then *aResult will contain the cloned
    *                node.
    */
   static nsresult CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
                                 nsNodeInfoManager *aNewNodeInfoManager,
-                                JSObject *aReparentScope,
+                                JS::Handle<JSObject*> aReparentScope,
                                 nsCOMArray<nsINode> &aNodesWithProperties,
                                 nsINode *aParent, nsINode **aResult);
 };
 
 #endif // nsNodeUtils_h___
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -3053,17 +3053,18 @@ nsObjectLoadingContent::SetupProtoChain(
   //   |      |__ Plugin NPRuntime JS object wrapper
   //   |
   //   |__ WebIDL object
   //
 }
 
 // static
 nsresult
-nsObjectLoadingContent::GetPluginJSObject(JSContext *cx, JSObject *obj,
+nsObjectLoadingContent::GetPluginJSObject(JSContext *cx,
+                                          JS::Handle<JSObject*> obj,
                                           nsNPAPIPluginInstance *plugin_inst,
                                           JSObject **plugin_obj,
                                           JSObject **plugin_proto)
 {
   *plugin_obj = nullptr;
   *plugin_proto = nullptr;
 
   JSAutoRequest ar(cx);
--- a/content/base/src/nsObjectLoadingContent.h
+++ b/content/base/src/nsObjectLoadingContent.h
@@ -457,17 +457,18 @@ class nsObjectLoadingContent : public ns
       nsRefPtr<nsIObjectLoadingContent> mContent;
     };
 
     // Utility getter for getting our nsNPAPIPluginInstance in a safe way.
     nsresult ScriptRequestPluginInstance(JSContext* aCx,
                                          nsNPAPIPluginInstance** aResult);
 
     // Utility method for getting our plugin JSObject
-    static nsresult GetPluginJSObject(JSContext *cx, JSObject *obj,
+    static nsresult GetPluginJSObject(JSContext *cx,
+                                      JS::Handle<JSObject*> obj,
                                       nsNPAPIPluginInstance *plugin_inst,
                                       JSObject **plugin_obj,
                                       JSObject **plugin_proto);
 
     // The final listener for mChannel (uriloader, pluginstreamlistener, etc.)
     nsCOMPtr<nsIStreamListener> mFinalListener;
 
     // Frame loader, for content documents we load.
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -996,31 +996,31 @@ nsXMLHttpRequest::GetResponse(JSContext*
         CreatePartialBlob();
       }
     }
 
     if (!mResponseBlob) {
       return JSVAL_NULL;
     }
 
-    JS::Value result = JSVAL_NULL;
+    JS::Rooted<JS::Value> result(aCx, JSVAL_NULL);
     JS::Rooted<JSObject*> scope(aCx, JS_GetGlobalForScopeChain(aCx));
-    aRv = nsContentUtils::WrapNative(aCx, scope, mResponseBlob, &result,
+    aRv = nsContentUtils::WrapNative(aCx, scope, mResponseBlob, result.address(),
                                      nullptr, true);
     return result;
   }
   case XML_HTTP_RESPONSE_TYPE_DOCUMENT:
   {
     if (!(mState & XML_HTTP_REQUEST_DONE) || !mResponseXML) {
       return JSVAL_NULL;
     }
 
     JS::Rooted<JSObject*> scope(aCx, JS_GetGlobalForScopeChain(aCx));
-    JS::Value result = JSVAL_NULL;
-    aRv = nsContentUtils::WrapNative(aCx, scope, mResponseXML, &result,
+    JS::Rooted<JS::Value> result(aCx, JSVAL_NULL);
+    aRv = nsContentUtils::WrapNative(aCx, scope, mResponseXML, result.address(),
                                      nullptr, true);
     return result;
   }
   case XML_HTTP_RESPONSE_TYPE_JSON:
   {
     if (!(mState & XML_HTTP_REQUEST_DONE)) {
       return JSVAL_NULL;
     }
@@ -2400,21 +2400,22 @@ GetRequestBody(nsIVariant* aBody, nsIInp
 
     // nsIXHRSendable?
     nsCOMPtr<nsIXHRSendable> sendable = do_QueryInterface(supports);
     if (sendable) {
       return GetRequestBody(sendable, aResult, aContentLength, aContentType, aCharset);
     }
 
     // ArrayBuffer?
-    JS::Value realVal;
-
-    nsresult rv = aBody->GetAsJSVal(&realVal);
+    AutoSafeJSContext cx;
+    JS::Rooted<JS::Value> realVal(cx);
+
+    nsresult rv = aBody->GetAsJSVal(realVal.address());
     if (NS_SUCCEEDED(rv) && !JSVAL_IS_PRIMITIVE(realVal)) {
-      JSObject *obj = JSVAL_TO_OBJECT(realVal);
+      JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(realVal));
       if (JS_IsArrayBufferObject(obj)) {
           ArrayBuffer buf(obj);
           return GetRequestBody(buf.Data(), buf.Length(), aResult,
                                 aContentLength, aContentType, aCharset);
       }
     }
   }
   else if (dataType == nsIDataType::VTYPE_VOID ||
--- a/content/html/content/src/HTMLMediaElement.cpp
+++ b/content/html/content/src/HTMLMediaElement.cpp
@@ -412,17 +412,17 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_
   for (uint32_t i = 0; i < tmp->mOutputStreams.Length(); ++i) {
     NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutputStreams[i].mStream);
   }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPlayed);
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLMediaElement, nsGenericHTMLElement)
   if (tmp->mSrcStream) {
-    // Need to EndMediaStreamPlayback to clear mStream and make sure everything
+    // Need to EndMediaStreamPlayback to clear mSrcStream and make sure everything
     // gets unhooked correctly.
     tmp->EndSrcMediaStreamPlayback();
   }
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSrcAttrStream)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourcePointer)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mLoadBlockedDoc)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceLoadCandidate)
   NS_IMPL_CYCLE_COLLECTION_UNLINK(mAudioChannelAgent)
@@ -1276,17 +1276,20 @@ NS_IMETHODIMP HTMLMediaElement::GetSeeki
   return NS_OK;
 }
 
 /* attribute double currentTime; */
 double
 HTMLMediaElement::CurrentTime() const
 {
   if (mSrcStream) {
-    return MediaTimeToSeconds(GetSrcMediaStream()->GetCurrentTime());
+    MediaStream* stream = GetSrcMediaStream();
+    if (stream) {
+      return MediaTimeToSeconds(stream->GetCurrentTime());
+    }
   }
 
   if (mDecoder) {
     return mDecoder->GetCurrentTime();
   }
 
   return 0.0;
 }
@@ -1462,17 +1465,20 @@ HTMLMediaElement::Pause(ErrorResult& aRv
   bool oldPaused = mPaused;
   mPaused = true;
   mAutoplaying = false;
   // We changed mPaused and mAutoplaying which can affect AddRemoveSelfReference
   AddRemoveSelfReference();
 
   if (!oldPaused) {
     if (mSrcStream) {
-      GetSrcMediaStream()->ChangeExplicitBlockerCount(1);
+      MediaStream* stream = GetSrcMediaStream();
+      if (stream) {
+        stream->ChangeExplicitBlockerCount(1);
+      }
     }
     FireTimeUpdate(false);
     DispatchAsyncEvent(NS_LITERAL_STRING("pause"));
   }
 }
 
 NS_IMETHODIMP HTMLMediaElement::Pause()
 {
@@ -2121,17 +2127,17 @@ HTMLMediaElement::WakeLockBoolWrapper::U
     NS_ENSURE_TRUE_VOID(pmService);
 
     if (!mWakeLock) {
       pmService->NewWakeLock(NS_LITERAL_STRING("cpu"),
                              mOuter->OwnerDoc()->GetWindow(),
                              getter_AddRefs(mWakeLock));
     }
   } else if (mWakeLock) {
-    // Wakelock 'unlocks' itself in its destructor.
+    mWakeLock->Unlock();
     mWakeLock = nullptr;
   }
 }
 
 bool HTMLMediaElement::ParseAttribute(int32_t aNamespaceID,
                                       nsIAtom* aAttribute,
                                       const nsAString& aValue,
                                       nsAttrValue& aResult)
@@ -2630,31 +2636,38 @@ void HTMLMediaElement::SetupSrcMediaStre
   mNetworkState = nsIDOMHTMLMediaElement::NETWORK_IDLE;
   AddRemoveSelfReference();
   // FirstFrameLoaded(false) will be called when the stream has current data,
   // to complete the setup by entering the HAVE_CURRENT_DATA state.
 }
 
 void HTMLMediaElement::EndSrcMediaStreamPlayback()
 {
-  GetSrcMediaStream()->RemoveListener(mSrcStreamListener);
+  MediaStream* stream = GetSrcMediaStream();
+  if (stream) {
+    stream->RemoveListener(mSrcStreamListener);
+  }
   // Kill its reference to this element
   mSrcStreamListener->Forget();
   mSrcStreamListener = nullptr;
-  GetSrcMediaStream()->RemoveAudioOutput(this);
+  if (stream) {
+    stream->RemoveAudioOutput(this);
+  }
   VideoFrameContainer* container = GetVideoFrameContainer();
   if (container) {
-    GetSrcMediaStream()->RemoveVideoOutput(container);
+    if (stream) {
+      stream->RemoveVideoOutput(container);
+    }
     container->ClearCurrentFrame();
   }
-  if (mPaused) {
-    GetSrcMediaStream()->ChangeExplicitBlockerCount(-1);
+  if (mPaused && stream) {
+    stream->ChangeExplicitBlockerCount(-1);
   }
-  if (mPausedForInactiveDocumentOrChannel) {
-    GetSrcMediaStream()->ChangeExplicitBlockerCount(-1);
+  if (mPausedForInactiveDocumentOrChannel && stream) {
+    stream->ChangeExplicitBlockerCount(-1);
   }
   mSrcStream = nullptr;
 }
 
 nsresult HTMLMediaElement::NewURIFromString(const nsAutoString& aURISpec, nsIURI** aURI)
 {
   NS_ENSURE_ARG_POINTER(aURI);
 
--- a/content/html/content/test/Makefile.in
+++ b/content/html/content/test/Makefile.in
@@ -314,27 +314,47 @@ MOCHITEST_FILES = \
 		file_iframe_sandbox_d_if6.html \
 		file_iframe_sandbox_d_if7.html \
 		file_iframe_sandbox_d_if8.html \
 		file_iframe_sandbox_d_if9.html \
 		file_iframe_sandbox_d_if10.html \
 		file_iframe_sandbox_d_if11.html \
 		file_iframe_sandbox_d_if12.html \
 		file_iframe_sandbox_d_if13.html \
+		file_iframe_sandbox_d_if14.html \
+		file_iframe_sandbox_d_if15.html \
+		file_iframe_sandbox_d_if16.html \
+		file_iframe_sandbox_d_if17.html \
+		file_iframe_sandbox_d_if18.html \
+		file_iframe_sandbox_d_if19.html \
+		file_iframe_sandbox_d_if20.html \
+		file_iframe_sandbox_d_if21.html \
+		file_iframe_sandbox_d_if22.html \
 		file_iframe_sandbox_navigation_start.html \
 		file_iframe_sandbox_navigation_pass.html \
 		file_iframe_sandbox_navigation_fail.html \
 		file_iframe_sandbox_e_if1.html \
 		file_iframe_sandbox_e_if2.html \
 		file_iframe_sandbox_e_if3.html \
 		file_iframe_sandbox_e_if4.html \
 		file_iframe_sandbox_e_if5.html \
 		file_iframe_sandbox_e_if6.html \
+		file_iframe_sandbox_e_if7.html \
+		file_iframe_sandbox_e_if8.html \
+		file_iframe_sandbox_e_if9.html \
+		file_iframe_sandbox_e_if10.html \
+		file_iframe_sandbox_e_if11.html \
+		file_iframe_sandbox_e_if12.html \
+		file_iframe_sandbox_e_if13.html \
+		file_iframe_sandbox_e_if14.html \
+		file_iframe_sandbox_e_if15.html \
+		file_iframe_sandbox_e_if16.html \
 		file_iframe_sandbox_top_navigation_pass.html \
 		file_iframe_sandbox_top_navigation_fail.html \
+		file_iframe_sandbox_window_navigation_fail.html \
 		test_iframe_sandbox_plugins.html \
 		file_iframe_sandbox_f_if1.html \
 		file_iframe_sandbox_f_if2.html \
 		file_iframe_sandbox_f_if2.html^headers^ \
 		test_iframe_sandbox_workers.html \
 		file_iframe_sandbox_g_if1.html \
 		file_iframe_sandbox_worker.js \
 		test_named_options.html \
@@ -346,16 +366,18 @@ MOCHITEST_FILES = \
 		test_mod_attributes_reflection.html \
 		test_mozaudiochannel.html \
 		test_mozLoadFrom.html \
 		test_style_attributes_reflection.html \
 		test_bug629801.html \
 		test_bug839371.html \
 		test_element_prototype.html \
 		test_formData.html \
+		test_audio_wakelock.html \
+		wakelock.ogg \
 		$(NULL)
 
 MOCHITEST_BROWSER_FILES = \
 		browser_bug649778.js \
 		file_bug649778.html \
 		file_bug649778.html^headers^ \
 		$(NULL)
 
--- a/content/html/content/test/file_iframe_sandbox_d_if1.html
+++ b/content/html/content/test/file_iframe_sandbox_d_if1.html
@@ -9,11 +9,11 @@
 <script type="application/javascript">
 function doTest() {
   sendMouseEvent({type:'click'}, 'anchor');
 }
 </script>
 <body onload="doTest()">
   I am sandboxed with 'allow-scripts'
 
-  <a href="file_iframe_sandbox_navigation_pass.html?if_1" target="_self" id='anchor'>
+  <a href="file_iframe_sandbox_navigation_pass.html?Test 1:%20" target="_self" id='anchor'>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if14.html
@@ -0,0 +1,35 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Tests for Bug 838692</title>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script type="text/javascript">
+  var test20Context = "Test 20: Navigate another window (not opened by us): ";
+
+  function doTest() {
+    // Try to navigate auxiliary browsing context (window) not opened by us.
+    // We should not be able to do this as we are sandboxed.
+    sendMouseEvent({type:'click'}, 'navigate_window');
+    window.parent.postMessage("test attempted", "*");
+
+    // Try to navigate auxiliary browsing context (window) not opened by us, using window.open().
+    // We should not be able to do this as we are sandboxed.
+    try {
+      window.open("file_iframe_sandbox_window_navigation_fail.html?" + escape(test20Context), "window_to_navigate2");
+      window.parent.postMessage("test attempted", "*");
+    } catch(error) {
+      window.parent.postMessage({ok: true, desc: test20Context + "as expected, error thrown during window.open(..., \"window_to_navigate2\")"}, "*");
+    }
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed but with "allow-scripts allow-same-origin allow-top-navigation".
+
+  <a href="file_iframe_sandbox_window_navigation_fail.html?Test 14: Navigate another window (not opened by us):%20" target="window_to_navigate" id="navigate_window">navigate window</a>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if15.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<body>
+  I am an unsandboxed iframe.
+
+  <iframe sandbox="allow-same-origin allow-scripts" id="if_16" src="file_iframe_sandbox_d_if16.html" height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if16.html
@@ -0,0 +1,22 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+</head>
+
+<script type="application/javascript">
+function doTest() {
+  window.parent.parent.postMessage("test attempted", "*");
+  sendMouseEvent({type:'click'}, 'anchor');
+}
+</script>
+
+<body onload="doTest()">
+  I am sandboxed with 'allow-same-origin allow-scripts'
+
+  <a href="file_iframe_sandbox_navigation_fail.html?Test 16: Navigate parent/ancestor by name:%20" target='if_parent' id='anchor'>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if17.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script type="application/javascript">
+  var testContext = "Test 17: navigate _self with window.open(): ";
+
+  function doTest() {
+    try {
+      window.open("file_iframe_sandbox_navigation_pass.html?" + escape(testContext), "_self");
+    } catch(error) {
+      window.parent.postMessage({ok: false, desc: testContext + "error thrown during window.open(..., \"_self\")"}, "*");
+    }
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts'
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if18.html
@@ -0,0 +1,33 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+</head>
+
+<script type="application/javascript">
+  window.addEventListener("message", receiveMessage, false);
+
+  function receiveMessage(event) {
+    window.parent.postMessage(event.data, "*");
+  }
+
+  var testContext = "Test 18: navigate child with window.open(): ";
+
+  function doTest() {
+    try {
+      window.open("file_iframe_sandbox_navigation_pass.html?" + escape(testContext), "foo");
+    } catch(error) {
+      window.parent.postMessage({ok: false, desc: testContext + " error thrown during window.open(..., \"foo\")"}, "*");
+    }
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts'
+
+  <iframe name="foo" height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if19.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+  I am sandboxed with 'allow-scripts'
+
+  <iframe sandbox="allow-scripts" id="if_20" src="file_iframe_sandbox_d_if20.html" height="10" width="10"></iframe>
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_d_if2.html
+++ b/content/html/content/test/file_iframe_sandbox_d_if2.html
@@ -5,24 +5,24 @@
   <title>Test for Bug 341604</title>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
 </head>
 <script type="application/javascript">
 // needed to forward the message to the main test page
 window.addEventListener("message", receiveMessage, false);
 
-function receiveMessage(event) { 
-  window.parent.postMessage({ok: event.data.ok, desc: event.data.desc}, "*");
+function receiveMessage(event) {
+  window.parent.postMessage(event.data, "*");
 }
 
 function doTest() {
   sendMouseEvent({type:'click'}, 'anchor');
 }
 </script>
 <body onload="doTest()">
   I am sandboxed with 'allow-scripts'
 
   <iframe name="foo" src="file_iframe_sandbox_navigation_start.html" height="10" width="10"></iframe>
 
-  <a href="file_iframe_sandbox_navigation_pass.html?if2" target='foo' id='anchor'>
+  <a href="file_iframe_sandbox_navigation_pass.html?Test 2:%20" target='foo' id='anchor'>
 </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if20.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script type="application/javascript">
+  var testContext = "Test 19: navigate _parent with window.open(): ";
+
+  function doTest() {
+    try {
+      window.open("file_iframe_sandbox_navigation_fail.html?" + escape(testContext), "_parent");
+      window.parent.parent.postMessage("test attempted", "*");
+    } catch(error) {
+      window.parent.parent.postMessage({ok: true, desc: testContext + "as expected, error thrown during window.open(..., \"_parent\")"}, "*");
+    }
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts'
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if21.html
@@ -0,0 +1,14 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<body>
+  I am an unsandboxed iframe.
+
+  <iframe sandbox="allow-same-origin allow-scripts" id="if_22" src="file_iframe_sandbox_d_if22.html" height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_d_if22.html
@@ -0,0 +1,25 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script type="application/javascript">
+  var testContext = "Test 21: navigate parent by name with window.open(): ";
+
+  function doTest() {
+    try {
+      window.open("file_iframe_sandbox_navigation_fail.html?" + escape(testContext), "if_parent2");
+      window.parent.parent.postMessage("test attempted", "*");
+    } catch(error) {
+      window.parent.parent.postMessage({ok: true, desc: testContext + "as expected, error thrown during window.open(..., \"if_parent2\")"}, "*");
+    }
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed with 'allow-same-origin allow-scripts'
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_d_if4.html
+++ b/content/html/content/test/file_iframe_sandbox_d_if4.html
@@ -3,16 +3,17 @@
 <head>
   <meta charset="utf-8">
   <title>Test for Bug 341604</title>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
 </head>
 <script type="application/javascript">
 function doTest() {
+  window.parent.parent.postMessage("test attempted", "*");
   sendMouseEvent({type:'click'}, 'anchor');
 }
 </script>
 <body onload="doTest()">
   I am sandboxed with 'allow-scripts'
 
   <a href="file_iframe_sandbox_navigation_fail.html" target='_parent' id='anchor'>
 </body>
--- a/content/html/content/test/file_iframe_sandbox_d_if5.html
+++ b/content/html/content/test/file_iframe_sandbox_d_if5.html
@@ -4,16 +4,17 @@
   <meta charset="utf-8">
   <title>Test for Bug 341604</title>
   <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
   <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
 </head>
 <script type="application/javascript">
 function doTest() {
   sendMouseEvent({type:'click'}, 'anchor');
+  window.parent.postMessage("test attempted", "*");
 }
 </script>
 <body onload="doTest()">
   I am sandboxed with 'allow-scripts allow-same-origin'
 
-  <a href="file_iframe_sandbox_navigation_fail.html" target='sibling' id='anchor'>
+  <a href="file_iframe_sandbox_navigation_fail.html?Test 4: Navigate sibling iframe by name:%20" target='if_sibling' id='anchor'>
 </body>
 </html>
--- a/content/html/content/test/file_iframe_sandbox_d_if7.html
+++ b/content/html/content/test/file_iframe_sandbox_d_if7.html
@@ -1,16 +1,20 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<script type="application/javascript">
-function doTest() {
-  window.parent.ok_wrapper(false, "a sandboxed document when navigated should still NOT be same-origin with its parent");
-}
-</script>
-<body onload="doTest()">
-  I am sandboxed with 'allow-scripts'
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script type="application/javascript">
+function doTest() {
+  try {
+    window.parent.ok_wrapper(false, "a sandboxed document when navigated should still NOT be same-origin with its parent");
+  } catch(error) {
+    window.parent.postMessage({ok: true, desc: "sandboxed document's attempt to access parent after navigation blocked, as not same-origin."}, "*");
+  }
+}
+</script>
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts'
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_d_if8.html
+++ b/content/html/content/test/file_iframe_sandbox_d_if8.html
@@ -1,16 +1,24 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<script type="application/javascript">
-function doTest() {
-  window.parent.modify_if_8();
-}
-</script>
-<body onload="doTest()">
-  I am sandboxed with 'allow-scripts' and 'allow-same-origin' the first time I am loaded, and with 'allow-scripts' the second time
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script type="application/javascript">
+function doTest() {
+  if (location.search == "?onreload") {
+    try {
+      window.parent.modify_if_8();
+    } catch (error) {
+      window.parent.postMessage({ok: true, desc: "allow-same-origin is no longer in effect after reload - parent access blocked."}, "*");
+    }
+  } else {
+    window.parent.modify_if_8();
+  }
+}
+</script>
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts' and 'allow-same-origin' the first time I am loaded, and with 'allow-scripts' the second time
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_e_if1.html
+++ b/content/html/content/test/file_iframe_sandbox_e_if1.html
@@ -1,24 +1,20 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-  <script>
-    window.addEventListener("message", receiveMessage, false);
-
-    function receiveMessage(event)
-    {
-      window.parent.postMessage("close", "*");
-
-      SimpleTest.executeSoon(function() {
-        window.close();
-      }); 
-    }
-  </script>
-  <iframe sandbox='allow-scripts allow-same-origin' id='if_6' src="file_iframe_sandbox_e_if6.html" height="10" width="10"></iframe>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+</head>
+
+<script>
+  function doTest() {
+    var testContext = location.search == "" ? "?Test 10: Navigate _top:%20" : location.search;
+    document.getElementById("if_6").src = "file_iframe_sandbox_e_if6.html" + testContext;
+  }
+</script>
+
+<body onload="doTest()">
+  <iframe sandbox='allow-scripts' id='if_6' height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if10.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  function doTest() {
+    var testContext = "?Test 23: Nested navigate _top with window.open():%20";
+    document.getElementById("if_9").src = "file_iframe_sandbox_e_if9.html" + testContext;
+  }
+</script>
+
+<body onload="doTest()">
+  <iframe sandbox='allow-scripts allow-top-navigation' id='if_9' height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if11.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script>
+  function doTest() {
+    var testContext = location.search.substring(1);
+    try {
+      var topsOpener = window.top.opener;
+      window.open("file_iframe_sandbox_top_navigation_pass.html?" + testContext, "_top");
+      topsOpener.postMessage({ok: true, desc: unescape(testContext) + "top navigation should be allowed by a document sandboxed with 'allow-top-navigation.'"}, "*");
+    } catch(error) {
+      window.top.opener.postMessage({ok: false, desc: unescape(testContext) + "error thrown during window.open(..., \"_top\")"}, "*");
+      window.top.close();
+    }
+  }
+</script>
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts and allow-top-navigation'
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if12.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  function doTest() {
+    var testContext = location.search == "" ? "?Test 24: Navigate _top with window.open():%20" : location.search;
+    document.getElementById("if_14").src = "file_iframe_sandbox_e_if14.html" + testContext;
+  }
+</script>
+
+<body onload="doTest()">
+  <iframe sandbox='allow-scripts' id='if_14' height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if13.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  function doTest() {
+    var testContext = "?Test 25: Nested navigate _top with window.open():%20";
+    document.getElementById("if_12").src = "file_iframe_sandbox_e_if12.html" + testContext;
+  }
+</script>
+
+<body onload="doTest()">
+  <iframe sandbox='allow-scripts allow-top-navigation' id='if_12' height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if14.html
@@ -0,0 +1,24 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script>
+  function doTest() {
+    var testContext = location.search.substring(1);
+    try {
+      var topsOpener = window.top.opener;
+      window.open("file_iframe_sandbox_top_navigation_fail.html?" + testContext, "_top");
+      topsOpener.postMessage({ok: false, desc: unescape(testContext) + "top navigation should NOT be allowed by a document sandboxed without 'allow-top-navigation.'"}, "*");
+    } catch(error) {
+      window.top.opener.postMessage({ok: true, desc: unescape(testContext) + "as expected error thrown during window.open(..., \"_top\")"}, "*");
+      window.top.close();
+    }
+  }
+</script>
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts'
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if15.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  // Set our name, to allow an attempt to navigate us by name.
+  window.name = "e_if15";
+</script>
+
+<body>
+  <iframe sandbox='allow-scripts' id='if_16' src="file_iframe_sandbox_e_if16.html" height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if16.html
@@ -0,0 +1,27 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Tests for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  var testContext = "Test 26: navigate top by name with window.open(): ";
+
+  function doTest() {
+    try {
+      var topsOpener = window.top.opener;
+      window.open("file_iframe_sandbox_top_navigation_fail.html?" + escape(testContext), "e_if15");
+      topsOpener.postMessage({ok: false, desc: unescape(testContext) + "top navigation should NOT be allowed by a document sandboxed without 'allow-top-navigation.'"}, "*");
+    } catch(error) {
+      window.top.opener.postMessage({ok: true, desc: testContext + "as expected, error thrown during window.open(..., \"e_if15\")"}, "*");
+      window.top.close();
+    }
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed but with "allow-scripts"
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_e_if2.html
+++ b/content/html/content/test/file_iframe_sandbox_e_if2.html
@@ -1,22 +1,12 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<body>
-  <script>
-    window.addEventListener("message", receiveMessage, false);
-
-    function receiveMessage(event)
-    {
-      SimpleTest.executeSoon(function() {
-        window.close();
-      });
-    }
-  </script>
-  <iframe sandbox='allow-scripts allow-top-navigation allow-same-origin' id='if_1' src="file_iframe_sandbox_e_if1.html" height="10" width="10"></iframe>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+</head>
+<body>
+  <iframe sandbox='allow-scripts allow-top-navigation allow-same-origin' id='if_1' src="file_iframe_sandbox_e_if1.html?Test 11: Nested navigate _top:%20" height="10" width="10"></iframe>
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_e_if6.html
+++ b/content/html/content/test/file_iframe_sandbox_e_if6.html
@@ -1,24 +1,22 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-</head>
-<script type="application/javascript">
-function doTest() {
-  sendMouseEvent({type:'click'}, 'anchor');
-
-   SimpleTest.executeSoon(function() {
-     window.parent.postMessage("close", "*");
-   });
-}
-</script>
-<body onload="doTest()">
-  I am sandboxed with 'allow-scripts'
-
-  <a href="file_iframe_sandbox_top_navigation_fail.html" target='_top' id='anchor'>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+</head>
+<script type="application/javascript">
+function doTest() {
+  document.getElementById('anchor').href = "file_iframe_sandbox_top_navigation_fail.html" + location.search;
+  window.top.opener.postMessage("test attempted", "*");
+  sendMouseEvent({type:'click'}, 'anchor');
+}
+</script>
+<body onload="doTest()">
+  I am sandboxed with 'allow-scripts'
+
+  <a target='_top' id='anchor'>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if7.html
@@ -0,0 +1,17 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  // Set our name, to allow an attempt to navigate us by name.
+  window.name = "e_if7";
+</script>
+
+<body>
+  <iframe sandbox='allow-scripts' id='if_8' src="file_iframe_sandbox_e_if8.html" height="10" width="10"></iframe>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if8.html
@@ -0,0 +1,23 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Tests for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+</head>
+
+<script>
+  function doTest() {
+    // Try to navigate top using its name (e_if7).  We should not be able to do this as allow-top-navigation is not specified.
+    window.top.opener.postMessage("test attempted", "*");
+    sendMouseEvent({type:'click'}, 'navigate_top');
+  }
+</script>
+
+<body onload="doTest()">
+  I am sandboxed but with "allow-scripts"
+
+  <a href="file_iframe_sandbox_top_navigation_fail.html?Test 15: Navigate top by name:%20" target="e_if7" id="navigate_top">navigate top</a>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_e_if9.html
@@ -0,0 +1,19 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+  function doTest() {
+    var testContext = location.search == "" ? "?Test 22: Navigate _top with window.open():%20" : location.search;
+    document.getElementById("if_11").src = "file_iframe_sandbox_e_if11.html" + testContext;
+  }
+</script>
+
+<body onload="doTest()">
+  <iframe sandbox='allow-scripts allow-top-navigation' id='if_11' height="10" width="10"></iframe>
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_navigation_fail.html
+++ b/content/html/content/test/file_iframe_sandbox_navigation_fail.html
@@ -1,16 +1,17 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body onLoad="doStuff()">
-FAIL
-</body>
-<script>
-  function doStuff() {
-    window.parent.postMessage({ok: false, desc: "this navigation should NOT be allowed by a sandboxed document"}, "*");
-  }
-</script>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body onLoad="doStuff()">
+FAIL
+</body>
+<script>
+  function doStuff() {
+    var testContext = unescape(location.search.substring(1));
+    window.parent.postMessage({ok: false, desc: testContext + "this navigation should NOT be allowed by a sandboxed document", addToAttempted: false}, "*");
+  }
+</script>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_navigation_pass.html
+++ b/content/html/content/test/file_iframe_sandbox_navigation_pass.html
@@ -1,16 +1,17 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<script>
-function doStuff() {
-  window.parent.postMessage({ok: true, desc: "this navigation should be allowed by a sandboxed document"}, "*");
-}
-</script>
-<body onLoad="doStuff()">
-PASS
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script>
+function doStuff() {
+  var testContext = unescape(location.search.substring(1));
+  window.parent.postMessage({ok: true, desc: testContext + "this navigation should be allowed by a sandboxed document"}, "*");
+}
+</script>
+<body onLoad="doStuff()">
+PASS
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_top_navigation_fail.html
+++ b/content/html/content/test/file_iframe_sandbox_top_navigation_fail.html
@@ -1,17 +1,18 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<script>
-function doStuff() {
-	window.opener.postMessage({ok: false, desc:  "top navigation should NOT be allowed by a document sandboxed without 'allow-top-navigation'"}, "*");
-	window.close();
-}
-</script>
-<body onLoad="doStuff()">
-FAIL\
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script>
+function doStuff() {
+  var testContext = unescape(location.search.substring(1));
+  window.opener.postMessage({ok: false, desc: testContext + "top navigation should NOT be allowed by a document sandboxed without 'allow-top-navigation'", addToAttempted: false}, "*");
+  window.close();
+}
+</script>
+<body onLoad="doStuff()">
+FAIL\
+</body>
+</html>
--- a/content/html/content/test/file_iframe_sandbox_top_navigation_pass.html
+++ b/content/html/content/test/file_iframe_sandbox_top_navigation_pass.html
@@ -1,17 +1,18 @@
-<!DOCTYPE HTML>
-<html>
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604</title>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<script>
-function doStuff() {
-	window.opener.postMessage({ok: true, desc:  "top navigation should be allowed by a document sandboxed with 'allow-top-navigation'"}, "*");
-	window.close();
-}
-</script>
-<body onLoad="doStuff()">
-PASS
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script>
+function doStuff() {
+  var testContext = unescape(location.search.substring(1));
+  window.opener.postMessage({ok: true, desc: testContext + "top navigation should be allowed by a document sandboxed with 'allow-top-navigation'"}, "*");
+  window.close();
+}
+</script>
+<body onLoad="doStuff()">
+PASS
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/file_iframe_sandbox_window_navigation_fail.html
@@ -0,0 +1,20 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 838692</title>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+
+<script>
+function doStuff() {
+  var testContext = unescape(location.search.substring(1));
+  window.opener.postMessage({ok: false, desc: testContext + "a sandboxed document should not be able to navigate a window it hasn't opened.", addToAttempted: false}, "*");
+  window.close();
+}
+</script>
+
+<body onLoad="doStuff()">
+FAIL
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/html/content/test/test_audio_wakelock.html
@@ -0,0 +1,113 @@
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=868943
+-->
+<head>
+  <title>Test for Bug 868943</title>
+  <script type="application/javascript" src="/MochiKit/packed.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=868943">Mozilla Bug 868943</a>
+<p id="display"></p>
+<div id="content">
+</div>
+<pre id="test">
+<script type="application/javascript">
+
+/** Test for Bug 868943 **/
+
+SpecialPowers.addPermission("power", true, document);
+
+function testAudioPlayPause() {
+  var lockState = true;
+  var count = 0;
+
+  var content = document.getElementById('content');
+
+  var audio = document.createElement('audio');
+  audio.src = "wakelock.ogg";
+  content.appendChild(audio);
+
+  audio.addEventListener('progress', function() {
+    lockState = false;
+    audio.pause();
+  });
+
+  navigator.mozPower.addWakeLockListener(function testAudioPlayListener(topic, state) {
+    is(topic, "cpu", "Audio element locked the target == cpu");
+    var locked = state == "locked-foreground" ||
+                 state == "locked-background";
+
+    is(locked, lockState, "Audio element locked the cpu - no paused");
+    count++;
+
+    // count == 1 is when the cpu wakelock is created
+    // count == 2 is when the cpu wakelock is released
+
+    if (count == 2) {
+      content.removeChild(audio);
+      navigator.mozPower.removeWakeLockListener(testAudioPlayListener);
+      runTests();
+    }
+  });
+
+  audio.play();
+}
+
+function testAudioPlay() {
+  var lockState = true;
+  var count = 0;
+
+  var content = document.getElementById('content');
+
+  var audio = document.createElement('audio');
+  audio.src = "wakelock.ogg";
+  content.appendChild(audio);
+
+  navigator.mozPower.addWakeLockListener(function testAudioPlayListener(topic, state) {
+    is(topic, "cpu", "Audio element locked the target == cpu");
+    var locked = state == "locked-foreground" ||
+                 state == "locked-background";
+
+    is(locked, lockState, "Audio element locked the cpu - no paused");
+    count++;
+
+    // count == 1 is when the cpu wakelock is created: the wakelock must be
+    // created when the media element starts playing.
+    // count == 2 is when the cpu wakelock is released.
+
+    if (count == 1) {
+      // The next step is to unlock the resource.
+      lockState = false;
+    } else if (count == 2) {
+      content.removeChild(audio);
+      navigator.mozPower.removeWakeLockListener(testAudioPlayListener);
+      runTests();
+    }
+  });
+
+  audio.play();
+}
+
+var tests = [ testAudioPlayPause, testAudioPlay ];
+function runTests() {
+  if (!tests.length) {
+    SimpleTest.finish();
+    return;
+  }
+
+  var test =  tests.pop();
+  test();
+};
+
+SimpleTest.waitForExplicitFinish();
+runTests();
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/html/content/test/test_iframe_sandbox_navigation.html
+++ b/content/html/content/test/test_iframe_sandbox_navigation.html
@@ -1,234 +1,356 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=341604
-Implement HTML5 sandbox attribute for IFRAMEs
--->
-<head>
-  <meta charset="utf-8">
-  <title>Test for Bug 341604 - navigation</title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
-	<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<script type="application/javascript">
-
-SimpleTest.expectAssertions(1, 2);
-
-/** Test for Bug 341604 - Implement HTML5 sandbox attribute for IFRAMEs **/
-/** Navigation tests **/
-
-SimpleTest.waitForExplicitFinish();
-// a postMessage handler that is used by sandboxed iframes without
-// 'allow-same-origin'/other windows to communicate pass/fail back to this main page.
-// it expects to be called with an object like {ok: true/false, desc:
-// <description of the test> which it then forwards to ok()
-window.addEventListener("message", receiveMessage, false);
-
-var testPassesReceived = 0;
-
-function receiveMessage(event) {
-  // this message is part of if_10's test
-  if (event.data.test == 'if_10') {
-    doIf10TestPart2();
-    return;
-  }
-
-  ok_wrapper(event.data.ok, event.data.desc);
-}
-
-var completedTests = 0;
-var passedTests = 0;
-
-function ok_wrapper(result, desc) {
-  ok(result, desc);
-
-  completedTests++;
-
-  if (result) {
-    passedTests++;
-  }
-
-  if (completedTests == 6) {
-    is(passedTests, 6, "There are 6 navigation tests that should pass");
-
-    SimpleTest.finish();
-  }
-}
-
-function doTest() {
-  // passes if good
-  // 1) A sandboxed iframe is allowed to navigate itself
-  // (done by file_iframe_sandbox_d_if1.html which has 'allow-scripts' and navigates to
-  // file_iframe_sandbox_navigation_pass.html).
-
-  // passes if good
-  // 2) A sandboxed iframe is allowed to navigate its children, even if they are sandboxed
-  // (done by file_iframe_sandbox_d_if2.html which has 'allow-scripts', it navigates a child
-  // iframe containing file_iframe_sandbox_navigation_start.html to file_iframe_sandbox_navigation_pass.html).
-
-  // fails if bad
-  // 3) A sandboxed iframe is not allowed to navigate its ancestor
-  // (done by file_iframe_sandbox_d_if4.html contained within file_iframe_sandbox_d_if3.html,
-  // it attempts to navigate file_iframe_sandbox_d_if3.html to file_iframe_sandbox_navigation_fail.html).
-
-  // fails if bad
-  // 4) A sandboxed iframe is not allowed to navigate its sibling
-  // (done by file_iframe_sandbox_d_if5.html which has 'allow scripts allow-same-origin'
-  // and attempts to navigate file_iframe_navigation_start.html contained in if_sibling on this
-  // page to file_iframe_sandbox_navigation_fail.html).
-
-  // fails if bad
-  // 5) When a link is clicked in a sandboxed iframe, the document navigated to is sandboxed
-  // the same as the original document and is not same origin with parent document
-  // (done by file_iframe_sandbox_d_if6.html which simulates a link click and navigates
-  // to file_iframe_sandbox_d_if7.html which attempts to call back into its parent).
-
-  // fails if bad
-  // 6) An iframe (if_8) has sandbox="allow-same-origin allow-scripts", the sandboxed document
-  // (file_iframe_sandbox_d_if_8.html) that it contains accesses its parent (this file) and removes
-  // 'allow-same-origin' and then triggers a reload.
-  // The document should not be able to access its parent (this file).
-
-  // fails if bad
-  // 7) An iframe (if_9) has sandbox="allow-same-origin allow-scripts", the sandboxed document
-  // (file_iframe_sandbox_d_if_9.html) that it contains accesses its parent (this file) and removes
-  // 'allow-scripts' and then triggers a reload.
-  // The document should not be able to run a script and access its parent (this file).
-
-  // passes if good
-  // 8) a document in an iframe with sandbox='allow-scripts' should have a different null
-  // principal in its original document than a document to which it navigates itself
-  // file_iframe_sandbox_d_if_10.html does this, co-ordinating with this page via postMessage
-  
-  // passes if good
-  // 9) a document (file_iframe_sandbox_d_if11.html in an iframe (if_11) with sandbox='allow-scripts'
-  // is navigated to file_iframe_sandbox_d_if12.html - when that document loads
-  // a message is sent back to this document, which adds 'allow-same-origin' to if_11 and then
-  // calls .back on it - file_iframe_sandbox_if12.html should be able to call back into this
-  // document - this is all contained in file_iframe_sandbox_d_if13.html which is opened in another
-  // tab so it has its own isolated session history
-  window.open("file_iframe_sandbox_d_if13.html");
-  
-  // open up the top navigation tests
-
-  // fails if bad
-  // 10) iframe with sandbox='allow-scripts' can NOT navigate top
-  // file_iframe_sandbox_e_if1.html contains file_iframe_sandbox_e_if6.html which
-  // attempts to navigate top
-  window.open("file_iframe_sandbox_e_if1.html");
-
-  // fails if bad
-  // 11) iframe with sandbox='allow-scripts' nested inside iframe with
-  // 'allow-top-navigation allow-scripts' can NOT navigate top
-  // file_iframe_sandbox_e_if2.html contains file_iframe_sandbox_e_if1.html which
-  // contains file_iframe_sandbox_e_if6.html which attempts to navigate top
-  window.open("file_iframe_sandbox_e_if2.html");
-
-  // passes if good
-  // 12) iframe with sandbox='allow-top-navigation allow-scripts' can navigate top
-  // file_iframe_sandbox_e_if3.html contains file_iframe_sandbox_e_if5.html which navigates top
-  window.open("file_iframe_sandbox_e_if3.html");
-
-  // passes if good
-  // 131) iframe with sandbox='allow-top-navigation allow-scripts' nested inside an iframe with
-  // 'allow-top-navigation allow-scripts' can navigate top
-  // file_iframe_sandbox_e_if4.html contains file_iframe_sandbox_e_if3.html which contains
-  // file_iframe_sandbox_e_if5.html which navigates top
-  window.open("file_iframe_sandbox_e_if4.html");
-}
-
-addLoadEvent(doTest);
-
-window.modified_if_8 = false;
-
-function reload_if_8() {
-  var if_8 = document.getElementById('if_8');
-  if_8.src = 'file_iframe_sandbox_d_if8.html';
-}
-
-function modify_if_8() {
-  // If this is the second time this has been called
-  // that's a failed test (allow-same-origin was removed
-  // the first time).
-  if (window.modified_if_8) {
-    ok_wrapper(false, "an sandboxed iframe from which 'allow-same-origin' was removed should not be able to access its parent");
-
-    // need to return here since we end up in an infinite loop otherwise
-    return;
-  }
-
-  var if_8 = document.getElementById('if_8');
-  window.modified_if_8 = true;
-
-  if_8.sandbox = 'allow-scripts';
-  sendMouseEvent({type:'click'}, 'a_button');
-}
-
-window.modified_if_9 = false;
-
-function reload_if_9() {
-  var if_9 = document.getElementById('if_9');
-  if_9.src = 'file_iframe_sandbox_d_if9.html';
-}
-
-function modify_if_9() {
-  // If this is the second time this has been called
-  // that's a failed test (allow-scripts was removed
-  // the first time).
-  if (window.modified_if_9) {
-    ok_wrapper(false, "an sandboxed iframe from which 'allow-scripts' should be removed should not be able to access its parent via a script");
-
-    // need to return here since we end up in an infinite loop otherwise
-    return;
-  }
-
-  var if_9 = document.getElementById('if_9');
-  window.modified_if_9 = true;
-
-  if_9.sandbox = 'allow-same-origin';
-
-  sendMouseEvent({type:'click'}, 'a_button2');
-}
-
-var firstPrincipal = "";
-var secondPrincipal;
-
-function doIf10TestPart1() {
-  if (firstPrincipal != "")
-    return;
-
-  // use SpecialPowers to get the principal of if_10.
-  // NB: We stringify here and below because special-powers wrapping doesn't
-  // preserve identity.
-  var if_10 = document.getElementById('if_10');
-  firstPrincipal = SpecialPowers.wrap(if_10).contentDocument.nodePrincipal.origin;
-  if_10.src = 'file_iframe_sandbox_d_if10.html';
-
-}
-function doIf10TestPart2() {
-  var if_10 = document.getElementById('if_10');
-  // use SpecialPowers to get the principal of if_10
-  secondPrincipal = SpecialPowers.wrap(if_10).contentDocument.nodePrincipal.origin;
-  ok_wrapper(firstPrincipal != secondPrincipal, "documents should NOT have the same principal if they are sandboxed without" +
-    " allow-same-origin and the first document is navigated to the second");
-}
-</script>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=341604">Mozilla Bug 341604</a> - Implement HTML5 sandbox attribute for IFRAMEs
-<p id="display"></p>
-<div id="content">
-<iframe sandbox="allow-scripts" id="if_1" src="file_iframe_sandbox_d_if1.html" height="10" width="10"></iframe>
-<iframe sandbox="allow-scripts" id="if_2" src="file_iframe_sandbox_d_if2.html" height="10" width="10"></iframe>
-<iframe sandbox="allow-scripts" id="if_3" src="file_iframe_sandbox_d_if3.html" height="10" width="10"></iframe>
-<iframe sandbox="allow_scripts allow-same-origin" id="if_5" src="file_iframe_sandbox_d_if5.html" height="10" width="10"></iframe>
-<iframe id="if_sibling" src="file_iframe_sandbox_navigation_start.html" height="10" width="10"></iframe>
-<iframe sandbox="allow_scripts" id="if_6" src="file_iframe_sandbox_d_if6.html" height="10" width="10"></iframe>
-<iframe sandbox="allow-same-origin allow-scripts" id="if_8" src="file_iframe_sandbox_d_if8.html" height="10" width="10"></iframe>
-<iframe sandbox="allow-same-origin allow-scripts" id="if_9" src="file_iframe_sandbox_d_if9.html" height="10" width="10"></iframe>
-<iframe sandbox="allow-scripts" id="if_10" src="file_iframe_sandbox_navigation_start.html" onload='doIf10TestPart1()' height="10" width="10"></iframe>
-</div>
-<input type='button' id="a_button" onclick='reload_if_8()'>
-<input type='button' id="a_button2" onclick='reload_if_9()'>
-</body>
-</html>
+<!DOCTYPE HTML>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=341604
+Implement HTML5 sandbox attribute for IFRAMEs
+-->
+<head>
+  <meta charset="utf-8">
+  <title>Test for Bug 341604 - navigation</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<script type="application/javascript">
+/** Test for Bug 341604 - Implement HTML5 sandbox attribute for IFRAMEs **/
+/** Navigation tests **/
+
+SimpleTest.expectAssertions(1, 3);
+SimpleTest.waitForExplicitFinish();
+// a postMessage handler that is used by sandboxed iframes without
+// 'allow-same-origin'/other windows to communicate pass/fail back to this main page.
+// it expects to be called with an object like {ok: true/false, desc:
+// <description of the test> which it then forwards to ok()
+window.addEventListener("message", receiveMessage, false);
+
+var testPassesReceived = 0;
+
+function receiveMessage(event) {
+  // this message is part of if_10's test
+  if (event.data.test == 'if_10') {
+    doIf10TestPart2();
+  } else if (event.data == "test attempted") {
+    testAttempted();
+  } else {
+    ok_wrapper(event.data.ok, event.data.desc, event.data.addToAttempted);
+  }
+}
+
+// Open windows for tests to attempt to navigate later.
+var windowsToClose = new Array();
+windowsToClose.push(window.open("about:blank", "window_to_navigate"));
+windowsToClose.push(window.open("about:blank", "window_to_navigate2"));
+
+var attemptedTests = 0;
+var passedTests = 0;
+var totalTestsToPass = 18;
+var totalTestsToAttempt = 26;
+
+function ok_wrapper(result, desc, addToAttempted = true) {
+  ok(result, desc);
+
+  if (result) {
+    passedTests++;
+  }
+
+  if (addToAttempted) {
+    testAttempted();
+  }
+}
+
+// Added so that tests that don't register unless they fail,
+// can at least notify that they've attempted to run.
+function testAttempted() {
+  attemptedTests++;
+  if (attemptedTests == totalTestsToAttempt) {
+    // Make sure all tests have had a chance to complete.
+    setTimeout(function() {finish();}, 1000);
+  }
+}
+
+var finishCalled = false;
+
+function finish() {
+  if (!finishCalled) {
+    finishCalled = true;
+    is(passedTests, totalTestsToPass, "There are " + totalTestsToPass + " navigation tests that should pass");
+
+    for (var i = 0; i < windowsToClose.length; i++) {
+      windowsToClose[i].close();
+    }
+
+    SimpleTest.finish();
+  }
+}
+
+function checkTestsFinished() {
+  // If our own finish() has not been called, probably failed due to a timeout, so close remaining windows.
+  if (!finishCalled) {
+    for (var i = 0; i < windowsToClose.length; i++) {
+      windowsToClose[i].close();
+    }
+  }
+}
+
+function doTest() {
+  // passes if good
+  // 1) A sandboxed iframe is allowed to navigate itself
+  // (done by file_iframe_sandbox_d_if1.html which has 'allow-scripts' and navigates to
+  // file_iframe_sandbox_navigation_pass.html).
+
+  // passes if good
+  // 2) A sandboxed iframe is allowed to navigate its children, even if they are sandboxed
+  // (done by file_iframe_sandbox_d_if2.html which has 'allow-scripts', it navigates a child
+  // iframe containing file_iframe_sandbox_navigation_start.html to file_iframe_sandbox_navigation_pass.html).
+
+  // fails if bad
+  // 3) A sandboxed iframe is not allowed to navigate its ancestor
+  // (done by file_iframe_sandbox_d_if4.html contained within file_iframe_sandbox_d_if3.html,
+  // it attempts to navigate file_iframe_sandbox_d_if3.html to file_iframe_sandbox_navigation_fail.html).
+
+  // fails if bad
+  // 4) A sandboxed iframe is not allowed to navigate its sibling
+  // (done by file_iframe_sandbox_d_if5.html which has 'allow scripts allow-same-origin'
+  // and attempts to navigate file_iframe_navigation_start.html contained in if_sibling on this
+  // page to file_iframe_sandbox_navigation_fail.html).
+
+  // passes if good, fails if bad
+  // 5) When a link is clicked in a sandboxed iframe, the document navigated to is sandboxed
+  // the same as the original document and is not same origin with parent document
+  // (done by file_iframe_sandbox_d_if6.html which simulates a link click and navigates
+  // to file_iframe_sandbox_d_if7.html which attempts to call back into its parent).
+
+  // passes if good, fails if bad
+  // 6) An iframe (if_8) has sandbox="allow-same-origin allow-scripts", the sandboxed document
+  // (file_iframe_sandbox_d_if_8.html) that it contains accesses its parent (this file) and removes
+  // 'allow-same-origin' and then triggers a reload.
+  // The document should not be able to access its parent (this file).
+
+  // fails if bad
+  // 7) An iframe (if_9) has sandbox="allow-same-origin allow-scripts", the sandboxed document
+  // (file_iframe_sandbox_d_if_9.html) that it contains accesses its parent (this file) and removes
+  // 'allow-scripts' and then triggers a reload.
+  // The document should not be able to run a script and access its parent (this file).
+
+  // passes if good
+  // 8) a document in an iframe with sandbox='allow-scripts' should have a different null
+  // principal in its original document than a document to which it navigates itself
+  // file_iframe_sandbox_d_if_10.html does this, co-ordinating with this page via postMessage
+
+  // passes if good
+  // 9) a document (file_iframe_sandbox_d_if11.html in an iframe (if_11) with sandbox='allow-scripts'
+  // is navigated to file_iframe_sandbox_d_if12.html - when that document loads
+  // a message is sent back to this document, which adds 'allow-same-origin' to if_11 and then
+  // calls .back on it - file_iframe_sandbox_if12.html should be able to call back into this
+  // document - this is all contained in file_iframe_sandbox_d_if13.html which is opened in another
+  // tab so it has its own isolated session history
+  window.open("file_iframe_sandbox_d_if13.html");
+
+  // open up the top navigation tests
+
+  // fails if bad
+  // 10) iframe with sandbox='allow-scripts' can NOT navigate top
+  // file_iframe_sandbox_e_if1.html contains file_iframe_sandbox_e_if6.html which
+  // attempts to navigate top
+  windowsToClose.push(window.open("file_iframe_sandbox_e_if1.html"));
+
+  // fails if bad
+  // 11) iframe with sandbox='allow-scripts' nested inside iframe with
+  // 'allow-top-navigation allow-scripts' can NOT navigate top
+  // file_iframe_sandbox_e_if2.html contains file_iframe_sandbox_e_if1.html which
+  // contains file_iframe_sandbox_e_if6.html which attempts to navigate top
+  windowsToClose.push(window.open("file_iframe_sandbox_e_if2.html"));
+
+  // passes if good
+  // 12) iframe with sandbox='allow-top-navigation allow-scripts' can navigate top
+  // file_iframe_sandbox_e_if3.html contains file_iframe_sandbox_e_if5.html which navigates top
+  window.open("file_iframe_sandbox_e_if3.html");
+
+  // passes if good
+  // 13) iframe with sandbox='allow-top-navigation allow-scripts' nested inside an iframe with
+  // 'allow-top-navigation allow-scripts' can navigate top
+  // file_iframe_sandbox_e_if4.html contains file_iframe_sandbox_e_if3.html which contains
+  // file_iframe_sandbox_e_if5.html which navigates top
+  window.open("file_iframe_sandbox_e_if4.html");
+
+  // fails if bad
+  // 14) iframe with sandbox='allow-same-origin allow-scripts allow-top-navigation' should not
+  // be able to navigate another window (opened by another browsing context) using its name.
+  // file_iframe_sandbox_d_if14.html in if_14 attempts to navigate "window_to_navigate",
+  // which has been opened in preparation.
+
+  // fails if bad
+  // 15) iframe with sandbox='allow-scripts' should not be able to navigate top using its
+  // real name (instead of _top) as allow-top-navigation is not specified.
+  // file_iframe_sandbox_e_if7.html contains file_iframe_sandbox_e_if8.html, which
+  // attempts to navigate top by name.
+  windowsToClose.push(window.open("file_iframe_sandbox_e_if7.html"));
+
+  // fails if bad
+  // 16) iframe with sandbox='allow-same-origin allow-scripts allow-top-navigation' should not
+  // be able to use its parent's name (instead of _parent) to navigate it, when it is not top.
+  // (Note: this would apply to other ancestors that are not top as well.)
+  // file_iframe_sandbox_d_if15.html in if_15 contains file_iframe_sandbox_d_if16.html, which
+  // tries to navigate if_15 by its name (if_parent).
+
+  // passes if good, fails if bad
+  // 17) A sandboxed iframe is allowed to navigate itself using window.open().
+  // (Done by file_iframe_sandbox_d_if17.html which has 'allow-scripts' and navigates to
+  // file_iframe_sandbox_navigation_pass.html).
+
+  // passes if good, fails if bad
+  // 18) A sandboxed iframe is allowed to navigate its children with window.open(), even if
+  // they are sandboxed.  (Done by file_iframe_sandbox_d_if18.html which has 'allow-scripts',
+  // it navigates a child iframe to file_iframe_sandbox_navigation_pass.html).
+
+  // passes if good, fails if bad
+  // 19) A sandboxed iframe is not allowed to navigate its ancestor with window.open().
+  // (Done by file_iframe_sandbox_d_if20.html contained within file_iframe_sandbox_d_if19.html,
+  // it attempts to navigate file_iframe_sandbox_d_if19.html to file_iframe_sandbox_navigation_fail.html).
+
+  // passes if good, fails if bad
+  // 20) iframe with sandbox='allow-same-origin allow-scripts allow-top-navigation' should not
+  // be able to navigate another window (opened by another browsing context) using window.open(..., "<name>").
+  // file_iframe_sandbox_d_if14.html in if_14 attempts to navigate "window_to_navigate2",
+  // which has been opened in preparation, using window.open(..., "window_to_navigate2").
+
+  // passes if good, fails if bad
+  // 21) iframe with sandbox='allow-same-origin allow-scripts allow-top-navigation' should not
+  // be able to use its parent's name (not _parent) to navigate it using window.open(), when it is not top.
+  // (Note: this would apply to other ancestors that are not top as well.)
+  // file_iframe_sandbox_d_if21.html in if_21 contains file_iframe_sandbox_d_if22.html, which
+  // tries to navigate if_21 by its name (if_parent2).
+
+  // passes if good, fails if bad
+  // 22) iframe with sandbox='allow-top-navigation allow-scripts' can navigate top with window.open().
+  // file_iframe_sandbox_e_if9.html contains file_iframe_sandbox_e_if11.html which navigates top.
+  window.open("file_iframe_sandbox_e_if9.html");
+
+  // passes if good, fails if bad
+  // 23) iframe with sandbox='allow-top-navigation allow-scripts' nested inside an iframe with
+  // 'allow-top-navigation allow-scripts' can navigate top, with window.open().
+  // file_iframe_sandbox_e_if10.html contains file_iframe_sandbox_e_if9.html which contains
+  // file_iframe_sandbox_e_if11.html which navigates top.
+  window.open("file_iframe_sandbox_e_if10.html");
+
+  // passes if good, fails if bad
+  // 24) iframe with sandbox='allow-scripts' can NOT navigate top with window.open().
+  // file_iframe_sandbox_e_if12.html contains file_iframe_sandbox_e_if14.html which navigates top.
+  window.open("file_iframe_sandbox_e_if12.html");
+
+  // passes if good, fails if bad
+  // 25) iframe with sandbox='allow-scripts' nested inside an iframe with
+  // 'allow-top-navigation allow-scripts' can NOT navigate top, with window.open(..., "_top").
+  // file_iframe_sandbox_e_if13.html contains file_iframe_sandbox_e_if12.html which contains
+  // file_iframe_sandbox_e_if14.html which navigates top.
+  window.open("file_iframe_sandbox_e_if13.html");
+
+  // passes if good, fails if bad
+  // 26) iframe with sandbox='allow-scripts' should not be able to navigate top using its real name
+  // (not with _top e.g. window.open(..., "topname")) as allow-top-navigation is not specified.
+  // file_iframe_sandbox_e_if15.html contains file_iframe_sandbox_e_if16.html, which
+  // attempts to navigate top by name using window.open().
+  window.open("file_iframe_sandbox_e_if15.html");
+}
+
+addLoadEvent(doTest);
+
+window.modified_if_8 = false;
+
+function reload_if_8() {
+  var if_8 = document.getElementById('if_8');
+  if_8.src = 'file_iframe_sandbox_d_if8.html?onreload';
+}
+
+function modify_if_8() {
+  // If this is the second time this has been called
+  // that's a failed test (allow-same-origin was removed
+  // the first time).
+  if (window.modified_if_8) {
+    ok_wrapper(false, "an sandboxed iframe from which 'allow-same-origin' was removed should not be able to access its parent");
+
+    // need to return here since we end up in an infinite loop otherwise
+    return;
+  }
+
+  var if_8 = document.getElementById('if_8');
+  window.modified_if_8 = true;
+
+  if_8.sandbox = 'allow-scripts';
+  sendMouseEvent({type:'click'}, 'a_button');
+}
+
+window.modified_if_9 = false;
+
+function reload_if_9() {
+  var if_9 = document.getElementById('if_9');
+  if_9.src = 'file_iframe_sandbox_d_if9.html';
+}
+
+function modify_if_9() {
+  // If this is the second time this has been called
+  // that's a failed test (allow-scripts was removed
+  // the first time).
+  if (window.modified_if_9) {
+    ok_wrapper(false, "an sandboxed iframe from which 'allow-scripts' should be removed should not be able to access its parent via a script", false);
+
+    // need to return here since we end up in an infinite loop otherwise
+    return;
+  }
+
+  var if_9 = document.getElementById('if_9');
+  window.modified_if_9 = true;
+
+  if_9.sandbox = 'allow-same-origin';
+
+  sendMouseEvent({type:'click'}, 'a_button2');
+  testAttempted();
+}
+
+var firstPrincipal = "";
+var secondPrincipal;
+
+function doIf10TestPart1() {
+  if (firstPrincipal != "")
+    return;
+
+  // use SpecialPowers to get the principal of if_10.
+  // NB: We stringify here and below because special-powers wrapping doesn't
+  // preserve identity.
+  var if_10 = document.getElementById('if_10');
+  firstPrincipal = SpecialPowers.wrap(if_10).contentDocument.nodePrincipal.origin;
+  if_10.src = 'file_iframe_sandbox_d_if10.html';
+}
+
+function doIf10TestPart2() {
+  var if_10 = document.getElementById('if_10');
+  // use SpecialPowers to get the principal of if_10
+  secondPrincipal = SpecialPowers.wrap(if_10).contentDocument.nodePrincipal.origin;
+  ok_wrapper(firstPrincipal != secondPrincipal, "documents should NOT have the same principal if they are sandboxed without" +
+    " allow-same-origin and the first document is navigated to the second");
+}
+</script>
+<body onunload="checkTestsFinished()">
+<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=341604">Mozilla Bug 341604</a> - Implement HTML5 sandbox attribute for IFRAMEs
+<p id="display"></p>
+<div id="content">
+<iframe sandbox="allow-scripts" id="if_1" src="file_iframe_sandbox_d_if1.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_2" src="file_iframe_sandbox_d_if2.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_3" src="file_iframe_sandbox_d_if3.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts allow-same-origin" id="if_5" src="file_iframe_sandbox_d_if5.html" height="10" width="10"></iframe>
+<iframe id="if_sibling" name="if_sibling" src="file_iframe_sandbox_navigation_start.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_6" src="file_iframe_sandbox_d_if6.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-same-origin allow-scripts" id="if_8" src="file_iframe_sandbox_d_if8.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-same-origin allow-scripts" id="if_9" src="file_iframe_sandbox_d_if9.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_10" src="file_iframe_sandbox_navigation_start.html" onload='doIf10TestPart1()' height="10" width="10"></iframe>
+<iframe sandbox="allow-same-origin allow-scripts allow-top-navigation" id="if_14" src="file_iframe_sandbox_d_if14.html" height="10" width="10"></iframe>
+<iframe id="if_15" name="if_parent" src="file_iframe_sandbox_d_if15.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_17" src="file_iframe_sandbox_d_if17.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_18" src="file_iframe_sandbox_d_if18.html" height="10" width="10"></iframe>
+<iframe sandbox="allow-scripts" id="if_19" src="file_iframe_sandbox_d_if19.html" height="10" width="10"></iframe>
+<iframe id="if_21" name="if_parent2" src="file_iframe_sandbox_d_if21.html" height="10" width="10"></iframe>
+</div>
+<input type='button' id="a_button" onclick='reload_if_8()'>
+<input type='button' id="a_button2" onclick='reload_if_9()'>
+</body>
+</html>
copy from content/media/test/bug461281.ogg
copy to content/html/content/test/wakelock.ogg
--- a/content/media/AudioNodeStream.cpp
+++ b/content/media/AudioNodeStream.cpp
@@ -48,20 +48,19 @@ AudioNodeStream::SetStreamTimeParameter(
   MOZ_ASSERT(this);
   GraphImpl()->AppendMessage(new Message(this, aIndex, aRelativeToStream, aStreamTime));
 }
 
 void
 AudioNodeStream::SetStreamTimeParameterImpl(uint32_t aIndex, MediaStream* aRelativeToStream,
                                             double aStreamTime)
 {
-  StreamTime streamTime = std::max<MediaTime>(0, SecondsToMediaTime(aStreamTime));
-  GraphTime graphTime = aRelativeToStream->StreamTimeToGraphTime(streamTime);
-  StreamTime thisStreamTime = GraphTimeToStreamTimeOptimistic(graphTime);
-  TrackTicks ticks = TimeToTicksRoundUp(IdealAudioRate(), thisStreamTime);
+  TrackTicks ticks =
+      WebAudioUtils::ConvertDestinationStreamTimeToSourceStreamTime(
+          aStreamTime, this, aRelativeToStream);
   mEngine->SetStreamTimeParameter(aIndex, ticks);
 }
 
 void
 AudioNodeStream::SetDoubleParameter(uint32_t aIndex, double aValue)
 {
   class Message : public ControlMessage {
   public:
@@ -277,17 +276,18 @@ AudioNodeStream::ObtainInputBlock(AudioC
     outputChannelCount = std::min(outputChannelCount, mNumberOfInputChannels);
     break;
   case ChannelCountMode::Max:
     // Nothing to do here, just shut up the compiler warning.
     break;
   }
 
   uint32_t inputChunkCount = inputChunks.Length();
-  if (inputChunkCount == 0) {
+  if (inputChunkCount == 0 ||
+      (inputChunkCount == 1 && inputChunks[0]->mChannelData.Length() == 0)) {
     aTmpChunk.SetNull(WEBAUDIO_BLOCK_SIZE);
     return;
   }
 
   if (inputChunkCount == 1 &&
       inputChunks[0]->mChannelData.Length() == outputChannelCount) {
     aTmpChunk = *inputChunks[0];
     return;
--- a/content/media/DOMMediaStream.cpp
+++ b/content/media/DOMMediaStream.cpp
@@ -18,17 +18,28 @@ using namespace mozilla::dom;
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMMediaStream)
   NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
   NS_INTERFACE_MAP_ENTRY(nsISupports)
   NS_INTERFACE_MAP_ENTRY(nsIDOMMediaStream)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMMediaStream)
 NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMMediaStream)
-NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(DOMMediaStream, mWindow, mTracks)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMMediaStream)
+  tmp->Destroy();
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mWindow)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK(mTracks)
+  NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
+NS_IMPL_CYCLE_COLLECTION_UNLINK_END
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMMediaStream)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mWindow)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTracks)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
+NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(DOMMediaStream)
 
 NS_IMPL_ISUPPORTS_INHERITED1(DOMLocalMediaStream, DOMMediaStream,
                              nsIDOMLocalMediaStream)
 
 class DOMMediaStream::StreamListener : public MediaStreamListener {
 public:
   StreamListener(DOMMediaStream* aStream)
     : mStream(aStream)
@@ -97,41 +108,54 @@ public:
   }
 
 private:
   // These fields may only be accessed on the main thread
   DOMMediaStream* mStream;
 };
 
 DOMMediaStream::DOMMediaStream()
-  : mStream(nullptr), mHintContents(0)
+  : mLogicalStreamStartTime(0),
+    mStream(nullptr), mHintContents(0), mTrackTypesAvailable(0),
+    mNotifiedOfMediaStreamGraphShutdown(false)
 {
   SetIsDOMBinding();
 }
 
 DOMMediaStream::~DOMMediaStream()
 {
+  Destroy();
+}
+
+void
+DOMMediaStream::Destroy()
+{
   if (mListener) {
     mListener->Forget();
+    mListener = nullptr;
   }
   if (mStream) {
     mStream->Destroy();
+    mStream = nullptr;
   }
 }
 
 JSObject*
 DOMMediaStream::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope)
 {
   return dom::MediaStreamBinding::Wrap(aCx, aScope, this);
 }
 
 double
 DOMMediaStream::CurrentTime()
 {
-  return mStream ? MediaTimeToSeconds(mStream->GetCurrentTime()) : 0.0;
+  if (!mStream) {
+    return 0.0;
+  }
+  return MediaTimeToSeconds(mStream->GetCurrentTime() - mLogicalStreamStartTime);
 }
 
 void
 DOMMediaStream::GetAudioTracks(nsTArray<nsRefPtr<AudioStreamTrack> >& aTracks)
 {
   for (uint32_t i = 0; i < mTracks.Length(); ++i) {
     AudioStreamTrack* t = mTracks[i]->AsAudioStreamTrack();
     if (t) {
@@ -153,26 +177,26 @@ DOMMediaStream::GetVideoTracks(nsTArray<
 
 bool
 DOMMediaStream::IsFinished()
 {
   return !mStream || mStream->IsFinished();
 }
 
 void
-DOMMediaStream::InitSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
+DOMMediaStream::InitSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents)
 {
   mWindow = aWindow;
   SetHintContents(aHintContents);
   MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
   InitStreamCommon(gm->CreateSourceStream(this));
 }
 
 void
-DOMMediaStream::InitTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
+DOMMediaStream::InitTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents)
 {
   mWindow = aWindow;
   SetHintContents(aHintContents);
   MediaStreamGraph* gm = MediaStreamGraph::GetInstance();
   InitStreamCommon(gm->CreateTrackUnionStream(this));
 }
 
 void
@@ -181,25 +205,25 @@ DOMMediaStream::InitStreamCommon(MediaSt
   mStream = aStream;
 
   // Setup track listener
   mListener = new StreamListener(this);
   aStream->AddListener(mListener);
 }
 
 already_AddRefed<DOMMediaStream>
-DOMMediaStream::CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
+DOMMediaStream::CreateSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents)
 {
   nsRefPtr<DOMMediaStream> stream = new DOMMediaStream();
   stream->InitSourceStream(aWindow, aHintContents);
   return stream.forget();
 }
 
 already_AddRefed<DOMMediaStream>
-DOMMediaStream::CreateTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
+DOMMediaStream::CreateTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents)
 {
   nsRefPtr<DOMMediaStream> stream = new DOMMediaStream();
   stream->InitTrackUnionStream(aWindow, aHintContents);
   return stream.forget();
 }
 
 bool
 DOMMediaStream::CombineWithPrincipal(nsIPrincipal* aPrincipal)
@@ -209,26 +233,30 @@ DOMMediaStream::CombineWithPrincipal(nsI
 
 MediaStreamTrack*
 DOMMediaStream::CreateDOMTrack(TrackID aTrackID, MediaSegment::Type aType)
 {
   MediaStreamTrack* track;
   switch (aType) {
   case MediaSegment::AUDIO:
     track = new AudioStreamTrack(this, aTrackID);
+    mTrackTypesAvailable |= HINT_CONTENTS_AUDIO;
     break;
   case MediaSegment::VIDEO:
     track = new VideoStreamTrack(this, aTrackID);
+    mTrackTypesAvailable |= HINT_CONTENTS_VIDEO;
     break;
   default:
     MOZ_NOT_REACHED("Unhandled track type");
     return nullptr;
   }
+  mTracks.AppendElement(track);
 
-  mTracks.AppendElement(track);
+  CheckTracksAvailable();
+
   return track;
 }
 
 MediaStreamTrack*
 DOMMediaStream::GetDOMTrackFor(TrackID aTrackID)
 {
   for (uint32_t i = 0; i < mTracks.Length(); ++i) {
     MediaStreamTrack* t = mTracks[i];
@@ -236,16 +264,54 @@ DOMMediaStream::GetDOMTrackFor(TrackID a
     // a different DOMMediaStream. Ignore those.
     if (t->GetTrackID() == aTrackID && t->GetStream() == this) {
       return t;
     }
   }
   return nullptr;
 }
 
+void
+DOMMediaStream::NotifyMediaStreamGraphShutdown()
+{
+  // No more tracks will ever be added, so just clear these callbacks now
+  // to prevent leaks.
+  mNotifiedOfMediaStreamGraphShutdown = true;
+  mRunOnTracksAvailable.Clear();
+}
+
+void
+DOMMediaStream::OnTracksAvailable(OnTracksAvailableCallback* aRunnable)
+{
+  if (mNotifiedOfMediaStreamGraphShutdown) {
+    // No more tracks will ever be added, so just delete the callback now.
+    delete aRunnable;
+    return;
+  }
+  mRunOnTracksAvailable.AppendElement(aRunnable);
+  CheckTracksAvailable();
+}
+
+void
+DOMMediaStream::CheckTracksAvailable()
+{
+  nsTArray<nsAutoPtr<OnTracksAvailableCallback> > callbacks;
+  callbacks.SwapElements(mRunOnTracksAvailable);
+
+  for (uint32_t i = 0; i < callbacks.Length(); ++i) {
+    OnTracksAvailableCallback* cb = callbacks[i];
+    if (~mTrackTypesAvailable & cb->GetExpectedTracks()) {
+      // Some expected tracks not available yet. Try this callback again later.
+      *mRunOnTracksAvailable.AppendElement() = callbacks[i].forget();
+      continue;
+    }
+    cb->NotifyTracksAvailable(this);
+  }
+}
+
 DOMLocalMediaStream::~DOMLocalMediaStream()
 {
   if (mStream) {
     // Make sure Listeners of this stream know it's going away
     Stop();
   }
 }
 
@@ -259,22 +325,24 @@ void
 DOMLocalMediaStream::Stop()
 {
   if (mStream && mStream->AsSourceStream()) {
     mStream->AsSourceStream()->EndAllTrackAndFinish();
   }
 }
 
 already_AddRefed<DOMLocalMediaStream>
-DOMLocalMediaStream::CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
+DOMLocalMediaStream::CreateSourceStream(nsIDOMWindow* aWindow,
+                                        TrackTypeHints aHintContents)
 {
   nsRefPtr<DOMLocalMediaStream> stream = new DOMLocalMediaStream();
   stream->InitSourceStream(aWindow, aHintContents);
   return stream.forget();
 }
 
 already_AddRefed<DOMLocalMediaStream>
-DOMLocalMediaStream::CreateTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents)
+DOMLocalMediaStream::CreateTrackUnionStream(nsIDOMWindow* aWindow,
+                                            TrackTypeHints aHintContents)
 {
   nsRefPtr<DOMLocalMediaStream> stream = new DOMLocalMediaStream();
   stream->InitTrackUnionStream(aWindow, aHintContents);
   return stream.forget();
 }
--- a/content/media/DOMMediaStream.h
+++ b/content/media/DOMMediaStream.h
@@ -7,16 +7,17 @@
 #define NSDOMMEDIASTREAM_H_
 
 #include "nsIDOMMediaStream.h"
 #include "nsCycleCollectionParticipant.h"
 #include "nsIPrincipal.h"
 #include "nsWrapperCache.h"
 #include "nsIDOMWindow.h"
 #include "StreamBuffer.h"
+#include "nsIRunnable.h"
 
 class nsXPCClassInfo;
 
 // GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
 // GetTickCount() and conflicts with NS_DECL_NSIDOMMEDIASTREAM, containing
 // currentTime getter.
 #ifdef GetCurrentTime
 #undef GetCurrentTime
@@ -44,16 +45,18 @@ class DOMMediaStream : public nsIDOMMedi
                        public nsWrapperCache
 {
   friend class DOMLocalMediaStream;
   typedef dom::MediaStreamTrack MediaStreamTrack;
   typedef dom::AudioStreamTrack AudioStreamTrack;
   typedef dom::VideoStreamTrack VideoStreamTrack;
 
 public:
+  typedef uint8_t TrackTypeHints;
+
   DOMMediaStream();
   virtual ~DOMMediaStream();
 
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMMediaStream)
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
 
   nsIDOMWindow* GetParentObject() const
   {
@@ -79,64 +82,106 @@ public:
    * Indicate that data will be contributed to this stream from origin aPrincipal.
    * If aPrincipal is null, this is ignored. Otherwise, from now on the contents
    * of this stream can only be accessed by principals that subsume aPrincipal.
    * Returns true if the stream's principal changed.
    */
   bool CombineWithPrincipal(nsIPrincipal* aPrincipal);
 
   /**
+   * Called when this stream's MediaStreamGraph has been shut down. Normally
+   * MSGs are only shut down when all streams have been removed, so this
+   * will only be called during a forced shutdown due to application exit.
+   */
+  void NotifyMediaStreamGraphShutdown();
+
+  // Indicate what track types we eventually expect to add to this stream
+  enum {
+    HINT_CONTENTS_AUDIO = 1 << 0,
+    HINT_CONTENTS_VIDEO = 1 << 1
+  };
+  TrackTypeHints GetHintContents() const { return mHintContents; }
+  void SetHintContents(TrackTypeHints aHintContents) { mHintContents = aHintContents; }
+
+  /**
    * Create an nsDOMMediaStream whose underlying stream is a SourceMediaStream.
    */
   static already_AddRefed<DOMMediaStream>
-  CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents);
-
-  // Hints to tell the SDP generator about whether this
-  // MediaStream probably has audio and/or video
-  enum {
-    HINT_CONTENTS_AUDIO = 0x00000001U,
-    HINT_CONTENTS_VIDEO = 0x00000002U
-  };
-  uint32_t GetHintContents() const { return mHintContents; }
-  void SetHintContents(uint32_t aHintContents) { mHintContents = aHintContents; }
+  CreateSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents);
 
   /**
    * Create an nsDOMMediaStream whose underlying stream is a TrackUnionStream.
    */
   static already_AddRefed<DOMMediaStream>
-  CreateTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents = 0);
+  CreateTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents = 0);
 
-  // Notifications from StreamListener
+  void SetLogicalStreamStartTime(StreamTime aTime)
+  {
+    mLogicalStreamStartTime = aTime;
+  }
+
+  // Notifications from StreamListener.
+  // CreateDOMTrack should only be called when it's safe to run script.
   MediaStreamTrack* CreateDOMTrack(TrackID aTrackID, MediaSegment::Type aType);
   MediaStreamTrack* GetDOMTrackFor(TrackID aTrackID);
 
+  class OnTracksAvailableCallback {
+  public:
+    OnTracksAvailableCallback(uint8_t aExpectedTracks = 0)
+      : mExpectedTracks(aExpectedTracks) {}
+    virtual ~OnTracksAvailableCallback() {}
+    virtual void NotifyTracksAvailable(DOMMediaStream* aStream) = 0;
+    TrackTypeHints GetExpectedTracks() { return mExpectedTracks; }
+    void SetExpectedTracks(TrackTypeHints aExpectedTracks) { mExpectedTracks = aExpectedTracks; }
+  private:
+    TrackTypeHints mExpectedTracks;
+  };
+  // When one track of the appropriate type has been added for each bit set
+  // in aCallback->GetExpectedTracks(), run aCallback->NotifyTracksAvailable.
+  // It is allowed to do anything, including run script.
+  // aCallback may run immediately during this call if tracks are already
+  // available!
+  // We only care about track additions, we'll fire the notification even if
+  // some of the tracks have been removed.
+  // Takes ownership of aCallback.
+  void OnTracksAvailable(OnTracksAvailableCallback* aCallback);
+
 protected:
-  void InitSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents);
-  void InitTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents);
+  void Destroy();
+  void InitSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents);
+  void InitTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents);
   void InitStreamCommon(MediaStream* aStream);
+  void CheckTracksAvailable();
 
   class StreamListener;
   friend class StreamListener;
 
+  // StreamTime at which the currentTime attribute would return 0.
+  StreamTime mLogicalStreamStartTime;
+
   // We need this to track our parent object.
   nsCOMPtr<nsIDOMWindow> mWindow;
 
   // MediaStream is owned by the graph, but we tell it when to die, and it won't
   // die until we let it.
   MediaStream* mStream;
   // Principal identifying who may access the contents of this stream.
   // If null, this stream can be used by anyone because it has no content yet.
   nsCOMPtr<nsIPrincipal> mPrincipal;
 
   nsAutoTArray<nsRefPtr<MediaStreamTrack>,2> mTracks;
   nsRefPtr<StreamListener> mListener;
 
-  // tells the SDP generator about whether this
-  // MediaStream probably has audio and/or video
-  uint32_t mHintContents;
+  nsTArray<nsAutoPtr<OnTracksAvailableCallback> > mRunOnTracksAvailable;
+
+  // Indicate what track types we eventually expect to add to this stream
+  uint8_t mHintContents;
+  // Indicate what track types have been added to this stream
+  uint8_t mTrackTypesAvailable;
+  bool mNotifiedOfMediaStreamGraphShutdown;
 };
 
 class DOMLocalMediaStream : public DOMMediaStream,
                             public nsIDOMLocalMediaStream
 {
 public:
   DOMLocalMediaStream() {}
   virtual ~DOMLocalMediaStream();
@@ -147,20 +192,20 @@ public:
                                JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
   virtual void Stop();
 
   /**
    * Create an nsDOMLocalMediaStream whose underlying stream is a SourceMediaStream.
    */
   static already_AddRefed<DOMLocalMediaStream>
-  CreateSourceStream(nsIDOMWindow* aWindow, uint32_t aHintContents);
+  CreateSourceStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents);
 
   /**
    * Create an nsDOMLocalMediaStream whose underlying stream is a TrackUnionStream.
    */
   static already_AddRefed<DOMLocalMediaStream>
-  CreateTrackUnionStream(nsIDOMWindow* aWindow, uint32_t aHintContents = 0);
+  CreateTrackUnionStream(nsIDOMWindow* aWindow, TrackTypeHints aHintContents = 0);
 };
 
 }
 
 #endif /* NSDOMMEDIASTREAM_H_ */
--- a/content/media/DecoderTraits.cpp
+++ b/content/media/DecoderTraits.cpp
@@ -34,17 +34,17 @@
 #include "GStreamerReader.h"
 #endif
 #ifdef MOZ_MEDIA_PLUGINS
 #include "MediaPluginHost.h"
 #include "MediaPluginDecoder.h"
 #include "MediaPluginReader.h"
 #include "MediaPluginHost.h"
 #endif
-#ifdef MOZ_WIDGET_GONK
+#ifdef MOZ_OMX_DECODER
 #include "MediaOmxDecoder.h"
 #include "MediaOmxReader.h"
 #include "nsIPrincipal.h"
 #include "mozilla/dom/HTMLMediaElement.h"
 #endif
 #ifdef MOZ_DASH
 #include "DASHDecoder.h"
 #endif
@@ -191,17 +191,17 @@ IsGStreamerSupportedType(const nsACStrin
   if (IsOggType(aMimeType) && !Preferences::GetBool("media.prefer-gstreamer", false))
     return false;
 #endif
 
   return GStreamerDecoder::CanHandleMediaType(aMimeType, nullptr);
 }
 #endif
 
-#ifdef MOZ_WIDGET_GONK
+#ifdef MOZ_OMX_DECODER
 static const char* const gOmxTypes[7] = {
   "audio/mpeg",
   "audio/mp4",
   "audio/amr",
   "video/mp4",
   "video/3gpp",
   "video/quicktime",
   nullptr
@@ -329,17 +329,17 @@ DecoderTraits::CanHandleMediaType(const 
 #ifdef MOZ_GSTREAMER
   if (GStreamerDecoder::CanHandleMediaType(nsDependentCString(aMIMEType),
                                            aHaveRequestedCodecs ? &aRequestedCodecs : nullptr)) {
     if (aHaveRequestedCodecs)
       return CANPLAY_YES;
     return CANPLAY_MAYBE;
   }
 #endif
-#ifdef MOZ_WIDGET_GONK
+#ifdef MOZ_OMX_DECODER
   if (IsOmxSupportedType(nsDependentCString(aMIMEType))) {
     codecList = gH264Codecs;
     result = CANPLAY_MAYBE;
   }
 #endif
 #ifdef MOZ_WMF
   if (WMFDecoder::GetSupportedCodecs(nsDependentCString(aMIMEType), &codecList)) {
     result = CANPLAY_MAYBE;
@@ -395,17 +395,17 @@ DecoderTraits::CreateDecoder(const nsACS
     decoder = new OggDecoder();
   }
 #endif
 #ifdef MOZ_WAVE
   if (IsWaveType(aType)) {
     decoder = new WaveDecoder();
   }
 #endif
-#ifdef MOZ_WIDGET_GONK
+#ifdef MOZ_OMX_DECODER
   if (IsOmxSupportedType(aType)) {
     // AMR audio is enabled for MMS, but we are discouraging Web and App
     // developers from using AMR, thus we only allow AMR to be played on WebApps.
     if (aType.EqualsASCII("audio/amr") || aType.EqualsASCII("video/3gpp")) {
       HTMLMediaElement* element = aOwner->GetMediaElement();
       if (!element) {
         return nullptr;
       }
@@ -467,17 +467,17 @@ MediaDecoderReader* DecoderTraits::Creat
     decoderReader = new OggReader(aDecoder);
   } else
 #endif
 #ifdef MOZ_WAVE
   if (IsWaveType(aType)) {
     decoderReader = new WaveReader(aDecoder);
   } else
 #endif
-#ifdef MOZ_WIDGET_GONK
+#ifdef MOZ_OMX_DECODER
   if (IsOmxSupportedType(aType)) {
     decoderReader = new MediaOmxReader(aDecoder);
   } else
 #endif
 #ifdef MOZ_MEDIA_PLUGINS
   if (MediaDecoder::IsMediaPluginsEnabled() &&
       GetMediaPluginHost()->FindDecoder(aType, nullptr)) {
     decoderReader = new MediaPluginReader(aDecoder, aType);
@@ -503,17 +503,17 @@ MediaDecoderReader* DecoderTraits::Creat
 
 /* static */
 bool DecoderTraits::IsSupportedInVideoDocument(const nsACString& aType)
 {
   return
 #ifdef MOZ_OGG
     IsOggType(aType) ||
 #endif
-#ifdef MOZ_WIDGET_GONK
+#ifdef MOZ_OMX_DECODER
     IsOmxSupportedType(aType) ||
 #endif
 #ifdef MOZ_WEBM
     IsWebMType(aType) ||
 #endif
 #ifdef MOZ_DASH
     IsDASHMPDType(aType) ||
 #endif
--- a/content/media/MediaDecoder.cpp
+++ b/content/media/MediaDecoder.cpp
@@ -1652,17 +1652,17 @@ MediaDecoder::IsWebMEnabled()
 #ifdef MOZ_GSTREAMER
 bool
 MediaDecoder::IsGStreamerEnabled()
 {
   return Preferences::GetBool("media.gstreamer.enabled");
 }
 #endif
 
-#ifdef MOZ_WIDGET_GONK
+#ifdef MOZ_OMX_DECODER
 bool
 MediaDecoder::IsOmxEnabled()
 {
   return Preferences::GetBool("media.omx.enabled", false);
 }
 #endif
 
 #ifdef MOZ_MEDIA_PLUGINS
--- a/content/media/MediaDecoder.h
+++ b/content/media/MediaDecoder.h
@@ -754,17 +754,17 @@ public:
 #ifdef MOZ_WEBM
   static bool IsWebMEnabled();
 #endif
 
 #ifdef MOZ_GSTREAMER
   static bool IsGStreamerEnabled();
 #endif
 
-#ifdef MOZ_WIDGET_GONK
+#ifdef MOZ_OMX_DECODER
   static bool IsOmxEnabled();
 #endif
 
 #ifdef MOZ_MEDIA_PLUGINS
   static bool IsMediaPluginsEnabled();
 #endif
 
 #ifdef MOZ_DASH
--- a/content/media/MediaDecoderReader.cpp
+++ b/content/media/MediaDecoderReader.cpp
@@ -295,17 +295,17 @@ VideoData* VideoData::CreateFromImage(Vi
                                        aEndTime,
                                        aKeyframe,
                                        aTimecode,
                                        aInfo.mDisplay));
   v->mImage = aImage;
   return v.forget();
 }
 
-#ifdef MOZ_WIDGET_GONK
+#ifdef MOZ_OMX_DECODER
 VideoData* VideoData::Create(VideoInfo& aInfo,
                              ImageContainer* aContainer,
                              int64_t aOffset,
                              int64_t aTime,
                              int64_t aEndTime,
                              mozilla::layers::GraphicBufferLocked* aBuffer,
                              bool aKeyframe,
                              int64_t aTimecode,
@@ -361,17 +361,17 @@ VideoData* VideoData::Create(VideoInfo& 
 
   data.mPicSize = gfxIntSize(aPicture.width, aPicture.height);
   data.mGraphicBuffer = aBuffer;
 
   videoImage->SetData(data);
 
   return v.forget();
 }
-#endif  // MOZ_WIDGET_GONK
+#endif  // MOZ_OMX_DECODER
 
 void* MediaDecoderReader::VideoQueueMemoryFunctor::operator()(void* anObject) {
   const VideoData* v = static_cast<const VideoData*>(anObject);
   if (!v->mImage) {
     return nullptr;
   }
   NS_ASSERTION(v->mImage->GetFormat() == PLANAR_YCBCR,
                "Wrong format?");
--- a/content/media/MediaDecoderStateMachine.cpp
+++ b/content/media/MediaDecoderStateMachine.cpp
@@ -409,17 +409,17 @@ MediaDecoderStateMachine::MediaDecoderSt
     mRealTime = false;
 
   mBufferingWait = mRealTime ? 0 : BUFFERING_WAIT_S;
   mLowDataThresholdUsecs = mRealTime ? 0 : LOW_DATA_THRESHOLD_USECS;
 
   // If we've got more than mAmpleVideoFrames decoded video frames waiting in
   // the video queue, we will not decode any more video frames until some have
   // been consumed by the play state machine thread.
-#if defined(MOZ_WIDGET_GONK) || defined(MOZ_MEDIA_PLUGINS)
+#if defined(MOZ_OMX_DECODER) || defined(MOZ_MEDIA_PLUGINS)
   // On B2G and Android this is decided by a similar value which varies for
   // each OMX decoder |OMX_PARAM_PORTDEFINITIONTYPE::nBufferCountMin|. This
   // number must be less than the OMX equivalent or gecko will think it is
   // chronically starved of video frames. All decoders seen so far have a value
   // of at least 4.
   mAmpleVideoFrames = Preferences::GetUint("media.video-queue.default-size", 3);
 #else
   mAmpleVideoFrames = Preferences::GetUint("media.video-queue.default-size", 10);
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -17,16 +17,17 @@
 #include "VideoUtils.h"
 #include "mozilla/Attributes.h"
 #include "TrackUnionStream.h"
 #include "ImageContainer.h"
 #include "AudioChannelCommon.h"
 #include "AudioNodeEngine.h"
 #include "AudioNodeStream.h"
 #include <algorithm>
+#include "DOMMediaStream.h"
 
 using namespace mozilla::layers;
 using namespace mozilla::dom;
 
 namespace mozilla {
 
 #ifdef PR_LOGGING
 PRLogModuleInfo* gMediaStreamGraphLog;
@@ -670,16 +671,18 @@ MediaStreamGraphImpl::NotifyHasCurrentDa
     aStream->mNotifiedHasCurrentData = true;
   }
 }
 
 void
 MediaStreamGraphImpl::CreateOrDestroyAudioStreams(GraphTime aAudioOutputStartTime,
                                                   MediaStream* aStream)
 {
+  MOZ_ASSERT(mRealtime, "Should only attempt to create audio streams in real-time mode");
+
   nsAutoTArray<bool,2> audioOutputStreamsFound;
   for (uint32_t i = 0; i < aStream->mAudioOutputStreams.Length(); ++i) {
     audioOutputStreamsFound.AppendElement(false);
   }
 
   if (!aStream->mAudioOutputs.IsEmpty()) {
     for (StreamBuffer::TrackIter tracks(aStream->GetStreamBuffer(), MediaSegment::AUDIO);
          !tracks.IsEnded(); tracks.Next()) {
@@ -726,16 +729,18 @@ MediaStreamGraphImpl::CreateOrDestroyAud
     }
   }
 }
 
 void
 MediaStreamGraphImpl::PlayAudio(MediaStream* aStream,
                                 GraphTime aFrom, GraphTime aTo)
 {
+  MOZ_ASSERT(mRealtime, "Should only attempt to play audio in realtime mode");
+
   if (aStream->mAudioOutputStreams.IsEmpty()) {
     return;
   }
 
   // When we're playing multiple copies of this stream at the same time, they're
   // perfectly correlated so adding volumes is the right thing to do.
   float volume = 0.0f;
   for (uint32_t i = 0; i < aStream->mAudioOutputs.Length(); ++i) {
@@ -799,16 +804,18 @@ MediaStreamGraphImpl::PlayAudio(MediaStr
       t = end;
     }
   }
 }
 
 void
 MediaStreamGraphImpl::PlayVideo(MediaStream* aStream)
 {
+  MOZ_ASSERT(mRealtime, "Should only attempt to play video in realtime mode");
+
   if (aStream->mVideoOutputs.IsEmpty())
     return;
 
   // Display the next frame a bit early. This is better than letting the current
   // frame be displayed for too long.
   GraphTime framePosition = mCurrentTime + MEDIA_GRAPH_TARGET_PERIOD_MS;
   NS_ASSERTION(framePosition >= aStream->mBufferStartTime, "frame position before buffer?");
   StreamTime frameBufferTime = GraphTimeToStreamTime(aStream, framePosition);
@@ -1004,71 +1011,76 @@ MediaStreamGraphImpl::RunThread()
             ps->ProduceOutput(prevComputedTime, mStateComputedTime);
             NS_ASSERTION(stream->mBuffer.GetEnd() >=
                          GraphTimeToStreamTime(stream, mStateComputedTime),
                        "Stream did not produce enough data");
           }
         }
       }
       NotifyHasCurrentData(stream);
-      CreateOrDestroyAudioStreams(prevComputedTime, stream);
-      PlayAudio(stream, prevComputedTime, mStateComputedTime);
-      audioStreamsActive += stream->mAudioOutputStreams.Length();
-      PlayVideo(stream);
+      if (mRealtime) {
+        // Only playback audio and video in real-time mode
+        CreateOrDestroyAudioStreams(prevComputedTime, stream);
+        PlayAudio(stream, prevComputedTime, mStateComputedTime);
+        audioStreamsActive += stream->mAudioOutputStreams.Length();
+        PlayVideo(stream);
+      }
       SourceMediaStream* is = stream->AsSourceStream();
       if (is) {
         UpdateBufferSufficiencyState(is);
       }
       GraphTime end;
       if (!stream->mBlocked.GetAt(mCurrentTime, &end) || end < GRAPH_TIME_MAX) {
         allBlockedForever = false;
       }
     }
     if (ensureNextIteration || !allBlockedForever || audioStreamsActive > 0) {
       EnsureNextIteration();
     }
 
     // Send updates to the main thread and wait for the next control loop
     // iteration.
     {
-      // Not using MonitorAutoLock since we need to unlock in a way
-      // that doesn't match lexical scopes.
       MonitorAutoLock lock(mMonitor);
       PrepareUpdatesToMainThreadState();
       if (mForceShutDown || (IsEmpty() && mMessageQueue.IsEmpty())) {
         // Enter shutdown mode. The stable-state handler will detect this
         // and complete shutdown. Destroy any streams immediately.
         LOG(PR_LOG_DEBUG, ("MediaStreamGraph %p waiting for main thread cleanup", this));
         // Commit to shutting down this graph object.
         mLifecycleState = LIFECYCLE_WAITING_FOR_MAIN_THREAD_CLEANUP;
         // No need to Destroy streams here. The main-thread owner of each
         // stream is responsible for calling Destroy them.
         return;
       }
 
-      PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
-      TimeStamp now = TimeStamp::Now();
-      if (mNeedAnotherIteration) {
-        int64_t timeoutMS = MEDIA_GRAPH_TARGET_PERIOD_MS -
-          int64_t((now - mCurrentTimeStamp).ToMilliseconds());
-        // Make sure timeoutMS doesn't overflow 32 bits by waking up at
-        // least once a minute, if we need to wake up at all
-        timeoutMS = std::max<int64_t>(0, std::min<int64_t>(timeoutMS, 60*1000));
-        timeout = PR_MillisecondsToInterval(uint32_t(timeoutMS));
-        LOG(PR_LOG_DEBUG, ("Waiting for next iteration; at %f, timeout=%f",
-                           (now - mInitialTimeStamp).ToSeconds(), timeoutMS/1000.0));
-        mWaitState = WAITSTATE_WAITING_FOR_NEXT_ITERATION;
-      } else {
-        mWaitState = WAITSTATE_WAITING_INDEFINITELY;
-      }
-      if (timeout > 0) {
-        mMonitor.Wait(timeout);
-        LOG(PR_LOG_DEBUG, ("Resuming after timeout; at %f, elapsed=%f",
-                           (TimeStamp::Now() - mInitialTimeStamp).ToSeconds(),
-                           (TimeStamp::Now() - now).ToSeconds()));
+      // No need to wait in non-realtime mode, just churn through the input as soon
+      // as possible.
+      if (mRealtime) {
+        PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
+        TimeStamp now = TimeStamp::Now();
+        if (mNeedAnotherIteration) {
+          int64_t timeoutMS = MEDIA_GRAPH_TARGET_PERIOD_MS -
+            int64_t((now - mCurrentTimeStamp).ToMilliseconds());
+          // Make sure timeoutMS doesn't overflow 32 bits by waking up at
+          // least once a minute, if we need to wake up at all
+          timeoutMS = std::max<int64_t>(0, std::min<int64_t>(timeoutMS, 60*1000));
+          timeout = PR_MillisecondsToInterval(uint32_t(timeoutMS));
+          LOG(PR_LOG_DEBUG, ("Waiting for next iteration; at %f, timeout=%f",
+                             (now - mInitialTimeStamp).ToSeconds(), timeoutMS/1000.0));
+          mWaitState = WAITSTATE_WAITING_FOR_NEXT_ITERATION;
+        } else {
+          mWaitState = WAITSTATE_WAITING_INDEFINITELY;
+        }
+        if (timeout > 0) {
+          mMonitor.Wait(timeout);
+          LOG(PR_LOG_DEBUG, ("Resuming after timeout; at %f, elapsed=%f",
+                             (TimeStamp::Now() - mInitialTimeStamp).ToSeconds(),
+                             (TimeStamp::Now() - now).ToSeconds()));
+        }
       }
       mWaitState = WAITSTATE_RUNNING;
       mNeedAnotherIteration = false;
       messageQueue.SwapElements(mMessageQueue);
     }
   }
 }
 
@@ -1132,23 +1144,33 @@ private:
 
 class MediaStreamGraphShutDownRunnable : public nsRunnable {
 public:
   MediaStreamGraphShutDownRunnable(MediaStreamGraphImpl* aGraph) : mGraph(aGraph) {}
   NS_IMETHOD Run()
   {
     NS_ASSERTION(mGraph->mDetectedNotRunning,
                  "We should know the graph thread control loop isn't running!");
+
+    mGraph->ShutdownThreads();
+
     // mGraph's thread is not running so it's OK to do whatever here
     if (mGraph->IsEmpty()) {
       // mGraph is no longer needed, so delete it. If the graph is not empty
       // then we must be in a forced shutdown and some later AppendMessage will
       // detect that the manager has been emptied, and delete it.
       delete mGraph;
     } else {
+      for (uint32_t i = 0; i < mGraph->mStreams.Length(); ++i) {
+        DOMMediaStream* s = mGraph->mStreams[i]->GetWrapper();
+        if (s) {
+          s->NotifyMediaStreamGraphShutdown();
+        }
+      }
+
       NS_ASSERTION(mGraph->mForceShutDown, "Not in forced shutdown?");
       mGraph->mLifecycleState =
         MediaStreamGraphImpl::LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION;
     }
     return NS_OK;
   }
 private:
   MediaStreamGraphImpl* mGraph;
@@ -1923,29 +1945,30 @@ ProcessedMediaStream::DestroyImpl()
 }
 
 /**
  * We make the initial mCurrentTime nonzero so that zero times can have
  * special meaning if necessary.
  */
 static const int32_t INITIAL_CURRENT_TIME = 1;
 
-MediaStreamGraphImpl::MediaStreamGraphImpl()
+MediaStreamGraphImpl::MediaStreamGraphImpl(bool aRealtime)
   : mCurrentTime(INITIAL_CURRENT_TIME)
   , mStateComputedTime(INITIAL_CURRENT_TIME)
   , mProcessingGraphUpdateIndex(0)
   , mPortCount(0)
   , mMonitor("MediaStreamGraphImpl")
   , mLifecycleState(LIFECYCLE_THREAD_NOT_STARTED)
   , mWaitState(WAITSTATE_RUNNING)
   , mNeedAnotherIteration(false)
   , mForceShutDown(false)
   , mPostedRunInStableStateEvent(false)
   , mDetectedNotRunning(false)
   , mPostedRunInStableState(false)
+  , mRealtime(aRealtime)
 {
 #ifdef PR_LOGGING
   if (!gMediaStreamGraphLog) {
     gMediaStreamGraphLog = PR_NewLogModule("MediaStreamGraph");
   }
 #endif
 
   mCurrentTimeStamp = mInitialTimeStamp = TimeStamp::Now();
@@ -1976,23 +1999,43 @@ MediaStreamGraph::GetInstance()
   NS_ASSERTION(NS_IsMainThread(), "Main thread only");
 
   if (!gGraph) {
     if (!gShutdownObserverRegistered) {
       gShutdownObserverRegistered = true;
       nsContentUtils::RegisterShutdownObserver(new MediaStreamGraphShutdownObserver());
     }
 
-    gGraph = new MediaStreamGraphImpl();
+    gGraph = new MediaStreamGraphImpl(true);
     LOG(PR_LOG_DEBUG, ("Starting up MediaStreamGraph %p", gGraph));
   }
 
   return gGraph;
 }
 
+MediaStreamGraph*
+MediaStreamGraph::CreateNonRealtimeInstance()
+{
+  NS_ASSERTION(NS_IsMainThread(), "Main thread only");
+
+  MediaStreamGraphImpl* graph = new MediaStreamGraphImpl(false);
+  return graph;
+}
+
+void
+MediaStreamGraph::DestroyNonRealtimeInstance(MediaStreamGraph* aGraph)
+{
+  NS_ASSERTION(NS_IsMainThread(), "Main thread only");
+  MOZ_ASSERT(aGraph != gGraph, "Should not destroy the global graph here");
+
+  MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(aGraph);
+  graph->ForceShutDown();
+  delete graph;
+}
+
 SourceMediaStream*
 MediaStreamGraph::CreateSourceStream(DOMMediaStream* aWrapper)
 {
   SourceMediaStream* stream = new SourceMediaStream(aWrapper);
   NS_ADDREF(stream);
   MediaStreamGraphImpl* graph = static_cast<MediaStreamGraphImpl*>(this);
   stream->SetGraphImpl(graph);
   graph->AppendMessage(new CreateMessage(stream));
--- a/content/media/MediaStreamGraph.h
+++ b/content/media/MediaStreamGraph.h
@@ -422,16 +422,22 @@ public:
    * will not be blocked after mStateComputedTime.
    */
   GraphTime StreamTimeToGraphTime(StreamTime aTime);
   bool IsFinishedOnGraphThread() { return mFinished; }
   void FinishOnGraphThread();
 
   bool HasCurrentData() { return mHasCurrentData; }
 
+  DOMMediaStream* GetWrapper()
+  {
+    NS_ASSERTION(NS_IsMainThread(), "Only use DOMMediaStream on main thread");
+    return mWrapper;
+  }
+
 protected:
   virtual void AdvanceTimeVaryingValuesToCurrentTime(GraphTime aCurrentTime, GraphTime aBlockedTime)
   {
     mBufferStartTime += aBlockedTime;
     mGraphUpdateIndices.InsertTimeAtStart(aBlockedTime);
     mGraphUpdateIndices.AdvanceCurrentTime(aCurrentTime);
     mExplicitBlockerCount.AdvanceCurrentTime(aCurrentTime);
 
@@ -876,27 +882,31 @@ protected:
   bool mInCycle;
 };
 
 // Returns ideal audio rate for processing
 inline TrackRate IdealAudioRate() { return 48000; }
 
 /**
  * Initially, at least, we will have a singleton MediaStreamGraph per
- * process.
+ * process.  Each OfflineAudioContext object creates its own MediaStreamGraph
+ * object too.
  */
 class MediaStreamGraph {
 public:
   // We ensure that the graph current time advances in multiples of
   // IdealAudioBlockSize()/IdealAudioRate(). A stream that never blocks
   // and has a track with the ideal audio rate will produce audio in
   // multiples of the block size.
 
   // Main thread only
   static MediaStreamGraph* GetInstance();
+  static MediaStreamGraph* CreateNonRealtimeInstance();
+  static void DestroyNonRealtimeInstance(MediaStreamGraph* aGraph);
+
   // Control API.
   /**
    * Create a stream that a media decoder (or some other source of
    * media data, such as a camera) can write to.
    */
   SourceMediaStream* CreateSourceStream(DOMMediaStream* aWrapper);
   /**
    * Create a stream that will form the union of the tracks of its input
--- a/content/media/MediaStreamGraphImpl.h
+++ b/content/media/MediaStreamGraphImpl.h
@@ -98,21 +98,29 @@ protected:
   MediaStream* mStream;
 };
 
 /**
  * The implementation of a media stream graph. This class is private to this
  * file. It's not in the anonymous namespace because MediaStream needs to
  * be able to friend it.
  *
- * Currently we only have one per process.
+ * Currently we have one global instance per process, and one per each
+ * OfflineAudioContext object.
  */
 class MediaStreamGraphImpl : public MediaStreamGraph {
 public:
-  MediaStreamGraphImpl();
+  /**
+   * Set aRealtime to true in order to create a MediaStreamGraph which provides
+   * support for real-time audio and video.  Set it to false in order to create
+   * a non-realtime instance which just churns through its inputs and produces
+   * output.  Those objects currently only support audio, and are used to
+   * implement OfflineAudioContext.  They do not support MediaStream inputs.
+   */
+  explicit MediaStreamGraphImpl(bool aRealtime);
   ~MediaStreamGraphImpl()
   {
     NS_ASSERTION(IsEmpty(),
                  "All streams should have been destroyed by messages from the main thread");
     LOG(PR_LOG_DEBUG, ("MediaStreamGraph %p destroyed", this));
   }
 
   // Main thread only.
@@ -501,13 +509,18 @@ public:
    * LIFECYCLE_RUNNING, this can be relied on to not change unexpectedly.
    */
   bool mDetectedNotRunning;
   /**
    * True when a stable state runner has been posted to the appshell to run
    * RunInStableState at the next stable state.
    */
   bool mPostedRunInStableState;
+  /**
+   * True when processing real-time audio/video.  False when processing non-realtime
+   * audio.
+   */
+  bool mRealtime;
 };
 
 }
 
 #endif /* MEDIASTREAMGRAPHIMPL_H_ */
--- a/content/media/MediaStreamTrack.h
+++ b/content/media/MediaStreamTrack.h
@@ -26,17 +26,17 @@ class MediaStreamTrack : public nsDOMEve
 public:
   /**
    * aTrackID is the MediaStreamGraph track ID for the track in the
    * MediaStream owned by aStream.
    */
   MediaStreamTrack(DOMMediaStream* aStream, TrackID aTrackID);
   virtual ~MediaStreamTrack();
 
-  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
+  NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaStreamTrack, nsDOMEventTargetHelper)
 
   DOMMediaStream* GetParentObject() const { return mStream; }
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aScope) MOZ_OVERRIDE = 0;
 
   DOMMediaStream* GetStream() const { return mStream; }
   TrackID GetTrackID() const { return mTrackID; }
--- a/content/media/moz.build
+++ b/content/media/moz.build
@@ -27,17 +27,17 @@ if CONFIG['MOZ_DASH']:
 if CONFIG['MOZ_MEDIA_PLUGINS']:
     PARALLEL_DIRS += ['plugins']
 
 if CONFIG['MOZ_WMF']:
     PARALLEL_DIRS += ['wmf']
 
 PARALLEL_DIRS += ['webrtc']
 
-if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gonk':
+if CONFIG['MOZ_OMX_DECODER']:
     PARALLEL_DIRS += ['omx']
 
 if CONFIG['MOZ_WEBSPEECH']:
     PARALLEL_DIRS += ['webspeech']
 
 TEST_DIRS += ['test']
 
 MODULE = 'content'
--- a/content/media/omx/MediaOmxStateMachine.h
+++ b/content/media/omx/MediaOmxStateMachine.h
@@ -16,12 +16,12 @@ protected:
   // many video buffers before shutting down the decoder. When we release these
   // buffers, they asynchronously signal to OMXCodec that we have returned
   // ownership of the buffer.
   // If this signal happens while the OMXCodec is shutting down, OMXCodec will
   // crash. If the OMXCodec shuts down before all buffers are returned,
   // OMXCodec will crash.
   // So we need few enough buffers in the queue that all buffers will be
   // returned before OMXCodec begins shutdown.
-  uint32_t GetAmpleVideoFrames() { return 1; }
+  uint32_t GetAmpleVideoFrames() { return 3; }
 };
 
 } // namespace mozilla
--- a/content/media/webaudio/GainNode.cpp
+++ b/content/media/webaudio/GainNode.cpp
@@ -58,38 +58,43 @@ public:
 
   virtual void ProduceAudioBlock(AudioNodeStream* aStream,
                                  const AudioChunk& aInput,
                                  AudioChunk* aOutput,
                                  bool* aFinished)
   {
     MOZ_ASSERT(mSource == aStream, "Invalid source stream");
 
-    *aOutput = aInput;
-    if (mGain.HasSimpleValue()) {
+    if (aInput.IsNull()) {
+      // If input is silent, so is the output
+      aOutput->SetNull(WEBAUDIO_BLOCK_SIZE);
+    } else if (mGain.HasSimpleValue()) {
       // Optimize the case where we only have a single value set as the volume
+      *aOutput = aInput;
       aOutput->mVolume *= mGain.GetValue();
     } else {
       // First, compute a vector of gains for each track tick based on the
       // timeline at hand, and then for each channel, multiply the values
       // in the buffer with the gain vector.
+      AllocateAudioBlock(aInput.mChannelData.Length(), aOutput);
 
       // Compute the gain values for the duration of the input AudioChunk
       // XXX we need to add a method to AudioEventTimeline to compute this buffer directly.
       float computedGain[WEBAUDIO_BLOCK_SIZE];
       for (size_t counter = 0; counter < WEBAUDIO_BLOCK_SIZE; ++counter) {
         TrackTicks tick = aStream->GetCurrentPosition();
         computedGain[counter] = mGain.GetValueAtTime(tick, counter) * aInput.mVolume;
       }
 
       // Apply the gain to the output buffer
       for (size_t channel = 0; channel < aOutput->mChannelData.Length(); ++channel) {
+        const float* inputBuffer = static_cast<const float*> (aInput.mChannelData[channel]);
         float* buffer = static_cast<float*> (const_cast<void*>
                           (aOutput->mChannelData[channel]));
-        AudioBlockCopyChannelWithScale(buffer, computedGain, buffer);
+        AudioBlockCopyChannelWithScale(inputBuffer, computedGain, buffer);
       }
     }
   }
 
   AudioNodeStream* mSource;
   AudioNodeStream* mDestination;
   AudioParamTimeline mGain;
 };
--- a/content/media/webaudio/WebAudioUtils.cpp
+++ b/content/media/webaudio/WebAudioUtils.cpp
@@ -13,32 +13,39 @@ namespace dom {
 
 struct ConvertTimeToTickHelper
 {
   AudioNodeStream* mSourceStream;
   AudioNodeStream* mDestinationStream;
 
   static int64_t Convert(double aTime, void* aClosure)
   {
-    TrackRate sampleRate = IdealAudioRate();
-    StreamTime streamTime;
-
     ConvertTimeToTickHelper* This = static_cast<ConvertTimeToTickHelper*> (aClosure);
     if (This->mSourceStream) {
-      TrackTicks tick = This->mDestinationStream->GetCurrentPosition();
-      StreamTime destinationStreamTime = TicksToTimeRoundDown(sampleRate, tick);
-      GraphTime graphTime = This->mDestinationStream->StreamTimeToGraphTime(destinationStreamTime);
-      streamTime = This->mSourceStream->GraphTimeToStreamTime(graphTime);
+      return WebAudioUtils::ConvertDestinationStreamTimeToSourceStreamTime(
+          aTime, This->mSourceStream, This->mDestinationStream);
     } else {
-      streamTime = This->mDestinationStream->GetCurrentPosition();
+      StreamTime streamTime = This->mDestinationStream->GetCurrentPosition();
+      return TimeToTicksRoundUp(IdealAudioRate(), streamTime + SecondsToMediaTime(aTime));
     }
-    return TimeToTicksRoundDown(sampleRate, streamTime + SecondsToMediaTime(aTime));
   }
 };
 
+TrackTicks
+WebAudioUtils::ConvertDestinationStreamTimeToSourceStreamTime(double aTime,
+                                                              MediaStream* aSource,
+                                                              MediaStream* aDestination)
+{
+  StreamTime streamTime = std::max<MediaTime>(0, SecondsToMediaTime(aTime));
+  GraphTime graphTime = aDestination->StreamTimeToGraphTime(streamTime);
+  StreamTime thisStreamTime = aSource->GraphTimeToStreamTimeOptimistic(graphTime);
+  TrackTicks ticks = TimeToTicksRoundUp(IdealAudioRate(), thisStreamTime);
+  return ticks;
+}
+
 double
 WebAudioUtils::StreamPositionToDestinationTime(TrackTicks aSourcePosition,
                                                AudioNodeStream* aSource,
                                                AudioNodeStream* aDestination)
 {
   StreamTime sourceTime = TicksToTimeRoundDown(IdealAudioRate(), aSourcePosition);
   GraphTime graphTime = aSource->StreamTimeToGraphTime(sourceTime);
   StreamTime destinationTime = aDestination->GraphTimeToStreamTimeOptimistic(graphTime);
--- a/content/media/webaudio/WebAudioUtils.h
+++ b/content/media/webaudio/WebAudioUtils.h
@@ -37,16 +37,25 @@ struct WebAudioUtils {
    * over aDuration seconds.
    */
   static double ComputeSmoothingRate(double aDuration, double aSampleRate)
   {
     return 1.0 - std::exp(-1.0 / (aDuration * aSampleRate));
   }
 
   /**
+   * Convert a time in second relative to the destination stream to
+   * TrackTicks relative to the source stream.
+   */
+  static TrackTicks
+  ConvertDestinationStreamTimeToSourceStreamTime(double aTime,
+                                                 MediaStream* aSource,
+                                                 MediaStream* aDestination);
+
+  /**
    * Converts AudioParamTimeline floating point time values to tick values
    * with respect to a source and a destination AudioNodeStream.
    *
    * This needs to be called for each AudioParamTimeline that gets sent to an
    * AudioNodeEngine on the engine side where the AudioParamTimeline is
    * received.  This means that such engines need to be aware of their source
    * and destination streams as well.
    */
--- a/content/media/webaudio/test/Makefile.in
+++ b/content/media/webaudio/test/Makefile.in
@@ -26,16 +26,17 @@ MOCHITEST_FILES := \
   test_AudioBuffer.html \
   test_AudioContext.html \
   test_AudioListener.html \
   test_AudioParam.html \
   test_audioParamExponentialRamp.html \
   test_audioParamLinearRamp.html \
   test_audioParamSetCurveAtTime.html \
   test_audioParamSetTargetAtTime.html \
+  test_audioParamTimelineDestinationOffset.html \
   test_audioBufferSourceNode.html \
   test_audioBufferSourceNodeLazyLoopParam.html \
   test_audioBufferSourceNodeLoop.html \
   test_audioBufferSourceNodeLoopStartEnd.html \
   test_audioBufferSourceNodeLoopStartEndSame.html \
   test_audioBufferSourceNodeNullBuffer.html \
   test_badConnect.html \
   test_biquadFilterNode.html \
@@ -43,16 +44,17 @@ MOCHITEST_FILES := \
   test_channelMergerNodeWithVolume.html \
   test_channelSplitterNode.html \
   test_channelSplitterNodeWithVolume.html \
   test_currentTime.html \
   test_delayNode.html \
   test_delayNodeWithGain.html \
   test_dynamicsCompressorNode.html \
   test_gainNode.html \
+  test_gainNodeInLoop.html \
   test_mediaDecoding.html \
   test_mixingRules.html \
   test_nodeToParamConnection.html \
   test_pannerNode.html \
   test_scriptProcessorNode.html \
   test_scriptProcessorNodeChannelCount.html \
   test_singleSourceDest.html \
   ting.ogg \
new file mode 100644
--- /dev/null
+++ b/content/media/webaudio/test/test_audioParamTimelineDestinationOffset.html
@@ -0,0 +1,55 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test AudioParam timeline events scheduled after the destination stream has started playback</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="webaudio.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function() {
+  SpecialPowers.setBoolPref("media.webaudio.enabled", true);
+
+  var context = new AudioContext();
+
+  var sourceBuffer = context.createBuffer(1, 2048, context.sampleRate);
+  for (var i = 0; i < 2048; ++i) {
+    sourceBuffer.getChannelData(0)[i] = 1;
+  }
+  var emptyBuffer = context.createBuffer(1, 16384, context.sampleRate);
+
+  setTimeout(function() {
+    var source = context.createBufferSource();
+    source.buffer = sourceBuffer;
+    source.start(context.currentTime);
+    source.stop(context.currentTime + sourceBuffer.duration);
+
+    var gain = context.createGain();
+    gain.gain.setValueAtTime(0, context.currentTime);
+    gain.gain.setTargetAtTime(0, context.currentTime + sourceBuffer.duration, 1);
+    source.connect(gain);
+
+    var sp = context.createScriptProcessor(16384, 1);
+    gain.connect(sp);
+    sp.connect(context.destination);
+
+    sp.onaudioprocess = function(e) {
+      is(e.inputBuffer.numberOfChannels, 1, "Correct input channel count");
+      compareBuffers(e.inputBuffer.getChannelData(0), emptyBuffer.getChannelData(0));
+
+      sp.onaudioprocess = null;
+
+      SpecialPowers.clearUserPref("media.webaudio.enabled");
+      SimpleTest.finish();
+    };
+  }, 100);
+});
+
+</script>
+</pre>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/content/media/webaudio/test/test_gainNodeInLoop.html
@@ -0,0 +1,57 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test GainNode in presence of loops</title>
+  <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+  <script type="text/javascript" src="webaudio.js"></script>
+  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+
+SimpleTest.waitForExplicitFinish();
+addLoadEvent(function() {
+  SpecialPowers.setBoolPref("media.webaudio.enabled", true);
+
+  var context = new AudioContext();
+
+  var sourceBuffer = context.createBuffer(1, 2048, context.sampleRate);
+  for (var i = 0; i < 2048; ++i) {
+    sourceBuffer.getChannelData(0)[i] = 1;
+  }
+  var expectedBuffer = context.createBuffer(1, 4096, context.sampleRate);
+  for (var i = 0; i < 4096; ++i) {
+    expectedBuffer.getChannelData(0)[i] = 0.5;
+  }
+
+  var source = context.createBufferSource();
+  source.buffer = sourceBuffer;
+  source.loop = true;
+  source.start(0);
+  source.stop(sourceBuffer.duration * 2);
+
+  var gain = context.createGain();
+  // Adjust the gain in a way that we don't just end up modifying AudioChunk::mVolume
+  gain.gain.setValueAtTime(0.5, 0);
+  source.connect(gain);
+
+  var sp = context.createScriptProcessor(4096, 1);
+  gain.connect(sp);
+  sp.connect(context.destination);
+
+  sp.onaudioprocess = function(e) {
+    is(e.inputBuffer.numberOfChannels, 1, "Correct input channel count");
+    compareBuffers(e.inputBuffer.getChannelData(0), expectedBuffer.getChannelData(0));
+
+    sp.onaudioprocess = null;
+
+    SpecialPowers.clearUserPref("media.webaudio.enabled");
+    SimpleTest.finish();
+  };
+});
+
+</script>
+</pre>
+</body>
+</html>
--- a/content/smil/nsSMILParserUtils.cpp
+++ b/content/smil/nsSMILParserUtils.cpp
@@ -111,17 +111,17 @@ GetUnsignedIntAndEndParen(const nsAStrin
     return false;
 
   return true;
 }
 
 inline bool
 ConsumeSubstring(const char*& aStart, const char* aEnd, const char* aSubstring)
 {
-  size_t substrLen = PL_strlen(aSubstring);
+  size_t substrLen = strlen(aSubstring);
 
   if (static_cast<size_t>(aEnd - aStart) < substrLen)
     return false;
 
   bool result = false;
 
   if (PL_strstr(aStart, aSubstring) == aStart) {
     aStart += substrLen;
--- a/content/svg/content/src/SVGAElement.h
+++ b/content/svg/content/src/SVGAElement.h
@@ -29,57 +29,57 @@ protected:
                                        already_AddRefed<nsINodeInfo> aNodeInfo));
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsINode interface methods
-  virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
-  virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
+  virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor) MOZ_OVERRIDE;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // nsILink
-  NS_IMETHOD LinkAdded() { return NS_OK; }
-  NS_IMETHOD LinkRemoved() { return NS_OK; }
+  NS_IMETHOD LinkAdded() MOZ_OVERRIDE { return NS_OK; }
+  NS_IMETHOD LinkRemoved() MOZ_OVERRIDE { return NS_OK; }
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument *aDocument, nsIContent *aParent,
                               nsIContent *aBindingParent,
-                              bool aCompileEventHandlers);
+                              bool aCompileEventHandlers) MOZ_OVERRIDE;
   virtual void UnbindFromTree(bool aDeep = true,
-                              bool aNullParent = true);
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
-  virtual bool IsFocusable(int32_t *aTabIndex = nullptr, bool aWithMouse = false);
-  virtual bool IsLink(nsIURI** aURI) const;
-  virtual void GetLinkTarget(nsAString& aTarget);
-  virtual nsLinkState GetLinkState() const;
-  virtual already_AddRefed<nsIURI> GetHrefURI() const;
-  virtual nsEventStates IntrinsicState() const;
+                              bool aNullParent = true) MOZ_OVERRIDE;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
+  virtual bool IsFocusable(int32_t *aTabIndex = nullptr, bool aWithMouse = false) MOZ_OVERRIDE;
+  virtual bool IsLink(nsIURI** aURI) const MOZ_OVERRIDE;
+  virtual void GetLinkTarget(nsAString& aTarget) MOZ_OVERRIDE;
+  virtual nsLinkState GetLinkState() const MOZ_OVERRIDE;
+  virtual already_AddRefed<nsIURI> GetHrefURI() const MOZ_OVERRIDE;
+  virtual nsEventStates IntrinsicState() const MOZ_OVERRIDE;
   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, bool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
   }
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                            nsIAtom* aPrefix, const nsAString& aValue,
-                           bool aNotify);
+                           bool aNotify) MOZ_OVERRIDE;
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
-                             bool aNotify);
+                             bool aNotify) MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> Href();
   already_AddRefed<nsIDOMSVGAnimatedString> Target();
   void GetDownload(nsAString & aDownload);
   void SetDownload(const nsAString & aDownload, ErrorResult& rv);
 
 protected:
 
-  virtual StringAttributesInfo GetStringInfo();
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { HREF, TARGET };
   nsSVGString mStringAttributes[2];
   static StringInfo sStringInfo[2];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGAltGlyphElement.h
+++ b/content/svg/content/src/SVGAltGlyphElement.h
@@ -23,31 +23,31 @@ protected:
   friend nsresult (::NS_NewSVGAltGlyphElement(nsIContent **aResult,
                                               already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGAltGlyphElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   // nsIContent interface
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> Href();
   void GetGlyphRef(nsAString & aGlyphRef);
   void SetGlyphRef(const nsAString & aGlyphRef, ErrorResult& rv);
   void GetFormat(nsAString & aFormat);
   void SetFormat(const nsAString & aFormat, ErrorResult& rv);
 
 protected:
 
   // nsSVGElement overrides
-  virtual StringAttributesInfo GetStringInfo();
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   virtual bool IsEventName(nsIAtom* aName);
 
   enum { HREF };
   nsSVGString mStringAttributes[1];
   static StringInfo sStringInfo[1];
 
 };
--- a/content/svg/content/src/SVGCircleElement.h
+++ b/content/svg/content/src/SVGCircleElement.h
@@ -23,31 +23,31 @@ protected:
   SVGCircleElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
   friend nsresult (::NS_NewSVGCircleElement(nsIContent **aResult,
                                             already_AddRefed<nsINodeInfo> aNodeInfo));
 
 public:
   // nsSVGSVGElement methods:
-  virtual bool HasValidDimensions() const;
+  virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // nsSVGPathGeometryElement methods:
-  virtual void ConstructPath(gfxContext *aCtx);
+  virtual void ConstructPath(gfxContext *aCtx) MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<SVGAnimatedLength> Cx();
   already_AddRefed<SVGAnimatedLength> Cy();
   already_AddRefed<SVGAnimatedLength> R();
 
 protected:
 
-  virtual LengthAttributesInfo GetLengthInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
 
   enum { ATTR_CX, ATTR_CY, ATTR_R };
   nsSVGLength2 mLengthAttributes[3];
   static LengthInfo sLengthInfo[3];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGClipPathElement.h
+++ b/content/svg/content/src/SVGClipPathElement.h
@@ -26,26 +26,26 @@ class SVGClipPathElement MOZ_FINAL : pub
 protected:
   friend nsresult (::NS_NewSVGClipPathElement(nsIContent **aResult,
                                               already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGClipPathElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> ClipPathUnits();
 
 protected:
 
   enum { CLIPPATHUNITS };
   nsSVGEnum mEnumAttributes[1];
   static EnumInfo sEnumInfo[1];
 
-  virtual EnumAttributesInfo GetEnumInfo();
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_SVGClipPathElement_h
--- a/content/svg/content/src/SVGComponentTransferFunctionElement.h
+++ b/content/svg/content/src/SVGComponentTransferFunctionElement.h
@@ -34,36 +34,36 @@ protected:
 
 public:
   // interfaces:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_SVG_FE_COMPONENT_TRANSFER_FUNCTION_ELEMENT_CID)
 
   NS_DECL_ISUPPORTS_INHERITED
 
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   virtual int32_t GetChannel() = 0;
   bool GenerateLookupTable(uint8_t* aTable);
 
   // WebIDL
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE = 0;
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> Type();
   already_AddRefed<DOMSVGAnimatedNumberList> TableValues();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Slope();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Intercept();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Amplitude();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Exponent();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Offset();
 
 protected:
-  virtual NumberAttributesInfo GetNumberInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual NumberListAttributesInfo GetNumberListInfo();
+  virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
+  virtual NumberListAttributesInfo GetNumberListInfo() MOZ_OVERRIDE;
 
   enum { TABLEVALUES };
   SVGAnimatedNumberList mNumberListAttributes[1];
   static NumberListInfo sNumberListInfo[1];
 
   enum { SLOPE, INTERCEPT, AMPLITUDE, EXPONENT, OFFSET };
   nsSVGNumber2 mNumberAttributes[5];
   static NumberInfo sNumberInfo[5];
@@ -87,19 +87,19 @@ class SVGFEFuncRElement : public SVGComp
 {
   friend nsresult (::NS_NewSVGFEFuncRElement(
     nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo));
 protected:
   SVGFEFuncRElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : SVGComponentTransferFunctionElement(aNodeInfo) {}
 
 public:
-  virtual int32_t GetChannel() { return 0; }
+  virtual int32_t GetChannel() MOZ_OVERRIDE { return 0; }
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
@@ -113,19 +113,19 @@ class SVGFEFuncGElement : public SVGComp
 {
   friend nsresult (::NS_NewSVGFEFuncGElement(
     nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo));
 protected:
   SVGFEFuncGElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : SVGComponentTransferFunctionElement(aNodeInfo) {}
 
 public:
-  virtual int32_t GetChannel() { return 1; }
+  virtual int32_t GetChannel() MOZ_OVERRIDE { return 1; }
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
@@ -139,19 +139,19 @@ class SVGFEFuncBElement : public SVGComp
 {
   friend nsresult (::NS_NewSVGFEFuncBElement(
     nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo));
 protected:
   SVGFEFuncBElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : SVGComponentTransferFunctionElement(aNodeInfo) {}
 
 public:
-  virtual int32_t GetChannel() { return 2; }
+  virtual int32_t GetChannel() MOZ_OVERRIDE { return 2; }
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
@@ -165,19 +165,19 @@ class SVGFEFuncAElement : public SVGComp
 {
   friend nsresult (::NS_NewSVGFEFuncAElement(
     nsIContent** aResult, already_AddRefed<nsINodeInfo> aNodeInfo));
 protected:
   SVGFEFuncAElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : SVGComponentTransferFunctionElement(aNodeInfo) {}
 
 public:
-  virtual int32_t GetChannel() { return 3; }
+  virtual int32_t GetChannel() MOZ_OVERRIDE { return 3; }
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 };
 
 } // namespace dom
 } // namespace mozilla
 
--- a/content/svg/content/src/SVGEllipseElement.h
+++ b/content/svg/content/src/SVGEllipseElement.h
@@ -23,32 +23,32 @@ protected:
   SVGEllipseElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
   friend nsresult (::NS_NewSVGEllipseElement(nsIContent **aResult,
                                              already_AddRefed<nsINodeInfo> aNodeInfo));
 
 public:
   // nsSVGSVGElement methods:
-  virtual bool HasValidDimensions() const;
+  virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // nsSVGPathGeometryElement methods:
-  virtual void ConstructPath(gfxContext *aCtx);
+  virtual void ConstructPath(gfxContext *aCtx) MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<SVGAnimatedLength> Cx();
   already_AddRefed<SVGAnimatedLength> Cy();
   already_AddRefed<SVGAnimatedLength> Rx();
   already_AddRefed<SVGAnimatedLength> Ry();
 
 protected:
 
-  virtual LengthAttributesInfo GetLengthInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
 
   enum { CX, CY, RX, RY };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGFEBlendElement.h
+++ b/content/svg/content/src/SVGFEBlendElement.h
@@ -34,33 +34,33 @@ protected:
   }
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
+  virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
+  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> In1();
   already_AddRefed<nsIDOMSVGAnimatedString> In2();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> Mode();
 
 protected:
 
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { MODE };
   nsSVGEnum mEnumAttributes[1];
   static nsSVGEnumMapping sModeMap[];
   static EnumInfo sEnumInfo[1];
 
   enum { RESULT, IN1, IN2 };
   nsSVGString mStringAttributes[3];
--- a/content/svg/content/src/SVGFEColorMatrixElement.h
+++ b/content/svg/content/src/SVGFEColorMatrixElement.h
@@ -35,35 +35,35 @@ protected:
   }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
+  virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
+  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> In1();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> Type();
   already_AddRefed<DOMSVGAnimatedNumberList> Values();
 
  protected:
-  virtual bool OperatesOnPremultipledAlpha(int32_t) { return false; }
+  virtual bool OperatesOnPremultipledAlpha(int32_t) MOZ_OVERRIDE { return false; }
 
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
-  virtual NumberListAttributesInfo GetNumberListInfo();
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
+  virtual NumberListAttributesInfo GetNumberListInfo() MOZ_OVERRIDE;
 
   enum { TYPE };
   nsSVGEnum mEnumAttributes[1];
   static nsSVGEnumMapping sTypeMap[];
   static EnumInfo sEnumInfo[1];
 
   enum { RESULT, IN1 };
   nsSVGString mStringAttributes[2];
--- a/content/svg/content/src/SVGFEComponentTransferElement.h
+++ b/content/svg/content/src/SVGFEComponentTransferElement.h
@@ -27,32 +27,32 @@ protected:
   }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
+  virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
+  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
 
   // nsIContent
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> In1();
 
 protected:
-  virtual bool OperatesOnPremultipledAlpha(int32_t) { return false; }
+  virtual bool OperatesOnPremultipledAlpha(int32_t) MOZ_OVERRIDE { return false; }
 
-  virtual StringAttributesInfo GetStringInfo();
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { RESULT, IN1 };
   nsSVGString mStringAttributes[2];
   static StringInfo sStringInfo[2];
 };
 
 } // namespace mozilla
 } // namespace dom
--- a/content/svg/content/src/SVGFECompositeElement.h
+++ b/content/svg/content/src/SVGFECompositeElement.h
@@ -38,41 +38,41 @@ protected:
   }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
+  virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
+  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
 
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> In1();
   already_AddRefed<nsIDOMSVGAnimatedString> In2();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> Operator();
   already_AddRefed<nsIDOMSVGAnimatedNumber> K1();
   already_AddRefed<nsIDOMSVGAnimatedNumber> K2();
   already_AddRefed<nsIDOMSVGAnimatedNumber> K3();
   already_AddRefed<nsIDOMSVGAnimatedNumber> K4();
   void SetK(float k1, float k2, float k3, float k4);
 
 protected:
-  virtual NumberAttributesInfo GetNumberInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { ATTR_K1, ATTR_K2, ATTR_K3, ATTR_K4 };
   nsSVGNumber2 mNumberAttributes[4];
   static NumberInfo sNumberInfo[4];
 
   enum { OPERATOR };
   nsSVGEnum mEnumAttributes[1];
   static nsSVGEnumMapping sOperatorMap[];
--- a/content/svg/content/src/SVGFEConvolveMatrixElement.h
+++ b/content/svg/content/src/SVGFEConvolveMatrixElement.h
@@ -37,58 +37,58 @@ protected:
   }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
+  virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
+  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
   virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance);
+          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
   virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
 
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> In1();
   already_AddRefed<nsIDOMSVGAnimatedInteger> OrderX();
   already_AddRefed<nsIDOMSVGAnimatedInteger> OrderY();
   already_AddRefed<DOMSVGAnimatedNumberList> KernelMatrix();
   already_AddRefed<nsIDOMSVGAnimatedInteger> TargetX();
   already_AddRefed<nsIDOMSVGAnimatedInteger> TargetY();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> EdgeMode();
   already_AddRefed<SVGAnimatedBoolean> PreserveAlpha();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Divisor();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Bias();
   already_AddRefed<nsIDOMSVGAnimatedNumber> KernelUnitLengthX();
   already_AddRefed<nsIDOMSVGAnimatedNumber> KernelUnitLengthY();
 
 protected:
-  virtual bool OperatesOnPremultipledAlpha(int32_t) {
+  virtual bool OperatesOnPremultipledAlpha(int32_t) MOZ_OVERRIDE {
     return !mBooleanAttributes[PRESERVEALPHA].GetAnimValue();
   }
 
-  virtual NumberAttributesInfo GetNumberInfo();
-  virtual NumberPairAttributesInfo GetNumberPairInfo();
-  virtual IntegerAttributesInfo GetIntegerInfo();
-  virtual IntegerPairAttributesInfo GetIntegerPairInfo();
-  virtual BooleanAttributesInfo GetBooleanInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
-  virtual NumberListAttributesInfo GetNumberListInfo();
+  virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
+  virtual NumberPairAttributesInfo GetNumberPairInfo() MOZ_OVERRIDE;
+  virtual IntegerAttributesInfo GetIntegerInfo() MOZ_OVERRIDE;
+  virtual IntegerPairAttributesInfo GetIntegerPairInfo() MOZ_OVERRIDE;
+  virtual BooleanAttributesInfo GetBooleanInfo() MOZ_OVERRIDE;
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
+  virtual NumberListAttributesInfo GetNumberListInfo() MOZ_OVERRIDE;
 
   enum { DIVISOR, BIAS };
   nsSVGNumber2 mNumberAttributes[2];
   static NumberInfo sNumberInfo[2];
 
   enum { KERNEL_UNIT_LENGTH };
   nsSVGNumberPair mNumberPairAttributes[1];
   static NumberPairInfo sNumberPairInfo[1];
--- a/content/svg/content/src/SVGFEDisplacementMapElement.h
+++ b/content/svg/content/src/SVGFEDisplacementMapElement.h
@@ -28,59 +28,59 @@ protected:
   }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
+  virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
+  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
   virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance);
+          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
   virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
 
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> In1();
   already_AddRefed<nsIDOMSVGAnimatedString> In2();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Scale();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> XChannelSelector();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> YChannelSelector();
 
 protected:
   virtual bool OperatesOnSRGB(nsSVGFilterInstance* aInstance,
-                              int32_t aInput, Image* aImage) {
+                              int32_t aInput, Image* aImage) MOZ_OVERRIDE {
     switch (aInput) {
     case 0:
       return aImage->mColorModel.mColorSpace == ColorModel::SRGB;
     case 1:
       return SVGFEDisplacementMapElementBase::OperatesOnSRGB(aInstance,
                                                              aInput, aImage);
     default:
       NS_ERROR("Will not give correct output color model");
       return false;
     }
   }
-  virtual bool OperatesOnPremultipledAlpha(int32_t aInput) {
+  virtual bool OperatesOnPremultipledAlpha(int32_t aInput) MOZ_OVERRIDE {
     return !(aInput == 1);
   }
 
-  virtual NumberAttributesInfo GetNumberInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { SCALE };
   nsSVGNumber2 mNumberAttributes[1];
   static NumberInfo sNumberInfo[1];
 
   enum { CHANNEL_X, CHANNEL_Y };
   nsSVGEnum mEnumAttributes[2];
   static nsSVGEnumMapping sChannelMap[];
--- a/content/svg/content/src/SVGFEDistantLightElement.h
+++ b/content/svg/content/src/SVGFEDistantLightElement.h
@@ -26,26 +26,26 @@ protected:
     : SVGFEDistantLightElementBase(aNodeInfo)
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedNumber> Azimuth();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Elevation();
 
 protected:
-  virtual NumberAttributesInfo GetNumberInfo();
+  virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
 
   enum { AZIMUTH, ELEVATION };
   nsSVGNumber2 mNumberAttributes[2];
   static NumberInfo sNumberInfo[2];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGFEFloodElement.h
+++ b/content/svg/content/src/SVGFEFloodElement.h
@@ -24,36 +24,36 @@ protected:
   SVGFEFloodElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : SVGFEFloodElementBase(aNodeInfo)
   {
   }
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
-  virtual bool SubregionIsUnionOfRegions() { return false; }
+  virtual bool SubregionIsUnionOfRegions() MOZ_OVERRIDE { return false; }
 
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
+  virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
 
   // nsIContent interface
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
 protected:
   virtual bool OperatesOnSRGB(nsSVGFilterInstance*,
-                              int32_t, Image*) { return true; }
+                              int32_t, Image*) MOZ_OVERRIDE { return true; }
 
-  virtual StringAttributesInfo GetStringInfo();
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { RESULT };
   nsSVGString mStringAttributes[1];
   static StringInfo sStringInfo[1];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGFEGaussianBlurElement.h
+++ b/content/svg/content/src/SVGFEGaussianBlurElement.h
@@ -29,40 +29,40 @@ protected:
   }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo >& aSources);
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
+  virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
+  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo >& aSources) MOZ_OVERRIDE;
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
   virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance);
+          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
   virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
 
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> In1();
   already_AddRefed<nsIDOMSVGAnimatedNumber> StdDeviationX();
   already_AddRefed<nsIDOMSVGAnimatedNumber> StdDeviationY();
   void SetStdDeviation(float stdDeviationX, float stdDeviationY);
 
 protected:
-  virtual NumberPairAttributesInfo GetNumberPairInfo();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual NumberPairAttributesInfo GetNumberPairInfo() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { STD_DEV };
   nsSVGNumberPair mNumberPairAttributes[1];
   static NumberPairInfo sNumberPairInfo[1];
 
   enum { RESULT, IN1 };
   nsSVGString mStringAttributes[2];
   static StringInfo sStringInfo[2];
--- a/content/svg/content/src/SVGFEImageElement.h
+++ b/content/svg/content/src/SVGFEImageElement.h
@@ -27,64 +27,64 @@ protected:
   friend nsresult (::NS_NewSVGFEImageElement(nsIContent **aResult,
                                              already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGFEImageElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual ~SVGFEImageElement();
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
-  virtual bool SubregionIsUnionOfRegions() { return false; }
+  virtual bool SubregionIsUnionOfRegions() MOZ_OVERRIDE { return false; }
 
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
 
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
+  virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
 
   // nsIContent
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
-                                const nsAttrValue* aValue, bool aNotify);
+                                const nsAttrValue* aValue, bool aNotify) MOZ_OVERRIDE;
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
-                              bool aCompileEventHandlers);
-  virtual void UnbindFromTree(bool aDeep, bool aNullParent);
-  virtual nsEventStates IntrinsicState() const;
+                              bool aCompileEventHandlers) MOZ_OVERRIDE;
+  virtual void UnbindFromTree(bool aDeep, bool aNullParent) MOZ_OVERRIDE;
+  virtual nsEventStates IntrinsicState() const MOZ_OVERRIDE;
 
-  NS_IMETHODIMP Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData);
+  NS_IMETHODIMP Notify(imgIRequest *aRequest, int32_t aType, const nsIntRect* aData) MOZ_OVERRIDE;
 
   void MaybeLoadSVGImage();
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> Href();
   already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
 
 private:
   // Invalidate users of the filter containing this element.
   void Invalidate();
 
   nsresult LoadSVGImage(bool aForce, bool aNotify);
 
 protected:
   virtual bool OperatesOnSRGB(nsSVGFilterInstance*,
-                                int32_t, Image*) { return true; }
+                                int32_t, Image*) MOZ_OVERRIDE { return true; }
 
-  virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { RESULT, HREF };
   nsSVGString mStringAttributes[2];
   static StringInfo sStringInfo[2];
 
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
 };
 
--- a/content/svg/content/src/SVGFEMergeElement.h
+++ b/content/svg/content/src/SVGFEMergeElement.h
@@ -27,24 +27,24 @@ protected:
   }
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
+  virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
+  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
 
   // nsIContent
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 protected:
-  virtual StringAttributesInfo GetStringInfo();
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { RESULT };
   nsSVGString mStringAttributes[1];
   static StringInfo sStringInfo[1];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGFEMergeNodeElement.h
+++ b/content/svg/content/src/SVGFEMergeNodeElement.h
@@ -24,28 +24,28 @@ protected:
   SVGFEMergeNodeElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : SVGFEMergeNodeElementBase(aNodeInfo)
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   const nsSVGString* GetIn1() { return &mStringAttributes[IN1]; }
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> In1();
 
 protected:
-  virtual StringAttributesInfo GetStringInfo();
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { IN1 };
   nsSVGString mStringAttributes[1];
   static StringInfo sStringInfo[1];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGFEMorphologyElement.h
+++ b/content/svg/content/src/SVGFEMorphologyElement.h
@@ -30,44 +30,44 @@ protected:
   }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
+  virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
+  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
   virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance);
+          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
   virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> In1();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> Operator();
   already_AddRefed<nsIDOMSVGAnimatedNumber> RadiusX();
   already_AddRefed<nsIDOMSVGAnimatedNumber> RadiusY();
   void SetRadius(float rx, float ry);
 
 protected:
   void GetRXY(int32_t *aRX, int32_t *aRY, const nsSVGFilterInstance& aInstance);
   nsIntRect InflateRect(const nsIntRect& aRect, const nsSVGFilterInstance& aInstance);
 
-  virtual NumberPairAttributesInfo GetNumberPairInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual NumberPairAttributesInfo GetNumberPairInfo() MOZ_OVERRIDE;
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { RADIUS };
   nsSVGNumberPair mNumberPairAttributes[1];
   static NumberPairInfo sNumberPairInfo[1];
 
   enum { OPERATOR };
   nsSVGEnum mEnumAttributes[1];
   static nsSVGEnumMapping sOperatorMap[];
--- a/content/svg/content/src/SVGFEOffsetElement.h
+++ b/content/svg/content/src/SVGFEOffsetElement.h
@@ -29,40 +29,40 @@ protected:
   }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
   virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
+  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
   virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance);
+          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
   virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> In1();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Dx();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Dy();
 
 protected:
   nsIntPoint GetOffset(const nsSVGFilterInstance& aInstance);
 
-  virtual NumberAttributesInfo GetNumberInfo();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { DX, DY };
   nsSVGNumber2 mNumberAttributes[2];
   static NumberInfo sNumberInfo[2];
 
   enum { RESULT, IN1 };
   nsSVGString mStringAttributes[2];
   static StringInfo sStringInfo[2];
--- a/content/svg/content/src/SVGFEPointLightElement.h
+++ b/content/svg/content/src/SVGFEPointLightElement.h
@@ -26,27 +26,27 @@ protected:
     : SVGFEPointLightElementBase(aNodeInfo)
   {
   }
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedNumber> X();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Y();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Z();
 
 protected:
-  virtual NumberAttributesInfo GetNumberInfo();
+  virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X, ATTR_Y, ATTR_Z };
   nsSVGNumber2 mNumberAttributes[3];
   static NumberInfo sNumberInfo[3];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGFESpotLightElement.h
+++ b/content/svg/content/src/SVGFESpotLightElement.h
@@ -29,32 +29,32 @@ protected:
     : SVGFESpotLightElementBase(aNodeInfo)
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedNumber> X();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Y();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Z();
   already_AddRefed<nsIDOMSVGAnimatedNumber> PointsAtX();
   already_AddRefed<nsIDOMSVGAnimatedNumber> PointsAtY();
   already_AddRefed<nsIDOMSVGAnimatedNumber> PointsAtZ();
   already_AddRefed<nsIDOMSVGAnimatedNumber> SpecularExponent();
   already_AddRefed<nsIDOMSVGAnimatedNumber> LimitingConeAngle();
 
 protected:
-  virtual NumberAttributesInfo GetNumberInfo();
+  virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X, ATTR_Y, ATTR_Z, POINTS_AT_X, POINTS_AT_Y, POINTS_AT_Z,
          SPECULAR_EXPONENT, LIMITING_CONE_ANGLE };
   nsSVGNumber2 mNumberAttributes[8];
   static NumberInfo sNumberInfo[8];
 };
 
 } // namespace dom
--- a/content/svg/content/src/SVGFETileElement.h
+++ b/content/svg/content/src/SVGFETileElement.h
@@ -29,35 +29,35 @@ protected:
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   virtual bool SubregionIsUnionOfRegions() { return false; }
 
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
-  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources);
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
+  virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
+  virtual void GetSourceImageNames(nsTArray<nsSVGStringInfo>& aSources) MOZ_OVERRIDE;
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
   virtual void ComputeNeededSourceBBoxes(const nsIntRect& aTargetBBox,
-          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance);
+          nsTArray<nsIntRect>& aSourceBBoxes, const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
   virtual nsIntRect ComputeChangeBBox(const nsTArray<nsIntRect>& aSourceChangeBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> In1();
 
 protected:
-  virtual StringAttributesInfo GetStringInfo();
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { RESULT, IN1 };
   nsSVGString mStringAttributes[2];
   static StringInfo sStringInfo[2];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGFETurbulenceElement.h
+++ b/content/svg/content/src/SVGFETurbulenceElement.h
@@ -28,44 +28,44 @@ protected:
   SVGFETurbulenceElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : SVGFETurbulenceElementBase(aNodeInfo)
   {
   }
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
-  virtual bool SubregionIsUnionOfRegions() { return false; }
+  virtual bool SubregionIsUnionOfRegions() MOZ_OVERRIDE { return false; }
 
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
   virtual bool AttributeAffectsRendering(
-          int32_t aNameSpaceID, nsIAtom* aAttribute) const;
-  virtual nsSVGString& GetResultImageName() { return mStringAttributes[RESULT]; }
+          int32_t aNameSpaceID, nsIAtom* aAttribute) const MOZ_OVERRIDE;
+  virtual nsSVGString& GetResultImageName() MOZ_OVERRIDE { return mStringAttributes[RESULT]; }
   virtual nsIntRect ComputeTargetBBox(const nsTArray<nsIntRect>& aSourceBBoxes,
-          const nsSVGFilterInstance& aInstance);
+          const nsSVGFilterInstance& aInstance) MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedNumber> BaseFrequencyX();
   already_AddRefed<nsIDOMSVGAnimatedNumber> BaseFrequencyY();
   already_AddRefed<nsIDOMSVGAnimatedInteger> NumOctaves();
   already_AddRefed<nsIDOMSVGAnimatedNumber> Seed();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> StitchTiles();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> Type();
 
 protected:
-  virtual NumberAttributesInfo GetNumberInfo();
-  virtual NumberPairAttributesInfo GetNumberPairInfo();
-  virtual IntegerAttributesInfo GetIntegerInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
+  virtual NumberPairAttributesInfo GetNumberPairInfo() MOZ_OVERRIDE;
+  virtual IntegerAttributesInfo GetIntegerInfo() MOZ_OVERRIDE;
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { SEED }; // floating point seed?!
   nsSVGNumber2 mNumberAttributes[1];
   static NumberInfo sNumberInfo[1];
 
   enum { BASE_FREQ };
   nsSVGNumberPair mNumberPairAttributes[1];
   static NumberPairInfo sNumberPairInfo[1];
--- a/content/svg/content/src/SVGFilterElement.h
+++ b/content/svg/content/src/SVGFilterElement.h
@@ -33,43 +33,43 @@ protected:
   friend nsresult (::NS_NewSVGFilterElement(nsIContent **aResult,
                                             already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGFilterElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   // nsIContent
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   // Invalidate users of this filter
   void Invalidate();
 
   // nsSVGSVGElement methods:
-  virtual bool HasValidDimensions() const;
+  virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<SVGAnimatedLength> X();
   already_AddRefed<SVGAnimatedLength> Y();
   already_AddRefed<SVGAnimatedLength> Width();
   already_AddRefed<SVGAnimatedLength> Height();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> FilterUnits();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> PrimitiveUnits();
   already_AddRefed<nsIDOMSVGAnimatedInteger> FilterResX();
   already_AddRefed<nsIDOMSVGAnimatedInteger> FilterResY();
   void SetFilterRes(uint32_t filterResX, uint32_t filterResY);
   already_AddRefed<nsIDOMSVGAnimatedString> Href();
 
 protected:
 
-  virtual LengthAttributesInfo GetLengthInfo();
-  virtual IntegerPairAttributesInfo GetIntegerPairInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
+  virtual IntegerPairAttributesInfo GetIntegerPairInfo() MOZ_OVERRIDE;
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 
   enum { FILTERRES };
   nsSVGIntegerPair mIntegerPairAttributes[1];
   static IntegerPairInfo sIntegerPairInfo[1];
--- a/content/svg/content/src/SVGForeignObjectElement.h
+++ b/content/svg/content/src/SVGForeignObjectElement.h
@@ -26,33 +26,33 @@ protected:
                                                    already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGForeignObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   // nsSVGElement specializations:
   virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
-                      TransformTypes aWhich = eAllTransforms) const;
-  virtual bool HasValidDimensions() const;
+                      TransformTypes aWhich = eAllTransforms) const MOZ_OVERRIDE;
+  virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // nsIContent interface
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<SVGAnimatedLength> X();
   already_AddRefed<SVGAnimatedLength> Y();
   already_AddRefed<SVGAnimatedLength> Width();
   already_AddRefed<SVGAnimatedLength> Height();
 
 protected:
 
-  virtual LengthAttributesInfo GetLengthInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGGradientElement.h
+++ b/content/svg/content/src/SVGGradientElement.h
@@ -45,33 +45,33 @@ protected:
   SVGGradientElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE = 0;
 
 public:
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE = 0;
 
   // nsIContent
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   virtual nsSVGAnimatedTransformList*
-    GetAnimatedTransformList(uint32_t aFlags = 0);
-  virtual nsIAtom* GetTransformListAttrName() const {
+    GetAnimatedTransformList(uint32_t aFlags = 0) MOZ_OVERRIDE;
+  virtual nsIAtom* GetTransformListAttrName() const MOZ_OVERRIDE {
     return nsGkAtoms::gradientTransform;
   }
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> GradientUnits();
   already_AddRefed<SVGAnimatedTransformList> GradientTransform();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> SpreadMethod();
   already_AddRefed<nsIDOMSVGAnimatedString> Href();
 
 protected:
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { GRADIENTUNITS, SPREADMETHOD };
   nsSVGEnum mEnumAttributes[2];
   static nsSVGEnumMapping sSpreadMethodMap[];
   static EnumInfo sEnumInfo[2];
 
   enum { HREF };
   nsSVGString mStringAttributes[1];
@@ -93,27 +93,27 @@ class SVGLinearGradientElement : public 
                                       already_AddRefed<nsINodeInfo> aNodeInfo));
 
 protected:
   SVGLinearGradientElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<SVGAnimatedLength> X1();
   already_AddRefed<SVGAnimatedLength> Y1();
   already_AddRefed<SVGAnimatedLength> X2();
   already_AddRefed<SVGAnimatedLength> Y2();
 
 protected:
 
-  virtual LengthAttributesInfo GetLengthInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X1, ATTR_Y1, ATTR_X2, ATTR_Y2 };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 };
 
 //-------------------------- Radial Gradients ----------------------------
 
@@ -127,27 +127,27 @@ class SVGRadialGradientElement : public 
                                       already_AddRefed<nsINodeInfo> aNodeInfo));
 
 protected:
   SVGRadialGradientElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext* aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<SVGAnimatedLength> Cx();
   already_AddRefed<SVGAnimatedLength> Cy();
   already_AddRefed<SVGAnimatedLength> R();
   already_AddRefed<SVGAnimatedLength> Fx();
   already_AddRefed<SVGAnimatedLength> Fy();
 protected:
 
-  virtual LengthAttributesInfo GetLengthInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
 
   enum { ATTR_CX, ATTR_CY, ATTR_R, ATTR_FX, ATTR_FY };
   nsSVGLength2 mLengthAttributes[5];
   static LengthInfo sLengthInfo[5];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGImageElement.h
+++ b/content/svg/content/src/SVGImageElement.h
@@ -38,33 +38,33 @@ protected:
 
 public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIContent interface
   virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
-                                const nsAttrValue* aValue, bool aNotify);
+                                const nsAttrValue* aValue, bool aNotify) MOZ_OVERRIDE;
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
-                              bool aCompileEventHandlers);
-  virtual void UnbindFromTree(bool aDeep, bool aNullParent);
+                              bool aCompileEventHandlers) MOZ_OVERRIDE;
+  virtual void UnbindFromTree(bool aDeep, bool aNullParent) MOZ_OVERRIDE;
 
-  virtual nsEventStates IntrinsicState() const;
+  virtual nsEventStates IntrinsicState() const MOZ_OVERRIDE;
 
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const MOZ_OVERRIDE;
 
   // nsSVGPathGeometryElement methods:
-  virtual void ConstructPath(gfxContext *aCtx);
+  virtual void ConstructPath(gfxContext *aCtx) MOZ_OVERRIDE;
 
   // nsSVGSVGElement methods:
-  virtual bool HasValidDimensions() const;
+  virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   nsresult CopyInnerTo(mozilla::dom::Element* aDest);
 
   void MaybeLoadSVGImage();
 
   bool IsImageSrcSetDisabled() const;
 
   // WebIDL
@@ -73,19 +73,19 @@ public:
   already_AddRefed<SVGAnimatedLength> Width();
   already_AddRefed<SVGAnimatedLength> Height();
   already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
   already_AddRefed<nsIDOMSVGAnimatedString> Href();
 
 protected:
   nsresult LoadSVGImage(bool aForce, bool aNotify);
 
-  virtual LengthAttributesInfo GetLengthInfo();
-  virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
+  virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
 
   enum { HREF };
--- a/content/svg/content/src/SVGLineElement.h
+++ b/content/svg/content/src/SVGLineElement.h
@@ -23,34 +23,34 @@ protected:
   SVGLineElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
   friend nsresult (::NS_NewSVGLineElement(nsIContent **aResult,
                                           already_AddRefed<nsINodeInfo> aNodeInfo));
 
 public:
   // nsIContent interface
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const MOZ_OVERRIDE;
 
   // nsSVGPathGeometryElement methods:
-  virtual bool IsMarkable() { return true; }
-  virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks);
-  virtual void ConstructPath(gfxContext *aCtx);
+  virtual bool IsMarkable() MOZ_OVERRIDE { return true; }
+  virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks) MOZ_OVERRIDE;
+  virtual void ConstructPath(gfxContext *aCtx) MOZ_OVERRIDE;
 
   virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
 
   // WebIDL
   already_AddRefed<SVGAnimatedLength> X1();
   already_AddRefed<SVGAnimatedLength> Y1();
   already_AddRefed<SVGAnimatedLength> X2();
   already_AddRefed<SVGAnimatedLength> Y2();
 
 protected:
 
-  virtual LengthAttributesInfo GetLengthInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X1, ATTR_Y1, ATTR_X2, ATTR_Y2 };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGMPathElement.h
+++ b/content/svg/content/src/SVGMPathElement.h
@@ -37,29 +37,29 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGMPathElement,
                                            SVGMPathElementBase)
 
   NS_DECL_NSIMUTATIONOBSERVER_ATTRIBUTECHANGED
 
   // nsIContent interface
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
-                              bool aCompileEventHandlers);
-  virtual void UnbindFromTree(bool aDeep, bool aNullParent);
+                              bool aCompileEventHandlers) MOZ_OVERRIDE;
+  virtual void UnbindFromTree(bool aDeep, bool aNullParent) MOZ_OVERRIDE;
 
   virtual nsresult UnsetAttr(int32_t aNamespaceID, nsIAtom* aAttribute,
-                             bool aNotify);
+                             bool aNotify) MOZ_OVERRIDE;
   // Element specializations
   virtual bool ParseAttribute(int32_t aNamespaceID,
                                 nsIAtom* aAttribute,
                                 const nsAString& aValue,
-                                nsAttrValue& aResult);
+                                nsAttrValue& aResult) MOZ_OVERRIDE;
 
   // Public helper method: If our xlink:href attribute links to a <path>
   // element, this method returns a pointer to that element. Otherwise,
   // this returns nullptr.
   SVGPathElement* GetReferencedPath();
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> Href();
@@ -68,35 +68,35 @@ protected:
   class PathReference : public nsReferencedElement {
   public:
     PathReference(SVGMPathElement* aMpathElement) :
       mMpathElement(aMpathElement) {}
   protected:
     // We need to be notified when target changes, in order to request a sample
     // (which will clear animation effects that used the old target-path
     // and recompute the animation effects using the new target-path).
-    virtual void ElementChanged(Element* aFrom, Element* aTo) {
+    virtual void ElementChanged(Element* aFrom, Element* aTo) MOZ_OVERRIDE {
       nsReferencedElement::ElementChanged(aFrom, aTo);
       if (aFrom) {
         aFrom->RemoveMutationObserver(mMpathElement);
       }
       if (aTo) {
         aTo->AddMutationObserver(mMpathElement);
       }
       mMpathElement->NotifyParentOfMpathChange(mMpathElement->GetParent());
     }
 
     // We need to override IsPersistent to get persistent tracking (beyond the
     // first time the target changes)
-    virtual bool IsPersistent() { return true; }
+    virtual bool IsPersistent() MOZ_OVERRIDE { return true; }
   private:
     SVGMPathElement* const mMpathElement;
   };
 
-  virtual StringAttributesInfo GetStringInfo();
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   void UpdateHrefTarget(nsIContent* aParent, const nsAString& aHrefStr);
   void UnlinkHrefTarget(bool aNotifyParent);
   void NotifyParentOfMpathChange(nsIContent* aParent);
 
   enum { HREF };
   nsSVGString        mStringAttributes[1];
   static StringInfo  sStringInfo[1];
--- a/content/svg/content/src/SVGMarkerElement.h
+++ b/content/svg/content/src/SVGMarkerElement.h
@@ -70,21 +70,21 @@ private:
 
     DOMAnimatedEnum(nsSVGOrientType* aVal,
                     nsSVGElement *aSVGElement)
       : mVal(aVal), mSVGElement(aSVGElement) {}
 
     nsSVGOrientType *mVal; // kept alive because it belongs to content
     nsRefPtr<nsSVGElement> mSVGElement;
 
-    NS_IMETHOD GetBaseVal(uint16_t* aResult)
+    NS_IMETHOD GetBaseVal(uint16_t* aResult) MOZ_OVERRIDE
       { *aResult = mVal->GetBaseValue(); return NS_OK; }
-    NS_IMETHOD SetBaseVal(uint16_t aValue)
+    NS_IMETHOD SetBaseVal(uint16_t aValue) MOZ_OVERRIDE
       { return mVal->SetBaseValue(aValue, mSVGElement); }
-    NS_IMETHOD GetAnimVal(uint16_t* aResult)
+    NS_IMETHOD GetAnimVal(uint16_t* aResult) MOZ_OVERRIDE
       { *aResult = mVal->GetAnimValue(); return NS_OK; }
   };
 };
 
 typedef nsSVGElement SVGMarkerElementBase;
 
 class SVGMarkerElement : public SVGMarkerElementBase
 {
@@ -94,31 +94,31 @@ protected:
   friend nsresult (::NS_NewSVGMarkerElement(nsIContent **aResult,
                                             already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGMarkerElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   // nsIContent interface
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const MOZ_OVERRIDE;
 
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
-                             bool aNotify);
+                             bool aNotify) MOZ_OVERRIDE;
 
   // nsSVGSVGElement methods:
-  virtual bool HasValidDimensions() const;
+  virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // public helpers
   gfxMatrix GetMarkerTransform(float aStrokeWidth,
                                float aX, float aY, float aAutoAngle);
   nsSVGViewBoxRect GetViewBoxRect();
   gfxMatrix GetViewBoxTransform();
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   nsSVGOrientType* GetOrientType() { return &mOrientType; }
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedRect> ViewBox();
   already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
   already_AddRefed<SVGAnimatedLength> RefX();
   already_AddRefed<SVGAnimatedLength> RefY();
@@ -129,25 +129,25 @@ public:
   already_AddRefed<SVGAnimatedAngle> OrientAngle();
   void SetOrientToAuto();
   void SetOrientToAngle(SVGAngle& angle, ErrorResult& rv);
 
 protected:
 
   virtual bool ParseAttribute(int32_t aNameSpaceID, nsIAtom* aName,
                                 const nsAString& aValue,
-                                nsAttrValue& aResult);
+                                nsAttrValue& aResult) MOZ_OVERRIDE;
 
   void SetParentCoordCtxProvider(SVGSVGElement *aContext);
 
-  virtual LengthAttributesInfo GetLengthInfo();
-  virtual AngleAttributesInfo GetAngleInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual nsSVGViewBox *GetViewBox();
-  virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
+  virtual AngleAttributesInfo GetAngleInfo() MOZ_OVERRIDE;
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
+  virtual nsSVGViewBox *GetViewBox() MOZ_OVERRIDE;
+  virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() MOZ_OVERRIDE;
 
   enum { REFX, REFY, MARKERWIDTH, MARKERHEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 
   enum { MARKERUNITS };
   nsSVGEnum mEnumAttributes[1];
   static nsSVGEnumMapping sUnitsMap[];
--- a/content/svg/content/src/SVGMaskElement.h
+++ b/content/svg/content/src/SVGMaskElement.h
@@ -30,34 +30,34 @@ protected:
   friend nsresult (::NS_NewSVGMaskElement(nsIContent **aResult,
                                           already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGMaskElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   // nsIContent interface
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   // nsSVGSVGElement methods:
-  virtual bool HasValidDimensions() const;
+  virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> MaskUnits();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> MaskContentUnits();
   already_AddRefed<SVGAnimatedLength> X();
   already_AddRefed<SVGAnimatedLength> Y();
   already_AddRefed<SVGAnimatedLength> Width();
   already_AddRefed<SVGAnimatedLength> Height();
 
 protected:
 
-  virtual LengthAttributesInfo GetLengthInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 
   enum { MASKUNITS, MASKCONTENTUNITS };
   nsSVGEnum mEnumAttributes[2];
   static EnumInfo sEnumInfo[2];
--- a/content/svg/content/src/SVGPathElement.h
+++ b/content/svg/content/src/SVGPathElement.h
@@ -32,37 +32,37 @@ protected:
   friend nsresult (::NS_NewSVGPathElement(nsIContent **aResult,
                                           already_AddRefed<nsINodeInfo> aNodeInfo));
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
   SVGPathElement(already_AddRefed<nsINodeInfo> aNodeInfo);
 
 public:
   // nsIContent interface
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const MOZ_OVERRIDE;
 
   // nsSVGSVGElement methods:
-  virtual bool HasValidDimensions() const;
+  virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // nsSVGPathGeometryElement methods:
-  virtual bool AttributeDefinesGeometry(const nsIAtom *aName);
-  virtual bool IsMarkable();
-  virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks);
-  virtual void ConstructPath(gfxContext *aCtx);
+  virtual bool AttributeDefinesGeometry(const nsIAtom *aName) MOZ_OVERRIDE;
+  virtual bool IsMarkable() MOZ_OVERRIDE;
+  virtual void GetMarkPoints(nsTArray<nsSVGMark> *aMarks) MOZ_OVERRIDE;
+  virtual void ConstructPath(gfxContext *aCtx) MOZ_OVERRIDE;
 
-  virtual already_AddRefed<gfxFlattenedPath> GetFlattenedPath(const gfxMatrix &aMatrix);
+  virtual already_AddRefed<gfxFlattenedPath> GetFlattenedPath(const gfxMatrix &aMatrix) MOZ_OVERRIDE;
 
   // nsIContent interface
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
-  virtual SVGAnimatedPathSegList* GetAnimPathSegList() {
+  virtual SVGAnimatedPathSegList* GetAnimPathSegList() MOZ_OVERRIDE {
     return &mD;
   }
 
-  virtual nsIAtom* GetPathDataAttrName() const {
+  virtual nsIAtom* GetPathDataAttrName() const MOZ_OVERRIDE {
     return nsGkAtoms::d;
   }
 
   enum PathLengthScaleForType {
     eForTextPath,
     eForStroking
   };
 
@@ -108,17 +108,17 @@ public:
   already_AddRefed<DOMSVGPathSegCurvetoQuadraticSmoothRel>
     CreateSVGPathSegCurvetoQuadraticSmoothRel(float x, float y);
   already_AddRefed<DOMSVGPathSegList> PathSegList();
   already_AddRefed<DOMSVGPathSegList> AnimatedPathSegList();
 
 protected:
 
   // nsSVGElement method
-  virtual NumberAttributesInfo GetNumberInfo();
+  virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
 
   SVGAnimatedPathSegList mD;
   nsSVGNumber2 mPathLength;
   static NumberInfo sNumberInfo;
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGPatternElement.h
+++ b/content/svg/content/src/SVGPatternElement.h
@@ -35,26 +35,26 @@ protected:
   SVGPatternElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   typedef mozilla::SVGAnimatedPreserveAspectRatio SVGAnimatedPreserveAspectRatio;
 
   // nsIContent interface
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // nsSVGSVGElement methods:
-  virtual bool HasValidDimensions() const;
+  virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   virtual mozilla::nsSVGAnimatedTransformList*
-    GetAnimatedTransformList(uint32_t aFlags = 0);
-  virtual nsIAtom* GetTransformListAttrName() const {
+    GetAnimatedTransformList(uint32_t aFlags = 0) MOZ_OVERRIDE;
+  virtual nsIAtom* GetTransformListAttrName() const MOZ_OVERRIDE {
     return nsGkAtoms::patternTransform;
   }
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedRect> ViewBox();
   already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> PatternUnits();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> PatternContentUnits();
@@ -62,21 +62,21 @@ public:
   already_AddRefed<SVGAnimatedLength> X();
   already_AddRefed<SVGAnimatedLength> Y();
   already_AddRefed<SVGAnimatedLength> Width();
   already_AddRefed<SVGAnimatedLength> Height();
   already_AddRefed<nsIDOMSVGAnimatedString> Href();
 
 protected:
 
-  virtual LengthAttributesInfo GetLengthInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual nsSVGViewBox *GetViewBox();
-  virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
+  virtual nsSVGViewBox *GetViewBox() MOZ_OVERRIDE;
+  virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 
   enum { PATTERNUNITS, PATTERNCONTENTUNITS };
   nsSVGEnum mEnumAttributes[2];
   static EnumInfo sEnumInfo[2];
--- a/content/svg/content/src/SVGRectElement.h
+++ b/content/svg/content/src/SVGRectElement.h
@@ -23,34 +23,34 @@ protected:
   SVGRectElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
   friend nsresult (::NS_NewSVGRectElement(nsIContent **aResult,
                                           already_AddRefed<nsINodeInfo> aNodeInfo));
 
 public:
   // nsSVGSVGElement methods:
-  virtual bool HasValidDimensions() const;
+  virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // nsSVGPathGeometryElement methods:
-  virtual void ConstructPath(gfxContext *aCtx);
+  virtual void ConstructPath(gfxContext *aCtx) MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<SVGAnimatedLength> X();
   already_AddRefed<SVGAnimatedLength> Y();
   already_AddRefed<SVGAnimatedLength> Height();
   already_AddRefed<SVGAnimatedLength> Width();
   already_AddRefed<SVGAnimatedLength> Rx();
   already_AddRefed<SVGAnimatedLength> Ry();
 
 protected:
 
-  virtual LengthAttributesInfo GetLengthInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT, ATTR_RX, ATTR_RY };
   nsSVGLength2 mLengthAttributes[6];
   static LengthInfo sLengthInfo[6];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGSVGElement.cpp
+++ b/content/svg/content/src/SVGSVGElement.cpp
@@ -701,19 +701,18 @@ SVGSVGElement::ChildrenOnlyTransformChan
   UpdateHasChildrenOnlyTransform();
 
   if (hadChildrenOnlyTransform != mHasChildrenOnlyTransform) {
     // Reconstruct the frame tree to handle stacking context changes:
     // XXXjwatt don't do this for root-<svg> or even outer-<svg>?
     changeHint = nsChangeHint_ReconstructFrame;
   } else {
     // We just assume the old and new transforms are different.
-    changeHint = nsChangeHint(nsChangeHint_RepaintFrame |
-                   nsChangeHint_UpdateOverflow |
-                   nsChangeHint_ChildrenOnlyTransform);
+    changeHint = nsChangeHint(nsChangeHint_UpdateOverflow |
+                              nsChangeHint_ChildrenOnlyTransform);
   }
 
   // If we're not reconstructing the frame tree, then we only call
   // PostRestyleEvent if we're not being called under reflow to avoid recursing
   // to death. See bug 767056 comments 10 and 12. Since our nsSVGOuterSVGFrame
   // is being reflowed we're going to invalidate and repaint its entire area
   // anyway (which will include our children).
   if ((changeHint & nsChangeHint_ReconstructFrame) ||
--- a/content/svg/content/src/SVGSVGElement.h
+++ b/content/svg/content/src/SVGSVGElement.h
@@ -47,24 +47,24 @@ public:
     : nsISVGPoint(aPt), mElement(aElement) {}
 
   DOMSVGTranslatePoint(DOMSVGTranslatePoint* aPt)
     : nsISVGPoint(&aPt->mPt), mElement(aPt->mElement) {}
 
   NS_DECL_ISUPPORTS_INHERITED
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMSVGTranslatePoint, nsISVGPoint)
 
-  virtual nsISVGPoint* Clone();
+  virtual nsISVGPoint* Clone() MOZ_OVERRIDE;
 
   // WebIDL
-  virtual float X() { return mPt.GetX(); }
-  virtual float Y() { return mPt.GetY(); }
-  virtual void SetX(float aValue, ErrorResult& rv);
-  virtual void SetY(float aValue, ErrorResult& rv);
-  virtual already_AddRefed<nsISVGPoint> MatrixTransform(SVGMatrix& matrix);
+  virtual float X() MOZ_OVERRIDE { return mPt.GetX(); }
+  virtual float Y() MOZ_OVERRIDE { return mPt.GetY(); }
+  virtual void SetX(float aValue, ErrorResult& rv) MOZ_OVERRIDE;
+  virtual void SetY(float aValue, ErrorResult& rv) MOZ_OVERRIDE;
+  virtual already_AddRefed<nsISVGPoint> MatrixTransform(SVGMatrix& matrix) MOZ_OVERRIDE;
 
   virtual nsISupports* GetParentObject() MOZ_OVERRIDE;
 
   nsRefPtr<SVGSVGElement> mElement;
 };
 
 class svgFloatSize {
 public:
@@ -120,25 +120,25 @@ public:
    * currentTranslate.y prior to the last change made to any one of them.
    */
   const SVGPoint& GetPreviousTranslate() { return mPreviousTranslate; }
   float GetPreviousScale() { return mPreviousScale; }
 
   nsSMILTimeContainer* GetTimedDocumentRoot();
 
   // nsIContent interface
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
-  virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
+  virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) MOZ_OVERRIDE;
 
   virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
 
   // nsSVGElement specializations:
   virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
-                      TransformTypes aWhich = eAllTransforms) const;
-  virtual bool HasValidDimensions() const;
+                      TransformTypes aWhich = eAllTransforms) const MOZ_OVERRIDE;
+  virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // SVGSVGElement methods:
   float GetLength(uint8_t mCtxType);
 
   // public helpers:
 
   /**
    * Returns true if this element has a base/anim value for its "viewBox"
@@ -191,17 +191,17 @@ public:
    */
   void ChildrenOnlyTransformChanged(uint32_t aFlags = 0);
 
   // This services any pending notifications for the transform on on this root
   // <svg> node needing to be recalculated.  (Only applicable in
   // SVG-as-an-image documents.)
   virtual void FlushImageTransformInvalidation();
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // Returns true IFF our attributes are currently overridden by a <view>
   // element and that element's ID matches the passed-in string.
   bool IsOverriddenBy(const nsAString &aViewID) const {
     return mCurrentViewID && mCurrentViewID->Equals(aViewID);
   }
 
   svgFloatSize GetViewportSize() const {
@@ -250,18 +250,18 @@ public:
   uint16_t ZoomAndPan();
   void SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv);
 
 private:
   // nsSVGElement overrides
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
-                              bool aCompileEventHandlers);
-  virtual void UnbindFromTree(bool aDeep, bool aNullParent);
+                              bool aCompileEventHandlers) MOZ_OVERRIDE;
+  virtual void UnbindFromTree(bool aDeep, bool aNullParent) MOZ_OVERRIDE;
 
   // implementation helpers:
 
   SVGViewElement* GetCurrentViewElement() const;
 
   // Methods for <image> elements to override my "PreserveAspectRatio" value.
   // These are private so that only our friends (AutoSVGRenderingState in
   // particular) have access.
@@ -327,31 +327,31 @@ private:
   nsSVGViewBoxRect GetViewBoxWithSynthesis(
       float aViewportWidth, float aViewportHeight) const;
   /**
    * Returns the explicit or default preserveAspectRatio, unless we're
    * synthesizing a viewBox, in which case it returns the "none" value.
    */
   SVGPreserveAspectRatio GetPreserveAspectRatioWithOverride() const;
 
-  virtual LengthAttributesInfo GetLengthInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 
-  virtual EnumAttributesInfo GetEnumInfo();
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
 
   enum { ZOOMANDPAN };
   nsSVGEnum mEnumAttributes[1];
   static nsSVGEnumMapping sZoomAndPanMap[];
   static EnumInfo sEnumInfo[1];
 
-  virtual nsSVGViewBox *GetViewBox();
-  virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio();
+  virtual nsSVGViewBox *GetViewBox() MOZ_OVERRIDE;
+  virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() MOZ_OVERRIDE;
 
   nsSVGViewBox                   mViewBox;
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
 
   nsAutoPtr<nsString>            mCurrentViewID;
 
   // The size of the rectangular SVG viewport into which we render. This is
   // not (necessarily) the same as the content area. See:
--- a/content/svg/content/src/SVGScriptElement.h
+++ b/content/svg/content/src/SVGScriptElement.h
@@ -37,47 +37,47 @@ protected:
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
   // interfaces:
 
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIScriptElement
-  virtual void GetScriptType(nsAString& type);
-  virtual void GetScriptText(nsAString& text);
-  virtual void GetScriptCharset(nsAString& charset);
-  virtual void FreezeUriAsyncDefer();
-  virtual CORSMode GetCORSMode() const;
+  virtual void GetScriptType(nsAString& type) MOZ_OVERRIDE;
+  virtual void GetScriptText(nsAString& text) MOZ_OVERRIDE;
+  virtual void GetScriptCharset(nsAString& charset) MOZ_OVERRIDE;
+  virtual void FreezeUriAsyncDefer() MOZ_OVERRIDE;
+  virtual CORSMode GetCORSMode() const MOZ_OVERRIDE;
 
   // nsScriptElement
-  virtual bool HasScriptContent();
+  virtual bool HasScriptContent() MOZ_OVERRIDE;
 
   // nsIContent specializations:
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
-                              bool aCompileEventHandlers);
+                              bool aCompileEventHandlers) MOZ_OVERRIDE;
   virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
-                                const nsAttrValue* aValue, bool aNotify);
+                                const nsAttrValue* aValue, bool aNotify) MOZ_OVERRIDE;
   virtual bool ParseAttribute(int32_t aNamespaceID,
                               nsIAtom* aAttribute,
                               const nsAString& aValue,
-                              nsAttrValue& aResult);
+                              nsAttrValue& aResult) MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   void GetType(nsAString & aType);
   void SetType(const nsAString & aType, ErrorResult& rv);
   void GetCrossOrigin(nsAString & aOrigin);
   void SetCrossOrigin(const nsAString & aOrigin, ErrorResult& rv);
   already_AddRefed<nsIDOMSVGAnimatedString> Href();
 
 protected:
-  virtual StringAttributesInfo GetStringInfo();
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { HREF };
   nsSVGString mStringAttributes[1];
   static StringInfo sStringInfo[1];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGStopElement.h
+++ b/content/svg/content/src/SVGStopElement.h
@@ -23,26 +23,26 @@ protected:
   friend nsresult (::NS_NewSVGStopElement(nsIContent **aResult,
                                           already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGStopElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *aCx,
                              JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
 
 public:
   // nsIContent interface
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedNumber> Offset();
 
 protected:
 
-  virtual NumberAttributesInfo GetNumberInfo();
+  virtual NumberAttributesInfo GetNumberInfo() MOZ_OVERRIDE;
   nsSVGNumber2 mOffset;
   static NumberInfo sNumberInfo;
 };
 
 } // namespace dom
 } // namespace mozilla
 
 #endif // mozilla_dom_SVGStopElement_h
--- a/content/svg/content/src/SVGStyleElement.h
+++ b/content/svg/content/src/SVGStyleElement.h
@@ -34,35 +34,35 @@ public:
   NS_DECL_ISUPPORTS_INHERITED
 
   NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGStyleElement,
                                            SVGStyleElementBase)
 
   // nsIContent
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
-                              bool aCompileEventHandlers);
+                              bool aCompileEventHandlers) MOZ_OVERRIDE;
   virtual void UnbindFromTree(bool aDeep = true,
-                              bool aNullParent = true);
+                              bool aNullParent = true) MOZ_OVERRIDE;
   nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                    const nsAString& aValue, bool aNotify)
   {
     return SetAttr(aNameSpaceID, aName, nullptr, aValue, aNotify);
   }
   virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
                            nsIAtom* aPrefix, const nsAString& aValue,
-                           bool aNotify);
+                           bool aNotify) MOZ_OVERRIDE;
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
-                             bool aNotify);
+                             bool aNotify) MOZ_OVERRIDE;
   virtual bool ParseAttribute(int32_t aNamespaceID,
                               nsIAtom* aAttribute,
                               const nsAString& aValue,
-                              nsAttrValue& aResult);
+                              nsAttrValue& aResult) MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // nsIMutationObserver
   NS_DECL_NSIMUTATIONOBSERVER_CHARACTERDATACHANGED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTAPPENDED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTINSERTED
   NS_DECL_NSIMUTATIONOBSERVER_CONTENTREMOVED
 
   // WebIDL
@@ -89,17 +89,17 @@ protected:
   // nsStyleLinkElement overrides
   already_AddRefed<nsIURI> GetStyleSheetURL(bool* aIsInline);
 
   void GetStyleSheetInfo(nsAString& aTitle,
                          nsAString& aType,
                          nsAString& aMedia,
                          bool* aIsScoped,
                          bool* aIsAlternate);
-  virtual CORSMode GetCORSMode() const;
+  virtual CORSMode GetCORSMode() const MOZ_OVERRIDE;
 
   /**
    * Common method to call from the various mutation observer methods.
    * aContent is a content node that's either the one that changed or its
    * parent; we should only respond to the change if aContent is non-anonymous.
    */
   void ContentChanged(nsIContent* aContent);
 };
--- a/content/svg/content/src/SVGTSpanElement.h
+++ b/content/svg/content/src/SVGTSpanElement.h
@@ -22,19 +22,19 @@ protected:
   friend nsresult (::NS_NewSVGTSpanElement(nsIContent **aResult,
                                            already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGTSpanElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   // nsIContent interface
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 protected:
 
   // nsSVGElement overrides
   virtual bool IsEventName(nsIAtom* aName);
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/SVGTextPathElement.h
+++ b/content/svg/content/src/SVGTextPathElement.h
@@ -42,33 +42,33 @@ protected:
   friend nsresult (::NS_NewSVGTextPathElement(nsIContent **aResult,
                                               already_AddRefed<nsINodeInfo> aNodeInfo));
   SVGTextPathElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
   // nsIContent interface
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<SVGAnimatedLength> StartOffset();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> Method();
   already_AddRefed<nsIDOMSVGAnimatedEnumeration> Spacing();
   already_AddRefed<nsIDOMSVGAnimatedString> Href();
 
  protected:
 
-  virtual LengthAttributesInfo GetLengthInfo();
-  virtual EnumAttributesInfo GetEnumInfo();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   enum { STARTOFFSET };
   nsSVGLength2 mLengthAttributes[1];
   static LengthInfo sLengthInfo[1];
 
   enum { METHOD, SPACING };
   nsSVGEnum mEnumAttributes[2];
   static nsSVGEnumMapping sMethodMap[];
--- a/content/svg/content/src/SVGTextPositioningElement.h
+++ b/content/svg/content/src/SVGTextPositioningElement.h
@@ -31,18 +31,18 @@ public:
   already_AddRefed<DOMSVGAnimatedNumberList> Rotate();
 
 protected:
 
   SVGTextPositioningElement(already_AddRefed<nsINodeInfo> aNodeInfo)
     : SVGTextPositioningElementBase(aNodeInfo)
   {}
 
-  virtual LengthListAttributesInfo GetLengthListInfo();
-  virtual NumberListAttributesInfo GetNumberListInfo();
+  virtual LengthListAttributesInfo GetLengthListInfo() MOZ_OVERRIDE;
+  virtual NumberListAttributesInfo GetNumberListInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X, ATTR_Y, ATTR_DX, ATTR_DY };
   SVGAnimatedLengthList mLengthListAttributes[4];
   static LengthListInfo sLengthListInfo[4];
 
   enum { ROTATE };
   SVGAnimatedNumberList mNumberListAttributes[1];
   static NumberListInfo sNumberListInfo[1];
--- a/content/svg/content/src/SVGUseElement.h
+++ b/content/svg/content/src/SVGUseElement.h
@@ -57,48 +57,48 @@ public:
 
   // for nsSVGUseFrame's nsIAnonymousContentCreator implementation.
   nsIContent* CreateAnonymousContent();
   nsIContent* GetAnonymousContent() const { return mClone; }
   void DestroyAnonymousContent();
 
   // nsSVGElement specializations:
   virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
-                      TransformTypes aWhich = eAllTransforms) const;
-  virtual bool HasValidDimensions() const;
+                      TransformTypes aWhich = eAllTransforms) const MOZ_OVERRIDE;
+  virtual bool HasValidDimensions() const MOZ_OVERRIDE;
 
   // nsIContent interface
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   // WebIDL
   already_AddRefed<nsIDOMSVGAnimatedString> Href();
   already_AddRefed<SVGAnimatedLength> X();
   already_AddRefed<SVGAnimatedLength> Y();
   already_AddRefed<SVGAnimatedLength> Width();
   already_AddRefed<SVGAnimatedLength> Height();
 
 protected:
   class SourceReference : public nsReferencedElement {
   public:
     SourceReference(SVGUseElement* aContainer) : mContainer(aContainer) {}
   protected:
-    virtual void ElementChanged(Element* aFrom, Element* aTo) {
+    virtual void ElementChanged(Element* aFrom, Element* aTo) MOZ_OVERRIDE {
       nsReferencedElement::ElementChanged(aFrom, aTo);
       if (aFrom) {
         aFrom->RemoveMutationObserver(mContainer);
       }
       mContainer->TriggerReclone();
     }
   private:
     SVGUseElement* mContainer;
   };
 
-  virtual LengthAttributesInfo GetLengthInfo();
-  virtual StringAttributesInfo GetStringInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
+  virtual StringAttributesInfo GetStringInfo() MOZ_OVERRIDE;
 
   /**
    * Returns true if our width and height should be used, or false if they
    * should be ignored. As per the spec, this depends on the type of the
    * element that we're referencing.
    */
   bool OurWidthAndHeightAreUsed() const;
   void SyncWidthOrHeight(nsIAtom *aName);
--- a/content/svg/content/src/SVGViewElement.h
+++ b/content/svg/content/src/SVGViewElement.h
@@ -37,43 +37,43 @@ protected:
   friend class ::nsSVGOuterSVGFrame;
   SVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo);
   friend nsresult (::NS_NewSVGViewElement(nsIContent **aResult,
                                           already_AddRefed<nsINodeInfo> aNodeInfo));
   virtual JSObject* WrapNode(JSContext *cx,
                              JS::Handle<JSObject*> scope) MOZ_OVERRIDE;
 
 public:
-  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
+  virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const MOZ_OVERRIDE;
 
   // WebIDL
   uint16_t ZoomAndPan() { return mEnumAttributes[ZOOMANDPAN].GetAnimValue(); }
   void SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv);
   already_AddRefed<nsIDOMSVGAnimatedRect> ViewBox();
   already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
   already_AddRefed<DOMSVGStringList> ViewTarget();
 
 private:
 
   // nsSVGElement overrides
 
-  virtual EnumAttributesInfo GetEnumInfo();
+  virtual EnumAttributesInfo GetEnumInfo() MOZ_OVERRIDE;
 
   enum { ZOOMANDPAN };
   nsSVGEnum mEnumAttributes[1];
   static nsSVGEnumMapping sZoomAndPanMap[];
   static EnumInfo sEnumInfo[1];
 
-  virtual nsSVGViewBox *GetViewBox();
-  virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio();
+  virtual nsSVGViewBox *GetViewBox() MOZ_OVERRIDE;
+  virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio() MOZ_OVERRIDE;
 
   nsSVGViewBox                   mViewBox;
   SVGAnimatedPreserveAspectRatio mPreserveAspectRatio;
 
-  virtual StringListAttributesInfo GetStringListInfo();
+  virtual StringListAttributesInfo GetStringListInfo() MOZ_OVERRIDE;
 
   enum { VIEW_TARGET };
   SVGStringList mStringListAttributes[1];
   static StringListInfo sStringListInfo[1];
 };
 
 } // namespace dom
 } // namespace mozilla
--- a/content/svg/content/src/nsSVGElement.h
+++ b/content/svg/content/src/nsSVGElement.h
@@ -84,36 +84,36 @@ public:
   typedef mozilla::SVGAnimatedPathSegList SVGAnimatedPathSegList;
   typedef mozilla::SVGAnimatedPreserveAspectRatio SVGAnimatedPreserveAspectRatio;
   typedef mozilla::nsSVGAnimatedTransformList nsSVGAnimatedTransformList;
   typedef mozilla::SVGStringList SVGStringList;
 
   // nsISupports
   NS_DECL_ISUPPORTS_INHERITED
 
-  virtual const nsAttrValue* DoGetClasses() const;
+  virtual const nsAttrValue* DoGetClasses() const MOZ_OVERRIDE;
   void DidAnimateClass();
 
   // nsIContent interface methods
 
   virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
                               nsIContent* aBindingParent,
-                              bool aCompileEventHandlers);
+                              bool aCompileEventHandlers) MOZ_OVERRIDE;
 
   virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
-                             bool aNotify);
+                             bool aNotify) MOZ_OVERRIDE;
 
   virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
-                                              int32_t aModType) const;
+                                              int32_t aModType) const MOZ_OVERRIDE;
 
-  virtual bool IsNodeOfType(uint32_t aFlags) const;
+  virtual bool IsNodeOfType(uint32_t aFlags) const MOZ_OVERRIDE;
 
-  NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
+  NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) MOZ_OVERRIDE;
 
-  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
+  NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const MOZ_OVERRIDE;
 
   static const MappedAttributeEntry sFillStrokeMap[];
   static const MappedAttributeEntry sGraphicsMap[];
   static const MappedAttributeEntry sTextContentElementsMap[];
   static const MappedAttributeEntry sFontSpecificationMap[];
   static const MappedAttributeEntry sGradientStopMap[];
   static const MappedAttributeEntry sViewportsMap[];
   static const MappedAttributeEntry sMarkersMap[];
@@ -314,22 +314,22 @@ protected:
 #ifdef DEBUG
   // We define BeforeSetAttr here and mark it MOZ_FINAL to ensure it is NOT used
   // by SVG elements.
   // This is because we're not currently passing the correct value for aValue to
   // BeforeSetAttr since it would involve allocating extra SVG value types.
   // See the comment in nsSVGElement::WillChangeValue.
   virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
                                  const nsAttrValueOrString* aValue,
-                                 bool aNotify) MOZ_FINAL { return NS_OK; }
+                                 bool aNotify) MOZ_OVERRIDE MOZ_FINAL { return NS_OK; }
 #endif // DEBUG
   virtual nsresult AfterSetAttr(int32_t aNamespaceID, nsIAtom* aName,
-                                const nsAttrValue* aValue, bool aNotify);
+                                const nsAttrValue* aValue, bool aNotify) MOZ_OVERRIDE;
   virtual bool ParseAttribute(int32_t aNamespaceID, nsIAtom* aAttribute,
-                                const nsAString& aValue, nsAttrValue& aResult);
+                                const nsAString& aValue, nsAttrValue& aResult) MOZ_OVERRIDE;
   static nsresult ReportAttributeParseFailure(nsIDocument* aDocument,
                                               nsIAtom* aAttribute,
                                               const nsAString& aValue);
 
   void UpdateContentStyleRule();
   void UpdateAnimatedContentStyleRule();
   mozilla::css::StyleRule* GetAnimatedContentStyleRule();
 
--- a/content/svg/content/src/nsSVGFilters.h
+++ b/content/svg/content/src/nsSVGFilters.h
@@ -220,17 +220,17 @@ protected:
     if (!frame) return false;
 
     nsStyleContext* style = frame->StyleContext();
     return style->StyleSVG()->mColorInterpolationFilters ==
              NS_STYLE_COLOR_INTERPOLATION_SRGB;
   }
 
   // nsSVGElement specializations:
-  virtual LengthAttributesInfo GetLengthInfo();
+  virtual LengthAttributesInfo GetLengthInfo() MOZ_OVERRIDE;
 
   enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
   nsSVGLength2 mLengthAttributes[4];
   static LengthInfo sLengthInfo[4];
 };
 
 typedef nsSVGElement SVGFEUnstyledElementBase;
 
@@ -261,42 +261,42 @@ protected:
 
 public:
   // interfaces:
   NS_DECL_ISUPPORTS_INHERITED
 
   virtual nsresult Filter(nsSVGFilterInstance* aInstance,
                           const nsTArray<const Image*>& aSources,
                           const Image* aTarget,
-                          const nsIntRect& aDataRect);
+                          const nsIntRect& aDataRect) MOZ_OVERRIDE;
   virtual bool AttributeAffectsRendering(