Merge the last PGO-green inbound changeset to m-c.
authorRyan VanderMeulen <ryanvm@gmail.com>
Wed, 02 Jan 2013 21:02:40 -0500
changeset 126444 4e18ac9b51e271770fd67b1e8dd5c4eb7d8a4f73
parent 126397 33064e13c3fde97df0c7729c847963b9fb414bda (current diff)
parent 126443 86204e3d7ce68643c7572d3f0f47be7aa99667e4 (diff)
child 126472 6955309291ee4afe219fee09987f3838ccf5ac83
child 126506 96867d3e710f6a168a2b71f0fd45ffe1a20e3ad0
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone20.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Merge the last PGO-green inbound changeset to m-c.
dom/base/nsJSEnvironment.cpp
dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing.html
toolkit/components/places/tests/browser/browser_favicon_privatebrowsing.js
--- a/Makefile.in
+++ b/Makefile.in
@@ -145,23 +145,16 @@ ifdef MOZ_SYMBOLS_EXTRA_BUILDID
 EXTRA_BUILDID := -$(MOZ_SYMBOLS_EXTRA_BUILDID)
 endif
 
 SYMBOL_INDEX_NAME = \
   $(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_TARGET)-$(BUILDID)-$(CPU_ARCH)$(EXTRA_BUILDID)-symbols.txt
 
 buildsymbols:
 ifdef MOZ_CRASHREPORTER
-ifdef USE_ELF_HACK
-    ifeq (mobile,$(MOZ_BUILD_APP))
-		$(MAKE) -C mobile/xul/installer elfhack
-    else
-		$(MAKE) -C $(MOZ_BUILD_APP)/installer elfhack
-    endif
-endif
 	echo building symbol store
 	$(RM) -r $(DIST)/crashreporter-symbols
 	$(RM) "$(DIST)/$(SYMBOL_ARCHIVE_BASENAME).zip"
 	$(NSINSTALL) -D $(DIST)/crashreporter-symbols
 	OBJCOPY="$(OBJCOPY)" \
 	$(PYTHON) $(topsrcdir)/toolkit/crashreporter/tools/symbolstore.py \
 	  $(MAKE_SYM_STORE_ARGS)                                          \
 	  $(foreach dir,$(SYM_STORE_SOURCE_DIRS),-s $(dir))               \
--- a/accessible/src/base/AccEvent.cpp
+++ b/accessible/src/base/AccEvent.cpp
@@ -1,9 +1,10 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #include "AccEvent.h"
 
 #include "ApplicationAccessibleWrap.h"
 #include "nsAccessibilityService.h"
@@ -112,20 +113,22 @@ AccTextChangeEvent::CreateXPCOMObject()
 // AccReorderEvent
 ////////////////////////////////////////////////////////////////////////////////
 
 uint32_t
 AccReorderEvent::IsShowHideEventTarget(const Accessible* aTarget) const
 {
   uint32_t count = mDependentEvents.Length();
   for (uint32_t index = count - 1; index < count; index--) {
-    if (mDependentEvents[index]->mAccessible == aTarget &&
-        mDependentEvents[index]->mEventType == nsIAccessibleEvent::EVENT_SHOW ||
-        mDependentEvents[index]->mEventType == nsIAccessibleEvent::EVENT_HIDE) {
-      return mDependentEvents[index]->mEventType;
+    if (mDependentEvents[index]->mAccessible == aTarget) {
+      uint32_t eventType = mDependentEvents[index]->mEventType;
+      if (eventType == nsIAccessibleEvent::EVENT_SHOW ||
+          eventType == nsIAccessibleEvent::EVENT_HIDE) {
+        return mDependentEvents[index]->mEventType;
+      }
     }
   }
 
   return 0;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // AccHideEvent
--- a/accessible/src/base/NotificationController.cpp
+++ b/accessible/src/base/NotificationController.cpp
@@ -636,17 +636,16 @@ NotificationController::CoalesceTextChan
   }
 
   aTailEvent->mTextChangeEvent.swap(aThisEvent->mTextChangeEvent);
 }
 
 void
 NotificationController::CreateTextChangeEventFor(AccMutationEvent* aEvent)
 {
-  DocAccessible* document = aEvent->GetDocAccessible();
   Accessible* container = aEvent->mAccessible->Parent();
   if (!container)
     return;
 
   HyperTextAccessible* textAccessible = container->AsHyperText();
   if (!textAccessible)
     return;
 
--- a/accessible/src/base/nsAccessibilityService.cpp
+++ b/accessible/src/base/nsAccessibilityService.cpp
@@ -1455,16 +1455,19 @@ nsAccessibilityService::CreateAccessible
     case ePluginType: {
       nsObjectFrame* objectFrame = do_QueryFrame(aFrame);
       newAcc = CreatePluginAccessible(objectFrame, aContent, aContext);
       break;
     }
     case eTextLeafType:
       newAcc = new TextLeafAccessibleWrap(aContent, document);
       break;
+    default:
+      MOZ_ASSERT(false);
+      break;
   }
 
   return newAcc.forget();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIAccessibilityService (DON'T put methods here)
 
--- a/b2g/components/UpdatePrompt.js
+++ b/b2g/components/UpdatePrompt.js
@@ -187,25 +187,25 @@ UpdatePrompt.prototype = {
       return;
     }
 
     // Schedule a fallback timeout in case the UI is unable to respond or show
     // a prompt for some reason.
     this._applyPromptTimer = this.createTimer(this.applyPromptTimeout);
   },
 
+  _copyProperties: ["appVersion", "buildID", "detailsURL", "displayVersion",
+                    "errorCode", "isOSUpdate", "platformVersion",
+                    "previousAppVersion", "state", "statusText"],
+
   sendUpdateEvent: function UP_sendUpdateEvent(aType, aUpdate) {
-    let detail = {
-      displayVersion: aUpdate.displayVersion,
-      detailsURL: aUpdate.detailsURL,
-      statusText: aUpdate.statusText,
-      state: aUpdate.state,
-      errorCode: aUpdate.errorCode,
-      isOSUpdate: aUpdate.isOSUpdate
-    };
+    let detail = {};
+    for each (let property in this._copyProperties) {
+      detail[property] = aUpdate[property];
+    }
 
     let patch = aUpdate.selectedPatch;
     if (!patch && aUpdate.patchCount > 0) {
       // For now we just check the first patch to get size information if a
       // patch hasn't been selected yet.
       patch = aUpdate.getPatchAt(0);
     }
 
--- a/browser/components/nsBrowserGlue.js
+++ b/browser/components/nsBrowserGlue.js
@@ -905,32 +905,33 @@ BrowserGlue.prototype = {
     /*
      * Display an opt-out notification when telemetry is enabled by default,
      * an opt-in prompt otherwise.
      *
      * But do not display this prompt/notification if:
      *
      * - The last accepted/refused policy (either by accepting the prompt or by
      *   manually flipping the telemetry preference) is already at version
-     *   TELEMETRY_DISPLAY_REV.
+     *   TELEMETRY_DISPLAY_REV or higher (to avoid the prompt in tests).
      */
     var telemetryDisplayed;
     try {
       telemetryDisplayed = Services.prefs.getIntPref(PREF_TELEMETRY_DISPLAYED);
     } catch(e) {}
-    if (telemetryDisplayed === TELEMETRY_DISPLAY_REV)
+    if (telemetryDisplayed >= TELEMETRY_DISPLAY_REV)
       return;
 
 #ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
     /*
      * Additionally, in opt-out builds, don't display the notification if:
      *
      * - Telemetry is disabled
      * - Telemetry was explicitly refused through the UI
-     * - Opt-in telemetry was enabled and this is the first run with opt-out.
+     * - Opt-in telemetry was already enabled, don't notify the user until next
+     *   policy update. (Do the check only at first run with opt-out builds)
      */
 
     var telemetryEnabled = Services.prefs.getBoolPref(PREF_TELEMETRY_ENABLED);
     if (!telemetryEnabled)
       return;
 
     // If telemetry was explicitly refused through the UI,
     // also disable opt-out telemetry and bail out.
--- a/browser/config/mozconfigs/win32/debug
+++ b/browser/config/mozconfigs/win32/debug
@@ -13,12 +13,15 @@ if test -z "${_PYMAKE}"; then
 fi
 
 if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
   . $topsrcdir/build/win32/mozconfig.vs2010-win64
 else
   . $topsrcdir/build/win32/mozconfig.vs2010
 fi
 
+# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
+ac_add_options --enable-warnings-as-errors
+
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/win32/nightly
+++ b/browser/config/mozconfigs/win32/nightly
@@ -22,12 +22,15 @@ if test -z "${_PYMAKE}"; then
 fi
 
 if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
   . $topsrcdir/build/win32/mozconfig.vs2010-win64
 else
   . $topsrcdir/build/win32/mozconfig.vs2010
 fi
 
+# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
+ac_add_options --enable-warnings-as-errors
+
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/win32/release
+++ b/browser/config/mozconfigs/win32/release
@@ -19,12 +19,15 @@ if test -z "${_PYMAKE}"; then
 fi
 
 if test "$PROCESSOR_ARCHITECTURE" = "AMD64" -o "$PROCESSOR_ARCHITEW6432" = "AMD64"; then
   . $topsrcdir/build/win32/mozconfig.vs2010-win64
 else
   . $topsrcdir/build/win32/mozconfig.vs2010
 fi
 
+# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
+ac_add_options --enable-warnings-as-errors
+
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/win64/debug
+++ b/browser/config/mozconfigs/win64/debug
@@ -8,14 +8,17 @@ ENABLE_MARIONETTE=1
 
 # Needed to enable breakpad in application.ini
 export MOZILLA_OFFICIAL=1
 
 if test -z "${_PYMAKE}"; then
   mk_add_options MOZ_MAKE_FLAGS=-j1
 fi
 
+# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
+ac_add_options --enable-warnings-as-errors
+
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 . $topsrcdir/build/win64/mozconfig.vs2010
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/browser/config/mozconfigs/win64/nightly
+++ b/browser/config/mozconfigs/win64/nightly
@@ -17,14 +17,17 @@ ac_add_options --enable-js-diagnostics
 export MOZILLA_OFFICIAL=1
 
 export MOZ_TELEMETRY_REPORTING=1
 
 if test -z "${_PYMAKE}"; then
   mk_add_options MOZ_MAKE_FLAGS=-j1
 fi
 
+# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
+ac_add_options --enable-warnings-as-errors
+
 # Package js shell.
 export MOZ_PACKAGE_JSSHELL=1
 
 . $topsrcdir/build/win64/mozconfig.vs2010
 
 . "$topsrcdir/build/mozconfig.common.override"
--- a/build/automation.py.in
+++ b/build/automation.py.in
@@ -402,18 +402,19 @@ user_pref("test.mousescroll", true);
 user_pref("security.default_personal_cert", "Select Automatically"); // Need to client auth test be w/o any dialogs
 user_pref("network.http.prompt-temp-redirect", false);
 user_pref("media.cache_size", 100);
 user_pref("security.warn_viewing_mixed", false);
 user_pref("app.update.enabled", false);
 user_pref("app.update.staging.enabled", false);
 user_pref("browser.panorama.experienced_first_run", true); // Assume experienced
 user_pref("dom.w3c_touch_events.enabled", 1);
-#expand user_pref("toolkit.telemetry.prompted", __MOZ_TELEMETRY_DISPLAY_REV__);
-#expand user_pref("toolkit.telemetry.notifiedOptOut", __MOZ_TELEMETRY_DISPLAY_REV__);
+// Set a future policy version to avoid the telemetry prompt.
+user_pref("toolkit.telemetry.prompted", 999);
+user_pref("toolkit.telemetry.notifiedOptOut", 999);
 // Existing tests assume there is no font size inflation.
 user_pref("font.size.inflation.emPerLine", 0);
 user_pref("font.size.inflation.minTwips", 0);
 
 // Only load extensions from the application and user profile
 // AddonManager.SCOPE_PROFILE + AddonManager.SCOPE_APPLICATION
 user_pref("extensions.enabledScopes", 5);
 // Disable metadata caching for installed add-ons by default
--- a/build/unix/elfhack/elf.cpp
+++ b/build/unix/elfhack/elf.cpp
@@ -580,17 +580,17 @@ void ElfSegment::addSection(ElfSection *
 void ElfSegment::removeSection(ElfSection *section)
 {
     sections.remove(section);
     section->removeFromSegment(this);
 }
 
 unsigned int ElfSegment::getFileSize()
 {
-    if (type == PT_GNU_RELRO)
+    if (type == PT_GNU_RELRO || isElfHackFillerSegment())
         return filesz;
 
     if (sections.empty())
         return 0;
     // Search the last section that is not SHT_NOBITS
     std::list<ElfSection *>::reverse_iterator i;
     for (i = sections.rbegin(); (i != sections.rend()) && ((*i)->getType() == SHT_NOBITS); ++i);
     // All sections are SHT_NOBITS
@@ -599,42 +599,49 @@ unsigned int ElfSegment::getFileSize()
 
     unsigned int end = (*i)->getAddr() + (*i)->getSize();
 
     return end - sections.front()->getAddr();
 }
 
 unsigned int ElfSegment::getMemSize()
 {
-    if (type == PT_GNU_RELRO)
+    if (type == PT_GNU_RELRO || isElfHackFillerSegment())
         return memsz;
 
     if (sections.empty())
         return 0;
 
     unsigned int end = sections.back()->getAddr() + sections.back()->getSize();
 
     return end - sections.front()->getAddr();
 }
 
 unsigned int ElfSegment::getOffset()
 {
     if ((type == PT_GNU_RELRO) && !sections.empty() &&
         (sections.front()->getAddr() != vaddr))
         throw std::runtime_error("PT_GNU_RELRO segment doesn't start on a section start");
 
+    // Neither bionic nor glibc linkers seem to like when the offset of that segment is 0
+    if (isElfHackFillerSegment())
+        return vaddr;
+
     return sections.empty() ? 0 : sections.front()->getOffset();
 }
 
 unsigned int ElfSegment::getAddr()
 {
     if ((type == PT_GNU_RELRO) && !sections.empty() &&
         (sections.front()->getAddr() != vaddr))
         throw std::runtime_error("PT_GNU_RELRO segment doesn't start on a section start");
 
+    if (isElfHackFillerSegment())
+        return vaddr;
+
     return sections.empty() ? 0 : sections.front()->getAddr();
 }
 
 void ElfSegment::clear()
 {
     for (std::list<ElfSection *>::iterator i = sections.begin(); i != sections.end(); ++i)
         (*i)->removeFromSegment(this);
     sections.clear();
--- a/build/unix/elfhack/elfhack.cpp
+++ b/build/unix/elfhack/elfhack.cpp
@@ -371,17 +371,17 @@ void set_relative_reloc(Elf_Rel *rel, El
 
 void set_relative_reloc(Elf_Rela *rel, Elf *elf, unsigned int value) {
     // ld puts the value of relocated relocations both in the addend and
     // at r_offset. For consistency, keep it that way.
     set_relative_reloc((Elf_Rel *)rel, elf, value);
     rel->r_addend = value;
 }
 
-void maybe_split_segment(Elf *elf, ElfSegment *segment)
+void maybe_split_segment(Elf *elf, ElfSegment *segment, bool fill)
 {
     std::list<ElfSection *>::iterator it = segment->begin();
     for (ElfSection *last = *(it++); it != segment->end(); last = *(it++)) {
         // When two consecutive non-SHT_NOBITS sections are apart by more
         // than the alignment of the section, the second can be moved closer
         // to the first, but this requires the segment to be split.
         if (((*it)->getType() != SHT_NOBITS) && (last->getType() != SHT_NOBITS) &&
             ((*it)->getOffset() - last->getOffset() - last->getSize() > segment->getAlign())) {
@@ -391,29 +391,50 @@ void maybe_split_segment(Elf *elf, ElfSe
             phdr.p_vaddr = 0;
             phdr.p_paddr = phdr.p_vaddr + segment->getVPDiff();
             phdr.p_flags = segment->getFlags();
             phdr.p_align = segment->getAlign();
             phdr.p_filesz = (unsigned int)-1;
             phdr.p_memsz = (unsigned int)-1;
             ElfSegment *newSegment = new ElfSegment(&phdr);
             elf->insertSegmentAfter(segment, newSegment);
+            ElfSection *section = *it;
             for (; it != segment->end(); ++it) {
                 newSegment->addSection(*it);
             }
             for (it = newSegment->begin(); it != newSegment->end(); it++) {
                 segment->removeSection(*it);
             }
+            // Fill the virtual address space gap left between the two PT_LOADs
+            // with a new PT_LOAD with no permissions. This avoids the linker
+            // (especially bionic's) filling the gap with anonymous memory,
+            // which breakpad doesn't like.
+            // /!\ running strip on a elfhacked binary will break this filler
+            // PT_LOAD.
+            if (!fill)
+                break;
+            ElfSection *previous = section->getPrevious();
+            phdr.p_vaddr = (previous->getAddr() + previous->getSize() + segment->getAlign() - 1) & ~(segment->getAlign() - 1);
+            phdr.p_paddr = phdr.p_vaddr + segment->getVPDiff();
+            phdr.p_flags = 0;
+            phdr.p_align = 0;
+            phdr.p_filesz = (section->getAddr() & ~(newSegment->getAlign() - 1)) - phdr.p_vaddr;
+            phdr.p_memsz = phdr.p_filesz;
+            if (phdr.p_filesz) {
+                newSegment = new ElfSegment(&phdr);
+                assert(newSegment->isElfHackFillerSegment());
+                elf->insertSegmentAfter(segment, newSegment);
+            }
             break;
         }
     }
 }
 
 template <typename Rel_Type>
-int do_relocation_section(Elf *elf, unsigned int rel_type, unsigned int rel_type2, bool force)
+int do_relocation_section(Elf *elf, unsigned int rel_type, unsigned int rel_type2, bool force, bool fill)
 {
     ElfDynamic_Section *dyn = elf->getDynSection();
     if (dyn ==NULL) {
         fprintf(stderr, "Couldn't find SHT_DYNAMIC section\n");
         return -1;
     }
 
     ElfSegment *relro = elf->getSegmentByType(PT_GNU_RELRO);
@@ -563,17 +584,17 @@ int do_relocation_section(Elf *elf, unsi
     if (section->getOffset() + section->getSize() >= old_end) {
         fprintf(stderr, "No gain. Skipping\n");
         return -1;
     }
 
     // Adjust PT_LOAD segments
     for (ElfSegment *segment = elf->getSegmentByType(PT_LOAD); segment;
          segment = elf->getSegmentByType(PT_LOAD, segment)) {
-        maybe_split_segment(elf, segment);
+        maybe_split_segment(elf, segment, fill);
     }
 
     // Ensure Elf sections will be at their final location.
     elf->normalize();
     ElfLocation *init = new ElfLocation(relhackcode, relhackcode->getEntryPoint());
     if (init_array) {
         // Adjust the first DT_INIT_ARRAY entry to point at the injected code
         // by transforming its relocation into a relative one pointing to the
@@ -594,17 +615,17 @@ int do_relocation_section(Elf *elf, unsi
 
 static inline int backup_file(const char *name)
 {
     std::string fname(name);
     fname += ".bak";
     return rename(name, fname.c_str());
 }
 
-void do_file(const char *name, bool backup = false, bool force = false)
+void do_file(const char *name, bool backup = false, bool force = false, bool fill = false)
 {
     std::ifstream file(name, std::ios::in|std::ios::binary);
     Elf elf(file);
     unsigned int size = elf.getSize();
     fprintf(stderr, "%s: ", name);
     if (elf.getType() != ET_DYN) {
         fprintf(stderr, "Not a shared object. Skipping\n");
         return;
@@ -617,23 +638,23 @@ void do_file(const char *name, bool back
             fprintf(stderr, "Already elfhacked. Skipping\n");
             return;
         }
     }
 
     int exit = -1;
     switch (elf.getMachine()) {
     case EM_386:
-        exit = do_relocation_section<Elf_Rel>(&elf, R_386_RELATIVE, R_386_32, force);
+        exit = do_relocation_section<Elf_Rel>(&elf, R_386_RELATIVE, R_386_32, force, fill);
         break;
     case EM_X86_64:
-        exit = do_relocation_section<Elf_Rela>(&elf, R_X86_64_RELATIVE, R_X86_64_64, force);
+        exit = do_relocation_section<Elf_Rela>(&elf, R_X86_64_RELATIVE, R_X86_64_64, force, fill);
         break;
     case EM_ARM:
-        exit = do_relocation_section<Elf_Rel>(&elf, R_ARM_RELATIVE, R_ARM_ABS32, force);
+        exit = do_relocation_section<Elf_Rel>(&elf, R_ARM_RELATIVE, R_ARM_ABS32, force, fill);
         break;
     }
     if (exit == 0) {
         if (!force && (elf.getSize() >= size)) {
             fprintf(stderr, "No gain. Skipping\n");
         } else if (backup && backup_file(name) != 0) {
             fprintf(stderr, "Couln't create backup file\n");
         } else {
@@ -672,54 +693,65 @@ void undo_file(const char *name, bool ba
     }
     if (data != text->getNext()) {
         fprintf(stderr, elfhack_data " section not following " elfhack_text ". Skipping\n");
         return;
     }
 
     ElfSegment *first = elf.getSegmentByType(PT_LOAD);
     ElfSegment *second = elf.getSegmentByType(PT_LOAD, first);
+    ElfSegment *filler = NULL;
+    // If the second PT_LOAD is a filler from elfhack --fill, check the third.
+    if (!second->isElfHackFillerSegment()) {
+        filler = second;
+        second = elf.getSegmentByType(PT_LOAD, filler);
+    }
     if (second->getFlags() != first->getFlags()) {
-        fprintf(stderr, "First two PT_LOAD segments don't have the same flags. Skipping\n");
+        fprintf(stderr, "Couldn't identify elfhacked PT_LOAD segments. Skipping\n");
         return;
     }
     // Move sections from the second PT_LOAD to the first, and remove the
     // second PT_LOAD segment.
     for (std::list<ElfSection *>::iterator section = second->begin();
          section != second->end(); ++section)
         first->addSection(*section);
 
     elf.removeSegment(second);
+    if (filler)
+        elf.removeSegment(filler);
 
     if (backup && backup_file(name) != 0) {
         fprintf(stderr, "Couln't create backup file\n");
     } else {
         std::ofstream ofile(name, std::ios::out|std::ios::binary|std::ios::trunc);
         elf.write(ofile);
         fprintf(stderr, "Grown by %d bytes\n", elf.getSize() - size);
     }
 }
 
 int main(int argc, char *argv[])
 {
     int arg;
     bool backup = false;
     bool force = false;
     bool revert = false;
+    bool fill = false;
     char *lastSlash = rindex(argv[0], '/');
     if (lastSlash != NULL)
         rundir = strndup(argv[0], lastSlash - argv[0]);
     for (arg = 1; arg < argc; arg++) {
         if (strcmp(argv[arg], "-f") == 0)
             force = true;
         else if (strcmp(argv[arg], "-b") == 0)
             backup = true;
         else if (strcmp(argv[arg], "-r") == 0)
             revert = true;
-        else if (revert)
+        else if (strcmp(argv[arg], "--fill") == 0)
+            fill = true;
+        else if (revert) {
             undo_file(argv[arg], backup);
-        else
-            do_file(argv[arg], backup, force);
+        } else
+            do_file(argv[arg], backup, force, fill);
     }
 
     free(rundir);
     return 0;
 }
--- a/build/unix/elfhack/elfxx.h
+++ b/build/unix/elfhack/elfxx.h
@@ -455,16 +455,20 @@ public:
 
     void addSection(ElfSection *section);
     void removeSection(ElfSection *section);
 
     std::list<ElfSection *>::iterator begin() { return sections.begin(); }
     std::list<ElfSection *>::iterator end() { return sections.end(); }
 
     void clear();
+
+    bool isElfHackFillerSegment() {
+      return type == PT_LOAD && flags == 0;
+    }
 private:
     unsigned int type;
     int v_p_diff; // Difference between physical and virtual address
     unsigned int flags;
     unsigned int align;
     std::list<ElfSection *> sections;
     // The following are only really used for PT_GNU_RELRO until something
     // better is found.
--- a/content/base/public/nsINode.h
+++ b/content/base/public/nsINode.h
@@ -1869,188 +1869,188 @@ extern const nsIID kThisPtrOffsetsSID;
     NS_INTERFACE_TABLE_ENTRY(_class, _i8)                                     \
     NS_INTERFACE_TABLE_ENTRY(_class, _i9)                                     \
   NS_OFFSET_AND_INTERFACE_TABLE_END                                           \
   NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
 
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsINode, NS_INODE_IID)
 
-#define NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER(_final) \
-  NS_IMETHOD GetNodeName(nsAString& aNodeName) _final \
+#define NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER(...) \
+  NS_IMETHOD GetNodeName(nsAString& aNodeName) __VA_ARGS__ \
   { \
     nsINode::GetNodeName(aNodeName); \
     return NS_OK; \
   } \
-  NS_IMETHOD GetNodeValue(nsAString& aNodeValue) _final \
+  NS_IMETHOD GetNodeValue(nsAString& aNodeValue) __VA_ARGS__ \
   { \
     nsINode::GetNodeValue(aNodeValue); \
     return NS_OK; \
   } \
-  NS_IMETHOD SetNodeValue(const nsAString& aNodeValue) _final \
+  NS_IMETHOD SetNodeValue(const nsAString& aNodeValue) __VA_ARGS__ \
   { \
     mozilla::ErrorResult rv; \
     nsINode::SetNodeValue(aNodeValue, rv); \
     return rv.ErrorCode(); \
   } \
-  NS_IMETHOD GetNodeType(uint16_t* aNodeType) _final \
+  NS_IMETHOD GetNodeType(uint16_t* aNodeType) __VA_ARGS__ \
   { \
     *aNodeType = nsINode::NodeType(); \
     return NS_OK; \
   } \
-  NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) _final \
+  NS_IMETHOD GetParentNode(nsIDOMNode** aParentNode) __VA_ARGS__ \
   { \
     return nsINode::GetParentNode(aParentNode); \
   } \
-  NS_IMETHOD GetParentElement(nsIDOMElement** aParentElement) _final \
+  NS_IMETHOD GetParentElement(nsIDOMElement** aParentElement) __VA_ARGS__ \
   { \
     return nsINode::GetParentElement(aParentElement); \
   } \
-  NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) _final \
+  NS_IMETHOD GetChildNodes(nsIDOMNodeList** aChildNodes) __VA_ARGS__ \
   { \
     return nsINode::GetChildNodes(aChildNodes); \
   } \
-  NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) _final \
+  NS_IMETHOD GetFirstChild(nsIDOMNode** aFirstChild) __VA_ARGS__ \
   { \
     return nsINode::GetFirstChild(aFirstChild); \
   } \
-  NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) _final \
+  NS_IMETHOD GetLastChild(nsIDOMNode** aLastChild) __VA_ARGS__ \
   { \
     return nsINode::GetLastChild(aLastChild); \
   } \
-  NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) _final \
+  NS_IMETHOD GetPreviousSibling(nsIDOMNode** aPreviousSibling) __VA_ARGS__ \
   { \
     return nsINode::GetPreviousSibling(aPreviousSibling); \
   } \
-  NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) _final \
+  NS_IMETHOD GetNextSibling(nsIDOMNode** aNextSibling) __VA_ARGS__ \
   { \
     return nsINode::GetNextSibling(aNextSibling); \
   } \
-  NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes) _final \
+  NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes) __VA_ARGS__ \
   { \
     return nsINode::GetAttributes(aAttributes); \
   } \
-  NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument) _final \
+  NS_IMETHOD GetOwnerDocument(nsIDOMDocument** aOwnerDocument) __VA_ARGS__ \
   { \
     return nsINode::GetOwnerDocument(aOwnerDocument); \
   } \
-  NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aResult) _final \
+  NS_IMETHOD InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild, nsIDOMNode** aResult) __VA_ARGS__ \
   { \
     return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aResult); \
   } \
-  NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aResult) _final \
+  NS_IMETHOD ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild, nsIDOMNode** aResult) __VA_ARGS__ \
   { \
     return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aResult); \
   } \
-  NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aResult) _final \
+  NS_IMETHOD RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aResult) __VA_ARGS__ \
   { \
     return nsINode::RemoveChild(aOldChild, aResult); \
   } \
-  NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aResult) _final \
+  NS_IMETHOD AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aResult) __VA_ARGS__ \
   { \
     return InsertBefore(aNewChild, nullptr, aResult); \
   } \
-  NS_IMETHOD HasChildNodes(bool* aResult) _final \
+  NS_IMETHOD HasChildNodes(bool* aResult) __VA_ARGS__ \
   { \
     *aResult = nsINode::HasChildNodes(); \
     return NS_OK; \
   } \
-  NS_IMETHOD CloneNode(bool aDeep, uint8_t aArgc, nsIDOMNode** aResult) _final \
+  NS_IMETHOD CloneNode(bool aDeep, uint8_t aArgc, nsIDOMNode** aResult) __VA_ARGS__ \
   { \
     if (aArgc == 0) { \
       aDeep = true; \
     } \
     mozilla::ErrorResult rv; \
     nsCOMPtr<nsINode> clone = nsINode::CloneNode(aDeep, rv); \
     if (rv.Failed()) { \
       return rv.ErrorCode(); \
     } \
     *aResult = clone.forget().get()->AsDOMNode(); \
     return NS_OK; \
   } \
-  NS_IMETHOD Normalize() _final \
+  NS_IMETHOD Normalize() __VA_ARGS__ \
   { \
     nsINode::Normalize(); \
     return NS_OK; \
   } \
-  NS_IMETHOD IsSupported(const nsAString& aFeature, const nsAString& aVersion, bool* aResult) _final \
+  NS_IMETHOD IsSupported(const nsAString& aFeature, const nsAString& aVersion, bool* aResult) __VA_ARGS__ \
   { \
     *aResult = nsINode::IsSupported(aFeature, aVersion); \
     return NS_OK; \
   } \
-  NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI) _final \
+  NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI) __VA_ARGS__ \
   { \
     mozilla::ErrorResult rv; \
     nsINode::GetNamespaceURI(aNamespaceURI, rv); \
     return rv.ErrorCode(); \
   } \
-  NS_IMETHOD GetPrefix(nsAString& aPrefix) _final \
+  NS_IMETHOD GetPrefix(nsAString& aPrefix) __VA_ARGS__ \
   { \
     nsINode::GetPrefix(aPrefix); \
     return NS_OK; \
   } \
-  NS_IMETHOD GetLocalName(nsAString& aLocalName) _final \
+  NS_IMETHOD GetLocalName(nsAString& aLocalName) __VA_ARGS__ \
   { \
     nsINode::GetLocalName(aLocalName); \
     return NS_OK; \
   } \
   using nsINode::HasAttributes; \
-  NS_IMETHOD HasAttributes(bool* aResult) _final \
+  NS_IMETHOD HasAttributes(bool* aResult) __VA_ARGS__ \
   { \
     *aResult = nsINode::HasAttributes(); \
     return NS_OK; \
   } \
-  NS_IMETHOD GetDOMBaseURI(nsAString& aBaseURI) _final \
+  NS_IMETHOD GetDOMBaseURI(nsAString& aBaseURI) __VA_ARGS__ \
   { \
     nsINode::GetBaseURI(aBaseURI); \
     return NS_OK; \
   } \
-  NS_IMETHOD CompareDocumentPosition(nsIDOMNode* aOther, uint16_t* aResult) _final \
+  NS_IMETHOD CompareDocumentPosition(nsIDOMNode* aOther, uint16_t* aResult) __VA_ARGS__ \
   { \
     return nsINode::CompareDocumentPosition(aOther, aResult); \
   } \
-  NS_IMETHOD GetTextContent(nsAString& aTextContent) _final \
+  NS_IMETHOD GetTextContent(nsAString& aTextContent) __VA_ARGS__ \
   { \
     nsINode::GetTextContent(aTextContent); \
     return NS_OK; \
   } \
-  NS_IMETHOD SetTextContent(const nsAString& aTextContent) _final \
+  NS_IMETHOD SetTextContent(const nsAString& aTextContent) __VA_ARGS__ \
   { \
     mozilla::ErrorResult rv; \
     nsINode::SetTextContent(aTextContent, rv); \
     return rv.ErrorCode(); \
   } \
-  NS_IMETHOD LookupPrefix(const nsAString& aNamespaceURI, nsAString& aResult) _final \
+  NS_IMETHOD LookupPrefix(const nsAString& aNamespaceURI, nsAString& aResult) __VA_ARGS__ \
   { \
     nsINode::LookupPrefix(aNamespaceURI, aResult); \
     return NS_OK; \
   } \
-  NS_IMETHOD IsDefaultNamespace(const nsAString& aNamespaceURI, bool* aResult) _final \
+  NS_IMETHOD IsDefaultNamespace(const nsAString& aNamespaceURI, bool* aResult) __VA_ARGS__ \
   { \
     *aResult = nsINode::IsDefaultNamespace(aNamespaceURI); \
     return NS_OK; \
   } \
-  NS_IMETHOD LookupNamespaceURI(const nsAString& aPrefix, nsAString& aResult) _final \
+  NS_IMETHOD LookupNamespaceURI(const nsAString& aPrefix, nsAString& aResult) __VA_ARGS__ \
   { \
     nsINode::LookupNamespaceURI(aPrefix, aResult); \
     return NS_OK; \
   } \
-  NS_IMETHOD IsEqualNode(nsIDOMNode* aArg, bool* aResult) _final \
+  NS_IMETHOD IsEqualNode(nsIDOMNode* aArg, bool* aResult) __VA_ARGS__ \
   { \
     return nsINode::IsEqualNode(aArg, aResult); \
   } \
-  NS_IMETHOD SetUserData(const nsAString& aKey, nsIVariant* aData, nsIDOMUserDataHandler* aHandler, nsIVariant** aResult) _final \
+  NS_IMETHOD SetUserData(const nsAString& aKey, nsIVariant* aData, nsIDOMUserDataHandler* aHandler, nsIVariant** aResult) __VA_ARGS__ \
   { \
     return nsINode::SetUserData(aKey, aData, aHandler, aResult); \
   } \
-  NS_IMETHOD GetUserData(const nsAString& aKey, nsIVariant** aResult) _final \
+  NS_IMETHOD GetUserData(const nsAString& aKey, nsIVariant** aResult) __VA_ARGS__ \
   { \
     return nsINode::GetUserData(aKey, aResult); \
   } \
-  NS_IMETHOD Contains(nsIDOMNode* aOther, bool* aResult) _final \
+  NS_IMETHOD Contains(nsIDOMNode* aOther, bool* aResult) __VA_ARGS__ \
   { \
     return nsINode::Contains(aOther, aResult); \
   }
 
 #define NS_FORWARD_NSIDOMNODE_TO_NSINODE \
   NS_FORWARD_NSIDOMNODE_TO_NSINODE_HELPER(MOZ_FINAL)
 
 #define NS_FORWARD_NSIDOMNODE_TO_NSINODE_OVERRIDABLE \
--- a/content/base/src/nsDOMBlobBuilder.h
+++ b/content/base/src/nsDOMBlobBuilder.h
@@ -120,17 +120,18 @@ protected:
     using mozilla::CheckedUint32;
 
     if (mDataBufferLen >= mDataLen + aSize) {
       mDataLen += aSize;
       return true;
     }
 
     // Start at 1 or we'll loop forever.
-    CheckedUint32 bufferLen = NS_MAX<uint32_t>(mDataBufferLen, 1);
+    CheckedUint32 bufferLen =
+      NS_MAX<uint32_t>(static_cast<uint32_t>(mDataBufferLen), 1);
     while (bufferLen.isValid() && bufferLen.value() < mDataLen + aSize)
       bufferLen *= 2;
 
     if (!bufferLen.isValid())
       return false;
 
     void* data = moz_realloc(mData, bufferLen.value());
     if (!data)
--- a/content/base/src/nsDOMFile.cpp
+++ b/content/base/src/nsDOMFile.cpp
@@ -610,18 +610,17 @@ nsDOMMemoryFile::GetInternalStream(nsIIn
 }
 
 /* static */ StaticAutoPtr<LinkedList<nsDOMMemoryFile::DataOwner> >
 nsDOMMemoryFile::DataOwner::sDataOwners;
 
 /* static */ bool
 nsDOMMemoryFile::DataOwner::sMemoryReporterRegistered;
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerSizeOf,
-                                     "memory-file-data");
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMMemoryFileDataOwnerMallocSizeOf)
 
 class nsDOMMemoryFileDataOwnerMemoryReporter MOZ_FINAL
   : public nsIMemoryMultiReporter
 {
   NS_DECL_ISUPPORTS
 
   NS_IMETHOD GetName(nsACString& aName)
   {
@@ -646,17 +645,17 @@ class nsDOMMemoryFileDataOwnerMemoryRepo
     }
 
     const size_t LARGE_OBJECT_MIN_SIZE = 8 * 1024;
     size_t smallObjectsTotal = 0;
 
     for (DataOwner *owner = DataOwner::sDataOwners->getFirst();
          owner; owner = owner->getNext()) {
 
-      size_t size = DOMMemoryFileDataOwnerSizeOf(owner->mData);
+      size_t size = DOMMemoryFileDataOwnerMallocSizeOf(owner->mData);
 
       if (size < LARGE_OBJECT_MIN_SIZE) {
         smallObjectsTotal += size;
       }
       else {
         SHA1Sum sha1;
         sha1.update(owner->mData, owner->mLength);
         uint8_t digest[SHA1Sum::HashSize]; // SHA1 digests are 20 bytes long.
--- a/content/canvas/src/Makefile.in
+++ b/content/canvas/src/Makefile.in
@@ -3,23 +3,24 @@
 # 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/.
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
-FAIL_ON_WARNINGS = 1
-
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= content
 LIBRARY_NAME	= gkconcvs_s
 LIBXUL_LIBRARY  = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 EXPORTS_NAMESPACES = mozilla/dom
 
 EXPORTS_mozilla/dom = \
 	CanvasUtils.h \
 	CanvasRenderingContext2D.h \
   ImageData.h \
   $(NULL)
--- a/content/canvas/src/WebGLContextReporter.cpp
+++ b/content/canvas/src/WebGLContextReporter.cpp
@@ -135,42 +135,42 @@ WebGLMemoryMultiReporterWrapper::WebGLMe
     NS_RegisterMemoryMultiReporter(mReporter);
 }
 
 WebGLMemoryMultiReporterWrapper::~WebGLMemoryMultiReporterWrapper()
 {
     NS_UnregisterMemoryMultiReporter(mReporter);
 }
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOfFun, "webgl-buffer")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLBufferMallocSizeOf)
 
 int64_t 
 WebGLMemoryMultiReporterWrapper::GetBufferCacheMemoryUsed() {
     const ContextsArrayType & contexts = Contexts();
     int64_t result = 0;
     for(size_t i = 0; i < contexts.Length(); ++i) {
         for (const WebGLBuffer *buffer = contexts[i]->mBuffers.getFirst();
              buffer;
              buffer = buffer->getNext())
         {
             if (buffer->Target() == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
-                result += buffer->SizeOfIncludingThis(WebGLBufferMallocSizeOfFun);
+                result += buffer->SizeOfIncludingThis(WebGLBufferMallocSizeOf);
         }
     }
     return result;
 }
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOfFun, "webgl-shader")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WebGLShaderMallocSizeOf)
 
 int64_t 
 WebGLMemoryMultiReporterWrapper::GetShaderSize() {
     const ContextsArrayType & contexts = Contexts();
     int64_t result = 0;
     for(size_t i = 0; i < contexts.Length(); ++i) {
         for (const WebGLShader *shader = contexts[i]->mShaders.getFirst();
              shader;
              shader = shader->getNext())
         {
-            result += shader->SizeOfIncludingThis(WebGLShaderMallocSizeOfFun);
+            result += shader->SizeOfIncludingThis(WebGLShaderMallocSizeOf);
         }
     }
     return result;
 }
--- a/content/events/src/Makefile.in
+++ b/content/events/src/Makefile.in
@@ -8,17 +8,19 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= content
 LIBRARY_NAME	= gkconevents_s
 LIBXUL_LIBRARY  = 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 EXPORTS		= \
 		nsEventStateManager.h \
 		nsEventListenerManager.h \
 		nsDOMEventTargetHelper.h \
 		nsDOMEvent.h \
 		nsDOMTouchEvent.h \
 		nsDOMUIEvent.h \
--- a/content/html/content/src/Makefile.in
+++ b/content/html/content/src/Makefile.in
@@ -8,17 +8,19 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= content
 LIBRARY_NAME	= gkconhtmlcon_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 
 EXPORTS		= \
 		HTMLPropertiesCollection.h \
 		nsGenericHTMLElement.h \
 		nsHTMLIFrameElement.h \
 		nsClientRect.h \
 		nsHTMLDNSPrefetch.h \
--- a/content/html/document/src/Makefile.in
+++ b/content/html/document/src/Makefile.in
@@ -8,17 +8,19 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= content
 LIBRARY_NAME	= gkconhtmldoc_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 CPPSRCS		= \
 		nsHTMLContentSink.cpp \
 		nsHTMLDocument.cpp \
 		ImageDocument.cpp \
 		MediaDocument.cpp \
 		PluginDocument.cpp \
 		$(NULL)
--- a/content/mathml/content/src/Makefile.in
+++ b/content/mathml/content/src/Makefile.in
@@ -8,17 +8,19 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= content
 LIBRARY_NAME	= gkcontentmathml_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 CPPSRCS		= \
 		nsMathMLElement.cpp               \
 		nsMathMLElementFactory.cpp        \
 		$(NULL)
 
 include $(topsrcdir)/config/config.mk
 
--- a/content/media/Makefile.in
+++ b/content/media/Makefile.in
@@ -1,23 +1,25 @@
 # 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/.
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = content
 LIBRARY_NAME = gkconmedia_s
 LIBXUL_LIBRARY = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 EXPORTS = \
   AbstractMediaDecoder.h \
   AudioSampleFormat.h \
   AudioSegment.h \
   BufferMediaResource.h \
   DecoderTraits.h \
   FileBlockCache.h \
--- a/content/media/MediaDecoder.h
+++ b/content/media/MediaDecoder.h
@@ -223,16 +223,22 @@ static const uint32_t FRAMEBUFFER_LENGTH
 // has to be within the following range.
 static const uint32_t FRAMEBUFFER_LENGTH_MIN = 512;
 static const uint32_t FRAMEBUFFER_LENGTH_MAX = 16384;
 
 static inline bool IsCurrentThread(nsIThread* aThread) {
   return NS_GetCurrentThread() == aThread;
 }
 
+// GetCurrentTime is defined in winbase.h as zero argument macro forwarding to
+// GetTickCount() and conflicts with MediaDecoder::GetCurrentTime implementation.
+#ifdef GetCurrentTime
+#undef GetCurrentTime
+#endif
+
 class MediaDecoder : public nsIObserver,
                      public AbstractMediaDecoder
 {
 public:
   typedef mozilla::layers::Image Image;
   class DecodedStreamMainThreadListener;
 
   NS_DECL_ISUPPORTS
--- a/content/media/MediaSegment.h
+++ b/content/media/MediaSegment.h
@@ -210,16 +210,17 @@ protected:
   MediaSegmentBase(Type aType) : MediaSegment(aType) {}
 
   /**
    * Appends the contents of aSource to this segment, clearing aSource.
    */
   void AppendFromInternal(MediaSegmentBase<C, Chunk>* aSource)
   {
     static_cast<C*>(this)->CheckCompatible(*static_cast<C*>(aSource));
+    MOZ_ASSERT(aSource->mDuration >= 0);
     mDuration += aSource->mDuration;
     aSource->mDuration = 0;
     if (!mChunks.IsEmpty() && !aSource->mChunks.IsEmpty() &&
         mChunks[mChunks.Length() - 1].CanCombineWithFollowing(aSource->mChunks[0])) {
       mChunks[mChunks.Length() - 1].mDuration += aSource->mChunks[0].mDuration;
       aSource->mChunks.RemoveElementAt(0);
     }
     mChunks.MoveElementsFrom(aSource->mChunks);
@@ -243,16 +244,17 @@ protected:
         mChunks.AppendElement(c)->SliceTo(start - offset, end - offset);
       }
       offset = nextOffset;
     }
   }
 
   Chunk* AppendChunk(TrackTicks aDuration)
   {
+    MOZ_ASSERT(aDuration >= 0);
     Chunk* c = mChunks.AppendElement();
     c->mDuration = aDuration;
     mDuration += aDuration;
     return c;
   }
 
   Chunk* FindChunkContaining(TrackTicks aOffset, TrackTicks* aStart = nullptr)
   {
--- a/content/media/MediaStreamGraph.cpp
+++ b/content/media/MediaStreamGraph.cpp
@@ -797,31 +797,29 @@ MediaStreamGraphImpl::UpdateCurrentTime(
   }
 
   for (uint32_t i = 0; i < mStreams.Length(); ++i) {
     MediaStream* stream = mStreams[i];
 
     // Calculate blocked time and fire Blocked/Unblocked events
     GraphTime blockedTime = 0;
     GraphTime t = prevCurrentTime;
-    // Save current blocked status
-    bool wasBlocked = stream->mBlocked.GetAt(prevCurrentTime);
     while (t < nextCurrentTime) {
       GraphTime end;
       bool blocked = stream->mBlocked.GetAt(t, &end);
       if (blocked) {
         blockedTime += NS_MIN(end, nextCurrentTime) - t;
       }
-      if (blocked != wasBlocked) {
+      if (blocked != stream->mNotifiedBlocked) {
         for (uint32_t j = 0; j < stream->mListeners.Length(); ++j) {
           MediaStreamListener* l = stream->mListeners[j];
           l->NotifyBlockingChanged(this,
               blocked ? MediaStreamListener::BLOCKED : MediaStreamListener::UNBLOCKED);
         }
-        wasBlocked = blocked;
+        stream->mNotifiedBlocked = blocked;
       }
       t = end;
     }
 
     stream->AdvanceTimeVaryingValuesToCurrentTime(nextCurrentTime, blockedTime);
     // Advance mBlocked last so that implementations of
     // AdvanceTimeVaryingValuesToCurrentTime can rely on the value of mBlocked.
     stream->mBlocked.AdvanceCurrentTime(nextCurrentTime);
@@ -1936,17 +1934,17 @@ MediaStream::ChangeExplicitBlockerCount(
   GraphImpl()->AppendMessage(new Message(this, aDelta));
 }
 
 void
 MediaStream::AddListenerImpl(already_AddRefed<MediaStreamListener> aListener)
 {
   MediaStreamListener* listener = *mListeners.AppendElement() = aListener;
   listener->NotifyBlockingChanged(GraphImpl(),
-    mBlocked.GetAt(GraphImpl()->mCurrentTime) ? MediaStreamListener::BLOCKED : MediaStreamListener::UNBLOCKED);
+    mNotifiedBlocked ? MediaStreamListener::BLOCKED : MediaStreamListener::UNBLOCKED);
   if (mNotifiedFinished) {
     listener->NotifyFinished(GraphImpl());
   }
 }
 
 void
 MediaStream::AddListener(MediaStreamListener* aListener)
 {
--- a/content/media/MediaStreamGraph.h
+++ b/content/media/MediaStreamGraph.h
@@ -256,16 +256,17 @@ public:
 
   MediaStream(nsDOMMediaStream* aWrapper)
     : mBufferStartTime(0)
     , mExplicitBlockerCount(0)
     , mBlocked(false)
     , mGraphUpdateIndices(0)
     , mFinished(false)
     , mNotifiedFinished(false)
+    , mNotifiedBlocked(false)
     , mWrapper(aWrapper)
     , mMainThreadCurrentTime(0)
     , mMainThreadFinished(false)
     , mMainThreadDestroyed(false)
   {
   }
   virtual ~MediaStream() {}
 
@@ -452,16 +453,21 @@ protected:
    * buffered data has been consumed.
    */
   bool mFinished;
   /**
    * When true, mFinished is true and we've played all the data in this stream
    * and fired NotifyFinished notifications.
    */
   bool mNotifiedFinished;
+  /**
+   * When true, the last NotifyBlockingChanged delivered to the listeners
+   * indicated that the stream is blocked.
+   */
+  bool mNotifiedBlocked;
 
   // Temporary data for ordering streams by dependency graph
   bool mHasBeenOrdered;
   bool mIsOnOrderingStack;
   // True if the stream is being consumed (i.e. has track data being played,
   // or is feeding into some stream that is being consumed).
   bool mIsConsumed;
   // Temporary data for computing blocking status of streams
--- a/content/media/ogg/Makefile.in
+++ b/content/media/ogg/Makefile.in
@@ -1,23 +1,25 @@
 # 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/.
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= content
 LIBRARY_NAME	= gkconogg_s
 LIBXUL_LIBRARY 	= 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 
 EXPORTS		+= \
 		OggDecoder.h \
 		OggCodecState.h \
 		OggReader.h \
 		$(NULL)
 
--- a/content/media/raw/Makefile.in
+++ b/content/media/raw/Makefile.in
@@ -2,23 +2,25 @@
 # 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/.
 
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = content
 LIBRARY_NAME = gkconraw_s
 LIBXUL_LIBRARY = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 EXPORTS += \
   RawDecoder.h \
   RawReader.h \
   RawStructs.h \
   $(NULL)
 
 CPPSRCS += \
--- a/content/media/webaudio/Makefile.in
+++ b/content/media/webaudio/Makefile.in
@@ -1,23 +1,25 @@
 # 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/.
 
 DEPTH            := @DEPTH@
 topsrcdir        := @top_srcdir@
 srcdir           := @srcdir@
 VPATH            := @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE         := content
 LIBRARY_NAME   := gkconwebaudio_s
 LIBXUL_LIBRARY := 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 CPPSRCS := \
   AudioBuffer.cpp \
   AudioBufferSourceNode.cpp \
   AudioContext.cpp \
   AudioDestinationNode.cpp \
   AudioListener.cpp \
   AudioNode.cpp \
--- a/content/media/webaudio/compiledtest/Makefile.in
+++ b/content/media/webaudio/compiledtest/Makefile.in
@@ -2,19 +2,22 @@
 # 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/.
 
 DEPTH          := @DEPTH@
 topsrcdir      := @top_srcdir@
 srcdir         := @srcdir@
 VPATH          := @srcdir@
 relativesrcdir := @relativesrcdir@
-FAIL_ON_WARNINGS = 1
 
 include $(DEPTH)/config/autoconf.mk
 
+ifndef _MSC_VER
+FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
+
 LOCAL_INCLUDES := -I$(srcdir)/..
 
 CPP_UNIT_TESTS := \
   TestAudioEventTimeline.cpp \
   $(NULL)
 
 include $(topsrcdir)/config/rules.mk
--- a/content/media/webrtc/MediaEngineWebRTCAudio.cpp
+++ b/content/media/webrtc/MediaEngineWebRTCAudio.cpp
@@ -156,17 +156,17 @@ MediaEngineWebRTCAudioSource::NotifyPull
                                          TrackID aID,
                                          StreamTime aDesiredTime,
                                          TrackTicks &aLastEndTime)
 {
   // Ignore - we push audio data
 #ifdef DEBUG
   TrackTicks target = TimeToTicksRoundUp(SAMPLE_FREQUENCY, aDesiredTime);
   TrackTicks delta = target - aLastEndTime;
-  LOG(("Audio:NotifyPull: target %lu, delta %lu",(uint64_t) target, (uint64_t) delta));
+  LOG(("Audio: NotifyPull: aDesiredTime %ld, target %ld, delta %ld",(int64_t) aDesiredTime, (int64_t) target, (int64_t) delta));
   aLastEndTime = target;
 #endif
 }
 
 nsresult
 MediaEngineWebRTCAudioSource::Snapshot(uint32_t aDuration, nsIDOMFile** aFile)
 {
    return NS_ERROR_NOT_IMPLEMENTED;
--- a/content/media/webrtc/MediaEngineWebRTCVideo.cpp
+++ b/content/media/webrtc/MediaEngineWebRTCVideo.cpp
@@ -7,18 +7,20 @@
 #include "ImageTypes.h"
 #include "ImageContainer.h"
 
 namespace mozilla {
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* GetMediaManagerLog();
 #define LOG(msg) PR_LOG(GetMediaManagerLog(), PR_LOG_DEBUG, msg)
+#define LOGFRAME(msg) PR_LOG(GetMediaManagerLog(), 6, msg)
 #else
 #define LOG(msg)
+#define LOGFRAME(msg)
 #endif
 
 /**
  * Webrtc video source.
  */
 NS_IMPL_THREADSAFE_ISUPPORTS1(MediaEngineWebRTCVideoSource, nsIRunnable)
 
 // ViEExternalRenderer Callback.
@@ -72,19 +74,19 @@ MediaEngineWebRTCVideoSource::DeliverFra
   data.mCbCrSize = gfxIntSize(mWidth/ 2, mHeight/ 2);
   data.mPicX = 0;
   data.mPicY = 0;
   data.mPicSize = gfxIntSize(mWidth, mHeight);
   data.mStereoMode = STEREO_MODE_MONO;
 
   videoImage->SetData(data);
 
-#ifdef LOG_ALL_FRAMES
+#ifdef DEBUG
   static uint32_t frame_num = 0;
-  LOG(("frame %d; timestamp %u, render_time %lu", frame_num++, time_stamp, render_time));
+  LOGFRAME(("frame %d; timestamp %u, render_time %lu", frame_num++, time_stamp, render_time));
 #endif
 
   // we don't touch anything in 'this' until here (except for snapshot,
   // which has it's own lock)
   ReentrantMonitorAutoEnter enter(mMonitor);
 
   // implicitly releases last image
   mImage = image.forget();
@@ -107,23 +109,26 @@ MediaEngineWebRTCVideoSource::NotifyPull
   ReentrantMonitorAutoEnter enter(mMonitor);
   if (mState != kStarted)
     return;
 
   // Note: we're not giving up mImage here
   nsRefPtr<layers::Image> image = mImage;
   TrackTicks target = TimeToTicksRoundUp(USECS_PER_S, aDesiredTime);
   TrackTicks delta = target - aLastEndTime;
-#ifdef LOG_ALL_FRAMES
-  LOG(("NotifyPull, target = %lu, delta = %lu", (uint64_t) target, (uint64_t) delta));
-#endif
-  // NULL images are allowed
-  segment.AppendFrame(image ? image.forget() : nullptr, delta, gfxIntSize(mWidth, mHeight));
-  aSource->AppendToTrack(aID, &(segment));
-  aLastEndTime = target;
+  LOGFRAME(("NotifyPull, desired = %ld, target = %ld, delta = %ld %s", (int64_t) aDesiredTime, 
+            (int64_t) target, (int64_t) delta, image ? "" : "<null>"));
+  // Don't append if we've already provided a frame that supposedly goes past the current aDesiredTime
+  // Doing so means a negative delta and thus messes up handling of the graph
+  if (delta > 0) {
+    // NULL images are allowed
+    segment.AppendFrame(image ? image.forget() : nullptr, delta, gfxIntSize(mWidth, mHeight));
+    aSource->AppendToTrack(aID, &(segment));
+    aLastEndTime = target;
+  }
 }
 
 void
 MediaEngineWebRTCVideoSource::ChooseCapability(uint32_t aWidth, uint32_t aHeight, uint32_t aMinFPS)
 {
   int num = mViECapture->NumberOfCapabilities(mUniqueId, KMaxUniqueIdLength);
 
   NS_WARN_IF_FALSE(!mCapabilityChosen,"Shouldn't select capability of a device twice");
@@ -187,16 +192,17 @@ MediaEngineWebRTCVideoSource::GetUUID(ns
 {
   // mUniqueId is UTF8
   CopyUTF8toUTF16(mUniqueId, aUUID);
 }
 
 nsresult
 MediaEngineWebRTCVideoSource::Allocate()
 {
+  LOG((__FUNCTION__));
   if (!mCapabilityChosen) {
     // XXX these should come from constraints
     ChooseCapability(mWidth, mHeight, mMinFps);
   }
 
   if (mState == kReleased && mInitDone) {
     if (mViECapture->AllocateCaptureDevice(mUniqueId, KMaxUniqueIdLength, mCaptureIndex)) {
       return NS_ERROR_FAILURE;
@@ -210,16 +216,17 @@ MediaEngineWebRTCVideoSource::Allocate()
   }
 
   return NS_OK;
 }
 
 nsresult
 MediaEngineWebRTCVideoSource::Deallocate()
 {
+  LOG((__FUNCTION__));
   if (mSources.IsEmpty()) {
     if (mState != kStopped && mState != kAllocated) {
       return NS_ERROR_FAILURE;
     }
 
     mViECapture->ReleaseCaptureDevice(mCaptureIndex);
     mState = kReleased;
     LOG(("Video device %d deallocated", mCaptureIndex));
@@ -236,16 +243,17 @@ MediaEngineWebRTCVideoSource::GetOptions
     ChooseCapability(mWidth, mHeight, mMinFps);
   }
   return &mOpts;
 }
 
 nsresult
 MediaEngineWebRTCVideoSource::Start(SourceMediaStream* aStream, TrackID aID)
 {
+  LOG((__FUNCTION__));
   int error = 0;
   if (!mInitDone || !aStream) {
     return NS_ERROR_FAILURE;
   }
 
   mSources.AppendElement(aStream);
 
   aStream->AddTrack(aID, USECS_PER_S, 0, new VideoSegment());
@@ -273,32 +281,36 @@ MediaEngineWebRTCVideoSource::Start(Sour
   }
 
   return NS_OK;
 }
 
 nsresult
 MediaEngineWebRTCVideoSource::Stop(SourceMediaStream *aSource, TrackID aID)
 {
+  LOG((__FUNCTION__));
   if (!mSources.RemoveElement(aSource)) {
     // Already stopped - this is allowed
     return NS_OK;
   }
   if (!mSources.IsEmpty()) {
     return NS_OK;
   }
 
   if (mState != kStarted) {
     return NS_ERROR_FAILURE;
   }
 
   {
     ReentrantMonitorAutoEnter enter(mMonitor);
     mState = kStopped;
     aSource->EndTrack(aID);
+    // Drop any cached image so we don't start with a stale image on next
+    // usage
+    mImage = nullptr;
   }
 
   mViERender->StopRender(mCaptureIndex);
   mViERender->RemoveRenderer(mCaptureIndex);
   mViECapture->StopCapture(mCaptureIndex);
 
   return NS_OK;
 }
@@ -402,16 +414,17 @@ MediaEngineWebRTCVideoSource::Snapshot(u
  */
 
 void
 MediaEngineWebRTCVideoSource::Init()
 {
   mDeviceName[0] = '\0'; // paranoia
   mUniqueId[0] = '\0';
 
+  LOG((__FUNCTION__));
   if (mVideoEngine == NULL) {
     return;
   }
 
   mViEBase = webrtc::ViEBase::GetInterface(mVideoEngine);
   if (mViEBase == NULL) {
     return;
   }
@@ -431,16 +444,17 @@ MediaEngineWebRTCVideoSource::Init()
   }
 
   mInitDone = true;
 }
 
 void
 MediaEngineWebRTCVideoSource::Shutdown()
 {
+  LOG((__FUNCTION__));
   if (!mInitDone) {
     return;
   }
 
   if (mState == kStarted) {
     while (!mSources.IsEmpty()) {
       Stop(mSources[0], kVideoTrack); // XXX change to support multiple tracks
     }
--- a/content/media/wmf/WMF.h
+++ b/content/media/wmf/WMF.h
@@ -24,18 +24,16 @@ which makes Windows Media Foundation una
 #include <mfidl.h>
 #include <mfreadwrite.h>
 #include <mfobjects.h>
 #include <stdio.h>
 #include <mferror.h>
 #include <propvarutil.h>
 #include <wmcodecdsp.h>
 
-#pragma comment(lib,"uuid.lib")
-#pragma comment(lib,"mfuuid.lib")
 
 namespace mozilla {
 namespace wmf {
 
 // Loads/Unloads all the DLLs in which the WMF functions are located.
 // The DLLs must be loaded before any of the WMF functions below will work.
 // All the function definitions below are wrappers which locate the
 // corresponding WMF function in the appropriate DLL (hence why LoadDLL()
--- a/content/smil/Makefile.in
+++ b/content/smil/Makefile.in
@@ -8,17 +8,19 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= content
 LIBRARY_NAME	= gkconsmil_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 EXPORTS	= \
 	nsISMILAnimationElement.h \
 	nsISMILAttr.h \
 	nsISMILType.h \
 	nsSMILAnimationController.h \
 	nsSMILCompositorTable.h \
 	nsSMILCSSProperty.h \
--- a/content/svg/content/src/Makefile.in
+++ b/content/svg/content/src/Makefile.in
@@ -8,17 +8,19 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= content
 LIBRARY_NAME	= gkcontentsvg_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS	= 1
+endif # !_MSC_VER
 
 CPPSRCS		= \
 		DOMSVGAnimatedLengthList.cpp \
 		DOMSVGAnimatedNumberList.cpp \
 		DOMSVGAnimatedTransformList.cpp \
 		DOMSVGLength.cpp \
 		DOMSVGLengthList.cpp \
 		DOMSVGMatrix.cpp \
--- a/dom/audiochannel/Makefile.in
+++ b/dom/audiochannel/Makefile.in
@@ -20,17 +20,19 @@ VPATH            = @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE           = dom
 LIBRARY_NAME     = domaudiochannel_s
 XPIDL_MODULE     = dom_audiochannel
 LIBXUL_LIBRARY = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 EXPORTS_NAMESPACES = \
   mozilla/dom \
   $(NULL)
 
 EXPORTS = AudioChannelService.h \
           AudioChannelServiceChild.h \
           AudioChannelCommon.h \
--- a/dom/base/Makefile.in
+++ b/dom/base/Makefile.in
@@ -2,24 +2,26 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= dom
 LIBRARY_NAME	= jsdombase_s
 LIBXUL_LIBRARY	= 1
 FORCE_STATIC_LIB = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 DIRS = \
   test \
   $(NULL)
 
 EXTRA_COMPONENTS = \
   SiteSpecificUserAgent.js \
   SiteSpecificUserAgent.manifest \
--- a/dom/base/nsDOMClassInfo.cpp
+++ b/dom/base/nsDOMClassInfo.cpp
@@ -4418,17 +4418,17 @@ nsDOMClassInfo::ResolveConstructor(JSCon
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMClassInfo::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                            JSObject *obj, jsid id, uint32_t flags,
                            JSObject **objp, bool *_retval)
 {
-  if (id == sConstructor_id && !(flags & JSRESOLVE_ASSIGNING)) {
+  if (id == sConstructor_id) {
     return ResolveConstructor(cx, obj, objp);
   }
 
   return NS_OK;
 }
 
 nsISupports*
 nsDOMTouchListSH::GetItemAt(nsISupports *aNative, uint32_t aIndex,
@@ -4902,18 +4902,18 @@ GetDocument(JSObject *obj)
 }
 
 // static
 JSBool
 nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSHandleObject obj,
                                           JSHandleId id, unsigned flags,
                                           JSMutableHandleObject objp)
 {
-  if ((flags & JSRESOLVE_ASSIGNING) || !JSID_IS_STRING(id)) {
-    // Nothing to do if we're assigning or resolving a non-string property.
+  if (!JSID_IS_STRING(id)) {
+    // Nothing to do if we're resolving a non-string property.
     return JS_TRUE;
   }
 
   nsHTMLDocument *document = GetDocument(obj);
 
   if (!document) {
     // If we don't have a document, return early.
 
@@ -6727,23 +6727,21 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
     }
 
     if (did_resolve) {
       *objp = obj;
       return NS_OK;
     }
   }
 
-  if (!(flags & JSRESOLVE_ASSIGNING)) {
-    // We want this code to be before the child frame lookup code
-    // below so that a child frame named 'constructor' doesn't
-    // shadow the window's constructor property.
-    if (sConstructor_id == id) {
-      return ResolveConstructor(cx, obj, objp);
-    }
+  // We want this code to be before the child frame lookup code
+  // below so that a child frame named 'constructor' doesn't
+  // shadow the window's constructor property.
+  if (sConstructor_id == id) {
+    return ResolveConstructor(cx, obj, objp);
   }
 
   if (!my_context || !my_context->IsContextInitialized()) {
     // The context is not yet initialized so there's nothing we can do
     // here yet.
 
     return NS_OK;
   }
@@ -6778,17 +6776,17 @@ nsWindowSH::NewResolve(nsIXPConnectWrapp
       return NS_ERROR_FAILURE;
     }
 
     *objp = obj;
 
     return NS_OK;
   }
 
-  if (sTop_id == id && !(flags & JSRESOLVE_ASSIGNING)) {
+  if (sTop_id == id) {
     nsCOMPtr<nsIDOMWindow> top;
     rv = win->GetScriptableTop(getter_AddRefs(top));
     NS_ENSURE_SUCCESS(rv, rv);
 
     jsval v;
     nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
     rv = WrapNative(cx, obj, top, &NS_GET_IID(nsIDOMWindow), true,
                     &v, getter_AddRefs(holder));
@@ -7189,17 +7187,17 @@ nsLocationSH::AddProperty(nsIXPConnectWr
 
 // DOM Navigator helper
 
 NS_IMETHODIMP
 nsNavigatorSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx,
                           JSObject *obj, jsid id, uint32_t flags,
                           JSObject **objp, bool *_retval)
 {
-  if (!JSID_IS_STRING(id) || (flags & JSRESOLVE_ASSIGNING)) {
+  if (!JSID_IS_STRING(id)) {
     return NS_OK;
   }
 
   nsScriptNameSpaceManager *nameSpaceManager =
     nsJSRuntime::GetNameSpaceManager();
   NS_ENSURE_TRUE(nameSpaceManager, NS_ERROR_NOT_INITIALIZED);
 
   nsDependentJSString name(id);
@@ -8383,22 +8381,16 @@ nsHTMLDocumentSH::DocumentAllGetProperty
 
   return JS_TRUE;
 }
 
 JSBool
 nsHTMLDocumentSH::DocumentAllNewResolve(JSContext *cx, JSHandleObject obj, JSHandleId id,
                                         unsigned flags, JSMutableHandleObject objp)
 {
-  if (flags & JSRESOLVE_ASSIGNING) {
-    // Nothing to do here if we're assigning
-
-    return JS_TRUE;
-  }
-
   js::RootedValue v(cx);
 
   if (sItem_id == id || sNamedItem_id == id) {
     // Define the item() or namedItem() method.
 
     JSFunction *fnc = ::JS_DefineFunctionById(cx, obj, id, CallToGetPropMapper,
                                               0, JSPROP_ENUMERATE);
     objp.set(obj);
--- a/dom/base/nsGlobalWindow.cpp
+++ b/dom/base/nsGlobalWindow.cpp
@@ -9822,22 +9822,16 @@ nsGlobalWindow::RescheduleTimeout(nsTime
     aTimeout->mTimeRemaining = delay;
     return true;
   }
 
   aTimeout->mWhen = currentNow + delay;
 
   // Reschedule the OS timer. Don't bother returning any error codes if
   // this fails since the callers of this method don't care about them.
-
-  // Make sure to cast the unsigned PR_USEC_PER_MSEC to signed
-  // PRTime to make the division do the right thing on 64-bit
-  // platforms whether delay is positive or negative (which we
-  // know is always positive here, but cast anyways for
-  // consistency).
   nsresult rv = aTimeout->InitTimer(TimerCallback, delay.ToMilliseconds());
 
   if (NS_FAILED(rv)) {
     NS_ERROR("Error initializing timer for DOM timeout!");
 
     // We failed to initialize the new OS timer, this timer does
     // us no good here so we just cancel it (just in case) and
     // null out the pointer to the OS timer, this will release the
--- a/dom/base/nsGlobalWindow.h
+++ b/dom/base/nsGlobalWindow.h
@@ -143,17 +143,18 @@ struct nsTimeout : mozilla::LinkedListEl
   ~nsTimeout();
 
   NS_DECL_CYCLE_COLLECTION_LEGACY_NATIVE_CLASS(nsTimeout)
 
   nsrefcnt Release();
   nsrefcnt AddRef();
 
   nsresult InitTimer(nsTimerCallbackFunc aFunc, uint64_t delay) {
-    return mTimer->InitWithFuncCallback(aFunc, this, delay,
+    return mTimer->InitWithFuncCallback(aFunc, this,
+                                        static_cast<uint32_t>(delay),
                                         nsITimer::TYPE_ONE_SHOT);
   }
 
   // Window for which this timeout fires
   nsRefPtr<nsGlobalWindow> mWindow;
 
   // The actual timer object
   nsCOMPtr<nsITimer> mTimer;
--- a/dom/base/nsJSEnvironment.cpp
+++ b/dom/base/nsJSEnvironment.cpp
@@ -172,18 +172,17 @@ static uint32_t sPreviousSuspectedCount 
 static uint32_t sCompartmentGCCount = NS_MAX_COMPARTMENT_GC_COUNT;
 static uint32_t sCleanupsSinceLastGC = UINT32_MAX;
 static bool sNeedsFullCC = false;
 static nsJSContext *sContextList = nullptr;
 
 static nsScriptNameSpaceManager *gNameSpaceManager;
 static nsIMemoryReporter *gReporter;
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ScriptNameSpaceManagerMallocSizeOf,
-                                     "script-namespace-manager")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ScriptNameSpaceManagerMallocSizeOf)
 
 static int64_t
 GetScriptNameSpaceManagerSize()
 {
   MOZ_ASSERT(gNameSpaceManager);
   return gNameSpaceManager->SizeOfIncludingThis(
              ScriptNameSpaceManagerMallocSizeOf);
 }
--- a/dom/base/nsWindowMemoryReporter.cpp
+++ b/dom/base/nsWindowMemoryReporter.cpp
@@ -100,17 +100,17 @@ AppendWindowURI(nsGlobalWindow *aWindow,
     aStr += spec;
   } else {
     // If we're unable to find a URI, we're dealing with a chrome window with
     // no document in it (or somesuch), so we call this a "system window".
     aStr += NS_LITERAL_CSTRING("[system]");
   }
 }
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(DOMStyleMallocSizeOf, "windows")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(WindowsMallocSizeOf)
 
 // The key is the window ID.
 typedef nsDataHashtable<nsUint64HashKey, nsCString> WindowPaths;
 
 static nsresult
 CollectWindowReports(nsGlobalWindow *aWindow,
                      nsWindowSizes *aWindowTotalSizes,
                      nsTHashtable<nsUint64HashKey> *aGhostWindowIDs,
@@ -161,17 +161,17 @@ CollectWindowReports(nsGlobalWindow *aWi
         nsresult rv;                                                          \
         rv = aCb->Callback(EmptyCString(), path, nsIMemoryReporter::KIND_HEAP,\
                       nsIMemoryReporter::UNITS_BYTES, _amount,                \
                       NS_LITERAL_CSTRING(_desc), aClosure);                   \
         NS_ENSURE_SUCCESS(rv, rv);                                            \
     }                                                                         \
   } while (0)
 
-  nsWindowSizes windowSizes(DOMStyleMallocSizeOf);
+  nsWindowSizes windowSizes(WindowsMallocSizeOf);
   aWindow->SizeOfIncludingThis(&windowSizes);
 
   REPORT("/dom/other", windowSizes.mDOMOther,
          "Memory used by a window's DOM, excluding element, text, CDATA, "
          "and comment nodes.");
   aWindowTotalSizes->mDOMOther += windowSizes.mDOMOther;
 
   REPORT("/dom/element-nodes", windowSizes.mDOMElementNodes,
--- a/dom/base/test/Makefile.in
+++ b/dom/base/test/Makefile.in
@@ -14,16 +14,17 @@ MOCHITEST_FILES = \
   test_document.all_unqualified.html \
   test_domrequest.html \
   test_e4x_for_each.html \
   test_gsp-standards.html \
   test_gsp-quirks.html \
   test_gsp-qualified.html \
   test_nondomexception.html \
   test_screen_orientation.html \
+  test_window_constructor.html \
   test_window_enumeration.html \
   test_writable-replaceable.html \
   $(NULL)
 
 MOCHITEST_CHROME_FILES = \
    test_bug715041.xul \
    test_bug715041_removal.xul \
    $(NULL)
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_window_constructor.html
@@ -0,0 +1,36 @@
+<!DOCTYPE html>
+<html>
+<!--
+https://bugzilla.mozilla.org/show_bug.cgi?id=824217
+-->
+<head>
+  <meta charset="UTF-8">
+  <title>Test for Bug 824217</title>
+  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.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=622491">Mozilla Bug 824217</a>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<iframe name="constructor" src="about:blank"></iframe>
+<pre id="test">
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+function run()
+{
+  // Ideally we'd test that this property lives on the right place in the
+  // [[Prototype]] chain, with the right attributes there, but we don't
+  // implement this right yet, so just test the value's what's expected.
+  is(window.constructor, Window,
+     "should have gotten Window, not the constructor frame");
+  SimpleTest.finish();
+}
+
+window.addEventListener("load", run, false);
+</script>
+</pre>
+</body>
+</html>
--- a/dom/bindings/Codegen.py
+++ b/dom/bindings/Codegen.py
@@ -6806,17 +6806,17 @@ class CGBindingRoot(CGThing):
             except NoSuchDescriptorError:
                 # just move along
                 pass
 
         def declareNativeType(nativeType):
             components = nativeType.split('::')
             className = components[-1]
             # JSObject is a struct, not a class
-            declare = CGClassForwardDeclare(className, className is "JSObject")
+            declare = CGClassForwardDeclare(className, className == "JSObject")
             if len(components) > 1:
                 declare = CGNamespace.build(components[:-1],
                                             CGWrapper(declare, declarePre='\n',
                                                       declarePost='\n'),
                                             declareOnly=True)
             return CGWrapper(declare, declarePost='\n')
 
         for x in descriptorsForForwardDeclaration:
--- a/dom/bluetooth/linux/BluetoothDBusService.cpp
+++ b/dom/bluetooth/linux/BluetoothDBusService.cpp
@@ -1996,16 +1996,24 @@ BluetoothDBusService::GetPairedDevicePro
 nsresult
 BluetoothDBusService::SetProperty(BluetoothObjectType aType,
                                   const nsAString& aPath,
                                   const BluetoothNamedValue& aValue,
                                   BluetoothReplyRunnable* aRunnable)
 {
   NS_ASSERTION(NS_IsMainThread(), "Must be called from main thread!");
 
+  if (!IsReady()) {
+    BluetoothValue v;
+    nsString errorStr;
+    errorStr.AssignLiteral("Bluetooth service is not ready yet!");
+    DispatchBluetoothReply(aRunnable, v, errorStr);
+    return NS_OK;
+  }
+
   MOZ_ASSERT(aType < ArrayLength(sBluetoothDBusIfaces));
   const char* interface = sBluetoothDBusIfaces[aType];
 
   /* Compose the command */
   DBusMessage* msg = dbus_message_new_method_call("org.bluez",
                                                   NS_ConvertUTF16toUTF8(aPath).get(),
                                                   interface,
                                                   "SetProperty");
new file mode 100644
--- /dev/null
+++ b/dom/contacts/tests/marionette/manifest.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+b2g = true
+browser = false
+qemu = true
+
+[test_sim_contacts.js]
new file mode 100644
--- /dev/null
+++ b/dom/contacts/tests/marionette/test_sim_contacts.js
@@ -0,0 +1,59 @@
+/* Any copyright is dedicated to the Public Domain.
+   http://creativecommons.org/publicdomain/zero/1.0/ */
+
+MARIONETTE_TIMEOUT = 30000;
+
+SpecialPowers.addPermission("contacts-read", true, document);
+
+let mozContacts = window.navigator.mozContacts;
+ok(mozContacts);
+
+function testImportSimContacts() {
+  let request = mozContacts.getSimContacts("ADN");
+  request.onsuccess = function onsuccess() {
+    let simContacts = request.result;
+
+    // These SIM contacts are harded in external/qemu/telephony/sim_card.c
+    is(simContacts.length, 4);
+
+    is(simContacts[0].name, "Mozilla");
+    is(simContacts[0].tel[0].value, "15555218201");
+
+    is(simContacts[1].name, "Saßê黃");
+    is(simContacts[1].tel[0].value, "15555218202");
+
+    is(simContacts[2].name, "Fire 火");
+    is(simContacts[2].tel[0].value, "15555218203");
+
+    is(simContacts[3].name, "Huang 黃");
+    is(simContacts[3].tel[0].value, "15555218204");
+
+    runNextTest();
+  };
+
+  request.onerror = function onerror() {
+    ok(false, "Cannot get Sim Contacts");
+    runNextTest();
+  };
+};
+
+let tests = [
+  testImportSimContacts,
+];
+
+function runNextTest() {
+  let test = tests.pop();
+  if (!test) {
+    cleanUp();
+    return;
+  }
+
+  test();
+}
+
+function cleanUp() {
+  SpecialPowers.removePermission("contacts-read", document);
+  finish();
+}
+
+runNextTest();
--- a/dom/devicestorage/Makefile.in
+++ b/dom/devicestorage/Makefile.in
@@ -9,17 +9,19 @@ VPATH            = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE           = dom
 LIBRARY_NAME     = domdevicestorage_s
 XPIDL_MODULE     = dom_devicestorage
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 include $(topsrcdir)/dom/dom-config.mk
 
 EXPORTS_NAMESPACES = mozilla/dom/devicestorage
 
 EXPORTS_mozilla/dom/devicestorage = \
   DeviceStorageRequestChild.h \
   DeviceStorageRequestParent.h \
--- a/dom/file/Makefile.in
+++ b/dom/file/Makefile.in
@@ -1,25 +1,27 @@
 # 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/.
 
 DEPTH            = @DEPTH@
 topsrcdir        = @top_srcdir@
 srcdir           = @srcdir@
 VPATH            = @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE           = dom
 LIBRARY_NAME     = domfile_s
 XPIDL_MODULE     = dom_file
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 include $(topsrcdir)/dom/dom-config.mk
 
 EXPORTS_NAMESPACES = mozilla/dom/file
 
 CPPSRCS = \
   AsyncHelper.cpp \
   DOMFileHandle.cpp \
--- a/dom/indexedDB/Makefile.in
+++ b/dom/indexedDB/Makefile.in
@@ -1,25 +1,27 @@
 # 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/.
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = dom
 LIBRARY_NAME = dom_indexeddb_s
 XPIDL_MODULE = dom_indexeddb
 LIBXUL_LIBRARY = 1
 FORCE_STATIC_LIB = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 EXPORTS_NAMESPACES = mozilla/dom/indexedDB
 
 CPPSRCS = \
   AsyncConnectionHelper.cpp \
   CheckPermissionsHelper.cpp \
   DatabaseInfo.cpp \
   FileInfo.cpp \
--- a/dom/ipc/Makefile.in
+++ b/dom/ipc/Makefile.in
@@ -9,17 +9,19 @@ VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = dom
 LIBRARY_NAME = domipc_s
 LIBXUL_LIBRARY = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
 TEST_DIRS += tests
 endif
 
 EXPORTS = PCOMContentPermissionRequestChild.h
 
 EXPORTS_NAMESPACES = \
--- a/dom/media/Makefile.in
+++ b/dom/media/Makefile.in
@@ -10,17 +10,19 @@ relativesrcdir   = @relativesrcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE           = dom
 XPIDL_MODULE     = dom_media
 LIBRARY_NAME     = dom_media_s
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 include $(topsrcdir)/dom/dom-config.mk
 
 EXTRA_COMPONENTS = \
   PeerConnection.js \
   PeerConnection.manifest \
   $(NULL)
 
--- a/dom/media/tests/mochitest/mediaStreamPlayback.js
+++ b/dom/media/tests/mochitest/mediaStreamPlayback.js
@@ -48,40 +48,30 @@ function MediaStreamPlayback(mediaElemen
     var canPlayThroughCallback = function() {
       // Disable the canplaythrough event listener to prevent multiple calls
       canPlayThroughFired = true;
       self.mediaElement.removeEventListener('canplaythrough',
         canPlayThroughCallback, false);
 
       is(self.mediaElement.paused, false,
         "Media element should be playing");
-      is(self.mediaElement.ended, false,
-        "Media element should not have ended");
       is(self.mediaElement.duration, Number.POSITIVE_INFINITY,
         "Duration should be infinity");
 
       // When the media element is playing with a real-time stream, we
       // constantly switch between having data to play vs. queuing up data,
       // so we can only check that the ready state is one of those two values
       ok(self.mediaElement.readyState === HTMLMediaElement.HAVE_ENOUGH_DATA ||
          self.mediaElement.readyState === HTMLMediaElement.HAVE_CURRENT_DATA,
          "Ready state shall be HAVE_ENOUGH_DATA or HAVE_CURRENT_DATA");
 
       is(self.mediaElement.seekable.length, 0,
          "Seekable length shall be zero");
       is(self.mediaElement.buffered.length, 0,
          "Buffered length shall be zero");
-      is(self.mediaElement.played.length, 1, "Played length shall be one");
-
-      if(self.mediaElement.played.length > 0) {
-        is(self.mediaElement.played.start(0), 0,
-          "Played start shall be zero");
-        is(self.mediaElement.played.end(0), self.mediaElement.currentTime,
-          "End shall be current time");
-      }
 
       is(self.mediaElement.seeking, false,
          "MediaElement is not seekable with MediaStream");
       ok(isNaN(self.mediaElement.startOffsetTime),
          "Start offset time shall not be a number");
       is(self.mediaElement.loop, false, "Loop shall be false");
       is(self.mediaElement.preload, "", "Preload should not exist");
       is(self.mediaElement.src, "", "No src should be defined");
--- a/dom/network/src/Makefile.in
+++ b/dom/network/src/Makefile.in
@@ -7,17 +7,19 @@ topsrcdir        = @top_srcdir@
 srcdir           = @srcdir@
 VPATH            = $(srcdir)
 
 include $(DEPTH)/config/autoconf.mk
 
 LIBRARY_NAME     = dom_network_s
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 EXTRA_COMPONENTS = \
 	TCPSocket.js \
 	TCPSocketParentIntermediary.js \
 	TCPSocket.manifest \
 	$(NULL)
 
 ifdef MOZ_B2G_RIL
--- a/dom/plugins/base/Makefile.in
+++ b/dom/plugins/base/Makefile.in
@@ -66,17 +66,19 @@ CPPSRCS		= \
 
 ifeq ($(MOZ_WIDGET_TOOLKIT),android)
 DIRS += android
 LOCAL_INCLUDES += -I$(topsrcdir)/dom/plugins/base/android
 else
 # android_npapi.h extends the NPNVariable and NPPVariable enums
 # using #defines, which results in Wswitch warnings in gcc-4.6.
 # Therefore, enable FAIL_ON_WARNINGS only on non-Android platforms.
+ifndef _MSC_VER
 FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 endif
 
 ifeq ($(OS_ARCH),WINNT)
 	CPPSRCS += nsPluginsDirWin.cpp
 	CPPSRCS += nsPluginNativeWindowWin.cpp
 	CPPSRCS += nsPluginDirServiceProvider.cpp
 	LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
 else
--- a/dom/plugins/ipc/Makefile.in
+++ b/dom/plugins/ipc/Makefile.in
@@ -1,21 +1,23 @@
 # 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/.
 
 DEPTH = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir = @srcdir@
 VPATH = @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = dom
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 EXPORTS_NAMESPACES = mozilla
 
 EXPORTS_mozilla = \
   PluginLibrary.h \
   $(NULL)
 
 EXPORTS_NAMESPACES = mozilla mozilla/plugins
--- a/dom/plugins/test/testplugin/Makefile.in
+++ b/dom/plugins/test/testplugin/Makefile.in
@@ -2,21 +2,23 @@
 # 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/.
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
-FAIL_ON_WARNINGS = 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE       = nptest
 LIBRARY_NAME = nptest
 MODULE_NAME  = TestPlugin
+ifndef _MSC_VER
+FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 DIRS = secondplugin
 
 RELATIVE_PATH=.
 COCOA_NAME=Test
 include @srcdir@/testplugin.mk
--- a/dom/power/Makefile.in
+++ b/dom/power/Makefile.in
@@ -8,17 +8,19 @@ srcdir           = @srcdir@
 VPATH            = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 LIBRARY_NAME     = dom_power_s
 XPIDL_MODULE     = dom_power
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 include $(topsrcdir)/dom/dom-config.mk
 
 EXPORTS_NAMESPACES = mozilla/dom/power
 
 EXPORTS_mozilla/dom/power = \
   PowerManagerService.h \
   Types.h \
--- a/dom/sms/src/Makefile.in
+++ b/dom/sms/src/Makefile.in
@@ -18,17 +18,19 @@ else ifdef MOZ_B2G_RIL
 VPATH += $(srcdir)/ril
 else
 VPATH += $(srcdir)/fallback
 endif
 
 LIBRARY_NAME     = dom_sms_s
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 include $(topsrcdir)/dom/dom-config.mk
 
 EXPORTS_NAMESPACES = mozilla/dom/sms
 
 EXPORTS_mozilla/dom/sms = \
   SmsChild.h \
   SmsParent.h \
--- a/dom/system/gonk/ril_worker.js
+++ b/dom/system/gonk/ril_worker.js
@@ -920,17 +920,17 @@ let RIL = {
    * @param [optional] aid
    *        AID value.
    */
   enterICCPIN: function enterICCPIN(options) {
     Buf.newParcel(REQUEST_ENTER_SIM_PIN, options);
     Buf.writeUint32(RILQUIRKS_V5_LEGACY ? 1 : 2);
     Buf.writeString(options.pin);
     if (!RILQUIRKS_V5_LEGACY) {
-      Buf.writeString(options.aid ? options.aid : this.aid);
+      Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
   },
 
   /**
    * Enter a PIN2 to unlock the ICC.
    *
    * @param pin
@@ -938,17 +938,17 @@ let RIL = {
    * @param [optional] aid
    *        AID value.
    */
   enterICCPIN2: function enterICCPIN2(options) {
     Buf.newParcel(REQUEST_ENTER_SIM_PIN2, options);
     Buf.writeUint32(RILQUIRKS_V5_LEGACY ? 1 : 2);
     Buf.writeString(options.pin);
     if (!RILQUIRKS_V5_LEGACY) {
-      Buf.writeString(options.aid ? options.aid : this.aid);
+      Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
   },
 
   /**
    * Requests a network personalization be deactivated.
    *
    * @param type
@@ -1002,17 +1002,17 @@ let RIL = {
    *        AID value.
    */
   changeICCPIN: function changeICCPIN(options) {
     Buf.newParcel(REQUEST_CHANGE_SIM_PIN, options);
     Buf.writeUint32(RILQUIRKS_V5_LEGACY ? 2 : 3);
     Buf.writeString(options.pin);
     Buf.writeString(options.newPin);
     if (!RILQUIRKS_V5_LEGACY) {
-      Buf.writeString(options.aid ? options.aid : this.aid);
+      Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
   },
 
   /**
    * Change the current ICC PIN2 number.
    *
    * @param pin
@@ -1023,17 +1023,17 @@ let RIL = {
    *        AID value.
    */
   changeICCPIN2: function changeICCPIN2(options) {
     Buf.newParcel(REQUEST_CHANGE_SIM_PIN2, options);
     Buf.writeUint32(RILQUIRKS_V5_LEGACY ? 2 : 3);
     Buf.writeString(options.pin);
     Buf.writeString(options.newPin);
     if (!RILQUIRKS_V5_LEGACY) {
-      Buf.writeString(options.aid ? options.aid : this.aid);
+      Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
   },
   /**
    * Supplies ICC PUK and a new PIN to unlock the ICC.
    *
    * @param puk
    *        String containing the PUK value.
@@ -1043,17 +1043,17 @@ let RIL = {
    *        AID value.
    */
    enterICCPUK: function enterICCPUK(options) {
      Buf.newParcel(REQUEST_ENTER_SIM_PUK, options);
      Buf.writeUint32(RILQUIRKS_V5_LEGACY ? 2 : 3);
      Buf.writeString(options.puk);
      Buf.writeString(options.newPin);
      if (!RILQUIRKS_V5_LEGACY) {
-       Buf.writeString(options.aid ? options.aid : this.aid);
+       Buf.writeString(options.aid || this.aid);
      }
      Buf.sendParcel();
    },
 
   /**
    * Supplies ICC PUK2 and a new PIN2 to unlock the ICC.
    *
    * @param puk
@@ -1064,17 +1064,17 @@ let RIL = {
    *        AID value.
    */
    enterICCPUK2: function enterICCPUK2(options) {
      Buf.newParcel(REQUEST_ENTER_SIM_PUK2, options);
      Buf.writeUint32(RILQUIRKS_V5_LEGACY ? 2 : 3);
      Buf.writeString(options.puk);
      Buf.writeString(options.newPin);
      if (!RILQUIRKS_V5_LEGACY) {
-       Buf.writeString(options.aid ? options.aid : this.aid);
+       Buf.writeString(options.aid || this.aid);
      }
      Buf.sendParcel();
    },
 
   /**
    * Helper function for fetching the state of ICC locks.
    */
   iccGetCardLock: function iccGetCardLock(options) {
@@ -1118,17 +1118,17 @@ let RIL = {
    */
   queryICCFacilityLock: function queryICCFacilityLock(options) {
     Buf.newParcel(REQUEST_QUERY_FACILITY_LOCK, options);
     Buf.writeUint32(RILQUIRKS_V5_LEGACY ? 3 : 4);
     Buf.writeString(options.facility);
     Buf.writeString(options.password);
     Buf.writeString(options.serviceClass.toString());
     if (!RILQUIRKS_V5_LEGACY) {
-      Buf.writeString(options.aid ? options.aid : this.aid);
+      Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
   },
 
   /**
    * Set ICC Pin lock. A wrapper call to setICCFacilityLock.
    *
    * @param enabled
@@ -1165,17 +1165,17 @@ let RIL = {
   setICCFacilityLock: function setICCFacilityLock(options) {
     Buf.newParcel(REQUEST_SET_FACILITY_LOCK, options);
     Buf.writeUint32(RILQUIRKS_V5_LEGACY ? 3 : 4);
     Buf.writeString(options.facility);
     Buf.writeString(options.enabled ? "1" : "0");
     Buf.writeString(options.password);
     Buf.writeString(options.serviceClass.toString());
     if (!RILQUIRKS_V5_LEGACY) {
-      Buf.writeString(options.aid ? options.aid : this.aid);
+      Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
   },
 
   /**
    *  Request an ICC I/O operation.
    *
    *  See TS 27.007 "restricted SIM" operation, "AT Command +CRSM".
@@ -1200,480 +1200,42 @@ let RIL = {
   iccIO: function iccIO(options) {
     let token = Buf.newParcel(REQUEST_SIM_IO, options);
     Buf.writeUint32(options.command);
     Buf.writeUint32(options.fileId);
     Buf.writeString(options.pathId);
     Buf.writeUint32(options.p1);
     Buf.writeUint32(options.p2);
     Buf.writeUint32(options.p3);
-    Buf.writeString(options.data);
-    Buf.writeString(options.pin2 ? options.pin2 : null);
+    Buf.writeString(options.data || null);
+    Buf.writeString(options.pin2 || null);
     if (!RILQUIRKS_V5_LEGACY) {
-      Buf.writeString(options.aid ? options.aid : this.aid);
+      Buf.writeString(options.aid || this.aid);
     }
     Buf.sendParcel();
   },
 
   /**
-   * Fetch ICC records.
-   */
-  fetchICCRecords: function fetchICCRecords() {
-    this.getICCID();
-    this.getIMSI();
-    this.getMSISDN();
-    this.getAD();
-    this.getSST();
-    this.getMBDN();
-  },
-
-  /**
-   * Update the ICC information to RadioInterfaceLayer.
-   */
-  _handleICCInfoChange: function _handleICCInfoChange() {
-    this.iccInfo.rilMessageType = "iccinfochange";
-    this.sendDOMMessage(this.iccInfo);
-  },
-
-  /**
-   * This will compute the spnDisplay field of the network.
-   * See TS 22.101 Annex A and TS 51.011 10.3.11 for details.
-   *
-   * @return True if some of iccInfo is changed in by this function.
-   */
-  updateDisplayCondition: function updateDisplayCondition() {
-    // If EFspn isn't existed in SIM or it haven't been read yet, we should
-    // just set isDisplayNetworkNameRequired = true and
-    // isDisplaySpnRequired = false
-    let iccInfo = this.iccInfo;
-    let iccInfoPriv = this.iccInfoPrivate;
-    let iccSpn = iccInfoPriv.SPN;
-    let origIsDisplayNetworkNameRequired = iccInfo.isDisplayNetworkNameRequired;
-    let origIsDisplaySPNRequired = iccInfo.isDisplaySpnRequired;
-
-    if (!iccSpn) {
-      iccInfo.isDisplayNetworkNameRequired = true;
-      iccInfo.isDisplaySpnRequired = false;
-    } else {
-      let operatorMnc = this.operator.mnc;
-      let operatorMcc = this.operator.mcc;
-
-      // First detect if we are on HPLMN or one of the PLMN
-      // specified by the SIM card.
-      let isOnMatchingPlmn = false;
-
-      // If the current network is the one defined as mcc/mnc
-      // in SIM card, it's okay.
-      if (iccInfo.mcc == operatorMcc && iccInfo.mnc == operatorMnc) {
-        isOnMatchingPlmn = true;
-      }
-
-      // Test to see if operator's mcc/mnc match mcc/mnc of PLMN.
-      if (!isOnMatchingPlmn && iccInfoPriv.SPDI) {
-        let iccSpdi = iccInfoPriv.SPDI; // PLMN list
-        for (let plmn in iccSpdi) {
-          let plmnMcc = iccSpdi[plmn].mcc;
-          let plmnMnc = iccSpdi[plmn].mnc;
-          isOnMatchingPlmn = (plmnMcc == operatorMcc) && (plmnMnc == operatorMnc);
-          if (isOnMatchingPlmn) {
-            break;
-          }
-        }
-      }
-
-      if (isOnMatchingPlmn) {
-        // The first bit of display condition tells us if we should display
-        // registered PLMN.
-        if (DEBUG) debug("updateDisplayCondition: PLMN is HPLMN or PLMN is in PLMN list");
-
-        // TS 31.102 Sec. 4.2.66 and TS 51.011 Sec. 10.3.50
-        // EF_SPDI contains a list of PLMNs in which the Service Provider Name
-        // shall be displayed.
-        iccInfo.isDisplaySpnRequired = true;
-        if (iccSpn.spnDisplayCondition & 0x01) {
-          iccInfo.isDisplayNetworkNameRequired = true;
-        } else {
-          iccInfo.isDisplayNetworkNameRequired = false;
-        }
-      } else {
-        // The second bit of display condition tells us if we should display
-        // registered PLMN.
-        if (DEBUG) debug("updateICCDisplayName: PLMN isn't HPLMN and PLMN isn't in PLMN list");
-
-        // We didn't found the requirement of displaying network name if
-        // current PLMN isn't HPLMN nor one of PLMN in SPDI. So we keep
-        // isDisplayNetworkNameRequired false.
-        if (iccSpn.spnDisplayCondition & 0x02) {
-          iccInfo.isDisplayNetworkNameRequired = false;
-          iccInfo.isDisplaySpnRequired = false;
-        } else {
-          iccInfo.isDisplayNetworkNameRequired = false;
-          iccInfo.isDisplaySpnRequired = true;
-        }
-      }
-    }
-
-    if (DEBUG) {
-      debug("updateDisplayCondition: isDisplayNetworkNameRequired = " + iccInfo.isDisplayNetworkNameRequired);
-      debug("updateDisplayCondition: isDisplaySpnRequired = " + iccInfo.isDisplaySpnRequired);
-    }
-
-    return ((origIsDisplayNetworkNameRequired !== iccInfo.isDisplayNetworkNameRequired) ||
-            (origIsDisplaySPNRequired !== iccInfo.isDisplaySpnRequired));
-  },
-
-  /**
-   * Get EF_phase.
-   * This EF is only available in SIM.
-   */
-  getICCPhase: function getICCPhase() {
-    function callback() {
-      let length = Buf.readUint32();
-
-      let phase = GsmPDUHelper.readHexOctet();
-      // If EF_phase is coded '03' or greater, an ME supporting STK shall
-      // perform the PROFILE DOWNLOAD procedure.
-      if (phase >= ICC_PHASE_2_PROFILE_DOWNLOAD_REQUIRED) {
-        this.sendStkTerminalProfile(STK_SUPPORTED_TERMINAL_PROFILE);
-      }
-
-      Buf.readStringDelimiter(length);
-    }
-
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_PHASE,
-      pathId:    EF_PATH_MF_SIM + EF_PATH_DF_GSM,
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_TRANSPARENT,
-      callback:  callback,
-    });
-  },
-
-  /**
    * Get IMSI.
    *
    * @param [optional] aid
    *        AID value.
    */
   getIMSI: function getIMSI(aid) {
     if (RILQUIRKS_V5_LEGACY) {
       Buf.simpleRequest(REQUEST_GET_IMSI);
       return;
     }
     let token = Buf.newParcel(REQUEST_GET_IMSI);
     Buf.writeUint32(1);
-    Buf.writeString(aid ? aid : this.aid);
+    Buf.writeString(aid || this.aid);
     Buf.sendParcel();
   },
 
   /**
-   * Read the ICCD from the ICC card.
-   */
-  getICCID: function getICCID() {
-    function callback() {
-      let length = Buf.readUint32();
-      this.iccInfo.iccid = GsmPDUHelper.readSwappedNibbleBcdString(length / 2);
-      Buf.readStringDelimiter(length);
-
-      if (DEBUG) debug("ICCID: " + this.iccInfo.iccid);
-      if (this.iccInfo.iccid) {
-        this._handleICCInfoChange();
-      }
-    }
-
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_ICCID,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_ICCID),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_TRANSPARENT,
-      callback:  callback,
-    });
-  },
-
-  /**
-   * Read the MSISDN from the ICC.
-   */
-  getMSISDN: function getMSISDN() {
-    function callback(options) {
-      let parseCallback = function parseCallback(msisdn) {
-        if (this.iccInfo.msisdn === msisdn.number) {
-          return;
-        }
-        this.iccInfo.msisdn = msisdn.number;
-        if (DEBUG) debug("MSISDN: " + this.iccInfo.msisdn);
-        this._handleICCInfoChange();
-      }
-      this.parseDiallingNumber(options, parseCallback);
-    }
-
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_MSISDN,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_MSISDN),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_LINEAR_FIXED,
-      callback:  callback,
-    });
-  },
-
-  /**
-   * Read the AD (Administrative Data) from the ICC.
-   */
-  getAD: function getAD() {
-    function callback() {
-      let length = Buf.readUint32();
-      // Each octet is encoded into two chars.
-      let len = length / 2;
-      this.iccInfo.ad = GsmPDUHelper.readHexOctetArray(len);
-      Buf.readStringDelimiter(length);
-
-      if (DEBUG) {
-        let str = "";
-        for (let i = 0; i < this.iccInfo.ad.length; i++) {
-          str += this.iccInfo.ad[i] + ", ";
-        }
-        debug("AD: " + str);
-      }
-
-      if (this.iccInfo.imsi) {
-        // MCC is the first 3 digits of IMSI
-        this.iccInfo.mcc = parseInt(this.iccInfo.imsi.substr(0,3));
-        // The 4th byte of the response is the length of MNC
-        this.iccInfo.mnc = parseInt(this.iccInfo.imsi.substr(3, this.iccInfo.ad[3]));
-        if (DEBUG) debug("MCC: " + this.iccInfo.mcc + " MNC: " + this.iccInfo.mnc);
-        this._handleICCInfoChange();
-      }
-    }
-
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_AD,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_AD),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_TRANSPARENT,
-      callback:  callback,
-    });
-  },
-
-  /**
-   * Read the SPN (Service Provider Name) from the ICC.
-   */
-  getSPN: function getSPN() {
-    function callback() {
-      let length = Buf.readUint32();
-      // Each octet is encoded into two chars.
-      // Minus 1 because first is used to store display condition
-      let len = (length / 2) - 1;
-      let spnDisplayCondition = GsmPDUHelper.readHexOctet();
-      let spn = GsmPDUHelper.readAlphaIdentifier(len);
-      Buf.readStringDelimiter(length);
-
-      if (DEBUG) {
-        debug("SPN: spn = " + spn +
-              ", spnDisplayCondition = " + spnDisplayCondition);
-      }
-
-      this.iccInfoPrivate.SPN = {
-        spn : spn,
-        spnDisplayCondition : spnDisplayCondition,
-      };
-      this.iccInfo.spn = spn;
-      this.updateDisplayCondition();
-      this._handleICCInfoChange();
-    }
-
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_SPN,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_SPN),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_TRANSPARENT,
-      callback:  callback,
-    });
-  },
-
-  /**
-   * Read the PLMNsel (Public Land Mobile Network) from the ICC.
-   *
-   * See ETSI TS 100.977 section 10.3.4 EF_PLMNsel
-   */
-  getPLMNSelector: function getPLMNSelector() {
-    function callback() {
-      if (DEBUG) debug("PLMN Selector: Process PLMN Selector");
-
-      let length = Buf.readUint32();
-      this.iccInfoPrivate.PLMN = this.readPLMNEntries(length/3);
-      Buf.readStringDelimiter(length);
-
-      if (DEBUG) debug("PLMN Selector: " + JSON.stringify(this.iccInfoPrivate.PLMN));
-
-      if (this.updateDisplayCondition()) {
-        this._handleICCInfoChange();
-      }
-    }
-
-    // PLMN List is Service 7 in SIM, EF_PLMNsel
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_PLMNsel,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_PLMNsel),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_TRANSPARENT,
-      callback:  callback,
-    });
-  },
-
-  /**
-   * Read the SPDI (Service Provider Display Information) from the ICC.
-   *
-   * See TS 131.102 section 4.2.66 for USIM and TS 51.011 section 10.3.50
-   * for SIM.
-   */
-  getSPDI: function getSPDI() {
-    function callback() {
-      let length = Buf.readUint32();
-      let readLen = 0;
-      let endLoop = false;
-      this.iccInfoPrivate.SPDI = null;
-      while ((readLen < length / 2) && !endLoop) {
-        let tlvTag = GsmPDUHelper.readHexOctet();
-        let tlvLen = GsmPDUHelper.readHexOctet();
-        readLen += 2; // For tag and length fields.
-        switch (tlvTag) {
-        case SPDI_TAG_SPDI:
-          // The value part itself is a TLV.
-          continue;
-        case SPDI_TAG_PLMN_LIST:
-          // This PLMN list is what we want.
-          this.iccInfoPrivate.SPDI = this.readPLMNEntries(tlvLen / 3);
-          readLen += tlvLen;
-          endLoop = true;
-          break;
-        default:
-          // We don't care about its content if its tag is not SPDI nor
-          // PLMN_LIST.
-          endLoop = true;
-          break;
-        }
-      }
-
-      // Consume unread octets.
-      Buf.seekIncoming((length / 2 - readLen) * PDU_HEX_OCTET_SIZE);
-      Buf.readStringDelimiter(length);
-
-      if (DEBUG) debug("SPDI: " + JSON.stringify(this.iccInfoPrivate.SPDI));
-      if (this.updateDisplayCondition()) {
-        this._handleICCInfoChange();
-      }
-    }
-
-    // PLMN List is Service 51 in USIM, EF_SPDI
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_SPDI,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_SPDI),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_TRANSPARENT,
-      callback:  callback,
-    });
-  },
-
-  /**
-   * Get whether specificed (U)SIM service is available.
-   *
-   * @param geckoService
-   *        Service name like "ADN", "BDN", etc.
-   *
-   * @return true if the service is enabled, false otherwise.
-   */
-  isICCServiceAvailable: function isICCServiceAvailable(geckoService) {
-    let serviceTable = this.iccInfo.sst;
-    let index, bitmask;
-    if (this.appType == CARD_APPTYPE_SIM) {
-      /**
-       * Service id is valid in 1..N, and 2 bits are used to code each service.
-       *
-       * +----+--  --+----+----+
-       * | b8 | ...  | b2 | b1 |
-       * +----+--  --+----+----+
-       *
-       * b1 = 0, service not allocated.
-       *      1, service allocated.
-       * b2 = 0, service not activatd.
-       *      1, service allocated.
-       *
-       * @see 3GPP TS 51.011 10.3.7.
-       */
-      let simService = GECKO_ICC_SERVICES.sim[geckoService];
-      if (!simService) {
-        return false;
-      }
-      simService -= 1;
-      index = Math.floor(simService / 4);
-      bitmask = 2 << ((simService % 4) << 1);
-    } else {
-      /**
-       * Service id is valid in 1..N, and 1 bit is used to code each service.
-       *
-       * +----+--  --+----+----+
-       * | b8 | ...  | b2 | b1 |
-       * +----+--  --+----+----+
-       *
-       * b1 = 0, service not avaiable.
-       *      1, service available.
-       * b2 = 0, service not avaiable.
-       *      1, service available.
-       *
-       * @see 3GPP TS 31.102 4.2.8.
-       */
-      let usimService = GECKO_ICC_SERVICES.usim[geckoService];
-      if (!usimService) {
-        return false;
-      }
-      usimService -= 1;
-      index = Math.floor(usimService / 8);
-      bitmask = 1 << ((usimService % 8) << 0);
-    }
-
-    return (serviceTable &&
-           (index < serviceTable.length) &&
-           (serviceTable[index] & bitmask)) != 0;
-  },
-
-  /**
    * Choose network names using EF_OPL and EF_PNN
    * See 3GPP TS 31.102 sec. 4.2.58 and sec. 4.2.59 for USIM,
    *     3GPP TS 51.011 sec. 10.3.41 and sec. 10.3.42 for SIM.
    */
   updateNetworkName: function updateNetworkName() {
     let iccInfoPriv = this.iccInfoPrivate;
     let iccInfo = this.iccInfo;
 
@@ -1738,628 +1300,16 @@ let RIL = {
 
     if (pnnEntry) {
       return [pnnEntry.fullName, pnnEntry.shortName];
     }
     return null;
   },
 
   /**
-   * Read OPL (Operator PLMN List) from USIM.
-   *
-   * See 3GPP TS 31.102 Sec. 4.2.59 for USIM
-   *     3GPP TS 51.011 Sec. 10.3.42 for SIM.
-   */
-  getOPL: function getOPL() {
-    let opl = [];
-    function callback(options) {
-      let len = Buf.readUint32();
-      // The first 7 bytes are LAI (for UMTS) and the format of LAI is defined
-      // in 3GPP TS 23.003, Sec 4.1
-      //    +-------------+---------+
-      //    | Octet 1 - 3 | MCC/MNC |
-      //    +-------------+---------+
-      //    | Octet 4 - 7 |   LAC   |
-      //    +-------------+---------+
-      let mccMnc = [GsmPDUHelper.readHexOctet(),
-                    GsmPDUHelper.readHexOctet(),
-                    GsmPDUHelper.readHexOctet()];
-      if (mccMnc[0] != 0xFF || mccMnc[1] != 0xFF || mccMnc[2] != 0xFF) {
-        let oplElement = {};
-        let semiOctets = [];
-        for (let i = 0; i < mccMnc.length; i++) {
-          semiOctets.push((mccMnc[i] & 0xf0) >> 4);
-          semiOctets.push(mccMnc[i] & 0x0f);
-        }
-        let reformat = [semiOctets[1], semiOctets[0], semiOctets[3],
-                        semiOctets[5], semiOctets[4], semiOctets[2]];
-        let buf = "";
-        for (let i = 0; i < reformat.length; i++) {
-          if (reformat[i] != 0xF) {
-            buf += GsmPDUHelper.semiOctetToBcdChar(reformat[i]);
-          }
-          if (i === 2) {
-            // 0-2: MCC
-            oplElement.mcc = parseInt(buf);
-            buf = "";
-          } else if (i === 5) {
-            // 3-5: MNC
-            oplElement.mnc = parseInt(buf);
-          }
-        }
-        // LAC/TAC
-        oplElement.lacTacStart =
-          (GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
-        oplElement.lacTacEnd =
-          (GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
-        // PLMN Network Name Record Identifier
-        oplElement.pnnRecordId = GsmPDUHelper.readHexOctet();
-        if (DEBUG) {
-          debug("OPL: [" + (opl.length + 1) + "]: " + JSON.stringify(oplElement));
-        }
-        opl.push(oplElement);
-      }
-      Buf.readStringDelimiter(len);
-      if (options.p1 < options.totalRecords) {
-        options.p1++;
-        this.iccIO(options);
-      } else {
-        this.iccInfoPrivate.OPL = opl;
-      }
-    }
-
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_OPL,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_OPL),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_LINEAR_FIXED,
-      callback:  callback,
-    });
-  },
-
-  /**
-   * Read PNN (PLMN Network Name) from USIM.
-   *
-   * See 3GPP TS 31.102 Sec. 4.2.58 for USIM
-   *     3GPP TS 51.011 Sec. 10.3.41 for SIM.
-   */
-  getPNN: function getPNN() {
-    let pnn = [];
-    function callback(options) {
-      let pnnElement = this.iccInfoPrivate.PNN = {};
-      let len = Buf.readUint32();
-      let readLen = 0;
-      while (len > readLen) {
-        let tlvTag = GsmPDUHelper.readHexOctet();
-        readLen = readLen + 2; // 1 Hex octet
-        if (tlvTag == 0xFF) {
-          // Unused byte
-          continue;
-        }
-        let tlvLen = GsmPDUHelper.readHexOctet();
-        let name;
-        switch (tlvTag) {
-        case PNN_IEI_FULL_NETWORK_NAME:
-          pnnElement.fullName = GsmPDUHelper.readNetworkName(tlvLen);
-          break;
-        case PNN_IEI_SHORT_NETWORK_NAME:
-          pnnElement.shortName = GsmPDUHelper.readNetworkName(tlvLen);
-          break;
-        default:
-          Buf.seekIncoming(PDU_HEX_OCTET_SIZE * tlvLen);
-        }
-        readLen += (tlvLen * 2 + 2);
-      }
-      if (DEBUG) {
-        debug("PNN: [" + (pnn.length + 1) + "]: " + JSON.stringify(pnnElement));
-      }
-      Buf.readStringDelimiter(len);
-      pnn.push(pnnElement);
-
-      if (options.p1 < options.totalRecords) {
-        options.p1++;
-        this.iccIO(options);
-      } else {
-        this.iccInfoPrivate.PNN = pnn;
-      }
-    }
-
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_PNN,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_PNN),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_LINEAR_FIXED,
-      callback:  callback,
-    });
-  },
-
-  /**
-   * Read the (U)SIM Service Table from the ICC.
-   */
-  getSST: function getSST() {
-    function callback() {
-      let length = Buf.readUint32();
-      // Each octet is encoded into two chars.
-      let len = length / 2;
-      this.iccInfo.sst = GsmPDUHelper.readHexOctetArray(len);
-      Buf.readStringDelimiter(length);
-
-      if (DEBUG) {
-        let str = "";
-        for (let i = 0; i < this.iccInfo.sst.length; i++) {
-          str += this.iccInfo.sst[i] + ", ";
-        }
-        debug("SST: " + str);
-      }
-
-      // Fetch SPN and PLMN list, if some of them are available.
-      if (this.isICCServiceAvailable("SPN")) {
-        if (DEBUG) debug("SPN: SPN is available");
-        this.getSPN();
-      } else {
-        if (DEBUG) debug("SPN: SPN service is not available");
-      }
-
-      if (this.isICCServiceAvailable("SPDI")) {
-        if (DEBUG) debug("SPDI: SPDI available.");
-        this.getSPDI();
-      } else {
-        if (DEBUG) debug("SPDI: SPDI service is not available");
-      }
-
-      if (this.isICCServiceAvailable("PNN")) {
-        if (DEBUG) debug("PNN: PNN is available");
-        this.getPNN();
-      } else {
-        if (DEBUG) debug("PNN: PNN is not available");
-      }
-
-      if (this.isICCServiceAvailable("OPL")) {
-        if (DEBUG) debug("OPL: OPL is available");
-        this.getOPL();
-      } else {
-        if (DEBUG) debug("OPL: OPL is not available");
-      }
-
-      if (this.isICCServiceAvailable("CBMI")) {
-        this.getCBMI();
-      } else {
-        this.cellBroadcastConfigs.CBMI = null;
-      }
-      if (this.isICCServiceAvailable("CBMIR")) {
-        this.getCBMIR();
-      } else {
-        this.cellBroadcastConfigs.CBMIR = null;
-      }
-      this._mergeAllCellBroadcastConfigs();
-    }
-
-    // ICC_EF_UST has the same value with ICC_EF_SST.
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_SST,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_SST),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_TRANSPARENT,
-      callback:  callback,
-    });
-  },
-
-  /**
-   * Read EFcbmi (Cell Broadcast Message Identifier selection)
-   *
-   * @see 3GPP TS 31.102 v110.02.0 section 4.2.14 EFcbmi
-   */
-  getCBMI: function getCBMI() {
-    function callback() {
-      let strLength = Buf.readUint32();
-
-      // Each Message Identifier takes two octets and each octet is encoded
-      // into two chars.
-      let numIds = strLength / 4, list = null;
-      if (numIds) {
-        list = [];
-        for (let i = 0, id; i < numIds; i++) {
-          id = GsmPDUHelper.readHexOctet() << 8 | GsmPDUHelper.readHexOctet();
-          // `Unused entries shall be set to 'FF FF'.`
-          if (id != 0xFFFF) {
-            list.push(id);
-            list.push(id + 1);
-          }
-        }
-      }
-      if (DEBUG) {
-        debug("CBMI: " + JSON.stringify(list));
-      }
-
-      Buf.readStringDelimiter(strLength);
-
-      this.cellBroadcastConfigs.CBMI = list;
-      this._mergeAllCellBroadcastConfigs();
-    }
-
-    function onerror() {
-      this.cellBroadcastConfigs.CBMI = null;
-      this._mergeAllCellBroadcastConfigs();
-    }
-
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_CBMI,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_CBMI),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_TRANSPARENT,
-      callback:  callback,
-      onerror:   onerror
-    });
-  },
-
-  /**
-   * Read EFcbmir (Cell Broadcast Message Identifier Range selection)
-   *
-   * @see 3GPP TS 31.102 v110.02.0 section 4.2.22 EFcbmir
-   */
-  getCBMIR: function getCBMIR() {
-    function callback() {
-      let strLength = Buf.readUint32();
-
-      // Each Message Identifier range takes four octets and each octet is
-      // encoded into two chars.
-      let numIds = strLength / 8, list = null;
-      if (numIds) {
-        list = [];
-        for (let i = 0, from, to; i < numIds; i++) {
-          // `Bytes one and two of each range identifier equal the lower value
-          // of a cell broadcast range, bytes three and four equal the upper
-          // value of a cell broadcast range.`
-          from = GsmPDUHelper.readHexOctet() << 8 | GsmPDUHelper.readHexOctet();
-          to = GsmPDUHelper.readHexOctet() << 8 | GsmPDUHelper.readHexOctet();
-          // `Unused entries shall be set to 'FF FF'.`
-          if ((from != 0xFFFF) && (to != 0xFFFF)) {
-            list.push(from);
-            list.push(to + 1);
-          }
-        }
-      }
-      if (DEBUG) {
-        debug("CBMIR: " + JSON.stringify(list));
-      }
-
-      Buf.readStringDelimiter(strLength);
-
-      this.cellBroadcastConfigs.CBMIR = list;
-      this._mergeAllCellBroadcastConfigs();
-    }
-
-    function onerror() {
-      this.cellBroadcastConfigs.CBMIR = null;
-      this._mergeAllCellBroadcastConfigs();
-    }
-
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_CBMIR,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_CBMIR),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_TRANSPARENT,
-      callback:  callback,
-      onerror:   onerror
-    });
-  },
-
-  /**
-   *  Helper to parse Dialling number from TS 131.102
-   *
-   *  @param options
-   *         The 'options' object passed from RIL.iccIO
-   *  @param addCallback
-   *         The function should be invoked when the ICC record is processed 
-   *         succesfully.
-   *  @param finishCallback
-   *         The function should be invoked when the final ICC record is 
-   *         processed.
-   *
-   */
-  parseDiallingNumber: function parseDiallingNumber(options,
-                                                    addCallback,
-                                                    finishCallback) {
-    let ffLen; // The length of trailing 0xff to be read.
-    let length = Buf.readUint32();
-
-    let alphaLen = options.recordSize - MSISDN_FOOTER_SIZE_BYTES;
-    let alphaId = GsmPDUHelper.readAlphaIdentifier(alphaLen);
-
-    let numLen = GsmPDUHelper.readHexOctet();
-    if (numLen != 0xff) {
-      if (numLen > MSISDN_MAX_NUMBER_SIZE_BYTES) {
-        debug("invalid length of BCD number/SSC contents - " + numLen);
-        return;
-      }
-
-      if (addCallback) {
-        addCallback.call(this, {alphaId: alphaId,
-                                number: GsmPDUHelper.readDiallingNumber(numLen)});
-      }
-
-      ffLen = length / 2 - alphaLen - numLen - 1; // Minus 1 for the numLen field.
-    } else {
-      ffLen = MSISDN_FOOTER_SIZE_BYTES - 1; // Minus 1 for the numLen field.
-    }
-
-    // Consumes the remaining 0xff
-    for (let i = 0; i < ffLen; i++) {
-      GsmPDUHelper.readHexOctet();
-    }
-    
-    Buf.readStringDelimiter(length);
-    
-    if (options.loadAll &&
-        options.p1 < options.totalRecords) {
-      options.p1++;
-      this.iccIO(options);
-    } else {
-      if (finishCallback) {
-        finishCallback.call(this);
-      }
-    }
-  },
-  
-  /**
-   *  Get ICC FDN.
-   *
-   *  @paran requestId
-   *         Request id from RadioInterfaceLayer.
-   */
-  getFDN: function getFDN(options) {
-    function callback(options) {
-      function add(contact) {
-        this.iccInfo.fdn.push(contact);
-      };
-      function finish() {
-        if (DEBUG) {
-          for (let i = 0; i < this.iccInfo.fdn.length; i++) {
-            debug("FDN[" + i + "] alphaId = " + this.iccInfo.fdn[i].alphaId +
-                                " number = " + this.iccInfo.fdn[i].number);
-          }
-        }
-        delete options.callback;
-        delete options.onerror;
-        options.rilMessageType = "icccontacts";
-        options.contacts = this.iccInfo.fdn;
-        this.sendDOMMessage(options);
-      };
-      this.parseDiallingNumber(options, add, finish);
-    }
-
-    this.iccInfo.fdn = [];
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_FDN,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_FDN),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_LINEAR_FIXED,
-      callback:  callback,
-      loadAll:   true,
-      requestId: options.requestId
-    });
-  },
-
-  /**
-   *  Get ICC ADN.
-   *
-   *  @param fileId
-   *         EF id of the ADN.
-   *  @paran requestId
-   *         Request id from RadioInterfaceLayer.
-   */
-  getADN: function getADN(options) {
-    function callback(options) {
-      function add(contact) {
-        this.iccInfo.adn.push(contact);
-      };
-
-      function finish() {
-        if (DEBUG) {
-          for (let i = 0; i < this.iccInfo.adn.length; i++) {
-            debug("ADN[" + i + "] alphaId = " + this.iccInfo.adn[i].alphaId +
-                                " number  = " + this.iccInfo.adn[i].number);
-          }
-        }
-        // To prevent DataCloneError when sending parcels,
-        // We need to delete those properties which are not
-        // 'Structured Clone Data',
-        // in this case, those callback functions.
-        delete options.callback;
-        delete options.onerror;
-        options.rilMessageType = "icccontacts";
-        options.contacts = this.iccInfo.adn;
-        this.sendDOMMessage(options);
-      };
-      this.parseDiallingNumber(options, add, finish);
-    }
-
-    function error(options) {
-      delete options.callback;
-      delete options.onerror;
-      options.rilMessageType = "icccontacts";
-      options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
-      this.sendDOMMessage(options);
-    }
-
-    this.iccInfo.adn = [];
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    options.fileId,
-      pathId:    this._getPathIdForICCRecord(options.fileId),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_LINEAR_FIXED,
-      callback:  callback,
-      onerror:   error,
-      loadAll:   true,
-      requestId: options.requestId,
-    });
-  },
-
-   /**
-   * Get ICC MBDN. (Mailbox Dialling Number)
-   *
-   * @see TS 131.102, clause 4.2.60
-   */
-  getMBDN: function getMBDN() {
-    function callback(options) {
-      let parseCallback = function parseCallback(contact) {
-        if (DEBUG) {
-          debug("MBDN, alphaId="+contact.alphaId+" number="+contact.number);
-        }
-        if (this.iccInfo.mbdn != contact.number) {
-          this.iccInfo.mbdn = contact.number;
-          contact.rilMessageType = "iccmbdn";
-          this.sendDOMMessage(contact);
-        }
-      };
-
-      this.parseDiallingNumber(options, parseCallback);
-    }
-
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_MBDN,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_MBDN),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_LINEAR_FIXED,
-      callback:  callback,
-    });
-  },
-
-  decodeSimTlvs: function decodeSimTlvs(tlvsLen) {
-    let index = 0;
-    let tlvs = [];
-    while (index < tlvsLen) {
-      let simTlv = {
-        tag : GsmPDUHelper.readHexOctet(),
-        length : GsmPDUHelper.readHexOctet(),
-      };
-      simTlv.value = GsmPDUHelper.readHexOctetArray(simTlv.length)
-      tlvs.push(simTlv);
-      index += simTlv.length + 2 /* The length of 'tag' and 'length' field */;
-    }
-    return tlvs;
-  },
-
-  _searchForIccUsimTag: function _searchForIccUsimTag(tlvs, tag) {
-    for (let i = 0; i < tlvs.length; i++) {
-      if (tlvs[i].tag == tag) {
-        return tlvs[i];
-      }
-    }
-    return null;
-  },
-
-  /**
-   *  Read the list of PLMN (Public Land Mobile Network) entries
-   *  We cannot directly rely on readSwappedNibbleBcdToString(),
-   *  since it will no correctly handle some corner-cases that are
-   *  not a problem in our case (0xFF 0xFF 0xFF).
-   *
-   *  @param length The number of PLMN records.
-   *  @return An array of string corresponding to the PLMNs.
-   */
-  readPLMNEntries: function readPLMNEntries(length) {
-    let plmnList = [];
-    // each PLMN entry has 3 byte
-    debug("readPLMNEntries: PLMN entries length = " + length);
-    let index = 0;
-    while (index < length) {
-      // Unused entries will be 0xFFFFFF, according to EF_SPDI
-      // specs (TS 131 102, section 4.2.66)
-      try {
-        let plmn = [GsmPDUHelper.readHexOctet(),
-                    GsmPDUHelper.readHexOctet(),
-                    GsmPDUHelper.readHexOctet()];
-        if (DEBUG) debug("readPLMNEntries: Reading PLMN entry: [" + index +
-                         "]: '" + plmn + "'");
-        if (plmn[0] != 0xFF &&
-            plmn[1] != 0xFF &&
-            plmn[2] != 0xFF) {
-          let semiOctets = [];
-          for (let idx = 0; idx < plmn.length; idx++) {
-            semiOctets.push((plmn[idx] & 0xF0) >> 4);
-            semiOctets.push(plmn[idx] & 0x0F);
-          }
-
-          // According to TS 24.301, 9.9.3.12, the semi octets is arranged
-          // in format:
-          // Byte 1: MCC[2] | MCC[1]
-          // Byte 2: MNC[3] | MCC[3]
-          // Byte 3: MNC[2] | MNC[1]
-          // Therefore, we need to rearrage them.
-          let reformat = [semiOctets[1], semiOctets[0], semiOctets[3],
-                          semiOctets[5], semiOctets[4], semiOctets[2]];
-          let buf = "";
-          let plmnEntry = {};
-          for (let i = 0; i < reformat.length; i++) {
-            if (reformat[i] != 0xF) {
-              buf += GsmPDUHelper.semiOctetToBcdChar(reformat[i]);
-            }
-            if (i === 2) {
-              // 0-2: MCC
-              plmnEntry.mcc = parseInt(buf);
-              buf = "";
-            } else if (i === 5) {
-              // 3-5: MNC
-              plmnEntry.mnc = parseInt(buf);
-            }
-          }
-          if (DEBUG) debug("readPLMNEntries: PLMN = " + plmnEntry.mcc + ", " + plmnEntry.mnc);
-          plmnList.push(plmnEntry);
-        }
-      } catch (e) {
-        if (DEBUG) debug("readPLMNEntries: PLMN entry " + index + " is invalid.");
-        break;
-      }
-      index ++;
-    }
-    return plmnList;
-  },
-
-  /**
    * Get UICC Phonebook.
    *
    * @params contactType
    *         "ADN" or "FDN".
    */
   getICCContacts: function getICCContacts(options) {
     if (!this.appType) {
       options.rilMessageType = "icccontacts";
@@ -2368,76 +1318,30 @@ let RIL = {
     }
 
     let type = options.contactType;
     switch (type) {
       case "ADN":
         switch (this.appType) {
           case CARD_APPTYPE_SIM:
             options.fileId = ICC_EF_ADN;
-            this.getADN(options);
+            ICCRecordHelper.getADN(options);
             break;
           case CARD_APPTYPE_USIM:
-            this.getPBR(options);
+            ICCRecordHelper.getPBR(options);
             break;
         }
         break;
       case "FDN":
-        this.getFDN(options);
+        ICCRecordHelper.getFDN(options);
         break;
     }
   },
 
   /**
-   * Get USIM Phonebook.
-   *
-   * @params requestId
-   *         Request id from RadioInterfaceLayer.
-   */
-  getPBR: function getPBR(options) {
-    function callback(options) {
-      let bufLen = Buf.readUint32();
-
-      let tag = GsmPDUHelper.readHexOctet();
-      let length = GsmPDUHelper.readHexOctet();
-      let value = this.decodeSimTlvs(length);
-
-      let adn = this._searchForIccUsimTag(value, ICC_USIM_EFADN_TAG);
-      let adnEfid = (adn.value[0] << 8) | adn.value[1];
-      this.getADN({fileId: adnEfid,
-                   requestId: options.requestId});
-
-      Buf.readStringDelimiter(bufLen);
-    }
-
-    function error(options) {
-      delete options.callback;
-      delete options.onerror;
-      options.rilMessageType = "icccontacts";
-      options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
-      this.sendDOMMessage(options);
-    }
-
-    this.iccIO({
-      command:   ICC_COMMAND_GET_RESPONSE,
-      fileId:    ICC_EF_PBR,
-      pathId:    this._getPathIdForICCRecord(ICC_EF_PBR),
-      p1:        0, // For GET_RESPONSE, p1 = 0
-      p2:        0, // For GET_RESPONSE, p2 = 0
-      p3:        GET_RESPONSE_EF_SIZE_BYTES,
-      data:      null,
-      pin2:      null,
-      type:      EF_TYPE_LINEAR_FIXED,
-      callback:  callback,
-      onerror:   error,
-      requestId: options.requestId,
-    });
-  },
-
-  /**
    * Request the phone's radio power to be switched on or off.
    *
    * @param on
    *        Boolean indicating the desired power state.
    */
   setRadioPower: function setRadioPower(options) {
     Buf.newParcel(REQUEST_RADIO_POWER);
     Buf.writeUint32(1);
@@ -3846,223 +2750,41 @@ let RIL = {
 
     // This was moved down from CARD_APPSTATE_READY
     this.requestNetworkInfo();
     this.getSignalStrength();
     if (newCardState == GECKO_CARDSTATE_READY) {
       // For type SIM, we need to check EF_phase first.
       // Other types of ICC we can send Terminal_Profile immediately.
       if (this.appType == CARD_APPTYPE_SIM) {
-        this.getICCPhase();
+        ICCRecordHelper.getICCPhase();
       } else {
         this.sendStkTerminalProfile(STK_SUPPORTED_TERMINAL_PROFILE);
       }
-      this.fetchICCRecords();
+      ICCRecordHelper.fetchICCRecords();
       this.reportStkServiceIsRunning();
     }
 
     this.cardState = newCardState;
     this.sendDOMMessage({rilMessageType: "cardstatechange",
                          cardState: this.cardState});
   },
 
-  /** 
-   * Helper function for getting the pathId for the specific ICC record
-   * depeding on which type of ICC card we are using.
-   * 
-   * @param fileId
-   *        File id.
-   * @return The pathId or null in case of an error or invalid input.
-   */
-  _getPathIdForICCRecord: function _getPathIdForICCRecord(fileId) {
-    let index = this.iccStatus.gsmUmtsSubscriptionAppIndex;
-    if (index == -1) {
-      return null;
-    }
-    let app = this.iccStatus.apps[index];
-    if (!app) {
-      return null;
-    }
-
-    // Here we handle only file ids that are common to RUIM, SIM, USIM
-    // and other types of ICC cards.
-    switch (fileId) {
-      case ICC_EF_ICCID:
-        return EF_PATH_MF_SIM;
-      case ICC_EF_ADN:
-        return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM;
-      case ICC_EF_PBR:
-        return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK;
-    }
-
-    switch (app.app_type) {
-      case CARD_APPTYPE_SIM:
-        switch (fileId) {
-          case ICC_EF_FDN:
-          case ICC_EF_MSISDN:
-            return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM;
-
-          case ICC_EF_AD:
-          case ICC_EF_MBDN:
-          case ICC_EF_PLMNsel:
-          case ICC_EF_SPN:
-          case ICC_EF_SPDI:
-          case ICC_EF_SST:
-          case ICC_EF_CBMI:
-          case ICC_EF_CBMIR:
-            return EF_PATH_MF_SIM + EF_PATH_DF_GSM;
-        }
-      case CARD_APPTYPE_USIM:
-        switch (fileId) {
-          case ICC_EF_AD:
-          case ICC_EF_FDN:
-          case ICC_EF_MBDN:
-          case ICC_EF_UST:
-          case ICC_EF_MSISDN:
-          case ICC_EF_SPN:
-          case ICC_EF_SPDI:
-          case ICC_EF_CBMI:
-          case ICC_EF_CBMIR:
-          case ICC_EF_OPL:
-          case ICC_EF_PNN:
-            return EF_PATH_MF_SIM + EF_PATH_ADF_USIM;
-
-          default:
-            // The file ids in USIM phone book entries are decided by the
-	    // card manufacturer. So if we don't match any of the cases
-	    // above and if its a USIM return the phone book path.
-            return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK;
-        }
-    }
-    return null;
-  },
-
    /**
    * Helper for processing responses of functions such as enterICC* and changeICC*.
    */
   _processEnterAndChangeICCResponses: function _processEnterAndChangeICCResponses(length, options) {
     options.success = options.rilRequestError == 0;
     if (!options.success) {
       options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
     }
     options.retryCount = length ? Buf.readUint32List()[0] : -1;
     this.sendDOMMessage(options);
   },
 
-  /**
-   * Process a ICC_COMMAND_GET_RESPONSE type command for REQUEST_SIM_IO.
-   */
-  _processICCIOGetResponse: function _processICCIOGetResponse(options) {
-    let length = Buf.readUint32();
-
-    // The format is from TS 51.011, clause 9.2.1
-
-    // Skip RFU, data[0] data[1]
-    Buf.seekIncoming(2 * PDU_HEX_OCTET_SIZE);
-
-    // File size, data[2], data[3]
-    let fileSize = (GsmPDUHelper.readHexOctet() << 8) |
-                    GsmPDUHelper.readHexOctet();
-
-    // 2 bytes File id. data[4], data[5]
-    let fileId = (GsmPDUHelper.readHexOctet() << 8) |
-                  GsmPDUHelper.readHexOctet();
-    if (fileId != options.fileId) {
-      if (DEBUG) {
-        debug("Expected file ID " + options.fileId + " but read " + fileId);
-      }
-      return;
-    }
-
-    // Type of file, data[6]
-    let fileType = GsmPDUHelper.readHexOctet();
-    if (fileType != TYPE_EF) {
-      if (DEBUG) {
-        debug("Unexpected file type " + fileType);
-      }
-      return;
-    }
-
-    // Skip 1 byte RFU, data[7],
-    //      3 bytes Access conditions, data[8] data[9] data[10],
-    //      1 byte File status, data[11],
-    //      1 byte Length of the following data, data[12].
-    Buf.seekIncoming(((RESPONSE_DATA_STRUCTURE - RESPONSE_DATA_FILE_TYPE - 1) *
-        PDU_HEX_OCTET_SIZE));
-
-    // Read Structure of EF, data[13]
-    let efType = GsmPDUHelper.readHexOctet();
-    if (efType != options.type) {
-      if (DEBUG) {
-        debug("Expected EF type " + options.type + " but read " + efType);
-      }
-      return;
-    }
-
-    // Length of a record, data[14]
-    options.recordSize = GsmPDUHelper.readHexOctet();
-    options.totalRecords = fileSize / options.recordSize;
-
-    Buf.readStringDelimiter(length);
-
-    switch (options.type) {
-      case EF_TYPE_LINEAR_FIXED:
-        // Reuse the options object and update some properties.
-        options.command = ICC_COMMAND_READ_RECORD;
-        options.p1 = 1; // Record number, always use the 1st record
-        options.p2 = READ_RECORD_ABSOLUTE_MODE;
-        options.p3 = options.recordSize;
-        this.iccIO(options);
-        break;
-      case EF_TYPE_TRANSPARENT:
-        // Reuse the options object and update some properties.
-        options.command = ICC_COMMAND_READ_BINARY;
-        options.p3 = fileSize;
-        this.iccIO(options);
-        break;
-    }
-  },
-
-  /**
-   * Process a ICC_COMMAND_READ_RECORD type command for REQUEST_SIM_IO.
-   */
-  _processICCIOReadRecord: function _processICCIOReadRecord(options) {
-    if (options.callback) {
-      options.callback.call(this, options);
-    }
-  },
-
-  /**
-   * Process a ICC_COMMAND_READ_BINARY type command for REQUEST_SIM_IO.
-   */
-  _processICCIOReadBinary: function _processICCIOReadBinary(options) {
-    if (options.callback) {
-      options.callback.call(this);
-    }
-  },
-
-  /**
-   * Process ICC I/O response.
-   */
-  _processICCIO: function _processICCIO(options) {
-    switch (options.command) {
-      case ICC_COMMAND_GET_RESPONSE:
-        this._processICCIOGetResponse(options);
-        break;
-
-      case ICC_COMMAND_READ_RECORD:
-        this._processICCIOReadRecord(options);
-        break;
-
-      case ICC_COMMAND_READ_BINARY:
-        this._processICCIOReadBinary(options);
-        break;
-    } 
-  },
-
   // We combine all of the NETWORK_INFO_MESSAGE_TYPES into one "networkinfochange"
   // message to the RadioInterfaceLayer, so we can avoid sending multiple
   // VoiceInfoChanged events for both operator / voice_data_registration
   //
   // State management here is a little tricky. We need to know both:
   // 1. Whether or not a response was received for each of the
   //    NETWORK_INFO_MESSAGE_TYPES
   // 2. The outbound message that corresponds with that response -- but this
@@ -4269,18 +2991,18 @@ let RIL = {
 
       if (networkTuple) {
         try {
           this._processNetworkTuple(networkTuple, this.operator);
         } catch (e) {
           debug("Error processing operator tuple: " + e);
         }
       }
-      if (this.updateDisplayCondition()) {
-        this._handleICCInfoChange();
+      if (ICCUtilsHelper.updateDisplayCondition()) {
+        ICCUtilsHelper.handleICCInfoChange();
       }
       this._sendNetworkInfoMessage(NETWORK_INFO_OPERATOR, this.operator);
     }
   },
 
   /**
    * Helpers for processing call state and handle the active call.
    */
@@ -4756,17 +3478,17 @@ let RIL = {
       // 9.2.3.9
       return PDU_FCS_OK;
     }
 
     if (message.messageClass == GECKO_SMS_MESSAGE_CLASSES[PDU_DCS_MSG_CLASS_2]) {
       switch (message.epid) {
         case PDU_PID_ANSI_136_R_DATA:
         case PDU_PID_USIM_DATA_DOWNLOAD:
-          if (this.isICCServiceAvailable("DATA_DOWNLOAD_SMS_PP")) {
+          if (ICCUtilsHelper.isICCServiceAvailable("DATA_DOWNLOAD_SMS_PP")) {
             // `If the service "data download via SMS Point-to-Point" is
             // allocated and activated in the (U)SIM Service Table, ... then the
             // ME shall pass the message transparently to the UICC using the
             // ENVELOPE (SMS-PP DOWNLOAD).` ~ 3GPP TS 31.111 7.1.1.1
             this.dataDownloadViaSMSPP(message);
 
             // `the ME shall not display the message, or alert the user of a
             // short message waiting.` ~ 3GPP TS 31.111 7.1.1.1
@@ -5736,39 +4458,42 @@ RIL[REQUEST_SETUP_DATA_CALL] = function 
   }
   // Pass `options` along. That way we retain the APN and other info about
   // how the data call was set up.
   this[REQUEST_DATA_CALL_LIST](length, options);
 };
 RIL[REQUEST_SIM_IO] = function REQUEST_SIM_IO(length, options) {
   if (!length) {
     if (options.onerror) {
-      options.onerror.call(this, options);
+      options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
+      options.onerror(options);
     }
     return;
   }
 
   // Don't need to read rilRequestError since we can know error status from
   // sw1 and sw2.
-  let sw1 = Buf.readUint32();
-  let sw2 = Buf.readUint32();
-  if (sw1 != ICC_STATUS_NORMAL_ENDING) {
+  options.sw1 = Buf.readUint32();
+  options.sw2 = Buf.readUint32();
+  if (options.sw1 != ICC_STATUS_NORMAL_ENDING) {
     // See GSM11.11, TS 51.011 clause 9.4, and ISO 7816-4 for the error
     // description.
+    let msg = "ICC I/O Error EF id = " + options.fileId.toString(16) +
+              " command = " + options.command.toString(16) +
+              "(" + options.sw1.toString(16) + "/" + options.sw2.toString(16) + ")"
     if (DEBUG) {
-      debug("ICC I/O Error EF id = " + options.fileId.toString(16) +
-            " command = " + options.command.toString(16) +
-            "(" + sw1.toString(16) + "/" + sw2.toString(16) + ")");
+      debug(msg);
     }
     if (options.onerror) {
-      options.onerror.call(this, options);
+      options.errorMsg = msg;
+      options.onerror(options);
     }
     return;
   }
-  this._processICCIO(options);
+  ICCIOHelper.processICCIO(options);
 };
 RIL[REQUEST_SEND_USSD] = function REQUEST_SEND_USSD(length, options) {
   if (DEBUG) {
     debug("REQUEST_SEND_USSD " + JSON.stringify(options));
   }
   options.success = this._ussdSession = options.rilRequestError == 0;
   options.errorMsg = RIL_ERROR_TO_GECKO_ERROR[options.rilRequestError];
   this.sendDOMMessage(options);
@@ -7169,16 +5894,52 @@ let GsmPDUHelper = {
     if ((toa & 0xF0) == (PDU_TOA_INTERNATIONAL)) {
       addr = '+' + addr;
     }
 
     return addr;
   },
 
   /**
+   *  Read Alpha Id and Dialling number from TS 131.102
+   *
+   *  @param options
+   *         The 'options' object passed from RIL.iccIO
+   */
+  readAlphaIdDiallingNumber: function readAlphaIdDiallingNumber(options) {
+    let contact = null;
+    let ffLen; // The length of trailing 0xff to be read.
+    let length = Buf.readUint32();
+
+    let alphaLen = options.recordSize - MSISDN_FOOTER_SIZE_BYTES;
+    let alphaId = this.readAlphaIdentifier(alphaLen);
+
+    let numLen = this.readHexOctet();
+    if (numLen != 0xff) {
+      // +1 for TON/NPI
+      if (numLen > MSISDN_MAX_NUMBER_SIZE_BYTES + 1) {
+        throw new Error("invalid length of BCD number/SSC contents - " + numLen);
+      }
+
+      contact = {alphaId: alphaId,
+                 number: this.readDiallingNumber(numLen)};
+
+      ffLen = length / 2 - alphaLen - numLen - 1; // Minus 1 for the numLen field.
+    } else {
+      ffLen = MSISDN_FOOTER_SIZE_BYTES - 1; // Minus 1 for the numLen field.
+    }
+
+    // Consumes the remaining 0xff
+    Buf.seekIncoming(ffLen * PDU_HEX_OCTET_SIZE);
+    Buf.readStringDelimiter(length);
+
+    return contact;
+  },
+
+  /**
    * Read Alpha Identifier.
    *
    * @see TS 131.102
    *
    * @param numOctets
    *        Number of octets to be read.
    *
    * It uses either
@@ -8275,17 +7036,17 @@ let StkCommandParamsFactory = {
       case STK_REFRESH_NAA_INIT_AND_FILE_CHANGE:
         let ctlv = StkProactiveCmdHelper.searchForTag(
           COMPREHENSIONTLV_TAG_FILE_LIST, ctlvs);
         if (ctlv) {
           let list = ctlv.value.fileList;
           if (DEBUG) {
             debug("Refresh, list = " + list);
           }
-          RIL.fetchICCRecords();
+          ICCRecordHelper.fetchICCRecords();
         }
         break;
     }
     return null;
   },
 
   /**
    * Construct a param for Poll Interval.
@@ -9342,16 +8103,1176 @@ let BerTlvHelper = {
       length: length,
       value: ctlvs
     };
     return berTlv;
   }
 };
 
 /**
+ * ICC Helper for getting EF path.
+ */
+let ICCFileHelper = {
+  /**
+   * This function handles only EFs that are common to RUIM, SIM, USIM
+   * and other types of ICC cards.
+   */
+  getCommonEFPath: function getCommonEFPath(fileId) {
+    switch (fileId) {
+      case ICC_EF_ICCID:
+        return EF_PATH_MF_SIM;
+      case ICC_EF_ADN:
+        return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM;
+      case ICC_EF_PBR:
+        return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK;
+    }
+    return null;
+  },
+
+  /**
+   * This function handles EFs for SIM.
+   */
+  getSimEFPath: function getSimEFPath(fileId) {
+    switch (fileId) {
+      case ICC_EF_FDN:
+      case ICC_EF_MSISDN:
+        return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM;
+      case ICC_EF_AD:
+      case ICC_EF_MBDN:
+      case ICC_EF_PLMNsel:
+      case ICC_EF_SPN:
+      case ICC_EF_SPDI:
+      case ICC_EF_SST:
+      case ICC_EF_PHASE:
+      case ICC_EF_CBMI:
+      case ICC_EF_CBMIR:
+      case ICC_EF_OPL:
+      case ICC_EF_PNN:
+        return EF_PATH_MF_SIM + EF_PATH_DF_GSM;
+      default:
+        return null
+    }
+  },
+
+  /**
+   * This function handles EFs for USIM.
+   */
+  getUSimEFPath: function getUSimEFPath(fileId) {
+    switch (fileId) {
+      case ICC_EF_AD:
+      case ICC_EF_FDN:
+      case ICC_EF_MBDN:
+      case ICC_EF_UST:
+      case ICC_EF_MSISDN:
+      case ICC_EF_SPN:
+      case ICC_EF_SPDI:
+      case ICC_EF_CBMI:
+      case ICC_EF_CBMIR:
+      case ICC_EF_OPL:
+      case ICC_EF_PNN:
+        return EF_PATH_MF_SIM + EF_PATH_ADF_USIM;
+      default:
+        // The file ids in USIM phone book entries are decided by the
+        // card manufacturer. So if we don't match any of the cases
+        // above and if its a USIM return the phone book path.
+        return EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK;
+    }
+  },
+
+  /**
+   * Helper function for getting the pathId for the specific ICC record
+   * depeding on which type of ICC card we are using.
+   *
+   * @param fileId
+   *        File id.
+   * @return The pathId or null in case of an error or invalid input.
+   */
+  getEFPath: function getEFPath(fileId) {
+    // TODO: Bug 726098, change to use cdmaSubscriptionAppIndex when in CDMA.
+    let index = RIL.iccStatus.gsmUmtsSubscriptionAppIndex;
+    if (index == -1) {
+      return null;
+    }
+    let app = RIL.iccStatus.apps[index];
+    if (!app) {
+      return null;
+    }
+
+    let path = this.getCommonEFPath(fileId);
+    if (path) {
+      return path;
+    }
+
+    switch (app.app_type) {
+      case CARD_APPTYPE_SIM:
+        return this.getSimEFPath(fileId);
+      case CARD_APPTYPE_USIM:
+        return this.getUSimEFPath(fileId);
+      default:
+        return null;
+    }
+  },
+};
+
+/**
+ * Helper for ICC IO functionalities.
+ */
+let ICCIOHelper = {
+  /**
+   * Load EF with type 'Linear Fixed'.
+   *
+   * @param fileId
+   *        The file to operate on, one of the ICC_EF_* constants.
+   * @param recordNumber [optional]
+   *        The number of the record shall be loaded.
+   * @param callback [optional]
+   *        The callback function shall be called when the record(s) is read.
+   * @param this [optional]
+   *        The 'this' object when the callback is called.
+   * @param onerror [optional]
+   *        The callback function shall be called when failure.
+   */
+  loadLinearFixedEF: function loadLinearFixedEF(options) {
+    options.type = EF_TYPE_LINEAR_FIXED;
+    let cb = options.callback;
+    options.callback = function callback(options) {
+      options.callback = cb;
+      options.command = ICC_COMMAND_READ_RECORD;
+      options.p1 = options.recordNumber || 1; // Record number
+      options.p2 = READ_RECORD_ABSOLUTE_MODE;
+      options.p3 = options.recordSize;
+      RIL.iccIO(options);
+    }.bind(this);
+    this.getResponse(options);
+  },
+
+  /**
+   * Load next record from current record Id.
+   */
+  loadNextRecord: function loadNextRecord(options) {
+    options.p1++;
+    RIL.iccIO(options);
+  },
+
+  /**
+   * Load EF with type 'Transparent'.
+   *
+   * @param fileId
+   *        The file to operate on, one of the ICC_EF_* constants.
+   * @param callback [optional]
+   *        The callback function shall be called when the record(s) is read.
+   * @param onerror [optional]
+   *        The callback function shall be called when failure.
+   */
+  loadTransparentEF: function loadTransparentEF(options) {
+    options.type = EF_TYPE_TRANSPARENT;
+    let cb = options.callback;
+    options.callback = function callback(options) {
+      options.callback = cb;
+      options.command = ICC_COMMAND_READ_BINARY;
+      options.p3 = options.fileSize;
+      RIL.iccIO(options);
+    }.bind(this);
+    this.getResponse(options);
+  },
+
+  /**
+   * Use ICC_COMMAND_GET_RESPONSE to query the EF.
+   *
+   * @param fileId
+   *        The file to operate on, one of the ICC_EF_* constants.
+   */
+  getResponse: function getResponse(options) {
+    options.command = ICC_COMMAND_GET_RESPONSE;
+    options.pathId = ICCFileHelper.getEFPath(options.fileId);
+    if (!options.pathId) {
+      throw new Error("Unknown pathId for " + options.fileId.toString(16));
+    }
+    options.p1 = 0; // For GET_RESPONSE, p1 = 0
+    options.p2 = 0; // For GET_RESPONSE, p2 = 0
+    options.p3 = GET_RESPONSE_EF_SIZE_BYTES;
+    RIL.iccIO(options);
+  },
+
+  /**
+   * Process ICC I/O response.
+   */
+  processICCIO: function processICCIO(options) {
+    let func = this[options.command];
+    func.call(this, options);
+  },
+
+  /**
+   * Process a ICC_COMMAND_GET_RESPONSE type command for REQUEST_SIM_IO.
+   */
+  processICCIOGetResponse: function processICCIOGetResponse(options) {
+    let length = Buf.readUint32();
+
+    // The format is from TS 51.011, clause 9.2.1
+
+    // Skip RFU, data[0] data[1]
+    Buf.seekIncoming(2 * PDU_HEX_OCTET_SIZE);
+
+    // File size, data[2], data[3]
+    options.fileSize = (GsmPDUHelper.readHexOctet() << 8) |
+                        GsmPDUHelper.readHexOctet();
+
+    // 2 bytes File id. data[4], data[5]
+    let fileId = (GsmPDUHelper.readHexOctet() << 8) |
+                  GsmPDUHelper.readHexOctet();
+    if (fileId != options.fileId) {
+      throw new Error("Expected file ID " + options.fileId.toString(16) +
+                      " but read " + fileId.toString(16));
+    }
+
+    // Type of file, data[6]
+    let fileType = GsmPDUHelper.readHexOctet();
+    if (fileType != TYPE_EF) {
+      throw new Error("Unexpected file type " + fileType);
+    }
+
+    // Skip 1 byte RFU, data[7],
+    //      3 bytes Access conditions, data[8] data[9] data[10],
+    //      1 byte File status, data[11],
+    //      1 byte Length of the following data, data[12].
+    Buf.seekIncoming(((RESPONSE_DATA_STRUCTURE - RESPONSE_DATA_FILE_TYPE - 1) *
+        PDU_HEX_OCTET_SIZE));
+
+    // Read Structure of EF, data[13]
+    let efType = GsmPDUHelper.readHexOctet();
+    if (efType != options.type) {
+      throw new Error("Expected EF type " + options.type + " but read " + efType);
+    }
+
+    // Length of a record, data[14]
+    options.recordSize = GsmPDUHelper.readHexOctet();
+    options.totalRecords = options.fileSize / options.recordSize;
+
+    Buf.readStringDelimiter(length);
+
+    if (options.callback) {
+      options.callback(options);
+    }
+  },
+
+  /**
+   * Process a ICC_COMMAND_READ_RECORD type command for REQUEST_SIM_IO.
+   */
+  processICCIOReadRecord: function processICCIOReadRecord(options) {
+    if (options.callback) {
+      options.callback(options);
+    }
+  },
+
+  /**
+   * Process a ICC_COMMAND_READ_BINARY type command for REQUEST_SIM_IO.
+   */
+  processICCIOReadBinary: function processICCIOReadBinary(options) {
+    if (options.callback) {
+      options.callback(options);
+    }
+  },
+};
+ICCIOHelper[ICC_COMMAND_SEEK] = null;
+ICCIOHelper[ICC_COMMAND_READ_BINARY] = function ICC_COMMAND_READ_BINARY(options) {
+  this.processICCIOReadBinary(options);
+};
+ICCIOHelper[ICC_COMMAND_READ_RECORD] = function ICC_COMMAND_READ_RECORD(options) {
+  this.processICCIOReadRecord(options);
+};
+ICCIOHelper[ICC_COMMAND_GET_RESPONSE] = function ICC_COMMAND_GET_RESPONSE(options) {
+  this.processICCIOGetResponse(options);
+};
+ICCIOHelper[ICC_COMMAND_UPDATE_BINARY] = null;
+ICCIOHelper[ICC_COMMAND_UPDATE_RECORD] = null;
+
+/**
+ * Helper for ICC records.
+ */
+let ICCRecordHelper = {
+  /**
+   * Fetch ICC records.
+   */
+  fetchICCRecords: function fetchICCRecords() {
+    this.getICCID();
+    RIL.getIMSI();
+    this.getMSISDN();
+    this.getAD();
+    this.getSST();
+    this.getMBDN();
+  },
+
+  /**
+   * Get EF_phase.
+   * This EF is only available in SIM.
+   */
+  getICCPhase: function getICCPhase() {
+    function callback() {
+      let length = Buf.readUint32();
+
+      let phase = GsmPDUHelper.readHexOctet();
+      // If EF_phase is coded '03' or greater, an ME supporting STK shall
+      // perform the PROFILE DOWNLOAD procedure.
+      if (phase >= ICC_PHASE_2_PROFILE_DOWNLOAD_REQUIRED) {
+        RIL.sendStkTerminalProfile(STK_SUPPORTED_TERMINAL_PROFILE);
+      }
+
+      Buf.readStringDelimiter(length);
+    }
+
+    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_PHASE,
+                                   callback: callback.bind(this)});
+  },
+
+  /**
+   * Read the ICCID.
+   */
+  getICCID: function getICCID() {
+    function callback() {
+      let length = Buf.readUint32();
+      RIL.iccInfo.iccid = GsmPDUHelper.readSwappedNibbleBcdString(length / 2);
+      Buf.readStringDelimiter(length);
+
+      if (DEBUG) debug("ICCID: " + RIL.iccInfo.iccid);
+      if (RIL.iccInfo.iccid) {
+        ICCUtilsHelper.handleICCInfoChange();
+      }
+    }
+
+    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_ICCID,
+                                   callback: callback.bind(this)});
+  },
+
+  /**
+   * Read the MSISDN from the ICC.
+   */
+  getMSISDN: function getMSISDN() {
+    function callback(options) {
+      let contact = GsmPDUHelper.readAlphaIdDiallingNumber(options);
+      if (!contact || RIL.iccInfo.msisdn === contact.number) {
+        return;
+      }
+      RIL.iccInfo.msisdn = contact.number;
+      if (DEBUG) debug("MSISDN: " + RIL.iccInfo.msisdn);
+      ICCUtilsHelper.handleICCInfoChange();
+    }
+
+    ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_MSISDN,
+                                   callback: callback.bind(this)});
+  },
+
+  /**
+   * Read the AD (Administrative Data) from the ICC.
+   */
+  getAD: function getAD() {
+    function callback() {
+      let length = Buf.readUint32();
+      // Each octet is encoded into two chars.
+      let len = length / 2;
+      RIL.iccInfo.ad = GsmPDUHelper.readHexOctetArray(len);
+      Buf.readStringDelimiter(length);
+
+      if (DEBUG) {
+        let str = "";
+        for (let i = 0; i < RIL.iccInfo.ad.length; i++) {
+          str += RIL.iccInfo.ad[i] + ", ";
+        }
+        debug("AD: " + str);
+      }
+
+      if (RIL.iccInfo.imsi) {
+        // MCC is the first 3 digits of IMSI.
+        RIL.iccInfo.mcc = parseInt(RIL.iccInfo.imsi.substr(0,3));
+        // The 4th byte of the response is the length of MNC.
+        RIL.iccInfo.mnc = parseInt(RIL.iccInfo.imsi.substr(3, RIL.iccInfo.ad[3]));
+        if (DEBUG) debug("MCC: " + RIL.iccInfo.mcc + " MNC: " + RIL.iccInfo.mnc);
+        ICCUtilsHelper.handleICCInfoChange();
+      }
+    }
+
+    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_AD,
+                                   callback: callback.bind(this)});
+  },
+
+  /**
+   * Read the SPN (Service Provider Name) from the ICC.
+   */
+  getSPN: function getSPN() {
+    function callback() {
+      let length = Buf.readUint32();
+      // Each octet is encoded into two chars.
+      // Minus 1 because the first octet is used to store display condition.
+      let len = (length / 2) - 1;
+      let spnDisplayCondition = GsmPDUHelper.readHexOctet();
+      let spn = GsmPDUHelper.readAlphaIdentifier(len);
+      Buf.readStringDelimiter(length);
+
+      if (DEBUG) {
+        debug("SPN: spn = " + spn +
+              ", spnDisplayCondition = " + spnDisplayCondition);
+      }
+
+      RIL.iccInfoPrivate.SPN = {
+        spn : spn,
+        spnDisplayCondition : spnDisplayCondition,
+      };
+      RIL.iccInfo.spn = spn;
+      ICCUtilsHelper.updateDisplayCondition();
+      ICCUtilsHelper.handleICCInfoChange();
+    }
+
+    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_SPN,
+                                   callback: callback.bind(this)});
+  },
+
+  /**
+   * Read the (U)SIM Service Table from the ICC.
+   */
+  getSST: function getSST() {
+    function callback() {
+      let length = Buf.readUint32();
+      // Each octet is encoded into two chars.
+      let len = length / 2;
+      RIL.iccInfo.sst = GsmPDUHelper.readHexOctetArray(len);
+      Buf.readStringDelimiter(length);
+
+      if (DEBUG) {
+        let str = "";
+        for (let i = 0; i < RIL.iccInfo.sst.length; i++) {
+          str += RIL.iccInfo.sst[i] + ", ";
+        }
+        debug("SST: " + str);
+      }
+
+      // Fetch SPN and PLMN list, if some of them are available.
+      if (ICCUtilsHelper.isICCServiceAvailable("SPN")) {
+        if (DEBUG) debug("SPN: SPN is available");
+        this.getSPN();
+      } else {
+        if (DEBUG) debug("SPN: SPN service is not available");
+      }
+
+      if (ICCUtilsHelper.isICCServiceAvailable("SPDI")) {
+        if (DEBUG) debug("SPDI: SPDI available.");
+        this.getSPDI();
+      } else {
+        if (DEBUG) debug("SPDI: SPDI service is not available");
+      }
+
+      if (ICCUtilsHelper.isICCServiceAvailable("PNN")) {
+        if (DEBUG) debug("PNN: PNN is available");
+        this.getPNN();
+      } else {
+        if (DEBUG) debug("PNN: PNN is not available");
+      }
+
+      if (ICCUtilsHelper.isICCServiceAvailable("OPL")) {
+        if (DEBUG) debug("OPL: OPL is available");
+        this.getOPL();
+      } else {
+        if (DEBUG) debug("OPL: OPL is not available");
+      }
+
+      if (ICCUtilsHelper.isICCServiceAvailable("CBMI")) {
+        this.getCBMI();
+      } else {
+        RIL.cellBroadcastConfigs.CBMI = null;
+      }
+      if (ICCUtilsHelper.isICCServiceAvailable("CBMIR")) {
+        this.getCBMIR();
+      } else {
+        RIL.cellBroadcastConfigs.CBMIR = null;
+      }
+      RIL._mergeAllCellBroadcastConfigs();
+    }
+
+    // ICC_EF_UST has the same value with ICC_EF_SST.
+    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_SST,
+                                   callback: callback.bind(this)});
+  },
+
+  /**
+   *  Get ICC FDN.
+   *
+   *  @param requestId
+   *         Request id from RadioInterfaceLayer.
+   */
+  getFDN: function getFDN(options) {
+    function callback(options) {
+      let contact = GsmPDUHelper.readAlphaIdDiallingNumber(options);
+      if (contact) {
+        RIL.iccInfo.fdn.push(contact);
+      }
+
+      if (options.p1 < options.totalRecords) {
+        ICCIOHelper.loadNextRecord(options);
+      } else {
+        if (DEBUG) {
+          for (let i = 0; i < RIL.iccInfo.fdn.length; i++) {
+            debug("FDN[" + i + "] alphaId = " + RIL.iccInfo.fdn[i].alphaId +
+                                " number  = " + RIL.iccInfo.fdn[i].number);
+          }
+        }
+        // To prevent DataCloneError when sending parcels, we need to delete
+        // those properties which are not 'Structured Clone Data', in this case,
+        // those callback functions.
+        delete options.callback;
+        delete options.onerror;
+        options.rilMessageType = "icccontacts";
+        options.contacts = RIL.iccInfo.fdn;
+        RIL.sendDOMMessage(options);
+      }
+    }
+
+    RIL.iccInfo.fdn = [];
+    options.fileId = ICC_EF_FDN;
+    options.callback = callback.bind(this);
+    ICCIOHelper.loadLinearFixedEF(options);
+  },
+
+  /**
+   *  Get ICC ADN.
+   *
+   *  @param fileId
+   *         EF id of the ADN.
+   *  @param requestId
+   *         Request id from RadioInterfaceLayer.
+   */
+  getADN: function getADN(options) {
+    function callback(options) {
+      let contact = GsmPDUHelper.readAlphaIdDiallingNumber(options);
+      if (contact) {
+        RIL.iccInfo.adn.push(contact);
+      }
+
+      if (options.p1 < options.totalRecords) {
+        ICCIOHelper.loadNextRecord(options);
+      } else {
+        if (DEBUG) {
+          for (let i = 0; i < RIL.iccInfo.adn.length; i++) {
+            debug("ADN[" + i + "] " + JSON.stringify(RIL.iccInfo.adn[i]));
+          }
+        }
+        // To prevent DataCloneError when sending parcels, we need to delete
+        // those properties which are not 'Structured Clone Data', in this case,
+        // those callback functions.
+        delete options.callback;
+        delete options.onerror;
+        options.rilMessageType = "icccontacts";
+        options.contacts = RIL.iccInfo.adn;
+        RIL.sendDOMMessage(options);
+      }
+    }
+
+    function error(options) {
+      delete options.callback;
+      delete options.onerror;
+      options.rilMessageType = "icccontacts";
+      RIL.sendDOMMessage(options);
+    }
+
+    RIL.iccInfo.adn = [];
+    options.callback = callback.bind(this);
+    options.onerror = error.bind(this);
+    ICCIOHelper.loadLinearFixedEF(options);
+  },
+
+  /**
+   * Get ICC MBDN. (Mailbox Dialling Number)
+   *
+   * @see TS 131.102, clause 4.2.60
+   */
+  getMBDN: function getMBDN() {
+    function callback(options) {
+      let contact = GsmPDUHelper.readAlphaIdDiallingNumber(options);
+      if (!contact || RIL.iccInfo.mbdn === contact.number){
+        return;
+      }
+      RIL.iccInfo.mbdn = contact.number;
+      if (DEBUG) {
+        debug("MBDN, alphaId="+contact.alphaId+" number="+contact.number);
+      }
+      contact.rilMessageType = "iccmbdn";
+      RIL.sendDOMMessage(contact);
+    }
+
+    ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_MBDN,
+                                   callback: callback.bind(this)});
+  },
+
+  /**
+   * Get USIM Phonebook.
+   *
+   * @param requestId
+   *         Request id from RadioInterfaceLayer.
+   */
+  getPBR: function getPBR(options) {
+    function callback(options) {
+      let bufLen = Buf.readUint32();
+
+      let tag = GsmPDUHelper.readHexOctet();
+      let length = GsmPDUHelper.readHexOctet();
+      let value = ICCUtilsHelper.decodeSimTlvs(length);
+
+      let adn = ICCUtilsHelper.searchForIccUsimTag(value, ICC_USIM_EFADN_TAG);
+      options.fileId = (adn.value[0] << 8) | adn.value[1];
+      Buf.readStringDelimiter(bufLen);
+
+      this.getADN(options);
+    }
+
+    function error(options) {
+      delete options.callback;
+      delete options.onerror;
+      options.rilMessageType = "icccontacts";
+      RIL.sendDOMMessage(options);
+    }
+
+    options.fileId = ICC_EF_PBR;
+    options.callback = callback.bind(this);
+    options.onerror = error.bind(this);
+    ICCIOHelper.loadLinearFixedEF(options);
+  },
+
+  /**
+   * Read the PLMNsel (Public Land Mobile Network) from the ICC.
+   *
+   * See ETSI TS 100.977 section 10.3.4 EF_PLMNsel
+   */
+  getPLMNSelector: function getPLMNSelector() {
+    function callback() {
+      if (DEBUG) debug("PLMN Selector: Process PLMN Selector");
+
+      let length = Buf.readUint32();
+      RIL.iccInfoPrivate.PLMN = this.readPLMNEntries(length/3);
+      Buf.readStringDelimiter(length);
+
+      if (DEBUG) debug("PLMN Selector: " + JSON.stringify(RIL.iccInfoPrivate.PLMN));
+
+      if (RIL.updateDisplayCondition()) {
+        this.handleICCInfoChange();
+      }
+    }
+
+    // PLMN List is Service 7 in SIM, EF_PLMNsel
+    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_PLMNsel,
+                                   callback: callback.bind(this)});
+  },
+
+  /**
+   * Read the SPDI (Service Provider Display Information) from the ICC.
+   *
+   * See TS 131.102 section 4.2.66 for USIM and TS 51.011 section 10.3.50
+   * for SIM.
+   */
+  getSPDI: function getSPDI() {
+    function callback() {
+      let length = Buf.readUint32();
+      let readLen = 0;
+      let endLoop = false;
+      RIL.iccInfoPrivate.SPDI = null;
+      while ((readLen < length / 2) && !endLoop) {
+        let tlvTag = GsmPDUHelper.readHexOctet();
+        let tlvLen = GsmPDUHelper.readHexOctet();
+        readLen += 2; // For tag and length fields.
+        switch (tlvTag) {
+        case SPDI_TAG_SPDI:
+          // The value part itself is a TLV.
+          continue;
+        case SPDI_TAG_PLMN_LIST:
+          // This PLMN list is what we want.
+          RIL.iccInfoPrivate.SPDI = this.readPLMNEntries(tlvLen / 3);
+          readLen += tlvLen;
+          endLoop = true;
+          break;
+        default:
+          // We don't care about its content if its tag is not SPDI nor
+          // PLMN_LIST.
+          endLoop = true;
+          break;
+        }
+      }
+
+      // Consume unread octets.
+      Buf.seekIncoming((length / 2 - readLen) * PDU_HEX_OCTET_SIZE);
+      Buf.readStringDelimiter(length);
+
+      if (DEBUG) debug("SPDI: " + JSON.stringify(RIL.iccInfoPrivate.SPDI));
+      if (ICCUtilsHelper.updateDisplayCondition()) {
+        ICCUtilsHelper.handleICCInfoChange();
+      }
+    }
+
+    // PLMN List is Servive 51 in USIM, EF_SPDI
+    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_SPDI,
+                                   callback: callback.bind(this)});
+  },
+
+  /**
+   * Read EFcbmi (Cell Broadcast Message Identifier selection)
+   *
+   * @see 3GPP TS 31.102 v110.02.0 section 4.2.14 EFcbmi
+   */
+  getCBMI: function getCBMI() {
+    function callback() {
+      let strLength = Buf.readUint32();
+
+      // Each Message Identifier takes two octets and each octet is encoded
+      // into two chars.
+      let numIds = strLength / 4, list = null;
+      if (numIds) {
+        list = [];
+        for (let i = 0, id; i < numIds; i++) {
+          id = GsmPDUHelper.readHexOctet() << 8 | GsmPDUHelper.readHexOctet();
+          // `Unused entries shall be set to 'FF FF'.`
+          if (id != 0xFFFF) {
+            list.push(id);
+            list.push(id + 1);
+          }
+        }
+      }
+      if (DEBUG) {
+        debug("CBMI: " + JSON.stringify(list));
+      }
+
+      Buf.readStringDelimiter(strLength);
+
+      RIL.cellBroadcastConfigs.CBMI = list;
+      RIL._mergeAllCellBroadcastConfigs();
+    }
+
+    function onerror() {
+      RIL.cellBroadcastConfigs.CBMI = null;
+      RIL._mergeAllCellBroadcastConfigs();
+    }
+
+    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_CBMI,
+                                   callback: callback.bind(this),
+                                   onerror: onerror.bind(this)});
+  },
+
+  /**
+   * Read EFcbmir (Cell Broadcast Message Identifier Range selection)
+   *
+   * @see 3GPP TS 31.102 v110.02.0 section 4.2.22 EFcbmir
+   */
+  getCBMIR: function getCBMIR() {
+    function callback() {
+      let strLength = Buf.readUint32();
+
+      // Each Message Identifier range takes four octets and each octet is
+      // encoded into two chars.
+      let numIds = strLength / 8, list = null;
+      if (numIds) {
+        list = [];
+        for (let i = 0, from, to; i < numIds; i++) {
+          // `Bytes one and two of each range identifier equal the lower value
+          // of a cell broadcast range, bytes three and four equal the upper
+          // value of a cell broadcast range.`
+          from = GsmPDUHelper.readHexOctet() << 8 | GsmPDUHelper.readHexOctet();
+          to = GsmPDUHelper.readHexOctet() << 8 | GsmPDUHelper.readHexOctet();
+          // `Unused entries shall be set to 'FF FF'.`
+          if ((from != 0xFFFF) && (to != 0xFFFF)) {
+            list.push(from);
+            list.push(to + 1);
+          }
+        }
+      }
+      if (DEBUG) {
+        debug("CBMIR: " + JSON.stringify(list));
+      }
+
+      Buf.readStringDelimiter(strLength);
+
+      RIL.cellBroadcastConfigs.CBMIR = list;
+      RIL._mergeAllCellBroadcastConfigs();
+    }
+
+    function onerror() {
+      RIL.cellBroadcastConfigs.CBMIR = null;
+      RIL._mergeAllCellBroadcastConfigs();
+    }
+
+    ICCIOHelper.loadTransparentEF({fileId: ICC_EF_CBMIR,
+                                   callback: callback.bind(this),
+                                   onerror: onerror.bind(this)});
+  },
+
+  /**
+   * Read OPL (Operator PLMN List) from USIM.
+   *
+   * See 3GPP TS 31.102 Sec. 4.2.59 for USIM
+   *     3GPP TS 51.011 Sec. 10.3.42 for SIM.
+   */
+  getOPL: function getOPL() {
+    let opl = [];
+    function callback(options) {
+      let len = Buf.readUint32();
+      // The first 7 bytes are LAI (for UMTS) and the format of LAI is defined
+      // in 3GPP TS 23.003, Sec 4.1
+      //    +-------------+---------+
+      //    | Octet 1 - 3 | MCC/MNC |
+      //    +-------------+---------+
+      //    | Octet 4 - 7 |   LAC   |
+      //    +-------------+---------+
+      let mccMnc = [GsmPDUHelper.readHexOctet(),
+                    GsmPDUHelper.readHexOctet(),
+                    GsmPDUHelper.readHexOctet()];
+      if (mccMnc[0] != 0xFF || mccMnc[1] != 0xFF || mccMnc[2] != 0xFF) {
+        let oplElement = {};
+        let semiOctets = [];
+        for (let i = 0; i < mccMnc.length; i++) {
+          semiOctets.push((mccMnc[i] & 0xf0) >> 4);
+          semiOctets.push(mccMnc[i] & 0x0f);
+        }
+        let reformat = [semiOctets[1], semiOctets[0], semiOctets[3],
+                        semiOctets[5], semiOctets[4], semiOctets[2]];
+        let buf = "";
+        for (let i = 0; i < reformat.length; i++) {
+          if (reformat[i] != 0xF) {
+            buf += GsmPDUHelper.semiOctetToBcdChar(reformat[i]);
+          }
+          if (i === 2) {
+            // 0-2: MCC
+            oplElement.mcc = parseInt(buf);
+            buf = "";
+          } else if (i === 5) {
+            // 3-5: MNC
+            oplElement.mnc = parseInt(buf);
+          }
+        }
+        // LAC/TAC
+        oplElement.lacTacStart =
+          (GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
+        oplElement.lacTacEnd =
+          (GsmPDUHelper.readHexOctet() << 8) | GsmPDUHelper.readHexOctet();
+        // PLMN Network Name Record Identifier
+        oplElement.pnnRecordId = GsmPDUHelper.readHexOctet();
+        if (DEBUG) {
+          debug("OPL: [" + (opl.length + 1) + "]: " + JSON.stringify(oplElement));
+        }
+        opl.push(oplElement);
+      }
+      Buf.readStringDelimiter(len);
+      if (options.p1 < options.totalRecords) {
+        ICCIOHelper.loadNextRecord(options);
+      } else {
+        RIL.iccInfoPrivate.OPL = opl;
+      }
+    }
+
+    ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_OPL,
+                                   callback: callback.bind(this)});
+  },
+
+  /**
+   * Read PNN (PLMN Network Name) from USIM.
+   *
+   * See 3GPP TS 31.102 Sec. 4.2.58 for USIM
+   *     3GPP TS 51.011 Sec. 10.3.41 for SIM.
+   */
+  getPNN: function getPNN() {
+    let pnn = [];
+    function callback(options) {
+      let pnnElement = RIL.iccInfoPrivate.PNN = {};
+      let len = Buf.readUint32();
+      let readLen = 0;
+      while (len > readLen) {
+        let tlvTag = GsmPDUHelper.readHexOctet();
+        readLen = readLen + 2; // 1 Hex octet
+        if (tlvTag == 0xFF) {
+          // Unused byte
+          continue;
+        }
+        let tlvLen = GsmPDUHelper.readHexOctet();
+        let name;
+        switch (tlvTag) {
+        case PNN_IEI_FULL_NETWORK_NAME:
+          pnnElement.fullName = GsmPDUHelper.readNetworkName(tlvLen);
+          break;
+        case PNN_IEI_SHORT_NETWORK_NAME:
+          pnnElement.shortName = GsmPDUHelper.readNetworkName(tlvLen);
+          break;
+        default:
+          Buf.seekIncoming(PDU_HEX_OCTET_SIZE * tlvLen);
+        }
+        readLen += (tlvLen * 2 + 2);
+      }
+      if (DEBUG) {
+        debug("PNN: [" + (pnn.length + 1) + "]: " + JSON.stringify(pnnElement));
+      }
+      Buf.readStringDelimiter(len);
+      pnn.push(pnnElement);
+
+      if (options.p1 < options.totalRecords) {
+        ICCIOHelper.loadNextRecord(options);
+      } else {
+        RIL.iccInfoPrivate.PNN = pnn;
+      }
+    }
+
+    ICCIOHelper.loadLinearFixedEF({fileId: ICC_EF_PNN,
+                                   callback: callback.bind(this)});
+  },
+
+  /**
+   *  Read the list of PLMN (Public Land Mobile Network) entries
+   *  We cannot directly rely on readSwappedNibbleBcdToString(),
+   *  since it will no correctly handle some corner-cases that are
+   *  not a problem in our case (0xFF 0xFF 0xFF).
+   *
+   *  @param length The number of PLMN records.
+   *  @return An array of string corresponding to the PLMNs.
+   */
+  readPLMNEntries: function readPLMNEntries(length) {
+    let plmnList = [];
+    // Each PLMN entry has 3 bytes.
+    debug("readPLMNEntries: PLMN entries length = " + length);
+    let index = 0;
+    while (index < length) {
+      // Unused entries will be 0xFFFFFF, according to EF_SPDI
+      // specs (TS 131 102, section 4.2.66)
+      try {
+        let plmn = [GsmPDUHelper.readHexOctet(),
+                    GsmPDUHelper.readHexOctet(),
+                    GsmPDUHelper.readHexOctet()];
+        if (DEBUG) debug("readPLMNEntries: Reading PLMN entry: [" + index +
+                         "]: '" + plmn + "'");
+        if (plmn[0] != 0xFF &&
+            plmn[1] != 0xFF &&
+            plmn[2] != 0xFF) {
+          let semiOctets = [];
+          for (let idx = 0; idx < plmn.length; idx++) {
+            semiOctets.push((plmn[idx] & 0xF0) >> 4);
+            semiOctets.push(plmn[idx] & 0x0F);
+          }
+
+          // According to TS 24.301, 9.9.3.12, the semi octets is arranged
+          // in format:
+          // Byte 1: MCC[2] | MCC[1]
+          // Byte 2: MNC[3] | MCC[3]
+          // Byte 3: MNC[2] | MNC[1]
+          // Therefore, we need to rearrange them.
+          let reformat = [semiOctets[1], semiOctets[0], semiOctets[3],
+                          semiOctets[5], semiOctets[4], semiOctets[2]];
+          let buf = "";
+          let plmnEntry = {};
+          for (let i = 0; i < reformat.length; i++) {
+            if (reformat[i] != 0xF) {
+              buf += GsmPDUHelper.semiOctetToBcdChar(reformat[i]);
+            }
+            if (i === 2) {
+              // 0-2: MCC
+              plmnEntry.mcc = parseInt(buf);
+              buf = "";
+            } else if (i === 5) {
+              // 3-5: MNC
+              plmnEntry.mnc = parseInt(buf);
+            }
+          }
+          if (DEBUG) debug("readPLMNEntries: PLMN = " + plmnEntry.mcc + ", " + plmnEntry.mnc);
+          plmnList.push(plmnEntry);
+        }
+      } catch (e) {
+        if (DEBUG) debug("readPLMNEntries: PLMN entry " + index + " is invalid.");
+        break;
+      }
+      index ++;
+    }
+    return plmnList;
+  },
+};
+
+/**
+ * Helper functions for ICC utilities.
+ */
+let ICCUtilsHelper = {
+  /**
+   * This will compute the spnDisplay field of the network.
+   * See TS 22.101 Annex A and TS 51.011 10.3.11 for details.
+   *
+   * @return True if some of iccInfo is changed in by this function.
+   */
+  updateDisplayCondition: function updateDisplayCondition() {
+    // If EFspn isn't existed in SIM or it haven't been read yet, we should
+    // just set isDisplayNetworkNameRequired = true and
+    // isDisplaySpnRequired = false
+    let iccInfo = RIL.iccInfo;
+    let iccInfoPriv = RIL.iccInfoPrivate;
+    let iccSpn = iccInfoPriv.SPN;
+    let origIsDisplayNetworkNameRequired = iccInfo.isDisplayNetworkNameRequired;
+    let origIsDisplaySPNRequired = iccInfo.isDisplaySpnRequired;
+
+    if (!iccSpn) {
+      iccInfo.isDisplayNetworkNameRequired = true;
+      iccInfo.isDisplaySpnRequired = false;
+    } else {
+      let operatorMnc = RIL.operator.mnc;
+      let operatorMcc = RIL.operator.mcc;
+
+      // First detect if we are on HPLMN or one of the PLMN
+      // specified by the SIM card.
+      let isOnMatchingPlmn = false;
+
+      // If the current network is the one defined as mcc/mnc
+      // in SIM card, it's okay.
+      if (iccInfo.mcc == operatorMcc && iccInfo.mnc == operatorMnc) {
+        isOnMatchingPlmn = true;
+      }
+
+      // Test to see if operator's mcc/mnc match mcc/mnc of PLMN.
+      if (!isOnMatchingPlmn && iccInfoPriv.SPDI) {
+        let iccSpdi = iccInfoPriv.SPDI; // PLMN list
+        for (let plmn in iccSpdi) {
+          let plmnMcc = iccSpdi[plmn].mcc;
+          let plmnMnc = iccSpdi[plmn].mnc;
+          isOnMatchingPlmn = (plmnMcc == operatorMcc) && (plmnMnc == operatorMnc);
+          if (isOnMatchingPlmn) {
+            break;
+          }
+        }
+      }
+
+      if (isOnMatchingPlmn) {
+        // The first bit of display condition tells us if we should display
+        // registered PLMN.
+        if (DEBUG) debug("updateDisplayCondition: PLMN is HPLMN or PLMN is in PLMN list");
+
+        // TS 31.102 Sec. 4.2.66 and TS 51.011 Sec. 10.3.50
+        // EF_SPDI contains a list of PLMNs in which the Service Provider Name
+        // shall be displayed.
+        iccInfo.isDisplaySpnRequired = true;
+        if (iccSpn.spnDisplayCondition & 0x01) {
+          iccInfo.isDisplayNetworkNameRequired = true;
+        } else {
+          iccInfo.isDisplayNetworkNameRequired = false;
+        }
+      } else {
+        // The second bit of display condition tells us if we should display
+        // registered PLMN.
+        if (DEBUG) debug("updateICCDisplayName: PLMN isn't HPLMN and PLMN isn't in PLMN list");
+
+        // We didn't found the requirement of displaying network name if
+        // current PLMN isn't HPLMN nor one of PLMN in SPDI. So we keep
+        // isDisplayNetworkNameRequired false.
+        if (iccSpn.spnDisplayCondition & 0x02) {
+          iccInfo.isDisplayNetworkNameRequired = false;
+          iccInfo.isDisplaySpnRequired = false;
+        } else {
+          iccInfo.isDisplayNetworkNameRequired = false;
+          iccInfo.isDisplaySpnRequired = true;
+        }
+      }
+    }
+
+    if (DEBUG) {
+      debug("updateDisplayCondition: isDisplayNetworkNameRequired = " + iccInfo.isDisplayNetworkNameRequired);
+      debug("updateDisplayCondition: isDisplaySpnRequired = " + iccInfo.isDisplaySpnRequired);
+    }
+
+    return ((origIsDisplayNetworkNameRequired !== iccInfo.isDisplayNetworkNameRequired) ||
+            (origIsDisplaySPNRequired !== iccInfo.isDisplaySpnRequired));
+  },
+
+  decodeSimTlvs: function decodeSimTlvs(tlvsLen) {
+    let index = 0;
+    let tlvs = [];
+    while (index < tlvsLen) {
+      let simTlv = {
+        tag : GsmPDUHelper.readHexOctet(),
+        length : GsmPDUHelper.readHexOctet(),
+      };
+      simTlv.value = GsmPDUHelper.readHexOctetArray(simTlv.length)
+      tlvs.push(simTlv);
+      index += simTlv.length + 2 /* The length of 'tag' and 'length' field */;
+    }
+    return tlvs;
+  },
+
+  searchForIccUsimTag: function searchForIccUsimTag(tlvs, tag) {
+    for (let i = 0; i < tlvs.length; i++) {
+      if (tlvs[i].tag == tag) {
+        return tlvs[i];
+      }
+    }
+    return null;
+  },
+
+  /**
+   * Update the ICC information to RadioInterfaceLayer.
+   */
+  handleICCInfoChange: function handleICCInfoChange() {
+    RIL.iccInfo.rilMessageType = "iccinfochange";
+    RIL.sendDOMMessage(RIL.iccInfo);
+  },
+
+  /**
+   * Get whether specificed (U)SIM service is available.
+   *
+   * @param geckoService
+   *        Service name like "ADN", "BDN", etc.
+   *
+   * @return true if the service is enabled, false otherwise.
+   */
+  isICCServiceAvailable: function isICCServiceAvailable(geckoService) {
+    let serviceTable = RIL.iccInfo.sst;
+    let index, bitmask;
+    if (RIL.appType == CARD_APPTYPE_SIM) {
+      /**
+       * Service id is valid in 1..N, and 2 bits are used to code each service.
+       *
+       * +----+--  --+----+----+
+       * | b8 | ...  | b2 | b1 |
+       * +----+--  --+----+----+
+       *
+       * b1 = 0, service not allocated.
+       *      1, service allocated.
+       * b2 = 0, service not activatd.
+       *      1, service allocated.
+       *
+       * @see 3GPP TS 51.011 10.3.7.
+       */
+      let simService = GECKO_ICC_SERVICES.sim[geckoService];
+      if (!simService) {
+        return false;
+      }
+      simService -= 1;
+      index = Math.floor(simService / 4);
+      bitmask = 2 << ((simService % 4) << 1);
+    } else {
+      /**
+       * Service id is valid in 1..N, and 1 bit is used to code each service.
+       *
+       * +----+--  --+----+----+
+       * | b8 | ...  | b2 | b1 |
+       * +----+--  --+----+----+
+       *
+       * b1 = 0, service not avaiable.
+       *      1, service available.
+       * b2 = 0, service not avaiable.
+       *      1, service available.
+       *
+       * @see 3GPP TS 31.102 4.2.8.
+       */
+      let usimService = GECKO_ICC_SERVICES.usim[geckoService];
+      if (!usimService) {
+        return false;
+      }
+      usimService -= 1;
+      index = Math.floor(usimService / 8);
+      bitmask = 1 << ((usimService % 8) << 0);
+    }
+
+    return (serviceTable &&
+           (index < serviceTable.length) &&
+           (serviceTable[index] & bitmask)) != 0;
+  },
+};
+
+/**
  * Global stuff.
  */
 
 if (!this.debug) {
   // Debugging stub that goes nowhere.
   this.debug = function debug(message) {
     dump("RIL Worker: " + message + "\n");
   };
--- a/dom/system/gonk/tests/test_ril_worker_icc.js
+++ b/dom/system/gonk/tests/test_ril_worker_icc.js
@@ -186,27 +186,28 @@ add_test(function test_octect_BCD() {
   octet = 0x56;
   number = helper.octetToBCD(octet);
   do_check_eq(helper.BCDToOctet(number), octet);
 
   run_next_test();
 });
 
 /**
- * Verify RIL.isICCServiceAvailable.
+ * Verify ICCUtilsHelper.isICCServiceAvailable.
  */
 add_test(function test_is_icc_service_available() {
   let worker = newUint8Worker();
+  let ICCUtilsHelper = worker.ICCUtilsHelper;
 
   function test_table(sst, geckoService, simEnabled, usimEnabled) {
     worker.RIL.iccInfo.sst = sst;
     worker.RIL.appType = CARD_APPTYPE_SIM;
-    do_check_eq(worker.RIL.isICCServiceAvailable(geckoService), simEnabled);
+    do_check_eq(ICCUtilsHelper.isICCServiceAvailable(geckoService), simEnabled);
     worker.RIL.appType = CARD_APPTYPE_USIM;
-    do_check_eq(worker.RIL.isICCServiceAvailable(geckoService), usimEnabled);
+    do_check_eq(ICCUtilsHelper.isICCServiceAvailable(geckoService), usimEnabled);
   }
 
   test_table([0x08], "ADN", true, false);
   test_table([0x08], "FDN", false, false);
   test_table([0x08], "SDN", false, true);
 
   run_next_test();
 });
@@ -565,27 +566,29 @@ add_test(function test_stk_proactive_com
   for (let i = 0; i < tlv.value.eventList.length; i++) {
     do_check_eq(tlv.value.eventList[i], i);
   }
 
   run_next_test();
 });
 
 add_test(function test_spn_display_condition() {
-  let RIL = newWorker({
+  let worker = newWorker({
     postRILMessage: function fakePostRILMessage(data) {
       // Do nothing
     },
     postMessage: function fakePostMessage(message) {
       // Do nothing
     }
-  }).RIL;
+  });
+  let RIL = worker.RIL;
+  let ICCUtilsHelper = worker.ICCUtilsHelper;
 
   // Test updateDisplayCondition runs before any of SIM file is ready.
-  do_check_eq(RIL.updateDisplayCondition(), true);
+  do_check_eq(ICCUtilsHelper.updateDisplayCondition(), true);
   do_check_eq(RIL.iccInfo.isDisplayNetworkNameRequired, true);
   do_check_eq(RIL.iccInfo.isDisplaySpnRequired, false);
 
   // Test with value.
   function testDisplayCondition(iccDisplayCondition,
                                 iccMcc, iccMnc, plmnMcc, plmnMnc,
                                 expectedIsDisplayNetworkNameRequired,
                                 expectedIsDisplaySPNRequired,
@@ -597,17 +600,17 @@ add_test(function test_spn_display_condi
       mcc: iccMcc,
       mnc: iccMnc
     };
     RIL.operator = {
       mcc: plmnMcc,
       mnc: plmnMnc
     };
 
-    do_check_eq(RIL.updateDisplayCondition(), true);
+    do_check_eq(ICCUtilsHelper.updateDisplayCondition(), true);
     do_check_eq(RIL.iccInfo.isDisplayNetworkNameRequired, expectedIsDisplayNetworkNameRequired);
     do_check_eq(RIL.iccInfo.isDisplaySpnRequired, expectedIsDisplaySPNRequired);
     do_timeout(0, callback);
   };
 
   function testDisplayConditions(func, caseArray, oncomplete) {
     (function do_call(index) {
       let next = index < (caseArray.length - 1) ? do_call.bind(null, index + 1) : oncomplete;
@@ -896,41 +899,42 @@ add_test(function test_stk_proactive_com
   do_check_eq(tlv.value.commandNumber, 0x01);
   do_check_eq(tlv.value.typeOfCommand, STK_CMD_PROVIDE_LOCAL_INFO);
   do_check_eq(tlv.value.commandQualifier, STK_LOCAL_INFO_DATE_TIME_ZONE);
 
   run_next_test();
 });
 
 add_test(function test_path_id_for_spid_and_spn() {
-  let RIL = newWorker({
+  let worker = newWorker({
     postRILMessage: function fakePostRILMessage(data) {
       // Do nothing
     },
     postMessage: function fakePostMessage(message) {
       // Do nothing
-    }
-  }).RIL;
+    }});
+  let RIL = worker.RIL;
+  let ICCFileHelper = worker.ICCFileHelper;
 
   // Test SIM
   RIL.iccStatus = {
     gsmUmtsSubscriptionAppIndex: 0,
     apps: [
       {
         app_type: CARD_APPTYPE_SIM
       }, {
         app_type: CARD_APPTYPE_USIM
       }
     ]
   }
-  do_check_eq(RIL._getPathIdForICCRecord(ICC_EF_SPDI),
+  do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPDI),
               EF_PATH_MF_SIM + EF_PATH_DF_GSM);
-  do_check_eq(RIL._getPathIdForICCRecord(ICC_EF_SPN),
+  do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPN),
               EF_PATH_MF_SIM + EF_PATH_DF_GSM);
 
   // Test USIM
   RIL.iccStatus.gsmUmtsSubscriptionAppIndex = 1;
-  do_check_eq(RIL._getPathIdForICCRecord(ICC_EF_SPDI),
+  do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPDI),
               EF_PATH_MF_SIM + EF_PATH_ADF_USIM);
-  do_check_eq(RIL._getPathIdForICCRecord(ICC_EF_SPDI),
+  do_check_eq(ICCFileHelper.getEFPath(ICC_EF_SPDI),
               EF_PATH_MF_SIM + EF_PATH_ADF_USIM);
   run_next_test();
-});
\ No newline at end of file
+});
--- a/dom/time/Makefile.in
+++ b/dom/time/Makefile.in
@@ -9,17 +9,19 @@ VPATH            = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE           = dom
 LIBRARY_NAME     = dom_time_s
 XPIDL_MODULE     = dom_time
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 include $(topsrcdir)/dom/dom-config.mk
 
 EXPORTS_NAMESPACES = mozilla/dom/time
 
 CPPSRCS = \
   TimeManager.cpp \
   TimeService.cpp \
--- a/dom/workers/Makefile.in
+++ b/dom/workers/Makefile.in
@@ -1,24 +1,26 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH            = @DEPTH@
 topsrcdir        = @top_srcdir@
 srcdir           = @srcdir@
 VPATH            = @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE           = dom
 LIBRARY_NAME     = domworkers_s
 LIBXUL_LIBRARY   = 1
 FORCE_STATIC_LIB = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 CPPSRCS = \
   ChromeWorkerScope.cpp \
   DOMBindingBase.cpp \
   Events.cpp \
   EventListenerManager.cpp \
   EventTarget.cpp \
   Exceptions.cpp \
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -504,22 +504,16 @@ BEGIN_WORKERS_NAMESPACE
 
 // Entry point for the DOM.
 JSBool
 ResolveWorkerClasses(JSContext* aCx, JSHandleObject aObj, JSHandleId aId, unsigned aFlags,
                      JSMutableHandleObject aObjp)
 {
   AssertIsOnMainThread();
 
-  // Don't care about assignments, bail now.
-  if (aFlags & JSRESOLVE_ASSIGNING) {
-    aObjp.set(nullptr);
-    return true;
-  }
-
   // Make sure our strings are interned.
   if (JSID_IS_VOID(gStringIDs[0])) {
     for (uint32_t i = 0; i < ID_COUNT; i++) {
       JSString* str = JS_InternString(aCx, gStringChars[i]);
       if (!str) {
         while (i) {
           gStringIDs[--i] = JSID_VOID;
         }
--- a/dom/workers/WorkerPrivate.cpp
+++ b/dom/workers/WorkerPrivate.cpp
@@ -75,17 +75,17 @@ using mozilla::MutexAutoLock;
 using mozilla::TimeDuration;
 using mozilla::TimeStamp;
 using mozilla::dom::workers::exceptions::ThrowDOMExceptionForNSResult;
 
 USING_WORKERS_NAMESPACE
 using namespace mozilla::dom::workers::events;
 using namespace mozilla::dom;
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(JsWorkerMallocSizeOf, "js-worker")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(JsWorkerMallocSizeOf)
 
 namespace {
 
 const char gErrorChars[] = "error";
 const char gMessageChars[] = "message";
 
 template <class T>
 class AutoPtrComparator
--- a/dom/workers/test/Makefile.in
+++ b/dom/workers/test/Makefile.in
@@ -36,16 +36,18 @@ MOCHITEST_FILES = \
   test_importScripts.html \
   importScripts_worker.js \
   importScripts_worker_imported1.js \
   importScripts_worker_imported2.js \
   importScripts_worker_imported3.js \
   importScripts_worker_imported4.js \
   test_instanceof.html \
   instanceof_worker.js \
+  test_resolveWorker.html \
+  test_resolveWorker-assignment.html \
   test_json.html \
   json_worker.js \
   test_location.html \
   location_worker.js \
   test_longThread.html \
   longThread_worker.js \
   test_navigator.html \
   navigator_worker.js \
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/test_resolveWorker-assignment.html
@@ -0,0 +1,32 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  </head>
+  <body>
+    <script type="application/javascript">
+      window.Worker = 17; // resolve through assignment
+
+      var desc = Object.getOwnPropertyDescriptor(window, "Worker");
+      ok(typeof desc === "object" && desc !== null, "Worker property must exist");
+
+      is(desc.value, 17, "Overwrite didn't work correctly");
+      // The JSRESOLVE_ASSIGNING flag-check around the "Resolve special classes"
+      // block in nsWindowSH::NewResolve needs to die to enable this.
+      todo_is(desc.enumerable, false,
+              "Initial descriptor was non-enumerable, and [[Put]] changes the " +
+              "property value but not its enumerability");
+      is(desc.configurable, true,
+         "Initial descriptor was configurable, and [[Put]] changes the " +
+         "property value but not its configurability");
+      is(desc.writable, true,
+         "Initial descriptor was writable, and [[Put]] changes the " +
+         "property value but not its writability");
+    </script>
+  </body>
+</html>
new file mode 100644
--- /dev/null
+++ b/dom/workers/test/test_resolveWorker.html
@@ -0,0 +1,31 @@
+<!--
+  Any copyright is dedicated to the Public Domain.
+  http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<!DOCTYPE html>
+<html>
+  <head>
+    <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+  </head>
+  <body>
+    <script type="application/javascript">
+      window.Worker; // resolve not through assignment
+      Worker = 17;
+
+      var desc = Object.getOwnPropertyDescriptor(window, "Worker");
+      ok(typeof desc === "object" && desc !== null, "Worker property must exist");
+
+      is(desc.value, 17, "Overwrite didn't work correctly");
+      is(desc.enumerable, false,
+         "Initial descriptor was non-enumerable, and [[Put]] changes the " +
+         "property value but not its enumerability");
+      is(desc.configurable, true,
+         "Initial descriptor was configurable, and [[Put]] changes the " +
+         "property value but not its configurability");
+      is(desc.writable, true,
+         "Initial descriptor was writable, and [[Put]] changes the " +
+         "property value but not its writability");
+    </script>
+  </body>
+</html>
--- a/editor/composer/src/Makefile.in
+++ b/editor/composer/src/Makefile.in
@@ -2,26 +2,28 @@
 # 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/.
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
-FAIL_ON_WARNINGS = 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= editor
 LIBRARY_NAME	= composer
 EXPORT_LIBRARY = 1
 IS_COMPONENT	= 1
 MODULE_NAME	= nsComposerModule
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 
 CPPSRCS  = \
            nsComposeTxtSrvFilter.cpp            \
            nsComposerController.cpp       \
            nsComposerCommands.cpp         \
            nsComposerDocumentCommands.cpp \
            nsComposerRegistration.cpp     \
--- a/editor/libeditor/base/Makefile.in
+++ b/editor/libeditor/base/Makefile.in
@@ -2,25 +2,27 @@
 # 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/.
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
-FAIL_ON_WARNINGS = 1
 
 include $(DEPTH)/config/autoconf.mk
 
 TEST_DIRS += tests
 
 MODULE		= editor
 LIBRARY_NAME	= editorbase_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 
 # Internal header files, needed by other editor sublibs:
 INTERNAL_HDR_DIR = ../internal
 
 CPPSRCS		=                           \
 		nsEditor.cpp                \
 		nsEditorCommands.cpp        \
--- a/extensions/spellcheck/hunspell/src/mozHunspell.cpp
+++ b/extensions/spellcheck/hunspell/src/mozHunspell.cpp
@@ -93,17 +93,17 @@ NS_INTERFACE_MAP_END
 NS_IMPL_CYCLE_COLLECTION_3(mozHunspell,
                            mPersonalDictionary,
                            mEncoder,
                            mDecoder)
 
 // Memory reporting stuff.
 static int64_t gHunspellAllocatedSize = 0;
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_ALLOC_FUN(HunspellMallocSizeOfOnAlloc, "hunspell")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_ALLOC_FUN(HunspellMallocSizeOfOnAlloc)
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_FREE_FUN(HunspellMallocSizeOfOnFree)
 
 void HunspellReportMemoryAllocation(void* ptr) {
   gHunspellAllocatedSize += HunspellMallocSizeOfOnAlloc(ptr);
 }
 void HunspellReportMemoryDeallocation(void* ptr) {
   gHunspellAllocatedSize -= HunspellMallocSizeOfOnFree(ptr);
 }
--- a/gfx/gl/Makefile.in
+++ b/gfx/gl/Makefile.in
@@ -8,17 +8,19 @@ srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= gl
 LIBRARY_NAME	= gl
 LIBXUL_LIBRARY	= 1
 EXPORT_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 EXPORTS	= \
 	GLDefs.h \
 	GLContext.h \
 	GLContextTypes.h \
 	GLContextSymbols.h \
 	GLContextProvider.h \
 	GLContextProviderImpl.h \
--- a/gfx/src/Makefile.in
+++ b/gfx/src/Makefile.in
@@ -12,17 +12,19 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE         = gfx
 MODULE_NAME    = nsGfxModule
 LIBRARY_NAME   = gkgfx
 EXPORT_LIBRARY = 1
 GRE_MODULE     = 1
 LIBXUL_LIBRARY = 1
 IS_COMPONENT   = 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 XPIDLSRCS = \
 	nsIFontEnumerator.idl \
 	nsIScriptableRegion.idl \
 	$(NULL)
 
 EXPORTS	= \
 	gfxCore.h \
--- a/gfx/thebes/gfxAndroidPlatform.cpp
+++ b/gfx/thebes/gfxAndroidPlatform.cpp
@@ -41,17 +41,17 @@ GetFreetypeSize()
 NS_MEMORY_REPORTER_IMPLEMENT(Freetype,
     "explicit/freetype",
     KIND_HEAP,
     UNITS_BYTES,
     GetFreetypeSize,
     "Memory used by Freetype."
 )
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_ALLOC_FUN(FreetypeMallocSizeOfOnAlloc, "freetype")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_ALLOC_FUN(FreetypeMallocSizeOfOnAlloc)
 NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_FREE_FUN(FreetypeMallocSizeOfOnFree)
 
 static void*
 CountingAlloc(FT_Memory memory, long size)
 {
     void *p = malloc(size);
     sFreetypeMemoryUsed += FreetypeMallocSizeOfOnAlloc(p);
     return p;
--- a/gfx/thebes/gfxFont.cpp
+++ b/gfx/thebes/gfxFont.cpp
@@ -1124,17 +1124,17 @@ gfxFontFamily::SizeOfIncludingThis(nsMal
  * Expires unused fonts after a short interval;
  * notifies fonts to age their cached shaped-word records;
  * observes memory-pressure notification and tells fonts to clear their
  * shaped-word caches to free up memory.
  */
 
 NS_IMPL_ISUPPORTS1(gfxFontCache::MemoryReporter, nsIMemoryMultiReporter)
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontCacheMallocSizeOf, "font-cache")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontCacheMallocSizeOf)
 
 NS_IMETHODIMP
 gfxFontCache::MemoryReporter::GetName(nsACString &aName)
 {
     aName.AssignLiteral("font-cache");
     return NS_OK;
 }
 
--- a/gfx/thebes/gfxPlatformFontList.cpp
+++ b/gfx/thebes/gfxPlatformFontList.cpp
@@ -67,17 +67,17 @@ gfxFontListPrefObserver::Observe(nsISupp
     // but it probably isn't that big a deal.
     gfxPlatformFontList::PlatformFontList()->ClearPrefFonts();
     gfxFontCache::GetCache()->AgeAllGenerations();
     return NS_OK;
 }
 
 NS_IMPL_ISUPPORTS1(gfxPlatformFontList::MemoryReporter, nsIMemoryMultiReporter)
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontListMallocSizeOf, "font-list")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(FontListMallocSizeOf)
 
 NS_IMETHODIMP
 gfxPlatformFontList::MemoryReporter::GetName(nsACString &aName)
 {
     aName.AssignLiteral("font-list");
     return NS_OK;
 }
 
--- a/image/build/Makefile.in
+++ b/image/build/Makefile.in
@@ -12,17 +12,19 @@ include $(DEPTH)/config/autoconf.mk
 
 MODULE		= imglib2
 LIBRARY_NAME	= imglib2
 EXPORT_LIBRARY = 1
 IS_COMPONENT	= 1
 MODULE_NAME	= nsImageLib2Module
 GRE_MODULE	= 1
 LIBXUL_LIBRARY = 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 CPPSRCS = \
 		nsImageModule.cpp \
 		$(NULL)
 
 LOCAL_INCLUDES	= \
 		-I. \
 		-I$(srcdir)/../src \
--- a/image/src/Makefile.in
+++ b/image/src/Makefile.in
@@ -11,17 +11,19 @@ VPATH		= @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= imglib2
 LIBRARY_NAME	= imglib2_s
 FORCE_STATIC_LIB = 1
 MODULE_NAME	= nsImageLib2Module
 GRE_MODULE	= 1
 LIBXUL_LIBRARY  = 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 
 EXPORTS		=  imgLoader.h \
 		   imgRequest.h \
 		   imgRequestProxy.h \
 		   $(NULL)
 
 CPPSRCS		= \
--- a/image/src/imgLoader.cpp
+++ b/image/src/imgLoader.cpp
@@ -59,17 +59,17 @@
 #include "nsIChannelPolicy.h"
 #include "nsILoadContext.h"
 
 #include "nsContentUtils.h"
 
 using namespace mozilla;
 using namespace mozilla::image;
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ImagesMallocSizeOf, "images")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(ImagesMallocSizeOf)
 
 class imgMemoryReporter MOZ_FINAL :
   public nsIMemoryMultiReporter
 {
 public:
   imgMemoryReporter()
   {
   }
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -2524,17 +2524,17 @@ sandbox_resolve(JSContext *cx, HandleObj
 {
     jsval v;
     JSBool b, resolved;
 
     if (!JS_GetProperty(cx, obj, "lazy", &v))
         return false;
 
     JS_ValueToBoolean(cx, v, &b);
-    if (b && (flags & JSRESOLVE_ASSIGNING) == 0) {
+    if (b) {
         if (!JS_ResolveStandardClass(cx, obj, id, &resolved))
             return false;
         if (resolved) {
             objp.set(obj);
             return true;
         }
     }
     objp.set(NULL);
@@ -4578,19 +4578,16 @@ env_enumerate(JSContext *cx, HandleObjec
 
 static JSBool
 env_resolve(JSContext *cx, HandleObject obj, HandleId id, unsigned flags,
             MutableHandleObject objp)
 {
     JSString *valstr;
     const char *name, *value;
 
-    if (flags & JSRESOLVE_ASSIGNING)
-        return true;
-
     IdStringifier idstr(cx, id, true);
     if (idstr.threw())
         return false;
 
     name = idstr.getBytes();
     value = getenv(name);
     if (value) {
         valstr = JS_NewStringCopyZ(cx, value);
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -940,19 +940,16 @@ env_enumerate(JSContext *cx, JSHandleObj
 }
 
 static JSBool
 env_resolve(JSContext *cx, JSHandleObject obj, JSHandleId id, unsigned flags,
             JSMutableHandleObject objp)
 {
     JSString *idstr, *valstr;
 
-    if (flags & JSRESOLVE_ASSIGNING)
-        return true;
-
     jsval idval;
     if (!JS_IdToValue(cx, id, &idval))
         return false;
 
     idstr = JS_ValueToString(cx, idval);
     if (!idstr)
         return false;
     JSAutoByteString name(cx, idstr);
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -1477,17 +1477,17 @@ NS_MEMORY_REPORTER_IMPLEMENT(XPConnectJS
         nsresult rv;                                                          \
         rv = cb->Callback(EmptyCString(), _path, _kind,                       \
                           nsIMemoryReporter::UNITS_BYTES, amount,             \
                           NS_LITERAL_CSTRING(_desc), closure);                \
         NS_ENSURE_SUCCESS(rv, rv);                                            \
         rtTotal += amount;                                                    \
     } while (0)
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(JsMallocSizeOf, "js")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(JsMallocSizeOf)
 
 namespace xpc {
 
 static nsresult
 ReportCompartmentStats(const JS::CompartmentStats &cStats,
                        const nsACString &cJSPathPrefix,
                        const nsACString &cDOMPathPrefix,
                        nsIMemoryMultiReporterCallback *cb,
@@ -1974,26 +1974,26 @@ class JSCompartmentsMultiReporter MOZ_FI
         return NS_OK;
     }
 };
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(JSCompartmentsMultiReporter
                               , nsIMemoryMultiReporter
                               )
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(OrphanSizeOf, "orphans")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(OrphanMallocSizeOf)
 
 namespace xpc {
 
 static size_t
 SizeOfTreeIncludingThis(nsINode *tree)
 {       
-    size_t n = tree->SizeOfIncludingThis(OrphanSizeOf);
+    size_t n = tree->SizeOfIncludingThis(OrphanMallocSizeOf);
     for (nsIContent* child = tree->GetFirstChild(); child; child = child->GetNextNode(tree)) {
-        n += child->SizeOfIncludingThis(OrphanSizeOf);
+        n += child->SizeOfIncludingThis(OrphanMallocSizeOf);
     }   
     return n;
 }
 
 class OrphanReporter : public JS::ObjectPrivateVisitor
 {
 public:
     OrphanReporter()
--- a/layout/base/Makefile.in
+++ b/layout/base/Makefile.in
@@ -12,17 +12,19 @@ include $(DEPTH)/config/autoconf.mk
 
 TEST_DIRS += tests
 
 MODULE		= layout
 XPIDL_MODULE	= layout_base
 GRE_MODULE	= 1
 LIBRARY_NAME	= gkbase_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 
 
 XPIDLSRCS	= \
 		nsIStyleSheetService.idl	\
 		$(NULL)
 
 EXPORTS_NAMESPACES = mozilla
--- a/layout/base/nsStyleSheetService.cpp
+++ b/layout/base/nsStyleSheetService.cpp
@@ -16,18 +16,17 @@
 #include "nsIServiceManager.h"
 #include "nsICategoryManager.h"
 #include "nsISupportsPrimitives.h"
 #include "nsNetUtil.h"
 #include "nsIObserverService.h"
 #include "nsLayoutStatics.h"
 #include "nsIMemoryReporter.h"
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(LayoutStyleSheetServiceMallocSizeOf,
-                                     "layout/style-sheet-service")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(LayoutStyleSheetServiceMallocSizeOf)
 
 static int64_t
 GetStyleSheetServiceSize()
 {
   return nsStyleSheetService::SizeOfIncludingThis(
            LayoutStyleSheetServiceMallocSizeOf);
 }
 
--- a/layout/build/Makefile.in
+++ b/layout/build/Makefile.in
@@ -17,17 +17,19 @@ endif
 
 MODULE		= layout
 LIBRARY_NAME	= gklayout
 EXPORT_LIBRARY = 1
 IS_COMPONENT	= 1
 MODULE_NAME	= nsLayoutModule
 GRE_MODULE	= 1
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 
 CPPSRCS		= \
 		nsLayoutModule.cpp \
 		nsContentDLF.cpp \
 		nsLayoutStatics.cpp \
 		$(NULL)
 
--- a/layout/forms/Makefile.in
+++ b/layout/forms/Makefile.in
@@ -13,17 +13,19 @@ include $(DEPTH)/config/autoconf.mk
 DIRS = $(NULL)
 
 TEST_DIRS += test
 
 MODULE		= layout
 XPIDL_MODULE	= layout_forms
 LIBRARY_NAME	= gkforms_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 XPIDLSRCS       = nsICapturePicker.idl
 
 EXPORTS		= \
 		nsIListControlFrame.h \
 		nsIComboboxControlFrame.h \
 		nsIFormControlFrame.h \
 		nsISelectControlFrame.h \
--- a/layout/generic/Makefile.in
+++ b/layout/generic/Makefile.in
@@ -9,17 +9,19 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 TEST_DIRS += test
 
 MODULE		= layout
 LIBRARY_NAME	= gkgeneric_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 EXPORTS		= \
 		nsQueryFrame.h \
 		nsFrameIdList.h \
 		nsFrameList.h \
 		nsCanvasFrame.h \
 		nsHTMLParts.h \
 		nsHTMLReflowMetrics.h \
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -2082,18 +2082,18 @@ nsGfxScrollFrameInner::BuildDisplayList(
   // CompositorParent can always find the scrollable layer for the root content
   // document.
   if (usingDisplayport) {
     mShouldBuildLayer = true;
   } else {
     nsRect scrollRange = GetScrollRange();
     ScrollbarStyles styles = GetScrollbarStylesFromFrame();
     mShouldBuildLayer =
-       (styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN ||
-        styles.mVertical != NS_STYLE_OVERFLOW_HIDDEN) &&
+       ((styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN && mHScrollbarBox) ||
+        (styles.mVertical   != NS_STYLE_OVERFLOW_HIDDEN && mVScrollbarBox)) &&
        (XRE_GetProcessType() == GeckoProcessType_Content &&
         (scrollRange.width > 0 || scrollRange.height > 0) &&
         (!mIsRoot || !mOuter->PresContext()->IsRootContentDocument()));
   }
 
   nsRect clip;
   nscoord radii[8];
 
--- a/layout/ipc/Makefile.in
+++ b/layout/ipc/Makefile.in
@@ -9,17 +9,19 @@ VPATH = @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = layout
 LIBRARY_NAME = gkipc_s
 LIBXUL_LIBRARY = 1
 FORCE_STATIC_LIB = 1
 EXPORT_LIBRARY = 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 EXPORTS_NAMESPACES = mozilla/layout
 
 EXPORTS_mozilla/layout = \
   RenderFrameChild.h \
   RenderFrameParent.h \
   RenderFrameUtils.h \
   $(NULL)
--- a/layout/mathml/Makefile.in
+++ b/layout/mathml/Makefile.in
@@ -9,17 +9,19 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE = layout
 LIBRARY_NAME = gkmathml_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 
 LOCAL_INCLUDES = \
 	-I$(srcdir)/../style \
 	-I$(srcdir)/../base \
 	-I$(srcdir)/../generic \
 	-I$(srcdir)/../tables \
 	-I$(topsrcdir)/content/base/src \
--- a/layout/printing/Makefile.in
+++ b/layout/printing/Makefile.in
@@ -9,17 +9,19 @@ VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= layout
 XPIDL_MODULE	= layout_printing
 GRE_MODULE	= 1
 LIBRARY_NAME	= gkprinting_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 XPIDLSRCS	= \
 		nsIPrintProgress.idl  \
 		nsIPrintProgressParams.idl  \
 		nsIPrintStatusFeedback.idl  \
 		$(NULL)
 
 CPPSRCS		= \
--- a/layout/style/nsLayoutStylesheetCache.cpp
+++ b/layout/style/nsLayoutStylesheetCache.cpp
@@ -11,18 +11,17 @@
 #include "nsLayoutCID.h"
 #include "nsIMemoryReporter.h"
 #include "nsNetUtil.h"
 #include "nsIObserverService.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIXULRuntime.h"
 #include "nsCSSStyleSheet.h"
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(LayoutStyleSheetCacheMallocSizeOf,
-                                     "layout/style-sheet-cache")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(LayoutStyleSheetCacheMallocSizeOf)
 
 static int64_t
 GetStylesheetCacheSize()
 {
   return nsLayoutStylesheetCache::SizeOfIncludingThis(
            LayoutStyleSheetCacheMallocSizeOf);
 }
 
--- a/layout/svg/Makefile.in
+++ b/layout/svg/Makefile.in
@@ -8,17 +8,19 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= layout
 LIBRARY_NAME	= gksvgbase_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 
 CPPSRCS		= \
 		nsSVGAFrame.cpp \
 		nsSVGClipPathFrame.cpp \
 		nsSVGContainerFrame.cpp \
 		nsSVGEffects.cpp \
 		SVGFEContainerFrame.cpp \
--- a/layout/tables/Makefile.in
+++ b/layout/tables/Makefile.in
@@ -8,17 +8,19 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= layout
 LIBRARY_NAME	= gktable_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 
 
 EXPORTS		= \
 		nsITableCellLayout.h \
 		$(NULL)
 
 CPPSRCS		= \
--- a/layout/tools/reftest/remotereftest.py
+++ b/layout/tools/reftest/remotereftest.py
@@ -315,18 +315,19 @@ class RemoteReftest(RefTest):
 
         # Turn off the locale picker screen
         fhandle = open(os.path.join(profileDir, "user.js"), 'a')
         fhandle.write("""
 user_pref("browser.firstrun.show.localepicker", false);
 user_pref("font.size.inflation.emPerLine", 0);
 user_pref("font.size.inflation.minTwips", 0);
 user_pref("reftest.remote", true);
-#expand user_pref("toolkit.telemetry.prompted", __MOZ_TELEMETRY_DISPLAY_REV__);
-#expand user_pref("toolkit.telemetry.notifiedOptOut", __MOZ_TELEMETRY_DISPLAY_REV__);
+// Set a future policy version to avoid the telemetry prompt.
+user_pref("toolkit.telemetry.prompted", 999);
+user_pref("toolkit.telemetry.notifiedOptOut", 999);
 user_pref("reftest.uri", "%s");
 """ % reftestlist)
 
         #workaround for jsreftests.
         if options.enablePrivilege:
             fhandle.write("""
 user_pref("capability.principal.codebase.p2.granted", "UniversalXPConnect");
 user_pref("capability.principal.codebase.p2.id", "http://%s:%s");
--- a/layout/tools/reftest/runreftestb2g.py
+++ b/layout/tools/reftest/runreftestb2g.py
@@ -400,18 +400,19 @@ user_pref("dom.ipc.tabs.disabled", false
 user_pref("dom.mozBrowserFramesEnabled", true);\n
 user_pref("dom.mozBrowserFramesWhitelist","app://system.gaiamobile.org");\n
 user_pref("network.dns.localDomains","app://system.gaiamobile.org");\n
 user_pref("font.size.inflation.emPerLine", 0);
 user_pref("font.size.inflation.minTwips", 0);
 user_pref("reftest.browser.iframe.enabled", true);
 user_pref("reftest.remote", true);
 user_pref("reftest.uri", "%s");
-#expand user_pref("toolkit.telemetry.prompted", __MOZ_TELEMETRY_DISPLAY_REV__);
-#expand user_pref("toolkit.telemetry.notifiedOptOut", __MOZ_TELEMETRY_DISPLAY_REV__);
+// Set a future policy version to avoid the telemetry prompt.
+user_pref("toolkit.telemetry.prompted", 999);
+user_pref("toolkit.telemetry.notifiedOptOut", 999);
 user_pref("marionette.loadearly", true);
 """ % reftestlist)
 
         #workaround for jsreftests.
         if getattr(options, 'enablePrivilege', False):
             fhandle.write("""
 user_pref("capability.principal.codebase.p2.granted", "UniversalXPConnect");
 user_pref("capability.principal.codebase.p2.id", "http://%s:%s");
--- a/layout/xul/base/src/Makefile.in
+++ b/layout/xul/base/src/Makefile.in
@@ -8,17 +8,19 @@ topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= layout
 LIBRARY_NAME	= gkxulbase_s
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 
 ifdef MOZ_XUL
 PARALLEL_DIRS = tree/public tree/src grid
 endif
 
 CPPSRCS		= \
 		nsScrollBoxFrame.cpp \
--- a/mfbt/Attributes.h
+++ b/mfbt/Attributes.h
@@ -105,25 +105,25 @@
 #      if __GNUC_MINOR__ >= 7
 #        define MOZ_HAVE_CXX11_FINAL     __final
 #      endif
 #    endif
 #  endif
 #  define MOZ_HAVE_NEVER_INLINE          __attribute__((noinline))
 #  define MOZ_HAVE_NORETURN              __attribute__((noreturn))
 #elif defined(_MSC_VER)
-#  if _MSC_VER >= 1400
-#    define MOZ_HAVE_CXX11_OVERRIDE
-     /* MSVC currently spells "final" as "sealed". */
+#  if _MSC_VER >= 1700
+#    define MOZ_HAVE_CXX11_FINAL         final
+#    define MOZ_HAVE_CXX11_STRONG_ENUMS
+#  else
+     /* MSVC <= 10 used to spell "final" as "sealed". */
 #    define MOZ_HAVE_CXX11_FINAL         sealed
-#    define MOZ_HAVE_CXX11_ENUM_TYPE
 #  endif
-#  if _MSC_VER >= 1700
-#    define MOZ_HAVE_CXX11_STRONG_ENUMS
-#  endif
+#  define MOZ_HAVE_CXX11_OVERRIDE
+#  define MOZ_HAVE_CXX11_ENUM_TYPE
 #  define MOZ_HAVE_NEVER_INLINE          __declspec(noinline)
 #  define MOZ_HAVE_NORETURN              __declspec(noreturn)
 #endif
 
 /*
  * MOZ_NEVER_INLINE is a macro which expands to tell the compiler that the
  * method decorated with it must never be inlined, even if the compiler would
  * otherwise choose to inline the method.  Compilers aren't absolutely
new file mode 100644
--- /dev/null
+++ b/mfbt/Char16.h
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+/* Implements a UTF-16 character type. */
+
+#ifndef mozilla_Char16_h_
+#define mozilla_Char16_h_
+
+#include "mozilla/Assertions.h"
+
+/*
+ * C11 and C++11 introduce a char16_t type and support for UTF-16 string and
+ * character literals. C++11's char16_t is a distinct builtin type. C11's
+ * char16_t is a typedef for uint_least16_t. Technically, char16_t is a 16-bit
+ * code unit of a Unicode code point, not a "character".
+ *
+ * For now, Char16.h only supports C++ because we don't want mix different C
+ * and C++ definitions of char16_t in the same code base.
+ */
+
+#ifdef _MSC_VER
+   /*
+    * C++11 says char16_t is a distinct builtin type, but Windows's yvals.h
+    * typedefs char16_t as an unsigned short. We would like to alias char16_t
+    * to Windows's 16-bit wchar_t so we can declare UTF-16 literals as constant
+    * expressions (and pass char16_t pointers to Windows APIs). We #define our
+    * char16_t as a macro to override yval.h's typedef of the same name.
+    */
+#  define MOZ_UTF16(s) L##s
+#  include <yvals.h>
+#  define char16_t wchar_t
+#elif defined(__cplusplus) && \
+      (__cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__))
+   /* C++11 has a builtin char16_t type. */
+#  define MOZ_UTF16(s) u##s
+#else
+#  error "Char16.h requires C++11 (or something like it) for UTF-16 support."
+#endif
+
+MOZ_STATIC_ASSERT(sizeof(char16_t) == 2, "Is char16_t type 16 bits?");
+MOZ_STATIC_ASSERT(sizeof(MOZ_UTF16('A')) == 2, "Is char literal 16 bits?");
+MOZ_STATIC_ASSERT(sizeof(MOZ_UTF16("")[0]) == 2, "Is string char 16 bits?");
+
+#endif /* mozilla_Char16_h_ */
--- a/mfbt/exported_headers.mk
+++ b/mfbt/exported_headers.mk
@@ -7,16 +7,17 @@
 # mfbt's exported headers itself.
 
 EXPORTS_NAMESPACES += mozilla
 
 EXPORTS_mozilla += \
   Assertions.h \
   Attributes.h \
   BloomFilter.h \
+  Char16.h \
   CheckedInt.h \
   Constants.h \
   DebugOnly.h \
   EnumSet.h \
   FloatingPoint.h \
   GuardObjects.h \
   HashFunctions.h \
   Likely.h \
--- a/mobile/android/base/AboutHomeContent.java
+++ b/mobile/android/base/AboutHomeContent.java
@@ -19,16 +19,17 @@ import org.mozilla.gecko.util.GeckoAsync
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 
 import android.accounts.Account;
 import android.accounts.AccountManager;
 import android.accounts.OnAccountsUpdateListener;
+import android.app.Activity;
 import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -248,20 +249,21 @@ public class AboutHomeContent extends Sc
     }
 
     public void onDestroy() {
         if (mAccountListener != null) {
             mAccountManager.removeOnAccountsUpdatedListener(mAccountListener);
             mAccountListener = null;
         }
 
-        Cursor cursor = mTopSitesAdapter.getCursor();
-        if (cursor != null && !cursor.isClosed())
-            cursor.close();
-
+        if (mTopSitesAdapter != null) {
+            Cursor cursor = mTopSitesAdapter.getCursor();
+            if (cursor != null && !cursor.isClosed())
+                cursor.close();
+        }
     }
 
     void setLastTabsVisibility(boolean visible) {
         if (visible)
             mLastTabs.show();
         else
             mLastTabs.hide();
     }
@@ -975,25 +977,27 @@ public class AboutHomeContent extends Sc
         intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
         intent.putExtra(AwesomeBar.TARGET_KEY, AwesomeBar.Target.PICK_SITE.toString());
         if (url != null && !TextUtils.isEmpty(url)) {
             intent.putExtra(AwesomeBar.CURRENT_URL_KEY, url);
         }
 
         int requestCode = GeckoAppShell.sActivityHelper.makeRequestCode(new ActivityResultHandler() {
             public void onActivityResult(int resultCode, Intent data) {
+                if (resultCode == Activity.RESULT_CANCELED || data == null)
+                    return;
+
                 final String title = data.getStringExtra(AwesomeBar.TITLE_KEY);
                 final String url = data.getStringExtra(AwesomeBar.URL_KEY);
 
                 // update the database on a background thread
                 (new GeckoAsyncTask<Void, Void, Void>(GeckoApp.mAppContext, GeckoAppShell.getHandler()) {
                     @Override
                     public Void doInBackground(Void... params) {
                         final ContentResolver resolver = mActivity.getContentResolver();
-                        Log.i(LOGTAG, "Pin : " + url + " and " + title);
                         BrowserDB.pinSite(resolver, url, (title == null ? url : title), position);
                         return null;
                     }
         
                     @Override
                     public void onPostExecute(Void v) {
                         update(EnumSet.of(UpdateFlags.TOP_SITES));
                     }
--- a/mobile/android/base/TabsPanel.java
+++ b/mobile/android/base/TabsPanel.java
@@ -242,16 +242,17 @@ public class TabsPanel extends TabHost
             case R.id.synced_tabs:
                 show(Panel.REMOTE_TABS);
                 return true;
 
             case R.id.close_all_tabs:
                 for (Tab tab : Tabs.getInstance().getTabsInOrder()) {
                     Tabs.getInstance().closeTab(tab);
                 }
+                autoHidePanel();
                 return true;
 
             case R.id.new_tab:
             case R.id.new_private_tab:
                 hide();
             // fall through
             default:
                 return mActivity.onOptionsItemSelected(item);
--- a/mobile/android/base/WebAppManifestFragment.xml.frag
+++ b/mobile/android/base/WebAppManifestFragment.xml.frag
@@ -1,13 +1,13 @@
         <activity android:name=".WebApps$WebApp@APPNUM@"
                   android:label="@string/webapp_generic_name"
                   android:configChanges="keyboard|keyboardHidden|mcc|mnc|orientation|screenSize"
                   android:windowSoftInputMode="stateUnspecified|adjustResize"
-                  android:launchMode="singleInstance"
+                  android:launchMode="singleTask"
                   android:taskAffinity="org.mozilla.gecko.WEBAPP@APPNUM@"
                   android:process=":@ANDROID_PACKAGE_NAME@.WebApp@APPNUM@"
                   android:theme="@style/Gecko.App">
             <intent-filter>
                 <action android:name="org.mozilla.gecko.WEBAPP@APPNUM@" />
             </intent-filter>
             <intent-filter>
                 <action android:name="org.mozilla.gecko.ACTION_ALERT_CALLBACK" />
--- a/mobile/android/base/db/BrowserDB.java
+++ b/mobile/android/base/db/BrowserDB.java
@@ -310,16 +310,17 @@ public class BrowserDB {
             if (c != null && c.getCount() > 0) {
                 c.moveToPosition(0);
                 do {
                     int pos = c.getInt(c.getColumnIndex(Bookmarks.POSITION));
                     String url = c.getString(c.getColumnIndex(URLColumns.URL));
                     String title = c.getString(c.getColumnIndex(URLColumns.TITLE));
                     mPinnedSites.put(pos, new PinnedSite(title, url));
                 } while (c.moveToNext());
+                c.close();
             }
         }
 
         public boolean hasPinnedSites() {
             return mPinnedSites != null && mPinnedSites.size() > 0;
         }
 
         public PinnedSite getPinnedSite(int position) {
--- a/mobile/android/chrome/content/WebAppRT.js
+++ b/mobile/android/chrome/content/WebAppRT.js
@@ -21,19 +21,19 @@ var WebAppRT = {
 
   prefs: [
     // Disable all add-on locations other than the profile (which can't be disabled this way)
     pref("extensions.enabledScopes", 1),
     // Auto-disable any add-ons that are "dropped in" to the profile
     pref("extensions.autoDisableScopes", 1),
     // Disable add-on installation via the web-exposed APIs
     pref("xpinstall.enabled", false),
-    // Disable the telemetry prompt in webapps
-#expand pref("toolkit.telemetry.prompted", __MOZ_TELEMETRY_DISPLAY_REV__),
-#expand pref("toolkit.telemetry.notifiedOptOut", __MOZ_TELEMETRY_DISPLAY_REV__)
+    // Set a future policy version to avoid the telemetry prompt.
+    pref("toolkit.telemetry.prompted", 999),
+    pref("toolkit.telemetry.notifiedOptOut", 999)
   ],
 
   init: function(isUpdate, url) {
     this.deck = document.getElementById("browsers");
     this.deck.addEventListener("click", this, false, true);
 
     // on first run, update any prefs
     if (isUpdate == "new") {
--- a/mobile/android/chrome/content/browser.js
+++ b/mobile/android/chrome/content/browser.js
@@ -7278,23 +7278,23 @@ var Telemetry = {
     /*
      * Display an opt-out notification when telemetry is enabled by default,
      * an opt-in prompt otherwise.
      *
      * But do not display this prompt/notification if:
      *
      * - The last accepted/refused policy (either by accepting the prompt or by
      *   manually flipping the telemetry preference) is already at version
-     *   TELEMETRY_DISPLAY_REV.
+     *   TELEMETRY_DISPLAY_REV or higher (to avoid the prompt in tests).
      */
     let telemetryDisplayed;
     try {
       telemetryDisplayed = Services.prefs.getIntPref(self._PREF_TELEMETRY_DISPLAYED);
     } catch(e) {}
-    if (telemetryDisplayed === self._TELEMETRY_DISPLAY_REV)
+    if (telemetryDisplayed >= self._TELEMETRY_DISPLAY_REV)
       return;
 
 #ifdef MOZ_TELEMETRY_ON_BY_DEFAULT
     /*
      * Additionally, in opt-out builds, don't display the notification if:
      *
      * - Telemetry is disabled
      * - Telemetry was explicitly refused through the UI
--- a/mobile/android/config/mozconfigs/android-armv6/debug
+++ b/mobile/android/config/mozconfigs/android-armv6/debug
@@ -4,18 +4,19 @@
 ac_add_options --enable-debug
 
 # Build Fennec
 ac_add_options --enable-application=mobile/android
 
 # Android
 ac_add_options --target=arm-linux-androideabi
 ac_add_options --with-arch=armv6
-ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
+ac_add_options --with-android-ndk="/tools/android-ndk-r8c"
 ac_add_options --with-android-sdk="/tools/android-sdk-r16/platforms/android-16"
+ac_add_options --with-android-gnu-compiler-version=4.6
 ac_add_options --with-android-version=5
 ac_add_options --with-system-zlib
 
 # IonMonkey disabled in bug 789373
 ac_add_options --disable-ion
 
 export JAVA_HOME=/tools/jdk6
 export MOZILLA_OFFICIAL=1
--- a/mobile/android/config/mozconfigs/android-armv6/l10n-nightly
+++ b/mobile/android/config/mozconfigs/android-armv6/l10n-nightly
@@ -10,18 +10,19 @@ ac_add_options --disable-tests
 ac_add_options --enable-js-diagnostics
 
 # Build Fennec
 ac_add_options --enable-application=mobile/android
 
 # Android
 ac_add_options --target=arm-linux-androideabi
 ac_add_options --with-arch=armv6
-ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
+ac_add_options --with-android-ndk="/tools/android-ndk-r8c"
 ac_add_options --with-android-sdk="/tools/android-sdk-r16/platforms/android-16"
+ac_add_options --with-android-gnu-compiler-version=4.6
 ac_add_options --with-android-version=5
 ac_add_options --with-system-zlib
 ac_add_options --enable-updater
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 
 export JAVA_HOME=/tools/jdk6
 export MOZILLA_OFFICIAL=1
 export MOZ_PKG_SPECIAL=armv6
--- a/mobile/android/config/mozconfigs/android-armv6/l10n-release
+++ b/mobile/android/config/mozconfigs/android-armv6/l10n-release
@@ -7,18 +7,19 @@ ac_add_options --with-l10n-base=..
 ac_add_options --disable-tests
 
 # Build Fennec
 ac_add_options --enable-application=mobile/android
 
 # Android
 ac_add_options --target=arm-linux-androideabi
 ac_add_options --with-arch=armv6
-ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
+ac_add_options --with-android-ndk="/tools/android-ndk-r8c"
 ac_add_options --with-android-sdk="/tools/android-sdk-r16/platforms/android-16"
+ac_add_options --with-android-gnu-compiler-version=4.6
 ac_add_options --with-android-version=5
 ac_add_options --with-system-zlib
 ac_add_options --enable-updater
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 
 export JAVA_HOME=/tools/jdk6
 export MOZILLA_OFFICIAL=1
 export MOZ_PKG_SPECIAL=armv6
--- a/mobile/android/config/mozconfigs/android-armv6/nightly
+++ b/mobile/android/config/mozconfigs/android-armv6/nightly
@@ -1,18 +1,19 @@
 . "$topsrcdir/mobile/android/config/mozconfigs/common"
 
 # Build Fennec
 ac_add_options --enable-application=mobile/android
 
 # Android
 ac_add_options --target=arm-linux-androideabi
 ac_add_options --with-arch=armv6
-ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
+ac_add_options --with-android-ndk="/tools/android-ndk-r8c"
 ac_add_options --with-android-sdk="/tools/android-sdk-r16/platforms/android-16"
+ac_add_options --with-android-gnu-compiler-version=4.6
 ac_add_options --with-android-version=5
 ac_add_options --with-system-zlib
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 
 # IonMonkey disabled in bug 789373
 ac_add_options --disable-ion
 
 export JAVA_HOME=/tools/jdk6
--- a/mobile/android/config/mozconfigs/android-armv6/release
+++ b/mobile/android/config/mozconfigs/android-armv6/release
@@ -1,18 +1,19 @@
 . "$topsrcdir/mobile/android/config/mozconfigs/common"
 
 # Build Fennec
 ac_add_options --enable-application=mobile/android
 
 # Android
 ac_add_options --target=arm-linux-androideabi
 ac_add_options --with-arch=armv6
-ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
+ac_add_options --with-android-ndk="/tools/android-ndk-r8c"
 ac_add_options --with-android-sdk="/tools/android-sdk-r16/platforms/android-16"
+ac_add_options --with-android-gnu-compiler-version=4.6
 ac_add_options --with-android-version=5
 ac_add_options --with-system-zlib
 ac_add_options --enable-updater
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 
 # IonMonkey disabled in bug 789373
 ac_add_options --disable-ion
 
--- a/mobile/android/config/mozconfigs/android-noion/nightly
+++ b/mobile/android/config/mozconfigs/android-noion/nightly
@@ -1,17 +1,18 @@
 . "$topsrcdir/mobile/android/config/mozconfigs/common"
 
 # Build Fennec
 ac_add_options --enable-application=mobile/android
 
 # Android
 ac_add_options --target=arm-linux-androideabi
-ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
+ac_add_options --with-android-ndk="/tools/android-ndk-r8c"
 ac_add_options --with-android-sdk="/tools/android-sdk-r16/platforms/android-16"
+ac_add_options --with-android-gnu-compiler-version=4.6
 ac_add_options --with-android-version=5
 ac_add_options --with-system-zlib
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 
 # IonMonkey disabled in bug 789373
 ac_add_options --disable-ion
 
 export JAVA_HOME=/tools/jdk6
--- a/mobile/android/config/mozconfigs/android/debug
+++ b/mobile/android/config/mozconfigs/android/debug
@@ -3,18 +3,19 @@
 # Global options
 ac_add_options --enable-debug
 
 # Build Fennec
 ac_add_options --enable-application=mobile/android
 
 # Android
 ac_add_options --target=arm-linux-androideabi
-ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
+ac_add_options --with-android-ndk="/tools/android-ndk-r8c"
 ac_add_options --with-android-sdk="/tools/android-sdk-r16/platforms/android-16"
+ac_add_options --with-android-gnu-compiler-version=4.6
 ac_add_options --with-android-version=5
 ac_add_options --with-system-zlib
 
 export JAVA_HOME=/tools/jdk6
 export MOZILLA_OFFICIAL=1
 export MOZ_TELEMETRY_REPORTING=1
 
 ac_add_options --with-branding=mobile/android/branding/nightly
--- a/mobile/android/config/mozconfigs/android/l10n-nightly
+++ b/mobile/android/config/mozconfigs/android/l10n-nightly
@@ -9,18 +9,19 @@ ac_add_options --disable-tests
 # Mozilla-Central nightlies only since this has a cost in performance
 ac_add_options --enable-js-diagnostics
 
 # Build Fennec
 ac_add_options --enable-application=mobile/android
 
 # Android
 ac_add_options --target=arm-linux-androideabi
-ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
+ac_add_options --with-android-ndk="/tools/android-ndk-r8c"
 ac_add_options --with-android-sdk="/tools/android-sdk-r16/platforms/android-16"
+ac_add_options --with-android-gnu-compiler-version=4.6
 ac_add_options --with-android-version=5
 ac_add_options --with-system-zlib
 ac_add_options --enable-updater
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 
 export JAVA_HOME=/tools/jdk6
 export MOZILLA_OFFICIAL=1
 
--- a/mobile/android/config/mozconfigs/android/l10n-release
+++ b/mobile/android/config/mozconfigs/android/l10n-release
@@ -6,18 +6,19 @@ ac_add_options --with-l10n-base=..
 # Global options
 ac_add_options --disable-tests
 
 # Build Fennec
 ac_add_options --enable-application=mobile/android
 
 # Android
 ac_add_options --target=arm-linux-androideabi
-ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
+ac_add_options --with-android-ndk="/tools/android-ndk-r8c"
 ac_add_options --with-android-sdk="/tools/android-sdk-r16/platforms/android-16"
+ac_add_options --with-android-gnu-compiler-version=4.6
 ac_add_options --with-android-version=5
 ac_add_options --with-system-zlib
 ac_add_options --enable-updater
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 
 export JAVA_HOME=/tools/jdk6
 export MOZILLA_OFFICIAL=1
 
--- a/mobile/android/config/mozconfigs/android/nightly
+++ b/mobile/android/config/mozconfigs/android/nightly
@@ -1,17 +1,18 @@
 . "$topsrcdir/mobile/android/config/mozconfigs/common"
 
 # Build Fennec
 ac_add_options --enable-application=mobile/android
 
 # Android
 ac_add_options --target=arm-linux-androideabi
-ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
+ac_add_options --with-android-ndk="/tools/android-ndk-r8c"
 ac_add_options --with-android-sdk="/tools/android-sdk-r16/platforms/android-16"
+ac_add_options --with-android-gnu-compiler-version=4.6
 ac_add_options --with-android-version=5
 ac_add_options --with-system-zlib
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 
 export JAVA_HOME=/tools/jdk6
 export MOZILLA_OFFICIAL=1
 export MOZ_TELEMETRY_REPORTING=1
 
--- a/mobile/android/config/mozconfigs/android/release
+++ b/mobile/android/config/mozconfigs/android/release
@@ -1,17 +1,18 @@
 . "$topsrcdir/mobile/android/config/mozconfigs/common"
 
 # Build Fennec
 ac_add_options --enable-application=mobile/android
 
 # Android
 ac_add_options --target=arm-linux-androideabi
-ac_add_options --with-android-ndk="/tools/android-ndk-r5c"
+ac_add_options --with-android-ndk="/tools/android-ndk-r8c"
 ac_add_options --with-android-sdk="/tools/android-sdk-r16/platforms/android-16"
+ac_add_options --with-android-gnu-compiler-version=4.6
 ac_add_options --with-android-version=5
 ac_add_options --with-system-zlib
 ac_add_options --enable-updater
 ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
 
 export JAVA_HOME=/tools/jdk6
 export MOZILLA_OFFICIAL=1
 export MOZ_TELEMETRY_REPORTING=1
--- a/modules/libpref/src/Preferences.cpp
+++ b/modules/libpref/src/Preferences.cpp
@@ -153,17 +153,17 @@ struct CacheData {
     uint32_t defaultValueUint;
   };
 };
 
 static nsTArray<nsAutoPtr<CacheData> >* gCacheData = nullptr;
 static nsRefPtrHashtable<ValueObserverHashKey,
                          ValueObserver>* gObserverTable = nullptr;
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(PreferencesMallocSizeOf, "preferences")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(PreferencesMallocSizeOf)
 
 static size_t
 SizeOfObserverEntryExcludingThis(ValueObserverHashKey* aKey,
                                  const nsRefPtr<ValueObserver>& aData,
                                  nsMallocSizeOfFun aMallocSizeOf,
                                  void*)
 {
   size_t n = 0;
--- a/mozglue/linker/CustomElf.cpp
+++ b/mozglue/linker/CustomElf.cpp
@@ -434,17 +434,17 @@ CustomElf::LoadSegment(const Phdr *pt_lo
    * of the page p_filesz is in, memory is nulled out.
    * Above the end of that page, and up to p_memsz, we already have nulled out
    * memory because we mapped anonymous memory on the whole library virtual
    * address space. We just need to adjust this anonymous memory protection
    * flags. */
   if (pt_load->p_memsz > pt_load->p_filesz) {
     Addr file_end = pt_load->p_vaddr + pt_load->p_filesz;
     Addr mem_end = pt_load->p_vaddr + pt_load->p_memsz;
-    Addr next_page = (file_end & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
+    Addr next_page = (file_end + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
     if (mem_end > next_page) {
       if (mprotect(GetPtr(next_page), mem_end - next_page, prot) < 0) {
         log("%s: Failed to mprotect", GetPath());
         return false;
       }
     }
   }
   return true;
--- a/netwerk/base/src/Makefile.in
+++ b/netwerk/base/src/Makefile.in
@@ -3,23 +3,25 @@
 # 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/.
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= necko
 LIBRARY_NAME	= neckobase_s
 LIBXUL_LIBRARY  = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 EXPORTS = \
 		nsMIMEInputStream.h \
 		nsURLHelper.h \
 		nsFileStreams.h \
 		$(NULL)
 
 EXPORTS_NAMESPACES = mozilla/net
--- a/netwerk/base/src/nsPACMan.cpp
+++ b/netwerk/base/src/nsPACMan.cpp
@@ -363,16 +363,17 @@ nsPACMan::LoadPACFromURI(const nsCString
     mLoadPending = true;
   }
 
   CancelExistingLoad();
 
   mLoader = loader;
   if (!spec.IsEmpty()) {
     mPACURISpec = spec;
+    mPACURIRedirectSpec.Truncate();
     mLoadFailureCount = 0;  // reset
   }
 
   // reset to Null
   mScheduledReload = TimeStamp();
   return NS_OK;
 }
 
@@ -653,20 +654,30 @@ nsPACMan::AsyncOnChannelRedirect(nsIChan
                                  nsIAsyncVerifyRedirectCallback *callback)
 {
   NS_ABORT_IF_FALSE(NS_IsMainThread(), "wrong thread");
   
   nsresult rv = NS_OK;
   nsCOMPtr<nsIURI> pacURI;
   if (NS_FAILED((rv = newChannel->GetURI(getter_AddRefs(pacURI)))))
       return rv;
-  rv = pacURI->GetSpec(mPACURISpec);
+
+  rv = pacURI->GetSpec(mPACURIRedirectSpec);
   if (NS_FAILED(rv))
       return rv;
 
+  LOG(("nsPACMan redirect from original %s to redirected %s\n",
+       mPACURISpec.get(), mPACURIRedirectSpec.get()));
+
+  // do not update mPACURISpec - that needs to stay as the
+  // configured URI so that we can determine when the config changes.
+  // However do track the most recent URI in the redirect change
+  // as mPACURIRedirectSpec so that URI can be allowed to bypass
+  // the proxy and actually fetch the pac file.
+
   callback->OnRedirectVerifyCallback(NS_OK);
   return NS_OK;
 }
 
 void
 nsPACMan::NamePACThread()
 {
   NS_ABORT_IF_FALSE(!NS_IsMainThread(), "wrong thread");
--- a/netwerk/base/src/nsPACMan.h
+++ b/netwerk/base/src/nsPACMan.h
@@ -122,32 +122,37 @@ public:
   nsresult LoadPACFromURI(const nsCString &pacSpec);
 
   /**
    * Returns true if we are currently loading the PAC file.
    */
   bool IsLoading() { return mLoader != nullptr; }
 
   /**
-   * Returns true if the given URI matches the URI of our PAC file.
+   * Returns true if the given URI matches the URI of our PAC file or the
+   * URI it has been redirected to. In the case of a chain of redirections
+   * only the current one being followed and the original are considered
+   * becuase this information is used, respectively, to determine if we
+   * should bypass the proxy (to fetch the pac file) or if the pac
+   * configuration has changed (and we should reload the pac file)
    */
+  bool IsPACURI(const nsACString &spec)
+  {
+    return mPACURISpec.Equals(spec) || mPACURIRedirectSpec.Equals(spec);
+  }
+
   bool IsPACURI(nsIURI *uri) {
-    if (mPACURISpec.IsEmpty())
+    if (mPACURISpec.IsEmpty() && mPACURIRedirectSpec.IsEmpty())
       return false;
 
     nsAutoCString tmp;
     uri->GetSpec(tmp);
     return IsPACURI(tmp);
   }
 
-  bool IsPACURI(const nsACString &spec)
-  {
-    return mPACURISpec.Equals(spec);
-  }
-
   NS_HIDDEN_(nsresult) Init(nsISystemProxySettings *);
   static nsPACMan *sInstance;
 
   // PAC thread operations only
   void ProcessPendingQ();
   void CancelPendingQ(nsresult);
 
 private:
@@ -197,16 +202,17 @@ private:
 private:
   mozilla::net::ProxyAutoConfig mPAC;
   nsCOMPtr<nsIThread>           mPACThread;
   nsCOMPtr<nsISystemProxySettings> mSystemProxySettings;
 
   mozilla::LinkedList<PendingPACQuery> mPendingQ; /* pac thread only */
 
   nsCString                    mPACURISpec; // Not an nsIRUI for use off main thread
+  nsCString                    mPACURIRedirectSpec;
   nsCOMPtr<nsIStreamLoader>    mLoader;
   bool                         mLoadPending;
   bool                         mShutdown;
   mozilla::TimeStamp           mScheduledReload;
   uint32_t                     mLoadFailureCount;
 
   bool                         mInProgress;
 };
--- a/netwerk/build/Makefile.in
+++ b/netwerk/build/Makefile.in
@@ -2,27 +2,29 @@
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE         = necko
 LIBRARY_NAME   = necko
 EXPORT_LIBRARY = 1
 IS_COMPONENT   = 1
 MODULE_NAME    = necko
 GRE_MODULE     = 1
 LIBXUL_LIBRARY = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 CPPSRCS = nsNetModule.cpp
 EXPORTS = nsNetCID.h
 
 SHARED_LIBRARY_LIBS = \
   ../base/src/$(LIB_PREFIX)neckobase_s.$(LIB_SUFFIX) \
   ../dns/$(LIB_PREFIX)neckodns_s.$(LIB_SUFFIX) \
   ../socket/$(LIB_PREFIX)neckosocket_s.$(LIB_SUFFIX) \
--- a/netwerk/cache/Makefile.in
+++ b/netwerk/cache/Makefile.in
@@ -2,25 +2,27 @@
 # 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/.
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE         = nkcache
 LIBRARY_NAME   = nkcache_s
 LIBXUL_LIBRARY = 1
 XPIDL_MODULE   = necko_cache
 GRE_MODULE     = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 FORCE_STATIC_LIB = 1
 
 XPIDLSRCS = \
   nsICache.idl \
   nsICacheEntryDescriptor.idl \
   nsICacheListener.idl \
   nsICacheService.idl \
--- a/netwerk/cache/nsCacheService.cpp
+++ b/netwerk/cache/nsCacheService.cpp
@@ -1075,17 +1075,17 @@ static nsCOMPtr<nsIMemoryReporter> Memor
 
 NS_THREADSAFE_MEMORY_REPORTER_IMPLEMENT(NetworkMemoryCache,
     "explicit/network/memory-cache",
     KIND_HEAP,
     UNITS_BYTES,
     nsCacheService::MemoryDeviceSize,
     "Memory used by the network memory cache.")
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(NetworkDiskCacheSizeOfFun, "network-disk-cache")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(NetworkDiskCacheMallocSizeOf)
 
 static nsCOMPtr<nsIMemoryReporter> DiskCacheReporter = nullptr;
 
 NS_THREADSAFE_MEMORY_REPORTER_IMPLEMENT(NetworkDiskCache,
     "explicit/network/disk-cache",
     KIND_HEAP,
     UNITS_BYTES,
     nsCacheService::DiskDeviceHeapSize,
@@ -2283,17 +2283,17 @@ nsCacheService::MemoryDeviceSize()
     return memoryDevice ? memoryDevice->TotalSize() : 0;
 }
 
 int64_t
 nsCacheService::DiskDeviceHeapSize()
 {
     nsCacheServiceAutoLock lock(LOCK_TELEM(NSCACHESERVICE_DISKDEVICEHEAPSIZE));
     nsDiskCacheDevice *diskDevice = GlobalInstance()->mDiskDevice;
-    return (int64_t)(diskDevice ? diskDevice->SizeOfIncludingThis(NetworkDiskCacheSizeOfFun) : 0);
+    return (int64_t)(diskDevice ? diskDevice->SizeOfIncludingThis(NetworkDiskCacheMallocSizeOf) : 0);
 }
 
 nsresult
 nsCacheService::DoomEntry(nsCacheEntry * entry)
 {
     return gService->DoomEntry_Internal(entry, true);
 }
 
--- a/netwerk/cookie/Makefile.in
+++ b/netwerk/cookie/Makefile.in
@@ -3,24 +3,26 @@
 # 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/.
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
 relativesrcdir = @relativesrcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 # export required interfaces, even if --disable-cookies has been given
 MODULE       = necko
 XPIDL_MODULE = necko_cookie
 GRE_MODULE   = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 SDK_XPIDLSRCS = \
   nsICookie.idl \
   nsICookieManager.idl \
   $(NULL)
 
 XPIDLSRCS = \
   nsICookie2.idl \
--- a/netwerk/dns/DNS.cpp
+++ b/netwerk/dns/DNS.cpp
@@ -4,17 +4,17 @@
 
 #include "mozilla/net/DNS.h"
 
 #include "mozilla/Assertions.h"
 #include "mozilla/mozalloc.h"
 #include <string.h>
 
 #ifdef XP_WIN
-#include "Ws2tcpip.h"
+#include "ws2tcpip.h"
 #endif
 
 namespace mozilla {
 namespace net {
 
 const char *inet_ntop_internal(int af, const void *src, char *dst, socklen_t size)
 {
 #ifdef XP_WIN
--- a/netwerk/dns/DNS.h
+++ b/netwerk/dns/DNS.h
@@ -10,17 +10,17 @@
 #include "prnetdb.h"
 #include "mozilla/LinkedList.h"
 
 #if !defined(XP_WIN) && !defined(XP_OS2)
 #include <arpa/inet.h>
 #endif
 
 #ifdef XP_WIN
-#include "Winsock2.h"
+#include "winsock2.h"
 #endif
 
 #define IPv6ADDR_IS_LOOPBACK(a) \
   (((a)->u32[0] == 0)     &&    \
    ((a)->u32[1] == 0)     &&    \
    ((a)->u32[2] == 0)     &&    \
    ((a)->u8[12] == 0)     &&    \
    ((a)->u8[13] == 0)     &&    \
--- a/netwerk/dns/Makefile.in
+++ b/netwerk/dns/Makefile.in
@@ -2,25 +2,27 @@
 # 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/.
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE         = necko
 LIBRARY_NAME   = neckodns_s
 LIBXUL_LIBRARY = 1
 XPIDL_MODULE   = necko_dns
 GRE_MODULE     = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 XPIDLSRCS = \
   nsIDNSListener.idl \
   nsIDNSRecord.idl \
   nsIDNSService.idl \
   nsIEffectiveTLDService.idl \
   nsIIDNService.idl \
   nsPIDNSService.idl \
--- a/netwerk/dns/nsEffectiveTLDService.cpp
+++ b/netwerk/dns/nsEffectiveTLDService.cpp
@@ -54,18 +54,17 @@ nsDomainEntry::FuncForStaticAsserts(void
 #undef ETLD_ENTRY_OFFSET
 #undef ETLD_STR_NUM
 #undef ETLD_STR_NUM1
 
 // ----------------------------------------------------------------------
 
 static nsEffectiveTLDService *gService = nullptr;
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(EffectiveTLDServiceMallocSizeOf,
-                                     "effective-tld-service")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(EffectiveTLDServiceMallocSizeOf)
 
 static int64_t
 GetEffectiveTLDSize()
 {
   return gService->SizeOfIncludingThis(EffectiveTLDServiceMallocSizeOf);
 }
 
 NS_MEMORY_REPORTER_IMPLEMENT(
--- a/netwerk/protocol/http/Makefile.in
+++ b/netwerk/protocol/http/Makefile.in
@@ -2,26 +2,28 @@
 # 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/.
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE         = necko
 LIBRARY_NAME   = nkhttp_s
 LIBXUL_LIBRARY = 1
 XPIDL_MODULE   = necko_http
 GRE_MODULE     = 1
 FORCE_STATIC_LIB = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 EXPORTS_NAMESPACES = mozilla/net
 
 SDK_XPIDLSRCS = \
   nsIHttpChannel.idl \
   nsIHttpHeaderVisitor.idl \
   $(NULL)
 
--- a/netwerk/protocol/res/Makefile.in
+++ b/netwerk/protocol/res/Makefile.in
@@ -2,25 +2,27 @@
 # 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/.
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
-FAIL_ON_WARNINGS = 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE         = necko
 LIBRARY_NAME   = nkres_s
 LIBXUL_LIBRARY = 1
 XPIDL_MODULE   = necko_res
 GRE_MODULE     = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 FORCE_STATIC_LIB = 1
 
 XPIDLSRCS = \
   nsIResProtocolHandler.idl \
   $(NULL)
 
 CPPSRCS = \
--- a/netwerk/protocol/websocket/Makefile.in
+++ b/netwerk/protocol/websocket/Makefile.in
@@ -1,26 +1,28 @@
 # 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/.
 
 DEPTH     = @DEPTH@
 topsrcdir = @top_srcdir@
 srcdir    = @srcdir@
 VPATH     = @srcdir@
-FAIL_ON_WARNINGS = 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE         = necko
 LIBRARY_NAME   = nkwebsocket_s
 LIBXUL_LIBRARY = 1
 XPIDL_MODULE   = necko_websocket
 GRE_MODULE     = 1
 FORCE_STATIC_LIB = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 EXPORTS_NAMESPACES = mozilla/net
 
 XPIDLSRCS = \
   nsIWebSocketChannel.idl \
   nsIWebSocketListener.idl \
   $(NULL)
 
--- a/netwerk/protocol/wyciwyg/Makefile.in
+++ b/netwerk/protocol/wyciwyg/Makefile.in
@@ -1,26 +1,28 @@
 # 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/.
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
-FAIL_ON_WARNINGS = 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= necko
 LIBRARY_NAME	= nkwyciwyg_s
 LIBXUL_LIBRARY	= 1
 XPIDL_MODULE	= necko_wyciwyg
 GRE_MODULE	= 1
 FORCE_STATIC_LIB = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS = 1
+endif # !_MSC_VER
 
 EXPORTS_NAMESPACES = mozilla/net
 
 XPIDLSRCS	= \
 		nsIWyciwygChannel.idl \
 		$(NULL)
 
 EXPORTS_mozilla/net += \
--- a/netwerk/streamconv/converters/Makefile.in
+++ b/netwerk/streamconv/converters/Makefile.in
@@ -2,23 +2,25 @@
 # 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/.
 
 DEPTH		= @DEPTH@
 topsrcdir	= @top_srcdir@
 srcdir		= @srcdir@
 VPATH		= @srcdir@
-FAIL_ON_WARNINGS := 1
 
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= necko
 LIBRARY_NAME	= nkcnvts_s
 LIBXUL_LIBRARY = 1
+ifndef _MSC_VER
+FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 
 CPPSRCS		= \
 		mozTXTToHTMLConv.cpp \
 		nsUnknownDecoder.cpp \
 		nsHTTPCompressConv.cpp \
 		nsTXTToHTMLConv.cpp \
 		nsDirIndex.cpp \
--- a/security/manager/ssl/src/SSLServerCertVerification.cpp
+++ b/security/manager/ssl/src/SSLServerCertVerification.cpp
@@ -100,16 +100,18 @@
 #include "nsIStrictTransportSecurityService.h"
 #include "nsNSSComponent.h"
 #include "nsNSSCleaner.h"
 #include "nsRecentBadCerts.h"
 #include "nsNSSIOLayer.h"
 #include "nsNSSShutDown.h"
 
 #include "mozilla/Assertions.h"
+#include "mozilla/Mutex.h"
+#include "mozilla/Telemetry.h"
 #include "nsIThreadPool.h"
 #include "nsXPCOMCIDInternal.h"
 #include "nsComponentManagerUtils.h"
 #include "nsServiceManagerUtils.h"
 #include "nsIConsoleService.h"
 #include "PSMRunnable.h"
 #include "ScopedNSSTypes.h"
 #include "SharedSSLState.h"
@@ -128,31 +130,38 @@ namespace mozilla { namespace psm {
 namespace {
 
 NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
 
 NSSCleanupAutoPtrClass_WithParam(PLArenaPool, PORT_FreeArena, FalseParam, false)
 
 // do not use a nsCOMPtr to avoid static initializer/destructor
 nsIThreadPool * gCertVerificationThreadPool = nullptr;
+
+// We avoid using a mutex for the success case to avoid lock-related
+// performance issues. However, we do use a lock in the error case to simplify
+// the code, since performance in the error case is not important.
+Mutex *gSSLVerificationTelemetryMutex = nullptr;
+
 } // unnamed namespace
 
 // Called when the socket transport thread starts, to initialize the SSL cert
 // verification thread pool. By tying the thread pool startup/shutdown directly
 // to the STS thread's lifetime, we ensure that they are *always* available for
 // SSL connections and that there are no races during startup and especially
 // shutdown. (Previously, we have had multiple problems with races in PSM
 // background threads, and the race-prevention/shutdown logic used there is
 // brittle. Since this service is critical to things like downloading updates,
 // we take no chances.) Also, by doing things this way, we avoid the need for
 // locks, since gCertVerificationThreadPool is only ever accessed on the socket
 // transport thread.
 void
 InitializeSSLServerCertVerificationThreads()
 {
+  gSSLVerificationTelemetryMutex = new Mutex("SSLVerificationTelemetryMutex");
   // TODO: tuning, make parameters preferences
   // XXX: instantiate nsThreadPool directly, to make this more bulletproof.
   // Currently, the nsThreadPool.h header isn't exported for us to do so.
   nsresult rv = CallCreateInstance(NS_THREADPOOL_CONTRACTID,
                                    &gCertVerificationThreadPool);
   if (NS_FAILED(rv)) {
     NS_WARNING("Failed to create SSL cert verification threads.");
     return;
@@ -175,16 +184,20 @@ InitializeSSLServerCertVerificationThrea
 // shutdown of the nsNSSComponent service. We use the
 // nsNSSShutdownPreventionLock where needed (not here) to prevent that.
 void StopSSLServerCertVerificationThreads()
 {
   if (gCertVerificationThreadPool) {
     gCertVerificationThreadPool->Shutdown();
     NS_RELEASE(gCertVerificationThreadPool);
   }
+  if (gSSLVerificationTelemetryMutex) {
+    delete gSSLVerificationTelemetryMutex;
+    gSSLVerificationTelemetryMutex = nullptr;
+  }
 }
 
 namespace {
 
 void
 LogInvalidCertError(TransportSecurityInfo *socketInfo, 
                     const nsACString &host, 
                     const nsACString &hostWithPort,
@@ -213,25 +226,29 @@ LogInvalidCertError(TransportSecurityInf
 // descriptor that is waiting for this result.
 class SSLServerCertVerificationResult : public nsRunnable
 {
 public:
   NS_DECL_NSIRUNNABLE
 
   SSLServerCertVerificationResult(TransportSecurityInfo * infoObject,
                                   PRErrorCode errorCode,
-                                  SSLErrorMessageType errorMessageType = 
+                                  Telemetry::ID telemetryID = Telemetry::HistogramCount,
+                                  uint32_t telemetryValue = -1,
+                                  SSLErrorMessageType errorMessageType =
                                       PlainErrorMessage);
 
   void Dispatch();
 private:
   const RefPtr<TransportSecurityInfo> mInfoObject;
 public:
   const PRErrorCode mErrorCode;
   const SSLErrorMessageType mErrorMessageType;
+  const Telemetry::ID mTelemetryID;
+  const uint32_t mTelemetryValue;
 };
 
 class CertErrorRunnable : public SyncRunnableBase
 {
  public:
   CertErrorRunnable(const void * fdForLogging,
                     nsIX509Cert * cert,
                     TransportSecurityInfo * infoObject,
@@ -388,16 +405,18 @@ CertErrorRunnable::CheckCertOverrides()
   PRErrorCode errorCodeToReport = mErrorCodeTrust    ? mErrorCodeTrust
                                 : mErrorCodeMismatch ? mErrorCodeMismatch
                                 : mErrorCodeExpired  ? mErrorCodeExpired
                                 : mDefaultErrorCodeToReport;
                                 
   SSLServerCertVerificationResult *result = 
     new SSLServerCertVerificationResult(mInfoObject, 
                                         errorCodeToReport,
+                                        Telemetry::HistogramCount,
+                                        -1,
                                         OverridableCertErrorMessage);
 
   LogInvalidCertError(mInfoObject,
                       nsDependentCString(mInfoObject->GetHostName()),
                       hostWithPortString,
                       port,
                       result->mErrorCode,
                       result->mErrorMessageType,
@@ -622,25 +641,27 @@ private:
   SSLServerCertVerificationJob(const void * fdForLogging,
                                TransportSecurityInfo * infoObject, 
                                CERTCertificate * cert,
                                uint32_t providerFlags);
   const void * const mFdForLogging;
   const RefPtr<TransportSecurityInfo> mInfoObject;
   const ScopedCERTCertificate mCert;
   const uint32_t mProviderFlags;
+  const TimeStamp mJobStartTime;
 };
 
 SSLServerCertVerificationJob::SSLServerCertVerificationJob(
     const void * fdForLogging, TransportSecurityInfo * infoObject,
     CERTCertificate * cert, uint32_t providerFlags)
   : mFdForLogging(fdForLogging)
   , mInfoObject(infoObject)
   , mCert(CERT_DupCertificate(cert))
   , mProviderFlags(providerFlags)
+  , mJobStartTime(TimeStamp::Now())
 {
 }
 
 SECStatus
 PSM_SSL_PKIX_AuthCertificate(CERTCertificate *peerCert, void * pinarg,
                              const char * hostname)
 {
     SECStatus          rv;
@@ -1045,23 +1066,48 @@ SSLServerCertVerificationJob::Run()
   if (mInfoObject->isAlreadyShutDown()) {
     error = SEC_ERROR_USER_CANCELLED;
   } else {
     // Reset the error code here so we can detect if AuthCertificate fails to
     // set the error code if/when it fails.
     PR_SetError(0, 0); 
     SECStatus rv = AuthCertificate(mInfoObject, mCert, mProviderFlags);
     if (rv == SECSuccess) {
+      uint32_t interval = (uint32_t) ((TimeStamp::Now() - mJobStartTime).ToMilliseconds());
+      Telemetry::ID telemetryID;
+      if(nsNSSComponent::globalConstFlagUsePKIXVerification){
+        telemetryID = Telemetry::SSL_SUCCESFUL_CERT_VALIDATION_TIME_LIBPKIX;
+      }
+      else{
+        telemetryID = Telemetry::SSL_SUCCESFUL_CERT_VALIDATION_TIME_CLASSIC;
+      }
       RefPtr<SSLServerCertVerificationResult> restart(
-        new SSLServerCertVerificationResult(mInfoObject, 0));
+        new SSLServerCertVerificationResult(mInfoObject, 0,
+                                            telemetryID, interval));
       restart->Dispatch();
       return NS_OK;
     }
 
+    // Note: the interval is not calculated once as PR_GetError MUST be called
+    // before any other  function call
     error = PR_GetError();
+    {
+      TimeStamp now = TimeStamp::Now();
+      Telemetry::ID telemetryID;
+      if(nsNSSComponent::globalConstFlagUsePKIXVerification){
+        telemetryID = Telemetry::SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_LIBPKIX;
+      }
+      else{
+        telemetryID = Telemetry::SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_CLASSIC;
+      }
+      MutexAutoLock telemetryMutex(*gSSLVerificationTelemetryMutex);
+      Telemetry::AccumulateTimeDelta(telemetryID,
+                                     mJobStartTime,
+                                     now);
+    }
     if (error != 0) {
       RefPtr<CertErrorRunnable> runnable(CreateCertErrorRunnable(
         error, mInfoObject, mCert, mFdForLogging, mProviderFlags));
       if (!runnable) {
         // CreateCertErrorRunnable set a new error code
         error = PR_GetError(); 
       } else {
         // We must block the the socket transport service thread while the
@@ -1269,21 +1315,29 @@ void EnsureServerVerificationInitialized
 
   RefPtr<InitializeIdentityInfo> initJob = new InitializeIdentityInfo();
   if (gCertVerificationThreadPool)
     gCertVerificationThreadPool->Dispatch(initJob, NS_DISPATCH_NORMAL);
 }
 
 SSLServerCertVerificationResult::SSLServerCertVerificationResult(
         TransportSecurityInfo * infoObject, PRErrorCode errorCode,
+        Telemetry::ID telemetryID, uint32_t telemetryValue,
         SSLErrorMessageType errorMessageType)
   : mInfoObject(infoObject)
   , mErrorCode(errorCode)
   , mErrorMessageType(errorMessageType)
+  , mTelemetryID(telemetryID)
+  , mTelemetryValue(telemetryValue)
 {
+// We accumulate telemetry for (only) successful validations on the main thread
+// to avoid adversely affecting performance by acquiring the mutex that we use
+// when accumulating the telemetry for unsuccessful validations. Unsuccessful
+// validations times are accumulated elsewhere.
+MOZ_ASSERT(telemetryID == Telemetry::HistogramCount || errorCode == 0);
 }
 
 void
 SSLServerCertVerificationResult::Dispatch()
 {
   nsresult rv;
   nsCOMPtr<nsIEventTarget> stsTarget
     = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
@@ -1293,15 +1347,18 @@ SSLServerCertVerificationResult::Dispatc
   NS_ASSERTION(NS_SUCCEEDED(rv), 
                "Failed to dispatch SSLServerCertVerificationResult");
 }
 
 NS_IMETHODIMP
 SSLServerCertVerificationResult::Run()
 {
   // TODO: Assert that we're on the socket transport thread
+  if (mTelemetryID != Telemetry::HistogramCount) {
+     Telemetry::Accumulate(mTelemetryID, mTelemetryValue);
+  }
   // XXX: This cast will be removed by the next patch
   ((nsNSSSocketInfo *) mInfoObject.get())
     ->SetCertVerificationResult(mErrorCode, mErrorMessageType);
   return NS_OK;
 }
 
 } } // namespace mozilla::psm
--- a/startupcache/StartupCache.cpp
+++ b/startupcache/StartupCache.cpp
@@ -61,17 +61,17 @@ GetStartupCacheMappingSize()
 NS_MEMORY_REPORTER_IMPLEMENT(StartupCacheMapping,
     "explicit/startup-cache/mapping",
     KIND_NONHEAP,
     nsIMemoryReporter::UNITS_BYTES,
     GetStartupCacheMappingSize,
     "Memory used to hold the mapping of the startup cache from file.  This "
     "memory is likely to be swapped out shortly after start-up.")
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(StartupCacheDataMallocSizeOf, "startup-cache/data")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(StartupCacheDataMallocSizeOf)
 
 static int64_t
 GetStartupCacheDataSize()
 {
     mozilla::scache::StartupCache* sc = mozilla::scache::StartupCache::GetSingleton();
     return sc ? sc->HeapSizeOfIncludingThis(StartupCacheDataMallocSizeOf) : 0;
 }
 
--- a/storage/src/mozStorageService.cpp
+++ b/storage/src/mozStorageService.cpp
@@ -465,48 +465,48 @@ namespace {
 // output as unreported, so we mark them as reported when they're allocated and
 // mark them as unreported when they are freed.
 //
 // In other words, we are marking all sqlite heap blocks as reported even
 // though we're not reporting them ourselves.  Instead we're trusting that
 // sqlite is fully and correctly accounting for all of its heap blocks via its
 // own memory accounting.
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_ALLOC_FUN(sqliteMallocSizeOfOnAlloc, "sqlite")
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_FREE_FUN(sqliteMallocSizeOfOnFree)
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_ALLOC_FUN(SqliteMallocSizeOfOnAlloc)
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_ON_FREE_FUN(SqliteMallocSizeOfOnFree)
 
 #endif
 
 static void *sqliteMemMalloc(int n)
 {
   void* p = ::moz_malloc(n);
 #ifdef MOZ_DMD
-  sqliteMallocSizeOfOnAlloc(p);
+  SqliteMallocSizeOfOnAlloc(p);
 #endif
   return p;
 }
 
 static void sqliteMemFree(void *p)
 {
 #ifdef MOZ_DMD
-  sqliteMallocSizeOfOnFree(p);
+  SqliteMallocSizeOfOnFree(p);
 #endif
   ::moz_free(p);
 }
 
 static void *sqliteMemRealloc(void *p, int n)
 {
 #ifdef MOZ_DMD
-  sqliteMallocSizeOfOnFree(p);
+  SqliteMallocSizeOfOnFree(p);
   void *pnew = ::moz_realloc(p, n);
   if (pnew) {
-    sqliteMallocSizeOfOnAlloc(pnew);
+    SqliteMallocSizeOfOnAlloc(pnew);
   } else {
-    // realloc failed;  undo the sqliteMallocSizeOfOnFree from above
-    sqliteMallocSizeOfOnAlloc(p);
+    // realloc failed;  undo the SqliteMallocSizeOfOnFree from above
+    SqliteMallocSizeOfOnAlloc(p);
   }
   return pnew;
 #else
   return ::moz_realloc(p, n);
 #endif
 }
 
 static int sqliteMemSize(void *p)
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/atoms/b2g_update_test.js
@@ -0,0 +1,252 @@
+/* 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/. */
+
+/**
+ * Helper functions and APIs for update tests.
+ * Generally, most update tests will try to install an update and run
+ * tests both before and after the update occurs. To support this, update
+ * tests support three different lifecycle functions: "preUpdate",
+ * "applyUpdate", and "postUpdate".
+ *
+ * Here's an example:
+ *
+ * // This test will apply an update, and run tests before and after is applied
+ * function preUpdate() {
+ *   myPreUpdate();
+ * }
+ * // use the default applyUpdate implementation
+ * function postUpdate() {
+ *   myPostUpdate();
+ * }
+ *
+ * When B2GUpdateTestCase.execute_update_test is called from python, this is the
+ * general flow:
+ *
+ * 1. The preUpdate function is called to run any initial tests and optionally
+ *    get an update ready to apply. If the "apply" argument is None, then steps
+ *    2 and 3 are skipped.
+ * 2. The applyUpdate function is called to apply the update. There is a default
+ *    implementation provided that can be overridden.
+ * 3. The postUpdate function is called to run any tests after the update has
+ *    been applied.
+ * See b2g_update_test.py for more information about using 'apply'
+ */
+"use strict";
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+const APPLY_TIMEOUT = 10;
+
+let browser = Services.wm.getMostRecentWindow("navigator:browser");
+if (!browser) {
+  log("Warning: No content browser");
+}
+
+let shell = browser.shell;
+function getContentWindow() {
+  return shell.contentBrowser.contentWindow;
+}
+
+function sendContentEvent(type, detail) {
+  detail = detail || {};
+  detail.type = type;
+
+  let content = getContentWindow();
+  shell.sendEvent(content, "mozContentEvent",
+                   ObjectWrapper.wrap(detail, content));
+  return true;
+}
+
+function addChromeEventListener(type, listener) {
+  let content = getContentWindow();
+  content.addEventListener("mozChromeEvent", function chromeListener(evt) {
+    if (!evt.detail || evt.detail.type !== type) {
+      return;
+    }
+
+    let remove = listener(evt);
+    if (remove) {
+      content.removeEventListener(chromeListener);
+    }
+  });
+}
+
+function createUpdatePrompt() {
+  return Cc["@mozilla.org/updates/update-prompt;1"].
+         createInstance(Ci.nsIUpdatePrompt);
+}
+
+let oldPrefs = {};
+
+function getPrefByType(pref, prefType) {
+  // The value may not exist, so swallow errors here
+  try {
+    switch (prefType) {
+      case "string":
+        return Services.prefs.getCharPref(pref);
+      case "number":
+        return Services.prefs.getIntPref(pref);
+      case "boolean":
+        return Services.prefs.getBoolPref(pref);
+    }
+  } catch (e) {}
+  return undefined;
+}
+
+function setPref(pref, value) {
+  switch (typeof(value)) {
+    case "string":
+      Services.prefs.setCharPref(pref, value);
+      break;
+    case "number":
+      Services.prefs.setIntPref(pref, value);
+      break;
+    case "boolean":
+      Services.prefs.setBoolPref(pref, value);
+      break;
+  }
+}
+
+function getPrefTypeDefaultValue(prefType) {
+  switch (prefType) {
+    case "string":
+      return null;
+    case "number":
+      return 0;
+    case "boolean":
+      return false;
+  }
+  return undefined;
+}
+
+function setPrefs() {
+  if (!updateArgs) {
+    return;
+  }
+
+  let prefs = updateArgs.prefs;
+  if (!prefs) {
+    return;
+  }
+
+  let keys = Object.keys(prefs);
+  for (let i = 0; i < keys.length; i++) {
+    let key = keys[i];
+    let value = prefs[key];
+    let oldValue = getPrefByType(key, typeof(value));
+    if (oldValue !== undefined) {
+      oldPrefs[key] = oldValue;
+    }
+
+    setPref(key, value);
+  }
+}
+
+function cleanPrefs() {
+  if (!updateArgs) {
+    return;
+  }
+
+  let prefs = updateArgs.prefs;
+  if (!prefs) {
+    return;
+  }
+
+  let keys = Object.keys(prefs);
+  for (let i = 0; i < keys.length; i++) {
+    let key = keys[i];
+    let value = prefs[key];
+    let oldValue = oldPrefs[key];
+    if (oldValue === undefined) {
+      oldValue = getPrefTypeDefaultValue(typeof(value));
+      if (oldValue === undefined) {
+        log("Warning: Couldn't unset pref " + key +
+            ", unknown type for: " + value);
+        continue;
+      }
+    }
+
+    setPref(key, oldValue);
+  }
+}
+
+function getStartBuild() {
+  let start = updateArgs.start;
+  ok(start, "Start build not found in updateArgs");
+  return start;
+}
+
+function getFinishBuild() {
+  let finish = updateArgs.finish;
+  ok(finish, "Finish build not found in updateArgs");
+  return finish;
+}
+
+function isFinishUpdate(update) {
+  let finish = getFinishBuild();
+
+  is(update.appVersion, finish.app_version,
+     "update app version should be finish app version: " + finish.app_version);
+  is(update.buildID, finish.app_build_id,
+     "update build ID should be finish app build ID: " + finish.app_build_id);
+}
+
+function isStartToFinishUpdate(update) {
+  let start = getStartBuild();
+
+  is(update.previousAppVersion, start.app_version,
+     "update previous app version should be start app version: " +
+     start.app_version);
+  isFinishUpdate(update);
+}
+
+function statusSettingIs(value, next) {
+  Services.settings.createLock().get("gecko.updateStatus", {
+    handle: function(name, v) {
+      is(v, value);
+      next();
+    },
+    handleError: function(error) {
+      fail(error);
+    }
+  });
+}
+
+function applyUpdate() {
+  sendContentEvent("update-prompt-apply-result", {
+    result: "restart"
+  });
+}
+
+function runUpdateTest(stage) {
+  switch (stage) {
+    case "pre-update":
+      if (preUpdate) {
+        preUpdate();
+      }
+      break;
+    case "apply-update":
+      if (applyUpdate) {
+        applyUpdate();
+      }
+      break;
+    case "post-update":
+      if (postUpdate) {
+        postUpdate();
+      }
+      break;
+  }
+}
+
+let updateArgs;
+if (__marionetteParams) {
+  updateArgs = __marionetteParams[0];
+}
+
+function cleanUp() {
+  cleanPrefs();
+  finish();
+  //marionetteScriptFinished();
+}
+
+setPrefs();
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/b2g_update_test.py
@@ -0,0 +1,453 @@
+# 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/.
+
+from cStringIO import StringIO
+import imp
+import os
+import re
+import subprocess
+import sys
+import tempfile
+import time
+import types
+import unittest
+import weakref
+
+from b2ginstance import B2GInstance
+from client import MarionetteClient
+from errors import MarionetteException, InvalidResponseException
+from marionette import Marionette
+from marionette_test import MarionetteTestCase
+from runtests import MarionetteTestRunner, cli, parse_options, startTestRunner
+
+class B2GUpdateMarionetteClient(MarionetteClient):
+    RETRY_TIMEOUT   = 5
+    CONNECT_TIMEOUT = 30
+    SEND_TIMEOUT    = 60 * 5
+    MAX_RETRIES     = 24
+
+    def __init__(self, addr, port, runner):
+        MarionetteClient.__init__(self, addr, port)
+        self.runner = runner
+
+    def connect(self):
+        """ When using ADB port forwarding, the ADB server will actually accept
+            connections even though there isn't a listening socket open on the
+            device. Here we add a retry loop since we have to restart the debug
+            server / b2g process for update tests
+        """
+        for i in range(self.MAX_RETRIES):
+            try:
+                MarionetteClient.connect(self, timeout=self.CONNECT_TIMEOUT)
+                break
+            except:
+                if i == self.MAX_RETRIES - 1:
+                    raise
+
+                time.sleep(self.RETRY_TIMEOUT)
+                self.runner.port_forward()
+
+        # Upon success, reset the socket timeout to something more reasonable
+        self.sock.settimeout(self.SEND_TIMEOUT)
+
+class B2GUpdateTestRunner(MarionetteTestRunner):
+    match_re = re.compile(r'update_(smoke)?test_(.*)\.py$')
+
+    def __init__(self, **kwargs):
+        MarionetteTestRunner.__init__(self, **kwargs)
+        if self.emulator or self.bin:
+            raise Exception('Update tests do not support emulator or custom binaries')
+
+        if not self.address:
+            raise Exception('Update tests must be run with '
+                            '--address=localhost:<port>')
+
+        self.host, port = self.address.split(':')
+        self.port = int(port)
+        self.test_handlers.append(self)
+
+        self.b2g = B2GInstance(homedir=kwargs.get('homedir'))
+        self.update_tools = self.b2g.import_update_tools()
+        self.adb = self.update_tools.AdbTool(path=self.b2g.adb_path,
+                                             device=self.device)
+
+    def match(self, filename):
+        return self.match_re.match(filename) is not None
+
+    def add_tests_to_suite(self, mod_name, filepath, suite, testloader,
+                           marionette, testvars):
+        """ Here the runner itself is a handler so we can forward along the
+            instance to test cases.
+        """
+        test_mod = imp.load_source(mod_name, filepath)
+
+        def add_test(testcase, testname, **kwargs):
+            suite.addTest(testcase(weakref.ref(marionette),
+                          methodName=testname,
+                          filepath=filepath,
+                          testvars=testvars,
+                          **kwargs))
+
+        # The TestCase classes are apparently being loaded multiple times, so
+        # using "isinstance" doesn't actually work. This function just compares
+        # type names as a close enough analog.
+        def has_super(cls, super_names):
+            if not isinstance(super_names, (tuple, list)):
+                super_names = (super_names)
+
+            base = cls
+            while base:
+                if base.__name__ in super_names:
+                    return True
+                base = base.__base__
+            return False
+
+        for name in dir(test_mod):
+            testcase = getattr(test_mod, name)
+            if not isinstance(testcase, (type, types.ClassType)):
+                continue
+
+            # Support both B2GUpdateTestCase and MarionetteTestCase
+            if has_super(testcase, 'B2GUpdateTestCase'):
+                for testname in testloader.getTestCaseNames(testcase):
+                    add_test(testcase, testname, runner=self)
+            elif has_super(testcase, ('MarionetteTestCase', 'TestCase')):
+                for testname in testloader.getTestCaseNames(testcase):
+                    add_test(testcase, testname)
+
+    def start_marionette(self):
+        MarionetteTestRunner.start_marionette(self)
+        self.marionette.client = B2GUpdateMarionetteClient(self.host,
+                                                           self.port,
+                                                           self)
+
+    def reset(self, b2g_pid):
+        if self.marionette.instance:
+            self.marionette.instance.close()
+            self.marionette.instance = None
+        del self.marionette
+
+        self.start_marionette()
+        self.b2g_pid = b2g_pid
+        return self.marionette
+
+    def find_b2g_pid(self):
+        pids = self.adb.get_pids('b2g')
+        if len(pids) == 0:
+            return None
+        return pids[0]
+
+    def port_forward(self):
+        try:
+            self.adb.run('forward', 'tcp:%d' % self.port, 'tcp:2828')
+        except:
+            # This command causes non-0 return codes even though it succeeds
+            pass
+
+OTA, FOTA = "OTA", "FOTA"
+class B2GUpdateTestCase(MarionetteTestCase):
+    """ A high level unit test for an OTA or FOTA update. This test case class
+    has structural support for automatically waiting on an update to apply,
+    and provides additional javascript support for separating a test into
+    'pre-update' and 'post-update' lifecycles.
+
+    See test examples in toolkit/mozapps/update/test/marionette/update_test_*.py
+    """
+
+    MAX_OTA_WAIT   = 60 * 2  # 2 minutes
+    MAX_FOTA_WAIT  = 60 * 10 # 10 minutes
+    REMOTE_USER_JS = '/data/local/user.js'
+
+    def __init__(self, marionette_weakref, **kwargs):
+        if 'runner' in kwargs:
+            self.runner = kwargs['runner']
+            del kwargs['runner']
+
+        update_test_js = os.path.join(os.path.dirname(__file__), 'atoms',
+                                      'b2g_update_test.js')
+        with open(update_test_js, 'r') as f:
+            self.update_test_js = f.read()
+
+        self.b2g_pid = self.runner.find_b2g_pid()
+        if not self.b2g_pid:
+            raise Exception('B2G PID could not be found for update test')
+        MarionetteTestCase.__init__(self, marionette_weakref, **kwargs)
+
+        self.testvars = self.testvars or {}
+        self.status_newline = True
+        self.loglines = []
+
+    def print_status(self, status, message=None):
+        if self.status_newline:
+            print ''
+            self.status_newline = False
+
+        status_msg = 'UPDATE-TEST-' + status
+        if message:
+            status_msg += ': ' + message
+        print status_msg
+
+    def setUp(self):
+        MarionetteTestCase.setUp(self)
+        self.marionette.set_context(Marionette.CONTEXT_CHROME)
+
+    def tearDown(self):
+        # This completey overrides MarionetteTestCase.tearDown so we can control
+        # logs being appended between various marionette runs
+        self.marionette.set_context(Marionette.CONTEXT_CONTENT)
+        self.marionette.execute_script("log('TEST-END: %s:%s')" %
+                                       (self.filepath.replace('\\', '\\\\'), self.methodName))
+        self.marionette.test_name = None
+
+        self.duration = time.time() - self.start_time
+        if self.marionette.session is not None:
+            self.loglines.extend(self.marionette.get_logs())
+            self.perfdata = self.marionette.get_perf_data()
+            self.marionette.delete_session()
+        self.marionette = None
+
+    def reset(self, b2g_pid):
+        self.print_status('RESET-MARIONETTE')
+        self._marionette_weakref = weakref.ref(self.runner.reset(b2g_pid))
+        self.marionette = self._marionette_weakref()
+        if self.marionette.session is None:
+            self.marionette.start_session()
+            self.marionette.set_context(Marionette.CONTEXT_CHROME)
+
+    def execute_update_test(self, path, apply=None):
+        self.execute_update_js(path, stage='pre-update',
+                               will_restart=(apply is not None))
+        if not apply:
+            return
+
+        if self.marionette.session is not None:
+            self.loglines.extend(self.marionette.get_logs())
+
+        # This function will probably force-kill b2g, so we can't capture logs
+        self.execute_update_js(path, stage='apply-update')
+        self.wait_for_update(apply)
+
+        self.execute_update_js(path, stage='post-update')
+
+    def execute_update_js(self, path, stage=None, will_restart=True):
+        data = self.update_test_js[:]
+        with open(path, "r") as f:
+            data += f.read()
+
+        status = 'EXEC'
+        if stage:
+            status += '-' + stage.upper()
+            data += '\nrunUpdateTest("%s");' % stage
+
+        self.print_status(status, os.path.basename(path))
+
+        try:
+            results = self.marionette.execute_async_script(data,
+                                                           script_args=[self.testvars],
+                                                           special_powers=True)
+            self.handle_results(path, stage, results)
+        except InvalidResponseException, e:
+            # If the update test causes a restart, we will get an invalid
+            # response from the socket here.
+            if not will_restart:
+                raise e
+
+    def handle_results(self, path, stage, results):
+        passed = results['passed']
+        failed = results['failed']
+
+        fails = StringIO()
+        stage_msg = ' %s' % stage if stage else ''
+        fails.write('%d%s tests failed:\n' % (failed, stage_msg))
+
+        for failure in results['failures']:
+            diag = failure.get('diag')
+            diag_msg = "" if not diag else "| %s " % diag
+            name = failure.get('name') or 'got false, expected true'
+            fails.write('TEST-UNEXPECTED-FAIL | %s %s| %s\n' %
+                        (os.path.basename(path), diag_msg, name))
+        self.assertEqual(0, failed, fails.getvalue())
+        self.assertTrue(passed + failed > 0, 'no tests run')
+
+    def stage_update(self, **kwargs):
+        mar = kwargs.get('complete_mar') or kwargs.get('partial_mar')
+        short_mar = os.path.relpath(mar, os.path.dirname(os.path.dirname(mar)))
+        self.print_status('STAGE', short_mar)
+
+        prefs = kwargs.pop('prefs', {})
+        update_xml = kwargs.get('update_xml')
+        if not update_xml:
+            xml_kwargs = kwargs.copy()
+            if 'update_dir' in xml_kwargs:
+                del xml_kwargs['update_dir']
+            if 'only_override' in xml_kwargs:
+                del xml_kwargs['only_override']
+            builder = self.runner.update_tools.UpdateXmlBuilder(**xml_kwargs)
+            update_xml = builder.build_xml()
+
+        test_kwargs = {
+            'adb_path': self.runner.adb.tool,
+            'update_xml': update_xml,
+            'only_override': kwargs.get('only_override', False),
+            'remote_prefs_js': self.REMOTE_USER_JS
+        }
+        for key in ('complete_mar', 'partial_mar', 'url_template', 'update_dir'):
+            test_kwargs[key] = kwargs.get(key)
+
+        test_update = self.runner.update_tools.TestUpdate(**test_kwargs)
+        test_update.test_update(write_url_pref=False, restart=False)
+        if 'prefs' not in self.testvars:
+            self.testvars['prefs'] = {}
+
+        self.testvars['prefs']['app.update.url.override'] = test_update.update_url
+        self.testvars['prefs'].update(prefs)
+
+    def wait_for_update(self, type):
+        if type == OTA:
+            self.wait_for_ota_restart()
+        elif type == FOTA:
+            self.wait_for_fota_reboot()
+
+    def wait_for_new_b2g_pid(self, max_wait):
+        for i in range(max_wait):
+            b2g_pid = self.runner.find_b2g_pid()
+            if b2g_pid and b2g_pid != self.b2g_pid:
+                return b2g_pid
+            time.sleep(1)
+
+        return None
+
+    def wait_for_ota_restart(self):
+        self.print_status('WAIT-FOR-OTA-RESTART')
+
+        new_b2g_pid = self.wait_for_new_b2g_pid(self.MAX_OTA_WAIT)
+        if not new_b2g_pid:
+            self.fail('Timed out waiting for B2G process during OTA update')
+            return
+
+        self.reset(new_b2g_pid)
+
+    def wait_for_fota_reboot(self):
+        self.print_status('WAIT-FOR-FOTA-REBOOT')
+
+        # First wait for the device to go offline
+        for i in range(self.MAX_FOTA_WAIT):
+            online = self.runner.adb.get_online_devices()
+            if self.runner.device not in online:
+                break
+            time.sleep(1)
+
+        if i == self.MAX_FOTA_WAIT - 1:
+            self.fail('Timed out waiting for device to go offline during FOTA update')
+
+        # Now wait for the device to come back online
+        for j in range(i, self.MAX_FOTA_WAIT):
+            online = self.runner.adb.get_online_devices()
+            if self.runner.device in online:
+                break
+            time.sleep(1)
+
+        if j == self.MAX_FOTA_WAIT - 1:
+            self.fail('Timed out waiting for device to come back online during FOTA update')
+
+        # Finally wait for the B2G process
+        for k in range(j, self.MAX_FOTA_WAIT):
+            b2g_pid = self.runner.find_b2g_pid()
+            if b2g_pid:
+                self.reset(b2g_pid)
+                return
+            time.sleep(1)
+
+        self.fail('Timed out waiting for B2G process to start during FOTA update')
+
+    def flash(self, flash_script):
+        update_tools = self.runner.update_tools
+        flash_build = os.path.basename(os.path.dirname(flash_script))
+        self.print_status('FLASH-BUILD', flash_build)
+
+        subprocess.check_call([flash_script, self.runner.device])
+        self.runner.adb.run('wait-for-device')
+        self.runner.port_forward()
+
+        self.b2g_pid = None
+        b2g_pid = self.wait_for_new_b2g_pid(self.MAX_OTA_WAIT)
+        if not b2g_pid:
+            self.fail('Timed out waiting for B2G process to start after a flash')
+
+        self.reset(b2g_pid)
+
+class B2GUpdateSmokeTestCase(B2GUpdateTestCase):
+    """ An even higher-level update test that is meant to be run with builds
+    and updates generated in an automated build environment.
+
+    Update smoke tests have two main differences from a plain update test:
+    - They are meant to be passed various MARs and system images through the
+      --testvars Marionette argument.
+    - Before each test, the device can be flashed with a specified set of images
+      by the test case.
+
+    See smoketest examples in
+    toolkit/mozapps/update/test/marionette/update_smoketest_*.py
+    """
+
+    "The path of the Javascript file that has assertions to run"
+    JS_PATH          = None
+
+    """ Which build to flash and vars to stage before the test is run.
+        Possible values: 'start', 'finish', or None
+    """
+    START_WITH_BUILD = 'start'
+
+    "A map of prefs to set while staging, before the test is run"
+    STAGE_PREFS      = None
+
+    "Marionette script timeout"
+    TIMEOUT          = 2 * 60 * 1000
+
+    """What kind of update to apply after the 'pre-update' tests have
+    finished. Possible values: OTA, FOTA, None. None means "Don't apply"
+    """
+    APPLY            = OTA
+
+    def setUp(self):
+        if self.START_WITH_BUILD:
+            build = self.testvars[self.START_WITH_BUILD]
+            self.flash(build['flash_script'])
+
+        B2GUpdateTestCase.setUp(self)
+
+    def stage_update(self, build=None, mar=None, **kwargs):
+        if build and not mar:
+            raise Exception('mar required with build')
+        if mar and not build:
+            raise Exception('build required with mar')
+
+        if not build:
+            B2GUpdateTestCase.stage_update(self, **kwargs)
+            return
+
+        build_vars = self.testvars[build]
+        mar_key = mar + '_mar'
+        mar_path = build_vars[mar_key]
+
+        stage_kwargs = {
+            'build_id': build_vars['app_build_id'],
+            'app_version': build_vars['app_version'],
+            'platform_version': build_vars['platform_milestone'],
+            mar_key: mar_path
+        }
+        stage_kwargs.update(kwargs)
+
+        if self.STAGE_PREFS:
+            if 'prefs' not in stage_kwargs:
+                stage_kwargs['prefs'] = self.STAGE_PREFS
+
+        B2GUpdateTestCase.stage_update(self, **stage_kwargs)
+
+    def execute_smoketest(self):
+        self.marionette.set_script_timeout(self.TIMEOUT)
+        self.execute_update_test(self.JS_PATH, apply=self.APPLY)
+
+if __name__ == '__main__':
+    cli(B2GUpdateTestRunner)
--- a/testing/marionette/client/marionette/b2ginstance.py
+++ b/testing/marionette/client/marionette/b2ginstance.py
@@ -1,4 +1,96 @@
 # 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/.
 
+import os
+import platform
+import subprocess
+import sys
+
+class B2GInstance(object):
+    @classmethod
+    def check_b2g_dir(cls, dir):
+        if os.path.isfile(os.path.join(dir, 'load-config.sh')):
+            return dir
+
+        oldstyle_dir = os.path.join(dir, 'glue', 'gonk-ics')
+        if os.access(oldstyle_dir, os.F_OK):
+            return oldstyle_dir
+
+        return None
+
+    @classmethod
+    def find_b2g_dir(cls):
+        for env_var in ('B2G_DIR', 'B2G_HOME'):
+            if env_var in os.environ:
+                env_dir = os.environ[env_var]
+                env_dir = cls.check_b2g_dir(env_dir)
+                if env_dir:
+                    return env_dir
+
+        cwd = os.getcwd()
+        cwd = cls.check_b2g_dir(cwd)
+        if cwd:
+            return cwd
+
+        return None
+
+    @classmethod
+    def check_adb(cls, homedir):
+        if 'ADB' in os.environ:
+            env_adb = os.environ['ADB']
+            if os.path.exists(env_adb):
+                return env_adb
+
+        return cls.check_host_binary(homedir, 'adb')
+
+    @classmethod
+    def check_fastboot(cls, homedir):
+        return cls.check_host_binary(homedir, 'fastboot')
+
+    @classmethod
+    def check_host_binary(cls, homedir, binary):
+        host_dir = "linux-x86"
+        if platform.system() == "Darwin":
+            host_dir = "darwin-x86"
+        binary_path = subprocess.Popen(['which', binary],
+                                       stdout=subprocess.PIPE,
+                                       stderr=subprocess.STDOUT)
+        if binary_path.wait() == 0:
+            return binary_path.stdout.read().strip()  # remove trailing newline
+        binary_paths = [os.path.join(homedir, 'glue', 'gonk', 'out', 'host',
+                                     host_dir, 'bin', binary),
+                        os.path.join(homedir, 'out', 'host', host_dir,
+                                     'bin', binary),
+                        os.path.join(homedir, 'bin', binary)]
+        for option in binary_paths:
+            if os.path.exists(option):
+                return option
+        raise Exception('%s not found!' % binary)
+
+    def __init__(self, homedir=None):
+        if not homedir:
+            homedir = self.find_b2g_dir()
+        else:
+            homedir = self.check_b2g_dir(homedir)
+
+        if not homedir:
+            raise EnvironmentError('Must define B2G_HOME or pass the homedir parameter')
+
+        self.homedir = homedir
+        self.adb_path = self.check_adb(self.homedir)
+        self.fastboot_path = self.check_fastboot(self.homedir)
+        self.update_tools = os.path.join(self.homedir, 'tools', 'update-tools')
+
+    def check_file(self, filePath):
+        if not os.access(filePath, os.F_OK):
+            raise Exception(('File not found: %s; did you pass the B2G home '
+                             'directory as the homedir parameter, or set '
+                             'B2G_HOME correctly?') % filePath)
+
+    def import_update_tools(self):
+        """Import the update_tools package from B2G"""
+        sys.path.append(self.update_tools)
+        import update_tools
+        sys.path.pop()
+        return update_tools
--- a/testing/marionette/client/marionette/client.py
+++ b/testing/marionette/client/marionette/client.py
@@ -1,16 +1,16 @@
 # 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/.
 
 import json
 import socket
 
-from errors import MarionetteException
+from errors import MarionetteException, InvalidResponseException, ErrorCodes
 
 class MarionetteClient(object):
     """ The Marionette socket client.  This speaks the same protocol
         as the remote debugger inside Gecko, in which messages are
         always preceded by the message length and a colon, e.g.,
         
         20:{'command': 'test'}
     """
@@ -44,24 +44,27 @@ class MarionetteClient(object):
         response = self.sock.recv(10)
         sep = response.find(':')
         length = response[0:sep]
         if length != '':
             response = response[sep + 1:]
             response += self._recv_n_bytes(int(length) + 1 + len(length) - 10)
             return json.loads(response)
         else:
-            raise MarionetteException("Could not successfully complete transport of message to Gecko, socket closed?")
+            raise InvalidResponseException("Could not successfully complete " \
+                                           "transport of message to Gecko, "
+                                           "socket closed?",
+                                           status=ErrorCodes.INVALID_RESPONSE)
 
-    def connect(self):
+    def connect(self, timeout=180.0):
         """ Connect to the server and process the hello message we expect
             to receive in response.
         """
         self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        self.sock.settimeout(180.0)
+        self.sock.settimeout(timeout)
         try:
             self.sock.connect((self.addr, self.port))
         except:
             # Unset self.sock so that the next attempt to send will cause
             # another connection attempt.
             self.sock = None
             raise
         hello = self.receive()
--- a/testing/marionette/client/marionette/emulator.py
+++ b/testing/marionette/client/marionette/emulator.py
@@ -1,12 +1,13 @@
 # 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/.
 
+from b2ginstance import B2GInstance
 import datetime
 from errors import *
 from mozdevice import devicemanagerADB, DMError
 from mozprocess import ProcessHandlerMixin
 import os
 import re
 import platform
 import shutil
@@ -67,25 +68,19 @@ class Emulator(object):
         self.sdcard = sdcard
         self.noWindow = noWindow
         if self.homedir is not None:
             self.homedir = os.path.expanduser(homedir)
         self.dataImg = userdata
         self.copy_userdata = self.dataImg is None
 
     def _check_for_b2g(self):
-        if self.homedir is None:
-            self.homedir = os.getenv('B2G_HOME')
-        if self.homedir is None:
-            raise Exception('Must define B2G_HOME or pass the homedir parameter')
-        self._check_file(self.homedir)
-
-        oldstyle_homedir = os.path.join(self.homedir, 'glue', 'gonk-ics')
-        if os.access(oldstyle_homedir, os.F_OK):
-            self.homedir = oldstyle_homedir
+        self.b2g = B2GInstance(homedir=self.homedir)
+        self.adb = self.b2g.adb_path
+        self.homedir = self.b2g.homedir
 
         if self.arch not in ("x86", "arm"):
             raise Exception("Emulator architecture must be one of x86, arm, got: %s" %
                             self.arch)
 
         host_dir = "linux-x86"
         if platform.system() == "Darwin":
             host_dir = "darwin-x86"
@@ -98,47 +93,40 @@ class Emulator(object):
             sysdir = "out/target/product/generic_x86"
             self.tail_args = []
         else:
             binary = os.path.join(host_bin_dir, "emulator")
             kernel = "prebuilts/qemu-kernel/arm/kernel-qemu-armv7"
             sysdir = "out/target/product/generic"
             self.tail_args = ["-cpu", "cortex-a8"]
 
-        self._check_for_adb()
         if(self.sdcard):
             self.mksdcard = os.path.join(self.homedir, host_bin_dir, "mksdcard")
             self.create_sdcard(self.sdcard)
 
         if not self.binary:
             self.binary = os.path.join(self.homedir, binary)
 
-        self._check_file(self.binary)
+        self.b2g.check_file(self.binary)
 
         self.kernelImg = os.path.join(self.homedir, kernel)
-        self._check_file(self.kernelImg)
+        self.b2g.check_file(self.kernelImg)
 
         self.sysDir = os.path.join(self.homedir, sysdir)
-        self._check_file(self.sysDir)
+        self.b2g.check_file(self.sysDir)
 
         if not self.dataImg:
             self.dataImg = os.path.join(self.sysDir, 'userdata.img')
-        self._check_file(self.dataImg)
+        self.b2g.check_file(self.dataImg)
 
     def __del__(self):
         if self.telnet:
             self.telnet.write('exit\n')
             self.telnet.read_all()
 
-    def _check_file(self, filePath):
-        if not os.access(filePath, os.F_OK):
-            raise Exception(('File not found: %s; did you pass the B2G home '
-                             'directory as the homedir parameter, or set '
-                             'B2G_HOME correctly?') % filePath)
-
     @property
     def args(self):
         qemuArgs = [self.binary,
                     '-kernel', self.kernelImg,
                     '-sysdir', self.sysDir,
                     '-data', self.dataImg]
         if self._tmp_sdcard:
             qemuArgs.extend(['-sdcard', self._tmp_sdcard])
@@ -178,37 +166,16 @@ class Emulator(object):
         sdargs = [self.mksdcard, "-l", "mySdCard", sdcard, self._tmp_sdcard]
         sd = subprocess.Popen(sdargs, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
         retcode = sd.wait()
         if retcode:
             raise Exception('unable to create sdcard : exit code %d: %s'
                             % (retcode, sd.stdout.read()))
         return None
 
-    def _check_for_adb(self):
-        host_dir = "linux-x86"
-        if platform.system() == "Darwin":
-            host_dir = "darwin-x86"
-        adb = subprocess.Popen(['which', 'adb'],
-                                stdout=subprocess.PIPE,
-                                stderr=subprocess.STDOUT)
-        if adb.wait() == 0:
-            self.adb = adb.stdout.read().strip()  # remove trailing newline
-            return
-        adb_paths = [os.path.join(self.homedir, 'glue', 'gonk', 'out', 'host',
-                                  host_dir, 'bin', 'adb'),
-                     os.path.join(self.homedir, 'out', 'host', host_dir,
-                                  'bin', 'adb'),
-                     os.path.join(self.homedir, 'bin', 'adb')]
-        for option in adb_paths:
-            if os.path.exists(option):
-                self.adb = option
-                return
-        raise Exception('adb not found!')
-
     def _run_adb(self, args):
         args.insert(0, self.adb)
         if self.port:
             args.insert(1, '-s')
             args.insert(2, 'emulator-%d' % self.port)
         adb = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
         retcode = adb.wait()
         if retcode:
@@ -308,17 +275,17 @@ waitFor(
             # older emulators.  45s *should* be enough of a delay
             # to allow telephony API's to work.
             pass
         print 'done'
         marionette.set_context(marionette.CONTEXT_CONTENT)
         marionette.delete_session()
 
     def connect(self):
-        self._check_for_adb()
+        self.adb = B2GInstance.check_adb(self.homedir)
         self.start_adb()
 
         online, offline = self._get_adb_devices()
         now = datetime.datetime.now()
         while online == set([]):
             time.sleep(1)
             if datetime.datetime.now() - now > datetime.timedelta(seconds=60):
                 raise Exception('timed out waiting for emulator to be available')
@@ -417,29 +384,47 @@ waitFor(
         push_attempts = 10
 
         print 'installing gecko binaries...'
 
         # see bug 809437 for the path that lead to this madness
         try:
             # need to remount so we can write to /system/b2g
             self._run_adb(['remount'])
+            self.dm.removeDir('/data/local/b2g')
+            self.dm.mkDir('/data/local/b2g')
             for root, dirs, files in os.walk(gecko_path):
                 for filename in files:
                     rel_path = os.path.relpath(os.path.join(root, filename), gecko_path)
-                    system_b2g_file = os.path.join('/system/b2g', rel_path)
+                    data_local_file = os.path.join('/data/local/b2g', rel_path)
                     for retry in range(1, push_attempts + 1):
-                        print 'pushing', system_b2g_file, '(attempt %s of %s)' % (retry, push_attempts)
+                        print 'pushing', data_local_file, '(attempt %s of %s)' % (retry, push_attempts)
                         try:
-                            self.dm.pushFile(os.path.join(root, filename), system_b2g_file)
+                            self.dm.pushFile(os.path.join(root, filename), data_local_file)
                             break
                         except DMError:
                             if retry == push_attempts:
                                 raise
 
+            self.dm.shellCheckOutput(['stop', 'b2g'])
+
+            for root, dirs, files in os.walk(gecko_path):
+                for filename in files:
+                    rel_path = os.path.relpath(os.path.join(root, filename), gecko_path)
+                    data_local_file = os.path.join('/data/local/b2g', rel_path)
+                    system_b2g_file = os.path.join('/system/b2g', rel_path)
+                    print 'copying', data_local_file, 'to', system_b2g_file
+                    try:
+                        self.dm.shellCheckOutput(['dd',
+                                                  'if=%s' % data_local_file,
+                                                  'of=%s' % system_b2g_file])
+                    except DMError:
+                        if retry == push_attempts:
+                            raise
+
             self.restart_b2g()
 
         except (DMError, MarionetteException):
             # Bug 812395 - raise a single exception type for these so we can
             # explicitly catch them elsewhere.
 
             # print exception, but hide from mozharness error detection
             exc = traceback.format_exc()
--- a/testing/marionette/client/marionette/errors.py
+++ b/testing/marionette/client/marionette/errors.py
@@ -18,16 +18,19 @@ class MarionetteException(Exception):
             return str(self.msg)
 
 class InstallGeckoError(MarionetteException):
     pass
 
 class TimeoutException(MarionetteException):
     pass
 
+class InvalidResponseException(MarionetteException):
+    pass
+
 class NoSuchAttributeException(MarionetteException):
     pass
 
 class JavascriptException(MarionetteException):
     pass
 
 class NoSuchElementException(MarionetteException):
     pass
@@ -88,8 +91,9 @@ class ErrorCodes(object):
     UNEXPECTED_ALERT_OPEN = 26
     NO_ALERT_OPEN = 27
     SCRIPT_TIMEOUT = 28
     INVALID_ELEMENT_COORDINATES = 29
     INVALID_SELECTOR = 32
     MOVE_TARGET_OUT_OF_BOUNDS = 34
     INVALID_XPATH_SELECTOR = 51
     INVALID_XPATH_SELECTOR_RETURN_TYPER = 52
+    INVALID_RESPONSE = 53
--- a/testing/marionette/client/marionette/runtests.py
+++ b/testing/marionette/client/marionette/runtests.py
@@ -180,17 +180,18 @@ class MarionetteTextTestRunner(unittest.
 class MarionetteTestRunner(object):
 
     def __init__(self, address=None, emulator=None, emulatorBinary=None,
                  emulatorImg=None, emulator_res='480x800', homedir=None,
                  bin=None, profile=None, autolog=False, revision=None,
                  es_server=None, rest_server=None, logger=None,
                  testgroup="marionette", noWindow=False, logcat_dir=None,
                  xml_output=None, repeat=0, perf=False, perfserv=None,
-                 gecko_path=None, testvars=None, tree=None, load_early=False):
+                 gecko_path=None, testvars=None, tree=None, load_early=False,
+                 device=None):
         self.address = address
         self.emulator = emulator
         self.emulatorBinary = emulatorBinary
         self.emulatorImg = emulatorImg
         self.emulator_res = emulator_res
         self.homedir = homedir
         self.bin = bin
         self.profile = profile
@@ -209,16 +210,17 @@ class MarionetteTestRunner(object):
         self.xml_output = xml_output
         self.repeat = repeat
         self.perf = perf
         self.perfserv = perfserv
         self.gecko_path = gecko_path
         self.testvars = None
         self.tree = tree
         self.load_early = load_early
+        self.device = device
 
         if testvars is not None:
             if not os.path.exists(testvars):
                 raise Exception('--testvars file does not exist')
 
             import json
             with open(testvars) as f:
                 self.testvars = json.loads(f.read())
@@ -587,16 +589,18 @@ def parse_options():
                       action = "store_true", dest = "noWindow",
                       default = False,
                       help = "when Marionette launches an emulator, start it "
                       "with the -no-window argument")
     parser.add_option('--logcat-dir', dest='logcat_dir', action='store',
                       help='directory to store logcat dump files')
     parser.add_option('--address', dest='address', action='store',
                       help='host:port of running Gecko instance to connect to')
+    parser.add_option('--device', dest='device', action='store',
+                      help='serial ID of a device to use for adb / fastboot')
     parser.add_option('--type', dest='type', action='store',
                       default='browser+b2g',
                       help = "The type of test to run, can be a combination "
                       "of values defined in unit-tests.ini; individual values "
                       "are combined with '+' or '-' chars.  Ex:  'browser+b2g' "
                       "means the set of tests which are compatible with both "
                       "browser and b2g; 'b2g-qemu' means the set of tests "
                       "which are compatible with b2g but do not require an "
@@ -688,17 +692,18 @@ def startTestRunner(runner_class, option
                           tree=options.tree,
                           autolog=options.autolog,
                           xml_output=options.xml_output,
                           repeat=options.repeat,
                           perf=options.perf,
                           perfserv=options.perfserv,
                           gecko_path=options.gecko_path,
                           testvars=options.testvars,
-                          load_early=options.load_early)
+                          load_early=options.load_early,
+                          device=options.device)
     runner.run_tests(tests, testtype=options.type)
     return runner
 
 def cli(runner_class=MarionetteTestRunner):
     options, tests = parse_options()
     runner = startTestRunner(runner_class, options, tests)
     if runner.failed > 0:
         sys.exit(10)
--- a/testing/marionette/client/marionette/tests/unit-tests.ini
+++ b/testing/marionette/client/marionette/tests/unit-tests.ini
@@ -14,11 +14,12 @@ skip = false
 ; webapi tests
 [include:../../../../../dom/telephony/test/marionette/manifest.ini]
 [include:../../../../../dom/battery/test/marionette/manifest.ini]
 [include:../../../../../dom/sms/tests/marionette/manifest.ini]
 [include:../../../../../dom/network/tests/marionette/manifest.ini]
 [include:../../../../../dom/system/gonk/tests/marionette/manifest.ini]
 [include:../../../../../dom/icc/tests/marionette/manifest.ini]
 [include:../../../../../dom/system/tests/marionette/manifest.ini]
+[include:../../../../../dom/contacts/tests/marionette/manifest.ini]
 
 ; marionette unit tests
 [include:unit/unit-tests.ini]
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/tests/update-tests.ini
@@ -0,0 +1,18 @@
+[DEFAULT]
+; true if the test requires an emulator, otherwise false
+qemu = false
+
+; true if the test is compatible with the browser, otherwise false
+browser = false
+
+; true if the test is compatible with b2g, otherwise false
+b2g = true
+
+; true if the test should be skipped
+skip = false
+
+; this is currently only set by high level update smoketests
+smoketest = false
+
+; AUS tests
+[include:../../../../../toolkit/mozapps/update/test/marionette/update-tests.ini]
new file mode 100644
--- /dev/null
+++ b/testing/marionette/client/marionette/venv_b2g_update_test.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# 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/.
+
+VIRTUAL_ENV_VERSION="1.8.2"
+
+PYTHON=$1
+
+# Store the current working directory so we can change back into it after
+# preparing the Marionette virtualenv
+CWD=$(pwd)
+
+if [ -z "${PYTHON}" ]
+then
+    echo "No python found"
+    exit 1
+fi
+
+# Determine the absolute path of the Marionette home folder
+MARIONETTE_HOME=$(cd `dirname $BASH_SOURCE`; dirname `pwd`)
+echo "Detected Marionette home in $MARIONETTE_HOME"
+
+# If a GECKO_OBJDIR environemnt variable exists, we will create the Python
+# virtual envirnoment there. Otherwise we create it in the PWD.
+VENV_DIR="marionette_venv"
+if [ -z $GECKO_OBJDIR ]
+then
+    VENV_DIR="$MARIONETTE_HOME/$VENV_DIR"
+else
+    VENV_DIR="$GECKO_OBJDIR/$VENV_DIR"
+fi
+
+# Check if environment exists, if not, create a virtualenv:
+if [ -d $VENV_DIR ]
+then
+  echo "Using virtual environment in $VENV_DIR"
+else
+  echo "Creating a virtual environment (version ${VIRTUAL_ENV_VERSION}) in ${VENV_DIR}"
+  curl https://raw.github.com/pypa/virtualenv/${VIRTUAL_ENV_VERSION}/virtualenv.py | ${PYTHON} - $VENV_DIR
+fi
+. $VENV_DIR/bin/activate
+
+# Updating the marionette_client needs us to change into its package folder.
+# Otherwise the call to setup.py will hang
+cd $MARIONETTE_HOME
+python setup.py develop
+cd $CWD
+
+# pop off the python parameter
+shift
+
+python $MARIONETTE_HOME/marionette/b2g_update_test.py $@
new file mode 100644
--- /dev/null
+++ b/testing/marionette/update-smoketests/flash-template.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+# 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/.
+#
+# This script is run by the update smoketest frontend
+
+ADB=${ADB:-adb}
+DEVICE=$1
+
+run_adb() {
+    $ADB -s $DEVICE $@
+}
+
+run_adb push %(flash_zip)s %(sdcard)s/_flash.zip
+run_adb shell 'echo -n "--update_package=%(sdcard_recovery)s/_flash.zip" > /cache/recovery/command'
+run_adb reboot recovery
new file mode 100755
--- /dev/null
+++ b/testing/marionette/update-smoketests/run-smoketests.py
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+#
+# 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/.
+
+import argparse
+import os
+import sys
+import tempfile
+
+from smoketest import *
+
+def main():
+    parser = argparse.ArgumentParser(prog="run-smoketests.py")
+    parser.add_argument("--build-dir", required=True,
+        help="directory that contains builds with build ID subdirectories")
+    parser.add_argument("--run-dir", default=None,
+        help="directory where partials and testvars are generated. default: "
+             "create a temp directory")
+    parser.add_argument("--tests", action='append',
+        help="which smoketest(s) to run. by default all tests are run")
+    parser.add_argument("build_ids", nargs="+", metavar="BUILD_ID",
+        help="a list of build IDs to run smoketests against. the IDs will be "
+             "sorted numerically, and partials will be generated from each to "
+             "the last update. this list of partials will be tested along with "
+             "a full update from each build to the last")
+    args = parser.parse_args()
+
+    try:
+        b2g = find_b2g()
+    except EnvironmentError, e:
+        parser.exit(1, "This tool must be run while inside the B2G directory, "
+                       "or B2G_HOME must be set in the environment.")
+
+    if not os.path.exists(args.build_dir):
+        parser.exit(1, "Build dir doesn't exist: %s" % args.build_dir)
+
+    if len(args.build_ids) < 2:
+        parser.exit(1, "This script requires at least two build IDs")
+
+    for test in args.tests:
+        if not os.path.exists(test):
+            parser.exit(1, "Smoketest does not exist: %s" % test)
+
+    try:
+        config = SmokeTestConfig(args.build_dir)
+        runner = SmokeTestRunner(config, b2g, run_dir=args.run_dir)
+        runner.run_smoketests(args.build_ids, args.tests)
+    except KeyError, e:
+        parser.exit(1, "Error: %s" % e)
+    except SmokeTestError, e:
+        parser.exit(1, "Error: %s" % e)
+
+if __name__ == "__main__":
+    main()
new file mode 100644
--- /dev/null
+++ b/testing/marionette/update-smoketests/smoketest.py
@@ -0,0 +1,195 @@
+# 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/.
+
+import json
+import os
+import subprocess
+import sys
+import tempfile
+import threading
+import zipfile
+
+from ConfigParser import ConfigParser
+
+this_dir = os.path.abspath(os.path.dirname(__file__))
+marionette_dir = os.path.dirname(this_dir)
+marionette_client_dir = os.path.join(marionette_dir, 'client', 'marionette')
+
+def find_b2g():
+    sys.path.append(marionette_client_dir)
+    from b2ginstance import B2GInstance
+    return B2GInstance()
+
+class DictObject(dict):
+    def __getattr__(self, item):
+        try:
+            return self.__getitem__(item)
+        except KeyError:
+            raise AttributeError(item)
+
+    def __getitem__(self, item):
+        value = dict.__getitem__(self, item)
+        if isinstance(value, dict):
+            return DictObject(value)
+        return value
+
+class SmokeTestError(Exception):
+    pass
+
+class SmokeTestConfigError(SmokeTestError):
+    def __init__(self, message):
+        SmokeTestError.__init__(self, 'smoketest-config.json: ' + message)
+
+class SmokeTestConfig(DictObject):
+    TOP_LEVEL_REQUIRED = ('devices', 'public_key', 'private_key')
+    DEVICE_REQUIRED    = ('system_fs_type', 'system_location', 'data_fs_type',
+                          'data_location', 'sdcard', 'sdcard_recovery',
+                          'serials')
+
+    def __init__(self, build_dir):
+        self.top_dir = build_dir
+        self.build_data = {}
+        self.flash_template = None
+
+        with open(os.path.join(build_dir, 'smoketest-config.json')) as f:
+            DictObject.__init__(self, json.loads(f.read()))
+
+        for required in self.TOP_LEVEL_REQUIRED:
+            if required not in self:
+                raise SmokeTestConfigError('No "%s" found' % required)
+
+        if len(self.devices) == 0:
+            raise SmokeTestConfigError('No devices found')
+
+        for name, device in self.devices.iteritems():
+            for required in self.DEVICE_REQUIRED:
+                if required not in device:
+                    raise SmokeTestConfigError('No "%s" found in device "%s"' % (required, name))
+
+    def get_build_data(self, device, build_id):
+        if device in self.build_data:
+            if build_id in self.build_data[device]:
+                return self.build_data[device][build_id]
+        else:
+            self.build_data[device] = {}
+
+        build_dir = os.path.join(self.top_dir, device, build_id)
+        flash_zip = os.path.join(build_dir, 'flash.zip')
+        with zipfile.ZipFile(flash_zip) as zip:
+            app_ini = ConfigParser()
+            app_ini.readfp(zip.open('system/b2g/application.ini'))
+            platform_ini = ConfigParser()
+            platform_ini.readfp(zip.open('system/b2g/platform.ini'))
+
+        build_data = self.build_data[device][build_id] = DictObject({
+            'app_version': app_ini.get('App', 'version'),
+            'app_build_id': app_ini.get('App', 'buildid'),
+            'platform_build_id': platform_ini.get('Build', 'buildid'),
+            'platform_milestone': platform_ini.get('Build', 'milestone'),
+            'complete_mar': os.path.join(build_dir, 'complete.mar'),
+            'flash_script': os.path.join(build_dir, 'flash.sh')
+        })
+
+        return build_data
+
+class SmokeTestRunner(object):
+    DEVICE_TIMEOUT = 30
+
+    def __init__(self, config, b2g, run_dir=None):
+        self.config = config
+        self.b2g = b2g
+        self.run_dir = run_dir or tempfile.mkdtemp()
+
+        update_tools = self.b2g.import_update_tools()
+        self.b2g_config = update_tools.B2GConfig()
+
+    def run_b2g_update_test(self, serial, testvars, tests):
+        b2g_update_test = os.path.join(marionette_client_dir,
+                                       'venv_b2g_update_test.sh')
+
+        if not tests:
+            tests = [os.path.join(marionette_client_dir, 'tests',
+                                  'update-tests.ini')]
+
+        args = ['bash', b2g_update_test, sys.executable,
+                '--homedir', self.b2g.homedir,
+                '--address', 'localhost:2828',
+                '--type', 'b2g+smoketest',
+                '--device', serial,
+                '--testvars', testvars]
+        args.extend(tests)
+
+        print ' '.join(args)
+        subprocess.check_call(args)
+
+    def build_testvars(self, device, start_id, finish_id):
+        run_dir = os.path.join(self.run_dir, device, start_id, finish_id)
+        if not os.path.exists(run_dir):
+            os.makedirs(run_dir)
+
+        start_data = self.config.get_build_data(device, start_id)
+        finish_data = self.config.get_build_data(device, finish_id)
+
+        partial_mar = os.path.join(run_dir, 'partial.mar')
+        if not os.path.exists(partial_mar):
+            build_gecko_mar = os.path.join(self.b2g.update_tools,
+                                           'build-gecko-mar.py')
+            subprocess.check_call([build_gecko_mar,
+                                   '--from', start_data.complete_mar,
+                                   '--to', finish_data.complete_mar,
+                                   partial_mar])
+        finish_data['partial_mar'] = partial_mar
+
+        testvars = os.path.join(run_dir, 'testvars.json')
+        if not os.path.exists(testvars):
+            open(testvars, 'w').write(json.dumps({
+                'start': start_data,
+                'finish': finish_data
+            }))
+
+        return testvars
+
+    def wait_for_device(self, device):
+        for serial in self.config.devices[device].serials:
+            proc = subprocess.Popen([self.b2g.adb_path, '-s', serial,
+                                     'wait-for-device'])
+            def wait_for_adb():
+                proc.communicate()
+
+            thread = threading.Thread(target=wait_for_adb)
+            thread.start()
+            thread.join(self.DEVICE_TIMEOUT)
+
+            if thread.isAlive():
+                print >>sys.stderr, '%s device %s is not recognized by ADB, ' \
+                                    'trying next device' % (device, serial)
+                proc.kill()
+                thread.join()
+                continue
+
+            return serial
+        return None
+
+    def run_smoketests_for_device(self, device, start_id, finish_id, tests):
+        testvars = self.build_testvars(device, start_id, finish_id)
+        serial = self.wait_for_device(device)
+        if not serial:
+            raise SmokeTestError('No connected serials for device "%s" could ' \
+                                 'be found' % device)
+
+        try:
+            self.run_b2g_update_test(serial, testvars, tests)
+        except subprocess.CalledProcessError:
+            print >>sys.stderr, 'SMOKETEST-FAIL | START=%s | FINISH=%s | ' \
+                                'DEVICE=%s/%s | %s' % (start_id, finish_id,
+                                                       device, serial, testvars)
+
+    def run_smoketests(self, build_ids, tests):
+        build_ids.sort()
+
+        latest_build_id = build_ids.pop(-1)
+        for build_id in build_ids:
+            for device in self.config.devices:
+                self.run_smoketests_for_device(device, build_id,
+                                               latest_build_id, tests)
new file mode 100755
--- /dev/null
+++ b/testing/marionette/update-smoketests/stage-update.py
@@ -0,0 +1,95 @@
+#!/usr/bin/env python
+#
+# 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/.
+
+import argparse
+import json
+import os
+import shutil
+import stat
+import subprocess
+import sys
+
+from ConfigParser import ConfigParser
+from smoketest import *
+
+this_dir = os.path.abspath(os.path.dirname(__file__))
+
+def stage_update(device, stage_dir):
+    config = SmokeTestConfig(stage_dir)
+    if device not in config.devices:
+        raise SmokeTestConfigError('Device "%s" not found' % device)
+
+    device_data = config.devices[device]
+
+    b2g_config = b2g.import_update_tools().B2GConfig()
+    target_out_dir = os.path.join(b2g.homedir, 'out', 'target', 'product', device)
+    app_ini = os.path.join(b2g_config.gecko_objdir, 'dist', 'bin',
+                           'application.ini')
+    gecko_mar = os.path.join(b2g_config.gecko_objdir, 'dist', 'b2g-update',
+                             'b2g-gecko-update.mar')
+
+    build_data = ConfigParser()
+    build_data.read(app_ini)
+    build_id = build_data.get('App', 'buildid')
+    app_version = build_data.get('App', 'version')
+
+    build_dir = os.path.join(config.top_dir, device, build_id)
+    if not os.path.exists(build_dir):
+        os.makedirs(build_dir)
+
+    if not os.path.exists(build_dir):
+        raise SmokeTestError('Couldn\'t create directory: %s' % build_dir)
+
+    build_flash_fota = os.path.join(b2g.update_tools, 'build-flash-fota.py')
+
+    flash_zip = os.path.join(build_dir, 'flash.zip')
+
+    print 'Building flash zip for device %s, version %s, build %s...' % \
+          (device, app_version, build_id)
+
+    subprocess.check_call([build_flash_fota,
+        '--system-dir', os.path.join(target_out_dir, 'system'),
+        '--system-fs-type', device_data.system_fs_type,
+        '--system-location', device_data.system_location,
+        '--data-fs-type', device_data.data_fs_type,
+        '--data-location', device_data.data_location,
+        '--output', flash_zip])
+
+    complete_mar = os.path.join(build_dir, 'complete.mar')
+    shutil.copy(gecko_mar, complete_mar)
+
+    flash_template = open(os.path.join(this_dir, 'flash-template.sh')).read()
+    flash_script = os.path.join(build_dir, 'flash.sh')
+    open(os.path.join(build_dir, 'flash.sh'), 'w').write(flash_template % {
+        'flash_zip': flash_zip,
+        'sdcard': device_data.sdcard,
+        'sdcard_recovery': device_data.sdcard_recovery
+    })
+    os.chmod(flash_script, stat.S_IRUSR | stat.S_IWUSR | stat.S_IXUSR |
+                           stat.S_IRGRP | stat.S_IXGRP |
+                           stat.S_IROTH | stat.S_IXOTH)
+
+def main():
+    parser = argparse.ArgumentParser(prog='stage-update.py')
+    parser.add_argument('device', help='device name for staging')
+    parser.add_argument('stage_dir',
+        help='directory to stage update and flash script for smoketests')
+    args = parser.parse_args()
+
+    try:
+        global b2g
+        b2g = find_b2g()
+    except EnvironmentError, e:
+        parser.exit(1, 'This tool must be run while inside the B2G directory, '
+                       'or B2G_HOME must be set in the environment.')
+
+    try:
+        stage_update(args.device, args.stage_dir)
+    except SmokeTestError, e:
+        parser.exit(1, str(e))
+
+if __name__ == '__main__':
+    main()
--- a/toolkit/components/places/History.cpp
+++ b/toolkit/components/places/History.cpp
@@ -1397,18 +1397,17 @@ StoreAndNotifyEmbedVisit(VisitData& aPla
     (void)NS_ProxyRelease(mainThread, aCallback, true);
   }
 
   VisitData noReferrer;
   nsCOMPtr<nsIRunnable> event = new NotifyVisitObservers(aPlace, noReferrer);
   (void)NS_DispatchToMainThread(event);
 }
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(HistoryLinksHashtableMallocSizeOf,
-                                     "history-links-hashtable")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(HistoryLinksHashtableMallocSizeOf)
 
 int64_t GetHistoryObserversSize()
 {
   History* history = History::GetService();
   return history ?
          history->SizeOfIncludingThis(HistoryLinksHashtableMallocSizeOf) : 0;
 }
 
--- a/toolkit/components/remote/nsXRemoteService.cpp
+++ b/toolkit/components/remote/nsXRemoteService.cpp
@@ -53,17 +53,17 @@ const unsigned char kRemoteVersion[] = "
 #define TO_LITTLE_ENDIAN32(x) \
     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >> 8) | \
     (((x) & 0x0000ff00) << 8) | (((x) & 0x000000ff) << 24))
 #else
 #define TO_LITTLE_ENDIAN32(x) (x)
 #endif
 
 // Minimize the roundtrips to the X server by getting all the atoms at once
-static char *XAtomNames[] = {
+static const char *XAtomNames[] = {
   MOZILLA_VERSION_PROP,
   MOZILLA_LOCK_PROP,
   MOZILLA_COMMAND_PROP,
   MOZILLA_RESPONSE_PROP,
   MOZILLA_USER_PROP,
   MOZILLA_PROFILE_PROP,
   MOZILLA_PROGRAM_PROP,
   MOZILLA_COMMANDLINE_PROP
@@ -272,18 +272,19 @@ nsXRemoteService::HandleCommand(char* aC
 
   if (!command.EqualsLiteral("ping")) {
     nsAutoCString desktopStartupID;
     nsDependentCString cmd(aCommand);
     FindExtensionParameterInCommand("DESKTOP_STARTUP_ID",
                                     cmd, '\n',
                                     &desktopStartupID);
 
-    char* argv[3] = {"dummyappname", "-remote", aCommand};
-    rv = cmdline->Init(3, argv, nullptr, nsICommandLine::STATE_REMOTE_EXPLICIT);
+    const char* argv[3] = {"dummyappname", "-remote", aCommand};
+    rv = cmdline->Init(3, const_cast<char**>(argv), nullptr,
+                       nsICommandLine::STATE_REMOTE_EXPLICIT);
     if (NS_FAILED(rv))
       return "509 internal error";
 
     if (aWindow)
       cmdline->SetWindowContext(aWindow);
 
     if (sRemoteImplementation)
       sRemoteImplementation->SetDesktopStartupIDOrTimestamp(desktopStartupID, aTimestamp);
@@ -367,18 +368,18 @@ nsXRemoteService::HandleCommandLine(char
 }
 
 void
 nsXRemoteService::EnsureAtoms(void)
 {
   if (sMozVersionAtom)
     return;
 
-  XInternAtoms(mozilla::DefaultXDisplay(), XAtomNames, ArrayLength(XAtomNames),
-               False, XAtoms);
+  XInternAtoms(mozilla::DefaultXDisplay(), const_cast<char**>(XAtomNames),
+               ArrayLength(XAtomNames), False, XAtoms);
 
   int i = 0;
   sMozVersionAtom     = XAtoms[i++];
   sMozLockAtom        = XAtoms[i++];
   sMozCommandAtom     = XAtoms[i++];
   sMozResponseAtom    = XAtoms[i++];
   sMozUserAtom        = XAtoms[i++];
   sMozProfileAtom     = XAtoms[i++];
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -2514,10 +2514,34 @@
     "n_buckets": 15,
     "description": "Time (ms) it takes to figure out extension last modified time"
   },
   "TELEMETRY_MEMORY_REPORTER_MS": {
     "kind": "exponential",
     "high": "5000",
     "n_buckets": 10,
     "description": "Time (ms) it takes to run memory reporters when sending a telemetry ping"
+  },
+  "SSL_SUCCESFUL_CERT_VALIDATION_TIME_LIBPKIX" : {
+    "kind": "exponential",
+    "high": "60000",
+    "n_buckets": 50,
+    "description": "Time spent on a successful cert verification in libpix mode (ms)"
+  },
+  "SSL_SUCCESFUL_CERT_VALIDATION_TIME_CLASSIC" : {
+    "kind": "exponential",
+    "high": "60000",
+    "n_buckets": 50,
+    "description": "Time spent on a successful cert  verification in classic mode (ms)"
+  },
+  "SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_LIBPKIX" : {
+    "kind": "exponential",
+    "high": "60000",
+    "n_buckets": 50,
+    "description": "Time spent on an initially failed cert verification in libpix mode (ms)"
+  },
+  "SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_CLASSIC" : {
+    "kind": "exponential",
+    "high": "60000",
+    "n_buckets": 50,
+    "description": "Time spent on an initially failed cert  verification in classic mode (ms)"
   }
 }
--- a/toolkit/components/telemetry/Telemetry.cpp
+++ b/toolkit/components/telemetry/Telemetry.cpp
@@ -324,17 +324,17 @@ private:
   bool mCachedTelemetryData;
   uint32_t mLastShutdownTime;
   std::vector<nsCOMPtr<nsIFetchTelemetryDataCallback> > mCallbacks;
   friend class nsFetchTelemetryData;
 };
 
 TelemetryImpl*  TelemetryImpl::sTelemetry = NULL;
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(TelemetryMallocSizeOf, "telemetry")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(TelemetryMallocSizeOf)
 
 size_t
 TelemetryImpl::SizeOfIncludingThis(nsMallocSizeOfFun aMallocSizeOf)
 {
   size_t n = 0;
   n += aMallocSizeOf(this);
   // Ignore the hashtables in mAddonMap; they are not significant.
   n += mAddonMap.SizeOfExcludingThis(impl<AddonEntryType>::SizeOfEntryExcludingThis,
--- a/toolkit/components/url-classifier/Classifier.cpp
+++ b/toolkit/components/url-classifier/Classifier.cpp
@@ -773,42 +773,42 @@ Classifier::GetLookupCache(const nsACStr
   }
   mLookupCaches.AppendElement(cache);
   return cache;
 }
 
 nsresult
 Classifier::ReadNoiseEntries(const Prefix& aPrefix,
                              const nsACString& aTableName,
-                             int32_t aCount,
+                             uint32_t aCount,
                              PrefixArray* aNoiseEntries)
 {
   LookupCache *cache = GetLookupCache(aTableName);
   if (!cache) {
     return NS_ERROR_FAILURE;
   }
 
   nsTArray<uint32_t> prefixes;
   nsresult rv = cache->GetPrefixes(&prefixes);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  int32_t idx = prefixes.BinaryIndexOf(aPrefix.ToUint32());
+  uint32_t idx = prefixes.BinaryIndexOf(aPrefix.ToUint32());
 
   if (idx == nsTArray<uint32_t>::NoIndex) {
     NS_WARNING("Could not find prefix in PrefixSet during noise lookup");
     return NS_ERROR_FAILURE;
   }
 
   idx -= idx % aCount;
 
-  for (int32_t i = 0; (i < aCount) && ((idx+i) < prefixes.Length()); i++) {
+  for (uint32_t i = 0; (i < aCount) && ((idx+i) < prefixes.Length()); i++) {
     Prefix newPref;
     newPref.FromUint32(prefixes[idx+i]);
     if (newPref != aPrefix) {
       aNoiseEntries->AppendElement(newPref);
     }
   }
 
   return NS_OK;
 }
 
-}
-}
+} // namespace safebrowsing
+} // namespace mozilla
--- a/toolkit/components/url-classifier/Classifier.h
+++ b/toolkit/components/url-classifier/Classifier.h
@@ -62,17 +62,17 @@ public:
   void SetFreshTime(uint32_t aTime) { mFreshTime = aTime; }
   void SetPerClientRandomize(bool aRandomize) { mPerClientRandomize = aRandomize; }
   /*
    * Get a bunch of extra prefixes to query for completion
    * and mask the real entry being requested
    */
   nsresult ReadNoiseEntries(const Prefix& aPrefix,
                             const nsACString& aTableName,
-                            int32_t aCount,
+                            uint32_t aCount,
                             PrefixArray* aNoiseEntries);
 private:
   void DropStores();
   nsresult CreateStoreDirectory();
   nsresult SetupPathNames();
   nsresult RecoverBackups();
   nsresult CleanToDelete();
   nsresult BackupTables();
--- a/toolkit/components/url-classifier/Entries.h
+++ b/toolkit/components/url-classifier/Entries.h
@@ -5,26 +5,16 @@
 
 #ifndef SBEntries_h__
 #define SBEntries_h__
 
 #include "nsTArray.h"
 #include "nsString.h"
 #include "nsICryptoHash.h"
 #include "nsNetUtil.h"
-#include "prlog.h"
-
-extern PRLogModuleInfo *gUrlClassifierDbServiceLog;
-#if defined(PR_LOGGING)
-#define LOG(args) PR_LOG(gUrlClassifierDbServiceLog, PR_LOG_DEBUG, args)
-#define LOG_ENABLED() PR_LOG_TEST(gUrlClassifierDbServiceLog, 4)
-#else
-#define LOG(args)
-#define LOG_ENABLED() (false)
-#endif
 
 #if DEBUG
 #include "plbase64.h"
 #endif
 
 namespace mozilla {
 namespace safebrowsing {
 
@@ -275,11 +265,11 @@ nsresult
 WriteTArray(nsIOutputStream* aStream, nsTArray<T>& aArray)
 {
   uint32_t written;
   return aStream->Write(reinterpret_cast<char*>(aArray.Elements()),
                         aArray.Length() * sizeof(T),
                         &written);
 }
 
-}
-}
-#endif
+} // namespace safebrowsing
+} // namespace mozilla
+#endif // SBEntries_h__
--- a/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierDBService.cpp
@@ -111,17 +111,17 @@ class nsUrlClassifierDBServiceWorker MOZ
 {
 public:
   nsUrlClassifierDBServiceWorker();
 
   NS_DECL_ISUPPORTS
   NS_DECL_NSIURLCLASSIFIERDBSERVICE
   NS_DECL_NSIURLCLASSIFIERDBSERVICEWORKER
 
-  nsresult Init(int32_t gethashNoise, nsCOMPtr<nsIFile> aCacheDir,
+  nsresult Init(uint32_t aGethashNoise, nsCOMPtr<nsIFile> aCacheDir,
                 bool aPerClientRandomize);
 
   // Queue a lookup for the worker to perform, called in the main thread.
   nsresult QueueLookup(const nsACString& lookupKey,
                        nsIUrlClassifierLookupCallback* callback);
 
   // Handle any queued-up lookups.  We call this function during long-running
   // update operations to prevent lookups from blocking for too long.
@@ -145,17 +145,17 @@ private:
   // Reset the in-progress update
   void ResetUpdate();
 
   // Perform a classifier lookup for a given url.
   nsresult DoLookup(const nsACString& spec, nsIUrlClassifierLookupCallback* c);
 
   nsresult AddNoise(const Prefix aPrefix,
                     const nsCString tableName,
-                    int32_t aCount,
+                    uint32_t aCount,
                     LookupResultArray& results);
 
   nsCOMPtr<nsICryptoHash> mCryptoHash;
 
   nsAutoPtr<Classifier> mClassifier;
   nsAutoPtr<ProtocolParser> mProtocolParser;
 
   // Directory where to store the SB databases.
@@ -179,17 +179,17 @@ private:
 
   // The client key with which the data from the server will be MAC'ed.
   nsCString mUpdateClientKey;
 
   // The client-specific hash key to rehash
   uint32_t mHashKey;
 
   // The number of noise entries to add to the set of lookup results.
-  int32_t mGethashNoise;
+  uint32_t mGethashNoise;
 
   // Randomize clients with a key or not.
   bool mPerClientRandomize;
 
   // Pending lookups are stored in a queue for processing.  The queue
   // is protected by mPendingLookupLock.
   Mutex mPendingLookupLock;
 
@@ -219,21 +219,21 @@ nsUrlClassifierDBServiceWorker::nsUrlCla
 nsUrlClassifierDBServiceWorker::~nsUrlClassifierDBServiceWorker()
 {
   NS_ASSERTION(!mClassifier,
                "Db connection not closed, leaking memory!  Call CloseDb "
                "to close the connection.");
 }
 
 nsresult
-nsUrlClassifierDBServiceWorker::Init(int32_t gethashNoise,
+nsUrlClassifierDBServiceWorker::Init(uint32_t aGethashNoise,
                                      nsCOMPtr<nsIFile> aCacheDir,
                                      bool aPerClientRandomize)
 {
-  mGethashNoise = gethashNoise;
+  mGethashNoise = aGethashNoise;
   mCacheDir = aCacheDir;
   mPerClientRandomize = aPerClientRandomize;
 
   ResetUpdate();
 
   return NS_OK;
 }
 
@@ -352,17 +352,17 @@ nsUrlClassifierDBServiceWorker::HandlePe
   }
 
   return NS_OK;
 }
 
 nsresult
 nsUrlClassifierDBServiceWorker::AddNoise(const Prefix aPrefix,
                                          const nsCString tableName,
-                                         int32_t aCount,
+                                         uint32_t aCount,
                                          LookupResultArray& results)
 {
   if (aCount < 1) {
     return NS_OK;
   }
 
   PrefixArray noiseEntries;
   nsresult rv = mClassifier->ReadNoiseEntries(aPrefix, tableName,
@@ -1124,41 +1124,41 @@ nsUrlClassifierDBService::Init()
     gUrlClassifierDbServiceLog = PR_NewLogModule("UrlClassifierDbService");
 #endif
 
   nsresult rv;
 
   // Should we check document loads for malware URIs?
   nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
 
-  int32_t gethashNoise = 0;
+  uint32_t gethashNoise = 0;
   if (prefs) {
     bool tmpbool;
     rv = prefs->GetBoolPref(CHECK_MALWARE_PREF, &tmpbool);
     mCheckMalware = NS_SUCCEEDED(rv) ? tmpbool : CHECK_MALWARE_DEFAULT;
 
     prefs->AddObserver(CHECK_MALWARE_PREF, this, false);
 
     rv = prefs->GetBoolPref(CHECK_PHISHING_PREF, &tmpbool);
     mCheckPhishing = NS_SUCCEEDED(rv) ? tmpbool : CHECK_PHISHING_DEFAULT;
 
     prefs->AddObserver(CHECK_PHISHING_PREF, this, false);
 
-    if (NS_FAILED(prefs->GetIntPref(GETHASH_NOISE_PREF, &gethashNoise))) {
-      gethashNoise = GETHASH_NOISE_DEFAULT;
-    }
+    int32_t tmpint;
+    rv = prefs->GetIntPref(GETHASH_NOISE_PREF, &tmpint);
+    gethashNoise = (NS_SUCCEEDED(rv) && tmpint >= 0) ?
+      static_cast<uint32_t>(tmpint) : GETHASH_NOISE_DEFAULT;
 
     nsXPIDLCString tmpstr;
     if (NS_SUCCEEDED(prefs->GetCharPref(GETHASH_TABLES_PREF, getter_Copies(tmpstr)))) {
       SplitTables(tmpstr, mGethashWhitelist);
     }
 
     prefs->AddObserver(GETHASH_TABLES_PREF, this, false);
 
-    int32_t tmpint;
     rv = prefs->GetIntPref(CONFIRM_AGE_PREF, &tmpint);
     PR_ATOMIC_SET(&gFreshnessGuarantee, NS_SUCCEEDED(rv) ? tmpint : CONFIRM_AGE_DEFAULT_SEC);
 
     prefs->AddObserver(CONFIRM_AGE_PREF, this, false);
 
     rv = prefs->GetBoolPref(RANDOMIZE_CLIENT_PREF, &tmpbool);
     mPerClientRandomize = NS_SUCCEEDED(rv) ? tmpbool : RANDOMIZE_CLIENT_DEFAULT;
 
--- a/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp
+++ b/toolkit/components/url-classifier/nsUrlClassifierPrefixSet.cpp
@@ -44,18 +44,17 @@ public:
 
 private:
   nsCString mPath;
   nsUrlClassifierPrefixSet* mParent;
 };
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsPrefixSetReporter, nsIMemoryReporter)
 
-NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(StoragePrefixSetMallocSizeOf,
-                                     "storage/prefixset")
+NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(StoragePrefixSetMallocSizeOf)
 
 nsPrefixSetReporter::nsPrefixSetReporter(nsUrlClassifierPrefixSet* aParent,
                                          const nsACString& aName)
 : mParent(aParent)
 {
   mPath.Assign(NS_LITERAL_CSTRING("explicit/storage/prefixset"));
   if (!aName.IsEmpty()) {
     mPath.Append("/");
--- a/toolkit/library/Makefile.in
+++ b/toolkit/library/Makefile.in
@@ -455,16 +455,20 @@ OS_LIBS += \
   -lsensorservice \
   -ldbus \
   -lstagefright \
   -lstagefright_omx \
   -lbinder \
   $(NULL)
 endif
 
+ifdef MOZ_WMF
+OS_LIBS += $(call EXPAND_LIBNAME,mfuuid)
+endif
+
 EXTRA_DEPS += \
   $(topsrcdir)/intl/unicharutil/util/objs.mk \
   $(topsrcdir)/rdf/util/src/objs.mk \
   $(NULL)
 
 CPPSRCS += \
   $(INTL_UNICHARUTIL_UTIL_LCPPSRCS) \
   $(RDF_UTIL_SRC_LCPPSRCS) \
--- a/toolkit/mozapps/installer/packager.mk
+++ b/toolkit/mozapps/installer/packager.mk
@@ -740,27 +740,21 @@ endif
 	@$(NSINSTALL) -D $(DEPTH)/installer-stage/core
 	@cp -av $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)/. $(DEPTH)/installer-stage/core
 	@(cd $(DEPTH)/installer-stage/core && $(CREATE_PRECOMPLETE_CMD))
 ifdef MOZ_SIGN_PREPARED_PACKAGE_CMD
 # The && true is necessary to make sure Pymake spins a shell
 	$(MOZ_SIGN_PREPARED_PACKAGE_CMD) $(DEPTH)/installer-stage && true
 endif
 
-elfhack:
-ifdef USE_ELF_HACK
-	@echo ===
-	@echo === If you get failures below, please file a bug describing the error
-	@echo === and your environment \(compiler and linker versions\), and use
-	@echo === --disable-elf-hack until this is fixed.
-	@echo ===
-	cd $(DIST)/bin; find . -name "*$(DLL_SUFFIX)" | xargs ../../build/unix/elfhack/elfhack
+ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))
+ELF_HACK_FLAGS = --fill
 endif
 
-stage-package: $(MOZ_PKG_MANIFEST) $(MOZ_PKG_REMOVALS_GEN) elfhack
+stage-package: $(MOZ_PKG_MANIFEST) $(MOZ_PKG_REMOVALS_GEN)
 	@rm -rf $(DIST)/$(PKG_PATH)$(PKG_BASENAME).tar $(DIST)/$(PKG_PATH)$(PKG_BASENAME).dmg $@ $(EXCLUDE_LIST)
 ifndef MOZ_FAST_PACKAGE
 	@rm -rf $(DIST)/$(MOZ_PKG_DIR)
 endif
 # NOTE: this must be a tar now that dist links into the tree so that we
 # do not strip the binaries actually in the tree.
 	@echo "Creating package directory..."
 	if ! test -d $(DIST)/$(MOZ_PKG_DIR) ; then \
@@ -838,16 +832,25 @@ ifndef PKG_SKIP_STRIP
 				! -name "*.dat" \
 				! -name "*.tbl" \
 				! -name "*.src" \
 				! -name "*.reg" \
 				$(PLATFORM_EXCLUDE_LIST) \
 				-exec $(STRIP) $(STRIP_FLAGS) {} >/dev/null 2>&1 \;
   endif
 endif # PKG_SKIP_STRIP
+ifdef USE_ELF_HACK
+	@echo ===
+	@echo === If you get failures below, please file a bug describing the error
+	@echo === and your environment \(compiler and linker versions\), and use
+	@echo === --disable-elf-hack until this is fixed.
+	@echo ===
+	cd $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR); find . -name "*$(DLL_SUFFIX)" | xargs ../../build/unix/elfhack/elfhack $(ELF_HACK_FLAGS)
+endif
+
 # We always sign nss because we don't do it from security/manager anymore
 	@$(SIGN_NSS)
 	@echo "Removing unpackaged files..."
 ifdef NO_PKG_FILES
 	cd $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH); rm -rf $(NO_PKG_FILES)
 endif
 ifdef MOZ_PKG_REMOVALS
 	$(SYSINSTALL) $(IFLAGS1) $(MOZ_PKG_REMOVALS_GEN) $(DIST)/$(STAGEPATH)$(MOZ_PKG_DIR)$(_BINPATH)
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/marionette/update-smoketests.ini
@@ -0,0 +1,5 @@
+[DEFAULT]
+smoketest = true
+
+[update_smoketest_ota_simple.py]
+[update_smoketest_ota_same_version.py]
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/marionette/update-tests.ini
@@ -0,0 +1,7 @@
+[DEFAULT]
+smoketest = false
+
+[update_test_ota_simple.py]
+
+; smoketests
+[include:update-smoketests.ini]
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/marionette/update_smoketest_ota_same_version.js
@@ -0,0 +1,25 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function testSameVersion() {
+  let mozSettings = window.navigator.mozSettings;
+  let forceSent = false;
+
+  mozSettings.addObserver("gecko.updateStatus", function statusObserver(setting) {
+    if (!forceSent) {
+      return;
+    }
+
+    mozSettings.removeObserver("gecko.updateStatus", statusObserver);
+    is(setting.settingValue, "already-latest-version");
+    cleanUp();
+  });
+
+  sendContentEvent("force-update-check");
+  forceSent = true;
+}
+
+// Update lifecycle callbacks
+function preUpdate() {
+  testSameVersion();
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/marionette/update_smoketest_ota_same_version.py
@@ -0,0 +1,17 @@
+from b2g_update_test import B2GUpdateSmokeTestCase, OTA, FOTA
+import os
+
+this_dir = os.path.dirname(__file__)
+
+class OTASameVersion(B2GUpdateSmokeTestCase):
+    JS_PATH          = os.path.join(this_dir, "update_smoketest_ota_same_version.js")
+    START_WITH_BUILD = "finish"
+    APPLY            = None
+
+    def test_ota_same_version_complete(self):
+        self.stage_update(build="finish", mar="complete")
+        self.execute_smoketest()
+
+    def test_ota_same_version_partial(self):
+        self.stage_update(build="finish", mar="partial")
+        self.execute_smoketest()
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/marionette/update_smoketest_ota_simple.js
@@ -0,0 +1,62 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function testForceCheck() {
+  addChromeEventListener("update-available", function(evt) {
+    isFinishUpdate(evt.detail);
+    statusSettingIs("check-complete", testDownload);
+    return true;
+  });
+  sendContentEvent("force-update-check");
+}
+
+function testDownload() {
+  let gotDownloading = false;
+  let progress = 0, total = 0;
+
+  addChromeEventListener("update-downloading", function(evt) {
+    gotDownloading = true;
+    return true;
+  });
+  addChromeEventListener("update-progress", function(evt) {
+    progress = evt.detail.progress;
+    total = evt.detail.total;
+    if (total == progress) {
+      ok(gotDownloading);
+      return true;
+    }
+    return false;
+  });
+  addChromeEventListener("update-downloaded", function(evt) {
+    ok(gotDownloading);
+    is(progress, total);
+    return true;
+  });
+  addChromeEventListener("update-prompt-apply", function(evt) {
+    isStartToFinishUpdate(evt.detail);
+    cleanUp();
+  });
+  sendContentEvent("update-available-result", {
+    result: "download"
+  });
+}
+
+function testApplied() {
+  let finish = getFinishBuild();
+  is(Services.appinfo.version, finish.app_version,
+     "Services.appinfo.version should be " + finish.app_version);
+  is(Services.appinfo.platformVersion, finish.platform_milestone,
+     "Services.appinfo.platformVersion should be " + finish.platform_milestone);
+  is(Services.appinfo.appBuildID, finish.app_build_id,
+     "Services.appinfo.appBuildID should be " + finish.app_build_id);
+  cleanUp();
+}
+
+// Update lifecycle callbacks
+function preUpdate() {
+  testForceCheck();
+}
+
+function postUpdate() {
+  testApplied();
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/marionette/update_smoketest_ota_simple.py
@@ -0,0 +1,21 @@
+from b2g_update_test import B2GUpdateSmokeTestCase, OTA, FOTA
+import os
+
+this_dir = os.path.dirname(__file__)
+
+class OTASimple(B2GUpdateSmokeTestCase):
+    JS_PATH          = os.path.join(this_dir, "update_smoketest_ota_simple.js")
+    START_WITH_BUILD = "start"
+    STAGE_PREFS      = {
+        "b2g.update.apply-idle-timeout": 0,
+        "b2g.update.apply-prompt-timeout": 5 * 60 * 1000
+    }
+    TIMEOUT     = 5 * 60 * 1000
+
+    def test_ota_simple_complete(self):
+        self.stage_update(build="finish", mar="complete")
+        self.execute_smoketest()
+
+    def test_ota_simple_partial(self):
+        self.stage_update(build="finish", mar="partial")
+        self.execute_smoketest()
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/marionette/update_test_ota_simple.js
@@ -0,0 +1,62 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+function testForceCheck() {
+  addChromeEventListener("update-available", function(evt) {
+    let update = evt.detail;
+    is(update.displayVersion, "99.0");
+    is(update.isOSUpdate, false);
+    statusSettingIs("check-complete", testDownload);
+    return true;
+  });
+  sendContentEvent("force-update-check");
+}
+
+function testDownload() {
+  let gotDownloading = false;
+  let progress = 0, total = 0;
+
+  addChromeEventListener("update-downloading", function(evt) {
+    gotDownloading = true;
+    return true;
+  });
+  addChromeEventListener("update-progress", function(evt) {
+    progress = evt.detail.progress;
+    total = evt.detail.total;
+    if (total == progress) {
+      ok(gotDownloading);
+      return true;
+    }
+    return false;
+  });
+  addChromeEventListener("update-downloaded", function(evt) {
+    ok(gotDownloading);
+    is(progress, total);
+    return true;
+  });
+  addChromeEventListener("update-prompt-apply", function(evt) {
+    let update = evt.detail;
+    is(update.displayVersion, "99.0");
+    is(update.isOSUpdate, false);
+    cleanUp();
+  });
+  sendContentEvent("update-available-result", {
+    result: "download"
+  });
+}
+
+function testApplied() {
+  let updateFile = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile);
+  updateFile.initWithPath("/system/b2g/update_test/UpdateTestAddFile");
+  ok(updateFile.exists());
+  cleanUp();
+}
+
+// Update lifecycle callbacks
+function preUpdate() {
+  testForceCheck();
+}
+
+function postUpdate() {
+  testApplied();
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/update/test/marionette/update_test_ota_simple.py
@@ -0,0 +1,20 @@
+from b2g_update_test import B2GUpdateTestCase, OTA, FOTA
+import os
+
+update_test_dir = os.path.dirname(os.path.dirname(__file__))
+
+class UpdateTestOTASimple(B2GUpdateTestCase):
+    def setUp(self):
+        prefs = {
+            "b2g.update.apply-idle-timeout": 0
+        }
+        mar_path = os.path.join(update_test_dir, "unit", "data", "simple.mar")
+        self.stage_update(complete_mar=mar_path, prefs=prefs)
+        B2GUpdateTestCase.setUp(self)
+
+    def test_ota_simple(self):
+        self.marionette.set_script_timeout(60 * 1000 * 5)
+
+        ota_simple_js = os.path.join(os.path.dirname(__file__),
+                                     "update_test_ota_simple.js")
+        self.execute_update_test(ota_simple_js, apply=OTA)
--- a/view/src/Makefile.in
+++ b/view/src/Makefile.in
@@ -11,17 +11,19 @@ VPATH		= @srcdir@
 include $(DEPTH)/config/autoconf.mk
 
 MODULE		= view
 LIBRARY_NAME	= gkview_s
 FORCE_STATIC_LIB = 1
 MODULE_NAME	= nsViewModule
 GRE_MODULE	= 1
 LIBXUL_LIBRARY	= 1
+ifndef _MSC_VER
 FAIL_ON_WARNINGS := 1
+endif # !_MSC_VER
 
 DEFINES += -D_IMPL_NS_LAYOUT
 
 CPPSRCS		= \
 		nsView.cpp \
 		nsViewManager.cpp \
 		$(NULL)
 
--- a/widget/xpwidgets/nsBaseWidget.cpp
+++ b/widget/xpwidgets/nsBaseWidget.cpp
@@ -120,17 +120,17 @@ nsBaseWidget::nsBaseWidget()
 static void DeferredDestroyCompositor(CompositorParent* aCompositorParent,
                               CompositorChild* aCompositorChild)
 {
     aCompositorChild->Destroy();
     aCompositorParent->Release();
     aCompositorChild->Release();
 }
 
-void nsBaseWidget::DestroyCompositor() 
+void nsBaseWidget::DestroyCompositor()
 {
   if (mCompositorChild) {
     mCompositorChild->SendWillStop();
 
     // The call just made to SendWillStop can result in IPC from the
     // CompositorParent to the CompositorChild (e.g. caused by the destruction
     // of shared memory). We need to ensure this gets processed by the
     // CompositorChild before it gets destroyed. It suffices to ensure that
@@ -268,17 +268,17 @@ nsBaseWidget::CreateChild(const nsIntRec
       NS_SUCCEEDED(widget->Create(parent, nativeParent, aRect,
                                   aContext, aInitData))) {
     return widget.forget();
   }
 
   return nullptr;
 }
 
-// Attach a view to our widget which we'll send events to. 
+// Attach a view to our widget which we'll send events to.
 NS_IMETHODIMP
 nsBaseWidget::AttachViewToTopLevel(bool aUseAttachedEvents,
                                    nsDeviceContext *aContext)
 {
   NS_ASSERTION((mWindowType == eWindowType_toplevel ||
                 mWindowType == eWindowType_dialog ||
                 mWindowType == eWindowType_invisible ||
                 mWindowType == eWindowType_child),
@@ -296,17 +296,17 @@ nsBaseWidget::AttachViewToTopLevel(bool 
 
   return NS_OK;
 }
 
 nsIWidgetListener* nsBaseWidget::GetAttachedWidgetListener()
  {
    return mAttachedWidgetListener;
  }
- 
+
 void nsBaseWidget::SetAttachedWidgetListener(nsIWidgetListener* aListener)
  {
    mAttachedWidgetListener = aListener;
  }
 
 //-------------------------------------------------------------------------
 //
 // Close this nsBaseWidget
@@ -400,17 +400,17 @@ double nsIWidget::GetDefaultScale()
 //
 // Add a child to the list of children
 //
 //-------------------------------------------------------------------------
 void nsBaseWidget::AddChild(nsIWidget* aChild)
 {
   NS_PRECONDITION(!aChild->GetNextSibling() && !aChild->GetPrevSibling(),
                   "aChild not properly removed from its old child list");
-  
+
   if (!mFirstChild) {
     mFirstChild = mLastChild = aChild;
   } else {
     // append to the list
     NS_ASSERTION(mLastChild, "Bogus state");
     NS_ASSERTION(!mLastChild->GetNextSibling(), "Bogus state");
     mLastChild->SetNextSibling(aChild);
     aChild->SetPrevSibling(mLastChild);
@@ -422,17 +422,17 @@ void nsBaseWidget::AddChild(nsIWidget* a
 //-------------------------------------------------------------------------
 //
 // Remove a child from the list of children
 //
 //-------------------------------------------------------------------------
 void nsBaseWidget::RemoveChild(nsIWidget* aChild)
 {
   NS_ASSERTION(aChild->GetParent() == this, "Not one of our kids!");
-  
+
   if (mLastChild == aChild) {
     mLastChild = mLastChild->GetPrevSibling();
   }
   if (mFirstChild == aChild) {
     mFirstChild = mFirstChild->GetNextSibling();
   }
 
   // Now remove from the list.  Make sure that we pass ownership of the tail
@@ -440,33 +440,33 @@ void nsBaseWidget::RemoveChild(nsIWidget
   nsIWidget* prev = aChild->GetPrevSibling();
   nsIWidget* next = aChild->GetNextSibling();
   if (prev) {
     prev->SetNextSibling(next);
   }
   if (next) {
     next->SetPrevSibling(prev);
   }
-  
+
   aChild->SetNextSibling(nullptr);
   aChild->SetPrevSibling(nullptr);
 }
 
 
 //-------------------------------------------------------------------------
 //
 // Sets widget's position within its parent's child list.
 //
 //-------------------------------------------------------------------------
 NS_IMETHODIMP nsBaseWidget::SetZIndex(int32_t aZIndex)
 {
   // Hold a ref to ourselves just in case, since we're going to remove
   // from our parent.
   nsCOMPtr<nsIWidget> kungFuDeathGrip(this);
-  
+
   mZIndex = aZIndex;
 
   // reorder this child in its parent's list.
   nsBaseWidget* parent = static_cast<nsBaseWidget*>(GetParent());
   if (parent) {
     parent->RemoveChild(this);
     // Scope sib outside the for loop so we can check it afterward
     nsIWidget* sib = parent->GetFirstChild();
@@ -557,29 +557,27 @@ NS_IMETHODIMP nsBaseWidget::GetSizeMode(
 // Get the foreground color
 //
 //-------------------------------------------------------------------------
 nscolor nsBaseWidget::GetForegroundColor(void)
 {
   return mForeground;
 }
 
-    
 //-------------------------------------------------------------------------
 //
 // Set the foreground color
 //
 //-------------------------------------------------------------------------
 NS_METHOD nsBaseWidget::SetForegroundColor(const nscolor &aColor)
 {
   mForeground = aColor;
   return NS_OK;
 }
 
-    
 //-------------------------------------------------------------------------
 //
 // Get the background color
 //
 //-------------------------------------------------------------------------
 nscolor nsBaseWidget::GetBackgroundColor(void)
 {
   return mBackground;
@@ -590,39 +588,39 @@ nscolor nsBaseWidget::GetBackgroundColor
 // Set the background color
 //
 //-------------------------------------------------------------------------
 NS_METHOD nsBaseWidget::SetBackgroundColor(const nscolor &aColor)
 {
   mBackground = aColor;
   return NS_OK;
 }
-     
+
 //-------------------------------------------------------------------------
 //
 // Get this component cursor
 //
 //-------------------------------------------------------------------------
 nsCursor nsBaseWidget::GetCursor()
 {
   return mCursor;
 }
 
 NS_METHOD nsBaseWidget::SetCursor(nsCursor aCursor)
 {
-  mCursor = aCursor; 
+  mCursor = aCursor;
   return NS_OK;
 }
 
 NS_IMETHODIMP nsBaseWidget::SetCursor(imgIContainer* aCursor,
                                       uint32_t aHotspotX, uint32_t aHotspotY)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
-    
+
 //-------------------------------------------------------------------------
 //
 // Get the window type for this widget
 //
 //-------------------------------------------------------------------------
 NS_IMETHODIMP nsBaseWidget::GetWindowType(nsWindowType& aWindowType)
 {
   aWindowType = mWindowType;
@@ -699,17 +697,17 @@ NS_IMETHODIMP nsBaseWidget::MakeFullScre
 
   if (aFullScreen) {
     if (!mOriginalBounds)
       mOriginalBounds = new nsIntRect();
     GetScreenBounds(*mOriginalBounds);
 
     // Move to top-left corner of screen and size to the screen dimensions
     nsCOMPtr<nsIScreenManager> screenManager;
-    screenManager = do_GetService("@mozilla.org/gfx/screenmanager;1"); 
+    screenManager = do_GetService("@mozilla.org/gfx/screenmanager;1");
     NS_ASSERTION(screenManager, "Unable to grab screenManager.");
     if (screenManager) {
       nsCOMPtr<nsIScreen> screen;
       // convert dev pix to display/CSS pix for ScreenForRect
       double scale = GetDefaultScale();
       screenManager->ScreenForRect(mOriginalBounds->x / scale,
                                    mOriginalBounds->y / scale,
                                    mOriginalBounds->width / scale,
@@ -774,22 +772,22 @@ nsBaseWidget::ComputeShouldAccelerate(bo
 {
 #if defined(XP_WIN) || defined(ANDROID) || (MOZ_PLATFORM_MAEMO > 5) || \
     defined(MOZ_GL_PROVIDER) || defined(XP_MACOSX)
   bool accelerateByDefault = true;
 #else
   bool accelerateByDefault = false;
 #endif
 
-  // We don't want to accelerate small popup windows like menu, but we still 
+  // We don't want to accelerate small popup windows like menu, but we still
   // want to accelerate xul panels that may contain arbitrarily complex content.
-  bool isSmallPopup = ((mWindowType == eWindowType_popup) && 
+  bool isSmallPopup = ((mWindowType == eWindowType_popup) &&
                       (mPopupType != ePopupTypePanel));
   // we should use AddBoolPrefVarCache
-  bool disableAcceleration = isSmallPopup || 
+  bool disableAcceleration = isSmallPopup ||
     Preferences::GetBool("layers.acceleration.disabled", false);
   mForceLayersAcceleration =
     Preferences::GetBool("layers.acceleration.force-enabled", false);
 
   const char *acceleratedEnv = PR_GetEnv("MOZ_ACCELERATED");
   accelerateByDefault = accelerateByDefault ||
                         (acceleratedEnv && (*acceleratedEnv != '0'));
 
@@ -816,17 +814,17 @@ nsBaseWidget::ComputeShouldAccelerate(bo
     }
   }
 
   if (disableAcceleration || safeMode)
     return false;
 
   if (mForceLayersAcceleration)
     return true;
-  
+
   if (!whitelisted) {
     NS_WARNING("OpenGL-accelerated layers are not supported on this system.");
 #ifdef MOZ_ANDROID_OMTC
     NS_RUNTIMEABORT("OpenGL-accelerated layers are a hard requirement on this platform. "
                     "Cannot continue without support for them.");
 #endif
     return false;
   }
@@ -879,17 +877,17 @@ void nsBaseWidget::CreateCompositor()
     NS_RUNTIMEABORT("failed to construct LayersChild");
     delete lm;
     mCompositorChild = nullptr;
   }
 }
 
 bool nsBaseWidget::UseOffMainThreadCompositing()
 {
-  bool isSmallPopup = ((mWindowType == eWindowType_popup) && 
+  bool isSmallPopup = ((mWindowType == eWindowType_popup) &&
                       (mPopupType != ePopupTypePanel));
   return CompositorParent::CompositorLoop() && !isSmallPopup;
 }
 
 LayerManager* nsBaseWidget::GetLayerManager(PLayersChild* aShadowManager,
                                             LayersBackend aBackendHint,
                                             LayerManagerPersistence aPersistence,
                                             bool* aAllowRetaining)
@@ -947,23 +945,23 @@ CompositorChild* nsBaseWidget::GetRemote
   return mCompositorChild;
 }
 
 //-------------------------------------------------------------------------
 //
 // Return the used device context
 //
 //-------------------------------------------------------------------------
-nsDeviceContext* nsBaseWidget::GetDeviceContext() 
+nsDeviceContext* nsBaseWidget::GetDeviceContext()
 {
   if (!mContextInitialized) {
     mContext->Init(this);
     mContextInitialized = true;
   }
-  return mContext; 
+  return mContext;
 }
 
 //-------------------------------------------------------------------------
 //
 // Get the thebes surface
 //
 //-------------------------------------------------------------------------
 gfxASurface *nsBaseWidget::GetThebesSurface()
@@ -1074,17 +1072,17 @@ nsIntPoint nsBaseWidget::GetClientOffset
   return nsIntPoint(0, 0);
 }
 
 NS_IMETHODIMP
 nsBaseWidget::GetNonClientMargins(nsIntMargin &margins)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
- 
+
 NS_IMETHODIMP
 nsBaseWidget::SetNonClientMargins(nsIntMargin &margins)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_METHOD nsBaseWidget::EnableDragDrop(bool aEnable)
 {
@@ -1238,17 +1236,17 @@ ResolveIconNameHelper(nsIFile *aFile,
  * platform specific icon file suffix (e.g., ".ico" under Win32).
  *
  * If no file is found matching the given parameters, then null is returned.
  */
 void
 nsBaseWidget::ResolveIconName(const nsAString &aIconName,
                               const nsAString &aIconSuffix,
                               nsIFile **aResult)
-{ 
+{
   *aResult = nullptr;
 
   nsCOMPtr<nsIProperties> dirSvc = do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
   if (!dirSvc)
     return;
 
   // first check auxilary chrome directories
 
@@ -1276,17 +1274,17 @@ nsBaseWidget::ResolveIconName(const nsAS
 
   nsCOMPtr<nsIFile> file;
   dirSvc->Get(NS_APP_CHROME_DIR, NS_GET_IID(nsIFile),
               getter_AddRefs(file));
   if (file && ResolveIconNameHelper(file, aIconName, aIconSuffix))
     NS_ADDREF(*aResult = file);
 }
 
-NS_IMETHODIMP 
+NS_IMETHODIMP
 nsBaseWidget::BeginResizeDrag(nsGUIEvent* aEvent, int32_t aHorizontal, int32_t aVertical)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 NS_IMETHODIMP
 nsBaseWidget::BeginMoveDrag(nsMouseEvent* aEvent)
 {
@@ -1476,27 +1474,27 @@ case _value: eventName.AssignLiteral(_na
     _ASSIGN_eventName(NS_PAGE_UNLOAD,"NS_PAGE_UNLOAD");
     _ASSIGN_eventName(NS_HASHCHANGE,"NS_HASHCHANGE");
     _ASSIGN_eventName(NS_READYSTATECHANGE,"NS_READYSTATECHANGE");
     _ASSIGN_eventName(NS_XUL_BROADCAST, "NS_XUL_BROADCAST");
     _ASSIGN_eventName(NS_XUL_COMMAND_UPDATE, "NS_XUL_COMMAND_UPDATE");
 
 #undef _ASSIGN_eventName
 
-  default: 
+  default:
     {
       char buf[32];
-      
+
       sprintf(buf,"UNKNOWN: %d",aGuiEvent->message);
-      
+
       CopyASCIItoUTF16(buf, eventName);
     }
     break;
   }
-  
+
   return nsAutoString(eventName);
 }
 //////////////////////////////////////////////////////////////
 //
 // Code to deal with paint and event debug prefs.
 //
 //////////////////////////////////////////////////////////////
 struct PrefPair
@@ -1593,17 +1591,17 @@ debug_RegisterPrefCallbacks()
     }
   }
 }
 //////////////////////////////////////////////////////////////
 static int32_t
 _GetPrintCount()
 {
   static int32_t sCount = 0;
-  
+
   return ++sCount;
 }
 //////////////////////////////////////////////////////////////
 /* static */ bool
 nsBaseWidget::debug_WantPaintFlashing()
 {
   return debug_GetCachedBoolPref("nglayout.debug.paint_flashing");
 }
@@ -1615,63 +1613,63 @@ nsBaseWidget::debug_DumpEvent(FILE *    
                               const nsAutoCString & aWidgetName,
                               int32_t               aWindowID)
 {
   if (aGuiEvent->message == NS_MOUSE_MOVE)
   {
     if (!debug_GetCachedBoolPref("nglayout.debug.motion_event_dumping"))
       return;
   }
-  
-  if (aGuiEvent->message == NS_MOUSE_ENTER || 
+
+  if (aGuiEvent->message == NS_MOUSE_ENTER ||
       aGuiEvent->message == NS_MOUSE_EXIT)
   {
     if (!debug_GetCachedBoolPref("nglayout.debug.crossing_event_dumping"))
       return;
   }
 
   if (!debug_GetCachedBoolPref("nglayout.debug.event_dumping"))
     return;
 
   NS_LossyConvertUTF16toASCII tempString(debug_GuiEventToString(aGuiEvent).get());
-  
+
   fprintf(aFileOut,
-          "%4d %-26s widget=%-8p name=%-12s id=%-8p refpt=%d,%d\n",
+          "%4d %-26s widget=%-8p name=%-12s id=0x%-6x refpt=%d,%d\n",
           _GetPrintCount(),
           tempString.get(),
           (void *) aWidget,
           aWidgetName.get(),
-          (void *) (aWindowID ? aWindowID : 0x0),
+          aWindowID,
           aGuiEvent->refPoint.x,
           aGuiEvent->refPoint.y);
 }
 //////////////////////////////////////////////////////////////
 /* static */ void
 nsBaseWidget::debug_DumpPaintEvent(FILE *                aFileOut,
                                    nsIWidget *           aWidget,
                                    const nsIntRegion &   aRegion,
                                    const nsAutoCString & aWidgetName,
                                    int32_t               aWindowID)
 {
   NS_ASSERTION(nullptr != aFileOut,"cmon, null output FILE");
   NS_ASSERTION(nullptr != aWidget,"cmon, the widget is null");
 
   if (!debug_GetCachedBoolPref("nglayout.debug.paint_dumping"))
     return;
-  
+
   nsIntRect rect = aRegion.GetBounds();
   fprintf(aFileOut,
-          "%4d PAINT      widget=%p name=%-12s id=%-8p bounds-rect=%3d,%-3d %3d,%-3d", 
+          "%4d PAINT      widget=%p name=%-12s id=0x%-6x bounds-rect=%3d,%-3d %3d,%-3d",
           _GetPrintCount(),
           (void *) aWidget,
           aWidgetName.get(),
-          (void *) aWindowID,
+          aWindowID,
           rect.x, rect.y, rect.width, rect.height
     );
-  
+
   fprintf(aFileOut,"\n");
 }
 //////////////////////////////////////////////////////////////
 /* static */ void
 nsBaseWidget::debug_DumpInvalidate(FILE *                aFileOut,
                                    nsIWidget *           aWidget,
                                    const nsIntRect *     aRect,
                                    const nsAutoCString & aWidgetName,
@@ -1679,36 +1677,36 @@ nsBaseWidget::debug_DumpInvalidate(FILE 
 {
   if (!debug_GetCachedBoolPref("nglayout.debug.invalidate_dumping"))
     return;
 
   NS_ASSERTION(nullptr != aFileOut,"cmon, null output FILE");
   NS_ASSERTION(nullptr != aWidget,"cmon, the widget is null");
 
   fprintf(aFileOut,
-          "%4d Invalidate widget=%p name=%-12s id=%-8p",
+          "%4d Invalidate widget=%p name=%-12s id=0x%-6x",
           _GetPrintCount(),
           (void *) aWidget,
           aWidgetName.get(),
-          (void *) aWindowID);
+          aWindowID);
 
-  if (aRect) 
+  if (aRect)
   {
     fprintf(aFileOut,
             " rect=%3d,%-3d %3d,%-3d",
-            aRect->x, 
+            aRect->x,
             aRect->y,
-            aRect->width, 
+            aRect->width,
             aRect->height);
   }
   else
   {
     fprintf(aFileOut,
             " rect=%-15s",
             "none");
   }
-  
+
   fprintf(aFileOut,"\n");
 }
 //////////////////////////////////////////////////////////////
 
 #endif // DEBUG
 
--- a/widget/xremoteclient/XRemoteClient.cpp
+++ b/widget/xremoteclient/XRemoteClient.cpp
@@ -75,17 +75,17 @@ XRemoteClient::XRemoteClient()
 XRemoteClient::~XRemoteClient()
 {
   PR_LOG(sRemoteLm, PR_LOG_DEBUG, ("XRemoteClient::~XRemoteClient"));
   if (mInitialized)
     Shutdown();
 }
 
 // Minimize the roundtrips to the X-server
-static char *XAtomNames[] = {
+static const char *XAtomNames[] = {
   MOZILLA_VERSION_PROP,
   MOZILLA_LOCK_PROP,
   MOZILLA_COMMAND_PROP,
   MOZILLA_RESPONSE_PROP,
   "WM_STATE",
   MOZILLA_USER_PROP,
   MOZILLA_PROFILE_PROP,
   MOZILLA_PROGRAM_PROP,
@@ -102,17 +102,18 @@ XRemoteClient::Init()
     return NS_OK;
 
   // try to open the display
   mDisplay = XOpenDisplay(0);
   if (!mDisplay)
     return NS_ERROR_FAILURE;
 
   // get our atoms
-  XInternAtoms(mDisplay, XAtomNames, ARRAY_LENGTH(XAtomNames), False, XAtoms);
+  XInternAtoms(mDisplay, const_cast<char**>(XAtomNames),
+               ARRAY_LENGTH(XAtomNames), False, XAtoms);
 
   int i = 0;
   mMozVersionAtom  = XAtoms[i++];
   mMozLockAtom     = XAtoms[i++];
   mMozCommandAtom  = XAtoms[i++];
   mMozResponseAtom = XAtoms[i++];
   mMozWMStateAtom  = XAtoms[i++];
   mMozUserAtom     = XAtoms[i++];
--- a/widget/xremoteclient/XRemoteClient.h
+++ b/widget/xremoteclient/XRemoteClient.h
@@ -60,14 +60,13 @@ private:
   Atom           mMozLockAtom;
   Atom           mMozCommandAtom;
   Atom           mMozCommandLineAtom;
   Atom           mMozResponseAtom;
   Atom           mMozWMStateAtom;
   Atom           mMozUserAtom;
   Atom           mMozProfileAtom;
   Atom           mMozProgramAtom;